Search code examples
cembeddedgpiocortex-m

TM4C123G launchpad: How to modify one pin (e.g. PE1) without knowing its GPIO and its position in the byte


Please allow me to clarify the title: I'm writing a function to connect 16x2 LCD pins to TM4C123G pins. Users should be able to select any TM4C123G pin they want. As the function writer, I need the user to pass the information of that pin to me so that I can connect the pins.

Now I know there are two ways to modify a pin:

Method 1: Reference the full register and AND/OR with a certain value:

// Want to set PE1 to high
#define GPIO_PORTE_DATA_R       (*((volatile unsigned long *)0x400243FC))
GPIO_PORTE_DATA_R |= 0x02;

Method 2: Use bit-specific addressing and reference PE1:

// Want to set PE1 to high
#define PE1       (*((volatile unsigned long *)0x40024008))
PE1 = 0x02;

Now consider the function I need to write: the user has to pass two pieces of information to it -- 1) Which GPIO is used (Port E), and 2) Which bit is used (PE1 the second bit from low end).

My question: Is there a way for the user to just pass me a memory address and I can simply set it to 0x01 for high and 0x00 for low?


Solution

  • This is actually a generic question independent of its platform. The solution is also opinion-based. Anyway, below are my suggestions :)

    As the user will only manage the GPIO, s/he doesn't need to be aware of the implementation details that cover the control of the underlying peripheral at a lower level. Hence, you may want to hide the implementation details by just providing some basic functions to the user as below

    /* Header File */
    int enableGpio(int gpioPort, int index);
    int disableGpio(int gpioPort, int index);
    

    You can also hide the macros that you use to handle the logic behind the operation by declaring them inside the source file.

    /* Source File */
    #define GPIO_PORTE_DATA_R       (*((volatile unsigned long *)0x400243FC))
    #define PE1                     (*((volatile unsigned long *)0x40024008))
    
    int enableGpio(int gpioPort, int index) { /* Implementation*/ }
    int disableGpio(int gpioPort, int index) { /* Implementation*/ }
    

    I would also recommend using enumerations for declaring GPIO ports instead of integers. By that, you can prevent making undefined calls to your functions.

    That's all for now :)