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