Hey
I'm trying to get the UART0 and UART1 working on my LPC2124 Olimex
board. I use the WINARM GNU toolchain.
I've wrote a simple code to test the UART. But when i send a byte to
my PC, the received byte is wrong.
This is my test program:
void SetUART(int baud){
unsigned int divisor = pCF / (16 * baud);
PINSEL0 |= 0x00050005; /* Enable UART0 & UART1 */
U0IER = 0x00; // disable all interrupts
U0IIR; // clear interrupt ID
U0RBR; // clear receive register
U0LSR; // clear line status register
U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit, DLAB=1*/
U0DLL = divisor;
U0DLM = (divisor >> 8);
U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
U0IER = 1;
U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit, DLAB=1*/
U1DLL = divisor;
U1DLM = (divisor >> 8);
U1LCR = 0x03;
U1IER = 1;
U0FCR = 0x07; //enable the FIFO's
U1FCR = 0x07; //enable the FIFO's
}
void __attribute__ ((interrupt("IRQ"))) tc0(void) {
timeval--;
T0_IR = 1; // Clear interrupt flag
VICVectAddr = 0; // Acknowledge Interrupt
}
void __attribute__ ((interrupt("IRQ"))) u0(void) {
putcha(U0RBR);
U0IIR;
VICVectAddr = 0;
}
void __attribute__ ((interrupt("IRQ"))) u1(void) {
status |= (1<<UART_1);
dummy = U1RBR;
U1IIR;
VICVectAddr = 0; // Acknowledge Interrupt
}
void setInterrupt(void)
{
enableIRQ();
VICIntEnClear = ~0x000000d0;
VICIntSelect &= ~0x000000d0;
VICIntEnable = 0x000000d0;
VICVectAddr0 = (unsigned long)tc0;
VICVectCntl0 = 0x20 | TIM0;
VICVectAddr1 = (unsigned long)u0;
VICVectCntl1 = 0x20 | UART_0;
VICVectAddr2 = (unsigned long)u1;
VICVectCntl2 = 0x20 | UART_1;
}
void init(void)
{
systemInit();
ledInit();
setInterrupt();
SetUART(9600);
}
char putcha(char ch)
{
while (!(U0LSR & 0x20));
return(U0THR=ch);
}
int main (void) {
init();
while(1)
{
if (IOPIN0 & (1<<SWPIN))
{}
else
putcha(0x30);
}
}
When I run this code, I receive 0x63 on my PC?? Any suggestions ??
What am I missing...
I've tested the board with the Keil CHARM compiler, with succes.....
Almost the same code....
Regards
Jesper Kristensen
Denmark
UART transmit problem with GNU
Started by ●April 28, 2005
Reply by ●April 28, 20052005-04-28
You need to encapsulate UODLL and DODLM by setting and clearing the
DLAB
U0LCR |= 0x80; /* Set DLAB */
U0DLL = divisor;
U0DLM = (divisor>>8);
U0LCR &= ~0x80; /* Clear DLAB */ > my PC, the received byte is wrong.
> This is my test program:
>
> void SetUART(int baud){
> unsigned int divisor = pCF / (16 * baud);
>
> PINSEL0 |= 0x00050005; /* Enable UART0 & UART1 */
>
> U0IER = 0x00; // disable all interrupts
> U0IIR; // clear interrupt ID
> U0RBR; // clear receive register
> U0LSR; // clear line status
register
>
> U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit, DLAB=1*/
> U0DLL = divisor;
> U0DLM = (divisor >> 8);
> U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
> U0IER = 1;
>
> U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
DLAB=1*/
> U1DLL = divisor;
> U1DLM = (divisor >> 8);
> U1LCR = 0x03;
> U1IER = 1;
>
> U0FCR = 0x07; //enable the FIFO's
> U1FCR = 0x07; //enable the FIFO's
> }
>
> void __attribute__ ((interrupt("IRQ"))) tc0(void) {
> timeval--;
> T0_IR = 1; // Clear interrupt
flag
> VICVectAddr = 0; // Acknowledge
Interrupt
> }
>
> void __attribute__ ((interrupt("IRQ"))) u0(void) {
> putcha(U0RBR);
> U0IIR;
> VICVectAddr = 0;
> }
>
> void __attribute__ ((interrupt("IRQ"))) u1(void) {
> status |= (1<<UART_1);
> dummy = U1RBR;
> U1IIR;
> VICVectAddr = 0; // Acknowledge
Interrupt
> }
>
> void setInterrupt(void)
> {
> enableIRQ();
>
> VICIntEnClear = ~0x000000d0;
> VICIntSelect &= ~0x000000d0;
> VICIntEnable = 0x000000d0;
> VICVectAddr0 = (unsigned long)tc0;
> VICVectCntl0 = 0x20 | TIM0;
> VICVectAddr1 = (unsigned long)u0;
> VICVectCntl1 = 0x20 | UART_0;
> VICVectAddr2 = (unsigned long)u1;
> VICVectCntl2 = 0x20 | UART_1;
> }
>
> void init(void)
> {
> systemInit();
> ledInit();
> setInterrupt();
> SetUART(9600);
> }
>
> char putcha(char ch)
> {
> while (!(U0LSR & 0x20));
> return(U0THR=ch);
> }
>
> int main (void) {
> init();
> while(1)
> {
> if (IOPIN0 & (1<<SWPIN))
> {}
> else
> putcha(0x30);
> }
> }
> When I run this code, I receive 0x63 on my PC?? Any suggestions ??
> What am I missing...
> I've tested the board with the Keil CHARM compiler, with
succes.....
> Almost the same code....
>
> Regards
> Jesper Kristensen
> Denmark
DLAB
U0LCR |= 0x80; /* Set DLAB */
U0DLL = divisor;
U0DLM = (divisor>>8);
U0LCR &= ~0x80; /* Clear DLAB */ > my PC, the received byte is wrong.
> This is my test program:
>
> void SetUART(int baud){
> unsigned int divisor = pCF / (16 * baud);
>
> PINSEL0 |= 0x00050005; /* Enable UART0 & UART1 */
>
> U0IER = 0x00; // disable all interrupts
> U0IIR; // clear interrupt ID
> U0RBR; // clear receive register
> U0LSR; // clear line status
register
>
> U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit, DLAB=1*/
> U0DLL = divisor;
> U0DLM = (divisor >> 8);
> U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
> U0IER = 1;
>
> U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
DLAB=1*/
> U1DLL = divisor;
> U1DLM = (divisor >> 8);
> U1LCR = 0x03;
> U1IER = 1;
>
> U0FCR = 0x07; //enable the FIFO's
> U1FCR = 0x07; //enable the FIFO's
> }
>
> void __attribute__ ((interrupt("IRQ"))) tc0(void) {
> timeval--;
> T0_IR = 1; // Clear interrupt
flag
> VICVectAddr = 0; // Acknowledge
Interrupt
> }
>
> void __attribute__ ((interrupt("IRQ"))) u0(void) {
> putcha(U0RBR);
> U0IIR;
> VICVectAddr = 0;
> }
>
> void __attribute__ ((interrupt("IRQ"))) u1(void) {
> status |= (1<<UART_1);
> dummy = U1RBR;
> U1IIR;
> VICVectAddr = 0; // Acknowledge
Interrupt
> }
>
> void setInterrupt(void)
> {
> enableIRQ();
>
> VICIntEnClear = ~0x000000d0;
> VICIntSelect &= ~0x000000d0;
> VICIntEnable = 0x000000d0;
> VICVectAddr0 = (unsigned long)tc0;
> VICVectCntl0 = 0x20 | TIM0;
> VICVectAddr1 = (unsigned long)u0;
> VICVectCntl1 = 0x20 | UART_0;
> VICVectAddr2 = (unsigned long)u1;
> VICVectCntl2 = 0x20 | UART_1;
> }
>
> void init(void)
> {
> systemInit();
> ledInit();
> setInterrupt();
> SetUART(9600);
> }
>
> char putcha(char ch)
> {
> while (!(U0LSR & 0x20));
> return(U0THR=ch);
> }
>
> int main (void) {
> init();
> while(1)
> {
> if (IOPIN0 & (1<<SWPIN))
> {}
> else
> putcha(0x30);
> }
> }
> When I run this code, I receive 0x63 on my PC?? Any suggestions ??
> What am I missing...
> I've tested the board with the Keil CHARM compiler, with
succes.....
> Almost the same code....
>
> Regards
> Jesper Kristensen
> Denmark
Reply by ●April 29, 20052005-04-29
Hey
Thanks for the hint, but it did'nt work... I still got problems...
Jesper
--- In lpc2000@lpc2..., "javida13" <javida13@y...> wrote:
> You need to encapsulate UODLL and DODLM by setting and clearing the
> DLAB
>
> U0LCR |= 0x80; /* Set DLAB */
> U0DLL = divisor;
> U0DLM = (divisor>>8);
> U0LCR &= ~0x80; /* Clear DLAB */ > > my PC, the received byte is wrong.
> > This is my test program:
> >
> > void SetUART(int baud){
> > unsigned int divisor = pCF / (16 * baud);
> >
> > PINSEL0 |= 0x00050005; /* Enable UART0 & UART1 */
> >
> > U0IER = 0x00; // disable all interrupts
> > U0IIR; // clear interrupt ID
> > U0RBR; // clear receive register
> > U0LSR; // clear line status
> register
> >
> > U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit, DLAB=1*/
> > U0DLL = divisor;
> > U0DLM = (divisor >> 8);
> > U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
> > U0IER = 1;
> >
> > U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
> DLAB=1*/
> > U1DLL = divisor;
> > U1DLM = (divisor >> 8);
> > U1LCR = 0x03;
> > U1IER = 1;
> >
> > U0FCR = 0x07; //enable the FIFO's
> > U1FCR = 0x07; //enable the FIFO's
> > }
> >
> > void __attribute__ ((interrupt("IRQ"))) tc0(void) {
> > timeval--;
> > T0_IR = 1; // Clear interrupt
> flag
> > VICVectAddr = 0; // Acknowledge
> Interrupt
> > }
> >
> > void __attribute__ ((interrupt("IRQ"))) u0(void) {
> > putcha(U0RBR);
> > U0IIR;
> > VICVectAddr = 0;
> > }
> >
> > void __attribute__ ((interrupt("IRQ"))) u1(void) {
> > status |= (1<<UART_1);
> > dummy = U1RBR;
> > U1IIR;
> > VICVectAddr = 0; // Acknowledge
> Interrupt
> > }
> >
> > void setInterrupt(void)
> > {
> > enableIRQ();
> >
> > VICIntEnClear = ~0x000000d0;
> > VICIntSelect &= ~0x000000d0;
> > VICIntEnable = 0x000000d0;
> > VICVectAddr0 = (unsigned long)tc0;
> > VICVectCntl0 = 0x20 | TIM0;
> > VICVectAddr1 = (unsigned long)u0;
> > VICVectCntl1 = 0x20 | UART_0;
> > VICVectAddr2 = (unsigned long)u1;
> > VICVectCntl2 = 0x20 | UART_1;
> > }
> >
> > void init(void)
> > {
> > systemInit();
> > ledInit();
> > setInterrupt();
> > SetUART(9600);
> > }
> >
> > char putcha(char ch)
> > {
> > while (!(U0LSR & 0x20));
> > return(U0THR=ch);
> > }
> >
> > int main (void) {
> > init();
> > while(1)
> > {
> > if (IOPIN0 & (1<<SWPIN))
> > {}
> > else
> > putcha(0x30);
> > }
> > }
> > When I run this code, I receive 0x63 on my PC?? Any
suggestions ??
> > What am I missing...
> > I've tested the board with the Keil CHARM compiler, with
> succes.....
> > Almost the same code....
> >
> > Regards
> > Jesper Kristensen
> > Denmark
Thanks for the hint, but it did'nt work... I still got problems...
Jesper
--- In lpc2000@lpc2..., "javida13" <javida13@y...> wrote:
> You need to encapsulate UODLL and DODLM by setting and clearing the
> DLAB
>
> U0LCR |= 0x80; /* Set DLAB */
> U0DLL = divisor;
> U0DLM = (divisor>>8);
> U0LCR &= ~0x80; /* Clear DLAB */ > > my PC, the received byte is wrong.
> > This is my test program:
> >
> > void SetUART(int baud){
> > unsigned int divisor = pCF / (16 * baud);
> >
> > PINSEL0 |= 0x00050005; /* Enable UART0 & UART1 */
> >
> > U0IER = 0x00; // disable all interrupts
> > U0IIR; // clear interrupt ID
> > U0RBR; // clear receive register
> > U0LSR; // clear line status
> register
> >
> > U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit, DLAB=1*/
> > U0DLL = divisor;
> > U0DLM = (divisor >> 8);
> > U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
> > U0IER = 1;
> >
> > U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
> DLAB=1*/
> > U1DLL = divisor;
> > U1DLM = (divisor >> 8);
> > U1LCR = 0x03;
> > U1IER = 1;
> >
> > U0FCR = 0x07; //enable the FIFO's
> > U1FCR = 0x07; //enable the FIFO's
> > }
> >
> > void __attribute__ ((interrupt("IRQ"))) tc0(void) {
> > timeval--;
> > T0_IR = 1; // Clear interrupt
> flag
> > VICVectAddr = 0; // Acknowledge
> Interrupt
> > }
> >
> > void __attribute__ ((interrupt("IRQ"))) u0(void) {
> > putcha(U0RBR);
> > U0IIR;
> > VICVectAddr = 0;
> > }
> >
> > void __attribute__ ((interrupt("IRQ"))) u1(void) {
> > status |= (1<<UART_1);
> > dummy = U1RBR;
> > U1IIR;
> > VICVectAddr = 0; // Acknowledge
> Interrupt
> > }
> >
> > void setInterrupt(void)
> > {
> > enableIRQ();
> >
> > VICIntEnClear = ~0x000000d0;
> > VICIntSelect &= ~0x000000d0;
> > VICIntEnable = 0x000000d0;
> > VICVectAddr0 = (unsigned long)tc0;
> > VICVectCntl0 = 0x20 | TIM0;
> > VICVectAddr1 = (unsigned long)u0;
> > VICVectCntl1 = 0x20 | UART_0;
> > VICVectAddr2 = (unsigned long)u1;
> > VICVectCntl2 = 0x20 | UART_1;
> > }
> >
> > void init(void)
> > {
> > systemInit();
> > ledInit();
> > setInterrupt();
> > SetUART(9600);
> > }
> >
> > char putcha(char ch)
> > {
> > while (!(U0LSR & 0x20));
> > return(U0THR=ch);
> > }
> >
> > int main (void) {
> > init();
> > while(1)
> > {
> > if (IOPIN0 & (1<<SWPIN))
> > {}
> > else
> > putcha(0x30);
> > }
> > }
> > When I run this code, I receive 0x63 on my PC?? Any
suggestions ??
> > What am I missing...
> > I've tested the board with the Keil CHARM compiler, with
> succes.....
> > Almost the same code....
> >
> > Regards
> > Jesper Kristensen
> > Denmark
Reply by ●May 1, 20052005-05-01
--- In lpc2000@lpc2..., "jesperkr123" <jk@t...> wrote:
Hey
Well I solved my problem... I calculated a wrong divisor.
unsigned int divisor = pCF / (16 * baud); //Works in Keil, but not GNU
should be:
unsigned int divisor = (int)(((FOSC*PLL_M/VPBDIV_VAL) / ((baud) *
16.0)) + 0.5); // Works in GNU
Jesper
> Hey
>
> Thanks for the hint, but it did'nt work... I still got problems...
>
> Jesper
>
> --- In lpc2000@lpc2..., "javida13" <javida13@y...> wrote:
> > You need to encapsulate UODLL and DODLM by setting and clearing
the
> > DLAB
> >
> > U0LCR |= 0x80; /* Set DLAB */
> > U0DLL = divisor;
> > U0DLM = (divisor>>8);
> > U0LCR &= ~0x80; /* Clear DLAB */
> >
> >
> > > my PC, the received byte is wrong.
> > > This is my test program:
> > >
> > > void SetUART(int baud){
> > > unsigned int divisor = pCF / (16 * baud);
> > >
> > > PINSEL0 |= 0x00050005; /* Enable UART0 & UART1
*/
> > >
> > > U0IER = 0x00; // disable all
interrupts
> > > U0IIR; // clear interrupt ID
> > > U0RBR; // clear receive
register
> > > U0LSR; // clear line status
> > register
> > >
> > > U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
DLAB=1*/
> > > U0DLL = divisor;
> > > U0DLM = (divisor >> 8);
> > > U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
> > > U0IER = 1;
> > >
> > > U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
> > DLAB=1*/
> > > U1DLL = divisor;
> > > U1DLM = (divisor >> 8);
> > > U1LCR = 0x03;
> > > U1IER = 1;
> > >
> > > U0FCR = 0x07; //enable the FIFO's
> > > U1FCR = 0x07; //enable the FIFO's
> > > }
> > >
> > > void __attribute__ ((interrupt("IRQ"))) tc0(void) {
> > > timeval--;
> > > T0_IR = 1; // Clear
interrupt
> > flag
> > > VICVectAddr = 0; // Acknowledge
> > Interrupt
> > > }
> > >
> > > void __attribute__ ((interrupt("IRQ"))) u0(void) {
> > > putcha(U0RBR);
> > > U0IIR;
> > > VICVectAddr = 0;
> > > }
> > >
> > > void __attribute__ ((interrupt("IRQ"))) u1(void) {
> > > status |= (1<<UART_1);
> > > dummy = U1RBR;
> > > U1IIR;
> > > VICVectAddr = 0; // Acknowledge
> > Interrupt
> > > }
> > >
> > > void setInterrupt(void)
> > > {
> > > enableIRQ();
> > >
> > > VICIntEnClear = ~0x000000d0;
> > > VICIntSelect &= ~0x000000d0;
> > > VICIntEnable = 0x000000d0;
> > > VICVectAddr0 = (unsigned long)tc0;
> > > VICVectCntl0 = 0x20 | TIM0;
> > > VICVectAddr1 = (unsigned long)u0;
> > > VICVectCntl1 = 0x20 | UART_0;
> > > VICVectAddr2 = (unsigned long)u1;
> > > VICVectCntl2 = 0x20 | UART_1;
> > > }
> > >
> > > void init(void)
> > > {
> > > systemInit();
> > > ledInit();
> > > setInterrupt();
> > > SetUART(9600);
> > > }
> > >
> > > char putcha(char ch)
> > > {
> > > while (!(U0LSR & 0x20));
> > > return(U0THR=ch);
> > > }
> > >
> > > int main (void) {
> > > init();
> > > while(1)
> > > {
> > > if (IOPIN0 & (1<<SWPIN))
> > > {}
> > > else
> > > putcha(0x30);
> > > }
> > > }
> > > When I run this code, I receive 0x63 on my PC?? Any
> suggestions ??
> > > What am I missing...
> > > I've tested the board with the Keil CHARM compiler, with
> > succes.....
> > > Almost the same code....
> > >
> > > Regards
> > > Jesper Kristensen
> > > Denmark
Hey
Well I solved my problem... I calculated a wrong divisor.
unsigned int divisor = pCF / (16 * baud); //Works in Keil, but not GNU
should be:
unsigned int divisor = (int)(((FOSC*PLL_M/VPBDIV_VAL) / ((baud) *
16.0)) + 0.5); // Works in GNU
Jesper
> Hey
>
> Thanks for the hint, but it did'nt work... I still got problems...
>
> Jesper
>
> --- In lpc2000@lpc2..., "javida13" <javida13@y...> wrote:
> > You need to encapsulate UODLL and DODLM by setting and clearing
the
> > DLAB
> >
> > U0LCR |= 0x80; /* Set DLAB */
> > U0DLL = divisor;
> > U0DLM = (divisor>>8);
> > U0LCR &= ~0x80; /* Clear DLAB */
> >
> >
> > > my PC, the received byte is wrong.
> > > This is my test program:
> > >
> > > void SetUART(int baud){
> > > unsigned int divisor = pCF / (16 * baud);
> > >
> > > PINSEL0 |= 0x00050005; /* Enable UART0 & UART1
*/
> > >
> > > U0IER = 0x00; // disable all
interrupts
> > > U0IIR; // clear interrupt ID
> > > U0RBR; // clear receive
register
> > > U0LSR; // clear line status
> > register
> > >
> > > U0LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
DLAB=1*/
> > > U0DLL = divisor;
> > > U0DLM = (divisor >> 8);
> > > U0LCR = 0x03; /* DLAB = 0 - no access to UART1 Div. */
> > > U0IER = 1;
> > >
> > > U1LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit,
> > DLAB=1*/
> > > U1DLL = divisor;
> > > U1DLM = (divisor >> 8);
> > > U1LCR = 0x03;
> > > U1IER = 1;
> > >
> > > U0FCR = 0x07; //enable the FIFO's
> > > U1FCR = 0x07; //enable the FIFO's
> > > }
> > >
> > > void __attribute__ ((interrupt("IRQ"))) tc0(void) {
> > > timeval--;
> > > T0_IR = 1; // Clear
interrupt
> > flag
> > > VICVectAddr = 0; // Acknowledge
> > Interrupt
> > > }
> > >
> > > void __attribute__ ((interrupt("IRQ"))) u0(void) {
> > > putcha(U0RBR);
> > > U0IIR;
> > > VICVectAddr = 0;
> > > }
> > >
> > > void __attribute__ ((interrupt("IRQ"))) u1(void) {
> > > status |= (1<<UART_1);
> > > dummy = U1RBR;
> > > U1IIR;
> > > VICVectAddr = 0; // Acknowledge
> > Interrupt
> > > }
> > >
> > > void setInterrupt(void)
> > > {
> > > enableIRQ();
> > >
> > > VICIntEnClear = ~0x000000d0;
> > > VICIntSelect &= ~0x000000d0;
> > > VICIntEnable = 0x000000d0;
> > > VICVectAddr0 = (unsigned long)tc0;
> > > VICVectCntl0 = 0x20 | TIM0;
> > > VICVectAddr1 = (unsigned long)u0;
> > > VICVectCntl1 = 0x20 | UART_0;
> > > VICVectAddr2 = (unsigned long)u1;
> > > VICVectCntl2 = 0x20 | UART_1;
> > > }
> > >
> > > void init(void)
> > > {
> > > systemInit();
> > > ledInit();
> > > setInterrupt();
> > > SetUART(9600);
> > > }
> > >
> > > char putcha(char ch)
> > > {
> > > while (!(U0LSR & 0x20));
> > > return(U0THR=ch);
> > > }
> > >
> > > int main (void) {
> > > init();
> > > while(1)
> > > {
> > > if (IOPIN0 & (1<<SWPIN))
> > > {}
> > > else
> > > putcha(0x30);
> > > }
> > > }
> > > When I run this code, I receive 0x63 on my PC?? Any
> suggestions ??
> > > What am I missing...
> > > I've tested the board with the Keil CHARM compiler, with
> > succes.....
> > > Almost the same code....
> > >
> > > Regards
> > > Jesper Kristensen
> > > Denmark