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?