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

ADC DMA Readings shift after pausing code or breakpoint nRF52832

Hello,

I am working on a project where I am using 8 ADC channels on the nRF52832.  When I run the code the device seems to get ADC values that look correct.  But, if I pause the device or hit a break point the ADC values seem to be off.  At first when I run the code, the ADC values seem to be in correct memory region, address.  When I pause the code and restart it, it seems as if the ADC readings have move over by two bytes.  Please see the attached images.  I tested this by modifying the analog signal that would be seen on AIN2, and I can see that from the first picture, the values of AIN2 appears to be in the column 3 and changing.  After pausing and restarting the device, the readings for AIN2 appear to be in column 4.

What is going on here?  Can anyone offer any suggestions? 

I am using a nRF52832 in a module from Raytac.

Below is a listing of the code that I used for the ADC values. 

 

// saadc defines
#define SAADC_SAMPLES_IN_BUFFER 256
#define SAADC_SAMPLE_RATE 5


//setup for adc reading of pot
#if (1)

volatile uint8_t state = 1;
float pot1;
float pot2;
float pot3;
float pot4;
float inpin;
float feedpin;
bool adcsampledone = false;
int STEP_COUNT = 50;


uint32_t ADC_AIN0 = 0;
uint32_t ADC_AIN1 = 0; 
uint32_t ADC_AIN2 = 0; 
uint32_t ADC_AIN3 = 0; 
uint32_t ADC_AIN4 = 0; 
uint32_t ADC_AIN5 = 0; 
uint32_t ADC_AIN6 = 0; 
uint32_t ADC_AIN7 = 0;


static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);
static nrf_saadc_value_t m_buffer_pool[2][SAADC_SAMPLES_IN_BUFFER];
static nrf_ppi_channel_t m_ppi_channel;
static uint32_t m_adc_evt_counter;
void timer_handler(nrf_timer_event_t event_type, void *p_context) 
{
}


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_config = NRF_DRV_TIMER_DEFAULT_CONFIG;
    timer_config.frequency = NRF_TIMER_FREQ_31250Hz;
    err_code = nrf_drv_timer_init(&m_timer, &timer_config, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, SAADC_SAMPLE_RATE);
    nrf_drv_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
    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_event_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_event_addr);
    APP_ERROR_CHECK(err_code);
}

void saadc_sampling_event_enable(void) 
{
    ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
    APP_ERROR_CHECK(err_code);
}

void saadc_callback(nrf_drv_saadc_evt_t const *p_event) 
{
    adcsampledone = true;
    //gpio024_on();
    //gpio027_on();
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE) 
    {
        ret_code_t err_code;
        uint16_t adc_value;
        uint8_t value[SAADC_SAMPLES_IN_BUFFER * 2];
        uint16_t bytes_to_send;

        // set buffers
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

        ADC_AIN0 = 0;
        ADC_AIN1 = 0; 
        ADC_AIN2 = 0; 
        ADC_AIN3 = 0; 
        ADC_AIN4 = 0; 
        ADC_AIN5 = 0; 
        ADC_AIN6 = 0; 
        ADC_AIN7 = 0; 

        for (uint16_t i = 0; i < SAADC_SAMPLES_IN_BUFFER; i++) 
        {
            ADC_AIN0 += p_event->data.done.p_buffer[i++];
            ADC_AIN1 += p_event->data.done.p_buffer[i++];
            ADC_AIN2 += p_event->data.done.p_buffer[i++];
            ADC_AIN3 += p_event->data.done.p_buffer[i++];
            ADC_AIN4  += p_event->data.done.p_buffer[i++];
            ADC_AIN5 += p_event->data.done.p_buffer[i++];
            ADC_AIN6 += p_event->data.done.p_buffer[i++]; 
            ADC_AIN7 += p_event->data.done.p_buffer[i];
        }

        ADC_AIN0 = ADC_AIN0 /(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN1 = ADC_AIN1/(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN2 = ADC_AIN2/(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN3 = ADC_AIN3/(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN4 = ADC_AIN4/(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN5 = ADC_AIN5 /(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN6 = ADC_AIN6/(SAADC_SAMPLES_IN_BUFFER/8);
        ADC_AIN7 = ADC_AIN7/(SAADC_SAMPLES_IN_BUFFER/8);
        m_adc_evt_counter++;
    }
    //gpio024_off();
    //gpio027_off();
}
#endif

void saadc_init(void) 
{
    ret_code_t err_code;

    nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
    saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT;

    // AIN0 
    nrf_saadc_channel_config_t channel_0_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);     //NRF_SAADC_INPUT_AIN4);
    channel_0_config.gain = NRF_SAADC_GAIN1_4;
    channel_0_config.reference = NRF_SAADC_REFERENCE_VDD4;

    // AIN1 
    nrf_saadc_channel_config_t channel_1_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);    //NRF_SAADC_INPUT_AIN5);
    channel_1_config.gain = NRF_SAADC_GAIN1_4;
    channel_1_config.reference = NRF_SAADC_REFERENCE_VDD4;

    // AIN2 
    nrf_saadc_channel_config_t channel_2_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);    //NRF_SAADC_INPUT_AIN6);
    channel_2_config.gain = NRF_SAADC_GAIN1_4;
    channel_2_config.reference = NRF_SAADC_REFERENCE_VDD4;

    // AIN3 
    nrf_saadc_channel_config_t channel_3_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3);    //NRF_SAADC_INPUT_AIN7);
    channel_3_config.gain = NRF_SAADC_GAIN1_4;
    channel_3_config.reference = NRF_SAADC_REFERENCE_VDD4;

    // AIN4 
    nrf_saadc_channel_config_t channel_4_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);    //NRF_SAADC_INPUT_AIN0);
    channel_4_config.gain = NRF_SAADC_GAIN1_4;
    channel_4_config.reference = NRF_SAADC_REFERENCE_VDD4;
    
    // AIN5 
    nrf_saadc_channel_config_t channel_5_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);    //NRF_SAADC_INPUT_AIN1);
    channel_5_config.gain = NRF_SAADC_GAIN1_4;
    channel_5_config.reference = NRF_SAADC_REFERENCE_VDD4;

    // AIN6 
    nrf_saadc_channel_config_t channel_6_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6);    //NRF_SAADC_INPUT_AIN1);
    channel_6_config.gain = NRF_SAADC_GAIN1_4;
    channel_6_config.reference = NRF_SAADC_REFERENCE_VDD4;

    // AIN7 
    nrf_saadc_channel_config_t channel_7_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);    //NRF_SAADC_INPUT_AIN1);
    channel_7_config.gain = NRF_SAADC_GAIN1_4;
    channel_7_config.reference = NRF_SAADC_REFERENCE_VDD4;

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

    err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(1, &channel_1_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(2, &channel_2_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(3, &channel_3_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(4, &channel_4_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(5, &channel_5_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(6, &channel_6_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(7, &channel_7_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0], SAADC_SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1], SAADC_SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}

///////////////////////////////////////////////////////////////////////////////////////
/* Main */
///////////////////////////////////////////////////////////////////////////////////////

int main(void) {

    //initalizations
    initp_024gpio_output();
    initp_027gpio_output();
    saadc_init();
    saadc_sampling_event_init();
    saadc_sampling_event_enable();

    uint32_t err_code;

    bool epprom_error = 0;
    bsp_board_init(BSP_INIT_LEDS);
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    /* Initializing TWI master interface for EEPROM */
    err_code = twi_master_init();
    APP_ERROR_CHECK(err_code);

    //err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL);

    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
    uart_config.pseltxd = TX_PIN_NUMBER;
    uart_config.pselrxd = RX_PIN_NUMBER;
    uart_config.hwfc = NRF_UART_HWFC_DISABLED;
    err_code = nrf_cli_init(&m_cli_uart, &uart_config, true, true, NRF_LOG_SEVERITY_INFO);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_cli_start(&m_cli_uart);
    APP_ERROR_CHECK(err_code);

    lfclk_config();

    rtc_config();

    /* Main loop */
    while (1) 
    {
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        nrf_cli_process(&m_cli_uart);
        if (epprom_error != eeprom_simulator_error_check()) 
        {
            epprom_error = eeprom_simulator_error_check();
            if (epprom_error != 0) 
            {
                NRF_LOG_RAW_INFO("WARNING: EEPROM transmission error detected.\n"
                "Use 'x' command to read error word.\n");
            }
        }



        if(GetDisplayControlInputValue() == true)
        {
            static uint32_t display_ControlValue_timestamp = 0;
            if ((getControlInputConfiguration() == INPUT_VOLTAGE_0_TO_5VDC)
             || (getControlInputConfiguration() == INPUT_VOLTAGE_0_TO_10VDC))
            {

                if(rtc_tick > (display_ControlValue_timestamp + 8))
                {
                    NRF_LOG_RAW_INFO("Control Voltage is " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(controlVoltage));
                    display_ControlValue_timestamp = rtc_tick;
                }
            }
        } 

        if(GetDisplayFeedbackInputValue() == true)
        {
            static uint32_t display_FeedbackValue_timestamp = 0;
            if ((getControlInputConfiguration() == INPUT_VOLTAGE_0_TO_5VDC)
             || (getControlInputConfiguration() == INPUT_VOLTAGE_0_TO_10VDC))
            {
                if(rtc_tick > (display_FeedbackValue_timestamp + 8))
                {
                    NRF_LOG_RAW_INFO("Feedback Voltage is " NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(feedbackVoltage));
                    display_FeedbackValue_timestamp = rtc_tick;
                }
            }
        }
        
    }
}

Thanks.

Parents
  • Good day,

    So when the saadc_callback occurs, I was not stopping the timer.  I have added a disable of the timer at the start of the saadc_callback and then re-enable it when completing the callback.  This seems to have fixed the issue.

    The callback now looks like this.

    void saadc_callback(nrf_drv_saadc_evt_t const *p_event) 
    {
        adcsampledone = true;
        //gpio024_on();
        //gpio027_on();
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE) 
        {
            nrf_drv_timer_disable(&m_timer);
            ret_code_t err_code;
            uint16_t adc_value;
            uint8_t value[SAADC_SAMPLES_IN_BUFFER * 2];
            uint16_t bytes_to_send;
    
            // set buffers
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
            ADC_AIN0 = 0;
            ADC_AIN1 = 0; 
            ADC_AIN2 = 0; 
            ADC_AIN3 = 0; 
            ADC_AIN4 = 0; 
            ADC_AIN5 = 0; 
            ADC_AIN6 = 0; 
            ADC_AIN7 = 0; 
    
            for (uint16_t i = 0; i < SAADC_SAMPLES_IN_BUFFER; i++) 
            {
                ADC_AIN0 += p_event->data.done.p_buffer[i++];
                ADC_AIN1 += p_event->data.done.p_buffer[i++];
                ADC_AIN2 += p_event->data.done.p_buffer[i++];
                ADC_AIN3 += p_event->data.done.p_buffer[i++];
                ADC_AIN4  += p_event->data.done.p_buffer[i++];
                ADC_AIN5 += p_event->data.done.p_buffer[i++];
                ADC_AIN6 += p_event->data.done.p_buffer[i++]; 
                ADC_AIN7 += p_event->data.done.p_buffer[i];
            }
    
            ADC_AIN0 = ADC_AIN0 /(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN1 = ADC_AIN1/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN2 = ADC_AIN2/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN3 = ADC_AIN3/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN4 = ADC_AIN4/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN5 = ADC_AIN5 /(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN6 = ADC_AIN6/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN7 = ADC_AIN7/(SAADC_SAMPLES_IN_BUFFER/8);
            m_adc_evt_counter++;
            nrf_drv_timer_enable(&m_timer);
        }
        //gpio024_off();
        //gpio027_off();
    }

Reply
  • Good day,

    So when the saadc_callback occurs, I was not stopping the timer.  I have added a disable of the timer at the start of the saadc_callback and then re-enable it when completing the callback.  This seems to have fixed the issue.

    The callback now looks like this.

    void saadc_callback(nrf_drv_saadc_evt_t const *p_event) 
    {
        adcsampledone = true;
        //gpio024_on();
        //gpio027_on();
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE) 
        {
            nrf_drv_timer_disable(&m_timer);
            ret_code_t err_code;
            uint16_t adc_value;
            uint8_t value[SAADC_SAMPLES_IN_BUFFER * 2];
            uint16_t bytes_to_send;
    
            // set buffers
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
            ADC_AIN0 = 0;
            ADC_AIN1 = 0; 
            ADC_AIN2 = 0; 
            ADC_AIN3 = 0; 
            ADC_AIN4 = 0; 
            ADC_AIN5 = 0; 
            ADC_AIN6 = 0; 
            ADC_AIN7 = 0; 
    
            for (uint16_t i = 0; i < SAADC_SAMPLES_IN_BUFFER; i++) 
            {
                ADC_AIN0 += p_event->data.done.p_buffer[i++];
                ADC_AIN1 += p_event->data.done.p_buffer[i++];
                ADC_AIN2 += p_event->data.done.p_buffer[i++];
                ADC_AIN3 += p_event->data.done.p_buffer[i++];
                ADC_AIN4  += p_event->data.done.p_buffer[i++];
                ADC_AIN5 += p_event->data.done.p_buffer[i++];
                ADC_AIN6 += p_event->data.done.p_buffer[i++]; 
                ADC_AIN7 += p_event->data.done.p_buffer[i];
            }
    
            ADC_AIN0 = ADC_AIN0 /(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN1 = ADC_AIN1/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN2 = ADC_AIN2/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN3 = ADC_AIN3/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN4 = ADC_AIN4/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN5 = ADC_AIN5 /(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN6 = ADC_AIN6/(SAADC_SAMPLES_IN_BUFFER/8);
            ADC_AIN7 = ADC_AIN7/(SAADC_SAMPLES_IN_BUFFER/8);
            m_adc_evt_counter++;
            nrf_drv_timer_enable(&m_timer);
        }
        //gpio024_off();
        //gpio027_off();
    }

Children
Related