Author Topic: MPLABX XC16 enhance code readability I/O bit-fields  (Read 2787 times)

0 Members and 1 Guest are viewing this topic.

Offline ZeynebTopic starter

  • Regular Contributor
  • *
  • Posts: 233
  • Country: nl
MPLABX XC16 enhance code readability I/O bit-fields
« on: August 02, 2015, 05:34:17 pm »
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
goto considered awesome!
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: MPLABX XC16 enhance code readability I/O bit-fields
« Reply #1 on: August 02, 2015, 08:49:45 pm »
Any reason you can't just do "#define DAC_CSn LATBbits.LATB5"?
 

Offline funkathustra

  • Regular Contributor
  • *
  • Posts: 150
  • Country: us
Re: MPLABX XC16 enhance code readability I/O bit-fields
« Reply #2 on: August 02, 2015, 11:57:18 pm »
Any reason you can't just do "#define DAC_CSn LATBbits.LATB5"?

+1.

The preprocessor is your friend.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf