summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/nrf/modules/machine/uart.c27
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;