First a question, you say the interrupt is not being generated, how do you
know?
A few comments on the code below, probably more when I get a chance to
review it properly.
At 05:12 PM 10/8/04 +0000, you wrote:
>It was a small oversite that it wasn't posted. I was copying stuff
>out that I didn't need. Since then I've made another small project
>that just tests the UART. I am now trying non vector irqs, and they
>still don't work. Here is the correct code:
>
>
>#include <stdio.h>
>#include "../ArmCommon/types.h"
>#include "../ArmCommon/LPC22xx.h"
>#include "../ArmCommon/LPC2294.h"
>
>#define TX_BUFFER_LENGTH 64
>
>static Uint16 txBytes = 0;
>static Uint16 txRdPos = 0;
>static Uint16 txWrPos = 0;
>static Uint16 txBuffer[TX_BUFFER_LENGTH];
>
>void uart0_config (void);
>void uart0_isr (void);
>void uart0_sendByte (Uint8);
>int putchar(int);
>int main (void);
>
>void uart0_config (void) {
> // Setup UART 0
> U0LCR = 0x80; // Enable DLAB
> U0DLL = 0x36; // Setup BGR
> U0DLM = 0x00; // ~57.6 kbps @ 50 Mhz
> U0LCR = 0x03; // Enable UART 0, 8 bits, no parity, 1 stop bit
>
> // Reset the FIFOs
> U0FCR = 0xC7; // RX FIFO trigger level 8 chars, reset tx and rx fifo,
>enable fifos
>
> // Setup Interrupts for UART0
> VICIntSelect &= 0xFFFFBFFF; // Make sure 6 is IRQ not FIQ
> VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt
> VICDefVectAddr = (unsigned long) uart0_isr; // Use Non vectored irq
> U0IER = 0x7;
>}
>
>void uart0_isr (void) __irq {
> Uint8 dummy;
> switch(U0LSR) {
This is potentially a very big problem. The LSR can (and often will) have
multiple bits set, so you will almost always be taking the default case
even if THRE is set (thus my question above). Given that the default case
is echoing whatever is in U0RBR (BTW what is CTI?) I would expect almost
anything if no characters had been sent to the port. Change this before
trying anything else. Then put a pin toggle or something in so you know if
the interrupt routine is ever reached.
> case 0x01: // RDR
> break;
> case 0x02: // OE
> break;
> case 0x04: // PE
> break;
> case 0x08: // FE
> break;
> case 0x10: // BI
> break;
> case 0x20: // THRE
> if(txBytes != 0) {
> U0THR = txBuffer[txRdPos];
> txRdPos++;
> txRdPos = (txRdPos ==
> TX_BUFFER_LENGTH)?0:txRdPos;
> txBytes--;
> }
> break;
> case 0x40: // TEMT
> break;
> case 0x80: // FXFE
> break;
> default: // Must be CTI
> uart0_sendByte(U0RBR); // Echo back
This is potentially a problem. I haven't looked at in detail but you are
using the same buffer routine here as you are in the non-interrupt
code. The ground is very unstable here.
> }
> dummy = U0IIR; // read to clear IRQ
UOIIR is what you should be using to determine the interrupt source.
> dummy += 1; // keep compiler from optimizing dummy out
And if U0IIR is read and used you don't need this line. In fact if U0IIR
is declared volatile (as it should be) you only would need this line if the
compiler was buggy.
> VICVectAddr = 0;
>}
>
>void uart0_sendByte(Uint8 a) {
> // Wait until there is room in the buffer
> while(txBytes == TX_BUFFER_LENGTH);
> if(!(U0LSR&0x20)) { // Put it in the software buffer
> txBuffer[txWrPos] = a;
> txWrPos++;
> txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
> txBytes++;
> }
> else { // If the chip buffer is empty, put it there
> U0THR = a;
> }
>}
>
>int putchar(int a) {
> uart0_sendByte((int)a);
> return 0;
>}
>
>int main (void) {
> PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD;
> VPBDIV = 0x1;
> uart0_config();
> printf("piece of crap!");
> while(1);
>}
>
>The output of this is "pep" when I run it on hardware. The Keil
>simulator of course says it is fine.
There are multiple examples of working serial interrupt code around, some
in the files section and the newlib support on
http://www.aeolusdevelopment.com has some as well. Most are GNU based, but
the concepts and pitfalls are the same for all compilers.
Robert
" 'Freedom' has no meaning of itself. There are always restrictions,
be they legal, genetic, or physical. If you don't believe me, try to
chew a radio signal. "
Kelvin Throop, IIIMessage
Re: [lpc2000] Re: Problems w/ UART
2004-10-08 by Robert Adsett
Attachments
- No local attachments were found for this message.