adc.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _HARDWARE_ADC_H
8 #define _HARDWARE_ADC_H
9 
10 #include "pico.h"
11 #include "hardware/structs/adc.h"
12 #include "hardware/gpio.h"
13 
47 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_ADC, Enable/disable assertions in the ADC module, type=bool, default=0, group=hardware_adc
48 #ifndef PARAM_ASSERTIONS_ENABLED_ADC
49 #define PARAM_ASSERTIONS_ENABLED_ADC 0
50 #endif
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
60 void adc_init(void);
61 
69 static inline void adc_gpio_init(uint gpio) {
70  invalid_params_if(ADC, gpio < 26 || gpio > 29);
71  // Select NULL function to make output driver hi-Z
72  gpio_set_function(gpio, GPIO_FUNC_NULL);
73  // Also disable digital pulls and digital receiver
74  gpio_disable_pulls(gpio);
75  gpio_set_input_enabled(gpio, false);
76 }
77 
86 static inline void adc_select_input(uint input) {
87  valid_params_if(ADC, input < NUM_ADC_CHANNELS);
88  hw_write_masked(&adc_hw->cs, input << ADC_CS_AINSEL_LSB, ADC_CS_AINSEL_BITS);
89 }
90 
96 static inline uint adc_get_selected_input(void) {
97  return (adc_hw->cs & ADC_CS_AINSEL_BITS) >> ADC_CS_AINSEL_LSB;
98 }
99 
108 static inline void adc_set_round_robin(uint input_mask) {
109  valid_params_if(ADC, input_mask < (1 << NUM_ADC_CHANNELS));
110  hw_write_masked(&adc_hw->cs, input_mask << ADC_CS_RROBIN_LSB, ADC_CS_RROBIN_BITS);
111 }
112 
119 static inline void adc_set_temp_sensor_enabled(bool enable) {
120  if (enable)
121  hw_set_bits(&adc_hw->cs, ADC_CS_TS_EN_BITS);
122  else
123  hw_clear_bits(&adc_hw->cs, ADC_CS_TS_EN_BITS);
124 }
125 
133 static inline uint16_t adc_read(void) {
134  hw_set_bits(&adc_hw->cs, ADC_CS_START_ONCE_BITS);
135 
136  while (!(adc_hw->cs & ADC_CS_READY_BITS))
138 
139  return (uint16_t) adc_hw->result;
140 }
141 
147 static inline void adc_run(bool run) {
148  if (run)
149  hw_set_bits(&adc_hw->cs, ADC_CS_START_MANY_BITS);
150  else
151  hw_clear_bits(&adc_hw->cs, ADC_CS_START_MANY_BITS);
152 }
153 
162 static inline void adc_set_clkdiv(float clkdiv) {
163  invalid_params_if(ADC, clkdiv >= 1 << (ADC_DIV_INT_MSB - ADC_DIV_INT_LSB + 1));
164  adc_hw->div = (uint32_t)(clkdiv * (float) (1 << ADC_DIV_INT_LSB));
165 }
166 
178  static inline void adc_fifo_setup(bool en, bool dreq_en, uint16_t dreq_thresh, bool err_in_fifo, bool byte_shift) {
179  hw_write_masked(&adc_hw->fcs,
180  (bool_to_bit(en) << ADC_FCS_EN_LSB) |
181  (bool_to_bit(dreq_en) << ADC_FCS_DREQ_EN_LSB) |
182  (((uint)dreq_thresh) << ADC_FCS_THRESH_LSB) |
183  (bool_to_bit(err_in_fifo) << ADC_FCS_ERR_LSB) |
184  (bool_to_bit(byte_shift) << ADC_FCS_SHIFT_LSB),
185  ADC_FCS_EN_BITS |
186  ADC_FCS_DREQ_EN_BITS |
187  ADC_FCS_THRESH_BITS |
188  ADC_FCS_ERR_BITS |
189  ADC_FCS_SHIFT_BITS
190  );
191 }
192 
198 static inline bool adc_fifo_is_empty(void) {
199  return !!(adc_hw->fcs & ADC_FCS_EMPTY_BITS);
200 }
201 
207 static inline uint8_t adc_fifo_get_level(void) {
208  return (adc_hw->fcs & ADC_FCS_LEVEL_BITS) >> ADC_FCS_LEVEL_LSB;
209 }
210 
216 static inline uint16_t adc_fifo_get(void) {
217  return (uint16_t)adc_hw->fifo;
218 }
219 
225 static inline uint16_t adc_fifo_get_blocking(void) {
226  while (adc_fifo_is_empty())
228  return (uint16_t)adc_hw->fifo;
229 }
230 
236 static inline void adc_fifo_drain(void) {
237  // Potentially there is still a conversion in progress -- wait for this to complete before draining
238  while (!(adc_hw->cs & ADC_CS_READY_BITS))
240  while (!adc_fifo_is_empty())
241  (void) adc_fifo_get();
242 }
243 
249 static inline void adc_irq_set_enabled(bool enabled) {
250  adc_hw->inte = !!enabled;
251 }
252 
253 #ifdef __cplusplus
254 }
255 #endif
256 
257 #endif
hw_clear_bits
static __force_inline void hw_clear_bits(io_rw_32 *addr, uint32_t mask)
Atomically clear the specified bits to 0 in a HW register.
Definition: address_mapped.h:131
gpio_disable_pulls
static void gpio_disable_pulls(uint gpio)
Disable pulls on specified GPIO.
Definition: gpio.h:251
adc_read
static uint16_t adc_read(void)
Perform a single conversion.
Definition: adc.h:133
adc_set_clkdiv
static void adc_set_clkdiv(float clkdiv)
Set the ADC Clock divisor.
Definition: adc.h:162
adc_gpio_init
static void adc_gpio_init(uint gpio)
Initialise the gpio for use as an ADC pin.
Definition: adc.h:69
adc_fifo_drain
static void adc_fifo_drain(void)
Drain the ADC FIFO.
Definition: adc.h:236
adc_set_temp_sensor_enabled
static void adc_set_temp_sensor_enabled(bool enable)
Enable the onboard temperature sensor.
Definition: adc.h:119
hw_write_masked
static __force_inline void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask)
Set new values for a sub-set of the bits in a HW register.
Definition: address_mapped.h:157
adc_irq_set_enabled
static void adc_irq_set_enabled(bool enabled)
Enable/Disable ADC interrupts.
Definition: adc.h:249
hw_set_bits
static __force_inline void hw_set_bits(io_rw_32 *addr, uint32_t mask)
Atomically set the specified bits to 1 in a HW register.
Definition: address_mapped.h:121
adc_fifo_is_empty
static bool adc_fifo_is_empty(void)
Check FIFO empty state.
Definition: adc.h:198
adc_fifo_setup
static void adc_fifo_setup(bool en, bool dreq_en, uint16_t dreq_thresh, bool err_in_fifo, bool byte_shift)
Setup the ADC FIFO.
Definition: adc.h:178
adc_init
void adc_init(void)
Initialise the ADC HW.
Definition: adc.c:11
adc_run
static void adc_run(bool run)
Enable or disable free-running sampling mode.
Definition: adc.h:147
gpio_set_function
void gpio_set_function(uint gpio, enum gpio_function fn)
Select GPIO function.
Definition: gpio.c:32
adc_select_input
static void adc_select_input(uint input)
ADC input select.
Definition: adc.h:86
tight_loop_contents
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:358
adc_fifo_get
static uint16_t adc_fifo_get(void)
Get ADC result from FIFO.
Definition: adc.h:216
pico.h
gpio_set_input_enabled
void gpio_set_input_enabled(uint gpio, bool enabled)
Enable GPIO input.
Definition: gpio.c:239
adc_fifo_get_blocking
static uint16_t adc_fifo_get_blocking(void)
Wait for the ADC FIFO to have data.
Definition: adc.h:225
gpio.h
adc_set_round_robin
static void adc_set_round_robin(uint input_mask)
Round Robin sampling selector.
Definition: adc.h:108
adc_fifo_get_level
static uint8_t adc_fifo_get_level(void)
Get number of entries in the ADC FIFO.
Definition: adc.h:207
adc_get_selected_input
static uint adc_get_selected_input(void)
Get the currently selected ADC input channel.
Definition: adc.h:96