1 /**
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 
44 static int32_t usart_async_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length);
45 static int32_t usart_async_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length);
46 static void    usart_process_byte_sent(struct _usart_async_device *device);
47 static void    usart_transmission_complete(struct _usart_async_device *device);
48 static void    usart_error(struct _usart_async_device *device);
49 static void    usart_fill_rx_buffer(struct _usart_async_device *device, uint8_t data);
50 
51 /**
52  * \brief Initialize usart interface
53  */
usart_async_init(struct usart_async_descriptor * const descr,void * const hw,uint8_t * rx_buffer,uint16_t rx_buffer_length,void * const func)54 int32_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  */
usart_async_deinit(struct usart_async_descriptor * const descr)82 int32_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  */
usart_async_enable(struct usart_async_descriptor * const descr)95 int32_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  */
usart_async_disable(struct usart_async_descriptor * const descr)106 int32_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  */
usart_async_get_io_descriptor(struct usart_async_descriptor * const descr,struct io_descriptor ** io)117 int32_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  */
usart_async_register_callback(struct usart_async_descriptor * const descr,const enum usart_async_callback_type type,usart_cb_t cb)128 int32_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  */
usart_async_set_flow_control(struct usart_async_descriptor * const descr,const union usart_flow_control_state state)156 int32_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  */
usart_async_set_baud_rate(struct usart_async_descriptor * const descr,const uint32_t baud_rate)168 int32_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  */
usart_async_set_data_order(struct usart_async_descriptor * const descr,const enum usart_data_order data_order)179 int32_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  */
usart_async_set_mode(struct usart_async_descriptor * const descr,const enum usart_mode mode)190 int32_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  */
usart_async_set_parity(struct usart_async_descriptor * const descr,const enum usart_parity parity)201 int32_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  */
usart_async_set_stopbits(struct usart_async_descriptor * const descr,const enum usart_stop_bits stop_bits)212 int32_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  */
usart_async_set_character_size(struct usart_async_descriptor * const descr,const enum usart_character_size size)223 int32_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  */
usart_async_flow_control_status(const struct usart_async_descriptor * const descr,union usart_flow_control_state * const state)234 int32_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  */
usart_async_is_tx_empty(const struct usart_async_descriptor * const descr)246 int32_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  */
usart_async_is_rx_not_empty(const struct usart_async_descriptor * const descr)255 int32_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  */
usart_async_get_status(struct usart_async_descriptor * const descr,struct usart_async_status * const status)265 int32_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  */
usart_async_flush_rx_buffer(struct usart_async_descriptor * const descr)287 int32_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  */
usart_async_get_version(void)297 uint32_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  */
usart_async_write(struct io_descriptor * const io_descr,const uint8_t * const buf,const uint16_t length)311 static 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  */
usart_async_read(struct io_descriptor * const io_descr,uint8_t * const buf,const uint16_t length)338 static 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  */
usart_process_byte_sent(struct _usart_async_device * device)362 static 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  */
usart_transmission_complete(struct _usart_async_device * device)378 static 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  */
usart_fill_rx_buffer(struct _usart_async_device * device,uint8_t data)394 static 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  */
usart_error(struct _usart_async_device * device)410 static 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 //@}
421