Hi, i'm developing a bootloader on a pxa255 based board. I have a problem using stuart RX interrupt. When I enter a character on a console, it receives the correct character when I read the STRBR register, but no jump to my IRQ function.
Below is a function initializing stuart. void serial_init(unsigned long baudrate) { unsigned int rate;
rate = UART_CLOCK/(16*baudrate);
_bl_disable_irq();
CKEN |= CKEN5_STUART;
STFCR = 0; /* disable TX/RX FIFO */
/* set baud rate */ STLCR = LCR_DLAB; /* DLAB on */ STDLL = rate & 0xFF; STDLH = rate >> 8; STLCR = LCR_WLS0 | LCR_WLS1;
/* enable and reset TX/RX FIFO(1-byte rx threshold FIFO) */ STFCR |= FCR_TRFIFOE|FCR_RESETRF|FCR_RESETTF;
__asm{ nop } STLCR &= ~LCR_DLAB; /* DLAB off */ STIER = IER_UUE | IER_RAVIE; /* enable UART, RX interrupt */
ICMR = 0xFFFFFFFF;
_bl_enable_irq();
}Below is the hexadecimal register values I print when a character is received(STLSR & LSR_DR). STIER=41, STLSR=21, STIIR=c4, ICIP=0, ICMR=ffffff80, ICPR=0 [ STIER=41 => 0x40:uart enabled, 0x01:Receiver Data Available Interrupt Enable. STLSR=21 => 0x20:Transmit FIFO has half or less than half data, 0x01:Data is available in RBR or the FIFO STIIR=c4 => 0xc0:FIFO mode is selected 0x04:Received Data Available ICIP=0 => IRQ Pending Register ICMR=FFFFFF80 ICPR=0 => no interrupt pending (why ?????????) ]
Below is the part I print above register values. (void)itoa(rcv_char, buffer, 16); serial_puts("\r\nc started, cpsr="); serial_puts(buffer); serial_puts(", STIER="); rcv_char = STIER; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer); serial_puts(", ICMR="); rcv_char = ICMR; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer); serial_puts("\r\n\n");
while(1) { if(STLSR & LSR_DR) { serial_puts("STIER="); rcv_char = STIER; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer);
serial_puts(", STLSR="); rcv_char = STLSR; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer);
serial_puts(", STIIR="); rcv_char = STIIR; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer);
serial_puts(", ICIP="); rcv_char = ICIP; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer);
serial_puts(", ICMR="); rcv_char = ICMR; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer);
serial_puts(", ICPR="); rcv_char = ICPR; (void)itoa(rcv_char, buffer, 16); serial_puts(buffer);
//serial_puts(", char="); //rcv_char = serial_tstc(); //serial_putc((char)rcv_char); serial_puts("\r\n"); rcv_char = STRBR; }
}The global interrupt in CPSR is enabled. And when I tested using OS timer, the coresponding interrupt was generated correctly.
Any help will be greatly appreciated. Thanks. Terry.