Merge pull request #4018 from iot49/cp-flow
add uart hardware flow control to nrf port
This commit is contained in:
commit
ced3dc70ff
@ -1793,6 +1793,10 @@ msgstr ""
|
|||||||
msgid "RNG Init Error"
|
msgid "RNG Init Error"
|
||||||
msgstr ""
|
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/esp32s2/common-hal/busio/UART.c
|
||||||
#: ports/mimxrt10xx/common-hal/busio/UART.c
|
#: ports/mimxrt10xx/common-hal/busio/UART.c
|
||||||
msgid "RS485 inversion specified when not in RS485 mode"
|
msgid "RS485 inversion specified when not in RS485 mode"
|
||||||
@ -1808,7 +1812,7 @@ msgid "RTC is not supported on this board"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c
|
#: 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"
|
msgid "RTS/CTS/RS485 Not yet supported on this device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ USB_PID = 0xc051
|
|||||||
USB_PRODUCT = "Simmel"
|
USB_PRODUCT = "Simmel"
|
||||||
USB_MANUFACTURER = "Betrusted"
|
USB_MANUFACTURER = "Betrusted"
|
||||||
|
|
||||||
|
CIRCUITPY_DEVICES="CDC,MSC,HID"
|
||||||
|
|
||||||
MCU_CHIP = nrf52833
|
MCU_CHIP = nrf52833
|
||||||
|
|
||||||
# SPI_FLASH_FILESYSTEM = 1
|
# SPI_FLASH_FILESYSTEM = 1
|
||||||
@ -29,6 +31,7 @@ CIRCUITPY_RTC = 1
|
|||||||
CIRCUITPY_SDCARDIO = 0
|
CIRCUITPY_SDCARDIO = 0
|
||||||
CIRCUITPY_TOUCHIO = 0
|
CIRCUITPY_TOUCHIO = 0
|
||||||
CIRCUITPY_ULAB = 0
|
CIRCUITPY_ULAB = 0
|
||||||
|
CIRCUITPY_USB_MIDI = 0
|
||||||
CIRCUITPY_WATCHDOG = 1
|
CIRCUITPY_WATCHDOG = 1
|
||||||
|
|
||||||
# Enable micropython.native
|
# Enable micropython.native
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "supervisor/shared/translate.h"
|
#include "supervisor/shared/translate.h"
|
||||||
|
|
||||||
#include "nrfx_uarte.h"
|
#include "nrfx_uarte.h"
|
||||||
|
#include "nrf_gpio.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// expression to examine, and return value in case of failing
|
// 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 ) {
|
switch ( event->type ) {
|
||||||
case NRFX_UARTE_EVT_RX_DONE:
|
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;
|
break;
|
||||||
|
|
||||||
case NRFX_UARTE_EVT_TX_DONE:
|
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,
|
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
|
||||||
bool sigint_enabled) {
|
bool sigint_enabled) {
|
||||||
|
|
||||||
if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
|
if ((rs485_dir != NULL) || (rs485_invert)) {
|
||||||
mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
|
mp_raise_ValueError(translate("RS485 Not yet supported on this device"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a free UART peripheral.
|
// 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"));
|
mp_raise_ValueError(translate("Odd parity is not supported"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hwfc = rts != NULL || cts != NULL;
|
||||||
|
|
||||||
nrfx_uarte_config_t config = {
|
nrfx_uarte_config_t config = {
|
||||||
.pseltxd = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number,
|
.pseltxd = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number,
|
||||||
.pselrxd = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number,
|
.pselrxd = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number,
|
||||||
.pselcts = NRF_UARTE_PSEL_DISCONNECTED,
|
.pselcts = (cts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : cts->number,
|
||||||
.pselrts = NRF_UARTE_PSEL_DISCONNECTED,
|
.pselrts = (rts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rts->number,
|
||||||
.p_context = self,
|
.p_context = self,
|
||||||
.baudrate = get_nrf_baud(baudrate),
|
.baudrate = get_nrf_baud(baudrate),
|
||||||
.interrupt_priority = 7,
|
.interrupt_priority = 7,
|
||||||
.hal_cfg = {
|
.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
|
.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;
|
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->baudrate = baudrate;
|
||||||
self->timeout_ms = timeout * 1000;
|
self->timeout_ms = timeout * 1000;
|
||||||
|
|
||||||
|
self->rx_paused = false;
|
||||||
|
|
||||||
// Initial wait for incoming byte
|
// Initial wait for incoming byte
|
||||||
_VERIFY_ERR(nrfx_uarte_rx(self->uarte, &self->rx_char, 1));
|
_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);
|
nrfx_uarte_uninit(self->uarte);
|
||||||
reset_pin_number(self->tx_pin_number);
|
reset_pin_number(self->tx_pin_number);
|
||||||
reset_pin_number(self->rx_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->tx_pin_number = NO_PIN;
|
||||||
self->rx_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);
|
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();
|
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
|
// Wait for all bytes received or timeout
|
||||||
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
|
||||||
RUN_BACKGROUND_TASKS;
|
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.
|
// Copy as much received data as available, up to len bytes.
|
||||||
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
|
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));
|
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
|
||||||
|
|
||||||
return rx_bytes;
|
return rx_bytes;
|
||||||
|
@ -42,10 +42,13 @@ typedef struct {
|
|||||||
uint32_t timeout_ms;
|
uint32_t timeout_ms;
|
||||||
|
|
||||||
ringbuf_t ringbuf;
|
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 tx_pin_number;
|
||||||
uint8_t rx_pin_number;
|
uint8_t rx_pin_number;
|
||||||
|
uint8_t cts_pin_number;
|
||||||
|
uint8_t rts_pin_number;
|
||||||
} busio_uart_obj_t;
|
} busio_uart_obj_t;
|
||||||
|
|
||||||
void uart_reset(void);
|
void uart_reset(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user