diff options
| author | Andrew Leech <andrew.leech@planetinnovation.com.au> | 2024-05-29 11:48:19 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2024-07-26 11:12:46 +1000 |
| commit | 56c161738496c03f0d651264861ff0c334b04e5d (patch) | |
| tree | 0084aafeb8128f6b1986065af0590537ae87c0dc | |
| parent | 19075695da82e30850e8f595c58521d2b3787b4a (diff) | |
nrf/modules/machine/uart: Support sending data stored in flash.
Signed-off-by: Andrew Leech <andrew@alelec.net>
| -rw-r--r-- | ports/nrf/modules/machine/uart.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c index de26fa1b1..90a67bcbc 100644 --- a/ports/nrf/modules/machine/uart.c +++ b/ports/nrf/modules/machine/uart.c @@ -29,6 +29,7 @@ // This file is never compiled standalone, it's included directly from // extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE. +#include <string.h> #include "py/mperrno.h" #include "py/mphal.h" #include "py/ringbuf.h" @@ -317,10 +318,30 @@ static mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t return size; } -static mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { - machine_uart_obj_t *self = self_in; +static mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { + #if !NRFX_UART_ENABLED + if (!nrfx_is_in_ram(buf)) { + // Peripherals using EasyDMA require that transfer buffers are placed in DataRAM, + // they cannot access data directly from flash. + // If buf is in flash, copy to ram in chunks to send. + char rambuf[64]; + char *flashbuf = (char *)buf; + mp_uint_t remaining = size; + while (remaining) { + mp_uint_t chunk = MIN(sizeof(rambuf), remaining); + memcpy(rambuf, flashbuf, chunk); + if (mp_machine_uart_write(self_in, rambuf, chunk, errcode) == MP_STREAM_ERROR) { + return MP_STREAM_ERROR; + } + remaining -= chunk; + flashbuf += chunk; + } + return size; + } + #endif - nrfx_err_t err = nrfx_uart_tx(self->p_uart, buf_in, size); + machine_uart_obj_t *self = self_in; + nrfx_err_t err = nrfx_uart_tx(self->p_uart, buf, size); if (err == NRFX_SUCCESS) { while (nrfx_uart_tx_in_progress(self->p_uart)) { MICROPY_EVENT_POLL_HOOK; |
