EmbeddedRelated.com
Forums

Stuck with THRE interrupt on LPC2103

Started by TomW...@Freightliner.com July 11, 2007
I've been stuck on this for a few days now. I was using the UART tx in a polled fashion, but it was wasting too much processing time. So I'm trying to set up an interrupt for txing. Rx works fine for the record.
Basically what I have is whenever I want to print something using printf, I use putchar to put the data into a buffer. The THRE interrupt is supposed to fire to pull data out of the buffer and into the FIFO. But the THRE interrupt never fires. I've tried "priming the pump" and everything else I've seen on here. I've also checked to make sure that UART0_IER is being set when DLAB is 0.
Heres some pertinent snippets of my code:

int putchar (char c)
{
thcnt++;
if (tx_restart == 1) {
tx_restart = 0;
UART0_THR = c;
}
else {
tbuffer[tin] = c;
tin++;
if (tin >%5) {
tin = 0;
}
}
return c;
}

void com_initialize (void)
{
volatile char dummy;
__DISABLE_INTERRUPT();
SCB_PLLCFG = 0x03; // sets M to be 4 and P to be 1, sets CCLK to be about 59 MHz
SCB_PLLCON = 0x03; // enables PLL and sets PLL to be clock for microcontroller
SCB_PLLFEED = 0xAA; //
SCB_PLLFEED = 0x55;
GPIO_IOSET = 0x00FF0000; /* clear LEDs */
/*------------
Setup serial port registers.
------------*/
PCB_PINSEL0 = 0x55400005; /* Enable RxD0 and TxD0 and JTAG*/

VICVectAddr0 = (unsigned)sio_irq;
VICVectCntl0 = 0x20 | 6; /* UART0 Interrupt */
VICIntEnable |= 0x00000040; /* Enable UART0 Interrupt */
UART0_LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
UART0_IER = 0x00; /* Disable UART0 Interrupts */
UART0_FCR = 0x01; // enable fifos

UART0_DLL = 0x00000008; // &0x00ff; // sets UART
UART0_DLM = 0x00000008>>8; // ????
UART0_LCR = 0x03; // sets DLAB to 0
UART0_IER = 0x03; /* Enable UART1 RX and THRE Interrupts */
__ENABLE_INTERRUPT();
}

void sio_irq (void)
id = UART0_IIR;
VICVectAddr = 0;
if (id && 0x02)
{
if (tin != tout) {
UART0_THR = tbuffer[tout];
tout++;
tx_restart = 1;
if (tout >= 255) {
out = 0;
}
}
else {
tx_restart = 0;
}
The first bit is my putchar routine, the second is where I initialize the UART and the third is part of my irq.

Any ideas?

An Engineer's Guide to the LPC2100 Series

In your interrupt handler (sio_irq) you need to use a bit wise AND where you
check the id to see if there is a THR Interrupt. e.g.
if ( id & 0x02)

Obviously your UART interrupt is working if the RX works, but have you
checked to see if you get any interrupt after you write a byte to UART_THR?
-Chris

On 7/12/07, T...@freightliner.com wrote:
>
> I've been stuck on this for a few days now. I was using the UART tx in a
> polled fashion, but it was wasting too much processing time. So I'm trying
> to set up an interrupt for txing. Rx works fine for the record.
> Basically what I have is whenever I want to print something using printf,
> I use putchar to put the data into a buffer. The THRE interrupt is supposed
> to fire to pull data out of the buffer and into the FIFO. But the THRE
> interrupt never fires. I've tried "priming the pump" and everything else
> I've seen on here. I've also checked to make sure that UART0_IER is being
> set when DLAB is 0.
> Heres some pertinent snippets of my code:
>
> int putchar (char c)
> {
> thcnt++;
> if (tx_restart == 1) {
> tx_restart = 0;
> UART0_THR = c;
> }
> else {
> tbuffer[tin] = c;
> tin++;
> if (tin >%5) {
> tin = 0;
> }
> }
> return c;
> }
>
> void com_initialize (void)
> {
> volatile char dummy;
> __DISABLE_INTERRUPT();
> SCB_PLLCFG = 0x03; // sets M to be 4 and P to be 1, sets CCLK to be about
> 59 MHz
> SCB_PLLCON = 0x03; // enables PLL and sets PLL to be clock for
> microcontroller
> SCB_PLLFEED = 0xAA; //
> SCB_PLLFEED = 0x55;
> GPIO_IOSET = 0x00FF0000; /* clear LEDs */
> /*------------
> Setup serial port registers.
> ------------*/
> PCB_PINSEL0 = 0x55400005; /* Enable RxD0 and TxD0 and JTAG*/
>
> VICVectAddr0 = (unsigned)sio_irq;
> VICVectCntl0 = 0x20 | 6; /* UART0 Interrupt */
> VICIntEnable |= 0x00000040; /* Enable UART0 Interrupt */
> UART0_LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
> UART0_IER = 0x00; /* Disable UART0 Interrupts */
> UART0_FCR = 0x01; // enable fifos
>
> UART0_DLL = 0x00000008; // &0x00ff; // sets UART
> UART0_DLM = 0x00000008>>8; // ????
> UART0_LCR = 0x03; // sets DLAB to 0
> UART0_IER = 0x03; /* Enable UART1 RX and THRE Interrupts */
> __ENABLE_INTERRUPT();
> }
>
> void sio_irq (void)
> id = UART0_IIR;
> VICVectAddr = 0;
> if (id && 0x02)
> {
> if (tin != tout) {
> UART0_THR = tbuffer[tout];
> tout++;
> tx_restart = 1;
> if (tout >= 255) {
> out = 0;
> }
> }
> else {
> tx_restart = 0;
> }
>
> The first bit is my putchar routine, the second is where I initialize the
> UART and the third is part of my irq.
>
> Any ideas?
>
>