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

SAADC callback never called with Softdevice

Hello, I'm having trouble to understand why the saadc buffer is not being filled.

I had already tested this functionality without the softdevice, and everything worked fine but now, with the softdevice,

I found that the "saadc_callback" function is not called at any time. 
I tried to follow some clues after reading several posts here on the blog on this subject, but they did not lead me to a solution.

Tested items:
Modify saadc to continuous mode.
Modify the saadc interrupt priority.


The timer for the PPI ist the TIMER1

Thanks
Parents
  • Hello,

    I'm having trouble to understand why the saadc buffer is not being filled.

    Is the SAADC generating any errors, or is it initializing and starting successfully?

    I had already tested this functionality without the softdevice, and everything worked fine but now, with the softdevice,

    By this, do you mean that the difference is when you enable the SoftDevice? Could you elaborate on how you included and enabled the SoftDevice?

    Tested items:
    Modify saadc to continuous mode.
    Modify the saadc interrupt priority.

    Could you share the code where you configure and start the sampling?
    Please use the "insert -> Code" option when doing so.

    The timer for the PPI ist the TIMER1

    Do you mean that the PPI timer IS or ISNT timer1?
    Timer0 is the one used by the SoftDevice.

    Looking forward to solving this issue together!

    Best regards,
    Karl

  • Is the SAADC generating any errors, or is it initializing and starting successfully?

    The SAADC is successfully initialized and started. 

    By this, do you mean that the difference is when you enable the SoftDevice? Could you elaborate on how you included and enabled the SoftDevice?

    I developed this part of the program (SAADC + FFT) based on the example of saadc and fft found in SKD17. I did the tests after modifying the project, but when I tried to join with the example of ble_app_uart_c also found in SDK17 (I just removed the part that uses the uart to receive and send the data that will be sent by ble, and this part I also tested) the buffer has stopped being filled.

    I use saadc+fft to decode one mac address and use it to connect to another ble device.

    Do you mean that the PPI timer IS or ISNT timer1?
    Timer0 is the one used by the SoftDevice.

    Sorry, I meant I use TIMER1 for the PPI that controls the SAADC sampling

    Could you share the code where you configure and start the sampling?
    Please use the "insert -> Code" option when doing so.

    void timer_handler(nrf_timer_event_t event_type, void * p_context)
    {
        flag_adc = true;
    }
    
    
    void saadc_sampling_event_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
        err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
        APP_ERROR_CHECK(err_code);
    
        uint32_t ticks = 100; //160000 kHz
        nrf_drv_timer_extended_compare(&m_timer,
                                       NRF_TIMER_CC_CHANNEL0,
                                       ticks,
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                       true);
        nrf_drv_timer_enable(&m_timer);
    
        uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                    NRF_TIMER_CC_CHANNEL0);
        uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();
    
        /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
        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);
    }
    
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {   
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            ret_code_t err_code;
            nrf_gpio_pin_toggle(NRF_GPIO_PIN_MAP(1, 11));
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
            
            if(flag_buffer == 1)
            {
                flag_buffer = 0;
    
            }else if(flag_buffer == 0){
                flag_buffer = 1;
    
            }
    
        }
    
    }
    
    
    void saadc_init(void)
    {
        ret_code_t err_code;
    
        //channel config
        nrf_saadc_channel_config_t channel_config;
    
        channel_config.resistor_p = NRF_SAADC_RESISTOR_PULLDOWN;
        channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
        channel_config.gain       = NRF_SAADC_GAIN1;
        channel_config.reference  = NRF_SAADC_REFERENCE_INTERNAL;
        channel_config.acq_time   = NRF_SAADC_ACQTIME_3US;
        channel_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
        channel_config.pin_p      = NRF_SAADC_INPUT_AIN1;
        channel_config.pin_n      = NRF_SAADC_INPUT_DISABLED;
    
        //saadc config
        nrf_drv_saadc_config_t saadc_config;
    
        saadc_config.low_power_mode = false;
        saadc_config.resolution= NRF_SAADC_RESOLUTION_12BIT;
        saadc_config.oversample= NRF_SAADC_OVERSAMPLE_16X;
        saadc_config.interrupt_priority= APP_IRQ_PRIORITY_LOW;
    
        //saadc init
        err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        //channel init
        err_code = nrf_drv_saadc_channel_init(0, &channel_config);
        APP_ERROR_CHECK(err_code);
    
        //buffer init (duble)
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    
        //continous mode
    //    nrf_saadc_continuous_mode_enable(100); //10khz enchantilionage
    //    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
    //    nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
    //    nrf_saadc_int_enable(NRF_SAADC_INT_END);
    
        saadc_sampling_event_init();
    
    }

    The idea for the future is to have several devices that all are configured as ble peripherals and when they receive an indication (boot status) it starts to behave as a central ble to connect to a specific device (through the mac address received using saadc + fft) to exchange data.

    Best regards,
    Fernando

  • Hello Fernando,

    Thank you for elaborating, this greatly helps my understanding of your project.
    I at least do not immediately see anything wrong with the setup and configuration of the SAADC that you have shared. However, I can not see that you are calling nrf_drv_ppi_channel_enable
    anywhere. Could you confirm for me that this is in fact done?

    f.albu said:
    First I checked through the watch that my buffer variable was not being modified, after I checked that the RESULT.PTR register is not being modified either. 

    Is the application functioning as expected, with the exception of the SAADC?
    Are you able to verify that the device has not become stuck somewhere, as a part of the added SoftDevice code?
    For example, does the SoftDevice / BLE communication with the device function as expected?

    Best regards,
    Karl

  • I can not see that you are calling nrf_drv_ppi_channel_enable
    anywhere. Could you confirm for me that this is in fact done?

    I do that in the main function.

    I think I found a solution, I changed the SAADC priority to APP_IRQ_PRIORITY_THREAD in their initialization but I don't know if it's the best (if it will cause problems in the future with the messages sent by ble)

        saadc_config.resolution= NRF_SAADC_RESOLUTION_12BIT;
        saadc_config.oversample= NRF_SAADC_OVERSAMPLE_16X;
        saadc_config.interrupt_priority= APP_IRQ_PRIORITY_THREAD;
    
        //saadc init
        err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
        APP_ERROR_CHECK(err_code);

  • f.albu said:
    I do that in the main function.

    Thank you for confirming this.

    f.albu said:
    I think I found a solution, I changed the SAADC priority to APP_IRQ_PRIORITY_THREAD in their initialization but I don't know if it's the best (if it will cause problems in the future with the messages sent by ble)

    I would not think that APP_IRQ_PRIORITY would cause the behavior you describe - SAADC initializing but buffer not getting filled, since you are using PPI.
    What is your SAMPLES_IN_BUFFER set to?

    f.albu said:
    (if it will cause problems in the future with the messages sent by ble)

    No, you can rest assured that this will not cause any problems with the BLE communication. The SoftDevice takes priority over any application-layer task.

    Best regards,
    Karl

  • SAMPLES_IN_BUFFER

    #define SAMPLES_IN_BUFFER         128  

    When I activate the BLE_NUS Log in debug mode, it shows the following message:

    <info> app: Connected to device with Nordic UART Service.
    <debug> nrf_ble_gq: Processing the request queue...

  • Thank you for the update.
    I do not immediately see how changing the priority to APP_IRQ_PRIORITY_THREAD could resolve the issue you described, but I am happy that you have found a solution to your issue.

    Please do not hesitate to open a new ticket if you should encounter any issues or questions in the future!

    Best regards,
    Karl

Reply Children
Related