ADC1 - PORTB conflict

We are using an Iris board with a Colibri iMX7D module on. We have a M4 software running that uses some ADC1 inputs and we have changed the dtb file so that linux will not use that peripheral. However, we are facing a problem when we try to use the linux software we have developed that communicates using serial portB . If the M4 firmware is not running our linux software works fine but when both are running we cannot use this serial port. Linux produces the following error:

[ 21.597604] imx-sdma 30bd0000.sdma: Timeout waiting for CH0 ready
[ 21.603821] imx-uart 30890000.serial: We cannot prepare for the TX slave d

If we modify our M4 code so that it does not use the ADC1 peripheral, both programs can run simultaneously without any problem.

Do you have any idea of what can be causing this problem and how we can solve it?

Colibri iMX7 ADC channels are completely separate from any UART lines. Are you using DMA at your M4 code?

Not sure. I have inherited this part of the code from a previous proyect writen by another engineer that is not working here now. I looks like the ADC is not using DMA, but the error code given by linux kernell says something different. This is the ADC1 initialization routine I’m using:

void GPIO_Ctrl_InitADC1()
{
RDC_SetPdapAccess(RDC, BOARD_ADC_RDC_PDAP, 3 << (BOARD_DOMAIN_ID * 2), false, false);
CCM_UpdateRoot(CCM, ccmRootIpg, ccmRootmuxIpgAHB, 0, 0);
CCM_EnableRoot(CCM, ccmRootIpg);
CCM_ControlGate(CCM, BOARD_ADC_CCM_CCGR, ccmClockNeededAll);

RDC_SEMAPHORE_Lock(BOARD_ADC_RDC_PDAP);

ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHA_COV_SHIFT), false);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHA_COV_INT_EN_SHIFT), false);
ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHB_COV_SHIFT), false);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHB_COV_INT_EN_SHIFT), false);
ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHC_COV_SHIFT), false);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHC_COV_INT_EN_SHIFT), false);
ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHD_COV_SHIFT), false);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHD_COV_INT_EN_SHIFT), false);
ADC_LogicChDeinit(BOARD_ADC_BASEADDR, adcLogicChA);
ADC_LogicChDeinit(BOARD_ADC_BASEADDR, adcLogicChB);
ADC_LogicChDeinit(BOARD_ADC_BASEADDR, adcLogicChC);
ADC_LogicChDeinit(BOARD_ADC_BASEADDR, adcLogicChD);
ADC_LogicChDeinit(BOARD_ADC_BASEADDR, adcLogicChSW);
ADC1_Init_Config.sampleRate = 1000000;
ADC1_Init_Config.levelShifterEnable = true;
ADC_Init(BOARD_ADC_BASEADDR, &ADC1_Init_Config);
// Power up ADC module
// not continuous, not comp., average 32 samples, channel 0
ADC1_Channel_Init_Config.averageEnable = true;
ADC1_Channel_Init_Config.averageNumber = adcAvgNum32;
ADC1_Channel_Init_Config.convertRate = 100000;
ADC1_Channel_Init_Config.coutinuousEnable = false;
ADC1_Channel_Init_Config.inputChannel = BOARD_ADC_SW12_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChA, &ADC1_Channel_Init_Config);
ADC1_Channel_Init_Config.inputChannel = BOARD_ADC_SW34_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChB, &ADC1_Channel_Init_Config);
ADC1_Channel_Init_Config.inputChannel = BOARD_ADC_LID_OPEN_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChC, &ADC1_Channel_Init_Config);
ADC1_Channel_Init_Config.inputChannel = BOARD_ADC_FLASH_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChD, &ADC1_Channel_Init_Config);

ADC_SetCmpMode(BOARD_ADC_BASEADDR, adcLogicChA, adcCmpModeDisable);
ADC_SetCmpMode(BOARD_ADC_BASEADDR, adcLogicChB, adcCmpModeDisable);
ADC_SetCmpMode(BOARD_ADC_BASEADDR, adcLogicChC, adcCmpModeDisable);
ADC_SetCmpMode(BOARD_ADC_BASEADDR, adcLogicChD, adcCmpModeDisable);
ADC_SetAutoDisableCmd(BOARD_ADC_BASEADDR, adcLogicChA, false);
ADC_SetAutoDisableCmd(BOARD_ADC_BASEADDR, adcLogicChB, false);
ADC_SetAutoDisableCmd(BOARD_ADC_BASEADDR, adcLogicChC, false);
ADC_SetAutoDisableCmd(BOARD_ADC_BASEADDR, adcLogicChD, false);
// DMA disable
ADC_SetDmaReset(BOARD_ADC_BASEADDR, true);
ADC_SetDmaCmd(BOARD_ADC_BASEADDR, false);
ADC_SetDmaFifoCmd(BOARD_ADC_BASEADDR, false);
// Interrupts
ADC_ClearStatusFlag(BOARD_ADC_BASEADDR, 0x003F1FEF);		// Clear all flags excepts reserved
ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHA_COV_SHIFT), true);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHA_COV_INT_EN_SHIFT), true);
ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHB_COV_SHIFT), true);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHB_COV_INT_EN_SHIFT), true);
ADC_SetIntSigCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_STATUS_CHC_COV_SHIFT), true);
ADC_SetIntCmd(BOARD_ADC_BASEADDR, (1<<ADC_INT_EN_CHC_COV_INT_EN_SHIFT), true);

RDC_SEMAPHORE_Unlock(BOARD_ADC_RDC_PDAP);

}

According to your code you are doing a DMA reset. It may affect DMA settings used by Linux.

I have reviewed the FreeRTOS example and I have modified the ADC initialization to remove some lines and changed the clock configuration and now it works fine, without affecting the linux PortB operation.
Thanks for your help.

void GPIO_Ctrl_InitADC1()
{
RDC_SetPdapAccess(RDC, BOARD_ADC_RDC_PDAP, 3 << (BOARD_DOMAIN_ID * 2), false, false);
CCM_ControlGate(CCM, BOARD_ADC_CCM_CCGR, ccmClockNeededRunWait);

RDC_SEMAPHORE_Lock(BOARD_ADC_RDC_PDAP);
ADC1_Config.sampleRate = 100000;
ADC1_Config.levelShifterEnable = true;
ADC_Init(BOARD_ADC_BASEADDR, &ADC1_Config);

// Initialize ADC Logic Channel module.
// not continuous, not comp., average 32 samples
ADC1_Channel_Config.averageEnable = true;
ADC1_Channel_Config.averageNumber = adcAvgNum32;
ADC1_Channel_Config.convertRate = 100000;
ADC1_Channel_Config.coutinuousEnable = false;
ADC1_Channel_Config.inputChannel = BOARD_ADC_SW12_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChA, &ADC1_Channel_Config);
ADC1_Channel_Config.inputChannel = BOARD_ADC_SW34_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChB, &ADC1_Channel_Config);
ADC1_Channel_Config.inputChannel = BOARD_ADC_LID_OPEN_CHANNEL;
ADC_LogicChInit(BOARD_ADC_BASEADDR, adcLogicChC, &ADC1_Channel_Config);
ADC_ClearStatusFlag(BOARD_ADC_BASEADDR, 0x003F1FEF);		// Clear all flags excepts reserved
RDC_SEMAPHORE_Unlock(BOARD_ADC_RDC_PDAP);

}

Glad your problem is solved. Thank you for the update.