IOM mode overrides GPIO?

I am using IOM2 to drive a write-only LCD display. This means that I only need SCK and MOSI for my SPI transfers - I don’t need MISO. My project ran out of GPIOs, so I am trying to use pad25 (A.K.A. the unneeded IOM2 MISO) as a GPIO while the SPI is active. This would seem to be possible by initializing the SPI, then reassigning pad25’s function mapping register contents setting from M2MISO (5) to GPIO25 (3).

The problem: I can set up pad25 to be GPIO and make it go high or low. But when am_hal_iom executes the ‘enable_submodule’ to finally enable IOM2 after initializing it for SPI operation, my pad25 GPIO gets driven high. Not only that, I then lose my ability to control it via HAL GPIO function calls. The strange part is that my debugger shows that the GPIO pad function mapping registers show that pad 25 is still mapped to GPIO functionality, not SPI functionality. But GPIO writes are ignored.

It would appear that enabling SPI operation on an IOM overrides whatever I set up in the function mapping registers. That would make sense except the only thing I can find on the subject in the data sheet indicates the opposite. Section 11.5.1.9 “IO Master 2 4-wire SPI Connection” explicitly states that you need to set the Function Mapping for each of the MOSI/MISO/SCK to 0x5 before using SPI.

I just did an experiment where I modded the innards of the hal routine enable_iom. It indicates that enabling an IOM forces the MISO pad to be associated with the IOM. If I disable the IOM, the pads are immediately usable by the GPIO again even though nothing changed in the pad Function Mapping register.

enable_submodule(uint32_t ui32Module, uint32_t ui32Type)
{
    // These GPIO operations work:
    am_hal_gpio_pinconfig(25, g_AM_HAL_GPIO_OUTPUT);
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_SET);
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_CLEAR);

    // Enable the IOM module
    if ( IOMn(ui32Module)->SUBMODCTRL_b.SMOD0TYPE == ui32Type )
    {
        IOMn(ui32Module)->SUBMODCTRL =
             _VAL2FLD(IOM0_SUBMODCTRL_SMOD1EN, 0) |
             _VAL2FLD(IOM0_SUBMODCTRL_SMOD0EN, 1);
    }
    else
    {
        IOMn(ui32Module)->SUBMODCTRL =
             _VAL2FLD(IOM0_SUBMODCTRL_SMOD1EN, 1) |
             _VAL2FLD(IOM0_SUBMODCTRL_SMOD0EN, 0);
    }

    // These GPIO operations have no effect:
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_CLEAR);
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_SET);
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_CLEAR);

    // ...but if I disable the SPI submodule again:
    IOMn(ui32Module)->SUBMODCTRL =
             _VAL2FLD(IOM0_SUBMODCTRL_SMOD1EN, 0) |
             _VAL2FLD(IOM0_SUBMODCTRL_SMOD0EN, 0);

    // ...then these GPIO operations work as expected:
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_CLEAR);
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_SET);
    am_hal_gpio_state_write(25, AM_HAL_GPIO_OUTPUT_CLEAR);


} // enable_submodule()

I guess what I learned is that there seems to be a hardware override on pin mapping functionality when you enable the IOM. That’s disappointing for my purposes because now I’m one GPIO pin short again!

Does anyone know if this is expected behavior? A pointer into the docs that I missed?

During a previous project, I observed the same issue when trying to set the output.

All I could find was a cryptic description in datasheet chapter 7.2 MSPI, NOT for the IOM, that made me believe there is a backdoor :

Enabling unused data lines will impact the values present on those pads even if the GPIO function select is not set to MSPI.

As it was only for testing and not the primary target to get that right, I left it for another time and focussed back on my project

After reviewing your code and the provided information, it appears that the behavior you are experiencing is expected.

In the code snippet you shared, when you enable the IOM2 submodule using am_hal_iom_enable_submodule(), the IOM module takes control of the pin functionality, including the MISO pin (pad25) that you previously configured as a GPIO. This behavior is inherent to the hardware design, where the IOM module takes precedence over the individual pad configuration.

Therefore, when the SPI submodule of IOM2 is enabled, the MISO pad is automatically associated with the SPI functionality, even though the pad function mapping registers might still indicate GPIO functionality.

As a result, you lose control over the MISO pad as a GPIO, and it is driven high. This behavior is expected for the IOM module in SPI mode. [YourTexasBenefits App

Unfortunately, this means that you cannot use pad25 as a GPIO while the SPI submodule of IOM2 is active. It seems that you are indeed one GPIO pin short for your project.

I apologize for any inconvenience caused. It’s essential to carefully review the microcontroller’s datasheet and reference manual to understand the specific capabilities and limitations of the IOM and GPIO functionality for your particular microcontroller model. In some cases, alternate solutions such as external multiplexers or using a different microcontroller with more GPIO pins might be necessary to meet your project requirements.](https://www.yourtexasbenefits.bid/)