Skip to content

Commit b71ea29

Browse files
authored
Merge pull request #6330 from KurtE/rp2040_uart_rs485
[RP2040] Allow any GPIO pin for RS485 direction pin
2 parents a7ec8b0 + 1fad381 commit b71ea29

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

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

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,6 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
112112
mp_raise_ValueError(translate("Invalid buffer size"));
113113
}
114114

115-
if ((rs485_dir != NULL) || (rs485_invert)) {
116-
mp_raise_NotImplementedError(translate("RS485 Not yet supported on this device"));
117-
}
118-
119115
uint8_t uart_id = ((((tx != NULL) ? tx->number : rx->number) + 4) / 8) % NUM_UARTS;
120116

121117
if (uart_status[uart_id] != STATUS_FREE) {
@@ -126,6 +122,29 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
126122
self->rx_pin = pin_init(uart_id, rx, 1);
127123
self->cts_pin = pin_init(uart_id, cts, 2);
128124
self->rts_pin = pin_init(uart_id, rts, 3);
125+
126+
if (rs485_dir != NULL) {
127+
uint8_t pin = rs485_dir->number;
128+
self->rs485_dir_pin = pin;
129+
self->rs485_invert = rs485_invert;
130+
131+
gpio_init(pin);
132+
133+
claim_pin(rs485_dir);
134+
135+
gpio_disable_pulls(pin);
136+
137+
// Turn on "strong" pin driving (more current available).
138+
hw_write_masked(&padsbank0_hw->io[pin],
139+
PADS_BANK0_GPIO0_DRIVE_VALUE_12MA << PADS_BANK0_GPIO0_DRIVE_LSB,
140+
PADS_BANK0_GPIO0_DRIVE_BITS);
141+
142+
gpio_put(self->rs485_dir_pin, rs485_invert);
143+
gpio_set_dir(self->rs485_dir_pin, GPIO_OUT);
144+
} else {
145+
self->rs485_dir_pin = NO_PIN;
146+
}
147+
129148
uart_status[uart_id] = STATUS_BUSY;
130149

131150

@@ -179,10 +198,12 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
179198
reset_pin_number(self->rx_pin);
180199
reset_pin_number(self->cts_pin);
181200
reset_pin_number(self->rts_pin);
201+
reset_pin_number(self->rs485_dir_pin);
182202
self->tx_pin = NO_PIN;
183203
self->rx_pin = NO_PIN;
184204
self->cts_pin = NO_PIN;
185205
self->rts_pin = NO_PIN;
206+
self->rs485_dir_pin = NO_PIN;
186207
}
187208

188209
// Write characters.
@@ -191,6 +212,11 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
191212
mp_raise_ValueError(translate("No TX pin"));
192213
}
193214

215+
if (self->rs485_dir_pin != NO_PIN) {
216+
uart_tx_wait_blocking(self->uart);
217+
gpio_put(self->rs485_dir_pin, !self->rs485_invert);
218+
}
219+
194220
size_t left_to_write = len;
195221
while (left_to_write > 0) {
196222
while (uart_is_writable(self->uart) && left_to_write > 0) {
@@ -201,7 +227,10 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
201227
}
202228
RUN_BACKGROUND_TASKS;
203229
}
204-
230+
if (self->rs485_dir_pin != NO_PIN) {
231+
uart_tx_wait_blocking(self->uart);
232+
gpio_put(self->rs485_dir_pin, self->rs485_invert);
233+
}
205234
return len;
206235
}
207236

ports/raspberrypi/common-hal/busio/UART.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ typedef struct {
3737
uint8_t tx_pin;
3838
uint8_t rx_pin;
3939
uint8_t cts_pin;
40+
uint8_t rs485_dir_pin;
41+
bool rs485_invert;
4042
uint8_t rts_pin;
4143
uint8_t uart_id;
4244
uint8_t uart_irq_id;

0 commit comments

Comments
 (0)