Здравствуйте
Для отправки в порт фрейма необходимо использовать DMA, используя стандартный пример от атмела удалось добиться вывода с использованием DMA. Только вот неясно как поймать момент окончания отправки чтобы уничтожить временный буфер отправки.
В даташите сказано что для этой цели можно использовать биты TXBUFE и ENDTX в статусном регистре UART, по выставлению которых можно генерировать прерывание. Добавил в обработчик проверку этих битов и в инициализацию портов добавил включение прерывания по US_ENDTX.
Так вот, если прерывание по US_ENDTX или US_TXEMPTY включено то процессор зависает при первой же передаче, как будто забыл сбросить какой то бит в обработчике прерывания от UART.
Код инициализации:
Код
unsigned int iBaud = 9600;
PIO_Configure(USART1_pins, PIO_LISTSIZE(USART1_pins));
PMC_EnablePeripheral(AT91C_ID_US1); // Enable the peripheral clock in the PMC
USART_Configure(AT91C_BASE_US1, mode, iBaud, 48000000); // Устанавливаем режим и скорость порта
IRQ_ConfigureIT(AT91C_ID_US1, 5, IRQ_UART1_RX); // IRQ_UART1_RX - обработчик прерывания по приходу байта // или по таймауту
IRQ_EnableIT(AT91C_ID_US1); // Разрешаем прерывание от UART1
USART_SetTransmitterEnabled(AT91C_BASE_US1, 1); // Включаем передатчик
USART_SetReceiverEnabled(AT91C_BASE_US1, 1); // Включаем приёмник
AT91C_BASE_US1->US_IER = AT91C_US_RXRDY | AT91C_US_TIMEOUT | AT91C_US_ENDTX; // Так зависает
// AT91C_BASE_US1->US_IER = AT91C_US_RXRDY | AT91C_US_TIMEOUT; // А так - нет
AT91C_BASE_US1->US_RTOR=cstTimeCOM; // Устанавливаем тайм-аут
Обработчик прерывания:
Код
void IRQ_UART1_RX()
{
unsigned int status = AT91C_BASE_US1->US_CSR & AT91C_BASE_US1->US_IMR;
if (status & AT91C_US_ENDTX) // Передача закончена
{
// Вот это событие хочу поймать
}
if (status & AT91C_US_OVRE) // Буфер был переполнен
SizeCOM1 = 0;
if (status & AT91C_US_RXRDY) // если прерывание произошло по приёму 1 байт буфера
InBufCOM1[SizeCOM1++] = AT91C_BASE_US1->US_RHR; // Заполнение буфера порта COM1
if (status & AT91C_US_TIMEOUT) // если прерывание произошло по таймауту, фрейм окончен
{
AT91C_BASE_US1->US_CR = AT91C_US_STTTO; // Сбрасываем тайм-аут
// Обработка пакета
}
}
}
Сообщение отредактировал athlon64 - Mar 29 2011, 12:49