Yahoo Groups archive

Lpc2000

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

Thread

UART transmit problem with GNU

UART transmit problem with GNU

2005-04-28 by jesperkr123

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

Re: UART transmit problem with GNU

2005-04-28 by javida13

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..... 
Show quoted textHide quoted text
> Almost the same code....
> 
> Regards
> Jesper Kristensen
> Denmark

Re: UART transmit problem with GNU

2005-04-29 by jesperkr123

Hey

Thanks for the hint, but it did'nt work... I still got problems...

Jesper

--- In lpc2000@yahoogroups.com, "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 ?? 
Show quoted textHide quoted text
> > What am I missing...
> > I've tested the board with the Keil CHARM compiler, with 
> succes..... 
> > Almost the same code....
> > 
> > Regards
> > Jesper Kristensen
> > Denmark

Re: UART transmit problem with GNU

2005-05-01 by jesperkr123

--- In lpc2000@yahoogroups.com, "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@yahoogroups.com, "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 
Show quoted textHide quoted text
> > 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

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.