Тайм-аут мне нужен чтобы определять окончание пакета.
С отдельным таймером для отсчитывания тайм-аута всё работает. Интересно использовать именно заложенную в USART аппаратную функцию. Прочитал раздел даташита про USART несколько раз, но всё равно чтото гдето забыл

Процессор получает пакет и даже успевает его пульнуть обратно, но по истечении таймаута процессор виснет.
Инициализация USART0:
Код
void ConfigureUsart(unsigned char usart_num)
{
unsigned int mode = AT91C_US_USMODE_NORMAL
| AT91C_US_CLKS_CLOCK
| AT91C_US_CHRL_8_BITS
| AT91C_US_PAR_NONE
| AT91C_US_NBSTOP_1_BIT
| AT91C_US_CHMODE_NORMAL;
PIO_Configure(USART0_pins, PIO_LISTSIZE(USART0_pins));
// Enable the peripheral clock in the PMC
PMC_EnablePeripheral(AT91C_ID_US0);
PMC_EnablePeripheral(AT91C_ID_US0);
// Configure the USART in the desired mode @9600 bauds
USART_Configure(AT91C_BASE_US0, mode, 9600, 48000000);
// Configure the USART interrupt
IRQ_ConfigureIT(AT91C_ID_US0, 0, USART0_IrqHandler);
IRQ_EnableIT(AT91C_ID_US0);
// Enable receiver & transmitter
USART_SetTransmitterEnabled(AT91C_BASE_US0, 1);
USART_SetReceiverEnabled(AT91C_BASE_US0, 1);
// Start receiving data and start timer
USART_ReadBuffer(AT91C_BASE_US0, &pBuffer, 1);
AT91C_BASE_US0->US_IER = AT91C_US_RXBUFF | AT91C_US_TIMEOUT;
//------------------------------------------------------------------------------
// Устанавливаем тайм-аут
AT91C_BASE_US0->US_RTOR=70u;
}
{
unsigned int mode = AT91C_US_USMODE_NORMAL
| AT91C_US_CLKS_CLOCK
| AT91C_US_CHRL_8_BITS
| AT91C_US_PAR_NONE
| AT91C_US_NBSTOP_1_BIT
| AT91C_US_CHMODE_NORMAL;
PIO_Configure(USART0_pins, PIO_LISTSIZE(USART0_pins));
// Enable the peripheral clock in the PMC
PMC_EnablePeripheral(AT91C_ID_US0);
PMC_EnablePeripheral(AT91C_ID_US0);
// Configure the USART in the desired mode @9600 bauds
USART_Configure(AT91C_BASE_US0, mode, 9600, 48000000);
// Configure the USART interrupt
IRQ_ConfigureIT(AT91C_ID_US0, 0, USART0_IrqHandler);
IRQ_EnableIT(AT91C_ID_US0);
// Enable receiver & transmitter
USART_SetTransmitterEnabled(AT91C_BASE_US0, 1);
USART_SetReceiverEnabled(AT91C_BASE_US0, 1);
// Start receiving data and start timer
USART_ReadBuffer(AT91C_BASE_US0, &pBuffer, 1);
AT91C_BASE_US0->US_IER = AT91C_US_RXBUFF | AT91C_US_TIMEOUT;
//------------------------------------------------------------------------------
// Устанавливаем тайм-аут
AT91C_BASE_US0->US_RTOR=70u;
}
Обработчик прерывания:
Код
void USART0_IrqHandler(void)
{
if ((AT91C_BASE_US0->US_CSR & AT91C_US_TIMEOUT) > 0) // если прерывание произошло по таймауту
BSP_LED_Toggle(1);
else if ((AT91C_BASE_US0->US_CSR & AT91C_US_RXRDY) == 1) { // если прерывание произошло по заполнению буфера
USART_ReadBuffer(AT91C_BASE_US0, &pBuffer, 1);
USART_Write(AT91C_BASE_US0,pBuffer,0);
AT91C_BASE_US0->US_CR =AT91C_BASE_US0->US_CR | AT91C_US_STTTO; //Начинаем отсчёт тайм-аута
}
}
{
if ((AT91C_BASE_US0->US_CSR & AT91C_US_TIMEOUT) > 0) // если прерывание произошло по таймауту
BSP_LED_Toggle(1);
else if ((AT91C_BASE_US0->US_CSR & AT91C_US_RXRDY) == 1) { // если прерывание произошло по заполнению буфера
USART_ReadBuffer(AT91C_BASE_US0, &pBuffer, 1);
USART_Write(AT91C_BASE_US0,pBuffer,0);
AT91C_BASE_US0->US_CR =AT91C_BASE_US0->US_CR | AT91C_US_STTTO; //Начинаем отсчёт тайм-аута
}
}