Regarding the C code when dealing with I/Os, I would like to refer to the schematic net names (like: DAC_CSn) and not to the MCU port pins (like: LATBbits.LATB5)
So I order to get what I want I took a look on how these I/O bit-field look like in the device header files. Then I just copied that bit layout to my main c code file and made the following adjustments. Note this is actually XC8 code.
typedef union
{
struct
{
unsigned :4; // RB0 to RB3 not present on this MCU
unsigned DEMUX1_En :1; // RB4
unsigned DAC_CSn :1; // RB5
unsigned DAC_SCK :1; // RB6 DAC_SCK is controlled by SPI peripheral
unsigned DAC_LDACn :1; // RB7
};
} B_LAT_TRIS_REDEFbits_t;
extern volatile B_LAT_TRIS_REDEFbits_t LATB_REDEFbits @ &LATBbits;
extern volatile B_LAT_TRIS_REDEFbits_t TRISB_REDEFbits @ &TRISBbits;
With that @ operator I can place it directly at the same address of LATBbits and TRISBbits. Now I can use LATB_REDEFbits and use my own defined names. Only thing to remember is to reference portB.
Now I've selected a 16-bit MCU and I want the same functionality with XC16. However I can't use the @ operator anymore. But with __attribute__((__sfr__)) I'm getting close:
typedef struct tagB_LAT_TRIS_REDEF_BITS
{
unsigned MY_NAME0 :1;
unsigned MY_NAME1 :1;
unsigned MY_NAME2 :1;
unsigned MY_NAME3 :1;
unsigned MY_NAME4 :1;
unsigned MY_NAME5 :1;
unsigned MY_NAME6 :1;
unsigned MY_NAME7 :1;
} B_LAT_TRIS_REDEF_BITS;
extern volatile B_LAT_TRIS_REDEF_BITS LATB_REDEFbits __attribute__((__sfr__));
extern volatile B_LAT_TRIS_REDEF_BITS TRISB_REDEFbits __attribute__((__sfr__));
The underscores around __sfr__ seems act as a placeholder for the actual address to be filled in during the linking process.
It doesn't seem to be possible to access the actual addresses of the IO registers from the C code. Like I was capable of in the XC8 variant. The IO address constants are all defined in the linker script file for each device (the *.gld files). Therefore I had to write a little custom linker script (port_redefs.gld):
----
INCLUDE "p30F3012.gld"
_LATB_REDEFbits = _LATBbits;
_TRISB_REDEFbits = _TRISBbits;
----
In MPLABX I add this gld file to the Linker Files section. Then this one gets called during linking instead of "p30F3012.gld" in this case. This works.
Maybe I put the redefinition bit-fields into a single header file. Then I just need to make such a header file for each board.
Would this be a good approach? Do you think something could be better in this process? Anyway, I'd strive for maximum code readability and low maintenance. I can't seem to get rid of my custom gld file, can I?
Best regards,
Zeyneb