summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2021-02-01 19:38:16 -0800
committerGitHub <noreply@github.com>2021-02-01 19:38:16 -0800
commitced3dc70fff6049702a409d359850ecd89672192 (patch)
tree95d3c4e8a00d6203ce8b61f1dc430e989aa0e8bf
parentdb7a9628023f115bcf7310e65261ae956e6139e5 (diff)
parent745ba01768e4f72fcd47c39a8a719f982772ca61 (diff)
Merge pull request #4018 from iot49/cp-flow
add uart hardware flow control to nrf port
-rw-r--r--locale/circuitpython.pot6
-rw-r--r--ports/nrf/boards/simmel/mpconfigboard.mk3
-rw-r--r--ports/nrf/common-hal/busio/UART.c62
-rw-r--r--ports/nrf/common-hal/busio/UART.h5
4 files changed, 66 insertions, 10 deletions
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 8443fb85b..e75a36459 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -1793,6 +1793,10 @@ msgstr ""
msgid "RNG Init Error"
msgstr ""
+#: ports/nrf/common-hal/busio/UART.c
+msgid "RS485 Not yet supported on this device"
+msgstr ""
+
#: ports/esp32s2/common-hal/busio/UART.c
#: ports/mimxrt10xx/common-hal/busio/UART.c
msgid "RS485 inversion specified when not in RS485 mode"
@@ -1808,7 +1812,7 @@ msgid "RTC is not supported on this board"
msgstr ""
#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c
-#: ports/nrf/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c
+#: ports/stm/common-hal/busio/UART.c
msgid "RTS/CTS/RS485 Not yet supported on this device"
msgstr ""
diff --git a/ports/nrf/boards/simmel/mpconfigboard.mk b/ports/nrf/boards/simmel/mpconfigboard.mk
index 032caac40..6bc05a7f0 100644
--- a/ports/nrf/boards/simmel/mpconfigboard.mk
+++ b/ports/nrf/boards/simmel/mpconfigboard.mk
@@ -3,6 +3,8 @@ USB_PID = 0xc051
USB_PRODUCT = "Simmel"
USB_MANUFACTURER = "Betrusted"
+CIRCUITPY_DEVICES="CDC,MSC,HID"
+
MCU_CHIP = nrf52833
# SPI_FLASH_FILESYSTEM = 1
@@ -29,6 +31,7 @@ CIRCUITPY_RTC = 1
CIRCUITPY_SDCARDIO = 0
CIRCUITPY_TOUCHIO = 0
CIRCUITPY_ULAB = 0
+CIRCUITPY_USB_MIDI = 0
CIRCUITPY_WATCHDOG = 1
# Enable micropython.native
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index 012ebc3b5..6ecf7e0ba 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -36,6 +36,7 @@
#include "supervisor/shared/translate.h"
#include "nrfx_uarte.h"
+#include "nrf_gpio.h"
#include <string.h>
// expression to examine, and return value in case of failing
@@ -98,10 +99,16 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
switch ( event->type ) {
case NRFX_UARTE_EVT_RX_DONE:
- ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
+ if (ringbuf_num_empty(&self->ringbuf) >= event->data.rxtx.bytes) {
+ ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
+ // keep receiving
+ (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
+ } else {
+ // receive buffer full, suspend
+ self->rx_paused = true;
+ nrf_gpio_pin_write(self->rts_pin_number, true);
+ }
- // keep receiving
- (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
break;
case NRFX_UARTE_EVT_TX_DONE:
@@ -137,8 +144,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled) {
- if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
- mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
+ if ((rs485_dir != NULL) || (rs485_invert)) {
+ mp_raise_ValueError(translate("RS485 Not yet supported on this device"));
}
// Find a free UART peripheral.
@@ -166,16 +173,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
mp_raise_ValueError(translate("Odd parity is not supported"));
}
+ bool hwfc = rts != NULL || cts != NULL;
+
nrfx_uarte_config_t config = {
.pseltxd = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number,
.pselrxd = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number,
- .pselcts = NRF_UARTE_PSEL_DISCONNECTED,
- .pselrts = NRF_UARTE_PSEL_DISCONNECTED,
+ .pselcts = (cts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : cts->number,
+ .pselrts = (rts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rts->number,
.p_context = self,
.baudrate = get_nrf_baud(baudrate),
.interrupt_priority = 7,
.hal_cfg = {
- .hwfc = NRF_UARTE_HWFC_DISABLED,
+ .hwfc = hwfc ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED,
.parity = (parity == BUSIO_UART_PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED
}
};
@@ -207,9 +216,25 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
self->tx_pin_number = NO_PIN;
}
+ if ( rts != NULL ) {
+ self->rts_pin_number = rts->number;
+ claim_pin(rts);
+ } else {
+ self->rts_pin_number = NO_PIN;
+ }
+
+ if ( cts != NULL ) {
+ self->cts_pin_number = cts->number;
+ claim_pin(cts);
+ } else {
+ self->cts_pin_number = NO_PIN;
+ }
+
self->baudrate = baudrate;
self->timeout_ms = timeout * 1000;
+ self->rx_paused = false;
+
// Initial wait for incoming byte
_VERIFY_ERR(nrfx_uarte_rx(self->uarte, &self->rx_char, 1));
}
@@ -223,8 +248,12 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
nrfx_uarte_uninit(self->uarte);
reset_pin_number(self->tx_pin_number);
reset_pin_number(self->rx_pin_number);
+ reset_pin_number(self->rts_pin_number);
+ reset_pin_number(self->cts_pin_number);
self->tx_pin_number = NO_PIN;
self->rx_pin_number = NO_PIN;
+ self->rts_pin_number = NO_PIN;
+ self->cts_pin_number = NO_PIN;
ringbuf_free(&self->ringbuf);
}
}
@@ -237,6 +266,13 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
uint64_t start_ticks = supervisor_ticks_ms64();
+ // check removed to reduce code size
+ /*
+ if (len > ringbuf_capacity(&self->ringbuf)) {
+ mp_raise_ValueError(translate("Reading >receiver_buffer_size bytes is not supported"));
+ }
+ */
+
// Wait for all bytes received or timeout
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
@@ -252,6 +288,16 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
+ // restart reader, if stopped
+ if (self->rx_paused) {
+ // the character that did not fit in ringbuf is in rx_char
+ ringbuf_put_n(&self->ringbuf, &self->rx_char, 1);
+ // keep receiving
+ (void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
+ nrf_gpio_pin_write(self->rts_pin_number, false);
+ self->rx_paused = false;
+ }
+
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
return rx_bytes;
diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h
index a25116291..2eaf58440 100644
--- a/ports/nrf/common-hal/busio/UART.h
+++ b/ports/nrf/common-hal/busio/UART.h
@@ -42,10 +42,13 @@ typedef struct {
uint32_t timeout_ms;
ringbuf_t ringbuf;
- uint8_t rx_char; // EasyDMA buf
+ uint8_t rx_char; // EasyDMA buf
+ bool rx_paused; // set by irq if no space in rbuf
uint8_t tx_pin_number;
uint8_t rx_pin_number;
+ uint8_t cts_pin_number;
+ uint8_t rts_pin_number;
} busio_uart_obj_t;
void uart_reset(void);