summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/cyw43/cywbt.c2
-rw-r--r--extmod/extmod.cmake1
-rw-r--r--extmod/extmod.mk1
-rw-r--r--extmod/machine_uart.c187
-rw-r--r--extmod/modmachine.h20
-rw-r--r--ports/esp32/esp32_common.cmake1
-rw-r--r--ports/esp32/machine_uart.c107
-rw-r--r--ports/esp32/modmachine.c2
-rw-r--r--ports/esp32/modmachine.h1
-rw-r--r--ports/esp32/mpconfigport.h3
-rw-r--r--ports/esp8266/Makefile1
-rw-r--r--ports/esp8266/machine_uart.c99
-rw-r--r--ports/esp8266/main.c3
-rw-r--r--ports/esp8266/modmachine.c4
-rw-r--r--ports/esp8266/modmachine.h1
-rw-r--r--ports/esp8266/modos.c5
-rw-r--r--ports/esp8266/mpconfigport.h2
-rw-r--r--ports/mimxrt/Makefile1
-rw-r--r--ports/mimxrt/machine_uart.c111
-rw-r--r--ports/mimxrt/modmachine.c2
-rw-r--r--ports/mimxrt/modmachine.h1
-rw-r--r--ports/mimxrt/mpconfigport.h3
-rw-r--r--ports/nrf/Makefile1
-rw-r--r--ports/nrf/main.c1
-rw-r--r--ports/nrf/modules/machine/modmachine.c1
-rw-r--r--ports/nrf/modules/machine/uart.c164
-rw-r--r--ports/nrf/modules/machine/uart.h11
-rw-r--r--ports/nrf/modules/os/modos.c2
-rw-r--r--ports/nrf/mpconfigport.h3
-rw-r--r--ports/nrf/mphalport.c2
-rw-r--r--ports/renesas-ra/Makefile1
-rw-r--r--ports/renesas-ra/machine_uart.c196
-rw-r--r--ports/renesas-ra/modmachine.c2
-rw-r--r--ports/renesas-ra/modmachine.h1
-rw-r--r--ports/renesas-ra/mpconfigport.h5
-rw-r--r--ports/rp2/CMakeLists.txt1
-rw-r--r--ports/rp2/machine_uart.c110
-rw-r--r--ports/rp2/modmachine.c2
-rw-r--r--ports/rp2/modmachine.h1
-rw-r--r--ports/rp2/mpbthciport.c1
-rw-r--r--ports/rp2/mpconfigport.h3
-rw-r--r--ports/samd/Makefile1
-rw-r--r--ports/samd/machine_i2c.c2
-rw-r--r--ports/samd/machine_spi.c2
-rw-r--r--ports/samd/machine_uart.c133
-rw-r--r--ports/samd/modmachine.h3
-rw-r--r--ports/samd/mpconfigport.h2
-rw-r--r--ports/samd/samd_soc.c25
-rw-r--r--ports/samd/samd_soc.h2
-rw-r--r--ports/stm32/Makefile1
-rw-r--r--ports/stm32/machine_uart.c224
-rw-r--r--ports/stm32/main.c7
-rw-r--r--ports/stm32/modmachine.c4
-rw-r--r--ports/stm32/modos.c7
-rw-r--r--ports/stm32/modpyb.c5
-rw-r--r--ports/stm32/mpbthciport.c7
-rw-r--r--ports/stm32/mpconfigport.h5
-rw-r--r--ports/stm32/mphalport.c2
-rw-r--r--ports/stm32/uart.c54
-rw-r--r--ports/stm32/uart.h35
-rw-r--r--ports/zephyr/CMakeLists.txt1
-rw-r--r--ports/zephyr/machine_uart.c63
-rw-r--r--ports/zephyr/modmachine.c3
-rw-r--r--ports/zephyr/modmachine.h1
-rw-r--r--ports/zephyr/mpconfigport.h2
65 files changed, 661 insertions, 996 deletions
diff --git a/drivers/cyw43/cywbt.c b/drivers/cyw43/cywbt.c
index bc6674ea2..d1b19382c 100644
--- a/drivers/cyw43/cywbt.c
+++ b/drivers/cyw43/cywbt.c
@@ -49,7 +49,7 @@ extern uint8_t mp_bluetooth_hci_cmd_buf[4 + 256];
#include "uart.h"
// Provided by the port.
-extern pyb_uart_obj_t mp_bluetooth_hci_uart_obj;
+extern machine_uart_obj_t mp_bluetooth_hci_uart_obj;
STATIC void cywbt_wait_cts_low(void) {
mp_hal_pin_config(CYW43_PIN_BT_CTS, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_UP, 0);
diff --git a/extmod/extmod.cmake b/extmod/extmod.cmake
index 6f01bafe4..a1a0a9f73 100644
--- a/extmod/extmod.cmake
+++ b/extmod/extmod.cmake
@@ -16,6 +16,7 @@ set(MICROPY_SOURCE_EXTMOD
${MICROPY_EXTMOD_DIR}/machine_pwm.c
${MICROPY_EXTMOD_DIR}/machine_signal.c
${MICROPY_EXTMOD_DIR}/machine_spi.c
+ ${MICROPY_EXTMOD_DIR}/machine_uart.c
${MICROPY_EXTMOD_DIR}/machine_wdt.c
${MICROPY_EXTMOD_DIR}/modbluetooth.c
${MICROPY_EXTMOD_DIR}/modframebuf.c
diff --git a/extmod/extmod.mk b/extmod/extmod.mk
index 76dfbf0a4..8a48a4293 100644
--- a/extmod/extmod.mk
+++ b/extmod/extmod.mk
@@ -13,6 +13,7 @@ SRC_EXTMOD_C += \
extmod/machine_signal.c \
extmod/machine_spi.c \
extmod/machine_timer.c \
+ extmod/machine_uart.c \
extmod/machine_wdt.c \
extmod/modasyncio.c \
extmod/modbinascii.c \
diff --git a/extmod/machine_uart.c b/extmod/machine_uart.c
new file mode 100644
index 000000000..dd556bbbb
--- /dev/null
+++ b/extmod/machine_uart.c
@@ -0,0 +1,187 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2023 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#if MICROPY_PY_MACHINE_UART
+
+#include "extmod/modmachine.h"
+#include "shared/runtime/mpirq.h"
+
+// The port must provide implementations of these low-level UART functions.
+
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self);
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self);
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self);
+
+#if MICROPY_PY_MACHINE_UART_SENDBREAK
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self);
+#endif
+
+#if MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR
+STATIC mp_int_t mp_machine_uart_readchar(machine_uart_obj_t *self);
+STATIC void mp_machine_uart_writechar(machine_uart_obj_t *self, uint16_t data);
+#endif
+
+#if MICROPY_PY_MACHINE_UART_IRQ
+STATIC mp_irq_obj_t *mp_machine_uart_irq(machine_uart_obj_t *self, bool any_args, mp_arg_val_t *args);
+#endif
+
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode);
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode);
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode);
+
+// The port provides implementations of the above in this file.
+#include MICROPY_PY_MACHINE_UART_INCLUDEFILE
+
+// UART.init(...)
+STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_machine_uart_init_helper(MP_OBJ_TO_PTR(args[0]), n_args - 1, args + 1, kw_args);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init);
+
+// UART.deinit()
+STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_machine_uart_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit);
+
+// UART.any()
+STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return MP_OBJ_NEW_SMALL_INT(mp_machine_uart_any(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
+
+// UART.txdone()
+STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(mp_machine_uart_txdone(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
+
+#if MICROPY_PY_MACHINE_UART_SENDBREAK
+
+// UART.sendbreak()
+STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_machine_uart_sendbreak(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
+
+#endif
+
+#if MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR
+
+// UART.readchar()
+STATIC mp_obj_t machine_uart_readchar(mp_obj_t self_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return MP_OBJ_NEW_SMALL_INT(mp_machine_uart_readchar(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_readchar_obj, machine_uart_readchar);
+
+// UART.writechar(char)
+STATIC mp_obj_t machine_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_machine_uart_writechar(self, mp_obj_get_int(char_in));
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_uart_writechar_obj, machine_uart_writechar);
+
+#endif
+
+#if MICROPY_PY_MACHINE_UART_IRQ
+
+// UART.irq(handler, trigger, hard)
+STATIC mp_obj_t machine_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mp_arg_val_t args[MP_IRQ_ARG_INIT_NUM_ARGS];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_IRQ_ARG_INIT_NUM_ARGS, mp_irq_init_args, args);
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ bool any_args = n_args > 1 || kw_args->used != 0;
+ return MP_OBJ_FROM_PTR(mp_machine_uart_irq(self, any_args, args));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_irq_obj, 1, machine_uart_irq);
+
+#endif
+
+STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
+ { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
+ { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
+
+ #if MICROPY_PY_MACHINE_UART_SENDBREAK
+ { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
+ #endif
+
+ #if MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR
+ { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&machine_uart_readchar_obj) },
+ { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&machine_uart_writechar_obj) },
+ #endif
+
+ #if MICROPY_PY_MACHINE_UART_IRQ
+ { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_uart_irq_obj) },
+ #endif
+
+ // A port must add UART class constants defining the following macro.
+ // It can be defined to nothing if there are no constants.
+ MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS
+};
+STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
+
+STATIC const mp_stream_p_t uart_stream_p = {
+ .read = mp_machine_uart_read,
+ .write = mp_machine_uart_write,
+ .ioctl = mp_machine_uart_ioctl,
+ .is_text = false,
+};
+
+MP_DEFINE_CONST_OBJ_TYPE(
+ machine_uart_type,
+ MP_QSTR_UART,
+ MP_TYPE_FLAG_ITER_IS_STREAM,
+ make_new, mp_machine_uart_make_new,
+ print, mp_machine_uart_print,
+ protocol, &uart_stream_p,
+ locals_dict, &machine_uart_locals_dict
+ );
+
+#endif // MICROPY_PY_MACHINE_UART
diff --git a/extmod/modmachine.h b/extmod/modmachine.h
index e635eedaa..c18c55553 100644
--- a/extmod/modmachine.h
+++ b/extmod/modmachine.h
@@ -65,10 +65,29 @@
#define MICROPY_PY_MACHINE_ADC_READ (0)
#endif
+// Whether to enable the UART.sendbreak() method.
+// Requires a port to implement mp_machine_uart_sendbreak().
+#ifndef MICROPY_PY_MACHINE_UART_SENDBREAK
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (0)
+#endif
+
+// Whether to enable the UART.readchar() and UART.writechar() methods.
+// Requires a port to implement mp_machine_uart_readchar() and mp_machine_uart_writechar().
+#ifndef MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR
+#define MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR (0)
+#endif
+
+// Whether to enable the UART.irq() method.
+// Requires a port to implement mp_machine_uart_irq().
+#ifndef MICROPY_PY_MACHINE_UART_IRQ
+#define MICROPY_PY_MACHINE_UART_IRQ (0)
+#endif
+
// A port must provide these types, but they are otherwise opaque.
typedef struct _machine_adc_obj_t machine_adc_obj_t;
typedef struct _machine_i2s_obj_t machine_i2s_obj_t;
typedef struct _machine_pwm_obj_t machine_pwm_obj_t;
+typedef struct _machine_uart_obj_t machine_uart_obj_t;
typedef struct _machine_wdt_obj_t machine_wdt_obj_t;
// These classes correspond to machine.Type entries in the machine module.
@@ -80,6 +99,7 @@ extern const mp_obj_type_t machine_i2s_type;
extern const mp_obj_type_t machine_pwm_type;
extern const mp_obj_type_t machine_spi_type;
extern const mp_obj_type_t machine_timer_type;
+extern const mp_obj_type_t machine_uart_type;
extern const mp_obj_type_t machine_wdt_type;
#endif // MICROPY_INCLUDED_EXTMOD_MODMACHINE_H
diff --git a/ports/esp32/esp32_common.cmake b/ports/esp32/esp32_common.cmake
index 4c90282c9..8b3dac532 100644
--- a/ports/esp32/esp32_common.cmake
+++ b/ports/esp32/esp32_common.cmake
@@ -69,7 +69,6 @@ list(APPEND MICROPY_SOURCE_PORT
machine_adcblock.c
machine_dac.c
machine_i2c.c
- machine_uart.c
modmachine.c
network_common.c
network_lan.c
diff --git a/ports/esp32/machine_uart.c b/ports/esp32/machine_uart.c
index 0b4f5890b..f498ab5b3 100644
--- a/ports/esp32/machine_uart.c
+++ b/ports/esp32/machine_uart.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Damien P. George
+ * Copyright (c) 2016-2023 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,9 +24,8 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
#include "driver/uart.h"
#include "freertos/FreeRTOS.h"
@@ -35,7 +34,6 @@
#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
-#include "modmachine.h"
#include "uart.h"
#if SOC_UART_SUPPORT_XTAL_CLK
@@ -75,7 +73,15 @@ STATIC const char *_parity_name[] = {"None", "1", "0"};
/******************************************************************************/
// MicroPython bindings for UART
-STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
+ { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INV_TX) }, \
+ { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INV_RX) }, \
+ { MP_ROM_QSTR(MP_QSTR_INV_RTS), MP_ROM_INT(UART_INV_RTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_INV_CTS), MP_ROM_INT(UART_INV_CTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HW_FLOWCTRL_RTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HW_FLOWCTRL_CTS) }, \
+
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t baudrate;
uart_get_baudrate(self->uart_num, &baudrate);
@@ -127,7 +133,7 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
mp_printf(print, ")");
}
-STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_tx, ARG_rx, ARG_rts, ARG_cts, ARG_txbuf, ARG_rxbuf, ARG_timeout, ARG_timeout_char, ARG_invert, ARG_flow };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 0} },
@@ -303,7 +309,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
uart_set_hw_flow_ctrl(self->uart_num, self->flowcontrol, UART_FIFO_LEN - UART_FIFO_LEN / 4);
}
-STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// get uart id
@@ -372,7 +378,7 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
// Make sure pins are connected.
uart_set_pin(self->uart_num, self->tx, self->rx, self->rts, self->cts);
@@ -380,30 +386,21 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- machine_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init);
-
-STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
uart_driver_delete(self->uart_num);
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit);
-STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
size_t rxbufsize;
uart_get_buffered_data_len(self->uart_num, &rxbufsize);
- return MP_OBJ_NEW_SMALL_INT(rxbufsize);
+ return rxbufsize;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
-STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ return uart_wait_tx_done(self->uart_num, 0) == ESP_OK;
+}
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
// Save settings
uint32_t baudrate;
uart_get_baudrate(self->uart_num, &baudrate);
@@ -418,46 +415,9 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
// Restore original setting
uart_set_baudrate(self->uart_num, baudrate);
-
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (uart_wait_tx_done(self->uart_num, 0) == ESP_OK) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-
-STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INV_TX) },
- { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INV_RX) },
- { MP_ROM_QSTR(MP_QSTR_INV_RTS), MP_ROM_INT(UART_INV_RTS) },
- { MP_ROM_QSTR(MP_QSTR_INV_CTS), MP_ROM_INT(UART_INV_CTS) },
-
- { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HW_FLOWCTRL_RTS) },
- { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HW_FLOWCTRL_CTS) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
-
-STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
// make sure we want at least 1 char
@@ -491,7 +451,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz
return bytes_read;
}
-STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
int bytes_written = uart_write_bytes(self->uart_num, buf_in, size);
@@ -505,7 +465,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
return bytes_written;
}
-STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
machine_uart_obj_t *self = self_in;
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
@@ -537,20 +497,3 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr
}
return ret;
}
-
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_uart_read,
- .write = machine_uart_write,
- .ioctl = machine_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_uart_make_new,
- print, machine_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &machine_uart_locals_dict
- );
diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c
index b1c9011cb..96df32d43 100644
--- a/ports/esp32/modmachine.c
+++ b/ports/esp32/modmachine.c
@@ -328,7 +328,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
{ MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) },
+ #if MICROPY_PY_MACHINE_UART
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
// Reset reasons
{ MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) },
diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h
index 68b7d4ffd..f60715f77 100644
--- a/ports/esp32/modmachine.h
+++ b/ports/esp32/modmachine.h
@@ -16,7 +16,6 @@ extern const mp_obj_type_t machine_adcblock_type;
extern const mp_obj_type_t machine_dac_type;
extern const mp_obj_type_t machine_i2c_type;
extern const mp_obj_type_t machine_spi_type;
-extern const mp_obj_type_t machine_uart_type;
extern const mp_obj_type_t machine_rtc_type;
extern const mp_obj_type_t machine_sdcard_type;
diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h
index 1718f31f6..39f91ab83 100644
--- a/ports/esp32/mpconfigport.h
+++ b/ports/esp32/mpconfigport.h
@@ -126,6 +126,9 @@
#define MICROPY_PY_MACHINE_I2S_FINALISER (1)
#define MICROPY_PY_MACHINE_I2S_CONSTANT_RX (I2S_MODE_MASTER | I2S_MODE_RX)
#define MICROPY_PY_MACHINE_I2S_CONSTANT_TX (I2S_MODE_MASTER | I2S_MODE_TX)
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/esp32/machine_uart.c"
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#define MICROPY_PY_MACHINE_WDT (1)
#define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/esp32/machine_wdt.c"
#define MICROPY_PY_NETWORK (1)
diff --git a/ports/esp8266/Makefile b/ports/esp8266/Makefile
index 0485f9bc0..b29df9fd2 100644
--- a/ports/esp8266/Makefile
+++ b/ports/esp8266/Makefile
@@ -114,7 +114,6 @@ SRC_C = \
machine_bitstream.c \
machine_pin.c \
machine_rtc.c \
- machine_uart.c \
machine_hspi.c \
modesp.c \
network_wlan.c \
diff --git a/ports/esp8266/machine_uart.c b/ports/esp8266/machine_uart.c
index 873b12b2f..f38858b0c 100644
--- a/ports/esp8266/machine_uart.c
+++ b/ports/esp8266/machine_uart.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Damien P. George
+ * Copyright (c) 2016-2023 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,24 +24,19 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
+#include "py/mperrno.h"
+#include "py/mphal.h"
#include "ets_sys.h"
#include "user_interface.h"
#include "uart.h"
-#include "py/runtime.h"
-#include "py/stream.h"
-#include "py/mperrno.h"
-#include "py/mphal.h"
-#include "modmachine.h"
-
// UartDev is defined and initialized in rom code.
extern UartDevice UartDev;
-typedef struct _pyb_uart_obj_t {
+typedef struct _machine_uart_obj_t {
mp_obj_base_t base;
uint8_t uart_id;
uint8_t bits;
@@ -50,21 +45,24 @@ typedef struct _pyb_uart_obj_t {
uint32_t baudrate;
uint16_t timeout; // timeout waiting for first char (in ms)
uint16_t timeout_char; // timeout waiting between chars (in ms)
-} pyb_uart_obj_t;
+} machine_uart_obj_t;
STATIC const char *_parity_name[] = {"None", "1", "0"};
/******************************************************************************/
// MicroPython bindings for UART
-STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// The UART class doesn't have any constants for this port.
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS
+
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, rxbuf=%u, timeout=%u, timeout_char=%u)",
self->uart_id, self->baudrate, self->bits, _parity_name[self->parity],
self->stop, uart0_get_rxbuf_len() - 1, self->timeout, self->timeout_char);
}
-STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_tx, ARG_rx, ARG_rxbuf, ARG_timeout, ARG_timeout_char };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 0} },
@@ -192,7 +190,7 @@ STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_o
uart_setup(self->uart_id);
}
-STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// get uart id
@@ -202,7 +200,7 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
}
// create instance
- pyb_uart_obj_t *self = mp_obj_malloc(pyb_uart_obj_t, &pyb_uart_type);
+ machine_uart_obj_t *self = mp_obj_malloc(machine_uart_obj_t, &machine_uart_type);
self->uart_id = uart_id;
self->baudrate = 115200;
self->bits = 8;
@@ -214,47 +212,25 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
// init the peripheral
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- pyb_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t pyb_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- pyb_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
- return mp_const_none;
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
+ (void)self;
}
-MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
-STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_NEW_SMALL_INT(uart_rx_any(self->uart_id));
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
+ return uart_rx_any(self->uart_id);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return uart_txdone(self->uart_id) == true ? mp_const_true : mp_const_false;
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ return uart_txdone(self->uart_id);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-
-STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
-
-STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (self->uart_id == 1) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("UART(1) can't read"));
@@ -282,8 +258,8 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
}
}
-STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
const byte *buf = buf_in;
/* TODO implement non-blocking
@@ -303,8 +279,8 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
return size;
}
-STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
- pyb_uart_obj_t *self = self_in;
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+ machine_uart_obj_t *self = self_in;
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
@@ -321,7 +297,7 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a
uint64_t timeout = (uint64_t)(3 + 127) * 13000000ll * 2 / self->baudrate
+ system_get_time();
do {
- if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
+ if (mp_machine_uart_txdone(self)) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
@@ -336,21 +312,4 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a
return ret;
}
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = pyb_uart_read,
- .write = pyb_uart_write,
- .ioctl = pyb_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- pyb_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, pyb_uart_make_new,
- print, pyb_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &pyb_uart_locals_dict
- );
-
MP_REGISTER_ROOT_POINTER(byte * uart0_rxbuf);
diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c
index 87e72bace..33e0272f8 100644
--- a/ports/esp8266/main.c
+++ b/ports/esp8266/main.c
@@ -40,6 +40,7 @@
#define USE_US_TIMER 1
#include "extmod/misc.h"
+#include "extmod/modmachine.h"
#include "shared/readline/readline.h"
#include "shared/runtime/pyexec.h"
#include "gccollect.h"
@@ -72,7 +73,7 @@ STATIC void mp_reset(void) {
mp_obj_t args[2];
args[0] = MP_OBJ_NEW_SMALL_INT(0);
args[1] = MP_OBJ_NEW_SMALL_INT(115200);
- args[0] = MP_OBJ_TYPE_GET_SLOT(&pyb_uart_type, make_new)(&pyb_uart_type, 2, 0, args);
+ args[0] = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)(&machine_uart_type, 2, 0, args);
args[1] = MP_OBJ_NEW_SMALL_INT(1);
mp_os_dupterm_obj.fun.var(2, args);
}
diff --git a/ports/esp8266/modmachine.c b/ports/esp8266/modmachine.c
index 43e94e0c8..d7e8ed033 100644
--- a/ports/esp8266/modmachine.c
+++ b/ports/esp8266/modmachine.c
@@ -430,7 +430,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
#if MICROPY_PY_MACHINE_ADC
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
#endif
- { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
+ #if MICROPY_PY_MACHINE_UART
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
#if MICROPY_PY_MACHINE_I2C
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) },
{ MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) },
diff --git a/ports/esp8266/modmachine.h b/ports/esp8266/modmachine.h
index 469d25e81..0c6a6afbb 100644
--- a/ports/esp8266/modmachine.h
+++ b/ports/esp8266/modmachine.h
@@ -5,7 +5,6 @@
extern const mp_obj_type_t pyb_pin_type;
extern const mp_obj_type_t pyb_rtc_type;
-extern const mp_obj_type_t pyb_uart_type;
extern const mp_obj_type_t pyb_i2c_type;
extern const mp_obj_type_t machine_hspi_type;
diff --git a/ports/esp8266/modos.c b/ports/esp8266/modos.c
index 78072d4f4..0194bf25f 100644
--- a/ports/esp8266/modos.c
+++ b/ports/esp8266/modos.c
@@ -30,6 +30,7 @@
#include "py/objtuple.h"
#include "py/objstr.h"
#include "extmod/misc.h"
+#include "extmod/modmachine.h"
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
#include "extmod/vfs_lfs.h"
@@ -53,10 +54,10 @@ STATIC mp_obj_t mp_os_urandom(mp_obj_t num) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_os_urandom_obj, mp_os_urandom);
void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached) {
- if (mp_obj_get_type(stream_attached) == &pyb_uart_type) {
+ if (mp_obj_get_type(stream_attached) == &machine_uart_type) {
++uart_attached_to_dupterm;
}
- if (mp_obj_get_type(stream_detached) == &pyb_uart_type) {
+ if (mp_obj_get_type(stream_detached) == &machine_uart_type) {
--uart_attached_to_dupterm;
}
}
diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h
index 4e3248513..8493814b4 100644
--- a/ports/esp8266/mpconfigport.h
+++ b/ports/esp8266/mpconfigport.h
@@ -74,6 +74,8 @@
#define MICROPY_PY_MACHINE_SOFTI2C (1)
#define MICROPY_PY_MACHINE_SPI (1)
#define MICROPY_PY_MACHINE_SOFTSPI (1)
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/esp8266/machine_uart.c"
#define MICROPY_PY_MACHINE_WDT (1)
#define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/esp8266/machine_wdt.c"
#define MICROPY_PY_NETWORK (1)
diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile
index b631c829b..6131a509d 100644
--- a/ports/mimxrt/Makefile
+++ b/ports/mimxrt/Makefile
@@ -202,7 +202,6 @@ SRC_C += \
machine_rtc.c \
machine_sdcard.c \
machine_spi.c \
- machine_uart.c \
main.c \
mbedtls/mbedtls_port.c \
mimxrt_flash.c \
diff --git a/ports/mimxrt/machine_uart.c b/ports/mimxrt/machine_uart.c
index 8e1505349..7d228d915 100644
--- a/ports/mimxrt/machine_uart.c
+++ b/ports/mimxrt/machine_uart.c
@@ -25,8 +25,9 @@
* THE SOFTWARE.
*/
-#include "py/runtime.h"
-#include "py/stream.h"
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
+
#include "py/mphal.h"
#include "ticks.h"
#include "fsl_common.h"
@@ -163,7 +164,16 @@ void machine_uart_set_baudrate(mp_obj_t uart_in, uint32_t baudrate) {
#endif
}
-STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+/******************************************************************************/
+// MicroPython bindings for UART
+
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
+ { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) }, \
+ { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) }, \
+ { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \
+
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, flow=%s, "
"rxbuf=%d, txbuf=%d, timeout=%u, timeout_char=%u, invert=%s)",
@@ -174,7 +184,7 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
_invert_name[self->invert]);
}
-STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_flow,
ARG_timeout, ARG_timeout_char, ARG_invert, ARG_rxbuf, ARG_txbuf};
static const mp_arg_t allowed_args[] = {
@@ -328,11 +338,9 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args
self->lpuart->STAT |= 1 << LPUART_STAT_BRK13_SHIFT;
LPUART_EnableTx(self->lpuart, true);
}
-
- return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// Get UART bus.
@@ -358,53 +366,33 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
if (uart_present) {
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- return machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ return MP_OBJ_FROM_PTR(self);
} else {
return mp_const_none;
}
}
-// uart.init(baud, [kwargs])
-STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- return machine_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
-}
-MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init);
-
// uart.deinit()
-STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
LPUART_SoftwareReset(self->lpuart);
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit);
-STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
machine_uart_ensure_active(self);
size_t count = LPUART_TransferGetRxRingBufferLength(self->lpuart, &self->handle);
- return MP_OBJ_NEW_SMALL_INT(count);
+ return count;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
-STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ return self->tx_status == kStatus_LPUART_TxIdle;
+}
+
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
machine_uart_ensure_active(self);
self->lpuart->CTRL |= 1 << LPUART_CTRL_SBK_SHIFT; // Set SBK bit
self->lpuart->CTRL &= ~LPUART_CTRL_SBK_MASK; // Clear SBK bit
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
-
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (self->tx_status == kStatus_LPUART_TxIdle) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
// Reset all defined UARTs
void machine_uart_deinit_all(void) {
@@ -415,31 +403,7 @@ void machine_uart_deinit_all(void) {
}
}
-STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) },
- { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) },
-
- { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) },
- { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) },
-
-};
-STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
-
-STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint64_t t = ticks_us64() + (uint64_t)self->timeout * 1000;
uint64_t timeout_char_us = (uint64_t)self->timeout_char * 1000;
@@ -474,7 +438,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz
return size;
}
-STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
lpuart_transfer_t xfer;
uint64_t t;
@@ -534,7 +498,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
return size;
}
-STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
machine_uart_obj_t *self = self_in;
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
@@ -558,7 +522,7 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
self->config.baudRate_Bps + ticks_us64();
do {
- if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
+ if (mp_machine_uart_txdone(self)) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
@@ -572,20 +536,3 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
}
return ret;
}
-
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_uart_read,
- .write = machine_uart_write,
- .ioctl = machine_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_uart_make_new,
- print, machine_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &machine_uart_locals_dict
- );
diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c
index 33394e62d..ab7f1de48 100644
--- a/ports/mimxrt/modmachine.c
+++ b/ports/mimxrt/modmachine.c
@@ -206,7 +206,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) },
#endif
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
+ #if MICROPY_PY_MACHINE_UART
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
#if MICROPY_PY_MACHINE_WDT
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) },
#endif
diff --git a/ports/mimxrt/modmachine.h b/ports/mimxrt/modmachine.h
index ff8ac0f08..c6ac4eb39 100644
--- a/ports/mimxrt/modmachine.h
+++ b/ports/mimxrt/modmachine.h
@@ -34,7 +34,6 @@ extern const mp_obj_type_t machine_rtc_type;
extern const mp_obj_type_t machine_sdcard_type;
extern const mp_obj_type_t machine_spi_type;
extern const mp_obj_type_t machine_timer_type;
-extern const mp_obj_type_t machine_uart_type;
void machine_adc_init(void);
void machine_pin_irq_deinit(void);
diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h
index 9df6397a8..01502d547 100644
--- a/ports/mimxrt/mpconfigport.h
+++ b/ports/mimxrt/mpconfigport.h
@@ -105,6 +105,9 @@ uint32_t trng_random_u32(void);
#define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/mimxrt/machine_wdt.c"
#define MICROPY_PY_MACHINE_WDT_TIMEOUT_MS (1)
#define MICROPY_SOFT_TIMER_TICKS_MS systick_ms
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/mimxrt/machine_uart.c"
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#define MICROPY_PY_ONEWIRE (1)
// fatfs configuration used in ffconf.h
diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile
index b5d832577..ac86ad2b1 100644
--- a/ports/nrf/Makefile
+++ b/ports/nrf/Makefile
@@ -321,7 +321,6 @@ endif
DRIVERS_SRC_C += $(addprefix modules/,\
machine/modmachine.c \
- machine/uart.c \
machine/spi.c \
machine/i2c.c \
machine/pin.c \
diff --git a/ports/nrf/main.c b/ports/nrf/main.c
index cd22521f4..959c31e2e 100644
--- a/ports/nrf/main.c
+++ b/ports/nrf/main.c
@@ -38,6 +38,7 @@
#include "py/stackctrl.h"
#include "py/gc.h"
#include "py/compile.h"
+#include "extmod/modmachine.h"
#include "shared/runtime/pyexec.h"
#include "readline.h"
#include "gccollect.h"
diff --git a/ports/nrf/modules/machine/modmachine.c b/ports/nrf/modules/machine/modmachine.c
index f8a6e424a..4d39a29b0 100644
--- a/ports/nrf/modules/machine/modmachine.c
+++ b/ports/nrf/modules/machine/modmachine.c
@@ -39,7 +39,6 @@
#include "lib/oofatfs/diskio.h"
#include "gccollect.h"
#include "pin.h"
-#include "uart.h"
#include "spi.h"
#include "i2c.h"
#include "timer.h"
diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c
index fd176549d..e0b56e831 100644
--- a/ports/nrf/modules/machine/uart.c
+++ b/ports/nrf/modules/machine/uart.c
@@ -26,13 +26,9 @@
* THE SOFTWARE.
*/
-#include <stdbool.h>
-#include <string.h>
-#include <stdarg.h>
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
-#include "py/nlr.h"
-#include "py/runtime.h"
-#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/ringbuf.h"
@@ -41,9 +37,7 @@
#include "shared/runtime/interrupt_char.h"
#include "uart.h"
-#include "mpconfigboard.h"
#include "nrf.h"
-#include "mphalport.h"
#if NRFX_UART_ENABLED
#include "nrfx_uart.h"
@@ -51,15 +45,12 @@
#include "nrfx_uarte.h"
#endif
-
-#if MICROPY_PY_MACHINE_UART
-
-typedef struct _machine_hard_uart_buf_t {
+typedef struct _machine_uart_buf_t {
uint8_t tx_buf[1];
uint8_t rx_buf[1];
uint8_t rx_ringbuf_array[64];
volatile ringbuf_t rx_ringbuf;
-} machine_hard_uart_buf_t;
+} machine_uart_buf_t;
#if NRFX_UARTE_ENABLED
@@ -96,17 +87,17 @@ typedef struct _machine_hard_uart_buf_t {
#endif
-typedef struct _machine_hard_uart_obj_t {
+typedef struct _machine_uart_obj_t {
mp_obj_base_t base;
const nrfx_uart_t * p_uart; // Driver instance
- machine_hard_uart_buf_t buf;
+ machine_uart_buf_t buf;
uint16_t timeout; // timeout waiting for first char (in ms)
uint16_t timeout_char; // timeout waiting between chars (in ms)
-} machine_hard_uart_obj_t;
+} machine_uart_obj_t;
static const nrfx_uart_t instance0 = NRFX_UART_INSTANCE(0);
-STATIC machine_hard_uart_obj_t machine_hard_uart_obj[] = {
+STATIC machine_uart_obj_t machine_uart_obj[] = {
{{&machine_uart_type}, .p_uart = &instance0}
};
@@ -116,14 +107,14 @@ void uart_init0(void) {
STATIC int uart_find(mp_obj_t id) {
// given an integer id
int uart_id = mp_obj_get_int(id);
- if (uart_id >= 0 && uart_id < MP_ARRAY_SIZE(machine_hard_uart_obj)) {
+ if (uart_id >= 0 && uart_id < MP_ARRAY_SIZE(machine_uart_obj)) {
return uart_id;
}
mp_raise_ValueError(MP_ERROR_TEXT("UART doesn't exist"));
}
STATIC void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context) {
- machine_hard_uart_obj_t *self = p_context;
+ machine_uart_obj_t *self = p_context;
if (p_event->type == NRFX_UART_EVT_RX_DONE) {
nrfx_uart_rx(self->p_uart, &self->buf.rx_buf[0], 1);
int chr = self->buf.rx_buf[0];
@@ -143,15 +134,15 @@ STATIC void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context
}
}
-bool uart_rx_any(machine_hard_uart_obj_t *self) {
+bool uart_rx_any(machine_uart_obj_t *self) {
return self->buf.rx_ringbuf.iput != self->buf.rx_ringbuf.iget;
}
-int uart_rx_char(machine_hard_uart_obj_t *self) {
+int uart_rx_char(machine_uart_obj_t *self) {
return ringbuf_get((ringbuf_t *)&self->buf.rx_ringbuf);
}
-STATIC nrfx_err_t uart_tx_char(machine_hard_uart_obj_t *self, int c) {
+STATIC nrfx_err_t uart_tx_char(machine_uart_obj_t *self, int c) {
while (nrfx_uart_tx_in_progress(self->p_uart)) {
;
}
@@ -160,13 +151,13 @@ STATIC nrfx_err_t uart_tx_char(machine_hard_uart_obj_t *self, int c) {
}
-void uart_tx_strn(machine_hard_uart_obj_t *uart_obj, const char *str, uint len) {
+void uart_tx_strn(machine_uart_obj_t *uart_obj, const char *str, uint len) {
for (const char *top = str + len; str < top; str++) {
uart_tx_char(uart_obj, *str);
}
}
-void uart_tx_strn_cooked(machine_hard_uart_obj_t *uart_obj, const char *str, uint len) {
+void uart_tx_strn_cooked(machine_uart_obj_t *uart_obj, const char *str, uint len) {
for (const char *top = str + len; str < top; str++) {
if (*str == '\n') {
uart_tx_char(uart_obj, '\r');
@@ -178,16 +169,24 @@ void uart_tx_strn_cooked(machine_hard_uart_obj_t *uart_obj, const char *str, uin
/******************************************************************************/
/* MicroPython bindings */
-STATIC void machine_hard_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+// The UART class doesn't have any constants for this port.
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS
+
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mp_printf(print, "UART(0)");
}
-/// \method init(id, baudrate)
-///
-/// Initialise the UART bus with the given parameters:
-/// - `id`is bus id.
-/// - `baudrate` is the clock rate.
-STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ // Parse args (none supported at this stage).
+ mp_arg_parse_all(n_args, pos_args, kw_args, 0, NULL, NULL);
+}
+
+// UART(id, baudrate)
+//
+// Initialise the UART bus with the given parameters:
+// - `id`is bus id.
+// - `baudrate` is the clock rate.
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_id, ARG_baudrate, ARG_timeout, ARG_timeout_char };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ },
@@ -202,7 +201,7 @@ STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_a
// get static peripheral object
int uart_id = uart_find(args[ARG_id].u_obj);
- machine_hard_uart_obj_t *self = &machine_hard_uart_obj[uart_id];
+ machine_uart_obj_t *self = &machine_uart_obj[uart_id];
nrfx_uart_config_t config;
@@ -267,78 +266,36 @@ STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_a
return MP_OBJ_FROM_PTR(self);
}
-/// \method writechar(char)
-/// Write a single character on the bus. `char` is an integer to write.
-/// Return value: `None`.
-STATIC mp_obj_t machine_hard_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
- machine_hard_uart_obj_t *self = self_in;
-
- // get the character to write (might be 9 bits)
- int data = mp_obj_get_int(char_in);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
+ (void)self;
+}
+// Write a single character on the bus. `data` is an integer to write.
+STATIC void mp_machine_uart_writechar(machine_uart_obj_t *self, uint16_t data) {
nrfx_err_t err = uart_tx_char(self, data);
if (err != NRFX_SUCCESS) {
mp_hal_raise(err);
}
-
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_hard_uart_writechar_obj, machine_hard_uart_writechar);
-
-/// \method readchar()
-/// Receive a single character on the bus.
-/// Return value: The character read, as an integer. Returns -1 on timeout.
-STATIC mp_obj_t machine_hard_uart_readchar(mp_obj_t self_in) {
- machine_hard_uart_obj_t *self = self_in;
- return MP_OBJ_NEW_SMALL_INT(uart_rx_char(self));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hard_uart_readchar_obj, machine_hard_uart_readchar);
-// uart.any()
-STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
- machine_hard_uart_obj_t *self = self_in;
- return MP_OBJ_NEW_SMALL_INT(ringbuf_avail((ringbuf_t *)&self->buf.rx_ringbuf));
+// Receive a single character on the bus.
+// Return value: The character read, as an integer. Returns -1 on timeout.
+STATIC mp_int_t mp_machine_uart_readchar(machine_uart_obj_t *self) {
+ return uart_rx_char(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
-// uart.sendbreak()
-STATIC mp_obj_t machine_hard_uart_sendbreak(mp_obj_t self_in) {
- return mp_const_none;
+// uart.any()
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
+ return ringbuf_avail((ringbuf_t *)&self->buf.rx_ringbuf);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_hard_uart_sendbreak_obj, machine_hard_uart_sendbreak);
// uart.txdone()
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- machine_hard_uart_obj_t *self = self_in;
- return mp_obj_new_bool(!nrfx_uart_tx_in_progress(self->p_uart));
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ return !nrfx_uart_tx_in_progress(self->p_uart);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-
-STATIC const mp_rom_map_elem_t machine_hard_uart_locals_dict_table[] = {
- // instance methods
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&machine_hard_uart_writechar_obj) },
- { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&machine_hard_uart_readchar_obj) },
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_hard_uart_sendbreak_obj) },
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
-
- // class constants
-/*
- { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) },
- { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) },
-*/
-};
-STATIC MP_DEFINE_CONST_DICT(machine_hard_uart_locals_dict, machine_hard_uart_locals_dict_table);
-
-STATIC mp_uint_t machine_hard_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
- machine_hard_uart_obj_t *self = self_in;
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+ machine_uart_obj_t *self = self_in;
byte *buf = buf_in;
uint32_t t = self->timeout + mp_hal_ticks_ms();
@@ -362,8 +319,8 @@ STATIC mp_uint_t machine_hard_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_
return size;
}
-STATIC mp_uint_t machine_hard_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
- machine_hard_uart_obj_t *self = self_in;
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+ machine_uart_obj_t *self = self_in;
nrfx_err_t err = nrfx_uart_tx(self->p_uart, buf_in, size);
if (err == NRFX_SUCCESS) {
@@ -378,8 +335,8 @@ STATIC mp_uint_t machine_hard_uart_write(mp_obj_t self_in, const void *buf_in, m
}
}
-STATIC mp_uint_t machine_hard_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
- machine_hard_uart_obj_t *self = self_in;
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+ machine_uart_obj_t *self = self_in;
(void)self;
mp_uint_t ret = 0;
@@ -399,22 +356,3 @@ STATIC mp_uint_t machine_hard_uart_ioctl(mp_obj_t self_in, mp_uint_t request, ui
}
return MP_STREAM_ERROR;
}
-
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_hard_uart_read,
- .write = machine_hard_uart_write,
- .ioctl = machine_hard_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_hard_uart_make_new,
- print, machine_hard_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &machine_hard_uart_locals_dict
- );
-
-#endif // MICROPY_PY_MACHINE_UART
diff --git a/ports/nrf/modules/machine/uart.h b/ports/nrf/modules/machine/uart.h
index eee0738fe..741473ab7 100644
--- a/ports/nrf/modules/machine/uart.h
+++ b/ports/nrf/modules/machine/uart.h
@@ -31,16 +31,15 @@
#include "pin.h"
#include "genhdr/pins.h"
-typedef struct _machine_hard_uart_obj_t machine_hard_uart_obj_t;
-extern const mp_obj_type_t machine_uart_type;
+typedef struct _machine_uart_obj_t machine_uart_obj_t;
void uart_init0(void);
void uart_deinit(void);
void uart_irq_handler(mp_uint_t uart_id);
-bool uart_rx_any(machine_hard_uart_obj_t *uart_obj);
-int uart_rx_char(machine_hard_uart_obj_t *uart_obj);
-void uart_tx_strn(machine_hard_uart_obj_t *uart_obj, const char *str, uint len);
-void uart_tx_strn_cooked(machine_hard_uart_obj_t *uart_obj, const char *str, uint len);
+bool uart_rx_any(machine_uart_obj_t *uart_obj);
+int uart_rx_char(machine_uart_obj_t *uart_obj);
+void uart_tx_strn(machine_uart_obj_t *uart_obj, const char *str, uint len);
+void uart_tx_strn_cooked(machine_uart_obj_t *uart_obj, const char *str, uint len);
#endif
diff --git a/ports/nrf/modules/os/modos.c b/ports/nrf/modules/os/modos.c
index 7654ac119..ebe504551 100644
--- a/ports/nrf/modules/os/modos.c
+++ b/ports/nrf/modules/os/modos.c
@@ -34,11 +34,11 @@
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
#include "modules/os/microbitfs.h"
+#include "extmod/modmachine.h"
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
#include "extmod/vfs_lfs.h"
#include "genhdr/mpversion.h"
-#include "uart.h"
#if MICROPY_HW_ENABLE_RNG
#include "drivers/rng.h"
diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h
index 79a74e856..929065b49 100644
--- a/ports/nrf/mpconfigport.h
+++ b/ports/nrf/mpconfigport.h
@@ -206,6 +206,9 @@
#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/nrf/modules/machine/soft_pwm.c"
#endif
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/nrf/modules/machine/uart.c"
+#define MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR (1)
+
#ifndef MICROPY_PY_MACHINE_TIMER_NRF
#define MICROPY_PY_MACHINE_TIMER_NRF (1)
#endif
diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c
index a2eec7fce..7a51e187b 100644
--- a/ports/nrf/mphalport.c
+++ b/ports/nrf/mphalport.c
@@ -378,4 +378,4 @@ const char *nrfx_error_code_lookup(uint32_t err_code) {
#endif // NRFX_LOG_ENABLED
-MP_REGISTER_ROOT_POINTER(struct _machine_hard_uart_obj_t *board_stdio_uart);
+MP_REGISTER_ROOT_POINTER(struct _machine_uart_obj_t *board_stdio_uart);
diff --git a/ports/renesas-ra/Makefile b/ports/renesas-ra/Makefile
index 4630c30fc..fb7bb67e4 100644
--- a/ports/renesas-ra/Makefile
+++ b/ports/renesas-ra/Makefile
@@ -322,7 +322,6 @@ SRC_C += \
machine_dac.c \
machine_i2c.c \
machine_spi.c \
- machine_uart.c \
machine_pin.c \
machine_rtc.c \
machine_sdcard.c \
diff --git a/ports/renesas-ra/machine_uart.c b/ports/renesas-ra/machine_uart.c
index f365223af..6c520f941 100644
--- a/ports/renesas-ra/machine_uart.c
+++ b/ports/renesas-ra/machine_uart.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013-2018 Damien P. George
+ * Copyright (c) 2013-2023 Damien P. George
* Copyright (c) 2021,2022 Renesas Electronics Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -25,12 +25,9 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
-#include "py/runtime.h"
-#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "shared/runtime/interrupt_char.h"
@@ -41,44 +38,13 @@
#define DEFAULT_UART_BAUDRATE (115200)
-STATIC const char *_parity_name[] = {"None", "ODD", "EVEN"};
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
+ { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) }, \
-/// \moduleref pyb
-/// \class UART - duplex serial communication bus
-///
-/// UART implements the standard UART/USART duplex serial communications protocol. At
-/// the physical level it consists of 2 lines: RX and TX. The unit of communication
-/// is a character (not to be confused with a string character) which can be 8 or 9
-/// bits wide.
-///
-/// UART objects can be created and initialised using:
-///
-/// from pyb import UART
-///
-/// uart = UART(1, 9600) # init with given baudrate
-/// uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
-///
-/// Bits can be 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2.
-///
-/// A UART object acts like a stream object and reading and writing is done
-/// using the standard stream methods:
-///
-/// uart.read(10) # read 10 characters, returns a bytes object
-/// uart.read() # read all available characters
-/// uart.readline() # read a line
-/// uart.readinto(buf) # read and store into the given buffer
-/// uart.write('abc') # write the 3 characters
-///
-/// Individual characters can be read/written using:
-///
-/// uart.readchar() # read 1 character and returns it as an integer
-/// uart.writechar(42) # write 1 character
-///
-/// To check if there is anything to be read, use:
-///
-/// uart.any() # returns True if any characters waiting
+STATIC const char *_parity_name[] = {"None", "ODD", "EVEN"};
-STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!self->is_enabled) {
mp_printf(print, "UART(%u)", self->uart_id);
@@ -116,7 +82,7 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
/// - `timeout_char` is the timeout in milliseconds to wait between characters.
/// - `flow` is RTS | CTS where RTS == 256, CTS == 512
/// - `read_buf_len` is the character length of the read buffer (0 to disable).
-STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_INT | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
@@ -238,7 +204,6 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args
#endif
// enable_irq(irq_state);
- return mp_const_none;
}
/// \classmethod \constructor(bus, ...)
@@ -256,7 +221,7 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args
/// - `UART(6)` is on `YA`: `(TX, RX) = (Y1, Y2) = (PC6, PC7)`
/// - `UART(3)` is on `YB`: `(TX, RX) = (Y9, Y10) = (PB10, PB11)`
/// - `UART(2)` is on: `(TX, RX) = (X3, X4) = (PA2, PA3)`
-STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
// check arguments
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
@@ -335,43 +300,33 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
// start the peripheral
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- return machine_uart_init_helper(MP_OBJ_TO_PTR(args[0]), n_args - 1, args + 1, kw_args);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init);
-
-/// \method deinit()
-/// Turn off the UART bus.
-STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// Turn off the UART bus.
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
uart_deinit(self);
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit);
-/// \method any()
-/// Return `True` if any characters waiting, else `False`.
-STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_NEW_SMALL_INT(uart_rx_any(self));
+// Return number of characters waiting.
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
+ return uart_rx_any(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
-/// \method writechar(char)
-/// Write a single character on the bus. `char` is an integer to write.
-/// Return value: `None`.
-STATIC mp_obj_t machine_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// Return `true` if all characters have been sent.
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ return !uart_tx_busy(self);
+}
- // get the character to write (might be 9 bits)
- uint16_t data = mp_obj_get_int(char_in);
+// Send a break condition.
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
+ ra_sci_tx_break((uint32_t)self->uart_id);
+}
- // write the character
+// Write a single character on the bus. `data` is an integer to write.
+STATIC void mp_machine_uart_writechar(machine_uart_obj_t *self, uint16_t data) {
int errcode;
if (uart_tx_wait(self, self->timeout)) {
uart_tx_data(self, &data, 1, &errcode);
@@ -382,53 +337,26 @@ STATIC mp_obj_t machine_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
if (errcode != 0) {
mp_raise_OSError(errcode);
}
-
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_uart_writechar_obj, machine_uart_writechar);
-/// \method readchar()
-/// Receive a single character on the bus.
-/// Return value: The character read, as an integer. Returns -1 on timeout.
-STATIC mp_obj_t machine_uart_readchar(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// Receive a single character on the bus.
+// Return value: The character read, as an integer. Returns -1 on timeout.
+STATIC mp_int_t mp_machine_uart_readchar(machine_uart_obj_t *self) {
if (uart_rx_wait(self, self->timeout)) {
- return MP_OBJ_NEW_SMALL_INT(uart_rx_char(self));
+ return uart_rx_char(self);
} else {
// return -1 on timeout
- return MP_OBJ_NEW_SMALL_INT(-1);
+ return -1;
}
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_readchar_obj, machine_uart_readchar);
-
-// uart.sendbreak()
-STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- ra_sci_tx_break((uint32_t)self->uart_id);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
-
-// \method uart.txdone()
-// Return `True` if all characters have been sent.
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return uart_tx_busy(self) ? mp_const_false : mp_const_true;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-
-// irq(handler, trigger, hard)
-STATIC mp_obj_t machine_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- mp_arg_val_t args[MP_IRQ_ARG_INIT_NUM_ARGS];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_IRQ_ARG_INIT_NUM_ARGS, mp_irq_init_args, args);
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+STATIC mp_irq_obj_t *mp_machine_uart_irq(machine_uart_obj_t *self, bool any_args, mp_arg_val_t *args) {
if (self->mp_irq_obj == NULL) {
self->mp_irq_trigger = 0;
self->mp_irq_obj = mp_irq_new(&uart_irq_methods, MP_OBJ_FROM_PTR(self));
}
- if (n_args > 1 || kw_args->used != 0) {
+ if (any_args) {
// Check the handler
mp_obj_t handler = args[MP_IRQ_ARG_INIT_handler].u_obj;
if (handler != mp_const_none && !mp_obj_is_callable(handler)) {
@@ -450,41 +378,10 @@ STATIC mp_obj_t machine_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map
uart_irq_config(self, true);
}
- return MP_OBJ_FROM_PTR(self->mp_irq_obj);
+ return self->mp_irq_obj;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_irq_obj, 1, machine_uart_irq);
-
-STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
- // instance methods
-
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
-
- /// \method read([nbytes])
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- /// \method readline()
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
- /// \method readinto(buf[, nbytes])
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- /// \method write(buf)
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
- { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_uart_irq_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&machine_uart_writechar_obj) },
- { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&machine_uart_readchar_obj) },
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
-
- // class constants
- { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) },
- { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
-
-STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
byte *buf = buf_in;
@@ -526,7 +423,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz
}
}
-STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
const byte *buf = buf_in;
@@ -555,7 +452,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
}
}
-STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
@@ -587,21 +484,4 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr
return ret;
}
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_uart_read,
- .write = machine_uart_write,
- .ioctl = machine_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_uart_make_new,
- locals_dict, &machine_uart_locals_dict,
- print, machine_uart_print,
- protocol, &uart_stream_p
- );
-
MP_REGISTER_ROOT_POINTER(struct _machine_uart_obj_t *machine_uart_obj_all[MICROPY_HW_MAX_UART + MICROPY_HW_MAX_LPUART]);
diff --git a/ports/renesas-ra/modmachine.c b/ports/renesas-ra/modmachine.c
index 9b93b6948..62c9a392c 100644
--- a/ports/renesas-ra/modmachine.c
+++ b/ports/renesas-ra/modmachine.c
@@ -296,7 +296,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
{ MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) },
#endif
+ #if MICROPY_PY_MACHINE_UART
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) },
#if MICROPY_PY_MACHINE_PWM
#if MICROPY_HW_ENABLE_HW_PWM
diff --git a/ports/renesas-ra/modmachine.h b/ports/renesas-ra/modmachine.h
index 1dd0eec75..ddf212221 100644
--- a/ports/renesas-ra/modmachine.h
+++ b/ports/renesas-ra/modmachine.h
@@ -37,7 +37,6 @@ extern const mp_obj_type_t machine_dac_type;
extern const mp_obj_type_t machine_i2c_type;
extern const mp_obj_type_t machine_spi_type;
extern const mp_obj_type_t machine_i2s_type;
-extern const mp_obj_type_t machine_uart_type;
extern const mp_obj_type_t machine_rtc_type;
extern const mp_obj_type_t machine_sdcard_type;
diff --git a/ports/renesas-ra/mpconfigport.h b/ports/renesas-ra/mpconfigport.h
index 71d5cab82..d3bc3235f 100644
--- a/ports/renesas-ra/mpconfigport.h
+++ b/ports/renesas-ra/mpconfigport.h
@@ -151,6 +151,11 @@
#define MICROPY_PY_MACHINE_PWM_DUTY (1)
#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/renesas-ra/machine_pwm.c"
#endif
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/renesas-ra/machine_uart.c"
+#define MICROPY_PY_MACHINE_UART_IRQ (1)
+#define MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR (1)
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#if MICROPY_HW_ENABLE_HW_DAC
#define MICROPY_PY_MACHINE_DAC (1)
#endif
diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt
index c93a8a55d..16f2d8a24 100644
--- a/ports/rp2/CMakeLists.txt
+++ b/ports/rp2/CMakeLists.txt
@@ -123,7 +123,6 @@ set(MICROPY_SOURCE_PORT
machine_rtc.c
machine_spi.c
machine_timer.c
- machine_uart.c
main.c
modmachine.c
modrp2.c
diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c
index 09870e78f..044c905ff 100644
--- a/ports/rp2/machine_uart.c
+++ b/ports/rp2/machine_uart.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2020-2021 Damien P. George
+ * Copyright (c) 2020-2023 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,12 +24,12 @@
* THE SOFTWARE.
*/
-#include "py/runtime.h"
-#include "py/stream.h"
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
+
#include "py/mphal.h"
#include "py/mperrno.h"
#include "py/ringbuf.h"
-#include "modmachine.h"
#include "hardware/irq.h"
#include "hardware/uart.h"
@@ -183,7 +183,13 @@ STATIC void uart1_irq_handler(void) {
/******************************************************************************/
// MicroPython bindings for UART
-STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
+ { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) }, \
+ { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) }, \
+ { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \
+
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, tx=%d, rx=%d, "
"txbuf=%d, rxbuf=%d, timeout=%u, timeout_char=%u, invert=%s)",
@@ -192,7 +198,7 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
self->timeout, self->timeout_char, _invert_name[self->invert]);
}
-STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_tx, ARG_rx, ARG_cts, ARG_rts,
ARG_timeout, ARG_timeout_char, ARG_invert, ARG_flow, ARG_txbuf, ARG_rxbuf};
static const mp_arg_t allowed_args[] = {
@@ -378,7 +384,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
}
}
-STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// Get UART bus.
@@ -393,20 +399,12 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
// Initialise the UART peripheral.
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- // Initialise the UART peripheral.
- machine_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
- return mp_const_none;
-}
-MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init);
-
-STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
uart_deinit(self->uart);
if (self->uart_id == 0) {
irq_set_enabled(UART0_IRQ, false);
@@ -416,63 +414,26 @@ STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
self->baudrate = 0;
MP_STATE_PORT(rp2_uart_rx_buffer[self->uart_id]) = NULL;
MP_STATE_PORT(rp2_uart_tx_buffer[self->uart_id]) = NULL;
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit);
-STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
// get all bytes from the fifo first
uart_drain_rx_fifo(self);
- return MP_OBJ_NEW_SMALL_INT(ringbuf_avail(&self->read_buffer));
+ return ringbuf_avail(&self->read_buffer);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
-STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ return ringbuf_avail(&self->write_buffer) == 0
+ && (uart_get_hw(self->uart)->fr & UART_UARTFR_TXFE_BITS);
+}
+
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
uart_set_break(self->uart, true);
mp_hal_delay_us(13000000 / self->baudrate + 1);
uart_set_break(self->uart, false);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
-
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (ringbuf_avail(&self->write_buffer) == 0 &&
- uart_get_hw(self->uart)->fr & UART_UARTFR_TXFE_BITS) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-
-STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) },
- { MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) },
- { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) },
- { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) },
-
-};
-STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
-
-STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint64_t t = time_us_64() + (uint64_t)self->timeout * 1000;
uint64_t timeout_char_us = (uint64_t)self->timeout_char * 1000;
@@ -502,7 +463,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz
return size;
}
-STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint64_t t = time_us_64() + (uint64_t)self->timeout * 1000;
uint64_t timeout_char_us = (uint64_t)self->timeout_char * 1000;
@@ -542,7 +503,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
return size;
}
-STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
machine_uart_obj_t *self = self_in;
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
@@ -560,7 +521,7 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
uint64_t timeout = time_us_64() +
(uint64_t)(33 + self->write_buffer.size) * 13000000ll * 2 / self->baudrate;
do {
- if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
+ if (mp_machine_uart_txdone(self)) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
@@ -574,22 +535,5 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
return ret;
}
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_uart_read,
- .write = machine_uart_write,
- .ioctl = machine_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_uart_make_new,
- print, machine_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &machine_uart_locals_dict
- );
-
MP_REGISTER_ROOT_POINTER(void *rp2_uart_rx_buffer[2]);
MP_REGISTER_ROOT_POINTER(void *rp2_uart_tx_buffer[2]);
diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c
index b47af1aba..94d87cf31 100644
--- a/ports/rp2/modmachine.c
+++ b/ports/rp2/modmachine.c
@@ -267,7 +267,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
{ MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) },
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) },
+ #if MICROPY_PY_MACHINE_UART
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
#if MICROPY_PY_MACHINE_WDT
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) },
#endif
diff --git a/ports/rp2/modmachine.h b/ports/rp2/modmachine.h
index 5feafdcea..4e4245ed3 100644
--- a/ports/rp2/modmachine.h
+++ b/ports/rp2/modmachine.h
@@ -8,7 +8,6 @@ extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t machine_rtc_type;
extern const mp_obj_type_t machine_spi_type;
extern const mp_obj_type_t machine_timer_type;
-extern const mp_obj_type_t machine_uart_type;
void machine_pin_init(void);
void machine_pin_deinit(void);
diff --git a/ports/rp2/mpbthciport.c b/ports/rp2/mpbthciport.c
index 772236092..16d50ddac 100644
--- a/ports/rp2/mpbthciport.c
+++ b/ports/rp2/mpbthciport.c
@@ -28,6 +28,7 @@
#include "py/stream.h"
#include "py/mphal.h"
#include "extmod/modbluetooth.h"
+#include "extmod/modmachine.h"
#include "extmod/mpbthci.h"
#include "modmachine.h"
#include "mpbthciport.h"
diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h
index b69a06387..0a6331273 100644
--- a/ports/rp2/mpconfigport.h
+++ b/ports/rp2/mpconfigport.h
@@ -129,6 +129,9 @@
#define MICROPY_PY_MACHINE_SPI_MSB (SPI_MSB_FIRST)
#define MICROPY_PY_MACHINE_SPI_LSB (SPI_LSB_FIRST)
#define MICROPY_PY_MACHINE_SOFTSPI (1)
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/rp2/machine_uart.c"
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#define MICROPY_PY_MACHINE_WDT (1)
#define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/rp2/machine_wdt.c"
#define MICROPY_PY_ONEWIRE (1)
diff --git a/ports/samd/Makefile b/ports/samd/Makefile
index 841e6a992..7d27367b6 100644
--- a/ports/samd/Makefile
+++ b/ports/samd/Makefile
@@ -102,7 +102,6 @@ SRC_C += \
machine_pin.c \
machine_rtc.c \
machine_spi.c \
- machine_uart.c \
main.c \
modmachine.c \
modsamd.c \
diff --git a/ports/samd/machine_i2c.c b/ports/samd/machine_i2c.c
index f3364950b..5606d7b62 100644
--- a/ports/samd/machine_i2c.c
+++ b/ports/samd/machine_i2c.c
@@ -71,8 +71,6 @@ typedef struct _machine_i2c_obj_t {
uint8_t *buf;
} machine_i2c_obj_t;
-extern Sercom *sercom_instance[];
-
STATIC void i2c_send_command(Sercom *i2c, uint8_t command) {
i2c->I2CM.CTRLB.bit.CMD = command;
while (i2c->I2CM.SYNCBUSY.bit.SYSOP) {
diff --git a/ports/samd/machine_spi.c b/ports/samd/machine_spi.c
index 99eb4e17f..b00eb4271 100644
--- a/ports/samd/machine_spi.c
+++ b/ports/samd/machine_spi.c
@@ -60,8 +60,6 @@ typedef struct _machine_spi_obj_t {
size_t rxlen;
} machine_spi_obj_t;
-extern Sercom *sercom_instance[];
-
void common_spi_irq_handler(int spi_id) {
// handle Sercom IRQ RXC
machine_spi_obj_t *self = MP_STATE_PORT(sercom_table[spi_id]);
diff --git a/ports/samd/machine_uart.c b/ports/samd/machine_uart.c
index b95e158b3..c081b8814 100644
--- a/ports/samd/machine_uart.c
+++ b/ports/samd/machine_uart.c
@@ -24,17 +24,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "py/runtime.h"
-#if MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_UART
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
#include "py/mphal.h"
-#include "py/stream.h"
#include "py/ringbuf.h"
-#include "modmachine.h"
#include "samd_soc.h"
#include "pin_af.h"
-#include "clock_config.h"
#define DEFAULT_UART_BAUDRATE (115200)
#define DEFAULT_BUFFER_SIZE (256)
@@ -43,6 +40,8 @@
#define FLOW_CONTROL_RTS (1)
#define FLOW_CONTROL_CTS (2)
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS
+
typedef struct _machine_uart_obj_t {
mp_obj_base_t base;
uint8_t id;
@@ -69,30 +68,6 @@ typedef struct _machine_uart_obj_t {
#endif
} machine_uart_obj_t;
-Sercom *sercom_instance[] = SERCOM_INSTS;
-MP_REGISTER_ROOT_POINTER(void *sercom_table[SERCOM_INST_NUM]);
-
-// Common Sercom functions used by all Serial devices
-void sercom_enable(Sercom *uart, int state) {
- uart->USART.CTRLA.bit.ENABLE = state; // Set the state on/off
- // Wait for the Registers to update.
- while (uart->USART.SYNCBUSY.bit.ENABLE) {
- }
-}
-
-void sercom_deinit_all(void) {
- for (int i = 0; i < SERCOM_INST_NUM; i++) {
- Sercom *uart = sercom_instance[i];
- uart->USART.INTENCLR.reg = 0xff;
- sercom_register_irq(i, NULL);
- sercom_enable(uart, 0);
- MP_STATE_PORT(sercom_table[i]) = NULL;
- }
-}
-#endif
-
-#if MICROPY_PY_MACHINE_UART
-
STATIC const char *_parity_name[] = {"None", "", "0", "1"}; // Is defined as 0, 2, 3
// Irq handler
@@ -137,7 +112,7 @@ void common_uart_irq_handler(int uart_id) {
}
}
-STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, "
"timeout=%u, timeout_char=%u, rxbuf=%d"
@@ -160,7 +135,7 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
);
}
-STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_tx, ARG_rx,
ARG_timeout, ARG_timeout_char, ARG_rxbuf, ARG_txbuf, ARG_rts, ARG_cts };
static const mp_arg_t allowed_args[] = {
@@ -373,11 +348,9 @@ STATIC mp_obj_t machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args
sercom_enable(uart, 1);
}
-
- return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
// Get UART bus.
@@ -405,17 +378,12 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- return machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
-}
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
-// uart.init(baud, [kwargs])
-STATIC mp_obj_t machine_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- return machine_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
+ return MP_OBJ_FROM_PTR(self);
}
-MP_DEFINE_CONST_FUN_OBJ_KW(machine_uart_init_obj, 1, machine_uart_init);
-STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
// Check if it is the active object.
if (MP_STATE_PORT(sercom_table)[self->id] == self) {
Sercom *uart = sercom_instance[self->id];
@@ -426,18 +394,23 @@ STATIC mp_obj_t machine_uart_deinit(mp_obj_t self_in) {
sercom_enable(uart, 0);
}
}
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_deinit_obj, machine_uart_deinit);
-STATIC mp_obj_t machine_uart_any(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_NEW_SMALL_INT(ringbuf_avail(&self->read_buffer));
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
+ return ringbuf_avail(&self->read_buffer);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_any_obj, machine_uart_any);
-STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ Sercom *uart = sercom_instance[self->id];
+
+ return uart->USART.INTFLAG.bit.DRE
+ #if MICROPY_HW_UART_TXBUF
+ && ringbuf_avail(&self->write_buffer) == 0
+ #endif
+ && uart->USART.INTFLAG.bit.TXC;
+}
+
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
uint32_t break_time_us = 13 * 1000000 / self->baudrate;
// Wait for the tx buffer to drain.
@@ -457,43 +430,9 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
mp_hal_pin_high(self->tx);
// Enable Mux again
mp_hal_set_pin_mux(self->tx, self->tx_pad_config.alt_fct);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
-
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- Sercom *uart = sercom_instance[self->id];
-
- if (uart->USART.INTFLAG.bit.DRE
- #if MICROPY_HW_UART_TXBUF
- && ringbuf_avail(&self->write_buffer) == 0
- #endif
- && uart->USART.INTFLAG.bit.TXC) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
-};
-STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
-
-STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
Sercom *uart = sercom_instance[self->id];
uint64_t t = mp_hal_ticks_ms_64() + self->timeout;
@@ -523,7 +462,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz
return size;
}
-STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
size_t i = 0;
const uint8_t *src = buf_in;
@@ -562,7 +501,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
return size;
}
-STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
machine_uart_obj_t *self = self_in;
mp_uint_t ret;
Sercom *uart = sercom_instance[self->id];
@@ -588,7 +527,7 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
#endif
) * 13000 * 2 / self->baudrate;
do {
- if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
+ if (mp_machine_uart_txdone(self)) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
@@ -601,21 +540,3 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
}
return ret;
}
-
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_uart_read,
- .write = machine_uart_write,
- .ioctl = machine_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_uart_make_new,
- print, machine_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &machine_uart_locals_dict
- );
-#endif
diff --git a/ports/samd/modmachine.h b/ports/samd/modmachine.h
index 81b307817..4f287bde3 100644
--- a/ports/samd/modmachine.h
+++ b/ports/samd/modmachine.h
@@ -40,9 +40,6 @@ extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t machine_spi_type;
#endif
extern const mp_obj_type_t machine_timer_type;
-#if MICROPY_PY_MACHINE_UART
-extern const mp_obj_type_t machine_uart_type;
-#endif
#if MICROPY_PY_MACHINE_RTC
extern const mp_obj_type_t machine_rtc_type;
#endif
diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h
index 201e657c6..801408ed4 100644
--- a/ports/samd/mpconfigport.h
+++ b/ports/samd/mpconfigport.h
@@ -116,6 +116,8 @@
#ifndef MICROPY_PY_MACHINE_UART
#define MICROPY_PY_MACHINE_UART (1)
#endif
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/samd/machine_uart.c"
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#define MICROPY_PY_MACHINE_TIMER (1)
#define MICROPY_SOFT_TIMER_TICKS_MS systick_ms
#define MICROPY_PY_OS_DUPTERM (3)
diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c
index a81e7c688..ad5910301 100644
--- a/ports/samd/samd_soc.c
+++ b/ports/samd/samd_soc.c
@@ -128,3 +128,28 @@ void samd_init(void) {
machine_rtc_start(false);
#endif
}
+
+#if MICROPY_PY_MACHINE_I2C || MICROPY_PY_MACHINE_SPI || MICROPY_PY_MACHINE_UART
+
+Sercom *sercom_instance[] = SERCOM_INSTS;
+MP_REGISTER_ROOT_POINTER(void *sercom_table[SERCOM_INST_NUM]);
+
+// Common Sercom functions used by all Serial devices
+void sercom_enable(Sercom *uart, int state) {
+ uart->USART.CTRLA.bit.ENABLE = state; // Set the state on/off
+ // Wait for the Registers to update.
+ while (uart->USART.SYNCBUSY.bit.ENABLE) {
+ }
+}
+
+void sercom_deinit_all(void) {
+ for (int i = 0; i < SERCOM_INST_NUM; i++) {
+ Sercom *uart = sercom_instance[i];
+ uart->USART.INTENCLR.reg = 0xff;
+ sercom_register_irq(i, NULL);
+ sercom_enable(uart, 0);
+ MP_STATE_PORT(sercom_table[i]) = NULL;
+ }
+}
+
+#endif
diff --git a/ports/samd/samd_soc.h b/ports/samd/samd_soc.h
index e8560b50e..1848cf7db 100644
--- a/ports/samd/samd_soc.h
+++ b/ports/samd/samd_soc.h
@@ -30,6 +30,8 @@
#include "sam.h"
#include "clock_config.h"
+extern Sercom *sercom_instance[];
+
void samd_init(void);
void samd_main(void);
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index d1248e0bb..d3b80ab5b 100644
--- a/ports/stm32/Makefile
+++ b/ports/stm32/Makefile
@@ -335,7 +335,6 @@ SRC_C += \
machine_bitstream.c \
machine_i2c.c \
machine_spi.c \
- machine_uart.c \
modmachine.c \
modpyb.c \
modstm.c \
diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c
index ba8c1a911..6f1a7f9a2 100644
--- a/ports/stm32/machine_uart.c
+++ b/ports/stm32/machine_uart.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013-2018 Damien P. George
+ * Copyright (c) 2013-2023 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,12 +24,11 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
+
#include <string.h>
-#include <stdarg.h>
-#include "py/runtime.h"
-#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "shared/runtime/interrupt_char.h"
@@ -38,43 +37,13 @@
#include "irq.h"
#include "pendsv.h"
-/// \moduleref pyb
-/// \class UART - duplex serial communication bus
-///
-/// UART implements the standard UART/USART duplex serial communications protocol. At
-/// the physical level it consists of 2 lines: RX and TX. The unit of communication
-/// is a character (not to be confused with a string character) which can be 8 or 9
-/// bits wide.
-///
-/// UART objects can be created and initialised using:
-///
-/// from pyb import UART
-///
-/// uart = UART(1, 9600) # init with given baudrate
-/// uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
-///
-/// Bits can be 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2.
-///
-/// A UART object acts like a stream object and reading and writing is done
-/// using the standard stream methods:
-///
-/// uart.read(10) # read 10 characters, returns a bytes object
-/// uart.read() # read all available characters
-/// uart.readline() # read a line
-/// uart.readinto(buf) # read and store into the given buffer
-/// uart.write('abc') # write the 3 characters
-///
-/// Individual characters can be read/written using:
-///
-/// uart.readchar() # read 1 character and returns it as an integer
-/// uart.writechar(42) # write 1 character
-///
-/// To check if there is anything to be read, use:
-///
-/// uart.any() # returns True if any characters waiting
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
+ { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) }, \
+ { MP_ROM_QSTR(MP_QSTR_IRQ_RXIDLE), MP_ROM_INT(UART_FLAG_IDLE) }, \
-STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!self->is_enabled) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
@@ -171,7 +140,7 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
/// - `timeout_char` is the timeout in milliseconds to wait between characters.
/// - `flow` is RTS | CTS where RTS == 256, CTS == 512
/// - `read_buf_len` is the character length of the read buffer (0 to disable).
-STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} },
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
@@ -292,8 +261,6 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
if (20 * baudrate_diff > actual_baudrate) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("set baudrate %d is not within 5%% of desired value"), actual_baudrate);
}
-
- return mp_const_none;
}
/// \classmethod \constructor(bus, ...)
@@ -311,7 +278,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
/// - `UART(6)` is on `YA`: `(TX, RX) = (Y1, Y2) = (PC6, PC7)`
/// - `UART(3)` is on `YB`: `(TX, RX) = (Y9, Y10) = (PB10, PB11)`
/// - `UART(2)` is on: `(TX, RX) = (X3, X4) = (PA2, PA3)`
-STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
// check arguments
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
@@ -391,59 +358,56 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%d) is reserved"), uart_id);
}
- pyb_uart_obj_t *self;
- if (MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] == NULL) {
+ machine_uart_obj_t *self;
+ if (MP_STATE_PORT(machine_uart_obj_all)[uart_id - 1] == NULL) {
// create new UART object
- self = m_new0(pyb_uart_obj_t, 1);
- self->base.type = &pyb_uart_type;
+ self = m_new0(machine_uart_obj_t, 1);
+ self->base.type = &machine_uart_type;
self->uart_id = uart_id;
- MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] = self;
+ MP_STATE_PORT(machine_uart_obj_all)[uart_id - 1] = self;
} else {
// reference existing UART object
- self = MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1];
+ self = MP_STATE_PORT(machine_uart_obj_all)[uart_id - 1];
}
if (n_args > 1 || n_kw > 0) {
// start the peripheral
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- pyb_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
}
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t pyb_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- return pyb_uart_init_helper(MP_OBJ_TO_PTR(args[0]), n_args - 1, args + 1, kw_args);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
-
-/// \method deinit()
-/// Turn off the UART bus.
-STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// Turn off the UART bus.
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
uart_deinit(self);
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit);
-/// \method any()
-/// Return `True` if any characters waiting, else `False`.
-STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_NEW_SMALL_INT(uart_rx_any(self));
+// Return number of characters waiting.
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
+ return uart_rx_any(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
-/// \method writechar(char)
-/// Write a single character on the bus. `char` is an integer to write.
-/// Return value: `None`.
-STATIC mp_obj_t pyb_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// Since uart.write() waits up to the last byte, uart.txdone() always returns True.
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ (void)self;
+ return true;
+}
- // get the character to write (might be 9 bits)
- uint16_t data = mp_obj_get_int(char_in);
+// Send a break condition.
+STATIC void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ self->uartx->RQR = USART_RQR_SBKRQ; // write-only register
+ #else
+ self->uartx->CR1 |= USART_CR1_SBK;
+ #endif
+}
+// Write a single character on the bus. `data` is an integer to write.
+// The `data` can be up to 9 bits.
+STATIC void mp_machine_uart_writechar(machine_uart_obj_t *self, uint16_t data) {
// write the character
int errcode;
if (uart_tx_wait(self, self->timeout)) {
@@ -455,49 +419,26 @@ STATIC mp_obj_t pyb_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
if (errcode != 0) {
mp_raise_OSError(errcode);
}
-
- return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_uart_writechar_obj, pyb_uart_writechar);
-/// \method readchar()
-/// Receive a single character on the bus.
-/// Return value: The character read, as an integer. Returns -1 on timeout.
-STATIC mp_obj_t pyb_uart_readchar(mp_obj_t self_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+// Receive a single character on the bus.
+// Return value: The character read, as an integer. Returns -1 on timeout.
+STATIC mp_int_t mp_machine_uart_readchar(machine_uart_obj_t *self) {
if (uart_rx_wait(self, self->timeout)) {
- return MP_OBJ_NEW_SMALL_INT(uart_rx_char(self));
+ return uart_rx_char(self);
} else {
// return -1 on timeout
- return MP_OBJ_NEW_SMALL_INT(-1);
+ return -1;
}
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar);
-
-// uart.sendbreak()
-STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
- self->uartx->RQR = USART_RQR_SBKRQ; // write-only register
- #else
- self->uartx->CR1 |= USART_CR1_SBK;
- #endif
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak);
-
-// irq(handler, trigger, hard)
-STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- mp_arg_val_t args[MP_IRQ_ARG_INIT_NUM_ARGS];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_IRQ_ARG_INIT_NUM_ARGS, mp_irq_init_args, args);
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+STATIC mp_irq_obj_t *mp_machine_uart_irq(machine_uart_obj_t *self, bool any_args, mp_arg_val_t *args) {
if (self->mp_irq_obj == NULL) {
self->mp_irq_trigger = 0;
self->mp_irq_obj = mp_irq_new(&uart_irq_methods, MP_OBJ_FROM_PTR(self));
}
- if (n_args > 1 || kw_args->used != 0) {
+ if (any_args) {
// Check the handler
mp_obj_t handler = args[MP_IRQ_ARG_INIT_handler].u_obj;
if (handler != mp_const_none && !mp_obj_is_callable(handler)) {
@@ -519,51 +460,11 @@ STATIC mp_obj_t pyb_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
uart_irq_config(self, true);
}
- return MP_OBJ_FROM_PTR(self->mp_irq_obj);
+ return self->mp_irq_obj;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_irq_obj, 1, pyb_uart_irq);
-// Since uart.write() waits up to the last byte, uart.txdone() always returns True.
-STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
- return mp_const_true;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
-
-STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
- // instance methods
-
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_uart_deinit_obj) },
- { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
-
- /// \method read([nbytes])
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- /// \method readline()
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
- /// \method readinto(buf[, nbytes])
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- /// \method write(buf)
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
- { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
- { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&pyb_uart_irq_obj) },
-
- { MP_ROM_QSTR(MP_QSTR_writechar), MP_ROM_PTR(&pyb_uart_writechar_obj) },
- { MP_ROM_QSTR(MP_QSTR_readchar), MP_ROM_PTR(&pyb_uart_readchar_obj) },
- { MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&pyb_uart_sendbreak_obj) },
- { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
-
- // class constants
- { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(UART_HWCONTROL_RTS) },
- { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(UART_HWCONTROL_CTS) },
-
- // IRQ flags
- { MP_ROM_QSTR(MP_QSTR_IRQ_RXIDLE), MP_ROM_INT(UART_FLAG_IDLE) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
-
-STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
byte *buf = buf_in;
// check that size is a multiple of character width
@@ -604,8 +505,8 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
}
}
-STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
const byte *buf = buf_in;
// check that size is a multiple of character width
@@ -631,8 +532,8 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
}
}
-STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
uintptr_t flags = arg;
@@ -652,20 +553,3 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t a
}
return ret;
}
-
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = pyb_uart_read,
- .write = pyb_uart_write,
- .ioctl = pyb_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- pyb_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, pyb_uart_make_new,
- print, pyb_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &pyb_uart_locals_dict
- );
diff --git a/ports/stm32/main.c b/ports/stm32/main.c
index 9e5dafc9f..06ba74f75 100644
--- a/ports/stm32/main.c
+++ b/ports/stm32/main.c
@@ -40,6 +40,7 @@
#include "lib/littlefs/lfs1_util.h"
#include "lib/littlefs/lfs2.h"
#include "lib/littlefs/lfs2_util.h"
+#include "extmod/modmachine.h"
#include "extmod/modnetwork.h"
#include "extmod/vfs.h"
#include "extmod/vfs_fat.h"
@@ -96,7 +97,7 @@ STATIC pyb_thread_t pyb_thread_main;
#ifndef MICROPY_HW_UART_REPL_RXBUF
#define MICROPY_HW_UART_REPL_RXBUF (260)
#endif
-STATIC pyb_uart_obj_t pyb_uart_repl_obj;
+STATIC machine_uart_obj_t pyb_uart_repl_obj;
STATIC uint8_t pyb_uart_repl_rxbuf[MICROPY_HW_UART_REPL_RXBUF];
#endif
@@ -431,7 +432,7 @@ void stm32_main(uint32_t reset_mode) {
#if defined(MICROPY_HW_UART_REPL)
// Set up a UART REPL using a statically allocated object
- pyb_uart_repl_obj.base.type = &pyb_uart_type;
+ pyb_uart_repl_obj.base.type = &machine_uart_type;
pyb_uart_repl_obj.uart_id = MICROPY_HW_UART_REPL;
pyb_uart_repl_obj.is_static = true;
pyb_uart_repl_obj.timeout = 0;
@@ -439,7 +440,7 @@ void stm32_main(uint32_t reset_mode) {
uart_init(&pyb_uart_repl_obj, MICROPY_HW_UART_REPL_BAUD, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, 0);
uart_set_rxbuf(&pyb_uart_repl_obj, sizeof(pyb_uart_repl_rxbuf), pyb_uart_repl_rxbuf);
uart_attach_to_repl(&pyb_uart_repl_obj, true);
- MP_STATE_PORT(pyb_uart_obj_all)[MICROPY_HW_UART_REPL - 1] = &pyb_uart_repl_obj;
+ MP_STATE_PORT(machine_uart_obj_all)[MICROPY_HW_UART_REPL - 1] = &pyb_uart_repl_obj;
MP_STATE_PORT(pyb_stdio_uart) = &pyb_uart_repl_obj;
#endif
diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c
index 070d0e116..3bbac6687 100644
--- a/ports/stm32/modmachine.c
+++ b/ports/stm32/modmachine.c
@@ -448,7 +448,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
#if MICROPY_PY_MACHINE_I2S
{ MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) },
#endif
- { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
+ #if MICROPY_PY_MACHINE_UART
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
#if MICROPY_PY_MACHINE_WDT
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&machine_wdt_type) },
#endif
diff --git a/ports/stm32/modos.c b/ports/stm32/modos.c
index 43543aa55..bd0101cab 100644
--- a/ports/stm32/modos.c
+++ b/ports/stm32/modos.c
@@ -25,6 +25,7 @@
*/
#include "py/runtime.h"
+#include "extmod/modmachine.h"
#include "rng.h"
#include "usb.h"
#include "uart.h"
@@ -47,7 +48,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_os_urandom_obj, mp_os_urandom);
bool mp_os_dupterm_is_builtin_stream(mp_const_obj_t stream) {
const mp_obj_type_t *type = mp_obj_get_type(stream);
- return type == &pyb_uart_type
+ return type == &machine_uart_type
#if MICROPY_HW_ENABLE_USB
|| type == &pyb_usb_vcp_type
#endif
@@ -55,7 +56,7 @@ bool mp_os_dupterm_is_builtin_stream(mp_const_obj_t stream) {
}
void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached) {
- if (mp_obj_get_type(stream_detached) == &pyb_uart_type) {
+ if (mp_obj_get_type(stream_detached) == &machine_uart_type) {
uart_attach_to_repl(MP_OBJ_TO_PTR(stream_detached), false);
}
#if MICROPY_HW_ENABLE_USB
@@ -64,7 +65,7 @@ void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t s
}
#endif
- if (mp_obj_get_type(stream_attached) == &pyb_uart_type) {
+ if (mp_obj_get_type(stream_attached) == &machine_uart_type) {
uart_attach_to_repl(MP_OBJ_TO_PTR(stream_attached), true);
}
#if MICROPY_HW_ENABLE_USB
diff --git a/ports/stm32/modpyb.c b/ports/stm32/modpyb.c
index 831ece74a..0bf2d6a2c 100644
--- a/ports/stm32/modpyb.c
+++ b/ports/stm32/modpyb.c
@@ -52,6 +52,7 @@
#include "usb.h"
#include "portmodules.h"
#include "modmachine.h"
+#include "extmod/modmachine.h"
#include "extmod/modnetwork.h"
#include "extmod/vfs.h"
#include "extmod/modtime.h"
@@ -103,7 +104,7 @@ STATIC mp_obj_t pyb_repl_uart(size_t n_args, const mp_obj_t *args) {
uart_attach_to_repl(MP_STATE_PORT(pyb_stdio_uart), false);
MP_STATE_PORT(pyb_stdio_uart) = NULL;
}
- } else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
+ } else if (mp_obj_get_type(args[0]) == &machine_uart_type) {
MP_STATE_PORT(pyb_stdio_uart) = MP_OBJ_TO_PTR(args[0]);
uart_attach_to_repl(MP_STATE_PORT(pyb_stdio_uart), true);
} else {
@@ -232,7 +233,7 @@ STATIC const mp_rom_map_elem_t pyb_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&pyb_i2c_type) },
#endif
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_spi_type) },
- { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
#if MICROPY_HW_ENABLE_CAN
{ MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&pyb_can_type) },
#endif
diff --git a/ports/stm32/mpbthciport.c b/ports/stm32/mpbthciport.c
index fe061a124..e764c6984 100644
--- a/ports/stm32/mpbthciport.c
+++ b/ports/stm32/mpbthciport.c
@@ -150,9 +150,10 @@ int mp_bluetooth_hci_uart_readpacket(mp_bluetooth_hci_uart_readchar_t handler) {
/******************************************************************************/
// HCI over UART
+#include "extmod/modmachine.h"
#include "uart.h"
-pyb_uart_obj_t mp_bluetooth_hci_uart_obj;
+machine_uart_obj_t mp_bluetooth_hci_uart_obj;
mp_irq_obj_t mp_bluetooth_hci_uart_irq_obj;
static uint8_t hci_uart_rxbuf[768];
@@ -169,13 +170,13 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) {
DEBUG_printf("mp_bluetooth_hci_uart_init (stm32)\n");
// bits (8), stop (1), parity (none) and flow (rts/cts) are assumed to match MYNEWT_VAL_BLE_HCI_UART_ constants in syscfg.h.
- mp_bluetooth_hci_uart_obj.base.type = &pyb_uart_type;
+ mp_bluetooth_hci_uart_obj.base.type = &machine_uart_type;
mp_bluetooth_hci_uart_obj.uart_id = port;
mp_bluetooth_hci_uart_obj.is_static = true;
// We don't want to block indefinitely, but expect flow control is doing its job.
mp_bluetooth_hci_uart_obj.timeout = 200;
mp_bluetooth_hci_uart_obj.timeout_char = 200;
- MP_STATE_PORT(pyb_uart_obj_all)[mp_bluetooth_hci_uart_obj.uart_id - 1] = &mp_bluetooth_hci_uart_obj;
+ MP_STATE_PORT(machine_uart_obj_all)[mp_bluetooth_hci_uart_obj.uart_id - 1] = &mp_bluetooth_hci_uart_obj;
// Initialise the UART.
uart_init(&mp_bluetooth_hci_uart_obj, baudrate, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, UART_HWCONTROL_RTS | UART_HWCONTROL_CTS);
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 0cb929f55..00ded86e1 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -128,6 +128,11 @@
#define MICROPY_PY_MACHINE_SPI_LSB (SPI_FIRSTBIT_LSB)
#define MICROPY_PY_MACHINE_SOFTSPI (1)
#define MICROPY_PY_MACHINE_TIMER (1)
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/stm32/machine_uart.c"
+#define MICROPY_PY_MACHINE_UART_IRQ (1)
+#define MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR (1)
+#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#define MICROPY_PY_MACHINE_WDT (1)
#define MICROPY_PY_MACHINE_WDT_INCLUDEFILE "ports/stm32/machine_wdt.c"
#endif
diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c
index 8edafa9bf..f8a5d66fc 100644
--- a/ports/stm32/mphalport.c
+++ b/ports/stm32/mphalport.c
@@ -182,4 +182,4 @@ void mp_hal_get_mac_ascii(int idx, size_t chr_off, size_t chr_len, char *dest) {
}
}
-MP_REGISTER_ROOT_POINTER(struct _pyb_uart_obj_t *pyb_stdio_uart);
+MP_REGISTER_ROOT_POINTER(struct _machine_uart_obj_t *pyb_stdio_uart);
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 908361874..0d648a6fc 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -117,12 +117,12 @@
#endif
-typedef struct _pyb_uart_irq_map_t {
+typedef struct _machine_uart_irq_map_t {
uint16_t irq_en;
uint16_t flag;
-} pyb_uart_irq_map_t;
+} machine_uart_irq_map_t;
-STATIC const pyb_uart_irq_map_t mp_uart_irq_map[] = {
+STATIC const machine_uart_irq_map_t mp_uart_irq_map[] = {
{ USART_CR1_IDLEIE, UART_FLAG_IDLE}, // RX idle
{ USART_CR1_PEIE, UART_FLAG_PE}, // parity error
#if defined(STM32G0) || defined(STM32WL)
@@ -162,18 +162,18 @@ void uart_init0(void) {
// unregister all interrupt sources
void uart_deinit_all(void) {
- for (int i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all)); i++) {
- pyb_uart_obj_t *uart_obj = MP_STATE_PORT(pyb_uart_obj_all)[i];
+ for (int i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(machine_uart_obj_all)); i++) {
+ machine_uart_obj_t *uart_obj = MP_STATE_PORT(machine_uart_obj_all)[i];
if (uart_obj != NULL && !uart_obj->is_static) {
uart_deinit(uart_obj);
- MP_STATE_PORT(pyb_uart_obj_all)[i] = NULL;
+ MP_STATE_PORT(machine_uart_obj_all)[i] = NULL;
}
}
}
bool uart_exists(int uart_id) {
- if (uart_id > MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all))) {
- // safeguard against pyb_uart_obj_all array being configured too small
+ if (uart_id > MP_ARRAY_SIZE(MP_STATE_PORT(machine_uart_obj_all))) {
+ // safeguard against machine_uart_obj_all array being configured too small
return false;
}
switch (uart_id) {
@@ -243,7 +243,7 @@ bool uart_exists(int uart_id) {
}
// assumes Init parameters have been set up correctly
-bool uart_init(pyb_uart_obj_t *uart_obj,
+bool uart_init(machine_uart_obj_t *uart_obj,
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow) {
USART_TypeDef *UARTx;
IRQn_Type irqn;
@@ -641,7 +641,7 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
return true;
}
-void uart_irq_config(pyb_uart_obj_t *self, bool enable) {
+void uart_irq_config(machine_uart_obj_t *self, bool enable) {
if (self->mp_irq_trigger) {
for (size_t entry = 0; entry < MP_ARRAY_SIZE(mp_uart_irq_map); ++entry) {
if (mp_uart_irq_map[entry].flag & MP_UART_RESERVED_FLAGS) {
@@ -658,7 +658,7 @@ void uart_irq_config(pyb_uart_obj_t *self, bool enable) {
}
}
-void uart_set_rxbuf(pyb_uart_obj_t *self, size_t len, void *buf) {
+void uart_set_rxbuf(machine_uart_obj_t *self, size_t len, void *buf) {
self->read_buf_head = 0;
self->read_buf_tail = 0;
self->read_buf_len = len;
@@ -670,7 +670,7 @@ void uart_set_rxbuf(pyb_uart_obj_t *self, size_t len, void *buf) {
}
}
-void uart_deinit(pyb_uart_obj_t *self) {
+void uart_deinit(machine_uart_obj_t *self) {
self->is_enabled = false;
// Disable UART
@@ -809,11 +809,11 @@ void uart_deinit(pyb_uart_obj_t *self) {
}
}
-void uart_attach_to_repl(pyb_uart_obj_t *self, bool attached) {
+void uart_attach_to_repl(machine_uart_obj_t *self, bool attached) {
self->attached_to_repl = attached;
}
-uint32_t uart_get_source_freq(pyb_uart_obj_t *self) {
+uint32_t uart_get_source_freq(machine_uart_obj_t *self) {
uint32_t uart_clk = 0;
#if defined(STM32F0) || defined(STM32G0)
@@ -921,7 +921,7 @@ uint32_t uart_get_source_freq(pyb_uart_obj_t *self) {
return uart_clk;
}
-uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
+uint32_t uart_get_baudrate(machine_uart_obj_t *self) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
return LL_LPUART_GetBaudRate(self->uartx, uart_get_source_freq(self)
@@ -938,7 +938,7 @@ uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
LL_USART_OVERSAMPLING_16);
}
-void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
+void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
LL_LPUART_SetBaudRate(self->uartx, uart_get_source_freq(self),
@@ -956,7 +956,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
LL_USART_OVERSAMPLING_16, baudrate);
}
-mp_uint_t uart_rx_any(pyb_uart_obj_t *self) {
+mp_uint_t uart_rx_any(machine_uart_obj_t *self) {
int buffer_bytes = self->read_buf_head - self->read_buf_tail;
if (buffer_bytes < 0) {
return buffer_bytes + self->read_buf_len;
@@ -970,7 +970,7 @@ mp_uint_t uart_rx_any(pyb_uart_obj_t *self) {
// Waits at most timeout milliseconds for at least 1 char to become ready for
// reading (from buf or for direct reading).
// Returns true if something available, false if not.
-bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
+bool uart_rx_wait(machine_uart_obj_t *self, uint32_t timeout) {
uint32_t start = HAL_GetTick();
for (;;) {
if (self->read_buf_tail != self->read_buf_head || UART_RXNE_IS_SET(self->uartx)) {
@@ -984,7 +984,7 @@ bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
}
// assumes there is a character available
-int uart_rx_char(pyb_uart_obj_t *self) {
+int uart_rx_char(machine_uart_obj_t *self) {
if (self->read_buf_tail != self->read_buf_head) {
// buffering via IRQ
int data;
@@ -1023,7 +1023,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
// Waits at most timeout milliseconds for TX register to become empty.
// Returns true if can write, false if can't.
-bool uart_tx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
+bool uart_tx_wait(machine_uart_obj_t *self, uint32_t timeout) {
uint32_t start = HAL_GetTick();
for (;;) {
if (uart_tx_avail(self)) {
@@ -1038,7 +1038,7 @@ bool uart_tx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
// Waits at most timeout milliseconds for UART flag to be set.
// Returns true if flag is/was set, false on timeout.
-STATIC bool uart_wait_flag_set(pyb_uart_obj_t *self, uint32_t flag, uint32_t timeout) {
+STATIC bool uart_wait_flag_set(machine_uart_obj_t *self, uint32_t flag, uint32_t timeout) {
// Note: we don't use WFI to idle in this loop because UART tx doesn't generate
// an interrupt and the flag can be set quickly if the baudrate is large.
uint32_t start = HAL_GetTick();
@@ -1062,7 +1062,7 @@ STATIC bool uart_wait_flag_set(pyb_uart_obj_t *self, uint32_t flag, uint32_t tim
// num_chars - number of characters to send (9-bit chars count for 2 bytes from src)
// *errcode - returns 0 for success, MP_Exxx on error
// returns the number of characters sent (valid even if there was an error)
-size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_chars, int *errcode) {
+size_t uart_tx_data(machine_uart_obj_t *self, const void *src_in, size_t num_chars, int *errcode) {
if (num_chars == 0) {
*errcode = 0;
return 0;
@@ -1124,7 +1124,7 @@ size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_chars,
return num_tx;
}
-void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
+void uart_tx_strn(machine_uart_obj_t *uart_obj, const char *str, uint len) {
int errcode;
uart_tx_data(uart_obj, str, len, &errcode);
}
@@ -1135,7 +1135,7 @@ void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
// - On STM32F4 the IRQ flags are cleared by reading SR then DR.
void uart_irq_handler(mp_uint_t uart_id) {
// get the uart object
- pyb_uart_obj_t *self = MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1];
+ machine_uart_obj_t *self = MP_STATE_PORT(machine_uart_obj_all)[uart_id - 1];
if (self == NULL) {
// UART object has not been set, so we can't do anything, not
@@ -1216,7 +1216,7 @@ void uart_irq_handler(mp_uint_t uart_id) {
}
STATIC mp_uint_t uart_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uart_irq_config(self, false);
self->mp_irq_trigger = new_trigger;
uart_irq_config(self, true);
@@ -1224,7 +1224,7 @@ STATIC mp_uint_t uart_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) {
}
STATIC mp_uint_t uart_irq_info(mp_obj_t self_in, mp_uint_t info_type) {
- pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (info_type == MP_IRQ_INFO_FLAGS) {
return self->mp_irq_flags;
} else if (info_type == MP_IRQ_INFO_TRIGGERS) {
@@ -1238,4 +1238,4 @@ const mp_irq_methods_t uart_irq_methods = {
.info = uart_irq_info,
};
-MP_REGISTER_ROOT_POINTER(struct _pyb_uart_obj_t *pyb_uart_obj_all[MICROPY_HW_MAX_UART + MICROPY_HW_MAX_LPUART]);
+MP_REGISTER_ROOT_POINTER(struct _machine_uart_obj_t *machine_uart_obj_all[MICROPY_HW_MAX_UART + MICROPY_HW_MAX_LPUART]);
diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h
index 61d1ac439..956cbb044 100644
--- a/ports/stm32/uart.h
+++ b/ports/stm32/uart.h
@@ -57,7 +57,7 @@ typedef enum {
// OR-ed IRQ flags which should not be touched by the user
#define MP_UART_RESERVED_FLAGS UART_FLAG_RXNE
-typedef struct _pyb_uart_obj_t {
+typedef struct _machine_uart_obj_t {
mp_obj_base_t base;
USART_TypeDef *uartx;
pyb_uart_t uart_id : 8;
@@ -75,34 +75,33 @@ typedef struct _pyb_uart_obj_t {
uint16_t mp_irq_trigger; // user IRQ trigger mask
uint16_t mp_irq_flags; // user IRQ active IRQ flags
mp_irq_obj_t *mp_irq_obj; // user IRQ object
-} pyb_uart_obj_t;
+} machine_uart_obj_t;
-extern const mp_obj_type_t pyb_uart_type;
extern const mp_irq_methods_t uart_irq_methods;
void uart_init0(void);
void uart_deinit_all(void);
bool uart_exists(int uart_id);
-bool uart_init(pyb_uart_obj_t *uart_obj,
+bool uart_init(machine_uart_obj_t *uart_obj,
uint32_t baudrate, uint32_t bits, uint32_t parity, uint32_t stop, uint32_t flow);
-void uart_irq_config(pyb_uart_obj_t *self, bool enable);
-void uart_set_rxbuf(pyb_uart_obj_t *self, size_t len, void *buf);
-void uart_deinit(pyb_uart_obj_t *uart_obj);
+void uart_irq_config(machine_uart_obj_t *self, bool enable);
+void uart_set_rxbuf(machine_uart_obj_t *self, size_t len, void *buf);
+void uart_deinit(machine_uart_obj_t *uart_obj);
void uart_irq_handler(mp_uint_t uart_id);
-void uart_attach_to_repl(pyb_uart_obj_t *self, bool attached);
-uint32_t uart_get_source_freq(pyb_uart_obj_t *self);
-uint32_t uart_get_baudrate(pyb_uart_obj_t *self);
-void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate);
+void uart_attach_to_repl(machine_uart_obj_t *self, bool attached);
+uint32_t uart_get_source_freq(machine_uart_obj_t *self);
+uint32_t uart_get_baudrate(machine_uart_obj_t *self);
+void uart_set_baudrate(machine_uart_obj_t *self, uint32_t baudrate);
-mp_uint_t uart_rx_any(pyb_uart_obj_t *uart_obj);
-bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout);
-int uart_rx_char(pyb_uart_obj_t *uart_obj);
-bool uart_tx_wait(pyb_uart_obj_t *self, uint32_t timeout);
-size_t uart_tx_data(pyb_uart_obj_t *self, const void *src_in, size_t num_chars, int *errcode);
-void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
+mp_uint_t uart_rx_any(machine_uart_obj_t *uart_obj);
+bool uart_rx_wait(machine_uart_obj_t *self, uint32_t timeout);
+int uart_rx_char(machine_uart_obj_t *uart_obj);
+bool uart_tx_wait(machine_uart_obj_t *self, uint32_t timeout);
+size_t uart_tx_data(machine_uart_obj_t *self, const void *src_in, size_t num_chars, int *errcode);
+void uart_tx_strn(machine_uart_obj_t *uart_obj, const char *str, uint len);
-static inline bool uart_tx_avail(pyb_uart_obj_t *self) {
+static inline bool uart_tx_avail(machine_uart_obj_t *self) {
#if defined(STM32F4) || defined(STM32L1)
return self->uartx->SR & USART_SR_TXE;
#elif defined(STM32G0) || defined(STM32H7) || defined(STM32WL)
diff --git a/ports/zephyr/CMakeLists.txt b/ports/zephyr/CMakeLists.txt
index ddc613a2c..8834aae96 100644
--- a/ports/zephyr/CMakeLists.txt
+++ b/ports/zephyr/CMakeLists.txt
@@ -40,7 +40,6 @@ set(MICROPY_SOURCE_PORT
machine_i2c.c
machine_spi.c
machine_pin.c
- machine_uart.c
modbluetooth_zephyr.c
modmachine.c
modsocket.c
diff --git a/ports/zephyr/machine_uart.c b/ports/zephyr/machine_uart.c
index b989c0f48..2c4b3a470 100644
--- a/ports/zephyr/machine_uart.c
+++ b/ports/zephyr/machine_uart.c
@@ -25,18 +25,16 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
#include <zephyr/zephyr.h>
#include <zephyr/drivers/uart.h>
-#include "py/runtime.h"
-#include "py/stream.h"
#include "py/mperrno.h"
-#include "py/objstr.h"
-#include "modmachine.h"
+
+// The UART class doesn't have any constants for this port.
+#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS
typedef struct _machine_uart_obj_t {
mp_obj_base_t base;
@@ -50,7 +48,7 @@ STATIC const char *_stop_bits_name[] = {"0.5", "1", "1.5", "2"};
STATIC const char *_data_bits_name[] = {"5", "6", "7", "8", "9"};
STATIC const char *_flow_control_name[] = {"None", "RTS/CTS", "DTR/DSR"};
-STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+STATIC void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
struct uart_config config;
uart_config_get(self->dev, &config);
@@ -60,7 +58,7 @@ STATIC void machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_pri
self->timeout, self->timeout_char);
}
-STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+STATIC void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_timeout, ARG_timeout_char };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
@@ -73,7 +71,7 @@ STATIC void machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, co
self->timeout_char = args[ARG_timeout_char].u_int;
}
-STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
machine_uart_obj_t *self = mp_obj_malloc(machine_uart_obj_t, &machine_uart_type);
@@ -84,20 +82,26 @@ STATIC mp_obj_t machine_uart_make_new(const mp_obj_type_t *type, size_t n_args,
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
+ mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
-STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
- { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
- { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
- { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
-};
-STATIC MP_DEFINE_CONST_DICT(machine_uart_locals_dict, machine_uart_locals_dict_table);
+STATIC void mp_machine_uart_deinit(machine_uart_obj_t *self) {
+ (void)self;
+}
+
+STATIC mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
+ (void)self;
+ mp_raise_NotImplementedError(NULL); // TODO
+}
-STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
+STATIC bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
+ (void)self;
+ mp_raise_NotImplementedError(NULL); // TODO
+}
+
+STATIC mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t *buffer = (uint8_t *)buf_in;
uint8_t data;
@@ -118,7 +122,7 @@ STATIC mp_uint_t machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t siz
return bytes_read;
}
-STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t *buffer = (uint8_t *)buf_in;
@@ -129,7 +133,7 @@ STATIC mp_uint_t machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uin
return size;
}
-STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
+STATIC mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
mp_uint_t ret;
if (request == MP_STREAM_POLL) {
@@ -146,20 +150,3 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr
}
return ret;
}
-
-STATIC const mp_stream_p_t uart_stream_p = {
- .read = machine_uart_read,
- .write = machine_uart_write,
- .ioctl = machine_uart_ioctl,
- .is_text = false,
-};
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_uart_type,
- MP_QSTR_UART,
- MP_TYPE_FLAG_ITER_IS_STREAM,
- make_new, machine_uart_make_new,
- print, machine_uart_print,
- protocol, &uart_stream_p,
- locals_dict, &machine_uart_locals_dict
- );
diff --git a/ports/zephyr/modmachine.c b/ports/zephyr/modmachine.c
index 633416805..14ddf027a 100644
--- a/ports/zephyr/modmachine.c
+++ b/ports/zephyr/modmachine.c
@@ -37,6 +37,7 @@
#include "extmod/machine_pulse.h"
#include "extmod/machine_i2c.h"
#include "extmod/machine_spi.h"
+#include "extmod/modmachine.h"
#include "modmachine.h"
#if MICROPY_PY_MACHINE
@@ -74,7 +75,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
#if MICROPY_PY_MACHINE_SPI
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },
#endif
+ #if MICROPY_PY_MACHINE_UART
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&machine_uart_type) },
+ #endif
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) },
{ MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
diff --git a/ports/zephyr/modmachine.h b/ports/zephyr/modmachine.h
index a605ada0d..520b36396 100644
--- a/ports/zephyr/modmachine.h
+++ b/ports/zephyr/modmachine.h
@@ -6,7 +6,6 @@
extern const mp_obj_type_t machine_pin_type;
extern const mp_obj_type_t machine_i2c_type;
extern const mp_obj_type_t machine_spi_type;
-extern const mp_obj_type_t machine_uart_type;
MP_DECLARE_CONST_FUN_OBJ_0(machine_info_obj);
diff --git a/ports/zephyr/mpconfigport.h b/ports/zephyr/mpconfigport.h
index 2f3e314db..49d00f4ca 100644
--- a/ports/zephyr/mpconfigport.h
+++ b/ports/zephyr/mpconfigport.h
@@ -69,6 +69,8 @@
#define MICROPY_PY_MACHINE_SPI_MSB (SPI_TRANSFER_MSB)
#define MICROPY_PY_MACHINE_SPI_LSB (SPI_TRANSFER_LSB)
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
+#define MICROPY_PY_MACHINE_UART (1)
+#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/zephyr/machine_uart.c"
#define MICROPY_PY_STRUCT (0)
#ifdef CONFIG_NETWORKING
// If we have networking, we likely want errno comfort