Skip to content

Commit 8f414eb

Browse files
authored
Merge pull request #7179 from jepler/picow-voltage-monitor
Add ability to read VOLTAGE_MONITOR on Pico W
2 parents 6e9909c + 7f36a36 commit 8f414eb

File tree

5 files changed

+55
-8
lines changed

5 files changed

+55
-8
lines changed

ports/raspberrypi/bindings/cyw43/__init__.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj) {
123123
return MP_OBJ_TO_PTR(obj);
124124
}
125125

126+
const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj) {
127+
const mcu_pin_obj_t *pin = validate_obj_is_pin(obj);
128+
if (obj != &pin_GPIO29) {
129+
assert_pin_free(pin);
130+
}
131+
return pin;
132+
}
133+
126134
const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj) {
127135
const mcu_pin_obj_t *pin = validate_obj_is_pin_including_cyw43(obj);
128136
assert_pin_free(pin);

ports/raspberrypi/bindings/cyw43/__init__.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
extern const mp_obj_type_t cyw43_pin_type;
3434
const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj);
35+
const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj);
3536
const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj);
3637

3738
#define CONSTANT_CYW43_PM_VALUE(pm_mode, pm2_sleep_ret_ms, li_beacon_period, li_dtim_period, li_assoc) \

ports/raspberrypi/boards/raspberry_pi_pico_w/pins.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
4545
{ MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) },
4646
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) },
4747

48+
{ MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) },
49+
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) },
50+
51+
4852
{ MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) },
4953
};
5054
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

ports/raspberrypi/common-hal/analogio/AnalogIn.c

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "common-hal/analogio/AnalogIn.h"
2828
#include "shared-bindings/analogio/AnalogIn.h"
29+
#include "shared-bindings/microcontroller/__init__.h"
2930
#include "shared-bindings/microcontroller/Pin.h"
3031
#include "py/runtime.h"
3132
#include "supervisor/shared/translate/translate.h"
@@ -35,16 +36,26 @@
3536
#define ADC_FIRST_PIN_NUMBER 26
3637
#define ADC_PIN_COUNT 4
3738

39+
// Voltage monitor is special on Pico W, because this pin is shared between the
40+
// voltage monitor function and the wifi function. Special handling is required
41+
// to read the analog voltage.
42+
#if CIRCUITPY_CYW43
43+
#define SPECIAL_PIN(pin) (pin->number == 29)
44+
#else
45+
#define SPECIAL_PIN(pin) false
46+
#endif
47+
3848
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) {
3949
if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number > ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT) {
4050
raise_ValueError_invalid_pin();
4151
}
4252

4353
adc_init();
54+
if (!SPECIAL_PIN(pin)) {
55+
adc_gpio_init(pin->number);
56+
claim_pin(pin);
57+
}
4458

45-
adc_gpio_init(pin->number);
46-
47-
claim_pin(pin);
4859
self->pin = pin;
4960
}
5061

@@ -57,14 +68,30 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) {
5768
return;
5869
}
5970

60-
reset_pin_number(self->pin->number);
71+
if (!SPECIAL_PIN(self->pin)) {
72+
reset_pin_number(self->pin->number);
73+
}
6174
self->pin = NULL;
6275
}
6376

6477
uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
65-
adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
66-
uint16_t value = adc_read();
67-
78+
uint16_t value;
79+
if (SPECIAL_PIN(self->pin)) {
80+
common_hal_mcu_disable_interrupts();
81+
uint32_t old_pad = padsbank0_hw->io[self->pin->number];
82+
uint32_t old_ctrl = iobank0_hw->io[self->pin->number].ctrl;
83+
adc_gpio_init(self->pin->number);
84+
adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
85+
common_hal_mcu_delay_us(100);
86+
value = adc_read();
87+
gpio_init(self->pin->number);
88+
padsbank0_hw->io[self->pin->number] = old_pad;
89+
iobank0_hw->io[self->pin->number].ctrl = old_ctrl;
90+
common_hal_mcu_enable_interrupts();
91+
} else {
92+
adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER);
93+
value = adc_read();
94+
}
6895
// Stretch 12-bit ADC reading to 16-bit range
6996
return (value << 4) | (value >> 8);
7097
}

shared-bindings/analogio/AnalogIn.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
#include "shared-bindings/analogio/AnalogIn.h"
3737
#include "shared-bindings/util.h"
3838

39+
#if CIRCUITPY_CYW43
40+
#include "bindings/cyw43/__init__.h"
41+
#endif
42+
3943
//| class AnalogIn:
4044
//| """Read analog voltage levels
4145
//|
@@ -60,8 +64,11 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type,
6064
mp_arg_check_num(n_args, n_kw, 1, 1, false);
6165

6266
// 1st argument is the pin
67+
#if CIRCUITPY_CYW43
68+
const mcu_pin_obj_t *pin = validate_obj_is_free_pin_or_gpio29(args[0]);
69+
#else
6370
const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]);
64-
71+
#endif
6572
analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t);
6673
self->base.type = &analogio_analogin_type;
6774
common_hal_analogio_analogin_construct(self, pin);

0 commit comments

Comments
 (0)