An MCC Mystery Solved

MCC-logo

MPLAB Code Configurator is a tool that has revolutionised the way I work with microcontrollers. I use it every day, for each and every project and, in fact, I found out that I am creating more projects than ever because of MCC.

It is so easy to set up an experiment, a little proof of concept or simply to sketch out the skeleton of a new application that I don’t even think about it, I just do it.. in minutes!

See the many examples I prepared for the Rocket Science book and for the Curiosity/Simplicity boards. Even the simplest activity such as defining the GP I/O pins is so much more convenient with MCC, besides, it never forgets to clear the ANSEL bits for me and it creates a pretty illustration that helps with the project documentation …

pinout

See the pin RC5? I gave it a custom name (LED) and made it an output with only a couple of clicks.

GPIOdialog

Once the “Generate Code” button is pressed a number of macros are created and placed in a file named:  “pin_manager.h”, intuitively enough. Here is a short excerpt:

// get/set LED aliases
#define LED_TRIS                TRISC5
#define LED_LAT                 LATC5
#define LED_PORT                RC5
#define LED_WPU                 WPUC5
#define LED_SetHigh()           do { LATC5 = 1; } while(0)
#define LED_SetLow()            do { LATC5 = 0; } while(0)
#define LED_Toggle()            do { LATC5 = ~LATC5; } while(0)
#define LED_GetValue()          RC5
#define LED_SetDigitalInput()   do { TRISC5 = 1; } while(0)
#define LED_SetDigitalOutput()  do { TRISC5 = 0; } while(0)
#define LED_SetPullup()         do { WPUC5 = 1; } while(0)
#define LED_ResetPullup()       do { WPUC5 = 0; } while(0)

Using these macros I can ensure that my code is going to be easier to read and in the future easier to port to other device or simply different I/O configurations. Being macros then, there is no waste of code space, the ones I don’t use, won’t generate any code.

Also note how some of the macros are more in the PIC “assembly style“, such as LED_TRIS and LED_PORT, while others are more in the “wiring style“, a bit more abstracted such as LED_SetHigh() and LED_SetLow(). I suppose it can be a matter of personal taste or past experiences…

But wait, what is going on with those do{…}while( 0) loops?

If you have not practiced your MISRA recently, it might seem that some MCC bug got into the pin manager and bloated our code unnecessarily. Nothing further from the truth, that is a really old trick designed to make those macros really safe to use in all  (C language) possible scenarios.

There are plenty of good articles on the web [for example] that explain in detail the  (not so) mysterious reasons for this ‘trick’, but the short of it goes as follows:

These macros are different from the ones above because they contain an assignment and possibly more than one. A pair of curly brackets would seem to solve the problem but  when used inside an if/else statement, a single semicolon (added after the macro) would cause havoc once the macro is expanded. The do/while wrapper solves the dilemma quite elegantly.

Most importantly, once the parser is satisfied, the loop is immediately optimised out by the compiler, with no residual performance penalty. In fact the XC8 compiler uses the full capabilities of the PIC instruction set and transforms those constructs into simple bit set (BSF) and bit clear (BCF) instructions!

This entry was posted in PIC16, Tips and Tricks, Tools and tagged , , . Bookmark the permalink.