Hello,
I changed saadc.zip for nRF5340DK and my main.c is like following:
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <helpers/nrfx_gppi.h>
#if defined(DPPI_PRESENT)
#include <nrfx_dppi.h>
#else
#include <nrfx_ppi.h>
#endif
//#include <nrfx_ppi.h>
#include <nrfx_saadc.h>
#include <nrfx_timer.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF);
#define SAADC_CHANNEL_NUM 0
#define SAMPLES_IN_BUFFER 1
#define SAMPLE_RATE 200UL //200uS sampling desired
int16_t saadc_buf1[SAMPLES_IN_BUFFER];
int16_t saadc_buf2[SAMPLES_IN_BUFFER];
nrfx_timer_t timer1 = NRFX_TIMER_INSTANCE(1); //timer instance
int64_t prevTime, elapsedTime = 0;
int64_t prevTicks, elapsedTicks = 0;
void saadc_evt_handler(nrfx_saadc_evt_t const * p_event)
{
printk("saadc_evt_handler\n");
printk("p_event->type = %d\n", p_event->type);
nrfx_err_t err = NRFX_SUCCESS;
static uint8_t counter = 0;
if(p_event->type == NRFX_SAADC_EVT_DONE)
{
elapsedTime = k_uptime_get() - prevTime;
prevTime = k_uptime_get();
printk("elapsedTime %lld\n", elapsedTime);
elapsedTicks = k_uptime_ticks() - prevTicks;
prevTicks = k_uptime_ticks();
printk("elapsedTicks %lld\n", elapsedTicks);
//CONFIG_SYS_CLOCK_TICKS_PER_SEC 32768 32.768kHz
printk("SAADC sampled: \n");
for(uint8_t i = 0; i < p_event->data.done.size; i++)
{
printk("%hi\n", p_event->data.done.p_buffer[i]);
}
}
else if(p_event->type == NRFX_SAADC_EVT_CALIBRATEDONE)
{
printk("SAADC calibrated.\n");
}
else if(p_event->type == NRFX_SAADC_EVT_BUF_REQ)
{
printk("SAADC buffer requested\n");
counter++;
if(counter%2)
{
err = nrfx_saadc_buffer_set(saadc_buf1, SAMPLES_IN_BUFFER);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not set buffer2: %d\n", err);
}
}
else
{
err = nrfx_saadc_buffer_set(saadc_buf2, SAMPLES_IN_BUFFER);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not set buffer1: %d\n", err);
}
}
}
else if(p_event->type == NRFX_SAADC_EVT_FINISHED)
{
printk("SAADC finished sampling\n\n");
}
}
void timer1_evt_handler(nrf_timer_event_t event_type, void * p_context) //called when timer is triggered
{
// Nothing to do here, the timer's IRQ is not enabled
printk("timer1_evt_handler\n");
}
void timer_init(void)
{
nrfx_err_t err = NRFX_SUCCESS;
nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
timer_cfg.frequency = NRF_TIMER_FREQ_16MHz;
timer_cfg.mode = NRF_TIMER_MODE_TIMER;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
timer_cfg.interrupt_priority = 0;//NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY;
err = nrfx_timer_init(&timer1, &timer_cfg, timer1_evt_handler);
uint32_t time_ticks;
time_ticks = nrfx_timer_us_to_ticks(&timer1, SAMPLE_RATE);
printk("time_ticks = %u\n", time_ticks);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not initialize TIMER1: %d\n", err);
}
nrfx_timer_extended_compare(&timer1, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
}
void saadc_init(void)
{
nrfx_err_t err = NRFX_SUCCESS;
nrfx_saadc_channel_t saadc_channel = NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN0, SAADC_CHANNEL_NUM);
nrfx_saadc_adv_config_t saadc_adv_cfg = NRFX_SAADC_DEFAULT_ADV_CONFIG;
saadc_adv_cfg.start_on_end = true;
err = nrfx_saadc_init(IRQ_PRIO_LOWEST);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not initialize SAADC: %d\n", err);
}
err = nrfx_saadc_offset_calibrate(NULL);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not calibrate offset: %d\n", err);
}
err = nrfx_saadc_channel_config(&saadc_channel);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not configure SAADC channels: %d\n", err);
}
err = nrfx_saadc_advanced_mode_set((1 << SAADC_CHANNEL_NUM), NRF_SAADC_RESOLUTION_10BIT, &saadc_adv_cfg, saadc_evt_handler);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not set advanced SAADC mode: %d\n", err);
}
err = nrfx_saadc_buffer_set(saadc_buf1, SAMPLES_IN_BUFFER);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not set buffer1: %d\n", err);
}
err = nrfx_saadc_buffer_set(saadc_buf2, SAMPLES_IN_BUFFER);
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could not set buffer2: %d\n", err);
}
err = nrfx_saadc_mode_trigger();
if(err != NRFX_SUCCESS)
{
LOG_ERR("Error! Could trigger mode: %d\n", err);
}
}
void main(void)
{
printk("nrfx_saadc sample on %s\n", CONFIG_BOARD);
nrfx_err_t err;
/* Connect SAADC IRQ to nrfx_saadc_irq_handler */
IRQ_CONNECT(SAADC_IRQn, IRQ_PRIO_LOWEST, nrfx_isr, nrfx_saadc_irq_handler, 0);
timer_init();
saadc_init();
/* Allocate a (D)PPI channel. */
#if defined(DPPI_PRESENT)
uint8_t channel;
err = nrfx_dppi_channel_alloc(&channel);
#else
nrf_ppi_channel_t channel;
err = nrfx_ppi_channel_alloc(&channel);
#endif
// /* Allocate a PPI channel. */
// nrf_ppi_channel_t channel;
// err = nrfx_ppi_channel_alloc(&channel);
if (err != NRFX_SUCCESS) {
LOG_ERR("(D)PPI channel allocation error: %08x", err);
return;
}
/* Configure endpoints of the channel so that the TIMER1 CAPTURE0
* event is connected with the SAADC SAMPLE task. This means that each time
* TIMER1 reaches it's set compare value, the SAADC will sample all
* enabled channel once.
*/
nrfx_gppi_channel_endpoints_setup(channel,
nrfx_timer_event_address_get(&timer1, NRF_TIMER_EVENT_COMPARE0),
nrf_saadc_task_address_get(NRF_SAADC, NRF_SAADC_TASK_SAMPLE));
// err = nrfx_ppi_channel_enable(channel);
// if (err != NRFX_SUCCESS) {
// LOG_ERR("Failed to enable PPI channel, error: %08x", err);
// return;
// }
// printk("PPI configured\n");
/* Enable (D)PPI channel. */
#if defined(DPPI_PRESENT)
err = nrfx_dppi_channel_enable(channel);
#else
err = nrfx_ppi_channel_enable(channel);
#endif
if (err != NRFX_SUCCESS) {
LOG_ERR("Failed to enable (D)PPI channel, error: %08x", err);
return;
}
LOG_INF("(D)PPI configured, leaving main()");
nrfx_timer_enable(&timer1);
printk("TIMER1 started\n");
while(1)
{
k_msleep(3000);
printk("while sleep\n");
}
}
At the end of my developement I would like to sample ADC at 200us and the buffer should have 1600 values and when full, transfer via BLE or perhaps evaluate right on the nRF5340 chip. Right now I dont know in detail what has to be done for evaluation purpose with the sampled buffer.
This DPPI featurte sound like powerfull magic!
There are a few problems or simple my lack of understanding:
how can I evaluate elapsed time between two ADC samples when this is happening without CPU involvement like described in
The distributed programmable peripheral interconnect (DPPI) enables peripherals to interact autonomously with each other by using tasks and events, without any intervention from the CPU DPPI
I mean how to get at the place / line where adc read task is happening with debugger or I dont know ?
&
I tried sitting at the
if(p_event->type == NRFX_SAADC_EVT_DONE)
{
elapsedTime = k_uptime_get() - prevTime;
prevTime = k_uptime_get();
printk("elapsedTime %lld\n", elapsedTime);
elapsedTicks = k_uptime_ticks() - prevTicks;
prevTicks = k_uptime_ticks();
printk("elapsedTicks %lld\n", elapsedTicks);
//CONFIG_SYS_CLOCK_TICKS_PER_SEC 32768 32.768kHz
printk("SAADC sampled: \n");
for(uint8_t i = 0; i < p_event->data.done.size; i++)
{
printk("%hi\n", p_event->data.done.p_buffer[i]);
}
}
and printk the time in ms or the ticks between every NRFX_SAADC_EVT_DONE , however at SAMPLE_RATE 200us or 1 000 000 us the measured time isnt accurate like desired .
What I m doing wrong ?
Not that important but ther is some example code from tutorial nrf52 EXTERN, I think the code is very similar, only
nrfx_timer_extended_compare(&timer0, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
enable_int parameter is set to true. And for sure the
nrfx_gppi_channel_endpoints_setup
isnt done because only blink LED.
When I set up enable_int to true, than I got the error

Thanks in advance,
Christoph


