cpu/nrf52840: fix UART DMA when data is in ROM
This commit is contained in:
parent
297efdd5b2
commit
91057de140
@ -27,6 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "periph/uart.h"
|
#include "periph/uart.h"
|
||||||
@ -46,6 +47,14 @@
|
|||||||
#define UART_HWFLOWCTRL (uart_config[uart].rts_pin != (uint8_t)GPIO_UNDEF && \
|
#define UART_HWFLOWCTRL (uart_config[uart].rts_pin != (uint8_t)GPIO_UNDEF && \
|
||||||
uart_config[uart].cts_pin != (uint8_t)GPIO_UNDEF)
|
uart_config[uart].cts_pin != (uint8_t)GPIO_UNDEF)
|
||||||
#define ISR_CTX isr_ctx[uart]
|
#define ISR_CTX isr_ctx[uart]
|
||||||
|
#define RAM_MASK (0x20000000)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Chunk size used for transferring data from ROM [in bytes]
|
||||||
|
*/
|
||||||
|
#ifndef NRF_UARTE_CHUNK_SIZE
|
||||||
|
#define NRF_UARTE_CHUNK_SIZE (32U)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocate memory for the interrupt context
|
* @brief Allocate memory for the interrupt context
|
||||||
@ -213,11 +222,8 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CPU_MODEL_NRF52840XXAA /* nrf52840 (using EasyDMA) */
|
#ifdef CPU_MODEL_NRF52840XXAA /* nrf52840 (using EasyDMA) */
|
||||||
|
static void _write_buf(uart_t uart, const uint8_t *data, size_t len)
|
||||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
|
||||||
{
|
{
|
||||||
assert(uart < UART_NUMOF);
|
|
||||||
|
|
||||||
/* reset endtx flag */
|
/* reset endtx flag */
|
||||||
dev(uart)->EVENTS_ENDTX = 0;
|
dev(uart)->EVENTS_ENDTX = 0;
|
||||||
/* set data to transfer to DMA TX pointer */
|
/* set data to transfer to DMA TX pointer */
|
||||||
@ -229,6 +235,30 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
|||||||
while (dev(uart)->EVENTS_ENDTX == 0) {}
|
while (dev(uart)->EVENTS_ENDTX == 0) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
assert(uart < UART_NUMOF);
|
||||||
|
|
||||||
|
/* EasyDMA can only transfer data from RAM (see ref. manual, sec. 6.34.1).
|
||||||
|
* So if the given `data` buffer resides in ROM, we need to copy it to RAM
|
||||||
|
* before being able to transfer it. To make sure the stack does not
|
||||||
|
* overflow, we do this chunk-wise. */
|
||||||
|
if (!((uint32_t)data & RAM_MASK)) {
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos < len) {
|
||||||
|
uint8_t tmp[NRF_UARTE_CHUNK_SIZE];
|
||||||
|
size_t off = len - pos;
|
||||||
|
off = (off > NRF_UARTE_CHUNK_SIZE) ? NRF_UARTE_CHUNK_SIZE : off;
|
||||||
|
memcpy(tmp, data + pos, off);
|
||||||
|
_write_buf(uart, tmp, off);
|
||||||
|
pos += off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_write_buf(uart, data, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void uart_poweron(uart_t uart)
|
void uart_poweron(uart_t uart)
|
||||||
{
|
{
|
||||||
assert(uart < UART_NUMOF);
|
assert(uart < UART_NUMOF);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user