diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index a4819798b..2842b2cd9 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -53,8 +53,8 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) { IOMUXC_SetPinConfig(0, 0, 0, 0, periph->pin->cfg_reg, IOMUXC_SW_PAD_CTL_PAD_HYS(0) - | IOMUXC_SW_PAD_CTL_PAD_PUS(0) - | IOMUXC_SW_PAD_CTL_PAD_PUE(0) + | IOMUXC_SW_PAD_CTL_PAD_PUS(1) + | IOMUXC_SW_PAD_CTL_PAD_PUE(1) | IOMUXC_SW_PAD_CTL_PAD_PKE(1) | IOMUXC_SW_PAD_CTL_PAD_ODE(0) | IOMUXC_SW_PAD_CTL_PAD_SPEED(1) @@ -72,9 +72,10 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st } void common_hal_busio_uart_construct(busio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, - uint16_t receiver_buffer_size) { + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, + const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode, + uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size) { // TODO: Allow none rx or tx @@ -111,12 +112,48 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if(self->rx_pin == NULL || self->tx_pin == NULL) { mp_raise_RuntimeError(translate("Invalid UART pin selection")); - } else { - self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1]; } + // Now check for RTS/CTS pin(s) + const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t); + const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t); + + if (rts != mp_const_none) { + for (uint32_t i=0; i < rts_count; ++i) + { + if (mcu_uart_rts_list[i].bank_idx == self->rx_pin->bank_idx) { + if (mcu_uart_rts_list[i].pin == rts) { + self->rts_pin = &mcu_uart_rts_list[i]; + break; + } + } + } + if (self->rts_pin == NULL) + mp_raise_ValueError(translate("Selected RTS pin not valid")); + } + + if (cts != mp_const_none) { + for (uint32_t i=0; i < cts_count; ++i) + { + if (mcu_uart_cts_list[i].bank_idx == self->rx_pin->bank_idx) { + if (mcu_uart_cts_list[i].pin == cts) { + self->cts_pin = &mcu_uart_cts_list[i]; + break; + } + } + } + if (self->cts_pin == NULL) + mp_raise_ValueError(translate("Selected CTS pin not valid")); + } + + self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1]; + config_periph_pin(self->rx_pin); config_periph_pin(self->tx_pin); + if (self->rts_pin) + config_periph_pin(self->rts_pin); + if (self->cts_pin) + config_periph_pin(self->cts_pin); lpuart_config_t config = { 0 }; LPUART_GetDefaultConfig(&config); @@ -125,10 +162,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, config.baudRate_Bps = self->baudrate; config.enableTx = self->tx_pin != NULL; config.enableRx = self->rx_pin != NULL; - + config.enableRxRTS = self->rts_pin != NULL; + config.enableTxCTS = self->cts_pin != NULL; + LPUART_Init(self->uart, &config, UART_CLOCK_FREQ); - claim_pin(self->tx_pin->pin); + if (self->tx_pin != NULL) + claim_pin(self->tx_pin->pin); if (self->rx_pin != NULL) { ringbuf_alloc(&self->rbuf, receiver_buffer_size, true); @@ -203,7 +243,9 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t LPUART_TransferAbortReceive(self->uart, &self->handle); } - return len - self->handle.rxDataSize; + // The only place we can reliably tell how many bytes have been received is from the current + // wp in the handle (because the abort nukes rxDataSize, and reading it before abort is a race.) + return self->handle.rxData-data; } // Write characters. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c index 39e4f0131..0417f29cc 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c @@ -109,53 +109,93 @@ LPUART_Type *mcu_uart_banks[] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, L const mcu_periph_obj_t mcu_uart_rx_list[16] = { PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_23), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_09), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_09), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_23), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_07), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_15), PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_03), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_33), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_11), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_11), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_EMC_33), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_39), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_11), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_11), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_39), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_13), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_01), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_35), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_05), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_05), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_35), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_27), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_03), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_03), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_27), }; const mcu_periph_obj_t mcu_uart_tx_list[16] = { PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_06), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_22), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_08), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_08), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_22), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_06), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_14), PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_02), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_32), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_10), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_10), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_EMC_32), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_38), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_10), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_10), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_38), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_12), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_00), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_34), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_04), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_04), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_34), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_26), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_02), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_26), +}; + +const mcu_periph_obj_t mcu_uart_rts_list[10] = { + PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_09), + + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_21), + PERIPH_PIN(2, 2, 0, 1, &pin_GPIO_AD_B1_07), + + PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_13), + + PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_01), + PERIPH_PIN(4, 2, 0, 1, &pin_GPIO_EMC_31), + + PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_37), + + PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_15), + + PERIPH_PIN(7, 2, 0, 1, &pin_GPIO_SD_B0_03), + + PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_25), +}; + +const mcu_periph_obj_t mcu_uart_cts_list[10] = { + PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_08), + + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 0, &pin_GPIO_AD_B1_06), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 1, &pin_GPIO_EMC_20), + + PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_12), + + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_00), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_30), + + PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_36), + + PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_14), + + PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B0_02), + + PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_24), }; const mcu_pwm_obj_t mcu_pwm_list[39] = { diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h index 1d720f633..ba88ef4c6 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h @@ -37,6 +37,8 @@ extern const mcu_periph_obj_t mcu_spi_miso_list[8]; extern const mcu_periph_obj_t mcu_uart_rx_list[16]; extern const mcu_periph_obj_t mcu_uart_tx_list[16]; +extern const mcu_periph_obj_t mcu_uart_rts_list[10]; +extern const mcu_periph_obj_t mcu_uart_cts_list[10]; extern const mcu_pwm_obj_t mcu_pwm_list[39]; diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 1fc81e78e..529d2d3ce 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -82,7 +82,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co // https://github.com/adafruit/circuitpython/issues/1056) busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; - enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size}; + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, ARG_rts, ARG_cts, ARG_rs485}; static const mp_arg_t allowed_args[] = { { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -92,6 +92,9 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, + { MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_rs485, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -124,7 +127,13 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); validate_timeout(timeout); - common_hal_busio_uart_construct(self, tx, rx, + const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(args[ARG_rts].u_obj); + + const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj); + + bool rs485 = args[ARG_rs485].u_bool; + + common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, args[ARG_baudrate].u_int, bits, parity, stop, timeout, args[ARG_receiver_buffer_size].u_int); return (mp_obj_t)self; diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h index cfd2c800c..1d748ecc7 100644 --- a/shared-bindings/busio/UART.h +++ b/shared-bindings/busio/UART.h @@ -40,9 +40,10 @@ typedef enum { // Construct an underlying UART object. extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, - uint16_t receiver_buffer_size); + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, + const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode, + uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size); extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 914bc4313..05567d7ab 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -100,8 +100,23 @@ mp_obj_t common_hal_board_create_uart(void) { const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX); const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX); +#ifdef DEFAULT_UART_BUS_RTS + const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RTS); +#else + const mcu_pin_obj_t* rts = mp_const_none; +#endif +#ifdef DEFAULT_UART_BUS_CTS + const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_CTS); +#else + const mcu_pin_obj_t* cts = mp_const_none; +#endif +#ifdef DEFAULT_UART_IS_RS485 + const bool rs485 = true; +#else + const bool rs485 = false; +#endif - common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64); + common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, 9600, 8, PARITY_NONE, 1, 1.0f, 64); MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self); return MP_STATE_VM(shared_uart_bus); }