Im trying to get SAADC to continuously sample using internal timer but im getting couple of samples and then it stops, tried everything but I'm obviously forgetting something.
Any help would be appreciated.
/* * Copyright (c) 2016 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/kernel.h> #include <zephyr/sys/printk.h> #include <zephyr/usb/usb_device.h> #include <zephyr/usb/usbd.h> #include <zephyr/drivers/uart.h> #include "nrfx_example.h" #include "saadc_examples_common.h" #include <nrfx_saadc.h> #include <nrfx_gpiote.h> BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart), "Console device is not ACM CDC UART device"); /** @brief Symbol specifying analog input to be observed by SAADC channel 0. */ #define CH0_AIN ANALOG_INPUT_TO_SAADC_AIN(ANALOG_INPUT_A0) /** @brief Symbol specifying GPIOTE instance to be used. */ #define GPIOTE_INST_IDX 0 /** @brief Symbol specifying GPIO pin used to test the functionality of SAADC. */ #define OUT_GPIO_PIN ANALOG_INPUT_A0 /** @brief Acquisition time [us] for source resistance <= 10 kOhm (see SAADC electrical * specification). */ #define ACQ_TIME_10K 3UL /** @brief Conversion time [us] (see SAADC electrical specification). */ #define CONV_TIME 2UL /** @brief Internal timer frequency [Hz] is derived from PCLK16M (see SAMPLERATE register in SAADC). */ #define INTERNAL_TIMER_FREQ 16000000UL /** @brief SAADC sample frequency for the continuous sampling. */ #define SAADC_SAMPLE_FREQUENCY 600UL /** @brief Internal timer capture and compare value. */ #define INTERNAL_TIMER_CC (INTERNAL_TIMER_FREQ / SAADC_SAMPLE_FREQUENCY) /** * @brief Symbol specifying the number of sample buffers ( @ref m_sample_buffers ). * Two buffers are required for performing double-buffered conversions. */ #define BUFFER_COUNT 2UL /** @brief Symbol specifying the size of singular sample buffer ( @ref m_sample_buffers ). */ #define BUFFER_SIZE 1UL /** @brief Symbol specifying the resolution of the SAADC. */ #define RESOLUTION NRF_SAADC_RESOLUTION_12BIT /** @brief SAADC channel configuration structure for single channel use. */ static const nrfx_saadc_channel_t m_single_channel = SAADC_CHANNEL_SE_ACQ_3US(CH0_AIN, 0); static uint16_t m_sample_buffers[BUFFER_COUNT][BUFFER_SIZE]; /** @brief Flag indicating that sampling on every specified channel is finished and buffer ( @ref * m_sample_buffers ) is filled with samples. */ static bool m_saadc_done; /** For continuous sampling the sample rate SAADC_SAMPLE_FREQUENCY should fulfill the following * criteria (see SAADC Continuous sampling). */ NRFX_STATIC_ASSERT(SAADC_SAMPLE_FREQUENCY <= (1000000UL / (ACQ_TIME_10K + CONV_TIME))); /** Possible range value of a CC field in the SAMPLERATE register (SAADC) is 80-2047. */ NRFX_STATIC_ASSERT((INTERNAL_TIMER_CC >= 80UL) && (INTERNAL_TIMER_CC <= 0xFFFFFUL)); void debug_saadc_state(void) { printk("SAMPLERATE register: 0x%08X\n", NRF_SAADC->SAMPLERATE); printk("STATUS: 0x%08X\n", NRF_SAADC->STATUS); printk("ENABLE: 0x%08X\n", NRF_SAADC->ENABLE); printk("EVENTS_END: %d\n", NRF_SAADC->EVENTS_END); printk("EVENTS_DONE: %d\n", NRF_SAADC->EVENTS_DONE); printk("RESULT.AMOUNT: %d\n", NRF_SAADC->RESULT.AMOUNT); printk("BUFFER PTR: 0x%08X\n", (uint32_t)NRF_SAADC->RESULT.PTR); printk("PUBLISH_END: 0x%08X\n", NRF_SAADC->PUBLISH_END); } static void saadc_handler(nrfx_saadc_evt_t const *p_event) { nrfx_err_t status; (void)status; static uint16_t buffer_index = 1; switch (p_event->type) { case NRFX_SAADC_EVT_CALIBRATEDONE: status = nrfx_saadc_mode_trigger(); NRFX_ASSERT(status == NRFX_SUCCESS); break; case NRFX_SAADC_EVT_BUF_REQ: printk("BUF_REQ triggered. Setting buffer index: %d\n", buffer_index); // Provide the next buffer nrfx_err_t status = nrfx_saadc_buffer_set(m_sample_buffers[buffer_index], BUFFER_SIZE); if (status != NRFX_SUCCESS) { printk("Error setting buffer: %d\n", status); } buffer_index = (buffer_index + 1) % BUFFER_COUNT; // Alternate buffers debug_saadc_state(); NRF_SAADC->RESULT.PTR = (uint32_t)m_sample_buffers[buffer_index]; break; case NRFX_SAADC_EVT_DONE: printk("DONE triggered.\n"); // Process the sample int16_t sample_value = NRFX_SAADC_SAMPLE_GET(RESOLUTION, p_event->data.done.p_buffer, 0); printk("= %d\n", sample_value); debug_saadc_state(); NRF_SAADC->EVENTS_DONE = 0; NRF_SAADC->EVENTS_END = 0; NRF_SAADC->TASKS_START = 1; break; default: break; } } int main(void) { if (usb_enable(NULL)) { return 0; } nrfx_err_t status; (void)status; IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_GPIOTE_INST_GET(GPIOTE_INST_IDX)), 2, NRFX_GPIOTE_INST_HANDLER_GET(GPIOTE_INST_IDX), 0, 0); IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_SAADC), 2, nrfx_saadc_irq_handler, 0, 0); printk("Starting nrfx_saadc advanced non-blocking sampling with internal timer example.\n"); printk("INTERNAL_TIMER_CC: %lu\n", INTERNAL_TIMER_CC); status = nrfx_saadc_init(2); NRFX_ASSERT(status == NRFX_SUCCESS); status = nrfx_saadc_channel_config(&m_single_channel); NRFX_ASSERT(status == NRFX_SUCCESS); nrfx_saadc_adv_config_t adv_config = NRFX_SAADC_DEFAULT_ADV_CONFIG; adv_config.internal_timer_cc = INTERNAL_TIMER_CC; adv_config.start_on_end = true; uint32_t channel_mask = nrfx_saadc_channels_configured_get(); status = nrfx_saadc_advanced_mode_set(channel_mask, RESOLUTION, &adv_config, saadc_handler); NRFX_ASSERT(status == NRFX_SUCCESS); status = nrfx_saadc_buffer_set(m_sample_buffers[0], BUFFER_SIZE); NRFX_ASSERT(status == NRFX_SUCCESS); nrfx_gpiote_t const gpiote_inst = NRFX_GPIOTE_INSTANCE(GPIOTE_INST_IDX); status = nrfx_gpiote_init(&gpiote_inst, 2); NRFX_ASSERT(status == NRFX_SUCCESS); printk("GPIOTE status: %s", nrfx_gpiote_init_check(&gpiote_inst) ? "initialized\n" : "not initialized\n"); pin_on_event_toggle_setup( &gpiote_inst, OUT_GPIO_PIN, nrf_saadc_event_address_get(NRF_SAADC, NRF_SAADC_EVENT_RESULTDONE)); m_saadc_done = true; status = nrfx_saadc_offset_calibrate(saadc_handler); NRFX_ASSERT(status == NRFX_SUCCESS); while (1) { k_sleep(K_SECONDS(1)); } }