diff options
| -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; |
