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 Reply Children
  • 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

  • ziv123 said:
    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.

    Why do you believe that? It's not true, the saadc driver has access to all the channels. 

    ziv123 said:
    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. 

     Yeah that's a bit tricky, you'll have to uninit and re-init the saadc driver each time to change the resolution/oversample configuration. You'll also need to change the buffers each time you sample.

    I suggest you use the highest resolution + oversample of the two settings and use it for both channels, in addition to sampling both channels at once, then ignore the samples you don't need. 

    What exactly are your saadc configurations and sample rate? 

  • I suggest you use the highest resolution + oversample of the two settings and use it for both channels, in addition to sampling both channels at once, then ignore the samples you don't need.

    with one saadc config i sample 3 channels, i can't use ovesampel with this channels cause oversample does ch1 sampel 1to ch1 sample n and then goes to ch2 sample 1 up to ch2 sample n and so on .. i need better accuracy between the channels sampels so ch1 is sampeld once, then ch2 then ch3 and then repeat for the next sample, i sample each channel 4 times .. my sample rate is 32KHz, so 12 samples there without oversampling and in 14 bit resolution

    the other saadc config is for one channel and i need only one read every some relatively long time , and 10 bit resulotion is enough, pluse i measure it only after i finish with all the other adc reads also i give some frequency piout to the device before reading this one channel 

    and eventualy i put the program to system on sleep mode so i am going to stop sampling and maybe cut the power to saadc driver anyway

    so to sum:

    what do i requier in order to re-init the saadc, why do i need to reconfigure the buffers and channels if i use 2 different saadc config in every init ?

  • ziv123 said:
    why do i need to reconfigure the buffers and channels if i use 2 different saadc config in every init ?

     In your case it seems like you will be done with processing the saadc buffers before you need to re-configure the saadc, in that case you don't need to reconfigure the buffers. 

    Just use the uninit and inint functions and you should be fine. 



  • hello again Slight smile

    must say your site is running quite low speed today and i have to rewrite all this message again because it didn't load ): 

    i have 2 modules, in each module's init function i configure the saadc.

    the first run fine the second give error 17, BUSY when i try to init the channel , i read in the forum that this type of error might have something to do with conversion of the buffers, don't realy understand why it matters in my case since i am using different buffers for each module's saadc. here is the codes:

    //  //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(3, &hydr_channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(hydr_buffer_pool[0], HYDR_NUMBER_OF_ADC_SAMPLES);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(hydr_buffer_pool[1], HYDR_NUMBER_OF_ADC_SAMPLES);
        APP_ERROR_CHECK(err_code);

    //    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(0, &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(1, &audio_channel_config);
        APP_ERROR_CHECK(err_code);
    
        audio_channel_config.pin_p = AUDIO_PIEZO_ADC_INPUT_PREAMPLYFIER_INPUT_PIN;
        err_code = nrf_drv_saadc_channel_init(2, &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);

    what will be the right way to handle this error ?

    what i have done that solved it (though i am not sure its the best way) is to take the buffer conversions and put it after i call the nrf_drv_saadc_init() each time i call it and after i finish with this module i call the saadc uninit function

    another question is that i see i start getting saadc sampling events right after calling the init even if i don't use the nrf_drv_saadc_sample()

    which is not good for me cause i want the sampling to start at a certain point and i want to have just one oversampled sample, what do i need to change ?

    my saadc init look like this now :

    err_code = nrf_drv_saadc_init(&hydr_saadc_config, hydr_saadc_callback);// TBD - need to make sure, maybe global volatile flag that
                                                                       // the other modul did not initialize the saadc WITHOUT UNINITIALIZING IT
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_buffer_convert(hydr_buffer_pool[0], HYDR_NUMBER_OF_ADC_SAMPLES);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_saadc_buffer_convert(hydr_buffer_pool[1], HYDR_NUMBER_OF_ADC_SAMPLES);
    APP_ERROR_CHECK(err_code);
                    

    and my callback:

    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();
        }
    }

    [later today i edit] - apperntly i was working at release mode while debugging, returning to debug mode created some assertion issues.. in specific i don't get this assertion:

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

    it says oversampling can be only when working with one channel but if over sampling is disabled and i have more then one channel it asserts .. so what should i do???, also this assertions comply me to init the saadc before the channels initiation and change the way i thought of working before .. don't know the all over consequences of this debug vs release head hack 

    hope to read you soon and hope this reply will be uploaded properly so i will not have to re-write it again ): 

    best regards

    Ziv

Related