Electronic – way to write a generic GPIO code for MSP430

cgpiolibrarymsp430

I'm currently working on an MSP430 board and I'm trying to create libraries for it so I can easily use them on my project. I'm starting with basic Digital I/O functions.

Say for example I need to set P1.0 ON. In that case, normally what I do is:

P1SEL &= (~BIT0);           // Set P1.0 SEL for GPIO
P1DIR |= BIT0;              // Set P1.0 as Output
P1OUT |= BIT0;              // Set P1.0 HIGH

But I need to write a function that will just take Port Num, Pin and Value and set the above registers. Something like this:

void setVal(int x, int y) {
    PxSEL &= (~BITy);
    PxDIR |= BITy;
    PxOUT |= BITy;
}

Where x is Port and Y is Pin. Is there a way I can implement such a function? OR has this been done before? If yes, please share the link for the same. I was thinking out maybe using a lookup table and selecting the Register via indexing. But I'm not sure if that's a good approach. Any help would be appreciated.

Thanks

Best Answer

This can be done with a set of macros:

#define GPIO_MODE_GPIO(...)  GPIO_MODE_GPIO_SUB(__VA_ARGS__)
#define GPIO_MODE_GPIO_SUB(port, pin) (P##port##SEL &= ~(1<<pin)) // making an assumption about register layout here

#define GPIO_OUT_SET(...)  GPIO_OUT_SET_SUB(__VA_ARGS__)
#define GPIO_OUT_SET_SUB(port, pin) (P##port##OUT &= ~(1<<pin))

//etc...

The ## operator does string concatenation in the preprocessor. The two-level macros are used to allow a level of macro expansion to happen between the first and second macros, which allows you to do things like this:

#define LED_IO  1,5
GIPO_OUT_SET(LED_IO);

Without that extra indirection, the preprocessor would complain about not having enough arguments to the GPIO_OUT_SET macro.

This style of system has adapted quite well to every MCU I've used so far, from AVRs to ARMs, and since it's a preprocessor macro it compiles down into the smallest possible set of instructions.