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

ADC on nRF9160 DK - Differential Inputs and more inputs

Hi,

I have just got my SAADC up and running on my nrf9160, reading a single ended input.

Thanks for the support on this ticket, "ADC on nRF9160 DK - Example code problems"

I would like to expand this code in two ways.

1. Add additional channels

2. Add a differential channel

 I used the sample code I used previously

https://github.com/Rallare/fw-nrfconnect-nrf/tree/nrf9160_samples/samples/nrf9160/adc/src

with the changes suggested by Martin.

I then tried to move everything to the second channel, basically changing all the "1st" to "2nd"

*********************************************************************************************

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
*/

#include <nrf9160.h>
#include <stdio.h>
#include <string.h>
#include <uart.h>
#include <adc.h>
#include <zephyr.h>

struct device *adc_dev;
#define CONFIG_BOARD_NRF9160_PCA10090

#if defined(CONFIG_BOARD_NRF52_PCA10040) || \
defined(CONFIG_BOARD_NRF52840_PCA10056) || \
defined(CONFIG_BOARD_NRF9160_PCA10090NS) || \
defined(CONFIG_BOARD_NRF52840_BLIP)

#include <hal/nrf_saadc.h>
#define ADC_DEVICE_NAME DT_ADC_2_NAME
#define ADC_RESOLUTION 10
#define ADC_GAIN ADC_GAIN_1_6
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10)
#define ADC_1ST_CHANNEL_ID 0
#define ADC_1ST_CHANNEL_INPUT NRF_SAADC_INPUT_AIN0
#define ADC_2ND_CHANNEL_ID 2
#define ADC_2ND_CHANNEL_INPUT NRF_SAADC_INPUT_AIN2

#endif

static const struct adc_channel_cfg m_2nd_channel_cfg = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
.channel_id = ADC_2ND_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = ADC_2ND_CHANNEL_INPUT,
#endif
};

#define BUFFER_SIZE 1
static s16_t m_sample_buffer[BUFFER_SIZE];

static int adc_sample(void)
{
int ret;

const struct adc_sequence sequence = {
.channels = BIT(ADC_2ND_CHANNEL_ID),
.buffer = m_sample_buffer,
.buffer_size = sizeof(m_sample_buffer),
.resolution = ADC_RESOLUTION,
};

if (!adc_dev) {
return -1;
}

ret = adc_read(adc_dev, &sequence);
printk("ADC read err: %d\n", ret);

/* Print the AIN0 values */
for (int i = 0; i < BUFFER_SIZE; i++) {
float adc_voltage = 0;
adc_voltage = (float)(((float)m_sample_buffer[i] / 1023.0f) *
3600.0f);
printk("ADC raw value: %d\n", m_sample_buffer[i]);
printf("Measured voltage: %f mV\n", adc_voltage);
}

return ret;
}

int main(void)
{
int err;

printk("nrf91 saadc sampling AIN0 (P0.13)\n");
printk("Example requires secure_boot to have ");
printk("SAADC set to non-secure!\n");
printk("If not; BusFault/UsageFault will be triggered\n");

adc_dev = device_get_binding("ADC_2");
if (!adc_dev) {
printk("device_get_binding ADC_2 failed\n");
}
err = adc_channel_setup(adc_dev, &m_2nd_channel_cfg);
if (err) {
printk("Error in adc setup: %d\n", err);
}

/* Trigger offset calibration
* As this generates a _DONE and _RESULT event
* the first result will be incorrect.
*/
NRF_SAADC_NS->TASKS_CALIBRATEOFFSET = 1;
while (1) {
err = adc_sample();
if (err) {
printk("Error in adc sampling: %d\n", err);
}
k_sleep(500);
}
}

*********************************************************************************************

I get an error,

Secure Boot: MSP_NS 200209b8

Secure Boot: prepare to jump to Non-Secure image

***** Booting Zephyr OS v1.13.99-ncs1-5561-gde69d2df908f *****

nrf91 saadc sampling AIN0 (P0.13)

Example requires secure_boot to have SAADC set to non-secure!

If not; BusFault/UsageFault will be triggered

device_get_binding ADC_2 failed

Exception occurred in Secure State

***** HARD FAULT *****

  Fault escalation (see below)

***** BUS FAULT *****

  Precise data bus error

  BFAR Address: 0x50008120

***** Hardware exception *****

Current thread ID = 0x200200b4

Faulting instruction address = 0x40d60

Fatal fault in ISR! Spinning...

I guess Im missing another setting somewhere?

Also, does anyone have any code detailing how to set up additional differential channels?

Thanks,

Rod

Related