Коллеги, не могу понять - что я не так делаю? Пишу обработчик уарта для LPC2214.
Код
//********************************************************************************
**********
//Обработчик прерывания UART1
//********************************************************************************
**********
void UART1_Handler(void) __irq
{
u8_t iid;
u8_t tmphead;
u8_t tmptail;
//iid = U1IIR;
iid = 0;
while(((iid & 1) == 0))
//while(((iid = U1IIR) & UIIR_NO_INT) == 0)
{
switch(iid & UIIR_ID_MASK)
{
case UIIR_RLS_INT: //Receive Line Status
U1LSR; //read LSR to clear
break;
//Прием
case UIIR_CTI_INT: //Character Timeout Indicator
case UIIR_RDA_INT: //Receive Data Available
do
{
iid = U1RBR;
if((uart1.flags & (1<<UART1_FLAG_TX_IN_PROGRESS)) == 0)
{
tmphead = (uart1.rx_head + 1) & UART1_RX_BUFFER_MASK;
uart1.rx_head = tmphead;
if(tmphead == uart1.rx_tail)
{
//ERROR! Receive buffer overflow
uart1.flags |= (1<<UART1_FLAG_ERR);
}
uart1.rx_buf[tmphead] = iid;
}
}while(U1LSR & U1LSR_RDR_BIT);
break;
//Прередача
case UIIR_THRE_INT:
while(U1LSR & U1LSR_THRE_BIT)
{
tmptail = uart1.tx_tail;
if(uart1.tx_head != tmptail)
{
tmptail = (uart1.tx_tail + 1) & UART1_TX_BUFFER_MASK;
uart1.tx_tail = tmptail;
U1THR = uart1.tx_buf[tmptail];
}
else
{
uart1.flags &= ~(1<<UART1_FLAG_TX_IN_PROGRESS);
uart1.flags |= (1<<UART1_FLAG_TX_COMPLETE);
}
}
break;
case UIIR_MS_INT: //MODEM Status
U1MSR; //read MSR to clear
break;
default: //Unknown
U1LSR;
U1RBR;
U1MSR;
break;
}
}
VICVectAddr = 0x00000000;
}
Начал проверять - не работает. Начал разбираться, смотрю - при передаче байта выражение while(((iid = U1IIR) & UIIR_NO_INT) == 0) всегда ложно. Я тогда тупо iid проинициализировал 0 - все равно. Посмотрел в дизасме (см. картинку) компилятор вместо while сразу поставил выход из цикла. Что это значит? Оптимизацию вообще отключил. Пишу в кейл/карм.
Еще - в автомате тоже циклы вида while(...){} не работают - компилер сразу ставит выход из цикла. Зато do{}while(...); отлично работает. Эх видно особенность карма.
Эскизы прикрепленных изображений