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?
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.
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]
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).
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?
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.
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.