blob: 704c6ab52d295da2b705d917b024bc333c209ac4 [file] [log] [blame]
Kévin Redonde9fb2e2019-04-03 20:55:02 +02001/**
2 * \file
3 *
4 * \brief I/O USART related functionality implementation.
5 *
6 * Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.
7 * Copyright (C) 2019 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Subject to your compliance with these terms, you may use Microchip
14 * software and any derivatives exclusively with Microchip products.
15 * It is your responsibility to comply with third party license terms applicable
16 * to your use of third party software (including open source software) that
17 * may accompany Microchip software.
18 *
19 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
21 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
22 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
23 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
24 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
25 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
26 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
27 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
28 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
29 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
30 *
31 * \asf_license_stop
32 *
33 */
34
35#include "hal_usart_async_rings.h"
36#include <utils_assert.h>
37#include <hal_atomic.h>
38#include <utils.h>
39
40/**
41 * \brief Driver version
42 */
43#define DRIVER_VERSION 0x00000001u
44
45static int32_t usart_async_rings_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length);
46static int32_t usart_async_rings_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length);
47static void usart_process_byte_sent(struct _usart_async_device *device);
48static void usart_transmission_complete(struct _usart_async_device *device);
49static void usart_error(struct _usart_async_device *device);
50static void usart_fill_rx_buffer(struct _usart_async_device *device, uint8_t data);
51
52/**
53 * \brief Initialize usart interface
54 */
55int32_t usart_async_rings_init(struct usart_async_rings_descriptor *const descr, void *const hw, uint8_t *const rx_buffer,
56 const uint16_t rx_buffer_length, uint8_t *const tx_buffer,
57 const uint16_t tx_buffer_length, void *const func)
58{
59 int32_t init_status;
60 ASSERT(descr && hw && rx_buffer && rx_buffer_length && tx_buffer && tx_buffer_length);
61
62 if (ERR_NONE != ringbuffer_init(&descr->rx, rx_buffer, rx_buffer_length)) {
63 return ERR_INVALID_ARG;
64 }
65 if (ERR_NONE != ringbuffer_init(&descr->tx, tx_buffer, tx_buffer_length)) {
66 return ERR_INVALID_ARG;
67 }
68 init_status = _usart_async_init(&descr->device, hw);
69 if (init_status) {
70 return init_status;
71 }
72
73 descr->io.read = usart_async_rings_read;
74 descr->io.write = usart_async_rings_write;
75
76 descr->device.usart_cb.tx_byte_sent = usart_process_byte_sent;
77 descr->device.usart_cb.rx_done_cb = usart_fill_rx_buffer;
78 descr->device.usart_cb.tx_done_cb = usart_transmission_complete;
79 descr->device.usart_cb.error_cb = usart_error;
80
81 return ERR_NONE;
82}
83
84/**
85 * \brief Deinitialize usart interface
86 */
87int32_t usart_async_rings_deinit(struct usart_async_rings_descriptor *const descr)
88{
89 ASSERT(descr);
90 _usart_async_deinit(&descr->device);
91 descr->io.read = NULL;
92 descr->io.write = NULL;
93
94 return ERR_NONE;
95}
96
97/**
98 * \brief Enable usart interface
99 */
100int32_t usart_async_rings_enable(struct usart_async_rings_descriptor *const descr)
101{
102 ASSERT(descr);
103 _usart_async_enable(&descr->device);
104
105 return ERR_NONE;
106}
107
108/**
109 * \brief Disable usart interface
110 */
111int32_t usart_async_rings_disable(struct usart_async_rings_descriptor *const descr)
112{
113 ASSERT(descr);
114 _usart_async_disable(&descr->device);
115
116 return ERR_NONE;
117}
118
119/**
120 * \brief Retrieve I/O descriptor
121 */
122int32_t usart_async_rings_get_io_descriptor(struct usart_async_rings_descriptor *const descr, struct io_descriptor **io)
123{
124 ASSERT(descr && io);
125
126 *io = &descr->io;
127 return ERR_NONE;
128}
129
130/**
131 * \brief Register usart callback
132 */
133int32_t usart_async_rings_register_callback(struct usart_async_rings_descriptor *const descr,
134 const enum usart_async_rings_callback_type type, usart_rings_cb_t cb)
135{
136 ASSERT(descr);
137
138 switch (type) {
139 case USART_ASYNC_RINGS_RXC_CB:
140 descr->usart_cb.rx_done = cb;
141 _usart_async_set_irq_state(&descr->device, USART_ASYNC_RX_DONE, NULL != cb);
142 break;
143 case USART_ASYNC_RINGS_TXC_CB:
144 descr->usart_cb.tx_done = cb;
145 _usart_async_set_irq_state(&descr->device, USART_ASYNC_TX_DONE, NULL != cb);
146 break;
147 case USART_ASYNC_RINGS_ERROR_CB:
148 descr->usart_cb.error = cb;
149 _usart_async_set_irq_state(&descr->device, USART_ASYNC_ERROR, NULL != cb);
150 break;
151 default:
152 return ERR_INVALID_ARG;
153 }
154
155 return ERR_NONE;
156}
157
158/**
159 * \brief Specify action for flow control pins
160 */
161int32_t usart_async_rings_set_flow_control(struct usart_async_rings_descriptor *const descr,
162 const union usart_flow_control_state state)
163{
164 ASSERT(descr);
165 _usart_async_set_flow_control_state(&descr->device, state);
166
167 return ERR_NONE;
168}
169
170/**
171 * \brief Set usart baud rate
172 */
173int32_t usart_async_rings_set_baud_rate(struct usart_async_rings_descriptor *const descr, const uint32_t baud_rate)
174{
175 ASSERT(descr);
176 _usart_async_set_baud_rate(&descr->device, baud_rate);
177
178 return ERR_NONE;
179}
180
181/**
182 * \brief Set usart data order
183 */
184int32_t usart_async_rings_set_data_order(struct usart_async_rings_descriptor *const descr, const enum usart_data_order data_order)
185{
186 ASSERT(descr);
187 _usart_async_set_data_order(&descr->device, data_order);
188
189 return ERR_NONE;
190}
191
192/**
193 * \brief Set usart mode
194 */
195int32_t usart_async_rings_set_mode(struct usart_async_rings_descriptor *const descr, const enum usart_mode mode)
196{
197 ASSERT(descr);
198 _usart_async_set_mode(&descr->device, mode);
199
200 return ERR_NONE;
201}
202
203/**
204 * \brief Set usart parity
205 */
206int32_t usart_async_rings_set_parity(struct usart_async_rings_descriptor *const descr, const enum usart_parity parity)
207{
208 ASSERT(descr);
209 _usart_async_set_parity(&descr->device, parity);
210
211 return ERR_NONE;
212}
213
214/**
215 * \brief Set usart stop bits
216 */
217int32_t usart_async_rings_set_stopbits(struct usart_async_rings_descriptor *const descr, const enum usart_stop_bits stop_bits)
218{
219 ASSERT(descr);
220 _usart_async_set_stop_bits(&descr->device, stop_bits);
221
222 return ERR_NONE;
223}
224
225/**
226 * \brief Set usart character size
227 */
228int32_t usart_async_rings_set_character_size(struct usart_async_rings_descriptor *const descr, const enum usart_character_size size)
229{
230 ASSERT(descr);
231 _usart_async_set_character_size(&descr->device, size);
232
233 return ERR_NONE;
234}
235
236/**
237 * \brief Retrieve the state of flow control pins
238 */
239int32_t usart_async_rings_flow_control_status(const struct usart_async_rings_descriptor *const descr,
240 union usart_flow_control_state *const state)
241{
242 ASSERT(descr && state);
243 *state = _usart_async_get_flow_control_state(&descr->device);
244
245 return ERR_NONE;
246}
247
248/**
249 * \brief Check if the usart transmitter is empty
250 */
251int32_t usart_async_rings_is_tx_empty(const struct usart_async_rings_descriptor *const descr)
252{
253 ASSERT(descr);
254 return _usart_async_is_byte_sent(&descr->device);
255}
256
257/**
258 * \brief Check if the usart receiver is not empty
259 */
260int32_t usart_async_rings_is_rx_not_empty(const struct usart_async_rings_descriptor *const descr)
261{
262 ASSERT(descr);
263
264 return ringbuffer_num(&descr->rx) > 0;
265}
266
267/**
268 * \brief Retrieve the current interface status
269 */
270int32_t usart_async_rings_get_status(struct usart_async_rings_descriptor *const descr, struct usart_async_rings_status *const status)
271{
272 ASSERT(descr);
273
274 volatile uint32_t *tmp_stat = &(descr->stat);
275
276 if (status) {
277 status->flags = *tmp_stat;
278 status->txcnt = ringbuffer_num(&descr->tx);
279 status->rxcnt = ringbuffer_num(&descr->rx);
280 }
281 if (*tmp_stat & USART_ASYNC_RINGS_STATUS_BUSY) {
282 return ERR_BUSY;
283 }
284
285 return ERR_NONE;
286}
287
288/**
289 * \brief flush usart rx ringbuf
290 */
291int32_t usart_async_rings_flush_rx_buffer(struct usart_async_rings_descriptor *const descr)
292{
293 ASSERT(descr);
294
295 return ringbuffer_flush(&descr->rx);
296}
297
298/**
299 * \brief Retrieve the current driver version
300 */
301uint32_t usart_async_rings_get_version(void)
302{
303 return DRIVER_VERSION;
304}
305
306/*
307 * \internal Write the given data to usart interface
308 *
309 * \param[in] descr The pointer to an io descriptor
310 * \param[in] buf Data to write to usart
311 * \param[in] length The number of bytes to write
312 *
313 * \return The number of bytes written.
314 *
315 * \warning blocking when the transmit buffer is full
316 */
317static int32_t usart_async_rings_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length)
318{
319 struct usart_async_rings_descriptor *descr = CONTAINER_OF(io_descr, struct usart_async_rings_descriptor, io);
320
321 ASSERT(descr && buf && length);
322
323 for (uint16_t i = 0; i < length; i++) {
Harald Welte977327c2019-11-12 17:31:23 +0100324 /* HACK: disabling this to avoid getting stuck indefinitely. In theory, this while loop below
325 * would exit at some point as the UART is supposedly transmitting data. However, in some
326 * situations it is not transmitting, and hence the condition becomes never true, waiting here
327 * indefinitely. We will now simply ovewrite old log data if it isn't sent fast enough */
328 //while (ringbuffer_num(&descr->tx) > descr->tx.size); // WARNING blocking until there is space in the buffer
Kévin Redonde9fb2e2019-04-03 20:55:02 +0200329 ringbuffer_put(&descr->tx, buf[i]);
330 }
331 descr->stat = USART_ASYNC_RINGS_STATUS_BUSY;
332 _usart_async_enable_byte_sent_irq(&descr->device);
333
334 return (int32_t)length;
335}
336
337/*
338 * \internal Read data from usart interface
339 *
340 * \param[in] descr The pointer to an io descriptor
341 * \param[in] buf A buffer to read data to
342 * \param[in] length The size of a buffer
343 *
344 * \return The number of bytes read.
345 */
346static int32_t usart_async_rings_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length)
347{
348 uint16_t was_read = 0;
349 uint32_t num;
350 struct usart_async_rings_descriptor *descr = CONTAINER_OF(io_descr, struct usart_async_rings_descriptor, io);
351
352 ASSERT(descr && buf && length);
353
354 CRITICAL_SECTION_ENTER()
355 num = ringbuffer_num(&descr->rx);
356 CRITICAL_SECTION_LEAVE()
357
358 while ((was_read < num) && (was_read < length)) {
359 ringbuffer_get(&descr->rx, &buf[was_read++]);
360 }
361
362 return (int32_t)was_read;
363}
364
365/**
366 * \brief Process "byte is sent" interrupt
367 *
368 * \param[in] device The pointer to device structure
369 */
370static void usart_process_byte_sent(struct _usart_async_device *device)
371{
372 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
373 if (ringbuffer_num(&descr->tx)) {
374 uint8_t byte;
375 ringbuffer_get(&descr->tx, &byte);
376 _usart_async_write_byte(&descr->device, byte);
377 _usart_async_enable_byte_sent_irq(&descr->device);
378 } else {
379 _usart_async_enable_tx_done_irq(&descr->device);
380 }
381}
382
383/**
384 * \brief Process completion of data sending
385 *
386 * \param[in] device The pointer to device structure
387 */
388static void usart_transmission_complete(struct _usart_async_device *device)
389{
390 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
391
392 descr->stat = 0;
393 if (descr->usart_cb.tx_done) {
394 descr->usart_cb.tx_done(descr);
395 }
396}
397
398/**
399 * \brief Process byte reception
400 *
401 * \param[in] device The pointer to device structure
402 * \param[in] data Data read
403 */
404static void usart_fill_rx_buffer(struct _usart_async_device *device, uint8_t data)
405{
406 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
407
408 ringbuffer_put(&descr->rx, data);
409
410 if (descr->usart_cb.rx_done) {
411 descr->usart_cb.rx_done(descr);
412 }
413}
414
415/**
416 * \brief Process error interrupt
417 *
418 * \param[in] device The pointer to device structure
419 */
420static void usart_error(struct _usart_async_device *device)
421{
422 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
423
424 descr->stat = 0;
425 if (descr->usart_cb.error) {
426 descr->usart_cb.error(descr);
427 }
428}
429
430//@}