mirror of
https://github.com/licsber/micropython.git
synced 2024-09-20 00:50:24 +08:00
rp2/machine_adc: Add support for external ADC channels.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
parent
4358faab0c
commit
5e52389f99
@ -27,6 +27,7 @@
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "hardware/adc.h"
|
||||
#include "machine_pin.h"
|
||||
|
||||
#define ADC_IS_VALID_GPIO(gpio) ((gpio) >= 26 && (gpio) <= 29)
|
||||
#define ADC_CHANNEL_FROM_GPIO(gpio) ((gpio) - 26)
|
||||
@ -48,6 +49,9 @@ const mp_obj_type_t machine_adc_type;
|
||||
typedef struct _machine_adc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint32_t channel;
|
||||
#if MICROPY_HW_ADC_EXT_COUNT
|
||||
uint32_t is_ext : 1;
|
||||
#endif
|
||||
} machine_adc_obj_t;
|
||||
|
||||
STATIC void machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
@ -63,6 +67,9 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
|
||||
mp_obj_t source = all_args[0];
|
||||
|
||||
uint32_t channel;
|
||||
bool is_ext = false;
|
||||
const machine_pin_obj_t *pin = NULL;
|
||||
|
||||
if (mp_obj_is_int(source)) {
|
||||
// Get and validate channel number.
|
||||
channel = mp_obj_get_int(source);
|
||||
@ -72,18 +79,35 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
|
||||
|
||||
} else {
|
||||
// Get GPIO and check it has ADC capabilities.
|
||||
channel = mp_hal_get_pin_obj(source);
|
||||
if (!ADC_IS_VALID_GPIO(channel)) {
|
||||
pin = machine_pin_find(source);
|
||||
channel = pin->id;
|
||||
bool valid_adc_pin = false;
|
||||
#if MICROPY_HW_ADC_EXT_COUNT
|
||||
is_ext = pin->is_ext;
|
||||
if (is_ext) {
|
||||
valid_adc_pin = machine_pin_ext_is_adc_channel(pin);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
valid_adc_pin = ADC_IS_VALID_GPIO(channel);
|
||||
}
|
||||
if (!valid_adc_pin) {
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("Pin doesn't have ADC capabilities"));
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise the ADC peripheral if it's not already running.
|
||||
if (!(adc_hw->cs & ADC_CS_EN_BITS)) {
|
||||
if (!is_ext && !(adc_hw->cs & ADC_CS_EN_BITS)) {
|
||||
adc_init();
|
||||
}
|
||||
|
||||
if (ADC_IS_VALID_GPIO(channel)) {
|
||||
if (is_ext) {
|
||||
#if MICROPY_HW_ADC_EXT_COUNT
|
||||
// Note external pins are mutable.
|
||||
machine_pin_ext_config((machine_pin_obj_t *)pin, MACHINE_PIN_MODE_ANALOG, 0);
|
||||
channel = machine_pin_ext_to_adc_channel(pin);
|
||||
#endif
|
||||
} else if (ADC_IS_VALID_GPIO(channel)) {
|
||||
// Configure the GPIO pin in ADC mode.
|
||||
adc_gpio_init(channel);
|
||||
channel = ADC_CHANNEL_FROM_GPIO(channel);
|
||||
@ -95,6 +119,9 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
|
||||
// Create ADC object.
|
||||
machine_adc_obj_t *o = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type);
|
||||
o->channel = channel;
|
||||
#if MICROPY_HW_ADC_EXT_COUNT
|
||||
o->is_ext = is_ext;
|
||||
#endif
|
||||
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
@ -102,6 +129,11 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s
|
||||
// read_u16()
|
||||
STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) {
|
||||
machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
#if MICROPY_HW_ADC_EXT_COUNT
|
||||
if (self->is_ext) {
|
||||
return MP_OBJ_NEW_SMALL_INT(machine_pin_ext_read_u16(self->channel));
|
||||
}
|
||||
#endif
|
||||
return MP_OBJ_NEW_SMALL_INT(adc_config_and_read_u16(self->channel));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_u16_obj, machine_adc_read_u16);
|
||||
|
@ -166,7 +166,7 @@ const machine_pin_af_obj_t *machine_pin_find_alt_by_index(const machine_pin_obj_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const machine_pin_obj_t *machine_pin_find(mp_obj_t pin) {
|
||||
const machine_pin_obj_t *machine_pin_find(mp_obj_t pin) {
|
||||
// Is already a object of the proper type
|
||||
if (mp_obj_is_type(pin, &machine_pin_type)) {
|
||||
return pin;
|
||||
|
@ -34,7 +34,8 @@ enum {
|
||||
MACHINE_PIN_MODE_IN = 0,
|
||||
MACHINE_PIN_MODE_OUT = 1,
|
||||
MACHINE_PIN_MODE_OPEN_DRAIN = 2,
|
||||
MACHINE_PIN_MODE_ALT = 3
|
||||
MACHINE_PIN_MODE_ALT = 3,
|
||||
MACHINE_PIN_MODE_ANALOG = 4
|
||||
};
|
||||
|
||||
typedef struct _machine_pin_af_obj_t {
|
||||
@ -71,10 +72,14 @@ extern const mp_obj_type_t pin_board_pins_obj_type;
|
||||
extern const mp_obj_dict_t pin_board_pins_locals_dict;
|
||||
|
||||
void machine_pin_ext_init(void);
|
||||
bool machine_pin_ext_is_adc_channel(const machine_pin_obj_t *self);
|
||||
uint32_t machine_pin_ext_to_adc_channel(const machine_pin_obj_t *self);
|
||||
void machine_pin_ext_set(machine_pin_obj_t *self, bool value);
|
||||
bool machine_pin_ext_get(machine_pin_obj_t *self);
|
||||
uint16_t machine_pin_ext_read_u16(uint32_t channel);
|
||||
void machine_pin_ext_config(machine_pin_obj_t *self, int mode, int value);
|
||||
|
||||
const machine_pin_obj_t *machine_pin_find(mp_obj_t pin);
|
||||
const machine_pin_obj_t *machine_pin_find_named(const mp_obj_dict_t *named_pins, mp_obj_t name);
|
||||
const machine_pin_af_obj_t *machine_pin_find_alt(const machine_pin_obj_t *pin, uint8_t fn);
|
||||
const machine_pin_af_obj_t *machine_pin_find_alt_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx);
|
||||
|
Loading…
Reference in New Issue
Block a user