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