How to Initiate a UART Transmit empty interrupt? LPC1xxx

Okay, so my standard buffered UART library that I use for most of my microcontrollers buffers both transmit and receive data.

The logic for transmit usually goes:

  1. Dump Data into transmit ring buffer.

  2. If the transmit data empty interrupt isn’t enabled, enable it.

  3. ISR receives first transmit empty interrupt, sends next character in buffer.

  4. If the buffer is empty, ISR disables the transmit empty interrupt.

The problem is that on other controllers I’m using, enabling the transmit empty interrupt when it was previously disabled initiates an interrupt right away, since the transmit register is empty. This allows the ISR to take it from there. For the LPC1xxx, I do not get an interrupt when enabling it, so the ISR is never called and never has a chance to do its work. I’m not certain if this is just the way it works, or maybe I’ve set something up wrong. I have the interrupt set to interrupt for every character outputted rather than partial buffer writes.

The only thing I can think of to fix this is to actually put the first character into the transmit register, but this plays hell with the buffer logic, since I then need to check to see if the buffer currently is being worked on or not.

The LPC1xxx looks like it’s very similar to the LPC2xxx and every UART library I’ve found that uses buffered UART reads still uses polled writes.

On an LPC2xxx we implemented a buffered UART write like this:

During init, set up the ISR and enable the receiver and transmitter interrupts.

When writting,

  1. push the data to a cicular buffer (CB).

  2. Read the LSR to see if the TX UART FIFO is empty.

  3. If it is, pull the next byte from the CB

  4. Put byte into UART TX register.

  5. If the TX UART FIFO is not empty, do nothing further.

In the ISR is you have a TX empty condition, try to pull the next byte from the CB and put it into the TX register.

Must do all the above with careful attention to interrupt nesting, and interrupt disabling to prevent reentrant problems. Especially true in a multitasking environment where the CB must be protected as well.

Thanks, I’ve done some more investigation and yes, this looks like my only option. The LPC1xxx will not trigger an interrupt on enable only after an actual character has been sent. I need to check to see if the buffer is currently being processed, if not extract a character from the buffer and push it out to start the service routine.

I’m still doing single character writes, I’ll have to update this later to try and fill up the UART buffer properly.

most 16xxx-like UARTs generate an interrupt when the transmit register or FIFO “becomes” empty rather than “already is” empty.

The ARM7’s I used behave like that.

stevech:
most 16xxx-like UARTs generate an interrupt when the transmit register or FIFO “becomes” empty rather than “already is” empty.

The ARM7’s I used behave like that.

ARM7 is the core architecture and has nothing to do with the peripherals.

I’m assuming you were using the LPC’s. The ARM7’s I used didn’t behave like that, neither does any other uC I’ve used. Z8 Encore, AVR, MSP430, and AT91SAM7 all generate a TX interrupt when the interrupt is enabled, which makes it easier to do the interrupt processing since I just need to set everything up and enable the interrupt. If the TX buffer is currently being processed nothing changes and it continues to be processed. If it’s not being processed it starts off and the handler does the work. Now I need to do what is mentioned above: disable interrupts, make sure nothing is happening, cycle a character off of the buffer, enable interrupts, transmit a character. It’s not that big a deal, but it’s painful to add this code when I’ve never needed it before.

Sorry, I’m so NXP-centric.

Yes, LPC21xx