Reading simultaneous ADC values from multiple channels of ADC0 and ADC1

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Reading simultaneous ADC values from multiple channels of ADC0 and ADC1

1,434 Views
Rambo1310
Contributor I

In an attempt to read ADC values from multiple channels of both ADC0 and ADC1 simultaneously, I modified the example code: "adc_hwtrigger_s32k144".

But I'm unable to read the values on these channels. Can someone review and tell me where I'm going wrong.

  //ADC_1
  #define ADC1_INSTANCE    1UL
  #define ADC1_CHN         15U //PTB16
  #define PDB1_INSTANCE    1UL
  //ADC_2
  #define ADC0_INSTANCE    0UL
  #define ADC0_CHN         9U //PTC1
  #define PDB0_INSTANCE    0UL

  #define ADC_VREFH       5.0f
  #define ADC_VREFL       0.0f


  /* Flag used to store if an ADC IRQ was executed */
 volatile bool adc1ConvDone;
 volatile bool adc0ConvDone;
   /* Variable to store value from ADC conversion */
 volatile uint16_t adc1RawValue;
 volatile uint16_t adc0RawValue;
 volatile uint16_t adcRawValue;
float adc0Value;
float adc1Value;


 bool calculateIntValue(const pdb_timer_config_t *pdbConfig, uint32_t uSec, uint16_t *intValue);


 void ADC1_IRQHandler(void)
 {
     /* Get channel result from ADC channel */
     ADC_DRV_GetChanResult(ADC1_INSTANCE, 15U, (uint16_t *)&adc1RawValue);
     /* Set ADC conversion complete flag */
     adc1ConvDone = true;
 }

 void ADC0_IRQHandler(void)
 {
     /* Get channel result from ADC channel */
     ADC_DRV_GetChanResult(ADC0_INSTANCE, 9U, (uint16_t *)&adc0RawValue);
     /* Set ADC conversion complete flag */
     adc0ConvDone = true;
 }

/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
    /* Write your local variable definition here */
    uint16_t delayValue = 0;

    /* Variables in which we store data from ADC */
    uint16_t adc0Max;
    uint16_t adc1Max;
    float adcValue;


    adc1ConvDone = false;
    adc0ConvDone = false;
  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of Processor Expert internal initialization.                    ***/
    /* Initialize and configure clocks
     *  -   see clock manager component for details
     */
    CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
                g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
    CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);

    /* Initialize pins
         *  -   See PinSettings component for more info
         */
        PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

        /* Get ADC max value from the resolution */
        if (adConv0_ConvConfig0.resolution == ADC_RESOLUTION_8BIT)
            adc0Max = (uint16_t) (1 << 8);
        else if (adConv0_ConvConfig0.resolution == ADC_RESOLUTION_10BIT)
            adc0Max = (uint16_t) (1 << 10);
        else
            adc0Max = (uint16_t) (1 << 12);

        if (adConv1_ConvConfig0.resolution == ADC_RESOLUTION_8BIT)
            adc1Max = (uint16_t) (1 << 8);
        else if (adConv1_ConvConfig0.resolution == ADC_RESOLUTION_10BIT)
            adc1Max = (uint16_t) (1 << 10);
        else
            adc1Max = (uint16_t) (1 << 12);

        /* Configure and calibrate the ADC converter
         *  -   See ADC component for the configuration details
         */

        DEV_ASSERT(adConv0_ChnConfig0.channel == ADC0_CHN);

        ADC_DRV_ConfigConverter(ADC1_INSTANCE, &adConv1_ConvConfig0);
        ADC_DRV_AutoCalibration(ADC1_INSTANCE);
        ADC_DRV_ConfigChan(ADC1_INSTANCE, 15U, &adConv1_ChnConfig0);

        DEV_ASSERT(adConv1_ChnConfig0.channel == ADC1_CHN);

        ADC_DRV_ConfigConverter(ADC0_INSTANCE, &adConv0_ConvConfig0);
        ADC_DRV_AutoCalibration(ADC0_INSTANCE);
        ADC_DRV_ConfigChan(ADC0_INSTANCE, 9U, &adConv0_ChnConfig0);

        IRQn_Type adc1IRQ = ADC1_IRQn;
        IRQn_Type adc0IRQ = ADC0_IRQn;

        INT_SYS_InstallHandler(adc1IRQ, &ADC1_IRQHandler, (isr_t*) 0);
        INT_SYS_InstallHandler(adc0IRQ, &ADC0_IRQHandler, (isr_t*) 0);

        /* Setup PDB instance
         *  -   See PDB component for details
         *  Note: Pre multiplier and Prescaler values come from
         *        calculateIntValue function.
         */
        PDB_DRV_Init(PDB1_INSTANCE, &pdb1_InitConfig0);
        PDB_DRV_Enable(PDB1_INSTANCE);
        PDB_DRV_ConfigAdcPreTrigger(PDB1_INSTANCE, 0UL, &pdb1_AdcTrigInitConfig0);
        PDB_DRV_SetTimerModulusValue(PDB1_INSTANCE, (uint32_t) delayValue);
        PDB_DRV_SetAdcPreTriggerDelayValue(PDB1_INSTANCE, 0UL, 0UL,
                                (uint32_t) delayValue);
        PDB_DRV_LoadValuesCmd(PDB1_INSTANCE);
        PDB_DRV_SoftTriggerCmd(PDB1_INSTANCE);

        PDB_DRV_Init(PDB0_INSTANCE, &pdb0_InitConfig0);
        PDB_DRV_Enable(PDB0_INSTANCE);
        PDB_DRV_ConfigAdcPreTrigger(PDB0_INSTANCE, 0UL, &pdb0_AdcTrigInitConfig0);
        PDB_DRV_SetTimerModulusValue(PDB0_INSTANCE, (uint32_t) delayValue);
        PDB_DRV_SetAdcPreTriggerDelayValue(PDB0_INSTANCE, 0UL, 0UL,
                        (uint32_t) delayValue);
        PDB_DRV_LoadValuesCmd(PDB0_INSTANCE);
        PDB_DRV_SoftTriggerCmd(PDB0_INSTANCE);

        /* Enable ADC interrupt */
        INT_SYS_EnableIRQ(adc1IRQ);
        INT_SYS_EnableIRQ(adc0IRQ);
  /* Write your code here */
  /* For example: for(;;) { } */
    while (1)
        {
            if (adc1ConvDone == true)
            {
                /* Process the result to get the value in volts */
                adc1Value = ((float) adc1RawValue / adc1Max) * (ADC_VREFH - ADC_VREFL);

                /* Clear conversion done interrupt flag */
                adc1ConvDone = false;

                /* Trigger PDB timer */
                PDB_DRV_SoftTriggerCmd(PDB1_INSTANCE);
            }

            if (adc0ConvDone == true)
                    {
                        /* Process the result to get the value in volts */
                        adc0Value = ((float) adc0RawValue / adc0Max) * (ADC_VREFH - ADC_VREFL);

                        /* Clear conversion done interrupt flag */
                        adc0ConvDone = false;

                        /* Trigger PDB timer */
                        PDB_DRV_SoftTriggerCmd(PDB0_INSTANCE);
                    }


        }
 

Thanks.

0 Kudos
Reply
5 Replies

1,312 Views
Rambo1310
Contributor I

I want to use PDB module but be able to read ADC values using polling. I have tried modifying the code for that but it seems to be stuck at PDB triggering when I check with breakpoints.

Can you check the modified code and suggest the necessary modification in configuration or code.

PFA the project

Thank you

0 Kudos
Reply

1,278 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

I remember that I have sent a project that can run successfully via private message before. Would you please modify based on that project(adc_hwtrigger_s32k144_SDK300.zip)?

Because I found that adc_polling.zip and ADC_PDB.zip made similar mistakes, such as
ADC did not select hardware trigger\PDB did not select SW trigger.

By the way, why do you want the PDB to trigger the ADC but read the value of the ADC in polling mode?
In this case your MCU will waste time waiting for ADC_DRV_WaitConvDone and ADC_DRV_GetChanResult.

I recommend you to study the PDB trigger ADC sampling combined with DMA projects mentioned in my previous answer.

0 Kudos
Reply

1,412 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi

I don't see an obvious problem, but haven't seen Processor Expert's configuration. Instead of posting the code, it is better to directly upload your simple test project for easy checking.
Regarding reading the conversion results of two ADC modules, please also refer to:
Example S32K144 PDB ADC DMA S32DS.ARM.2018.R1
Example S32K148 PDB0-PDB1 ring S32DS3.4 RTM4.0.3
Example S32K148 PDB0-PDB1 ring DMA S32DS3.4 RTM4.0.3


Best Regards,
Robin

0 Kudos
Reply

1,407 Views
Rambo1310
Contributor I

Thanks for your response.

PFA the test project. Please review and let me know where am going wrong.

I'll go through the suggested examples.

 

0 Kudos
Reply

1,391 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

I have checked your project. But found that there are several different settings of Processor Expert from adc_hwtrigger_s32k144.
For example, lack of #include head files\ADC did not select hardware trigger\PDB did not select SW trigger\delayValue=0, etc.

0 Kudos
Reply