1 /**
2  * \file
3  *
4  * \brief I/O USART related functionality implementation.
5  *
6  * Copyright (C) 2014 - 2016 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 
44 #include "hal_usart_sync.h"
45 #include <utils_assert.h>
46 #include <utils.h>
47 
48 /**
49  * \brief Driver version
50  */
51 #define DRIVER_VERSION 0x00000001u
52 
53 static int32_t usart_sync_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length);
54 static int32_t usart_sync_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length);
55 
56 /**
57  * \brief Initialize usart interface
58  */
usart_sync_init(struct usart_sync_descriptor * const descr,void * const hw,void * const func)59 int32_t usart_sync_init(struct usart_sync_descriptor *const descr, void *const hw, void *const func)
60 {
61 	int32_t init_status;
62 	ASSERT(descr && hw);
63 	init_status = _usart_sync_init(&descr->device, hw);
64 	if (init_status) {
65 		return init_status;
66 	}
67 
68 	descr->io.read  = usart_sync_read;
69 	descr->io.write = usart_sync_write;
70 
71 	return ERR_NONE;
72 }
73 
74 /**
75  * \brief Uninitialize usart interface
76  */
usart_sync_deinit(struct usart_sync_descriptor * const descr)77 int32_t usart_sync_deinit(struct usart_sync_descriptor *const descr)
78 {
79 	ASSERT(descr);
80 	_usart_sync_deinit(&descr->device);
81 
82 	descr->io.read  = NULL;
83 	descr->io.write = NULL;
84 
85 	return ERR_NONE;
86 }
87 
88 /**
89  * \brief Enable usart interface
90  */
usart_sync_enable(struct usart_sync_descriptor * const descr)91 int32_t usart_sync_enable(struct usart_sync_descriptor *const descr)
92 {
93 	ASSERT(descr);
94 	_usart_sync_enable(&descr->device);
95 
96 	return ERR_NONE;
97 }
98 
99 /**
100  * \brief Disable usart interface
101  */
usart_sync_disable(struct usart_sync_descriptor * const descr)102 int32_t usart_sync_disable(struct usart_sync_descriptor *const descr)
103 {
104 	ASSERT(descr);
105 	_usart_sync_disable(&descr->device);
106 
107 	return ERR_NONE;
108 }
109 
110 /**
111  * \brief Retrieve I/O descriptor
112  */
usart_sync_get_io_descriptor(struct usart_sync_descriptor * const descr,struct io_descriptor ** io)113 int32_t usart_sync_get_io_descriptor(struct usart_sync_descriptor *const descr, struct io_descriptor **io)
114 {
115 	ASSERT(descr && io);
116 
117 	*io = &descr->io;
118 	return ERR_NONE;
119 }
120 
121 /**
122  * \brief Specify action for flow control pins
123  */
usart_sync_set_flow_control(struct usart_sync_descriptor * const descr,const union usart_flow_control_state state)124 int32_t usart_sync_set_flow_control(struct usart_sync_descriptor *const  descr,
125                                     const union usart_flow_control_state state)
126 {
127 	ASSERT(descr);
128 	_usart_sync_set_flow_control_state(&descr->device, state);
129 
130 	return ERR_NONE;
131 }
132 
133 /**
134  * \brief Set usart baud rate
135  */
usart_sync_set_baud_rate(struct usart_sync_descriptor * const descr,const uint32_t baud_rate)136 int32_t usart_sync_set_baud_rate(struct usart_sync_descriptor *const descr, const uint32_t baud_rate)
137 {
138 	ASSERT(descr);
139 	_usart_sync_set_baud_rate(&descr->device, baud_rate);
140 
141 	return ERR_NONE;
142 }
143 
144 /**
145  * \brief Set usart data order
146  */
usart_sync_set_data_order(struct usart_sync_descriptor * const descr,const enum usart_data_order data_order)147 int32_t usart_sync_set_data_order(struct usart_sync_descriptor *const descr, const enum usart_data_order data_order)
148 {
149 	ASSERT(descr);
150 	_usart_sync_set_data_order(&descr->device, data_order);
151 
152 	return ERR_NONE;
153 }
154 
155 /**
156  * \brief Set usart mode
157  */
usart_sync_set_mode(struct usart_sync_descriptor * const descr,const enum usart_mode mode)158 int32_t usart_sync_set_mode(struct usart_sync_descriptor *const descr, const enum usart_mode mode)
159 {
160 	ASSERT(descr);
161 	_usart_sync_set_mode(&descr->device, mode);
162 
163 	return ERR_NONE;
164 }
165 
166 /**
167  * \brief Set usart parity
168  */
usart_sync_set_parity(struct usart_sync_descriptor * const descr,const enum usart_parity parity)169 int32_t usart_sync_set_parity(struct usart_sync_descriptor *const descr, const enum usart_parity parity)
170 {
171 	ASSERT(descr);
172 	_usart_sync_set_parity(&descr->device, parity);
173 
174 	return ERR_NONE;
175 }
176 
177 /**
178  * \brief Set usart stop bits
179  */
usart_sync_set_stopbits(struct usart_sync_descriptor * const descr,const enum usart_stop_bits stop_bits)180 int32_t usart_sync_set_stopbits(struct usart_sync_descriptor *const descr, const enum usart_stop_bits stop_bits)
181 {
182 	ASSERT(descr);
183 	_usart_sync_set_stop_bits(&descr->device, stop_bits);
184 
185 	return ERR_NONE;
186 }
187 
188 /**
189  * \brief Set usart character size
190  */
usart_sync_set_character_size(struct usart_sync_descriptor * const descr,const enum usart_character_size size)191 int32_t usart_sync_set_character_size(struct usart_sync_descriptor *const descr, const enum usart_character_size size)
192 {
193 	ASSERT(descr);
194 	_usart_sync_set_character_size(&descr->device, size);
195 
196 	return ERR_NONE;
197 }
198 
199 /**
200  * \brief Retrieve the state of flow control pins
201  */
usart_sync_flow_control_status(const struct usart_sync_descriptor * const descr,union usart_flow_control_state * const state)202 int32_t usart_sync_flow_control_status(const struct usart_sync_descriptor *const descr,
203                                        union usart_flow_control_state *const     state)
204 {
205 	ASSERT(descr && state);
206 	*state = _usart_sync_get_flow_control_state(&descr->device);
207 
208 	return ERR_NONE;
209 }
210 
211 /**
212  * \brief Check if the usart transmitter is empty
213  */
usart_sync_is_tx_empty(const struct usart_sync_descriptor * const descr)214 int32_t usart_sync_is_tx_empty(const struct usart_sync_descriptor *const descr)
215 {
216 	ASSERT(descr);
217 	return _usart_sync_is_byte_sent(&descr->device);
218 }
219 
220 /**
221  * \brief Check if the usart receiver is not empty
222  */
usart_sync_is_rx_not_empty(const struct usart_sync_descriptor * const descr)223 int32_t usart_sync_is_rx_not_empty(const struct usart_sync_descriptor *const descr)
224 {
225 	ASSERT(descr);
226 	return _usart_sync_is_byte_received(&descr->device);
227 }
228 
229 /**
230  * \brief Retrieve the current driver version
231  */
usart_sync_get_version(void)232 uint32_t usart_sync_get_version(void)
233 {
234 	return DRIVER_VERSION;
235 }
236 
237 /*
238  * \internal Write the given data to usart interface
239  *
240  * \param[in] descr The pointer to an io descriptor
241  * \param[in] buf Data to write to usart
242  * \param[in] length The number of bytes to write
243  *
244  * \return The number of bytes written.
245  */
usart_sync_write(struct io_descriptor * const io_descr,const uint8_t * const buf,const uint16_t length)246 static int32_t usart_sync_write(struct io_descriptor *const io_descr, const uint8_t *const buf, const uint16_t length)
247 {
248 	uint32_t                      offset = 0;
249 	struct usart_sync_descriptor *descr  = CONTAINER_OF(io_descr, struct usart_sync_descriptor, io);
250 
251 	ASSERT(io_descr && buf && length);
252 	while (!_usart_sync_is_byte_sent(&descr->device))
253 		;
254 	do {
255 		_usart_sync_write_byte(&descr->device, buf[offset]);
256 		while (!_usart_sync_is_byte_sent(&descr->device))
257 			;
258 	} while (++offset < length);
259 
260 	return (int32_t)offset;
261 }
262 
263 /*
264  * \internal Read data from usart interface
265  *
266  * \param[in] descr The pointer to an io descriptor
267  * \param[in] buf A buffer to read data to
268  * \param[in] length The size of a buffer
269  *
270  * \return The number of bytes read.
271  */
usart_sync_read(struct io_descriptor * const io_descr,uint8_t * const buf,const uint16_t length)272 static int32_t usart_sync_read(struct io_descriptor *const io_descr, uint8_t *const buf, const uint16_t length)
273 {
274 	uint32_t                      offset = 0;
275 	struct usart_sync_descriptor *descr  = CONTAINER_OF(io_descr, struct usart_sync_descriptor, io);
276 
277 	ASSERT(io_descr && buf && length);
278 	do {
279 		while (!_usart_sync_is_byte_received(&descr->device))
280 			;
281 		buf[offset] = _usart_sync_read_byte(&descr->device);
282 	} while (++offset < length);
283 
284 	return (int32_t)offset;
285 }
286