Yahoo Groups archive

Lpc2000

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

Message

Re: [lpc2000] Re: Looking to buy compiler

2005-11-08 by Tom Walsh

????????? ??????? wrote:

>On Tue, 08 Nov 2005 04:47:49 -0500
>  Tom Walsh <tom@...> wrote:
>  
>
>>vaneenbergen wrote:
>>
>>    
>>
>>>That the first bit of the second byte also changed is very possible. 
>>>This is de to the processor. The timer register should be handled in 
>>>a 32 bit access. this is what i found out. so instead of these kind 
>>>of structures i just handle them in 32-bit. this way it is also 
>>>quicker, you can change all values at the same time.
>>>
>>>is this really the fault of the compiler?????
>>> 
>>>
>>>      
>>>
>>He didn't understand what it was that he wrote so how can he answer 
>>that 
>>question?
>>
>>
>>TomW
>>
>>    
>>
>
>What you mean? I think it obviously, that it's really fault of 
>compiler. I explain my point of view to Paul
>  
>
Okay, while washing some dishes in the kitchen, I finally realized that 
you skipped ahead to blame the compiler and were convinced that your 
code is correct.  It is not.

I believe, and correct me if I am wrong, that what you were trying to do 
was to describe the T0MCR register so that you could access it and 
change values???

If so, here is what you should have done:

================= packed struct ===================
typedef struct __attribute__ ((packed))
{
__REG32 MR0I :1;
__REG32 MR0R :1;
__REG32 MR0S :1;

__REG32 MR1I :1;
__REG32 MR1R :1;
__REG32 MR1S :1;

__REG32 MR2I :1;
__REG32 MR2R :1;
__REG32 MR2S :1;

__REG32 MR3I :1;
__REG32 MR3R :1;
__REG32 MR3S :1;
__REG32 :4;
} __txmcr_bits;

#define T0MCRbits (*(volatile __txmcr_bits *)0xE0004014)

===================== snip =======================

The volatile can stay, it is harmless.  What is key is the 
"__attribute__ ((packed))" keyphrase.  What that means is that the 
padding between elements of the structure is to be removed.  If you say 
this:

=============== begin ===============

struct FLESHY {
    long    foo;
    char   bar;
    long   done;
};

struct SMALLER {
    long    foo;
    char   bar;
    long   done;
} __attribute__ ((packed));

struct FLESHY bean;

struct SMALLER soup;

============== snip ================

You will find that "bean" is 12 bytes and "soup" is 9 bytes...  This is 
because the structure has been packed, all the "air" has been removed.  
ok?  Try it, do a printf ("%d\n", sizeof(bean)) and a printf("%d\n", 
sizeof(soup)).

Now, what you said was this:  "MR01 is significant to 1 bit and is 
aligned on a 32 bit boundry".

gcc did not do it "wrong", you just did not read what you told it.  The 
compiler did exactly what you told it to do.

Look at this, this is my definition of the RTCTCR registers of the LPC2138:

=========== begin ================
typedef struct __attribute__ ((packed))
{
    uint    seconds:6;
    uint    reserved:2;
    uint    minutes:6;
    uint    reserved1:2;
    uint    hours:5;
    uint    reserved2:3;
    uint    dayOfWeek:3;
    uint    reserved3:5;
} rtcCTIME0_t;

typedef struct __attribute__ ((packed)) {
    uint    dayOfMonth:5;
    uint    reserved:3;
    uint    month:4;
    uint    reserved1:4;
    uint    year:12;
    uint    reserved2:4;
} rtcCTIME1_t;

typedef struct __attribute__ ((packed)) {
    uint    dayOfYear:12;
    uint    reserved:20;
} rtcCTIME2_t;


typedef struct
{
  REG_8 ilr;            // Interrupt Location Register
  REG_8 _pad0[3];
  REG16 ctc;            // Clock Tick Counter
  REG16 _pad1;
  REG_8 ccr;            // Clock Control Register
  REG_8 _pad2[3];
  REG_8 ciir;            // Counter Increment Interrupt Register
  REG_8 _pad3[3];
  REG_8 amr;            // Alarm Mask Register
  REG_8 _pad4[3];
  rtcCTIME0_t ctime0;            // Consolidated Time Register 0
  rtcCTIME1_t ctime1;            // Consolidated Time Register 1
  rtcCTIME2_t ctime2;            // Consolidated Time Register 2
  REG_8 sec;            // Seconds Register
  REG_8 _pad5[3];
  REG_8 min;            // Minutes Register
  REG_8 _pad6[3];
  REG_8 hour;            // Hours Register
  REG_8 _pad7[3];
  REG_8 dom;            // Day Of Month Register
  REG_8 _pad8[3];
  REG_8 dow;            // Day Of Week Register
  REG_8 _pad9[3];
  REG16 doy;            // Day Of Year Register
  REG16 _pad10;
  REG_8 month;            // Months Register
  REG_8 _pad11[3];
  REG16 year;            // Years Register
  REG32 _pad12[8];
  REG_8 alsec;            // Alarm Seconds Register
  REG_8 _pad13[3];
  REG_8 almin;            // Alarm Minutes Register
  REG_8 _pad14[3];
  REG_8 alhour;        // Alarm Hours Register
  REG_8 _pad15[3];
  REG_8 aldom;            // Alarm Day Of Month Register
  REG_8 _pad16[3];
  REG_8 aldow;            // Alarm Day Of Week Register
  REG_8 _pad17[3];
  REG16 aldoy;            // Alarm Day Of Year Register
  REG16 _pad18;
  REG_8 almon;            // Alarm Months Register
  REG_8 _pad19[3];
  REG16 alyear;        // Alarm Years Register
  REG16 _pad20;
  REG16 preint;        // Prescale Value Register (integer)
  REG16 _pad21;
  REG16 prefrac;        // Prescale Value Register (fraction)
  REG16 _pad22;
} rtcRegs_t;

#define RTC             ((rtcRegs_t *)0xE0024000)
#define RTCTCR                ((rtcTCR_t *)0xe0024020)

============ snip ================

The difference with gcc is that you have to _explicitly_ tell it to pack 
a structure.

TomW



-- 
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------------------------------------------

Attachments

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.