blob: 38bdca4b3735b664ea21b0bcf6181ae3c9ea4b78 [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++) {
324 while (ringbuffer_num(&descr->tx) > descr->tx.size); // WARNING blocking until there is space in the buffer
325 ringbuffer_put(&descr->tx, buf[i]);
326 }
327 descr->stat = USART_ASYNC_RINGS_STATUS_BUSY;
328 _usart_async_enable_byte_sent_irq(&descr->device);
329
330 return (int32_t)length;
331}
332
333/*
334 * \internal Read data from usart interface
335 *
336 * \param[in] descr The pointer to an io descriptor
337 * \param[in] buf A buffer to read data to
338 * \param[in] length The size of a buffer
339 *
340 * \return The number of bytes read.
341 */
342static int32_t usart_async_rings_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length)
343{
344 uint16_t was_read = 0;
345 uint32_t num;
346 struct usart_async_rings_descriptor *descr = CONTAINER_OF(io_descr, struct usart_async_rings_descriptor, io);
347
348 ASSERT(descr && buf && length);
349
350 CRITICAL_SECTION_ENTER()
351 num = ringbuffer_num(&descr->rx);
352 CRITICAL_SECTION_LEAVE()
353
354 while ((was_read < num) && (was_read < length)) {
355 ringbuffer_get(&descr->rx, &buf[was_read++]);
356 }
357
358 return (int32_t)was_read;
359}
360
361/**
362 * \brief Process "byte is sent" interrupt
363 *
364 * \param[in] device The pointer to device structure
365 */
366static void usart_process_byte_sent(struct _usart_async_device *device)
367{
368 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
369 if (ringbuffer_num(&descr->tx)) {
370 uint8_t byte;
371 ringbuffer_get(&descr->tx, &byte);
372 _usart_async_write_byte(&descr->device, byte);
373 _usart_async_enable_byte_sent_irq(&descr->device);
374 } else {
375 _usart_async_enable_tx_done_irq(&descr->device);
376 }
377}
378
379/**
380 * \brief Process completion of data sending
381 *
382 * \param[in] device The pointer to device structure
383 */
384static void usart_transmission_complete(struct _usart_async_device *device)
385{
386 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
387
388 descr->stat = 0;
389 if (descr->usart_cb.tx_done) {
390 descr->usart_cb.tx_done(descr);
391 }
392}
393
394/**
395 * \brief Process byte reception
396 *
397 * \param[in] device The pointer to device structure
398 * \param[in] data Data read
399 */
400static void usart_fill_rx_buffer(struct _usart_async_device *device, uint8_t data)
401{
402 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
403
404 ringbuffer_put(&descr->rx, data);
405
406 if (descr->usart_cb.rx_done) {
407 descr->usart_cb.rx_done(descr);
408 }
409}
410
411/**
412 * \brief Process error interrupt
413 *
414 * \param[in] device The pointer to device structure
415 */
416static void usart_error(struct _usart_async_device *device)
417{
418 struct usart_async_rings_descriptor *descr = CONTAINER_OF(device, struct usart_async_rings_descriptor, device);
419
420 descr->stat = 0;
421 if (descr->usart_cb.error) {
422 descr->usart_cb.error(descr);
423 }
424}
425
426//@}