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,

    f.albu said:
    The SAADC is successfully initialized and started. 

    Please elaborate how you have verified this. If it is started, I would assume that the buffer would begin filling shortly after.
    How are you verifying whether the buffer is being filled or not? 
    And what is your intended sampling frequency?

    f.albu said:
    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)

    Just to make sure I have understood you intentions correctly - you successfully implemented your desired SAADC + FFT functionality in the SAADC example from the SDK, before you copied this code into the ble_app_uart_c BLE central example from the SDK. You then removed the parts of the example responsible for receiving and sending UART messages, and replaced it by your SAADC outputs instead?

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

    So, you are receiving a signal on your SAADC input that is a mac address encoded using FFT, have I understood you correctly?

    f.albu said:
    Sorry, I meant I use TIMER1 for the PPI that controls the SAADC sampling

    Thank you for clarifying.

    f.albu said:
    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.

    I see. Have you seen the experimental multirole example from the SDK?
    It demonstrates functionality similar to what you describe.

    Looking forward to resolving this issue together!

    Best regards,
    Karl

  • Please elaborate how you have verified this. If it is started, I would assume that the buffer would begin filling shortly after.

    To verify that the SAADC was well initiated, I checked the recorders with the help of segger. As you can see in the text below.

    SAADC                                          
        TASKS_START                                
            TASKS_START                            
        TASKS_SAMPLE                               
            TASKS_SAMPLE                           
        TASKS_STOP                                 
            TASKS_STOP                             
        TASKS_CALIBRATEOFFSET                      
            TASKS_CALIBRATEOFFSET                  
        EVENTS_STARTED               0x00000000    
            EVENTS_STARTED           0             
        EVENTS_END                   0x00000001    
            EVENTS_END               1             
        EVENTS_DONE                  0x00000001    
            EVENTS_DONE              1             
        EVENTS_RESULTDONE            0x00000001    
            EVENTS_RESULTDONE        1             
        EVENTS_CALIBRATEDONE         0x00000000    
            EVENTS_CALIBRATEDONE     0             
        EVENTS_STOPPED               0x00000000    
            EVENTS_STOPPED           0             
        INTEN                        0x00000002    
            STARTED                  0             
            END                      1             
            DONE                     0             
            RESULTDONE               0             
            CALIBRATEDONE            0             
            STOPPED                  0             
            CH0LIMITH                0             
            CH0LIMITL                0             
            CH1LIMITH                0             
            CH1LIMITL                0             
            CH2LIMITH                0             
            CH2LIMITL                0             
            CH3LIMITH                0             
            CH3LIMITL                0             
            CH4LIMITH                0             
            CH4LIMITL                0             
            CH5LIMITH                0             
            CH5LIMITL                0             
            CH6LIMITH                0             
            CH6LIMITL                0             
            CH7LIMITH                0             
            CH7LIMITL                0             
        INTENSET                     0x00000002    
            STARTED                  0             
            END                      1             
            DONE                     0             
            RESULTDONE               0             
            CALIBRATEDONE            0             
            STOPPED                  0             
            CH0LIMITH                0             
            CH0LIMITL                0             
            CH1LIMITH                0             
            CH1LIMITL                0             
            CH2LIMITH                0             
            CH2LIMITL                0             
            CH3LIMITH                0             
            CH3LIMITL                0             
            CH4LIMITH                0             
            CH4LIMITL                0             
            CH5LIMITH                0             
            CH5LIMITL                0             
            CH6LIMITH                0             
            CH6LIMITL                0             
            CH7LIMITH                0             
            CH7LIMITL                0             
        INTENCLR                     0x00000002    
            STARTED                  0             
            END                      1             
            DONE                     0             
            RESULTDONE               0             
            CALIBRATEDONE            0             
            STOPPED                  0             
            CH0LIMITH                0             
            CH0LIMITL                0             
            CH1LIMITH                0             
            CH1LIMITL                0             
            CH2LIMITH                0             
            CH2LIMITL                0             
            CH3LIMITH                0             
            CH3LIMITL                0             
            CH4LIMITH                0             
            CH4LIMITL                0             
            CH5LIMITH                0             
            CH5LIMITL                0             
            CH6LIMITH                0             
            CH6LIMITL                0             
            CH7LIMITH                0             
            CH7LIMITL                0             
        STATUS                       0x00000001    
            STATUS                   1             
        ENABLE                       0x00000001    
            ENABLE                   1             
        RESOLUTION                   0x00000002    
            VAL                      2             
        OVERSAMPLE                   0x00000004    
            OVERSAMPLE               4             
        SAMPLERATE                   0x00000000    
            CC                       0x000         
            MODE                     0             
        EVENTS_CH[0].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[0].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[1].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[1].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[2].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[2].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[3].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[3].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[4].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[4].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[5].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[5].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[6].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[6].LIMITL          0x00000000    
            LIMITL                   0             
        EVENTS_CH[7].LIMITH          0x00000000    
            LIMITH                   0             
        EVENTS_CH[7].LIMITL          0x00000000    
            LIMITL                   0             
        CH[0].PSELP                  0x00000002    
            PSELP                    2             
        CH[0].PSELN                  0x00000000    
            PSELN                    0             
        CH[0].CONFIG                 0x00000501    
            RESP                     1             
            RESN                     0             
            GAIN                     5             
            REFSEL                   0             
            TACQ                     0             
            MODE                     0             
            BURST                    0             
        CH[0].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[1].PSELP                  0x00000000    
            PSELP                    0             
        CH[1].PSELN                  0x00000000    
            PSELN                    0             
        CH[1].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[1].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[2].PSELP                  0x00000000    
            PSELP                    0             
        CH[2].PSELN                  0x00000000    
            PSELN                    0             
        CH[2].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[2].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[3].PSELP                  0x00000000    
            PSELP                    0             
        CH[3].PSELN                  0x00000000    
            PSELN                    0             
        CH[3].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[3].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[4].PSELP                  0x00000000    
            PSELP                    0             
        CH[4].PSELN                  0x00000000    
            PSELN                    0             
        CH[4].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[4].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[5].PSELP                  0x00000000    
            PSELP                    0             
        CH[5].PSELN                  0x00000000    
            PSELN                    0             
        CH[5].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[5].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[6].PSELP                  0x00000000    
            PSELP                    0             
        CH[6].PSELN                  0x00000000    
            PSELN                    0             
        CH[6].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[6].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        CH[7].PSELP                  0x00000000    
            PSELP                    0             
        CH[7].PSELN                  0x00000000    
            PSELN                    0             
        CH[7].CONFIG                 0x00020000    
            RESP                     0             
            RESN                     0             
            GAIN                     0             
            REFSEL                   0             
            TACQ                     2             
            MODE                     0             
            BURST                    0             
        CH[7].LIMIT                  0x7fff8000    
            LOW                      0x8000        
            HIGH                     0x7fff        
        RESULT.PTR                   0x20003c3c    
            PTR                      0x20003c3c    
        RESULT.MAXCNT                0x00000080    
            MAXCNT                   0x0080        
        RESULT.AMOUNT                0x00000080    
            AMOUNT                   0x0080        

    How are you verifying whether the buffer is being filled or not?

    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. 

    And what is your intended sampling frequency?

    I need a 10kHz sampling frequency. But as I use oversampling in x16, I set it to have a sampling frequency of 160kHz.

    Just to make sure I have understood you intentions correctly - you successfully implemented your desired SAADC + FFT functionality in the SAADC example from the SDK, before you copied this code into the ble_app_uart_c BLE central example from the SDK. You then removed the parts of the example responsible for receiving and sending UART messages, and replaced it by your SAADC outputs instead?

    That's right, but the message I send is the value of the power of a specific frequency, which I obtain through the treatment of the signal sampled

    So, you are receiving a signal on your SAADC input that is a mac address encoded using FFT, have I understood you correctly?

    Is the MAC address modulated in frequency

    I see. Have you seen the experimental multirole example from the SDK?

    Yes, I've seen it, but for now I've left defined the roles of each module (or central or peripheral)

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

Reply
  • 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);

Children
Related