EmbeddedRelated.com
Forums

Using Bit Field structures to access LPC-2000 registers

Started by jdauchot May 27, 2009
Hi All

I see from IAR C code examples that they use bit field structures to access the LPC-2000 registers. This a neat idea.

My knowledge of C does not go deep enough to understand the way IAR C code is written which is complicated enough as it goes very deep into lots of embedded include files.

Has anyone used this technique using GCC/Yargarto tool chains. If so can anyone send me a sample example of this and I will try to go from there.

Regards
Jean-Jacques

An Engineer's Guide to the LPC2100 Series

Hi,

> I see from IAR C code examples that they use bit field structures to
access
> the LPC-2000 registers. This a neat idea.
>
> My knowledge of C does not go deep enough to understand the way IAR C code
> is written which is complicated enough as it goes very deep into lots of
> embedded include files.
>
> Has anyone used this technique using GCC/Yargarto tool chains. If so can
> anyone send me a sample example of this and I will try to go from there.

Don't. It won't work, for lots of reasons. You can try, but you'll end up
chucking it in the bin.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Hi Paul

I presume you had a go at this?

I had a very brief go at it and got very confused.

So I am asking if anyone had a go

Regards

JJ

_____

From: l... [mailto:l...] On Behalf Of
Paul Curtis
Sent: 27 May 2009 16:18
To: l...
Subject: RE: [lpc2000] Using Bit Field structures to access LPC-2000
registers

Hi,

> I see from IAR C code examples that they use bit field structures to
access
> the LPC-2000 registers. This a neat idea.
>
> My knowledge of C does not go deep enough to understand the way IAR C code
> is written which is complicated enough as it goes very deep into lots of
> embedded include files.
>
> Has anyone used this technique using GCC/Yargarto tool chains. If so can
> anyone send me a sample example of this and I will try to go from there.

Don't. It won't work, for lots of reasons. You can try, but you'll end up
chucking it in the bin.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.
co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors



Hi,

> I presume you had a go at this?

Nope. I know better.

> I had a very brief go at it and got very confused.
>
> So I am asking if anyone had a go

As you have chosen GCC as your compiler, I suggest you do not even try. GCC
will optimize writes to bitfields and will happily use a reduced-width
instruction if it pleases. Like I said, don't do this.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors

Hi JJ,

>> I presume you had a go at this?
>
> Nope. I know better.
>
>> I had a very brief go at it and got very confused.
>>
>> So I am asking if anyone had a go
>
> As you have chosen GCC as your compiler, I suggest you do not even try. GCC
> will optimize writes to bitfields and will happily use a reduced-width
> instruction if it pleases. Like I said, don't do this.

I concur with Paul's comments.

Depending on the processor, GCC will happily convert the
operations on the bitfields into 8-bit, 16-bit, or 32-bit
transactions, and you have no control over when this
will happen.

You also get into trouble with 'write-1 to clear' registers
that are defined using bitfields. Manipulation of a bitfield
will cause a read-modify-write sequence to occur.

You are better off using the & and | operators to mask and
set bits.

Cheers,
Dave

Well I better start converting all those bit field instruction to normal
ones.

I want to convert several LCD drivers etc for the LPC-2478 STK sample code

Regards

JJ

_____

From: l... [mailto:l...] On Behalf Of
Paul Curtis
Sent: 27 May 2009 17:04
To: l...
Subject: RE: [lpc2000] Using Bit Field structures to access LPC-2000
registers

Hi,

> I presume you had a go at this?

Nope. I know better.

> I had a very brief go at it and got very confused.
>
> So I am asking if anyone had a go

As you have chosen GCC as your compiler, I suggest you do not even try. GCC
will optimize writes to bitfields and will happily use a reduced-width
instruction if it pleases. Like I said, don't do this.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.
co.uk
CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors



Danger, Will Robinson, Danger!

Do not do this. It's a attractive trap. There are too many things that go
wrong. Access width is not guaranteed, the process is inherently
read-modify-write and that won't work with some registers etc...

Robert

Original Message:
-----------------
From: jdauchot t...@gotadsl.co.uk
Date: Wed, 27 May 2009 15:15:14 -0000
To: l...
Subject: [lpc2000] Using Bit Field structures to access LPC-2000 registers
Hi All

I see from IAR C code examples that they use bit field structures to access
the LPC-2000 registers. This a neat idea.

My knowledge of C does not go deep enough to understand the way IAR C code
is written which is complicated enough as it goes very deep into lots of
embedded include files.

Has anyone used this technique using GCC/Yargarto tool chains. If so can
anyone send me a sample example of this and I will try to go from there.

Regards
Jean-Jacques

Hi Daniel

Effectively the LPC2478 and LPC2378 have the same register set apart from the LCD interface

I have got a basic LPC2478 project working OK based on LPC2378 code. Flashing LEDs etc

I would like to convert IAR LPC2478 LCD code projects to Yargarto tool chain.

But IAR uses those bit field structures to access registers that nobody likes for some good reasons it appears.

I have a lot work to do the convert the bit field code to more conversional instructions

Regards

Jean-Jacques

--- In l..., "Jean-Jacques Dauchot" wrote:
>
> Well I better start converting all those bit field instruction to normal
> ones.
>
> I want to convert several LCD drivers etc for the LPC-2478 STK sample code
>
>
>
> Regards
>
>
>
> JJ
>
>
>
> _____
>
> From: l... [mailto:l...] On Behalf Of
> Paul Curtis
> Sent: 27 May 2009 17:04
> To: l...
> Subject: RE: [lpc2000] Using Bit Field structures to access LPC-2000
> registers
>
>
> Hi,
>
> > I presume you had a go at this?
>
> Nope. I know better.
>
> > I had a very brief go at it and got very confused.
> >
> > So I am asking if anyone had a go
>
> As you have chosen GCC as your compiler, I suggest you do not even try. GCC
> will optimize writes to bitfields and will happily use a reduced-width
> instruction if it pleases. Like I said, don't do this.
>
> --
> Paul Curtis, Rowley Associates Ltd http://www.rowley.
> co.uk
> CrossWorks for ARM, MSP430, AVR, MAXQ, and now Cortex-M3 processors
>
>
>

jdauchot wrote:
>
> But IAR uses those bit field structures to access registers that nobody likes for some good reasons it appears.
I just did a quick test. Code:
typedef unsigned int uint;

struct Pinsel {
uint p0_16:2;
uint p0_17:2;
uint p0_18:2;
uint p0_19:2;
uint p0_20:2;
uint p0_21:2;
uint p0_22:2;
uint p0_23:2;
uint p0_24:2;
uint p0_25:2;
uint p0_26:2;
uint p0_27:2;
uint p0_28:2;
uint p0_29:2;
uint p0_30:2;
uint p0_31:2;
};
volatile Pinsel& _pinsel1bits = *(volatile Pinsel*)0xe002c004;
int main()
{
_pinsel1bits.p0_16 = 0b01; // P0.16 = EINT0 (should: clear+set bits)
_pinsel1bits.p0_27 = 0b00; // P0.27 = GPIO 0.27 (should: clear bits)
_pinsel1bits.p0_21 = 0b11; // P0.21 = Capture 1.3 (should: set bits)

for (;;) ;
}

Compiled with (OS X, g++ 4.3.3):
/opt/yagarto/bin/arm-elf-g++ -marm -mcpu=arm7tdmi-s -Os -fno-exceptions
-fno-rtti -ffunction-sections -ffreestanding -S -c foo.cpp

Resulting code:

.file "foo.cpp"
.section .text.main,"ax",%progbits
.align 2
.global main
.type main, %function
main:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
ldr r3, .L4
ldr r2, [r3, #0]
ldr r3, [r2, #0]
bic r3, r3, #2
orr r3, r3, #1
str r3, [r2, #0]
ldr r3, [r2, #0]
bic r3, r3, #12582912
str r3, [r2, #0]
ldr r3, [r2, #0]
orr r3, r3, #3072
str r3, [r2, #0]
.L2:
b .L2
.L5:
.align 2
.L4:
.word _pinsel1bits
.size main, .-main
.global _pinsel1bits
.section .rodata
.align 2
.type _pinsel1bits, %object
.size _pinsel1bits, 4
_pinsel1bits:
.word -536690684
.ident "GCC: (GNU) 4.3.3"

Which looks perfectly correct to me and exhibits none of the problems
that were mentioned.

I coded many of the LPC21x9 registers in C without bitfields, even though I use the IAR compiler. Not code per se, just constants. Bitfields or constants, the same code gets generated. It's not that hard.
--- In l..., Jan Brittenson wrote:
>
> jdauchot wrote:
> >
> > But IAR uses those bit field structures to access registers that nobody likes for some good reasons it appears.
> I just did a quick test. Code:
> typedef unsigned int uint;
>
> struct Pinsel {
> uint p0_16:2;
> uint p0_17:2;
> uint p0_18:2;
> uint p0_19:2;
> uint p0_20:2;
> uint p0_21:2;
> uint p0_22:2;
> uint p0_23:2;
> uint p0_24:2;
> uint p0_25:2;
> uint p0_26:2;
> uint p0_27:2;
> uint p0_28:2;
> uint p0_29:2;
> uint p0_30:2;
> uint p0_31:2;
> };
> volatile Pinsel& _pinsel1bits = *(volatile Pinsel*)0xe002c004;
> int main()
> {
> _pinsel1bits.p0_16 = 0b01; // P0.16 = EINT0 (should: clear+set bits)
> _pinsel1bits.p0_27 = 0b00; // P0.27 = GPIO 0.27 (should: clear bits)
> _pinsel1bits.p0_21 = 0b11; // P0.21 = Capture 1.3 (should: set bits)
>
> for (;;) ;
> }
>
> Compiled with (OS X, g++ 4.3.3):
> /opt/yagarto/bin/arm-elf-g++ -marm -mcpu=arm7tdmi-s -Os -fno-exceptions
> -fno-rtti -ffunction-sections -ffreestanding -S -c foo.cpp
>
> Resulting code:
>
> .file "foo.cpp"
> .section .text.main,"ax",%progbits
> .align 2
> .global main
> .type main, %function
> main:
> @ args = 0, pretend = 0, frame = 0
> @ frame_needed = 0, uses_anonymous_args = 0
> @ link register save eliminated.
> ldr r3, .L4
> ldr r2, [r3, #0]
> ldr r3, [r2, #0]
> bic r3, r3, #2
> orr r3, r3, #1
> str r3, [r2, #0]
> ldr r3, [r2, #0]
> bic r3, r3, #12582912
> str r3, [r2, #0]
> ldr r3, [r2, #0]
> orr r3, r3, #3072
> str r3, [r2, #0]
> .L2:
> b .L2
> .L5:
> .align 2
> .L4:
> .word _pinsel1bits
> .size main, .-main
> .global _pinsel1bits
> .section .rodata
> .align 2
> .type _pinsel1bits, %object
> .size _pinsel1bits, 4
> _pinsel1bits:
> .word -536690684
> .ident "GCC: (GNU) 4.3.3"
>
> Which looks perfectly correct to me and exhibits none of the problems
> that were mentioned.
>