Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: lpc2134-01 не приходит прерывание uart CTI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
HEX
Чего-то не приходят прерывания CTI от uart (работаю с uart0), если размер посылки >= RxFIFITrigerLevel. Если размер < все нормально. Модуль работы с uart перенес с lpc2292 там все работало. Попадалось сообщение в конфе про глюк в uart lpc2138, ни чего подробно не нашел. Искать у себя или проц такой? пожалуйста кто использует lpc213x отзовитесь.

Инициализация:
Код
#define RxFIFOTrigger8  0x80
...
{
  Word W;

  //Line control register
  U0LCR = ByteSize + StopBits + Parity;
  //BaudRate
  W = Fvpb/16/BaudRate;
  U0LCR = U0LCR | DivisorLatchAccessBit;    
  U0DLM = Hi(W);
  U0DLL = Lo(W);
  U0LCR = U0LCR & (~DivisorLatchAccessBit);    
  //FIFO
  U0FCR = RxFIFORstFlag + TxFIFORstFlag;
  U0FCR = FIFOEnableFlag + RxFIFOTrigger;
  // Set Interrupt Enable Register
  U0IER = RBRInterruptEnable + RLSInterruptEnable;
  //Инициализация вектора прерываний
  VICProtection = 0x00;                          
  //Установка вектора прерывания
  VICIntSelect &= ~(1<<VIC_UART0);                
  VICVectAddr6 = (unsigned long)&IRQHandler;    
  VICVectCntl6 = 0x20|VIC_UART0;                  
  VICIntEnable = VICIntEnable|(1<<VIC_UART0);    
  VICProtection = 0x01;
}


Обработчик прерывания:
Код
{
  Byte B;
  Byte Src;
  int i;

  do {
    Src = U0IIR;
    switch(Src & InterruptIDMask) {
      case RLSInterruptID: {
        DoOnRLSEvent(U0LSR);
        break;
      }
      case RDAInterruptID: {
        while ((U0LSR & ReceiverDataReady) != 0)
          FInQueue.Put(U0RBR);
        break;
      }
      case CTIInterruptID: {
        while ((U0LSR & ReceiverDataReady) != 0)
          FInQueue.Put(U0RBR);
        DoOnCTIEvent();
        break;
      }
      case THREInterruptID: {
        i = TxFIFODepth;
        do
        {
          if (FOutQueue.Get(&B)) {
            U0THR = B;
          }
          else {
            U0IER = U0IER & (~THREInterruptEnable);
            break;
          }
          i = i - 1;
        }
        while(i != 0);
        break;
      }
    }
  }
  while((Src & IntPendingFlag) == 0);
Александр_С
Цитата(HEX @ May 22 2008, 22:45) *
Чего-то не приходят прерывания CTI от uart (работаю с uart0), если размер посылки >= RxFIFITrigerLevel. Если размер < все нормально. Модуль работы с uart перенес с lpc2292 там все работало. Попадалось сообщение в конфе про глюк в uart lpc2138, ни чего подробно не нашел. Искать у себя или проц такой? пожалуйста кто использует lpc213x отзовитесь.

Инициализация:
Код
#define RxFIFOTrigger8  0x80
...
{
  Word W;

  //Line control register
  U0LCR = ByteSize + StopBits + Parity;
  //BaudRate
  W = Fvpb/16/BaudRate;
  U0LCR = U0LCR | DivisorLatchAccessBit;    
  U0DLM = Hi(W);
  U0DLL = Lo(W);
  U0LCR = U0LCR & (~DivisorLatchAccessBit);    
  //FIFO
  U0FCR = RxFIFORstFlag + TxFIFORstFlag;
  U0FCR = FIFOEnableFlag + RxFIFOTrigger;
  // Set Interrupt Enable Register
  U0IER = RBRInterruptEnable + RLSInterruptEnable;
  //Инициализация вектора прерываний
  VICProtection = 0x00;                          
  //Установка вектора прерывания
  VICIntSelect &= ~(1<<VIC_UART0);                
  VICVectAddr6 = (unsigned long)&IRQHandler;    
  VICVectCntl6 = 0x20|VIC_UART0;                  
  VICIntEnable = VICIntEnable|(1<<VIC_UART0);    
  VICProtection = 0x01;
}


Обработчик прерывания:
Код
{
  Byte B;
  Byte Src;
  int i;

  do {
    Src = U0IIR;
    switch(Src & InterruptIDMask) {
      case RLSInterruptID: {
        DoOnRLSEvent(U0LSR);
        break;
      }
      case RDAInterruptID: {
        while ((U0LSR & ReceiverDataReady) != 0)
          FInQueue.Put(U0RBR);
        break;
      }
      case CTIInterruptID: {
        while ((U0LSR & ReceiverDataReady) != 0)
          FInQueue.Put(U0RBR);
        DoOnCTIEvent();
        break;
      }
      case THREInterruptID: {
        i = TxFIFODepth;
        do
        {
          if (FOutQueue.Get(&B)) {
            U0THR = B;
          }
          else {
            U0IER = U0IER & (~THREInterruptEnable);
            break;
          }
          i = i - 1;
        }
        while(i != 0);
        break;
      }
    }
  }
  while((Src & IntPendingFlag) == 0);



В LPC213x нужно обрабатывать прерывание наличие данных в буфере FIFO
оно срабатывает если количество принятых данных равно установленому в настройке тригера FIFO.
Прерывание CTI будет свормировано при количестве данных меньше установленого тригера FIFO с задержкой.

switch(U0IIR&0x0F)
{
case 0xC: //Character time out indicator interrupt (CTI)
case 0x4: //Receive data available
//обрабатываем полученые данные

break;
case 0x2: //THRE interrupt
break;
case 0x0: //Modem interrupt
case 0x6: //Receive line status interrupt (RDA)
default:
break;
}
zltigo
Цитата(Александр_С @ May 24 2008, 08:05) *

Moderator:
Настоятельно прошу воздержаться от ТУПОГО ненужного цитирования постов.


Цитата(HEX @ May 22 2008, 20:45) *
Чего-то не приходят прерывания CTI от uart (работаю с uart0), если размер посылки >= RxFIFITrigerLevel. Если размер < все нормально.

А с чего им приходить, если в этом случае отрабатывает штатное прерывание по приему БЕЗ таймаута.
Отличий в этом отношении между LPC21/2xx и LPC213/4 нет никаких. "Глюков" в классическом 82550 нет уже несколько десятилений.
HEX
До перло, так работает:
Цитата
...
case RDAInterruptID: {
if ((U0LSR & ReceiverDataReady) != 0)
FInQueue.Put(U0RBR);
break;
}
...


всем спасибо!
Alex03
А смысл?
Проще тогда FIFO отключить.

Кстати в приведённом коде есть некоторая непонятность с инициализацией FCR
Код
#define RxFIFOTrigger8  0x80
...
//FIFO
U0FCR = RxFIFORstFlag + TxFIFORstFlag;
U0FCR = FIFOEnableFlag + RxFIFOTrigger;

Чему равен RxFIFOTrigger ? Или там RxFIFOTrigger8?
HEX
Цитата(Alex03 @ May 28 2008, 08:29) *
Чему равен RxFIFOTrigger ? Или там RxFIFOTrigger8?

виноват, забыл вставить
Код
#define RxFIFOTrigger1  0x00
#define RxFIFOTrigger4  0x40
#define RxFIFOTrigger8  0x80
#define RxFIFOTrigger14 0xC0

#define RxFIFOTrigger  RxFIFOTrigger8


Еще доработал:
Код
...
  case RDAInterruptID: {
    i = 0;
    while ((i < (RxFIFOTrigger - 1)) & ((U0LSR & ReceiverDataReady) != 0))
    {
      FInQueue.Put(U0RBR);
      i = i + 1;
    }
    break;
  }
...

Вот как это будет работать (если не прав поправте):
При приеме данных когда в FIFO набирается >= RxFIFOTriggerLevel, должно прийти прерывание RDA.
Забираем данные, прерывание по RDA снимется когда в FIFO будет данных < RxFIFOTriggerLevel. Если считаем все данные из FIFO мы не получем CTI (согласно мануалу). Поэтому надо оставлять один байт в RxFIFO, соответственно TriggerLevel должен быть > 1.
Alex03
Цитата(HEX @ May 28 2008, 13:04) *
Еще доработал:
Код
...
    while ((i < (RxFIFOTrigger - 1)) & ((U0LSR & ReceiverDataReady) != 0))
...
Вот как это будет работать (если не прав поправте): ....

А RxFIFOTrigger при этом 0x80... smile.gif
HEX
Цитата(Alex03 @ May 28 2008, 13:08) *
А RxFIFOTrigger при этом 0x80... smile.gif

это описка, спасибо, ну идея то правельная?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.