ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_nrf5_sdk15_communication_uart.c
Go to the documentation of this file.
3#if RUUVI_NRF5_SDK15_UART_ENABLED
10#include "nrf_serial.h"
11
12#ifndef RUUVI_NRF5_SDK15_UART_LOG_LEVEL
13#define LOG_LEVEL RI_LOG_LEVEL_INFO
14#else
15#define LOG_LEVEL RUUVI_NRF5_SDK15_UART_LOG_LEVEL
16#endif
17#define LOG(msg) (ri_log(LOG_LEVEL, msg))
18#define LOGD(msg) (ri_log(RI_LOG_LEVEL_DEBUG, msg))
19
20static const ri_comm_channel_t * m_channel;
21static uint16_t m_rxcnt = 0;
22static uint16_t m_txcnt = 0;
23
24static void sleep_handler (void)
25{
26 ri_yield();
27}
28
29// Handle UART events
30static void uart_handler (struct nrf_serial_s const * p_serial, nrf_serial_event_t event)
31{
32 if (m_channel && m_channel->on_evt)
33 {
34 switch (event)
35 {
36 case NRF_SERIAL_EVENT_TX_DONE:
37 LOGD ("TX\r\n");
38
39 if (0 == (--m_txcnt))
40 {
41 m_channel->on_evt (RI_COMM_SENT, NULL, 0);
42 }
43
44 break;
45
46 case NRF_SERIAL_EVENT_RX_DATA:
47 LOGD ("RX\r\n");
48
49 if ( ( ( (char *) (p_serial->p_ctx->p_config->p_buffers->p_rxb)) [0] == '\n')
50 || ++m_rxcnt >= RI_COMM_MESSAGE_MAX_LENGTH)
51 {
52 ri_comm_message_t msg = {0};
54 m_channel->read (&msg);
55 m_channel->on_evt (RI_COMM_RECEIVED, (void *) &msg.data[0], msg.data_length);
56 }
57
58 break;
59
60 case NRF_SERIAL_EVENT_DRV_ERR:
61 LOGD ("UART Error\r\n");
62 break;
63
64 case NRF_SERIAL_EVENT_FIFO_ERR:
65 LOGD ("FIFO Error\r\n");
66 break;
67
68 default:
69 LOGD ("UART unknown event\r\n");
70 break;
71 }
72 }
73}
74
75static nrf_drv_uart_config_t m_uart0_drv_config;
76
77// FIFOs have a guard byte
78#define GUARD_SIZE (1U)
79#define SERIAL_FIFO_TX_SIZE (RI_COMM_MESSAGE_MAX_LENGTH + GUARD_SIZE)
80#define SERIAL_FIFO_RX_SIZE (RI_COMM_MESSAGE_MAX_LENGTH + GUARD_SIZE)
81
82NRF_SERIAL_QUEUES_DEF (serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
83
84
85#define SERIAL_BUFF_TX_SIZE (1U)
86#define SERIAL_BUFF_RX_SIZE (1U)
87
88NRF_SERIAL_BUFFERS_DEF (serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
89
90NRF_SERIAL_CONFIG_DEF (serial_config, NRF_SERIAL_MODE_DMA,
91 &serial_queues, &serial_buffs, uart_handler, sleep_handler);
92
93
94NRF_SERIAL_UART_DEF (serial_uart, 0);
95
96// Convert constants from Ruuvi to nRF52 SDK
97static nrf_uarte_baudrate_t ruuvi_to_nrf_baudrate (const ri_uart_baudrate_t baud)
98{
99 switch (baud)
100 {
102 return NRF_UARTE_BAUDRATE_9600;
103
105 default:
106 return NRF_UARTE_BAUDRATE_115200;
107 }
108}
109
110static rd_status_t ri_uart_send_async (ri_comm_message_t * const msg)
111{
112 rd_status_t err_code = RD_SUCCESS;
113
114 if (NULL == msg)
115 {
116 err_code |= RD_ERROR_NULL;
117 }
118
119 if (1 < msg->repeat_count)
120 {
121 err_code |= RD_ERROR_NOT_SUPPORTED;
122 }
123 else if (0 != m_txcnt)
124 {
125 if (NRF_MTX_LOCKED == serial_uart.p_ctx->write_lock)
126 {
127 err_code |= RD_ERROR_BUSY;
128 }
129 else
130 {
131 m_txcnt = 0;
132 m_channel->on_evt (RI_COMM_SENT, NULL, 0);
133 }
134 }
135 else
136 {
137 nrfx_err_t status = NRF_SUCCESS;
138 size_t written = 0;
139 status |= nrf_serial_write (&serial_uart, msg->data, msg->data_length, &written, 0);
140 m_txcnt = written;
141 err_code |= ruuvi_nrf5_sdk15_to_ruuvi_error (status);
142
143 if (written != msg->data_length)
144 {
145 err_code |= RD_ERROR_NO_MEM;
146 }
147 }
148
149 return err_code;
150}
151
152static rd_status_t ri_uart_read_buf (ri_comm_message_t * const msg)
153{
154 rd_status_t err_code = RD_SUCCESS;
155
156 if (NULL == msg)
157 {
158 err_code |= RD_ERROR_NULL;
159 }
160
161 if (1 < msg->repeat_count)
162 {
163 err_code |= RD_ERROR_NOT_SUPPORTED;
164 }
165 else
166 {
167 nrfx_err_t status = NRF_SUCCESS;
168 size_t bytes_read = nrf_queue_utilization_get (&serial_queues_rxq);
169
170 if (msg->data_length < bytes_read)
171 {
172 bytes_read = msg->data_length;
173 }
174
175 status |= nrf_queue_read (&serial_queues_rxq, msg->data, bytes_read);
176 msg->data_length = bytes_read;
177 msg->repeat_count = 1;
178 err_code |= ruuvi_nrf5_sdk15_to_ruuvi_error (status);
179 m_rxcnt = 0;
180 }
181
182 return err_code;
183}
184
186{
187 rd_status_t err_code = RD_SUCCESS;
188
189 if (NULL == channel)
190 {
191 err_code |= RD_ERROR_NULL;
192 }
193 else if (NULL != m_channel)
194 {
195 err_code |= RD_ERROR_INVALID_STATE;
196 }
197 else
198 {
199 channel->send = ri_uart_send_async;
200 channel->read = ri_uart_read_buf;
201 channel->init = ri_uart_init;
202 channel->uninit = ri_uart_uninit;
203 m_channel = channel;
204 }
205
206 return err_code;
207}
208
209rd_status_t ri_uart_config (const ri_uart_init_t * const config)
210{
211 rd_status_t err_code = RD_SUCCESS;
212
213 if (NULL == config)
214 {
215 err_code |= RD_ERROR_NULL;
216 }
217 else
218 {
219 nrfx_err_t nrf_status = NRF_SUCCESS;
220 m_uart0_drv_config.baudrate = ruuvi_to_nrf_baudrate (config->baud);
221 m_uart0_drv_config.pseltxd = ruuvi_to_nrf_pin_map (config->tx);
222 m_uart0_drv_config.pselrxd = ruuvi_to_nrf_pin_map (config->rx);
223
224 if (config->hwfc_enabled)
225 {
226 m_uart0_drv_config.pselcts = ruuvi_to_nrf_pin_map (config->cts);
227 m_uart0_drv_config.pselrts = ruuvi_to_nrf_pin_map (config->rts);
228 }
229 else
230 {
231 m_uart0_drv_config.pselcts = NRF_UARTE_PSEL_DISCONNECTED;
232 m_uart0_drv_config.pselrts = NRF_UARTE_PSEL_DISCONNECTED;
233 }
234
235 m_uart0_drv_config.parity = config->parity_enabled ? NRF_UARTE_PARITY_INCLUDED :
236 NRF_UARTE_PARITY_EXCLUDED;
237 m_uart0_drv_config.hwfc = config->hwfc_enabled ? NRF_UARTE_HWFC_ENABLED :
238 NRF_UARTE_HWFC_DISABLED;
239 m_uart0_drv_config.interrupt_priority = APP_IRQ_PRIORITY_HIGH;
240 nrf_status |= nrf_serial_init (&serial_uart, &m_uart0_drv_config, &serial_config);
241 err_code |= ruuvi_nrf5_sdk15_to_ruuvi_error (nrf_status);
242 }
243
244 return err_code;
245}
246
248{
249 m_channel = NULL;
250 return nrf_serial_uninit (&serial_uart);
251}
252
253#endif
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
rd_status_t ruuvi_nrf5_sdk15_to_ruuvi_error(const ret_code_t error)
convert nrf5 sdk15 error code into Ruuvi error code.
#define RD_ERROR_NOT_SUPPORTED
Not supported.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_NO_MEM
No Memory for operation.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_ERROR_BUSY
Busy.
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
#define RI_COMM_MESSAGE_MAX_LENGTH
The maximum length for the application message for sending over BLE, which depends on whether extende...
@ RI_COMM_RECEIVED
New data received, available to read with read function.
@ RI_COMM_SENT
One queued message was sent with all repetitions.
ri_uart_baudrate_t
Supported baudrates.
@ RI_UART_BAUD_115200
Run at 115200 baud.
@ RI_UART_BAUD_9600
Run at 9600 baud.
rd_status_t ri_uart_uninit(ri_comm_channel_t *const channel)
rd_status_t ri_uart_config(const ri_uart_init_t *const config)
Configure UART.
rd_status_t ri_uart_init(ri_comm_channel_t *const channel)
Initialize UART.
#define LOGD(fmt,...)
rd_status_t ri_yield(void)
Function which will release execution.
control API for communication via outside world
ri_comm_evt_handler_fp_t on_evt
Callback to application-level event handler, must be set in application.
ri_comm_xfer_fp_t send
Asynchronous send function.
ri_comm_init_fp_t init
Initialize and populate channel api control.
ri_comm_init_fp_t uninit
Uninitialize and depopulate channel api control.
ri_comm_xfer_fp_t read
Asynchronous read function.
Application message structure used for communication.
uint8_t data[RI_COMM_MESSAGE_MAX_LENGTH]
Data payload.
uint8_t repeat_count
Number of times to repeat the message,.
uint8_t data_length
Length of data.
UART initialization data.
ri_gpio_id_t rts
RTS pin. Can be RI_GPIO_UNUSED if not using HWFC.
bool hwfc_enabled
True to enable hardware flow control.
bool parity_enabled
True to enable parity.
ri_uart_baudrate_t baud
ri_uart_baudrate_t.
ri_gpio_id_t cts
CTS pin. Can be RI_GPIO_UNUSED if not using HWFC.