From e5ec9e8aff66605c1d32404ebc343331da3f9398 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Wed, 24 Jan 2024 16:48:43 +0100 Subject: [PATCH 1/3] rp2/machine_adc.c: Initialise the ADC GPIO when a Pin is referred. The change closes the gap when an integer was used as Pin reference. With that change, e.g. ADC(26), ADC(Pin(26)) and ADC("GP26") behave identical and the GPIO is initialised in high-Z mode. Only when using ADC channel numbers the ADC is not initialised and that step is left to the user code. Signed-off-by: robert-hh --- ports/rp2/machine_adc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ports/rp2/machine_adc.c b/ports/rp2/machine_adc.c index e5a428563d..ec77e6f5b9 100644 --- a/ports/rp2/machine_adc.c +++ b/ports/rp2/machine_adc.c @@ -73,12 +73,9 @@ static mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args 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); - if (ADC_IS_VALID_GPIO(channel)) { - channel = ADC_CHANNEL_FROM_GPIO(channel); - } else if (!(channel >= 0 && channel <= ADC_CHANNEL_TEMPSENSOR)) { + if (mp_obj_is_int(source) && (channel = mp_obj_get_int(source)) <= ADC_CHANNEL_TEMPSENSOR) { + // Validate channel number. + if (channel < 0) { mp_raise_ValueError(MP_ERROR_TEXT("invalid channel")); } } else { From 0fb86ad94173b0393e5e4fe57ea4e089873111f9 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 2 Feb 2024 13:47:12 +0100 Subject: [PATCH 2/3] docs/rp2/quickref.rst: Document the use of channel numbers for ADC. Signed-off-by: robert-hh --- docs/rp2/quickref.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/rp2/quickref.rst b/docs/rp2/quickref.rst index 11a808c110..8ee467d014 100644 --- a/docs/rp2/quickref.rst +++ b/docs/rp2/quickref.rst @@ -187,6 +187,13 @@ Use the :ref:`machine.ADC ` class:: adc = ADC(Pin(26)) # create ADC object on ADC pin adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v +The argument of the constructor ADC specifies either a Pin by number, name of as +Pin object, or a channel number in the range 0 - 3. If a pin is specified, +the pin is initialized in high-Z mode. If a channel number is used, the pin +is not initialized and configuring is left to the user code. After hard reset, +RP2040 pins operate in current sink mode at about 60µA. If the pin is not +otherwise configured, that may lead to wrong ADC readings. + Software SPI bus ---------------- From 40ffe6ecefb48c68b7d7b379689e8ad9e47858b5 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Mon, 12 Feb 2024 20:34:15 +0100 Subject: [PATCH 3/3] rp2/machine_uart.c: Test for an invalid baud rate. The baud rate requested in the init call may not be achievable. This happens at least if the baud rate is too low or too high, but may as well happen at other baud rates. If the deviation is larger than 2 %, an error is raised. Signed-off-by: robert-hh --- ports/rp2/machine_uart.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c index ccbf8f781a..0aa958c962 100644 --- a/ports/rp2/machine_uart.c +++ b/ports/rp2/machine_uart.c @@ -367,7 +367,11 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, self->timeout_char = min_timeout_char; } - uart_init(self->uart, self->baudrate); + uint32_t new_baudrate = uart_init(self->uart, self->baudrate); + uint32_t baudrate_diff = new_baudrate > self->baudrate ? new_baudrate - self->baudrate : self->baudrate - new_baudrate; + if (baudrate_diff > (self->baudrate / 50)) { + mp_raise_ValueError(MP_ERROR_TEXT("Invalid baud rate")); + } uart_set_format(self->uart, self->bits, self->stop, self->parity); __DSB(); // make sure UARTLCR_H register is written to uart_set_fifo_enabled(self->uart, true);