This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Regarding the use of macros instead of API's

Hi,

       I am using tm4c123gxl launchpad and Keil IDE. I had done different projects using Tivaware driver library. In my projects mostly I am using specific names for gpio pins for example:( #define GPIO_PIN_2 LED1). But the problem is that I can't able to name correctly if both ports are using the same pin for different application. So I had tried to use macros instead of API's (#define set_high()  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2)
                                       #define set_low()        ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0))

and it worked as well. I just want to know whether any side-effects(regarding timing) or some other problems for using macros.

  • Hi,

    No, macros are evaluated at compile time, not at run time. 

    Every IDE/toolchain has the possibility to check the results of macro substitution - that is pre-processing and may be used seldom, if you need that. Errors are highlighted as usual, since the pre-processing is the first phase of compilation.

    What is unusual in your description is the need to have same macro in different appilcations - that is not needed due to the obvious reason that a pin can be input in one application and output in another one. And a macro is one level of abstraction used to make the code more readable.

    Petrei

  • Hi Petrei,

                    This is my sample code

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/gpio.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    
    #define set_high(x)  ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, x)
    #define set_low(x)		ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, x)
    
    
    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
    }
    #endif
    
    //*****************************************************************************
    //
    // Toggle a GPIO.
    //
    //*****************************************************************************
    int
    main(void)
    {
        //
        // Enable the GPIO module.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        ROM_SysCtlDelay(1);
    
        //
        // Configure PA1 as an output.
        //
        ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
    
        //
        // Loop forever.
        //
        while(1)
        {
            //
            // Set the GPIO high.
            //
    				set_high(GPIO_PIN_2);
    
            //
            // Delay for a while.
            //
            ROM_SysCtlDelay(1000000);
    
            //
            // Set the GPIO low.
            //
            set_low(0);
    
            //
            // Delay for a while.
            //
            ROM_SysCtlDelay(1000000);
        }
    }
    

    Is anything wrong in doing like this? It would give me a better understanding. Actually I had mistaken in the previous post( #define GPIO_PIN_2 LED1), what I meant is like this(#define LED1 GPIO_PIN_2).

    If you are using the name LED1 instead of GPIO_PIN_2 in PORTF and now I want to connect a relay across GPIO_PIN_2 of PORTD, then both pins in the two ports will have same name. This causes the confusion!

    #define LED1 GPIO_PIN_2

    ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED1,LED1);

    ROM_GPIOPinWrite(GPIO_PORTD_BASE, LED1,LED1);

  • Hi, 

    These are not exclusive resources, like port/peripherals. You may write also 

    #define REL1 GPIO_PIN_2

    and use it in your code as this: ROM_GPIOPinWrite(GPIO_PORTD_BASE, REL1, REL1);

    Petrei

  • Hi Petrei,

                  I had one more doubt regarding the internal memory storage. Presently, I am working with DOT matrix display and there I had come across a lot of data for displaying the glyphs. I want to know what is the best option for storing these large amount of data (flash,EEPROM,SRAM) and their pros and cons

  • Hi,

    Store them into flash anyway, they must be there from the beginning. If modified at run time, then a copy into SRAM. The EEPROM can be saved from that, maybe used for configurations/some data results/ other, depend on your application.

    Petrei

  • Quick look at your coding style reveals it to be "limiting" thus inefficient for more standard use.  Look here:

    nithin kurian said:

        while(1)
        {
            //
            // Set the GPIO high.
            //
            set_high(GPIO_PIN_2);

            //
            // Delay for a while.
            //
            ROM_SysCtlDelay(1000000);

            //
            // Set the GPIO low.
            //
            set_low(0);

            //
            // Delay for a while.
            //
            ROM_SysCtlDelay(1000000);
        }
    }
    Is anything wrong in doing like this? It would give me a better understanding. Actually I had mistaken in the previous post( #define GPIO_PIN_2 LED1), what I meant is like this(#define LED1 GPIO_PIN_2). 

    While not necessarily "wrong" - consider the implications enforced when you change to another port - another pin!  (The code will fail except when that same pin is employed.)  Further - it's normal to output multiple bits of data - perhaps even an entire 8 bit bus - your "method" will "wear you out" when that's required.

    The API GPIO functions nicely anticipate this "normal/customary" (any bit and/or byte-wide) data transactions - and provide for such via 2 key function parameters - one selectively enabling bits w/in a port - the 2nd accommodating their output. 

    You may comment each such GPIO function call when a specific port/pin occurs - to heighten documentation.  Or you may "define" general GPIO Ports - and pins - to reflect your actual use (thus auto-commenting) yet still remain w/in the well designed "framework" of this vendor's powerful API.