10. General Purpose ADC (Manual Mode)
The DA1453x contains a 4-channel, high-speed, ultra-low-power, 10-bit general purpose Analog-to-Digital Converter (GPADC). It can operate in both single ended and differential modes and has a maximum sampling rate of 1Msps.
Note
You must have created a modified version of the empty_peripheral_template example project, as described in the Initial Project chapter before proceeding!
10.1. Using the GPADC
The following sections provide step-by-step instructions showing how to update the modified empty_peripheral_template example project you created in the Initial Project chapter to use the GPADC peripheral driver, provided with SDK6, in manual mode.
10.1.1. Configuring the ADC Input
In this example we will use GPIO P0_6
as the input to the ADC. To do this, first add the following definitions to the user_periph_setup.h file:
#define ADC_INPUT_PORT GPIO_PORT_0
#define ADC_INPUT_PIN GPIO_PIN_6
Next, reserve the GPIO by adding the following to the GPIO_reservations function that can be found in the user_periph_setup.c file:
RESERVE_GPIO(ADC_INPUT, ADC_INPUT_PORT, ADC_INPUT_PIN, PID_ADC);
Finally, configure the GPIO to act as an ADC input by adding the following to the set_pad_functions function that can be found in the user_periph_setup.c file:
GPIO_ConfigurePin(ADC_INPUT_PORT, ADC_INPUT_PIN, INPUT, PID_ADC, false);
10.1.2. Adding the GPADC Driver
The GPADC driver is implemented in the file adc_531.c and this has already been added to the empty_peripheral_template example project. However, in order to use the ADC driver functions we need to add the appropriate include files into the user_empty_peripheral_template.c file:
#include "adc.h"
#include "adc_531.h"
10.2. Manual Mode Measurement (Single Ended)
The GPADC can be operated in both manual and continuous modes. The following function demonstrates how to manually perform a single measurement. Add the function to the end of the user_empty_peripheral_template.c file.
static uint16_t gpadc_read(void)
{
/* Initialize the ADC */
adc_config_t adc_cfg =
{
.input_mode = ADC_INPUT_MODE_SINGLE_ENDED,
.input = ADC_INPUT_SE_P0_6,
.smpl_time_mult = 2,
.continuous = false,
.interval_mult = 0,
.input_attenuator = ADC_INPUT_ATTN_4X,
.chopping = false,
.oversampling = 0,
};
adc_init(&adc_cfg);
/* Perform offset calibration of the ADC */
adc_offset_calibrate(ADC_INPUT_MODE_SINGLE_ENDED);
adc_start();
uint16_t result = adc_correct_sample(adc_get_sample());
adc_disable();
return (result);
}
The above function can be called periodically, and the result output via the serial debug port. To do this, add the following prototype and variable declarations to the user_empty_peripheral_template.c file, just before the user_on_init function:
static void timer_cb(void);
static uint16_t gpadc_read(void);
static uint16_t gpadc_sample_to_mv(uint16_t sample);
static timer_hnd timer_id __attribute__((section("retention_mem_area0"),zero_init));
To start the timer, add the following code into the user_on_set_dev_config_complete function contained within user_empty_peripheral_template.c:
/* Start timer - period has units of 10ms i.e. 200 = 2000ms */
timer_id = app_easy_timer(200, timer_cb);
Now add the following function, which converts the result of an ADC conversion into a millivolt value, to the end of the user_empty_peripheral_template.c file:
static uint16_t gpadc_sample_to_mv(uint16_t sample)
{
/* Resolution of ADC sample depends on oversampling rate */
uint32_t adc_res = 10 + ((6 < adc_get_oversampling()) ? 6 : adc_get_oversampling());
/* Reference voltage is 900mv but scale based in input attenation */
uint32_t ref_mv = 900 * (GetBits16(GP_ADC_CTRL2_REG, GP_ADC_ATTN) + 1);
return (uint16_t)((((uint32_t)sample) * ref_mv) >> adc_res);
}
Finally, implement the callback that will be executed when the timer expires. To do this, add the following function to the end of the user_empty_peripheral_template.c file:
static void timer_cb(void)
{
/* Perform single ADC conversion */
uint16_t result = gpadc_read();
arch_printf("\n\radc result: %dmv", gpadc_sample_to_mv(result));
/* Restart the timer */
timer_id = app_easy_timer(200, timer_cb);
}
10.2.1. Testing
The above example performs an ADC conversion on the P0_6
input. For test purposes we will connect P0_6
to a 3.3V supply by placing a jumper wire from pin 1 on J2 (3.3V), to pin 27 on J2 (P0_6
):
Figure 11 ADC Test Jumper Wire Location (DA14531 DEVKT-P)
Figure 12 ADC Test Jumper Wire Location(DA1453x DEVKT-P)
Now build the project and load it onto your target. When it is executed the GPADC measurements will be output via the serial debug port every 2 seconds:

Figure 13 Serial debug output of Single ADC Measurement