Author Topic: <SOLVED> Bitfield definition results in error  (Read 1811 times)

0 Members and 1 Guest are viewing this topic.

Offline ExystenceTopic starter

  • Newbie
  • Posts: 2
  • Country: nl
<SOLVED> Bitfield definition results in error
« on: December 29, 2021, 11:16:48 am »
Hi,

I'm always strugling with bitfields (because I don't use it very often).
My bitfield is defined in main.h, like:
Code: [Select]

typedef struct
{
unsigned int unused: 4;
unsigned int DTIME: 2;
unsigned int ISGAIN: 2;
unsigned int EXSTALL: 1;
unsigned int MODE: 4;
unsigned int RSTEP: 1;
unsigned int RDIR: 1;
unsigned int ENBL: 1;
} structDRV8711CTRL;
extern structDRV8711CTRL DRV8711CTRL;

And in main.c as:
Code: [Select]
structDRV8711CTRL DRV8711CTRL;

From within another file windingProcess.c the I use the code:
Code: [Select]
DRV8711MODE=4;
DRV8711CTRL.DTIME=3;
DRV8711CTRL.ISGAIN=0;
DRV8711CTRL.EXSTALL=0;
DRV8711CTRL.MODE=4;
DRV8711CTRL.RSTEP=0;
DRV8711CTRL.RDIR=0;
DRV8711CTRL.ENBL=1;
data=SPIserial(1,1,DRV8711CTRL);

Which results in error: windingProcess.c:120:5: error: incompatible type for argument 3 of 'SPIserial'

I guess because an unsigned int is expected as declared in the file procEE.h: extern unsigned int SPIserial(unsigned int SPIn, unsigned int target, unsigned int data);

But I can't get a grip on where it's going wrong. I've searched online for several solutions, but none worked so far.

Can anyone help in this?

Thanx!

« Last Edit: December 29, 2021, 04:01:04 pm by Exystence »
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8179
  • Country: fi
Re: Bitfield definition results in error
« Reply #1 on: December 29, 2021, 11:29:03 am »
You are trying to put a struct into unsigned int. Not going to work.

Personally, I solve this by wrapping the struct inside an union to create aliases in all types I need to work with.

Remember that bitfields are implementation defined and the ordering and padding of the elements only works within one compiler. I'm usually fine with that, language purists are not. In any case, you need to be aware of this.

Code: [Select]
typedef union
{
    struct __attribute__((packed)) {  // seems to be 16 bits actually
    unsigned int unused: 4;
    unsigned int DTIME: 2;
    unsigned int ISGAIN: 2;
    unsigned int EXSTALL: 1;
    unsigned int MODE: 4;
    unsigned int RSTEP: 1;
    unsigned int RDIR: 1;
    unsigned int ENBL: 1;
    };
    uint16_t u16;
    uint8_t u8[2];
} structDRV8711CTRL;

...

data=SPIserial(1,1,DRV8711CTRL.u16);

SPIserial() should be modified to use stdint types, in my opinion. Does it really expect at 16-bit or 32-bit argument? What is the platform? unsigned int might be 16 or 32 bits.
 
The following users thanked this post: Exystence

Offline ExystenceTopic starter

  • Newbie
  • Posts: 2
  • Country: nl
Re: Bitfield definition results in error
« Reply #2 on: December 29, 2021, 03:59:51 pm »
Thanx!

I'm using the 16 bit controller PIC24FJ128GA308 and MPLABX with XC16.

The result is:

In main.h I had to include <stdio.h> (even though it is included in main.c (?))

The code in main.h is:
Code: [Select]
typedef union
{
    uint16_t ALL;

    struct
    {
        unsigned int unused: 4;
        unsigned int DTIME: 2;
        unsigned int ISGAIN: 2;
        unsigned int EXSTALL: 1;
        unsigned int MODE: 4;
        unsigned int RSTEP: 1;
        unsigned int RDIR: 1;
        unsigned int ENBL: 1;
    };
} structDRV8711CTRL;

extern structDRV8711CTRL DRV8711CTRL;
And in main.c:
Code: [Select]
structDRV8711CTRL DRV8711CTRL;

Then in windingProcess.c the code is:
Code: [Select]
    DRV8711MODE=4;
    DRV8711CTRL.DTIME=3;
    DRV8711CTRL.ISGAIN=1;
    DRV8711CTRL.EXSTALL=0;
    DRV8711CTRL.MODE=DRV8711MODE;
    DRV8711CTRL.RSTEP=0;
    DRV8711CTRL.RDIR=0;
    DRV8711CTRL.ENBL=1;
   
    data=SPIserial(1,1,DRV8711CTRL.ALL);

Now I only have to remember it!
« Last Edit: December 29, 2021, 04:05:02 pm by Exystence »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf