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.

TM4C1294NCPDT: Tivaware SPI/SSI configuration of pins - Using GPIOPinConfigure in a personal library

Part Number: TM4C1294NCPDT

Gentlemen,

The typical pin configuration of a SPI pin (in this example, the CLK pin) is:

    GPIOPinTypeSSI(SSI_GYROS_CLK_PORT,SSI_GYROS_CLK_PIN);
    GPIOPinConfigure(GPIO_PA2_SSI0CLK);

I would like to have a fixed external function to let me to initialize a given SPI peripheral from my main application.

Simplifying for the CLK pin, the idea would be:

SPISensorHWInit(int32_t SSIBase, int32_t sensorClockPort, int_32_t sensorClockPin) // Plus the ports and pins of the other MISO/MOSI/CS GPIO's
{
// First, execute the SSI Peripheral Configuration
// Then each of the pins, for example:
GPIOPinTypeSSI(sensorClockBase,sensorClockPin); GPIOPinConfigure(SOMETHING); // This is tricky... }

I see two possible ways regarding the SOMETHING parameter:

1) To pass the original GPIOPinConfigure GPIO_PA2_SSI0CLK argument inside the "packing" function, adding yet one more argument to the already long list

or

2) To kind of reconstruct the said parameter inside the function, if the fact that we are dealing with SSI peripheral and we know the SSI base are enough for that.

I looked into the GPIOPinConfigure code, and it is not that easy to read. In the end we want to write a register:

    HWREG(ui32Base + GPIO_O_PCTL) = ((HWREG(ui32Base + GPIO_O_PCTL) &
                                      ~(0xf << ui32Shift)) |
                                     ((ui32PinConfig & 0xf) << ui32Shift));

Question is: can we determine the Base, Shift and remaining PinConfig from the know figures SSI base and pin? What are the "magic" rules?

Regards

Bruno

  • Hi Bruno,

    IIRC, you can approach this the other way; the GPIO port and pin can be extracted from the GPIOPinConfigure parameter value. I dug to some old code and found these:

    // Get the pin number (from 0 to 7) from a GPIO_Pxy_zzzz pinConfig value
    #define VTL_GPIOGetPinNumberByPinConfig(pinConfig) (((pinConfig) >> 10) & 0x7)
    uint32_t VTL_GPIOGetBaseByPinConfig(uint32_t pinConfig) {
    	// Extract base index
    	uint32_t gpioBaseIdx = (pinConfig >> 16) & 0xff;
    
    	// On APB or AHB bus?
        if(HWREG(SYSCTL_GPIOHBCTL) & (1 << gpioBaseIdx))
        {
        	return VTL_GPIObaseAddrs[(gpioBaseIdx << 1) + 1];
        }
        else
        {
        	return VTL_GPIObaseAddrs[gpioBaseIdx << 1];
        }
    }

    And the GPIO base address table looks like this:

    /**
     * GPIO port base addresses
     */
    const uint32_t VTL_GPIObaseAddrs[] =
    {
    		GPIO_PORTA_BASE, GPIO_PORTA_AHB_BASE,
    		GPIO_PORTB_BASE, GPIO_PORTB_AHB_BASE,
    		GPIO_PORTC_BASE, GPIO_PORTC_AHB_BASE,
    		GPIO_PORTD_BASE, GPIO_PORTD_AHB_BASE,
    		GPIO_PORTE_BASE, GPIO_PORTE_AHB_BASE,
    		GPIO_PORTF_BASE, GPIO_PORTF_AHB_BASE,
    		GPIO_PORTG_BASE, GPIO_PORTG_AHB_BASE,
    		GPIO_PORTH_BASE, GPIO_PORTH_AHB_BASE,
    		GPIO_PORTJ_BASE, GPIO_PORTJ_AHB_BASE,
    		GPIO_PORTK_BASE, GPIO_PORTK_BASE,
    		GPIO_PORTL_BASE, GPIO_PORTL_BASE,
    		GPIO_PORTM_BASE, GPIO_PORTM_BASE,
    		GPIO_PORTN_BASE, GPIO_PORTN_BASE,
    		GPIO_PORTP_BASE, GPIO_PORTP_BASE,
        	GPIO_PORTQ_BASE, GPIO_PORTQ_BASE,
    #ifdef VTL_TM4C129
        	GPIO_PORTR_BASE, GPIO_PORTR_BASE,
        	GPIO_PORTS_BASE, GPIO_PORTS_BASE,
        	GPIO_PORTT_BASE, GPIO_PORTT_BASE
    #endif
    };

    Do these make sense?

    Br,

    Veikko

  • Greetings Veikko,
    Yes, that's a neat suggestion, thank you. Will certainly keep the code cleaner!
    I meant to reply only after testing, but with so much going on right now, it will probably take a few days until then - I'll try to remember to come back here and say how it went!
    Cheers
    Bruno