I will need to see if it makes sense to create a dedicated test project that I can share, and if it would have the same behaviour. I am using a custom board design, with a full project, which I can't really share.
Since this seems to happen only when using FreeRTOS vs. a while() loop, I assume something about a context switch is causing the GPIO change for the address to be blocked or overwritten with a previous value.
I ran a debug (in SEGGER SystemView) and the GPIO issue only happened infrequently (every ~100k executions).
Here is a code snippet extract that shows what I use to set and check the GPIO for the address. This is modified code from my project, so don't try to compile it.
#define IO_MUX_GPIO GPIO1
#define IO_MUX_0_PIN 28U
#define IO_MUX_1_PIN 29U
#define IO_MUX_2_PIN 30U
volatile uint8_t g_addrNum = 0U;
volatile uint16_t g_AdcConversionValue2;
void ADC_ETC_IRQ1_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
ADC_ETC_ClearInterruptStatusFlags(ADC_ETC, kADC_ETC_Trg4TriggerSource, kADC_ETC_Done1StatusFlagMask);
g_AdcConversionValue2 = ADC_ETC_GetADCConversionValue(ADC_ETC, 4U, 0U);
if (g_addrNum == (GPIO_PinRead(IO_MUX_GPIO, IO_MUX_0_PIN) | (GPIO_PinRead(IO_MUX_GPIO, IO_MUX_1_PIN) << 1) | (GPIO_PinRead(IO_MUX_GPIO, IO_MUX_2_PIN) << 2)))
{
GPIO_PortClear(IO_MUX_GPIO, 0x70000000);
if (g_addrNum != 5)
{
g_addrNum++;
GPIO_PortSet(IO_MUX_GPIO, g_addrNum << 28);
}
else
{
g_addrNum = 0;
}
// give the semaphore
xSemaphoreGiveFromISR(adc_conv_sem, &xHigherPriorityTaskWoken );
}
else
{
// DANGER
// the address doesn't match what we set it to!
}
if (xHigherPriorityTaskWoken != pdFALSE)
{
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
__DSB();
}