Keil™, An ARM® Company

Discussion Forum

LPC2368 UART register sizes in lpc23xx.h file?

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Ken VanDeWater
Posted
1-Jul-2008 06:00
Toolset
ARM
New! LPC2368 UART register sizes in lpc23xx.h file?

I have a question about the lpc23xx.h file version 1.04

I was wondering why some of the UART registers were defined as unsigned long, when they appear to only be 8 bits (unsigned char)?
For example, the RBR, THR, DLL, DLM, FCR, LCR, LSR, SCR and TER registers for all the UARTS.
Is there a reason for this, or was this just a cut and paste typo?

Read-Only
Author
Robert Rostohar
Posted
1-Jul-2008 22:22
Toolset
ARM
New! RE: LPC2368 UART register sizes in lpc23xx.h file?

It's not a typo.

LPC23xx is an 32-bit ARM device and using 32-bit registers generates the best code. This is the reason why UART registers are defined as unsigned long.

Read-Only
Author
Ken VanDeWater
Posted
2-Jul-2008 06:14
Toolset
ARM
New! RE: LPC2368 UART register sizes in lpc23xx.h file?

That's what I thought at first, but I'm not so sure...
For example:

recData is unsigned char, REC_DATA (U0RBR) is unsigned long

  305:         recData = (unsigned char)REC_DATA;
0x00000500  E5900000  LDR       R0,[R0]
0x00000504  E20060FF  AND       R6,R0,#0x000000FF

recData is unsigned char, REC_DATA (U0RBR) is unsigned char

   305:         recData = REC_DATA;
0x00000500  E5D06000  LDRB      R6,[R0]
Read-Only
Author
Robert Rostohar
Posted
2-Jul-2008 07:34
Toolset
ARM
New! RE: LPC2368 UART register sizes in lpc23xx.h file?

The second case generates only one instruction (no cast is required) and this is the best way to use it (when REC_DATA is unsigned long).

Read-Only
Author
Ken VanDeWater
Posted
2-Jul-2008 08:05
Toolset
ARM
New! RE: LPC2368 UART register sizes in lpc23xx.h file?

I think you might be confused...
In the first case (when REC_DATA is unsigned long) the compiler generates two instructions whether or not I use the cast (the cast is assumed by the compiler since I'm loading an unsigned long into an unsigned char variable).
In the second case, I changed the definition of REC_DATA(U0RBR) from unsigned long to unsigned char which matches the variable I was using. This allowed the compiler to only use one (LDRB- load register byte value) instruction which is obviously more efficient (speed wise).
If I left the REC_DATA(U0RBR) definition as unsigned long and used a variable that was an unsigned long, i would be back down to one (LDR - load 32 bit word from memory) instruction, but this would be less efficient memory wise (just wasted 3 bytes).
So, back to my original question, why keep the 8 bit UART registers defined as unsigned long?

Read-Only
Author
Robert Rostohar
Posted
2-Jul-2008 23:01
Toolset
ARM
New! RE: LPC2368 UART register sizes in lpc23xx.h file?

I think you might be confused...
Not really, I have just overlooked that in the second case unsigned char was used.

If I left the REC_DATA(U0RBR) definition as unsigned long and used a variable that was an unsigned long, i would be back down to one (LDR - load 32 bit word from memory) instruction, but this would be less efficient memory wise (just wasted 3 bytes).
Not always true regarding memory usage. When variables are local they are located in registers (or stack) and since they are 32-bit anyway there is no real wasted memory.

So, back to my original question, why keep the 8 bit UART registers defined as unsigned long?
Since 32-bit is native size it should generate more efficient code but as you have tried out this is not always the case. So using 8-bit definitions might be better.

Read-Only
Author
Per Westermark
Posted
2-Jul-2008 23:46
Toolset
ARM
New! RE: LPC2368 UART register sizes in lpc23xx.h file?

It is quite common that the developer selects the int or unsigned int data types. So it isn't an unreasonable assumption that the SFR can be accessed with 32-bit accesses. The chip designer have designed the chip to allow such accesses.

Anyway: The most general solution is to define two sets of definitions to access these registers, just as the GPIO ports has 8-bit, 16-bit and 32-bit access methods.

Next Thread | Thread List | Previous Thread Start a Thread | Settings