Skip to content

Commit 84ad3d8

Browse files
committed
Addition of RTS/CTS/RS485 UART functionality
1 parent 6f06f92 commit 84ad3d8

File tree

6 files changed

+145
-36
lines changed

6 files changed

+145
-36
lines changed

ports/mimxrt10xx/common-hal/busio/UART.c

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
5353
IOMUXC_SetPinConfig(0, 0, 0, 0,
5454
periph->pin->cfg_reg,
5555
IOMUXC_SW_PAD_CTL_PAD_HYS(0)
56-
| IOMUXC_SW_PAD_CTL_PAD_PUS(0)
57-
| IOMUXC_SW_PAD_CTL_PAD_PUE(0)
56+
| IOMUXC_SW_PAD_CTL_PAD_PUS(1)
57+
| IOMUXC_SW_PAD_CTL_PAD_PUE(1)
5858
| IOMUXC_SW_PAD_CTL_PAD_PKE(1)
5959
| IOMUXC_SW_PAD_CTL_PAD_ODE(0)
6060
| IOMUXC_SW_PAD_CTL_PAD_SPEED(1)
@@ -72,9 +72,10 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st
7272
}
7373

7474
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
75-
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
76-
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
77-
uint16_t receiver_buffer_size) {
75+
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
76+
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode,
77+
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
78+
mp_float_t timeout, uint16_t receiver_buffer_size) {
7879

7980
// TODO: Allow none rx or tx
8081

@@ -111,12 +112,48 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
111112

112113
if(self->rx_pin == NULL || self->tx_pin == NULL) {
113114
mp_raise_RuntimeError(translate("Invalid UART pin selection"));
114-
} else {
115-
self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1];
116115
}
117116

117+
// Now check for RTS/CTS pin(s)
118+
const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t);
119+
const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t);
120+
121+
if (rts != mp_const_none) {
122+
for (uint32_t i=0; i < rts_count; ++i)
123+
{
124+
if (mcu_uart_rts_list[i].bank_idx == self->rx_pin->bank_idx) {
125+
if (mcu_uart_rts_list[i].pin == rts) {
126+
self->rts_pin = &mcu_uart_rts_list[i];
127+
break;
128+
}
129+
}
130+
}
131+
if (self->rts_pin == NULL)
132+
mp_raise_ValueError(translate("Selected RTS pin not valid"));
133+
}
134+
135+
if (cts != mp_const_none) {
136+
for (uint32_t i=0; i < cts_count; ++i)
137+
{
138+
if (mcu_uart_cts_list[i].bank_idx == self->rx_pin->bank_idx) {
139+
if (mcu_uart_cts_list[i].pin == cts) {
140+
self->cts_pin = &mcu_uart_cts_list[i];
141+
break;
142+
}
143+
}
144+
}
145+
if (self->cts_pin == NULL)
146+
mp_raise_ValueError(translate("Selected CTS pin not valid"));
147+
}
148+
149+
self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1];
150+
118151
config_periph_pin(self->rx_pin);
119152
config_periph_pin(self->tx_pin);
153+
if (self->rts_pin)
154+
config_periph_pin(self->rts_pin);
155+
if (self->cts_pin)
156+
config_periph_pin(self->cts_pin);
120157

121158
lpuart_config_t config = { 0 };
122159
LPUART_GetDefaultConfig(&config);
@@ -125,10 +162,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
125162
config.baudRate_Bps = self->baudrate;
126163
config.enableTx = self->tx_pin != NULL;
127164
config.enableRx = self->rx_pin != NULL;
128-
165+
config.enableRxRTS = self->rts_pin != NULL;
166+
config.enableTxCTS = self->cts_pin != NULL;
167+
129168
LPUART_Init(self->uart, &config, UART_CLOCK_FREQ);
130169

131-
claim_pin(self->tx_pin->pin);
170+
if (self->tx_pin != NULL)
171+
claim_pin(self->tx_pin->pin);
132172

133173
if (self->rx_pin != NULL) {
134174
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
203243
LPUART_TransferAbortReceive(self->uart, &self->handle);
204244
}
205245

206-
return len - self->handle.rxDataSize;
246+
// The only place we can reliably tell how many bytes have been received is from the current
247+
// wp in the handle (because the abort nukes rxDataSize, and reading it before abort is a race.)
248+
return self->handle.rxData-data;
207249
}
208250

209251
// Write characters.

ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,53 +109,93 @@ LPUART_Type *mcu_uart_banks[] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, L
109109
const mcu_periph_obj_t mcu_uart_rx_list[16] = {
110110
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07),
111111

112-
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_23),
113-
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_09),
112+
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_09),
113+
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_23),
114114

115115
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_07),
116116
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_15),
117117

118118
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_03),
119-
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_33),
120-
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_11),
119+
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_11),
120+
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_EMC_33),
121121

122-
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_39),
123-
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_11),
122+
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_11),
123+
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_39),
124124

125125
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_13),
126126
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_01),
127127

128-
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_35),
129-
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_05),
128+
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_05),
129+
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_35),
130130

131-
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_27),
132-
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_03),
131+
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_03),
132+
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_27),
133133
};
134134

135135
const mcu_periph_obj_t mcu_uart_tx_list[16] = {
136136
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_06),
137137

138-
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_22),
139-
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_08),
138+
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_08),
139+
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_22),
140140

141141
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_06),
142142
PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_14),
143143

144144
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_02),
145-
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_32),
146-
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_10),
145+
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_10),
146+
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_EMC_32),
147147

148-
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_38),
149-
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_10),
148+
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_10),
149+
PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_38),
150150

151151
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_12),
152152
PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_00),
153153

154-
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_34),
155-
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_04),
154+
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_04),
155+
PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_34),
156156

157-
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_26),
158-
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02),
157+
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_02),
158+
PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_26),
159+
};
160+
161+
const mcu_periph_obj_t mcu_uart_rts_list[10] = {
162+
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_09),
163+
164+
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_21),
165+
PERIPH_PIN(2, 2, 0, 1, &pin_GPIO_AD_B1_07),
166+
167+
PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_13),
168+
169+
PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_01),
170+
PERIPH_PIN(4, 2, 0, 1, &pin_GPIO_EMC_31),
171+
172+
PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_37),
173+
174+
PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_15),
175+
176+
PERIPH_PIN(7, 2, 0, 1, &pin_GPIO_SD_B0_03),
177+
178+
PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_25),
179+
};
180+
181+
const mcu_periph_obj_t mcu_uart_cts_list[10] = {
182+
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_08),
183+
184+
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 0, &pin_GPIO_AD_B1_06),
185+
PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 1, &pin_GPIO_EMC_20),
186+
187+
PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_12),
188+
189+
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_00),
190+
PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_30),
191+
192+
PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_36),
193+
194+
PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_14),
195+
196+
PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B0_02),
197+
198+
PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_24),
159199
};
160200

161201
const mcu_pwm_obj_t mcu_pwm_list[39] = {

ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ extern const mcu_periph_obj_t mcu_spi_miso_list[8];
3737

3838
extern const mcu_periph_obj_t mcu_uart_rx_list[16];
3939
extern const mcu_periph_obj_t mcu_uart_tx_list[16];
40+
extern const mcu_periph_obj_t mcu_uart_rts_list[10];
41+
extern const mcu_periph_obj_t mcu_uart_cts_list[10];
4042

4143
extern const mcu_pwm_obj_t mcu_pwm_list[39];
4244

shared-bindings/busio/UART.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co
8282
// https://github.com/adafruit/circuitpython/issues/1056)
8383
busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t);
8484
self->base.type = &busio_uart_type;
85-
enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size};
85+
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};
8686
static const mp_arg_t allowed_args[] = {
8787
{ MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ },
8888
{ 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
9292
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
9393
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
9494
{ MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
95+
{ MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
96+
{ MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
97+
{ MP_QSTR_rs485, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } },
9598
};
9699
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
97100
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
124127
mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
125128
validate_timeout(timeout);
126129

127-
common_hal_busio_uart_construct(self, tx, rx,
130+
const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(args[ARG_rts].u_obj);
131+
132+
const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj);
133+
134+
bool rs485 = args[ARG_rs485].u_bool;
135+
136+
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485,
128137
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
129138
args[ARG_receiver_buffer_size].u_int);
130139
return (mp_obj_t)self;

shared-bindings/busio/UART.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ typedef enum {
4040

4141
// Construct an underlying UART object.
4242
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
43-
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
44-
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
45-
uint16_t receiver_buffer_size);
43+
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
44+
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode,
45+
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
46+
mp_float_t timeout, uint16_t receiver_buffer_size);
4647

4748
extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self);
4849
extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self);

shared-module/board/__init__.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,23 @@ mp_obj_t common_hal_board_create_uart(void) {
100100

101101
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
102102
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
103+
#ifdef DEFAULT_UART_BUS_RTS
104+
const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RTS);
105+
#else
106+
const mcu_pin_obj_t* rts = mp_const_none;
107+
#endif
108+
#ifdef DEFAULT_UART_BUS_CTS
109+
const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_CTS);
110+
#else
111+
const mcu_pin_obj_t* cts = mp_const_none;
112+
#endif
113+
#ifdef DEFAULT_UART_IS_RS485
114+
const bool rs485 = true;
115+
#else
116+
const bool rs485 = false;
117+
#endif
103118

104-
common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
119+
common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
105120
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
106121
return MP_STATE_VM(shared_uart_bus);
107122
}

0 commit comments

Comments
 (0)