123 lines
4.0 KiB
C
123 lines
4.0 KiB
C
#include <string.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#include "nrf_gpio.h"
|
|
#include "nrf_uarte.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "semphr.h"
|
|
#include "task.h"
|
|
|
|
#include "nrf_log.h"
|
|
#include "nrf_log_ctrl.h"
|
|
#include "nrf_log_default_backends.h"
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#define HOST_UART (NRF_UARTE0)
|
|
#define HOST_UART_DRV_TX_PIN NRF_GPIO_PIN_MAP(0, 4)
|
|
#define HOST_UART_DRV_RX_PIN NRF_GPIO_PIN_MAP(0, 27)
|
|
|
|
static SemaphoreHandle_t uart_drv_tx_sem;
|
|
static SemaphoreHandle_t uart_drv_rx_sem;
|
|
static SemaphoreHandle_t uart_drv_tx_mutex;
|
|
static SemaphoreHandle_t uart_drv_rx_mutex;
|
|
|
|
uint32_t uart_drv_rx(void *p_data, uint16_t len)
|
|
{
|
|
if (nrfx_is_in_ram(p_data) == false)
|
|
{
|
|
__BKPT(255);
|
|
}
|
|
xSemaphoreTake(uart_drv_rx_mutex, portMAX_DELAY);
|
|
nrf_uarte_rx_buffer_set(HOST_UART, p_data, len);
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_RXTO);
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_ENDRX);
|
|
nrf_uarte_int_enable(HOST_UART, NRF_UARTE_INT_RXDRDY_MASK);
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_RXDRDY);
|
|
nrf_uarte_task_trigger(HOST_UART, NRF_UARTE_TASK_STARTRX);
|
|
xSemaphoreTake(uart_drv_rx_sem, portMAX_DELAY);
|
|
do {
|
|
} while (xSemaphoreTake(uart_drv_rx_sem, pdMS_TO_TICKS(3)));
|
|
nrf_uarte_task_trigger(HOST_UART, NRF_UARTE_TASK_STOPRX);
|
|
xSemaphoreTake(uart_drv_rx_sem, portMAX_DELAY);
|
|
uint32_t recv_bytes = nrf_uarte_rx_amount_get(HOST_UART);
|
|
xSemaphoreGive(uart_drv_rx_mutex);
|
|
return recv_bytes;
|
|
}
|
|
|
|
void uart_drv_tx(void *p_data, uint16_t len)
|
|
{
|
|
if (nrfx_is_in_ram(p_data) == false)
|
|
{
|
|
__BKPT(255);
|
|
}
|
|
xSemaphoreTake(uart_drv_tx_mutex, portMAX_DELAY);
|
|
HOST_UART->TXD.PTR = (uint32_t)p_data;
|
|
HOST_UART->TXD.MAXCNT = len;
|
|
nrf_uarte_task_trigger(HOST_UART, NRF_UARTE_TASK_STARTTX);
|
|
xSemaphoreTake(uart_drv_tx_sem, portMAX_DELAY);
|
|
xSemaphoreGive(uart_drv_tx_mutex);
|
|
}
|
|
|
|
void uart_drv_init(void)
|
|
{
|
|
uart_drv_rx_sem = xSemaphoreCreateBinary();
|
|
uart_drv_tx_sem = xSemaphoreCreateBinary();
|
|
uart_drv_rx_mutex = xSemaphoreCreateMutex();
|
|
uart_drv_tx_mutex = xSemaphoreCreateMutex();
|
|
|
|
nrf_gpio_cfg_output(HOST_UART_DRV_TX_PIN);
|
|
nrf_gpio_cfg_input(HOST_UART_DRV_RX_PIN, NRF_GPIO_PIN_NOPULL);
|
|
nrf_uarte_configure(HOST_UART, NRF_UARTE_PARITY_EXCLUDED, NRF_UARTE_HWFC_DISABLED);
|
|
nrf_uarte_baudrate_set(HOST_UART, NRF_UARTE_BAUDRATE_115200);
|
|
nrf_uarte_txrx_pins_set(HOST_UART, HOST_UART_DRV_TX_PIN, HOST_UART_DRV_RX_PIN);
|
|
nrf_uarte_hwfc_pins_disconnect(HOST_UART);
|
|
nrf_uarte_enable(HOST_UART);
|
|
|
|
// Enable interrput (for easyDMA)
|
|
sd_nvic_SetPriority(UARTE0_UART0_IRQn, _PRIO_APP_MID);
|
|
sd_nvic_EnableIRQ(UARTE0_UART0_IRQn);
|
|
nrf_uarte_int_enable(HOST_UART, NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_RXTO_MASK);
|
|
}
|
|
|
|
void UARTE0_UART0_IRQHandler(void)
|
|
{
|
|
if (nrf_uarte_event_check(HOST_UART, NRF_UARTE_EVENT_RXDRDY))
|
|
{
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_RXDRDY);
|
|
BaseType_t xHigherPriorityTaskWoken;
|
|
xSemaphoreGiveFromISR(uart_drv_rx_sem, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
return;
|
|
}
|
|
if (nrf_uarte_event_check(HOST_UART, NRF_UARTE_EVENT_RXTO))
|
|
{
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_RXTO);
|
|
nrf_uarte_task_trigger(HOST_UART, NRF_UARTE_TASK_FLUSHRX);
|
|
return;
|
|
}
|
|
if (nrf_uarte_event_check(HOST_UART, NRF_UARTE_EVENT_ENDRX))
|
|
{
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_ENDRX);
|
|
BaseType_t xHigherPriorityTaskWoken;
|
|
xSemaphoreGiveFromISR(uart_drv_rx_sem, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
return;
|
|
}
|
|
if (nrf_uarte_event_check(HOST_UART, NRF_UARTE_EVENT_ENDTX))
|
|
{
|
|
nrf_uarte_event_clear(HOST_UART, NRF_UARTE_EVENT_ENDTX);
|
|
BaseType_t xHigherPriorityTaskWoken;
|
|
xSemaphoreGiveFromISR(uart_drv_tx_sem, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
return;
|
|
}
|
|
}
|