Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Problems w/ UART

Problems w/ UART

2004-10-07 by peterburdine

I think I may be missing something stupid, but can anyone help me?
I am tring to write to UART0, but it doesn't seem to work.  I am
trying to write a software buffer to help out the one byte hardware
buffer.  Specifically I am using the LPC 2294.  Below is my code.

I am using the Keil toolset (compiler/debugger/simulator).  The code
works perfectly fine when running it on the simulator, but when I try
to run it on the chip, I will only get "ho" instead of "hello".  I put
some break points in it when using JTAG to debug, but the ISR is never
called when running on the real hardware, it is called on the
simulator.  Also, when I debug on JTAG I never se the THRE or TEMT
clear.  Can you see anything obviously wrong?  I think I put in
everything that you need to compile it.

#include <stdio.h>
#define TX_BUFFER_LENGTH 64
#define UART0_THRE			(U0LSR & 0x20)
#define		PINSEL0_00_TxD		(0x01)
#define		PINSEL0_01_GPIO		(0x00 << 2)
#define U0RBR          (*((volatile unsigned char *) 0xE000C000))
#define U0THR          (*((volatile unsigned char *) 0xE000C000))
#define U0IER          (*((volatile unsigned char *) 0xE000C004))
#define U0IIR          (*((volatile unsigned char *) 0xE000C008))
#define U0FCR          (*((volatile unsigned char *) 0xE000C008))
#define U0LCR          (*((volatile unsigned char *) 0xE000C00C))
#define U0MCR          (*((volatile unsigned char *) 0xE000C010))
#define U0LSR          (*((volatile unsigned char *) 0xE000C014))
#define U0MSR          (*((volatile unsigned char *) 0xE000C018))
#define U0SCR          (*((volatile unsigned char *) 0xE000C01C))
#define U0DLL          (*((volatile unsigned char *) 0xE000C000))
#define U0DLM          (*((volatile unsigned char *) 0xE000C004))
#define VICVectAddr6   (*((volatile unsigned long *) 0xFFFFF118))
#define VICVectCntl6   (*((volatile unsigned long *) 0xFFFFF218))
#define VICIntSelect   (*((volatile unsigned long *) 0xFFFFF00C))
#define VICIntEnable   (*((volatile unsigned long *) 0xFFFFF010))
#define VICIntEnClr    (*((volatile unsigned long *) 0xFFFFF014))
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 = 0x16; // Setup BGR
	U0DLM = 0x05; // ~2400 Bit/s @ 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
	U0IER = 0x7;
	VICIntSelect &= 0x0;
	VICVectCntl6 = 0x20 | 6;
	VICVectAddr6 = (unsigned long) uart0_isr;
	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt	
}

void uart0_isr (void) __irq {
	switch((U0IIR>>1)&0x7) {
		// THRE
		case	001:
			if(txBytes != 0) {
				U0THR = txBuffer[txRdPos];
				txRdPos++;
				txRdPos = (txRdPos == TX_BUFFER_LENGTH)?0:txRdPos;
				txBytes--;
			}
			break;
	}
}

void uart0_sendByte(Uint8 byte) {
	// Wait until there is room in the buffer
	while(txBytes == TX_BUFFER_LENGTH);
	VICIntEnClr |= (1 << 6);
	if(!UART0_THRE) {  // Put it in the software buffer 
		txBuffer[txWrPos] = byte;
		txWrPos++;
		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
		txBytes++;
	}
	else { // If the chip buffer is empty, put it there
		U0THR = byte;	
	}
	VICIntEnable |= (1 << 6);
}

int putchar(int a) {
	uart0_sendByte((int)a);
}

int main (void) {
	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
	printf("hello");
}

Re: Problems w/ UART

2004-10-07 by Pete

In an interrupt service routine:
in order to exit it properly you must, Clear the interrupt flag that 
triggered it (write a 1 to the flag?) eg:
U0IIR 	= 0x0000000A;	//Clear the interrupt register

anyway, most importantly you also need to write to teh vector 
address register:
eg:
VICVectAddr 	= 0x00000000;//Dummy write to signal end of interrupt

failure to do these will lead to continuous interrupts.....


Does this help???

rgds
pete


--- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
wrote:
> 
> I think I may be missing something stupid, but can anyone help me?
> I am tring to write to UART0, but it doesn't seem to work.  I am
> trying to write a software buffer to help out the one byte hardware
> buffer.  Specifically I am using the LPC 2294.  Below is my code.
> 
> I am using the Keil toolset (compiler/debugger/simulator).  The 
code
> works perfectly fine when running it on the simulator, but when I 
try
> to run it on the chip, I will only get "ho" instead of "hello".  I 
put
> some break points in it when using JTAG to debug, but the ISR is 
never
> called when running on the real hardware, it is called on the
> simulator.  Also, when I debug on JTAG I never se the THRE or TEMT
> clear.  Can you see anything obviously wrong?  I think I put in
> everything that you need to compile it.
> 
> #include <stdio.h>
> #define TX_BUFFER_LENGTH 64
> #define UART0_THRE			(U0LSR & 0x20)
> #define		PINSEL0_00_TxD		(0x01)
> #define		PINSEL0_01_GPIO		(0x00 << 2)
> #define U0RBR          (*((volatile unsigned char *) 0xE000C000))
> #define U0THR          (*((volatile unsigned char *) 0xE000C000))
> #define U0IER          (*((volatile unsigned char *) 0xE000C004))
> #define U0IIR          (*((volatile unsigned char *) 0xE000C008))
> #define U0FCR          (*((volatile unsigned char *) 0xE000C008))
> #define U0LCR          (*((volatile unsigned char *) 0xE000C00C))
> #define U0MCR          (*((volatile unsigned char *) 0xE000C010))
> #define U0LSR          (*((volatile unsigned char *) 0xE000C014))
> #define U0MSR          (*((volatile unsigned char *) 0xE000C018))
> #define U0SCR          (*((volatile unsigned char *) 0xE000C01C))
> #define U0DLL          (*((volatile unsigned char *) 0xE000C000))
> #define U0DLM          (*((volatile unsigned char *) 0xE000C004))
> #define VICVectAddr6   (*((volatile unsigned long *) 0xFFFFF118))
> #define VICVectCntl6   (*((volatile unsigned long *) 0xFFFFF218))
> #define VICIntSelect   (*((volatile unsigned long *) 0xFFFFF00C))
> #define VICIntEnable   (*((volatile unsigned long *) 0xFFFFF010))
> #define VICIntEnClr    (*((volatile unsigned long *) 0xFFFFF014))
> 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 = 0x16; // Setup BGR
> 	U0DLM = 0x05; // ~2400 Bit/s @ 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
> 	U0IER = 0x7;
> 	VICIntSelect &= 0x0;
> 	VICVectCntl6 = 0x20 | 6;
> 	VICVectAddr6 = (unsigned long) uart0_isr;
> 	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt	
> }
> 
> void uart0_isr (void) __irq {
> 	switch((U0IIR>>1)&0x7) {
> 		// THRE
> 		case	001:
> 			if(txBytes != 0) {
> 				U0THR = txBuffer[txRdPos];
> 				txRdPos++;
> 				txRdPos = (txRdPos == 
TX_BUFFER_LENGTH)?0:txRdPos;
Show quoted textHide quoted text
> 				txBytes--;
> 			}
> 			break;
> 	}
> }
> 
> void uart0_sendByte(Uint8 byte) {
> 	// Wait until there is room in the buffer
> 	while(txBytes == TX_BUFFER_LENGTH);
> 	VICIntEnClr |= (1 << 6);
> 	if(!UART0_THRE) {  // Put it in the software buffer 
> 		txBuffer[txWrPos] = byte;
> 		txWrPos++;
> 		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
> 		txBytes++;
> 	}
> 	else { // If the chip buffer is empty, put it there
> 		U0THR = byte;	
> 	}
> 	VICIntEnable |= (1 << 6);
> }
> 
> int putchar(int a) {
> 	uart0_sendByte((int)a);
> }
> 
> int main (void) {
> 	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
> 	printf("hello");
> }

Re: [lpc2000] Re: Problems w/ UART

2004-10-07 by Robert Adsett

At 06:07 PM 10/7/04 +0000, you wrote:
>In an interrupt service routine:
>in order to exit it properly you must, Clear the interrupt flag that
>triggered it (write a 1 to the flag?) eg:
>U0IIR   = 0x0000000A;   //Clear the interrupt register

Actually, just reading IIR does that for the UART.  But as you point out 
you still need the write to VICVectAddr.

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, III

Re: Problems w/ UART

2004-10-07 by peterburdine

I am sure the might help, if the ISR was called in the first place. 
But it isn't.
Also, according to the user manual I have,, it states that only U0IIR
must be accessed to clear the IRQ (for TXRE anyways).

--Peter

--- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> wrote:
Show quoted textHide quoted text
> 
> In an interrupt service routine:
> in order to exit it properly you must, Clear the interrupt flag that 
> triggered it (write a 1 to the flag?) eg:
> U0IIR 	= 0x0000000A;	//Clear the interrupt register
> 
> anyway, most importantly you also need to write to teh vector 
> address register:
> eg:
> VICVectAddr 	= 0x00000000;//Dummy write to signal end of interrupt
> 
> failure to do these will lead to continuous interrupts.....
> 
> 
> Does this help???
> 
> rgds
> pete
> 
> 
> --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> wrote:
> > 
> > I think I may be missing something stupid, but can anyone help me?
> > I am tring to write to UART0, but it doesn't seem to work.  I am
> > trying to write a software buffer to help out the one byte hardware
> > buffer.  Specifically I am using the LPC 2294.  Below is my code.
> > 
> > I am using the Keil toolset (compiler/debugger/simulator).  The 
> code
> > works perfectly fine when running it on the simulator, but when I 
> try
> > to run it on the chip, I will only get "ho" instead of "hello".  I 
> put
> > some break points in it when using JTAG to debug, but the ISR is 
> never
> > called when running on the real hardware, it is called on the
> > simulator.  Also, when I debug on JTAG I never se the THRE or TEMT
> > clear.  Can you see anything obviously wrong?  I think I put in
> > everything that you need to compile it.
> > 
> > #include <stdio.h>
> > #define TX_BUFFER_LENGTH 64
> > #define UART0_THRE			(U0LSR & 0x20)
> > #define		PINSEL0_00_TxD		(0x01)
> > #define		PINSEL0_01_GPIO		(0x00 << 2)
> > #define U0RBR          (*((volatile unsigned char *) 0xE000C000))
> > #define U0THR          (*((volatile unsigned char *) 0xE000C000))
> > #define U0IER          (*((volatile unsigned char *) 0xE000C004))
> > #define U0IIR          (*((volatile unsigned char *) 0xE000C008))
> > #define U0FCR          (*((volatile unsigned char *) 0xE000C008))
> > #define U0LCR          (*((volatile unsigned char *) 0xE000C00C))
> > #define U0MCR          (*((volatile unsigned char *) 0xE000C010))
> > #define U0LSR          (*((volatile unsigned char *) 0xE000C014))
> > #define U0MSR          (*((volatile unsigned char *) 0xE000C018))
> > #define U0SCR          (*((volatile unsigned char *) 0xE000C01C))
> > #define U0DLL          (*((volatile unsigned char *) 0xE000C000))
> > #define U0DLM          (*((volatile unsigned char *) 0xE000C004))
> > #define VICVectAddr6   (*((volatile unsigned long *) 0xFFFFF118))
> > #define VICVectCntl6   (*((volatile unsigned long *) 0xFFFFF218))
> > #define VICIntSelect   (*((volatile unsigned long *) 0xFFFFF00C))
> > #define VICIntEnable   (*((volatile unsigned long *) 0xFFFFF010))
> > #define VICIntEnClr    (*((volatile unsigned long *) 0xFFFFF014))
> > 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 = 0x16; // Setup BGR
> > 	U0DLM = 0x05; // ~2400 Bit/s @ 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
> > 	U0IER = 0x7;
> > 	VICIntSelect &= 0x0;
> > 	VICVectCntl6 = 0x20 | 6;
> > 	VICVectAddr6 = (unsigned long) uart0_isr;
> > 	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt	
> > }
> > 
> > void uart0_isr (void) __irq {
> > 	switch((U0IIR>>1)&0x7) {
> > 		// THRE
> > 		case	001:
> > 			if(txBytes != 0) {
> > 				U0THR = txBuffer[txRdPos];
> > 				txRdPos++;
> > 				txRdPos = (txRdPos == 
> TX_BUFFER_LENGTH)?0:txRdPos;
> > 				txBytes--;
> > 			}
> > 			break;
> > 	}
> > }
> > 
> > void uart0_sendByte(Uint8 byte) {
> > 	// Wait until there is room in the buffer
> > 	while(txBytes == TX_BUFFER_LENGTH);
> > 	VICIntEnClr |= (1 << 6);
> > 	if(!UART0_THRE) {  // Put it in the software buffer 
> > 		txBuffer[txWrPos] = byte;
> > 		txWrPos++;
> > 		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
> > 		txBytes++;
> > 	}
> > 	else { // If the chip buffer is empty, put it there
> > 		U0THR = byte;	
> > 	}
> > 	VICIntEnable |= (1 << 6);
> > }
> > 
> > int putchar(int a) {
> > 	uart0_sendByte((int)a);
> > }
> > 
> > int main (void) {
> > 	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
> > 	printf("hello");
> > }

Re: Problems w/ UART

2004-10-07 by Pete

peter

i think also that you need to initialise the isr function 
differently...
something like this:
void uart0_isr(void) __attribute__ ((interrupt("IRQ")));

rather than:
void uart0_isr (void);

see the user manual section on interrupt handling....

also, add the:
 VICVectAddr = 0;//Dummy write to signal end of interrupt

to the end of the isr...
does this help?

kind regards
Pete


--- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
wrote:
> 
> I am sure the might help, if the ISR was called in the first 
place. 
> But it isn't.
> Also, according to the user manual I have,, it states that only 
U0IIR
> must be accessed to clear the IRQ (for TXRE anyways).
> 
> --Peter
> 
> --- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> 
wrote:
> > 
> > In an interrupt service routine:
> > in order to exit it properly you must, Clear the interrupt flag 
that 
> > triggered it (write a 1 to the flag?) eg:
> > U0IIR 	= 0x0000000A;	//Clear the interrupt register
> > 
> > anyway, most importantly you also need to write to teh vector 
> > address register:
> > eg:
> > VICVectAddr 	= 0x00000000;//Dummy write to signal end of 
interrupt
> > 
> > failure to do these will lead to continuous interrupts.....
> > 
> > 
> > Does this help???
> > 
> > rgds
> > pete
> > 
> > 
> > --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> > wrote:
> > > 
> > > I think I may be missing something stupid, but can anyone help 
me?
> > > I am tring to write to UART0, but it doesn't seem to work.  I 
am
> > > trying to write a software buffer to help out the one byte 
hardware
> > > buffer.  Specifically I am using the LPC 2294.  Below is my 
code.
> > > 
> > > I am using the Keil toolset (compiler/debugger/simulator).  
The 
> > code
> > > works perfectly fine when running it on the simulator, but 
when I 
> > try
> > > to run it on the chip, I will only get "ho" instead 
of "hello".  I 
> > put
> > > some break points in it when using JTAG to debug, but the ISR 
is 
> > never
> > > called when running on the real hardware, it is called on the
> > > simulator.  Also, when I debug on JTAG I never se the THRE or 
TEMT
> > > clear.  Can you see anything obviously wrong?  I think I put in
> > > everything that you need to compile it.
> > > 
> > > #include <stdio.h>
> > > #define TX_BUFFER_LENGTH 64
> > > #define UART0_THRE			(U0LSR & 0x20)
> > > #define		PINSEL0_00_TxD		(0x01)
> > > #define		PINSEL0_01_GPIO		(0x00 << 2)
> > > #define U0RBR          (*((volatile unsigned char *) 
0xE000C000))
> > > #define U0THR          (*((volatile unsigned char *) 
0xE000C000))
> > > #define U0IER          (*((volatile unsigned char *) 
0xE000C004))
> > > #define U0IIR          (*((volatile unsigned char *) 
0xE000C008))
> > > #define U0FCR          (*((volatile unsigned char *) 
0xE000C008))
> > > #define U0LCR          (*((volatile unsigned char *) 
0xE000C00C))
> > > #define U0MCR          (*((volatile unsigned char *) 
0xE000C010))
> > > #define U0LSR          (*((volatile unsigned char *) 
0xE000C014))
> > > #define U0MSR          (*((volatile unsigned char *) 
0xE000C018))
> > > #define U0SCR          (*((volatile unsigned char *) 
0xE000C01C))
> > > #define U0DLL          (*((volatile unsigned char *) 
0xE000C000))
> > > #define U0DLM          (*((volatile unsigned char *) 
0xE000C004))
> > > #define VICVectAddr6   (*((volatile unsigned long *) 
0xFFFFF118))
> > > #define VICVectCntl6   (*((volatile unsigned long *) 
0xFFFFF218))
> > > #define VICIntSelect   (*((volatile unsigned long *) 
0xFFFFF00C))
> > > #define VICIntEnable   (*((volatile unsigned long *) 
0xFFFFF010))
> > > #define VICIntEnClr    (*((volatile unsigned long *) 
0xFFFFF014))
Show quoted textHide quoted text
> > > 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 = 0x16; // Setup BGR
> > > 	U0DLM = 0x05; // ~2400 Bit/s @ 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
> > > 	U0IER = 0x7;
> > > 	VICIntSelect &= 0x0;
> > > 	VICVectCntl6 = 0x20 | 6;
> > > 	VICVectAddr6 = (unsigned long) uart0_isr;
> > > 	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt	
> > > }
> > > 
> > > void uart0_isr (void) __irq {
> > > 	switch((U0IIR>>1)&0x7) {
> > > 		// THRE
> > > 		case	001:
> > > 			if(txBytes != 0) {
> > > 				U0THR = txBuffer[txRdPos];
> > > 				txRdPos++;
> > > 				txRdPos = (txRdPos == 
> > TX_BUFFER_LENGTH)?0:txRdPos;
> > > 				txBytes--;
> > > 			}
> > > 			break;
> > > 	}
> > > }
> > > 
> > > void uart0_sendByte(Uint8 byte) {
> > > 	// Wait until there is room in the buffer
> > > 	while(txBytes == TX_BUFFER_LENGTH);
> > > 	VICIntEnClr |= (1 << 6);
> > > 	if(!UART0_THRE) {  // Put it in the software buffer 
> > > 		txBuffer[txWrPos] = byte;
> > > 		txWrPos++;
> > > 		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
> > > 		txBytes++;
> > > 	}
> > > 	else { // If the chip buffer is empty, put it there
> > > 		U0THR = byte;	
> > > 	}
> > > 	VICIntEnable |= (1 << 6);
> > > }
> > > 
> > > int putchar(int a) {
> > > 	uart0_sendByte((int)a);
> > > }
> > > 
> > > int main (void) {
> > > 	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
> > > 	printf("hello");
> > > }

Re: Problems w/ UART

2004-10-08 by peterburdine

Pete,

The Keil's compilier does not require such initialization.  I have a
timer isr that works just fine being declared as

void timer_isr (void);

void timer_isr (void) __irq {....}

I do now have the VicVectAddr = 0;, but that doesn't help if it
doesn't get called.

--Peter

--- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> wrote:
Show quoted textHide quoted text
> 
> peter
> 
> i think also that you need to initialise the isr function 
> differently...
> something like this:
> void uart0_isr(void) __attribute__ ((interrupt("IRQ")));
> 
> rather than:
> void uart0_isr (void);
> 
> see the user manual section on interrupt handling....
> 
> also, add the:
>  VICVectAddr = 0;//Dummy write to signal end of interrupt
> 
> to the end of the isr...
> does this help?
> 
> kind regards
> Pete
> 
> 
> --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> wrote:
> > 
> > I am sure the might help, if the ISR was called in the first 
> place. 
> > But it isn't.
> > Also, according to the user manual I have,, it states that only 
> U0IIR
> > must be accessed to clear the IRQ (for TXRE anyways).
> > 
> > --Peter
> > 
> > --- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> 
> wrote:
> > > 
> > > In an interrupt service routine:
> > > in order to exit it properly you must, Clear the interrupt flag 
> that 
> > > triggered it (write a 1 to the flag?) eg:
> > > U0IIR 	= 0x0000000A;	//Clear the interrupt register
> > > 
> > > anyway, most importantly you also need to write to teh vector 
> > > address register:
> > > eg:
> > > VICVectAddr 	= 0x00000000;//Dummy write to signal end of 
> interrupt
> > > 
> > > failure to do these will lead to continuous interrupts.....
> > > 
> > > 
> > > Does this help???
> > > 
> > > rgds
> > > pete
> > > 
> > > 
> > > --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> > > wrote:
> > > > 
> > > > I think I may be missing something stupid, but can anyone help 
> me?
> > > > I am tring to write to UART0, but it doesn't seem to work.  I 
> am
> > > > trying to write a software buffer to help out the one byte 
> hardware
> > > > buffer.  Specifically I am using the LPC 2294.  Below is my 
> code.
> > > > 
> > > > I am using the Keil toolset (compiler/debugger/simulator).  
> The 
> > > code
> > > > works perfectly fine when running it on the simulator, but 
> when I 
> > > try
> > > > to run it on the chip, I will only get "ho" instead 
> of "hello".  I 
> > > put
> > > > some break points in it when using JTAG to debug, but the ISR 
> is 
> > > never
> > > > called when running on the real hardware, it is called on the
> > > > simulator.  Also, when I debug on JTAG I never se the THRE or 
> TEMT
> > > > clear.  Can you see anything obviously wrong?  I think I put in
> > > > everything that you need to compile it.
> > > > 
> > > > #include <stdio.h>
> > > > #define TX_BUFFER_LENGTH 64
> > > > #define UART0_THRE			(U0LSR & 0x20)
> > > > #define		PINSEL0_00_TxD		(0x01)
> > > > #define		PINSEL0_01_GPIO		(0x00 << 2)
> > > > #define U0RBR          (*((volatile unsigned char *) 
> 0xE000C000))
> > > > #define U0THR          (*((volatile unsigned char *) 
> 0xE000C000))
> > > > #define U0IER          (*((volatile unsigned char *) 
> 0xE000C004))
> > > > #define U0IIR          (*((volatile unsigned char *) 
> 0xE000C008))
> > > > #define U0FCR          (*((volatile unsigned char *) 
> 0xE000C008))
> > > > #define U0LCR          (*((volatile unsigned char *) 
> 0xE000C00C))
> > > > #define U0MCR          (*((volatile unsigned char *) 
> 0xE000C010))
> > > > #define U0LSR          (*((volatile unsigned char *) 
> 0xE000C014))
> > > > #define U0MSR          (*((volatile unsigned char *) 
> 0xE000C018))
> > > > #define U0SCR          (*((volatile unsigned char *) 
> 0xE000C01C))
> > > > #define U0DLL          (*((volatile unsigned char *) 
> 0xE000C000))
> > > > #define U0DLM          (*((volatile unsigned char *) 
> 0xE000C004))
> > > > #define VICVectAddr6   (*((volatile unsigned long *) 
> 0xFFFFF118))
> > > > #define VICVectCntl6   (*((volatile unsigned long *) 
> 0xFFFFF218))
> > > > #define VICIntSelect   (*((volatile unsigned long *) 
> 0xFFFFF00C))
> > > > #define VICIntEnable   (*((volatile unsigned long *) 
> 0xFFFFF010))
> > > > #define VICIntEnClr    (*((volatile unsigned long *) 
> 0xFFFFF014))
> > > > 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 = 0x16; // Setup BGR
> > > > 	U0DLM = 0x05; // ~2400 Bit/s @ 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
> > > > 	U0IER = 0x7;
> > > > 	VICIntSelect &= 0x0;
> > > > 	VICVectCntl6 = 0x20 | 6;
> > > > 	VICVectAddr6 = (unsigned long) uart0_isr;
> > > > 	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt	
> > > > }
> > > > 
> > > > void uart0_isr (void) __irq {
> > > > 	switch((U0IIR>>1)&0x7) {
> > > > 		// THRE
> > > > 		case	001:
> > > > 			if(txBytes != 0) {
> > > > 				U0THR = txBuffer[txRdPos];
> > > > 				txRdPos++;
> > > > 				txRdPos = (txRdPos == 
> > > TX_BUFFER_LENGTH)?0:txRdPos;
> > > > 				txBytes--;
> > > > 			}
> > > > 			break;
> > > > 	}
> > > > }
> > > > 
> > > > void uart0_sendByte(Uint8 byte) {
> > > > 	// Wait until there is room in the buffer
> > > > 	while(txBytes == TX_BUFFER_LENGTH);
> > > > 	VICIntEnClr |= (1 << 6);
> > > > 	if(!UART0_THRE) {  // Put it in the software buffer 
> > > > 		txBuffer[txWrPos] = byte;
> > > > 		txWrPos++;
> > > > 		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
> > > > 		txBytes++;
> > > > 	}
> > > > 	else { // If the chip buffer is empty, put it there
> > > > 		U0THR = byte;	
> > > > 	}
> > > > 	VICIntEnable |= (1 << 6);
> > > > }
> > > > 
> > > > int putchar(int a) {
> > > > 	uart0_sendByte((int)a);
> > > > }
> > > > 
> > > > int main (void) {
> > > > 	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
> > > > 	printf("hello");
> > > > }

Re: [lpc2000] Re: Problems w/ UART

2004-10-08 by Robert Adsett

At 02:33 PM 10/8/04 +0000, you wrote:
>I do now have the VicVectAddr = 0;, but that doesn't help if it
>doesn't get called.

Speaking of which, I just reviewed your code.  You don't appear to be 
actually calling your uart initialization code anywhere (I don't see how 
you would get your baud rate right if you hadn't but...).  Also you should 
probably disable interrupts before disabling a specific interrupt via 
VICIntEnClr

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, III

Re: Problems w/ UART

2004-10-08 by Pete

Hi Peter
Interesting to hear this as I too am using Keil, but wasnt aware 
that you could do this! 

For my info, how do you tell Keil that you want the interrupt to be 
a Fast interrupt rather than the normal type?

sorry i didnt help fix the problem, and hope someone else can help u 
out.
rgds
pete

--- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
wrote:
> 
> Pete,
> 
> The Keil's compilier does not require such initialization.  I have 
a
> timer isr that works just fine being declared as
> 
> void timer_isr (void);
> 
> void timer_isr (void) __irq {....}
> 
> I do now have the VicVectAddr = 0;, but that doesn't help if it
> doesn't get called.
> 
> --Peter
> 
> --- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> 
wrote:
> > 
> > peter
> > 
> > i think also that you need to initialise the isr function 
> > differently...
> > something like this:
> > void uart0_isr(void) __attribute__ ((interrupt("IRQ")));
> > 
> > rather than:
> > void uart0_isr (void);
> > 
> > see the user manual section on interrupt handling....
> > 
> > also, add the:
> >  VICVectAddr = 0;//Dummy write to signal end of interrupt
> > 
> > to the end of the isr...
> > does this help?
> > 
> > kind regards
> > Pete
> > 
> > 
> > --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> > wrote:
> > > 
> > > I am sure the might help, if the ISR was called in the first 
> > place. 
> > > But it isn't.
> > > Also, according to the user manual I have,, it states that 
only 
> > U0IIR
> > > must be accessed to clear the IRQ (for TXRE anyways).
> > > 
> > > --Peter
> > > 
> > > --- In lpc2000@yahoogroups.com, "Pete" 
<peterbrown_abroad@y...> 
> > wrote:
> > > > 
> > > > In an interrupt service routine:
> > > > in order to exit it properly you must, Clear the interrupt 
flag 
> > that 
> > > > triggered it (write a 1 to the flag?) eg:
> > > > U0IIR 	= 0x0000000A;	//Clear the interrupt register
> > > > 
> > > > anyway, most importantly you also need to write to teh 
vector 
> > > > address register:
> > > > eg:
> > > > VICVectAddr 	= 0x00000000;//Dummy write to signal end of 
> > interrupt
> > > > 
> > > > failure to do these will lead to continuous interrupts.....
> > > > 
> > > > 
> > > > Does this help???
> > > > 
> > > > rgds
> > > > pete
> > > > 
> > > > 
> > > > --- In lpc2000@yahoogroups.com, "peterburdine" 
<lordofdawn@h...> 
> > > > wrote:
> > > > > 
> > > > > I think I may be missing something stupid, but can anyone 
help 
> > me?
> > > > > I am tring to write to UART0, but it doesn't seem to 
work.  I 
> > am
> > > > > trying to write a software buffer to help out the one byte 
> > hardware
> > > > > buffer.  Specifically I am using the LPC 2294.  Below is 
my 
> > code.
> > > > > 
> > > > > I am using the Keil toolset 
(compiler/debugger/simulator).  
> > The 
> > > > code
> > > > > works perfectly fine when running it on the simulator, but 
> > when I 
> > > > try
> > > > > to run it on the chip, I will only get "ho" instead 
> > of "hello".  I 
> > > > put
> > > > > some break points in it when using JTAG to debug, but the 
ISR 
> > is 
> > > > never
> > > > > called when running on the real hardware, it is called on 
the
> > > > > simulator.  Also, when I debug on JTAG I never se the THRE 
or 
> > TEMT
> > > > > clear.  Can you see anything obviously wrong?  I think I 
put in
> > > > > everything that you need to compile it.
> > > > > 
> > > > > #include <stdio.h>
> > > > > #define TX_BUFFER_LENGTH 64
> > > > > #define UART0_THRE			(U0LSR & 0x20)
> > > > > #define		PINSEL0_00_TxD		(0x01)
> > > > > #define		PINSEL0_01_GPIO		(0x00 << 2)
> > > > > #define U0RBR          (*((volatile unsigned char *) 
> > 0xE000C000))
> > > > > #define U0THR          (*((volatile unsigned char *) 
> > 0xE000C000))
> > > > > #define U0IER          (*((volatile unsigned char *) 
> > 0xE000C004))
> > > > > #define U0IIR          (*((volatile unsigned char *) 
> > 0xE000C008))
> > > > > #define U0FCR          (*((volatile unsigned char *) 
> > 0xE000C008))
> > > > > #define U0LCR          (*((volatile unsigned char *) 
> > 0xE000C00C))
> > > > > #define U0MCR          (*((volatile unsigned char *) 
> > 0xE000C010))
> > > > > #define U0LSR          (*((volatile unsigned char *) 
> > 0xE000C014))
> > > > > #define U0MSR          (*((volatile unsigned char *) 
> > 0xE000C018))
> > > > > #define U0SCR          (*((volatile unsigned char *) 
> > 0xE000C01C))
> > > > > #define U0DLL          (*((volatile unsigned char *) 
> > 0xE000C000))
> > > > > #define U0DLM          (*((volatile unsigned char *) 
> > 0xE000C004))
> > > > > #define VICVectAddr6   (*((volatile unsigned long *) 
> > 0xFFFFF118))
> > > > > #define VICVectCntl6   (*((volatile unsigned long *) 
> > 0xFFFFF218))
> > > > > #define VICIntSelect   (*((volatile unsigned long *) 
> > 0xFFFFF00C))
> > > > > #define VICIntEnable   (*((volatile unsigned long *) 
> > 0xFFFFF010))
> > > > > #define VICIntEnClr    (*((volatile unsigned long *) 
> > 0xFFFFF014))
> > > > > 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 = 0x16; // Setup BGR
> > > > > 	U0DLM = 0x05; // ~2400 Bit/s @ 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
> > > > > 	U0IER = 0x7;
> > > > > 	VICIntSelect &= 0x0;
> > > > > 	VICVectCntl6 = 0x20 | 6;
> > > > > 	VICVectAddr6 = (unsigned long) uart0_isr;
> > > > > 	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt
	
> > > > > }
> > > > > 
> > > > > void uart0_isr (void) __irq {
> > > > > 	switch((U0IIR>>1)&0x7) {
> > > > > 		// THRE
> > > > > 		case	001:
> > > > > 			if(txBytes != 0) {
> > > > > 				U0THR = txBuffer[txRdPos];
> > > > > 				txRdPos++;
> > > > > 				txRdPos = (txRdPos == 
> > > > TX_BUFFER_LENGTH)?0:txRdPos;
> > > > > 				txBytes--;
> > > > > 			}
> > > > > 			break;
> > > > > 	}
> > > > > }
> > > > > 
> > > > > void uart0_sendByte(Uint8 byte) {
> > > > > 	// Wait until there is room in the buffer
> > > > > 	while(txBytes == TX_BUFFER_LENGTH);
> > > > > 	VICIntEnClr |= (1 << 6);
> > > > > 	if(!UART0_THRE) {  // Put it in the software buffer 
> > > > > 		txBuffer[txWrPos] = byte;
> > > > > 		txWrPos++;
> > > > > 		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?
0:txWrPos;
Show quoted textHide quoted text
> > > > > 		txBytes++;
> > > > > 	}
> > > > > 	else { // If the chip buffer is empty, put it there
> > > > > 		U0THR = byte;	
> > > > > 	}
> > > > > 	VICIntEnable |= (1 << 6);
> > > > > }
> > > > > 
> > > > > int putchar(int a) {
> > > > > 	uart0_sendByte((int)a);
> > > > > }
> > > > > 
> > > > > int main (void) {
> > > > > 	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
> > > > > 	printf("hello");
> > > > > }

Re: Problems w/ UART

2004-10-08 by peterburdine

Use __fiq instead of __irq.

From Keil help:

Fast Interrupt Functions (__fiq)
Fast Interrupt Functions can be directly defined using the __fiq
function attribute:

void funcname (void)  __fiq
Where

funcname
 is the name of the function. 
__fiq
 indicates the function as fast interrupt function. 

The __fiq attribute affects the generated code of the function as follows:

The function is generated using ARM instructions, even when the THUMB
directive is specified. 
On function entry the registers R0 - R7 (when modified) are saved on
the stack. 
When exiting the function all register contents saved on the stack are
restored. 
The instruction SUBS PC,R14,#4 is used to return from the __fiq function. 
The ARM device jumps to the __fiq vector location (some ARM devices
provide an Vectored Interrupt Controller that supports also fiq
interrupts). By default, the CPU startup code (STARTUP.S) jumps to the
function FIQ_Handler. When the __fiq function in the application code
is named FIQ_Handler no modification to the STARTUP.S file is required.

The following sample program shows how to use the __fiq attribute. The
code sequences generated are shown in the Assembler Listing section.

stmt  level    source

   1          /*
   2           *  IRQ Handler for ADuC7000 Timer0 Interrupt
   3           */
   4          
   5          #include <ADuC7024.H>
   6          
   7          volatile int T0_ticks;
   8          
   9          void IRQ_Handler (void)  __fiq  {
  10   1        if (IRQSIG & 0x00000004)  {   // Timer0 Interrupt
  11   2          T0CLRI = 1;
  12   2          T0_ticks++;
  13   2        }
  14   1      }

ASSEMBLY LISTING OF GENERATED OBJECT CODE

*** PUBLICS:
 PUBLIC         IRQ_Handler?A
 PUBLIC         T0_ticks



*** DATA SEGMENT '?DT0?irq':
 00000000          T0_ticks:
 00000000            DS          4



*** CODE SEGMENT '?PR?IRQ_Handler?A?irq':
    9: void IRQ_Handler (void)  __irq  {
 00000000  E92D0003  STMDB       R13!,{R0-R1}
   10:   if (IRQSIG & 0x00000004)  {   // Timer0 Interrupt
 00000004  E5100000  LDR         R0,=0xFFFF0004
 00000008  E5900000  LDR         R0,[R0,#0x0]
 0000000C  E3A01004  MOV         R1,#0x4
 00000010  E1100001  TST         R0,R1
 00000014  0A000006  BEQ         L_1  ; Targ=0x34
   11:     T0CLRI = 1;
 00000018  E3A01001  MOV         R1,#0x1
 0000001C  E5100000  LDR         R0,=0xFFFF030C
 00000020  E5801000  STR         R1,[R0,#0x0]
   12:     T0_ticks++;
 00000024  E5100000  LDR         R0,=T0_ticks ; T0_ticks
 00000028  E5901000  LDR         R1,[R0,#0x0] ; T0_ticks
 0000002C  E2811001  ADD         R1,R1,#0x0001
 00000030  E5801000  STR         R1,[R0,#0x0] ; T0_ticks
   13:   }
 00000034          L_1:
 00000034  E8BD0003  LDMIA       R13!,{R0-R1}
 00000038  E25EF004  SUBS        R15,R14,#0x0004
 0000003C          ENDP ; 'IRQ_Handler?A'
 Note

The __fiq attribute is not allowed when declaring or prototyping
external functions. For example, the following function prototype is
invalid: 
extern void func (void) __fiq;
Passing parameters to interrupt function is not possible. Any attempt
to define an interrupt function with arguments generates an error
message. 
Interrupt function declarations may not include a return value. They
must be declared with a void return type. The compiler generates an
error message if an attempt to define a return value for the interrupt
function is made. 
The run-time library of the CARM Compiler contains a default
FIQ_Handler that generates an end-less loop using the instruction B $. 



--- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> wrote:
Show quoted textHide quoted text
> 
> Hi Peter
> Interesting to hear this as I too am using Keil, but wasnt aware 
> that you could do this! 
> 
> For my info, how do you tell Keil that you want the interrupt to be 
> a Fast interrupt rather than the normal type?
> 
> sorry i didnt help fix the problem, and hope someone else can help u 
> out.
> rgds
> pete
> 
> --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> wrote:
> > 
> > Pete,
> > 
> > The Keil's compilier does not require such initialization.  I have 
> a
> > timer isr that works just fine being declared as
> > 
> > void timer_isr (void);
> > 
> > void timer_isr (void) __irq {....}
> > 
> > I do now have the VicVectAddr = 0;, but that doesn't help if it
> > doesn't get called.
> > 
> > --Peter
> > 
> > --- In lpc2000@yahoogroups.com, "Pete" <peterbrown_abroad@y...> 
> wrote:
> > > 
> > > peter
> > > 
> > > i think also that you need to initialise the isr function 
> > > differently...
> > > something like this:
> > > void uart0_isr(void) __attribute__ ((interrupt("IRQ")));
> > > 
> > > rather than:
> > > void uart0_isr (void);
> > > 
> > > see the user manual section on interrupt handling....
> > > 
> > > also, add the:
> > >  VICVectAddr = 0;//Dummy write to signal end of interrupt
> > > 
> > > to the end of the isr...
> > > does this help?
> > > 
> > > kind regards
> > > Pete
> > > 
> > > 
> > > --- In lpc2000@yahoogroups.com, "peterburdine" <lordofdawn@h...> 
> > > wrote:
> > > > 
> > > > I am sure the might help, if the ISR was called in the first 
> > > place. 
> > > > But it isn't.
> > > > Also, according to the user manual I have,, it states that 
> only 
> > > U0IIR
> > > > must be accessed to clear the IRQ (for TXRE anyways).
> > > > 
> > > > --Peter
> > > > 
> > > > --- In lpc2000@yahoogroups.com, "Pete" 
> <peterbrown_abroad@y...> 
> > > wrote:
> > > > > 
> > > > > In an interrupt service routine:
> > > > > in order to exit it properly you must, Clear the interrupt 
> flag 
> > > that 
> > > > > triggered it (write a 1 to the flag?) eg:
> > > > > U0IIR 	= 0x0000000A;	//Clear the interrupt register
> > > > > 
> > > > > anyway, most importantly you also need to write to teh 
> vector 
> > > > > address register:
> > > > > eg:
> > > > > VICVectAddr 	= 0x00000000;//Dummy write to signal end of 
> > > interrupt
> > > > > 
> > > > > failure to do these will lead to continuous interrupts.....
> > > > > 
> > > > > 
> > > > > Does this help???
> > > > > 
> > > > > rgds
> > > > > pete
> > > > > 
> > > > > 
> > > > > --- In lpc2000@yahoogroups.com, "peterburdine" 
> <lordofdawn@h...> 
> > > > > wrote:
> > > > > > 
> > > > > > I think I may be missing something stupid, but can anyone 
> help 
> > > me?
> > > > > > I am tring to write to UART0, but it doesn't seem to 
> work.  I 
> > > am
> > > > > > trying to write a software buffer to help out the one byte 
> > > hardware
> > > > > > buffer.  Specifically I am using the LPC 2294.  Below is 
> my 
> > > code.
> > > > > > 
> > > > > > I am using the Keil toolset 
> (compiler/debugger/simulator).  
> > > The 
> > > > > code
> > > > > > works perfectly fine when running it on the simulator, but 
> > > when I 
> > > > > try
> > > > > > to run it on the chip, I will only get "ho" instead 
> > > of "hello".  I 
> > > > > put
> > > > > > some break points in it when using JTAG to debug, but the 
> ISR 
> > > is 
> > > > > never
> > > > > > called when running on the real hardware, it is called on 
> the
> > > > > > simulator.  Also, when I debug on JTAG I never se the THRE 
> or 
> > > TEMT
> > > > > > clear.  Can you see anything obviously wrong?  I think I 
> put in
> > > > > > everything that you need to compile it.
> > > > > > 
> > > > > > #include <stdio.h>
> > > > > > #define TX_BUFFER_LENGTH 64
> > > > > > #define UART0_THRE			(U0LSR & 0x20)
> > > > > > #define		PINSEL0_00_TxD		(0x01)
> > > > > > #define		PINSEL0_01_GPIO		(0x00 << 2)
> > > > > > #define U0RBR          (*((volatile unsigned char *) 
> > > 0xE000C000))
> > > > > > #define U0THR          (*((volatile unsigned char *) 
> > > 0xE000C000))
> > > > > > #define U0IER          (*((volatile unsigned char *) 
> > > 0xE000C004))
> > > > > > #define U0IIR          (*((volatile unsigned char *) 
> > > 0xE000C008))
> > > > > > #define U0FCR          (*((volatile unsigned char *) 
> > > 0xE000C008))
> > > > > > #define U0LCR          (*((volatile unsigned char *) 
> > > 0xE000C00C))
> > > > > > #define U0MCR          (*((volatile unsigned char *) 
> > > 0xE000C010))
> > > > > > #define U0LSR          (*((volatile unsigned char *) 
> > > 0xE000C014))
> > > > > > #define U0MSR          (*((volatile unsigned char *) 
> > > 0xE000C018))
> > > > > > #define U0SCR          (*((volatile unsigned char *) 
> > > 0xE000C01C))
> > > > > > #define U0DLL          (*((volatile unsigned char *) 
> > > 0xE000C000))
> > > > > > #define U0DLM          (*((volatile unsigned char *) 
> > > 0xE000C004))
> > > > > > #define VICVectAddr6   (*((volatile unsigned long *) 
> > > 0xFFFFF118))
> > > > > > #define VICVectCntl6   (*((volatile unsigned long *) 
> > > 0xFFFFF218))
> > > > > > #define VICIntSelect   (*((volatile unsigned long *) 
> > > 0xFFFFF00C))
> > > > > > #define VICIntEnable   (*((volatile unsigned long *) 
> > > 0xFFFFF010))
> > > > > > #define VICIntEnClr    (*((volatile unsigned long *) 
> > > 0xFFFFF014))
> > > > > > 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 = 0x16; // Setup BGR
> > > > > > 	U0DLM = 0x05; // ~2400 Bit/s @ 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
> > > > > > 	U0IER = 0x7;
> > > > > > 	VICIntSelect &= 0x0;
> > > > > > 	VICVectCntl6 = 0x20 | 6;
> > > > > > 	VICVectAddr6 = (unsigned long) uart0_isr;
> > > > > > 	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt
> 	
> > > > > > }
> > > > > > 
> > > > > > void uart0_isr (void) __irq {
> > > > > > 	switch((U0IIR>>1)&0x7) {
> > > > > > 		// THRE
> > > > > > 		case	001:
> > > > > > 			if(txBytes != 0) {
> > > > > > 				U0THR = txBuffer[txRdPos];
> > > > > > 				txRdPos++;
> > > > > > 				txRdPos = (txRdPos == 
> > > > > TX_BUFFER_LENGTH)?0:txRdPos;
> > > > > > 				txBytes--;
> > > > > > 			}
> > > > > > 			break;
> > > > > > 	}
> > > > > > }
> > > > > > 
> > > > > > void uart0_sendByte(Uint8 byte) {
> > > > > > 	// Wait until there is room in the buffer
> > > > > > 	while(txBytes == TX_BUFFER_LENGTH);
> > > > > > 	VICIntEnClr |= (1 << 6);
> > > > > > 	if(!UART0_THRE) {  // Put it in the software buffer 
> > > > > > 		txBuffer[txWrPos] = byte;
> > > > > > 		txWrPos++;
> > > > > > 		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?
> 0:txWrPos;
> > > > > > 		txBytes++;
> > > > > > 	}
> > > > > > 	else { // If the chip buffer is empty, put it there
> > > > > > 		U0THR = byte;	
> > > > > > 	}
> > > > > > 	VICIntEnable |= (1 << 6);
> > > > > > }
> > > > > > 
> > > > > > int putchar(int a) {
> > > > > > 	uart0_sendByte((int)a);
> > > > > > }
> > > > > > 
> > > > > > int main (void) {
> > > > > > 	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD; 
> > > > > > 	printf("hello");
> > > > > > }

Re: Problems w/ UART

2004-10-08 by peterburdine

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) {
		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
	}
	dummy = U0IIR; // read to clear IRQ
	dummy += 1; // keep compiler from optimizing dummy out
	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.

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> At 02:33 PM 10/8/04 +0000, you wrote:
> >I do now have the VicVectAddr = 0;, but that doesn't help if it
> >doesn't get called.
> 
> Speaking of which, I just reviewed your code.  You don't appear to be 
> actually calling your uart initialization code anywhere (I don't see
how 
> you would get your baud rate right if you hadn't but...).  Also you
should 
Show quoted textHide quoted text
> probably disable interrupts before disabling a specific interrupt via 
> VICIntEnClr
> 
> 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, III

Re: [lpc2000] Re: Problems w/ UART

2004-10-08 by Robert Adsett

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, III

Re: Problems w/ UART

2004-10-08 by peterburdine

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> First a question, you say the interrupt is not being generated, how
do you 
> know?
> 
While I was debugging w/ JTAG, I put a breakpoint in the isr, it was
never reached.  I'd turn on an LED if one existed for my dev board.


> 
> 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.
> 
I think that it would rarely take the default case since it would
match the first one and then break.

In previous version I tried enabling all of the interrupts in U0IIR,
the ISR still didn't work, so I was trying something different here.

CTI is character time out.  It will generate the RBR interrupt even if
the threshold has not been reached after 3.5-4.5 character times, so
you know you have data waiting.


> 
> 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.
I removed the vectored irq setup, still doesn't work.

> 
> 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.

It is defined as volatile (using keil's development tools).

Re: [lpc2000] Re: Problems w/ UART

2004-10-08 by Robert Adsett

At 05:55 PM 10/8/04 +0000, you wrote:
>--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> > First a question, you say the interrupt is not being generated, how
>do you
> > know?
> >
>While I was debugging w/ JTAG, I put a breakpoint in the isr, it was
>never reached.  I'd turn on an LED if one existed for my dev board.

OK, but where in the interrupt?



> >
> > 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.
> >
>I think that it would rarely take the default case since it would
>match the first one and then break.

No, switch does not work that way.  It is an exact match, not a bit 
mask.  And having multiple bits set is not only possible but likely, at the 
very least TEMT and THRE are often on simultaneously.


>In previous version I tried enabling all of the interrupts in U0IIR,
>the ISR still didn't work, so I was trying something different here.
>
>CTI is character time out.  It will generate the RBR interrupt even if
>the threshold has not been reached after 3.5-4.5 character times, so
>you know you have data waiting.

Ah, there is no separate LSR status bit for character timeout.  All that 
happens is IIR gets set to indicate a received character and trigger an 
interrupt.  LSR will simply indicate via RBR.  The LSR does not 'pay 
attention' to the threshold level, RBR will be set as long as at least one 
character is waiting.



> >
> > 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.
>I removed the vectored irq setup, still doesn't work.

This is not a matter of vectored or not.


> >
> > 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.
>
>It is defined as volatile (using keil's development tools).

Then the increment is unneeded (and could be optimized out anyway).  In any 
case there is virtually no chance of this working until you fix the switch 
statement (well eliminate the switch statement).

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, III

Re: Problems w/ UART

2004-10-08 by peterburdine

> OK, but where in the interrupt?
The first line of code that should always be executed.

> 
> No, switch does not work that way.  It is an exact match, not a bit 
> mask.  And having multiple bits set is not only possible but likely,
at the 
> very least TEMT and THRE are often on simultaneously.
> 
You are correct, I was just being stupid.

> > > 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.
> >I removed the vectored irq setup, still doesn't work.
> 
> This is not a matter of vectored or not.

If I removed the vectored setup, then there is only one interrupt left
 to call the isr, so there should not be a problem.


I gave up on that and started over, and this is what I think I am
doing.  I start by disabling all interrupts globally and for the uart.
 Then I enable only the RBR interrupt, then the uart vic.  In the main
I print out 123 by using a for loop as a delay.  I setup the rbr isr
to print out '!' if it receives a character.  Now the problem is when
I send 2 characters the processor resets.  Is there something wrong w/
my 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);
Uint32 irqBackup;

void disableInterrupts (void);
void enableInterrupts (void);

void disableInterrupts (void) {
	irqBackup = VICIntEnable;
	VICIntEnable = 0;
}
void enableInterrupts (void) {
	VICIntEnable = irqBackup;
}

void uart0_config (void) {
	volatile Uint8 x;
	// 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

	// Clear any old irqs
	x = U0LSR;
	x = U0RBR;
	x = U0IIR;
	
	// Setup Interrupts for UART0
	U0IER = 0x1; // Only RBR IRQ on
	VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt
	VICVectAddr6 = (Uint32) uart0_isr;
	VICVectCntl6 = 0x20 | 6;
}

void uart0_isr (void) __irq {
	volatile Uint8 x;
	uart0_sendByte('!');

	// Clear IRQ
	x = U0LSR;
	x = U0IIR;
	x = U0RBR;	
	VICVectAddr = 0; 
}

void uart0_sendByte(Uint8 a) {
	// Wait until there is room in the buffer
	while(txBytes == TX_BUFFER_LENGTH);
	if(U0LSR&0x20) { // If the chip buffer is empty, put it there
		U0THR = a;
	}
	else { // Put in software buffer
		disableInterrupts();
		txBuffer[txWrPos] = a;
		txWrPos++;
		txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
		txBytes++;
		enableInterrupts();
	}
}

int putchar(int a) {
	uart0_sendByte((int)a);
	return 0;
}

int main (void) {
	Uint16 x;
	PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD;
	VPBDIV = 0x1;
	VICIntSelect = 0;	 // Only IRQs, no FIQs
	VICIntEnClr = 0xFFFFFFFF; // Disable all irqs
	uart0_config();
	// Proof that it can send more than one character
	printf("1");
	for(x = 0; x < 1000; x++);
	printf("2");
	for(x = 0; x < 1000; x++);
	printf("3");

	while(1);
}

Re: [lpc2000] Re: Problems w/ UART

2004-10-08 by Robert Adsett

At 08:44 PM 10/8/04 +0000, you wrote:
> > OK, but where in the interrupt?
>The first line of code that should always be executed.
This may seem obtuse, but first line of C or asm?  A good optimizer on the 
ARM may change the order of execution in non-obvious ways.


> > > > 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.
> > >I removed the vectored irq setup, still doesn't work.
> >
> > This is not a matter of vectored or not.
>
>If I removed the vectored setup, then there is only one interrupt left
>  to call the isr, so there should not be a problem.

It doesn't matter if it is 1 interrupt or 10 the potential for a problem 
still exists, you are calling the same buffer for both the interrupt and 
mainline code.



>I gave up on that and started over, and this is what I think I am
>doing.  I start by disabling all interrupts globally and for the uart.
>  Then I enable only the RBR interrupt, then the uart vic.  In the main
>I print out 123 by using a for loop as a delay.  I setup the rbr isr
>to print out '!' if it receives a character.  Now the problem is when
>I send 2 characters the processor resets.  Is there something wrong w/
>my code?

Resetting may actually be a good thing here ;)  At least it suggests to me 
that you might actually be getting your interrupt this time.


>#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);
>Uint32 irqBackup;
>
>void disableInterrupts (void);
>void enableInterrupts (void);
>
>void disableInterrupts (void) {
>         irqBackup = VICIntEnable;
>         VICIntEnable = 0;
>}
>void enableInterrupts (void) {
>         VICIntEnable = irqBackup;
>}

I'd feel a lot better about these if you were really disabling and 
restoring interrupts at the CPU level rather than just the VIC flags, but I 
don't think that's your problem source.


>void uart0_config (void) {
>         volatile Uint8 x;
>         // 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
>
>         // Clear any old irqs
>         x = U0LSR;
>         x = U0RBR;
>         x = U0IIR;
>
>         // Setup Interrupts for UART0
>         U0IER = 0x1; // Only RBR IRQ on
>         VICIntEnable |= (0x1 << 6); // Enable Uart0 Interrupt
>         VICVectAddr6 = (Uint32) uart0_isr;
>         VICVectCntl6 = 0x20 | 6;
>}
>
>void uart0_isr (void) __irq {
>         volatile Uint8 x;
>         uart0_sendByte('!');

There are problems here.  First you never empty the buffer so the buffer 
becomes blocked very quickly.  Now watch what happens when you send a 
string of bytes through that will fill the buffer up.

- First byte gets written at point A--
- Second byte comes along right behind it and also gets written at point 
A-- since the first byte has moved into the shift register.
- The rest of the buffer gets filled up via the else clause (Point B--) and 
then
- the next call sits in the infinite loop at point C--
- Shortly after the UART finally catches up and finishes sending the first 
character and moves the second character into the shift register while 
flagging an interrupt.
- The interrupt fires and the first thing that occurs is a call to 
uart0_sendByte which goes into an infinite loop at point C-- since the 
buffer is full.

You get two characters out, one interrupt fires and you never exit the 
interrupt routine.  Unless you have a watchdog enabled I would expect this 
to hang, not reset.

Unless the interrupt stack isn't setup correctly.  I'm not familiar with 
the startup code for your compiler so someone else might be better suited 
to suggest if that is an issue.


>         // Clear IRQ
>         x = U0LSR;
>         x = U0IIR;
>         x = U0RBR;
>         VICVectAddr = 0;
>}
>
>void uart0_sendByte(Uint8 a) {
>         // Wait until there is room in the buffer

C--

>         while(txBytes == TX_BUFFER_LENGTH);

A---

>         if(U0LSR&0x20) { // If the chip buffer is empty, put it there
>                 U0THR = a;
>         }

B--

>         else { // Put in software buffer
>                 disableInterrupts();
>                 txBuffer[txWrPos] = a;
>                 txWrPos++;
>                 txWrPos = (txWrPos == TX_BUFFER_LENGTH)?0:txWrPos;
>                 txBytes++;
>                 enableInterrupts();
>         }
>}
>
>int putchar(int a) {
>         uart0_sendByte((int)a);
>         return 0;
>}
>
>int main (void) {
>         Uint16 x;
>         PINSEL0 = PINSEL0_00_TxD | PINSEL0_01_RxD;
>         VPBDIV = 0x1;
>         VICIntSelect = 0;       // Only IRQs, no FIQs
>         VICIntEnClr = 0xFFFFFFFF; // Disable all irqs
>         uart0_config();
>         // Proof that it can send more than one character
>         printf("1");
>         for(x = 0; x < 1000; x++);
>         printf("2");
>         for(x = 0; x < 1000; x++);
>         printf("3");
>
>         while(1);
>}

Remember there are three places to disable/enable interrupts from the UART

- the uart itself
- the VIC peripheral
- the CPU

To avoid subtle phase problems (especially when first starting to work with 
interrupts) it makes sense as a simple precaution to disable interrupts at 
the CPU level when enabling or disabling them at the other levels.

Again I'd suggest looking at other UART code for this processor (take a 
look at the pointers from an earlier post).


" '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, III

Re: [lpc2000] Re: Problems w/ UART

2004-10-09 by Bill Knight

Have a look at UT040803A.zip in the files section on Yahoo.
It contains operational uart code for both polled and interrupt
modes of operation.

Regards
-Bill Knight
www.theARMPatch.com

Re: Problems w/ UART

2004-10-09 by peterburdine

Thanks, Bill.

I was about to email you about that actually.  I had just changed all
the code necessary for it to compile on the Keil's compiler.  The
strange thing is that it doesn't work with their simulator, but it
works on the real hardware.  All the code I wrote worked on the
simulator, but not the real hardware.  Guess I'll have to complain.

Would you like me to email you the changed code for you to post or for
reference?  I think the only things that I needed to change were the
inline assembly and I had to make the unions in uartRegs_t non-anonymous.

--Peter

--- In lpc2000@yahoogroups.com, "Bill Knight" <BillK@t...> wrote:
Show quoted textHide quoted text
> Have a look at UT040803A.zip in the files section on Yahoo.
> It contains operational uart code for both polled and interrupt
> modes of operation.
> 
> Regards
> -Bill Knight
> www.theARMPatch.com

Re: Problems w/ UART

2004-10-11 by jerome_gueunier

Writing 0 to VICVECTADDRESS release interrupt priority level into the
VIC see ARM VIC primecell specification

Jérôme

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> wrote:
> At 02:33 PM 10/8/04 +0000, you wrote:
> >I do now have the VicVectAddr = 0;, but that doesn't help if it
> >doesn't get called.
> 
> Speaking of which, I just reviewed your code.  You don't appear to be 
> actually calling your uart initialization code anywhere (I don't see
how 
> you would get your baud rate right if you hadn't but...).  Also you
should 
Show quoted textHide quoted text
> probably disable interrupts before disabling a specific interrupt via 
> VICIntEnClr
> 
> 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, III

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.