EmbeddedRelated.com
Forums

LPC2129 UART Help Needed

Started by rtos2010 February 28, 2010
I'm using the Keil MCB2100 Demo Board. LPC2129, 12MHZ crystal and
PLLCFG_Val = 0x00000024

I'm using this UART demo code from " raju_nem
" at the following user group
link/ It says "testing" near the code so I;m not sure it is fully
working correctly?
http://tech.groups.yahoo.com/group/lpc2000/files/LPC2129_UART/


I integrated the code into my program and it compiles and links fine.
When I run it I get garbage characters from the serial port. Like the
baud rate is not correct.

I tried changing U0DLL and U0DLM with no luck. Is this demo code bad?
Does anyone have any other demo code that shows how to use the UART?
Thanks.
#define DESIRED_BAUDRATE 19200

#define CRYSTAL_FREQUENCY_IN_HZ 12000000
#define PCLK CRYSTAL_FREQUENCY_IN_HZ // since VPBDIV=0x01
#define DIVISOR (PCLK/(16*DESIRED_BAUDRATE))
void InitUart0(void)
{
/* U0LCR: UART0 Line Control Register
0x83: enable Divisor Latch access, set 8-bit word length,
1 stop bit, no parity, disable break transmission */
U0LCR=0x83;

/* VPBDIV: VPB bus clock divider
0x01: PCLK = processor clock */
VPBDIV=0x01;

/* U0DLL: UART0 Divisor Latch (LSB) */
U0DLL=DIVISOR&0xFF;

/* U0DLM: UART0 Divisor Latch (MSB) */
U0DLM=DIVISOR>>8;

/* U0LCR: UART0 Line Control Register
0x03: same as above, but disable Divisor Latch access */
U0LCR=0x03 ;

/* U0FCR: UART0 FIFO Control Register
0x05: Clear Tx FIFO and enable Rx and Tx FIFOs */
U0FCR=0x05 ;

An Engineer's Guide to the LPC2100 Series

I've written a function (in C) to set UART baud rates to whatever you want.
It takes the CCLK and the desired baud rate, and the UART number as inputs,
and works out the register settings to provide the desired baud rate. It is
not a polished piece of code, nor is it well commented. It does use
floating-point math, but you could probably work around that if you really
wanted to avoid it.

If you're interested in wading through it (it's not guaranteed bug-free, but
it does work!) I'll post it here. You can set the baud rate to just about
any value you want (e.g. 73250kbps if you wish!), and if there is any
register setting combination that can give you that baud rate within
workable tolerances, it will do that for you. Else it will return an error.

Want it? Just one condition: You don't copyright it. I don't want to be
debarred from using it in my own applications!!!

Let me know...

-Ahmad
On Mon, Mar 1, 2010 at 4:07 AM, rtos2010 wrote:

> I'm using the Keil MCB2100 Demo Board. LPC2129, 12MHZ crystal and
> PLLCFG_Val = 0x00000024
>
> I'm using this UART demo code from " raju_nem "
> at the following user group link/ It says "testing" near the code so I;m
> not sure it is fully working correctly?
> http://tech.groups.yahoo.com/group/lpc2000/files/LPC2129_UART/
>
> I integrated the code into my program and it compiles and links fine. When
> I run it I get garbage characters from the serial port. Like the baud rate
> is not correct.
>
> I tried changing U0DLL and U0DLM with no luck. Is this demo code bad?
> Does anyone have any other demo code that shows how to use the UART?
> Thanks.
> #define DESIRED_BAUDRATE 19200
>
> #define CRYSTAL_FREQUENCY_IN_HZ 12000000
> #define PCLK CRYSTAL_FREQUENCY_IN_HZ // since VPBDIV=0x01
> #define DIVISOR (PCLK/(16*DESIRED_BAUDRATE))
> void InitUart0(void)
> {
> /* U0LCR: UART0 Line Control Register
> 0x83: enable Divisor Latch access, set 8-bit word length,
> 1 stop bit, no parity, disable break transmission */
> U0LCR=0x83;
>
> /* VPBDIV: VPB bus clock divider
> 0x01: PCLK = processor clock */
> VPBDIV=0x01;
>
> /* U0DLL: UART0 Divisor Latch (LSB) */
> U0DLL=DIVISOR&0xFF;
>
> /* U0DLM: UART0 Divisor Latch (MSB) */
> U0DLM=DIVISOR>>8;
>
> /* U0LCR: UART0 Line Control Register
> 0x03: same as above, but disable Divisor Latch access */
> U0LCR=0x03 ;
>
> /* U0FCR: UART0 FIFO Control Register
> 0x05: Clear Tx FIFO and enable Rx and Tx FIFOs */
> U0FCR=0x05 ;
>
>
>
Ahmad,

It's generous of you.. I think we should collect code snippets for LPC
family and perfect them as a library.

However, I follow a simpler approach:

NXP released an Excel sheet that calculates variables for you for given
master clock. The main calculation bottleneck is the fractional boudrate
register. It uses step based approach but does a good job. I calculated one
boudrate such that 19200, keeping the fractional boudrate same, the variable
for desired boudrate is multiple of what it is for 19200..

Deniz

From: l... [mailto:l...] On Behalf Of
Ahmad
Sent: 01 March, 2010 21:48
To: l...
Subject: Re: [lpc2000] LPC2129 UART Help Needed

I've written a function (in C) to set UART baud rates to whatever you want.
It takes the CCLK and the desired baud rate, and the UART number as inputs,
and works out the register settings to provide the desired baud rate. It is
not a polished piece of code, nor is it well commented. It does use
floating-point math, but you could probably work around that if you really
wanted to avoid it.

If you're interested in wading through it (it's not guaranteed bug-free, but
it does work!) I'll post it here. You can set the baud rate to just about
any value you want (e.g. 73250kbps if you wish!), and if there is any
register setting combination that can give you that baud rate within
workable tolerances, it will do that for you. Else it will return an error.

Want it? Just one condition: You don't copyright it. I don't want to be
debarred from using it in my own applications!!!

Let me know...

-Ahmad

On Mon, Mar 1, 2010 at 4:07 AM, rtos2010 wrote:

I'm using the Keil MCB2100 Demo Board. LPC2129, 12MHZ crystal and
PLLCFG_Val = 0x00000024

I'm using this UART demo code from " raju_nem
" at the following user group link/
It says "testing" near the code so I;m not sure it is fully working
correctly? http://tech.groups.yahoo.com/group/lpc2000/files/LPC2129_UART/

I integrated the code into my program and it compiles and links fine. When
I run it I get garbage characters from the serial port. Like the baud rate
is not correct.

I tried changing U0DLL and U0DLM with no luck. Is this demo code bad? Does
anyone have any other demo code that shows how to use the UART? Thanks.
#define DESIRED_BAUDRATE 19200

#define CRYSTAL_FREQUENCY_IN_HZ 12000000
#define PCLK CRYSTAL_FREQUENCY_IN_HZ // since VPBDIV=0x01
#define DIVISOR (PCLK/(16*DESIRED_BAUDRATE))
void InitUart0(void)
{
/* U0LCR: UART0 Line Control Register
0x83: enable Divisor Latch access, set 8-bit word length,
1 stop bit, no parity, disable break transmission */
U0LCR=0x83;

/* VPBDIV: VPB bus clock divider
0x01: PCLK = processor clock */
VPBDIV=0x01;

/* U0DLL: UART0 Divisor Latch (LSB) */
U0DLL=DIVISOR&0xFF;

/* U0DLM: UART0 Divisor Latch (MSB) */
U0DLM=DIVISOR>>8;

/* U0LCR: UART0 Line Control Register
0x03: same as above, but disable Divisor Latch access */
U0LCR=0x03 ;

/* U0FCR: UART0 FIFO Control Register
0x05: Clear Tx FIFO and enable Rx and Tx FIFOs */
U0FCR=0x05 ;
I agree this is a sensible approach. The absolute error can be a tiny
bit higher this way than optimizing for each baudrate individually, but
not significantly so.

It has some advantages:

1. If NXP ever get around to fixing the auto-baud feature so it
actually works in conjunction with the fractional baudrate divider, then
you can set and forget your fractional divider and know it will work for
any baudrate the port user is likely to want to auto-baud to.
(Unfortunately autobaud is broken with fractional at present. Oooops!).
2. The fractional divider can be set once you know the CPU clock
rate. This is usually invariant for a particular system, so regardless
of the baudrate required you probably won't need to change this. This
means this calculation doesn't actually need to be done at runtime at
all....get the makefile to do it instead ! Just do the simple baudrate
calculation in your embedded code.

Cheers,

Bruce

________________________________

From: l... [mailto:l...] On Behalf
Of Deniz Can Cigsar
Sent: Tuesday, 2 March 2010 9:54 AM
To: l...
Subject: RE: [lpc2000] LPC2129 UART Help Needed

Ahmad,

It's generous of you.. I think we should collect code snippets for LPC
family and perfect them as a library.

However, I follow a simpler approach:

NXP released an Excel sheet that calculates variables for you for given
master clock. The main calculation bottleneck is the fractional boudrate
register. It uses step based approach but does a good job. I calculated
one boudrate such that 19200, keeping the fractional boudrate same, the
variable for desired boudrate is multiple of what it is for 19200..

Deniz

From: l... [mailto:l...] On Behalf
Of Ahmad
Sent: 01 March, 2010 21:48
To: l...
Subject: Re: [lpc2000] LPC2129 UART Help Needed

I've written a function (in C) to set UART baud rates to whatever you
want. It takes the CCLK and the desired baud rate, and the UART number
as inputs, and works out the register settings to provide the desired
baud rate. It is not a polished piece of code, nor is it well
commented. It does use floating-point math, but you could probably work
around that if you really wanted to avoid it.

If you're interested in wading through it (it's not guaranteed bug-free,
but it does work!) I'll post it here. You can set the baud rate to just
about any value you want (e.g. 73250kbps if you wish!), and if there is
any register setting combination that can give you that baud rate within
workable tolerances, it will do that for you. Else it will return an
error.

Want it? Just one condition: You don't copyright it. I don't want to
be debarred from using it in my own applications!!!

Let me know...

-Ahmad

On Mon, Mar 1, 2010 at 4:07 AM, rtos2010 wrote:

I'm using the Keil MCB2100 Demo Board. LPC2129, 12MHZ crystal and
PLLCFG_Val = 0x00000024

I'm using this UART demo code from " raju_nem
" at the following user group
link/ It says "testing" near the code so I;m not sure it is fully
working correctly?
http://tech.groups.yahoo.com/group/lpc2000/files/LPC2129_UART/

I integrated the code into my program and it compiles and links fine.
When I run it I get garbage characters from the serial port. Like the
baud rate is not correct.

I tried changing U0DLL and U0DLM with no luck. Is this demo code bad?
Does anyone have any other demo code that shows how to use the UART?
Thanks.
#define DESIRED_BAUDRATE 19200

#define CRYSTAL_FREQUENCY_IN_HZ 12000000
#define PCLK CRYSTAL_FREQUENCY_IN_HZ // since VPBDIV=0x01
#define DIVISOR (PCLK/(16*DESIRED_BAUDRATE))
void InitUart0(void)
{
/* U0LCR: UART0 Line Control Register
0x83: enable Divisor Latch access, set 8-bit word length,
1 stop bit, no parity, disable break transmission */
U0LCR=0x83;

/* VPBDIV: VPB bus clock divider
0x01: PCLK = processor clock */
VPBDIV=0x01;

/* U0DLL: UART0 Divisor Latch (LSB) */
U0DLL=DIVISOR&0xFF;

/* U0DLM: UART0 Divisor Latch (MSB) */
U0DLM=DIVISOR>>8;

/* U0LCR: UART0 Line Control Register
0x03: same as above, but disable Divisor Latch access */
U0LCR=0x03 ;

/* U0FCR: UART0 FIFO Control Register
0x05: Clear Tx FIFO and enable Rx and Tx FIFOs */
U0FCR=0x05 ;
Sorry I forgot to mention it, but this code runs on the LPC, so you can
change the baud rate real-time as you scale your clock... So no real
restrictions on clock PLL ratios... I agree NXP's excel sheet does a darn
good job and gives a pretty good insight of what can be achieved with all
those regisers!
On Tue, Mar 2, 2010 at 5:04 AM, Bruce Paterson <
b...@beamcommunications.com> wrote:

> I agree this is a sensible approach. The absolute error can be a tiny bit
> higher this way than optimizing for each baudrate individually, but not
> significantly so.
>
> It has some advantages:
>
> 1. If NXP ever get around to fixing the auto-baud feature so it
> actually works in conjunction with the fractional baudrate divider, then you
> can set and forget your fractional divider and know it will work for any
> baudrate the port user is likely to want to auto-baud to. (Unfortunately
> autobaud is broken with fractional at present. Oooops!).
> 2. The fractional divider can be set once you know the CPU clock rate.
> This is usually invariant for a particular system, so regardless of the
> baudrate required you probably wont need to change this. This means this
> calculation doesnt actually need to be done at runtime at all.get the
> makefile to do it instead ! Just do the simple baudrate calculation in your
> embedded code.
>
> Cheers,
>
> Bruce
> ------------------------------
>
> *From:* l... [mailto:l...] *On
> Behalf Of *Deniz Can Cigsar
> *Sent:* Tuesday, 2 March 2010 9:54 AM
> *To:* l...
> *Subject:* RE: [lpc2000] LPC2129 UART Help Needed
> Ahmad,
>
> Its generous of you.. I think we should collect code snippets for LPC
> family and perfect them as a library.
>
> However, I follow a simpler approach:
>
> NXP released an Excel sheet that calculates variables for you for given
> master clock. The main calculation bottleneck is the fractional boudrate
> register. It uses step based approach but does a good job. I calculated one
> boudrate such that 19200, keeping the fractional boudrate same, the variable
> for desired boudrate is multiple of what it is for 19200..
>
> Deniz
>
> *From:* l... [mailto:l...] *On
> Behalf Of *Ahmad
> *Sent:* 01 March, 2010 21:48
> *To:* l...
> *Subject:* Re: [lpc2000] LPC2129 UART Help Needed
>
> I've written a function (in C) to set UART baud rates to whatever you want.
> It takes the CCLK and the desired baud rate, and the UART number as inputs,
> and works out the register settings to provide the desired baud rate. It is
> not a polished piece of code, nor is it well commented. It does use
> floating-point math, but you could probably work around that if you really
> wanted to avoid it.
>
> If you're interested in wading through it (it's not guaranteed bug-free,
> but it does work!) I'll post it here. You can set the baud rate to just
> about any value you want (e.g. 73250kbps if you wish!), and if there is any
> register setting combination that can give you that baud rate within
> workable tolerances, it will do that for you. Else it will return an error.
>
> Want it? Just one condition: You don't copyright it. I don't want to be
> debarred from using it in my own applications!!!
>
> Let me know...
>
> -Ahmad
>
> On Mon, Mar 1, 2010 at 4:07 AM, rtos2010 wrote:
>
> I'm using the Keil MCB2100 Demo Board. LPC2129, 12MHZ crystal and
> PLLCFG_Val = 0x00000024
>
> I'm using this UART demo code from " raju_nem" at the following user group link/ It says "testing" near the code so I;m
> not sure it is fully working correctly?
> http://tech.groups.yahoo.com/group/lpc2000/files/LPC2129_UART/
>
> I integrated the code into my program and it compiles and links fine. When
> I run it I get garbage characters from the serial port. Like the baud rate
> is not correct.
>
> I tried changing U0DLL and U0DLM with no luck. Is this demo code bad?
> Does anyone have any other demo code that shows how to use the UART?
> Thanks.
> #define DESIRED_BAUDRATE 19200
>
> #define CRYSTAL_FREQUENCY_IN_HZ 12000000
> #define PCLK CRYSTAL_FREQUENCY_IN_HZ // since VPBDIV=0x01
> #define DIVISOR (PCLK/(16*DESIRED_BAUDRATE))
> void InitUart0(void)
> {
> /* U0LCR: UART0 Line Control Register
> 0x83: enable Divisor Latch access, set 8-bit word length,
> 1 stop bit, no parity, disable break transmission */
> U0LCR=0x83;
>
> /* VPBDIV: VPB bus clock divider
> 0x01: PCLK = processor clock */
> VPBDIV=0x01;
>
> /* U0DLL: UART0 Divisor Latch (LSB) */
> U0DLL=DIVISOR&0xFF;
>
> /* U0DLM: UART0 Divisor Latch (MSB) */
> U0DLM=DIVISOR>>8;
>
> /* U0LCR: UART0 Line Control Register
> 0x03: same as above, but disable Divisor Latch access */
> U0LCR=0x03 ;
>
> /* U0FCR: UART0 FIFO Control Register
> 0x05: Clear Tx FIFO and enable Rx and Tx FIFOs */
> U0FCR=0x05 ;
>
>
I posted a file UART_Baudrate_Calc.cpp to the files section. It contains the same calculation code I already posted here once, so I
am repeating myself, but this topic comes regularly each couple of months, so I posted it.

The calculation provides DL and FDR registers for given frequency and desired baudrate. It calculates the optimal settings and uses
no floating point. The calculation takes 225 iterations of the cycle body, which I believe is fast enough not to be really
recognizable/significant during the chip initialization.

It calculates settings for smallest baudrate higher than (or equal to) the target baudrate, and optionally it can also search for
largest baudrate lower than the target baudrate (in this mode it would search for both and pick the closest).

Written originally in a superior language (C++), so it needs adaption if C is (still) used :-)

With regards,
Jan

----- Original Message -----
From: "Bruce Paterson"
To:
Sent: Tuesday, March 02, 2010 12:34 AM
Subject: RE: [lpc2000] LPC2129 UART Help Needed
I agree this is a sensible approach. The absolute error can be a tiny
bit higher this way than optimizing for each baudrate individually, but
not significantly so.

It has some advantages:

1. If NXP ever get around to fixing the auto-baud feature so it
actually works in conjunction with the fractional baudrate divider, then
you can set and forget your fractional divider and know it will work for
any baudrate the port user is likely to want to auto-baud to.
(Unfortunately autobaud is broken with fractional at present. Oooops!).
2. The fractional divider can be set once you know the CPU clock
rate. This is usually invariant for a particular system, so regardless
of the baudrate required you probably won't need to change this. This
means this calculation doesn't actually need to be done at runtime at
all....get the makefile to do it instead ! Just do the simple baudrate
calculation in your embedded code.

Cheers,

Bruce

________________________________

From: l... [mailto:l...] On Behalf
Of Deniz Can Cigsar
Sent: Tuesday, 2 March 2010 9:54 AM
To: l...
Subject: RE: [lpc2000] LPC2129 UART Help Needed

Ahmad,

It's generous of you.. I think we should collect code snippets for LPC
family and perfect them as a library.

However, I follow a simpler approach:

NXP released an Excel sheet that calculates variables for you for given
master clock. The main calculation bottleneck is the fractional boudrate
register. It uses step based approach but does a good job. I calculated
one boudrate such that 19200, keeping the fractional boudrate same, the
variable for desired boudrate is multiple of what it is for 19200..

Deniz

From: l... [mailto:l...] On Behalf
Of Ahmad
Sent: 01 March, 2010 21:48
To: l...
Subject: Re: [lpc2000] LPC2129 UART Help Needed

I've written a function (in C) to set UART baud rates to whatever you
want. It takes the CCLK and the desired baud rate, and the UART number
as inputs, and works out the register settings to provide the desired
baud rate. It is not a polished piece of code, nor is it well
commented. It does use floating-point math, but you could probably work
around that if you really wanted to avoid it.

If you're interested in wading through it (it's not guaranteed bug-free,
but it does work!) I'll post it here. You can set the baud rate to just
about any value you want (e.g. 73250kbps if you wish!), and if there is
any register setting combination that can give you that baud rate within
workable tolerances, it will do that for you. Else it will return an
error.

Want it? Just one condition: You don't copyright it. I don't want to
be debarred from using it in my own applications!!!

Let me know...

-Ahmad

On Mon, Mar 1, 2010 at 4:07 AM, rtos2010 wrote:

I'm using the Keil MCB2100 Demo Board. LPC2129, 12MHZ crystal and
PLLCFG_Val = 0x00000024

I'm using this UART demo code from " raju_nem
" at the following user group
link/ It says "testing" near the code so I;m not sure it is fully
working correctly?
http://tech.groups.yahoo.com/group/lpc2000/files/LPC2129_UART/

I integrated the code into my program and it compiles and links fine.
When I run it I get garbage characters from the serial port. Like the
baud rate is not correct.

I tried changing U0DLL and U0DLM with no luck. Is this demo code bad?
Does anyone have any other demo code that shows how to use the UART?
Thanks.
#define DESIRED_BAUDRATE 19200

#define CRYSTAL_FREQUENCY_IN_HZ 12000000
#define PCLK CRYSTAL_FREQUENCY_IN_HZ // since VPBDIV=0x01
#define DIVISOR (PCLK/(16*DESIRED_BAUDRATE))
void InitUart0(void)
{
/* U0LCR: UART0 Line Control Register
0x83: enable Divisor Latch access, set 8-bit word length,
1 stop bit, no parity, disable break transmission */
U0LCR=0x83;

/* VPBDIV: VPB bus clock divider
0x01: PCLK = processor clock */
VPBDIV=0x01;

/* U0DLL: UART0 Divisor Latch (LSB) */
U0DLL=DIVISOR&0xFF;

/* U0DLM: UART0 Divisor Latch (MSB) */
U0DLM=DIVISOR>>8;

/* U0LCR: UART0 Line Control Register
0x03: same as above, but disable Divisor Latch access */
U0LCR=0x03 ;

/* U0FCR: UART0 FIFO Control Register
0x05: Clear Tx FIFO and enable Rx and Tx FIFOs */
U0FCR=0x05 ;