реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> LPC2478. проблемы с UART., частичная потеря байт на приеме.
navy2000
сообщение Feb 15 2011, 18:16
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 203
Регистрация: 17-07-06
Пользователь №: 18 874



Подключил смарт карту к UART3 по интерфейсу ISO-7816. Сигнал с TX инвертируется на ключике и идет на разрешающий вход одноканального аналогового коммутатора. Один конец коммутатора подключен к земле, а второй подтянут к питанию (10к) и подключен к I/O смарт карты, сюда же напрямую подключен RX. Таким образом, когда идет передача приемник видит собственную посылку. Когда передача закончена аналоговый коммутатор не оказывает влияния на линию, карта отвечает на RX.
Провожу инициализацию карты - принимаю ATR. Принимаю правильно, все расшифровывается и соответствует даташиту на карту.
Подаю PPS команду (скорость нужно установить), карта ее воспринимает и отвечает эхо-посылкой. Причем в UART-е вижу как запрос, так и ответ.
Кодирую APDU команду в протокол Т=1 (GetVersion) посылаю в карту. И вот тут начинаются чудеса. В буфере UART-а вижу запрос (сама команда) и один байт ответа карты. Смотрю осциллографом, вижу четкий запрос и четкий ответ на 32 байт. Сделал запись, разобрал посылки, все четко. Фронты хорошие, посылки друг на друга не налазят, скорости запроса и ответа совпадают. Более того, подключил на линию RX прослушку и подключился терминалкой с компа. Она принимает и запрос и ответ. Но UART принимать ответ карты отказывается.
Исходники привожу. В них в реальной жизни все гораздо сложнее, но в процессе поиска недостающих байт я из них все лишнее вычистил.
Код
// Ноги UART-а
PINSEL0_bit.P0_0=2;  // TxD3
PINSEL0_bit.P0_1=2;  // RxD3

Код
// работа с UART

typedef struct
{
  unsigned long                   power_bit;
  unsigned long                   int_no;
  void*                           int_handler;
  volatile unsigned long*         acr;
  volatile unsigned long*         fcr;
  volatile unsigned char*         lcr;
  volatile unsigned long*         dlm;
  volatile unsigned char*         dll;
  volatile unsigned long*         fdr;
  volatile unsigned long*         ier;
  volatile const unsigned char*   lsr;
  volatile unsigned char*         thr;
  volatile unsigned long*         iir;
  volatile unsigned char*         rbr;
}NXP_UART_HARDWARE;

// Прерывание UART
void nxp_uart_interrupt(unsigned long uart_index)
{
  volatile unsigned char reg;
  unsigned long status=(*nxp_uart[uart_index].hardware->iir>>1)&0x07;

  switch(status)
  {
   case 2: //Прием
   case 6: //CTI
    while(*nxp_uart[uart_index].hardware->lsr&(1<<0))
    {
      unsigned char data=*nxp_uart[uart_index].hardware->rbr;

#ifdef DEBUG_MODE
// отладка. посчитаем количество принятых байт
      nxp_uart[uart_index].receive_count++;
#endif

// сохраняем данные в программное FIFO
      if (!fifo_full(&nxp_uart[uart_index].rx_fifo))
       fifo_write(&nxp_uart[uart_index].rx_fifo,data);

    }
    break;

   case 1: //Отправка
    while((*nxp_uart[uart_index].hardware->lsr&(1<<5)) && !fifo_empty(&nxp_uart[uart_index].tx_fifo))
    {
      *nxp_uart[uart_index].hardware->thr=fifo_read(&nxp_uart[uart_index].tx_fifo);

#ifdef DEBUG_MODE
// отладка. посчитаем количество отправленных байт
       nxp_uart[uart_index].send_count++;
#endif

// данные загружаем из программного FIFO
      if (fifo_empty(&nxp_uart[uart_index].tx_fifo))
       *nxp_uart[uart_index].hardware->ier&=~(1<<1); //Данных нет, запретим прерывание
    }
    break;

   case 3: //Ошибка
    reg=*nxp_uart[uart_index].hardware->lsr;
    if (reg&0x9E)
    {

#ifdef DEBUG_MODE
      nxp_uart[uart_index].last_error_state=reg;
      nxp_uart[uart_index].error_count++;
#endif

      reg=*nxp_uart[uart_index].hardware->rbr;
    }
    break;
  }
}

// Инициализация UART
void nxp_uart_open(unsigned long uart_index,unsigned char* rx_buffer, unsigned long rx_buffer_size, unsigned char* tx_buffer, unsigned long tx_buffer_size, unsigned long int_priority)
{
  nxp_uart[uart_index].hardware=&nxp_uart_hardware[uart_index];

  nxp_uart[uart_index].rx_fifo.buffer=rx_buffer;
  nxp_uart[uart_index].rx_fifo.read_pointer=0;
  nxp_uart[uart_index].rx_fifo.write_pointer=0;
  nxp_uart[uart_index].rx_fifo.size=rx_buffer_size;

  nxp_uart[uart_index].tx_fifo.buffer=tx_buffer;
  nxp_uart[uart_index].tx_fifo.read_pointer=0;
  nxp_uart[uart_index].tx_fifo.write_pointer=0;
  nxp_uart[uart_index].tx_fifo.size=tx_buffer_size;

#ifdef DEBUG_MODE
  nxp_uart[uart_index].receive_count=0;
  nxp_uart[uart_index].send_count=0;
  nxp_uart[uart_index].error_count=0;
  nxp_uart[uart_index].last_error_state=0;
#endif

  PCONP|=(1<<nxp_uart[uart_index].hardware->power_bit);

  *nxp_uart[uart_index].hardware->acr&=~(1<<0);    // autobaud off
  *nxp_uart[uart_index].hardware->fcr=0x41;            // FIFO Enable, прерывание по приему четвертого байта

  //ПРЕРЫВАНИЯ
  *nxp_uart[uart_index].hardware->ier|=(1<<0);       //Прием разрешим
  *nxp_uart[uart_index].hardware->ier&=~(1<<1);    //Передачу запретим (начало пакета отправляется из основного цикла)
  *nxp_uart[uart_index].hardware->ier|=(1<<2);       //Статус разрешим

  nxp_irq_install(nxp_uart[uart_index].hardware->int_no,nxp_uart[uart_index].hardware->int_handler,int_priority);

}


Отчего часть байт может быть потеряна. Уже не знаю в какую сторону копать. Считал что библиотеки работы с UART для этого камня давно написаны и отлажены, но как оказалось есть нюансы.
Go to the top of the page
 
+Quote Post
Рашпиль
сообщение Feb 16 2011, 14:24
Сообщение #2





Группа: Новичок
Сообщений: 6
Регистрация: 9-02-11
Из: Украина, Харьков
Пользователь №: 62 830



У меня была похожая проблема. Проверьте количество стоп битов и контроль четности. Одинаковые ли настройки с обеих сторон?


--------------------
Жизнь - не те дни, что прошли, а те, что остались.
Go to the top of the page
 
+Quote Post
navy2000
сообщение Feb 16 2011, 18:05
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 203
Регистрация: 17-07-06
Пользователь №: 18 874



Цитата(Рашпиль @ Feb 16 2011, 20:24) *
У меня была похожая проблема. Проверьте количество стоп битов и контроль четности. Одинаковые ли настройки с обеих сторон?


Да. Так и оказалось.
В описании на ISO-7816 указывалось, что имеется интервал между байтами примерно равный одному полтора бита.
Поэтому я сделал два стоп бита (в стандартной посылке стоп бит может использоваться для перезапроса ошибочно принятого байта).
Оказалось, что карта довольно условно поддерживает этот стандарт. И если ATR передавался по стандарту, то есть с двумя стоп битами
прекрасно принимался, то ответ на APDU команду не принимался вовсе. Но вот что мне до сих пор осталось не понятно, почему из 34 байт принимался только один (последний) но ни одного раза не возникала ошибка приема? По наивности полагал, что раз Frame Error отсутствует то со стоп битом все нормально. А вот на неправильную четность он сразу выдавал Parity Error.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 14:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.01387 секунд с 7
ELECTRONIX ©2004-2016