This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

working with 2 saadc configurations does not work

hello Nordic

i am working with nrf52840, sdk 16.0 

i am building my project over the peripheral app_ble_blinky example 

i whish to have 2 seprate configs for saadc

i call the following init function twice (with 2 different saadc_configs (different naming as well) ):

err_code = nrf_drv_saadc_init(&saadc_config, saadc_sample_event_handler);
    APP_ERROR_CHECK(err_code);

it does not seem to be working.. is there a way to initialize 2 saadc configs

best regards

Ziv

Parents
  • No, you have to uninit the driver beforehand. 

    What is it that you are trying to do exactly?

  • No, you have to uninit the driver beforehand.

    ok .. i found out that saadc has bass address in the instantiation table, so to my understanding there can be only one operational 'nrf_drv_saadc_config_t' at a time, so it brings the question of how is it possible to read all the AIN0-7 channels when one instance can have only 4 channels if i am not wrong.

    anyway, so i configure one 'nrf_drv_saadc_config_t' lets call 1_saadc_config and configure a second 'nrf_drv_saadc_config_t' 2_saadc_config,

    then i call for nrf_drv_saadc_init(&1_saadc_config,... some handler)

    then when sampling is done i call nrf_dev_saadc_uninit();

    then i call for nrf_drv_saadc_init(&2_saadc_config, .. some other handler)

    and when sampling is done i call nrf_drv_saadc_uninit();

    i do not re-init the channel or try to convert the buffers again

    i did not test it yet but i hope you can concur the above logic

    What is it that you are trying to do exactly?

    i need to read 2 analog inputs, each at a different time in the program's flow, so there is no collision there. each analog read requires different configurations in resolution and oversampling. 

    hope to read from you soon

    best regards

    Ziv

  • yes the oversampling is something related to saadc init but as can be seen in my configurations:

      //Configure SAADC
        audio_saadc_config.resolution = NRF_SAADC_RESOLUTION_14BIT;       //Set SAADC resolution to 12-bit. This will make the SAADC output values from 0 (when input voltage is 0V) to 2^12=2048 (when input voltage is 3.6V for channel gain setting of 1/6).
        audio_saadc_config.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;    //DIABLED - //Set oversample to 4x. This will make the SAADC output a single averaged value when the SAMPLE task is triggered 4 times.
        audio_saadc_config.interrupt_priority = APP_IRQ_PRIORITY_LOW;     //Set SAADC interrupt to low priority.
        audio_saadc_config.low_power_mode = NRFX_SAADC_CONFIG_LP_MODE;
    	

    the oversampling is disabled 

    still i get this assertion.. does it has anything to to with the previous configuration  ?

    if not then any idea for solving the problem ?

    i will also add, maybe it matters, this 2 variables that one of them goes in the saadc init are global variables in each of the modules using the saadc

    static nrf_drv_saadc_config_t audio_saadc_config;
    static nrf_saadc_channel_config_t audio_channel_config;

    static nrf_drv_saadc_config_t hydr_saadc_config;
    static nrf_saadc_channel_config_t hydr_channel_config;

    best regards

    Ziv

  • Hi,

    Are you able to find which of the two are causing the assert in the first place?

    NRFX_ASSERT(nrf_saadc_oversample_get() != NRF_SAADC_OVERSAMPLE_DISABLED);

    NRFX_ASSERT(m_cb.active_channels == 0);

    Are you able to make a simple example where you switch between the two that I can run on an nRF52840-DK?

    Kenneth

  • hi

    in debug i can see the following:

    nrf_saadc_oversample_get() = NRF_SAADC_OVERSAMPLE_DISABLED

    m_cb.active_channels = 1

    i can't understand the logic in that assertion .. it is saying the "Oversampling can be used only with one channel" but when over sampling is disabled it fails to, so what's the point ????

    Are you able to make a simple example where you switch between the two that I can run on an nRF52840-DK?

    i am not sure what you meant but i can't bring my self to write a code for testing on your side, i am on tight schedule and i am late cause of this unclear bug that i am trying to explain for so long.

    here is all relevant saadc code in the order it is called:

    global vars:
    
    static nrf_drv_saadc_config_t audio_saadc_config;
    static nrf_saadc_channel_config_t audio_channel_config;
    static nrf_saadc_value_t     m_buffer_pool[2][CONVERTED_ADC_SAMPELS_BUFF_SIZE];
    
    static nrf_drv_saadc_config_t hydr_saadc_config;
    static nrf_saadc_channel_config_t hydr_channel_config;
    static nrf_saadc_value_t     hydr_buffer_pool[HYDR_NUMBER_OF_ADC_SAMPLES];
    
    relevant defins:
    
    #define ADC_PIEZO_CHANNEL     0
    #define ADC_MIC_CHANNEL       1
    #define ADC_AMPLIFIER_CHANNEL 2
    #define ADC_HYDRATION_CHANNEL 3
    
    
    init calls:
    
    Audio_sens_init();
    Physical_measures_init();
    
    the init themselvs:
    
    void Audio_sens_init(void)
    {
        ret_code_t err_code;
    
    //    nrf_gpio_cfg_output(ARDUINO_13_PIN); // FOR DEBUG
    
        //Configure SAADC
        audio_saadc_config.resolution = NRF_SAADC_RESOLUTION_14BIT;       //Set SAADC resolution to 12-bit. This will make the SAADC output values from 0 (when input voltage is 0V) to 2^12=2048 (when input voltage is 3.6V for channel gain setting of 1/6).
        audio_saadc_config.oversample = NRF_SAADC_OVERSAMPLE_DISABLED;    //DIABLED - //Set oversample to 4x. This will make the SAADC output a single averaged value when the SAMPLE task is triggered 4 times.
        audio_saadc_config.interrupt_priority = APP_IRQ_PRIORITY_LOW;     //Set SAADC interrupt to low priority.
        audio_saadc_config.low_power_mode = NRFX_SAADC_CONFIG_LP_MODE;
    	
        //Configure SAADC channels:
        audio_channel_config.reference = NRF_SAADC_REFERENCE_VDD4;          //Set internal reference of fixed 0.6 volts
        audio_channel_config.gain = NRF_SAADC_GAIN1_4;                      //Set input gain to 1/6. The maximum SAADC input voltage is then 0.6V/(1/6)=3.6V. The single ended input range is then 0V-3.6V
        audio_channel_config.acq_time = NRF_SAADC_ACQTIME_10US;             //Set acquisition time. Set low acquisition time to enable maximum sampling frequency of 200kHz. Set high acquisition time to allow maximum source resistance up to 800 kohm, see the SAADC electrical specification in the PS. 
        audio_channel_config.mode = NRF_SAADC_MODE_SINGLE_ENDED;            //Set SAADC as single ended. This means it will only have the positive pin as input, and the negative pin is shorted to ground (0V) internally.
        audio_channel_config.pin_n = NRF_SAADC_INPUT_DISABLED;              //Since the SAADC is single ended, the negative pin is disabled. The negative pin is shorted to ground internally.
        audio_channel_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;      //Disable pullup resistor on the input pin
        audio_channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;        
        audio_channel_config.burst = NRF_SAADC_BURST_DISABLED;   
     
     ....(not relevant to saadc)
        uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();
    
    // samling event configurations - ppi timer event to start saadc sampling:
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel, timer_compare_event_addr, saadc_sample_task_addr);
        APP_ERROR_CHECK(err_code);
    
    ....(not relevant to saadc)
    }
    
    void Physical_measures_init(void)
    {
    ....(not relevant to saadc)
        // init saadc read:
    ////////////////////////////
    
      //Configure SAADC
        hydr_saadc_config.resolution         = NRF_SAADC_RESOLUTION_14BIT;   //Set SAADC resolution to 12-bit. This will make the SAADC output values from 0 (when input voltage is 0V) to 2^12=2048 (when input voltage is 3.6V for channel gain setting of 1/6).
        hydr_saadc_config.oversample         = NRF_SAADC_OVERSAMPLE_4X;      //Set oversample to 4x. This will make the SAADC output a single averaged value when the SAMPLE task is triggered 4 times.
        hydr_saadc_config.interrupt_priority = APP_IRQ_PRIORITY_LOW;         //Set SAADC interrupt to low priority.
        hydr_saadc_config.low_power_mode     = NRFX_SAADC_CONFIG_LP_MODE;
    	  
      //Configure SAADC channel
        hydr_channel_config.reference = NRF_SAADC_REFERENCE_VDD4;          //Set internal reference of fixed 0.6 volts
        hydr_channel_config.gain = NRF_SAADC_GAIN1_4;                      //Set input gain to 1/6. The maximum SAADC input voltage is then 0.6V/(1/6)=3.6V. The single ended input range is then 0V-3.6V
        hydr_channel_config.acq_time = NRF_SAADC_ACQTIME_10US;             //Set acquisition time. Set low acquisition time to enable maximum sampling frequency of 200kHz. Set high acquisition time to allow maximum source resistance up to 800 kohm, see the SAADC electrical specification in the PS. 
        hydr_channel_config.mode = NRF_SAADC_MODE_SINGLE_ENDED;            //Set SAADC as single ended. This means it will only have the positive pin as input, and the negative pin is shorted to ground (0V) internally.
        hydr_channel_config.pin_p = HYDRATION_ADC_INPUT_PIN;               // adc input pin
        hydr_channel_config.pin_n = NRF_SAADC_INPUT_DISABLED;              //Since the SAADC is single ended, the negative pin is disabled. The negative pin is shorted to ground internally.
        hydr_channel_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;      //Disable pullup resistor on the input pin
        hydr_channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;        
        hydr_channel_config.burst = NRF_SAADC_BURST_ENABLED;
    }
    
    
    saadc init calls in main loop (after initialization):
    
    //Initialize SAADC
        err_code = nrf_drv_saadc_init(&hydr_saadc_config, hydr_saadc_callback);
        APP_ERROR_CHECK(err_code);
    
      //Initialize SAADC channel
        err_code = nrf_drv_saadc_channel_init(ADC_HYDRATION_CHANNEL, &hydr_channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(hydr_buffer_pool, HYDR_NUMBER_OF_ADC_SAMPLES);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_sample();  // i want sampling to start only when i use saadc sample
        APP_ERROR_CHECK(err_code);
    
    static void hydr_saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            ret_code_t err_code;
         //   err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, HYDR_NUMBER_OF_ADC_SAMPLES);
          //  APP_ERROR_CHECK(err_code);
    
            hydration_sample_buff[count_of_10_min_sample_events] /*hydr_val*/ = p_event->data.done.p_buffer[0];// + p_event->data.done.p_buffer[1] + p_event->data.done.p_buffer[2] + p_event->data.done.p_buffer[3])/4;        
            measurments_state = MEASURE_STATE_DONE;
            nrf_drv_saadc_uninit();
        }
    }
    
    
    //Initialize second SAADC 
        err_code = nrf_drv_saadc_init(&audio_saadc_config, audio_saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        audio_channel_config.pin_p = AUDIO_PIEZO_ADC_INPUT_PIN; 
        err_code = nrf_drv_saadc_channel_init(ADC_PIEZO_CHANNEL, &audio_channel_config);
        APP_ERROR_CHECK(err_code);
    
        audio_channel_config.pin_p = AUDIO_MIC_ADC_INPUT_PIN;
        err_code = nrf_drv_saadc_channel_init(ADC_MIC_CHANNEL, &audio_channel_config);
    /////// 
    HERE IS WERE THE ASSERTION HAPPENS !!! IN THE CHANNEL INIT FOR ADC_MIC_CHANNEL
    //////
        APP_ERROR_CHECK(err_code);
    
        audio_channel_config.pin_p = AUDIO_PIEZO_ADC_INPUT_PREAMPLYFIER_INPUT_PIN;
        err_code = nrf_drv_saadc_channel_init(ADC_AMPLIFIER_CHANNEL, &audio_channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], CONVERTED_ADC_SAMPELS_BUFF_SIZE);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], CONVERTED_ADC_SAMPELS_BUFF_SIZE);
        APP_ERROR_CHECK(err_code);
    

    hope you can help me to solve this issue 

    best regards

    Ziv

  • I think the best and fastest way forward is to send me a project that I can compile and run here on an nRF52840-DK to recreate this. Then I will be able to help you properly.

    Best regards,
    Kenneth

  • my code contains  a lot of other modules and algorithms so sharing it is not my first choice

     

    any way, the issue and source for lack of logic in the assert is that i was advised to change it for another project a while ago and the correct form is actually as follows:


    // Oversampling can be used only with one channel.
     NRFX_ASSERT((nrf_saadc_oversample_get() == NRF_SAADC_OVERSAMPLE_DISABLED) ||
     (m_cb.active_channels == 0));

    == instead of != NRF_SAADC_OVERSAMPLE_DISABLED which is the original SDK code 

    i must admit that i am a bit disappointed that no one could relate to this lack of logic and correct my miss use of the nrfx_saadc.c file and save me a tone of time and so many changes to the my original organized code.

     

    i have some more issues with timing of the adc but i will open a new thread for that

    best regards 

    Ziv

Reply
  • my code contains  a lot of other modules and algorithms so sharing it is not my first choice

     

    any way, the issue and source for lack of logic in the assert is that i was advised to change it for another project a while ago and the correct form is actually as follows:


    // Oversampling can be used only with one channel.
     NRFX_ASSERT((nrf_saadc_oversample_get() == NRF_SAADC_OVERSAMPLE_DISABLED) ||
     (m_cb.active_channels == 0));

    == instead of != NRF_SAADC_OVERSAMPLE_DISABLED which is the original SDK code 

    i must admit that i am a bit disappointed that no one could relate to this lack of logic and correct my miss use of the nrfx_saadc.c file and save me a tone of time and so many changes to the my original organized code.

     

    i have some more issues with timing of the adc but i will open a new thread for that

    best regards 

    Ziv

Children
No Data
Related