Reputation: 13209
In microchip C30 compiler i can set pin i/o value using LAT register in this way:
LATBbits.LATB10=1;
LATBbits is defined as:
typedef struct tagLATBBITS {
unsigned LATB0:1;
unsigned LATB1:1;
unsigned LATB2:1;
unsigned LATB3:1;
unsigned LATB4:1;
unsigned LATB5:1;
unsigned LATB6:1;
unsigned LATB7:1;
unsigned LATB8:1;
unsigned LATB9:1;
unsigned LATB10:1;
unsigned LATB11:1;
unsigned LATB12:1;
unsigned LATB13:1;
unsigned LATB14:1;
unsigned LATB15:1;
} LATBBITS;
extern volatile LATBBITS LATBbits __attribute__((__sfr__));
My target is to write a function that can set i/o value using LAT register as an argument, in pseudocode:
void setPin(unsigned int* latReg, unsigned int value){
(*latReg)=value;
}
setPin(&LATBbits.LATB10, 1);
Unfortunately this code won't compile because "cannot take address of bit-field 'LATB10'".
I need it because i want to realize a simil-class library that can handle a port expander. Each port expander can have different pins, so i need to configure it and i think to do something like this:
typedef struct sPortExpander{
unsigned int* CS;
unsigned int* SPBUFF;
ecc...
} PortExpander
void PortExpander_setOutput(PortExpander p, unsigned char value){
(*p.CS)=0;
// Send SPI data
(*p.CS=1);
}
In this way i can manage multiple port expander.
So, there is a way to do what i try to do?
Thanks.
Upvotes: 2
Views: 244
Reputation:
Declare the struct as __attribute__((packed))
, then use:
void function setPin(struct LATBBITS *reg, unsigned int fieldno, unsigned int value){
if (value)
*(uint16_t *)reg |= (1 << fieldno);
else
*(uint16_t *)reg &= ~(1 << fieldno);
}
Upvotes: 1