]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAMV71_Xplained_IAR_Keil/libchip_samv7/source/usart.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAMV71_Xplained_IAR_Keil / libchip_samv7 / source / usart.c
1 /* ----------------------------------------------------------------------------\r
2  *         ATMEL Microcontroller Software Support \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2014, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 \r
31 /**\r
32  * \file\r
33  *\r
34  * Implementation of USART (Universal Synchronous Asynchronous Receiver Transmitter)\r
35  * controller.\r
36  *\r
37  */\r
38 /*------------------------------------------------------------------------------\r
39  *         Headers\r
40  *------------------------------------------------------------------------------*/\r
41 #include "chip.h"\r
42 \r
43 #include <assert.h>\r
44 #include <string.h>\r
45 \r
46 /*----------------------------------------------------------------------------\r
47  *        Local definitions\r
48  *----------------------------------------------------------------------------*/\r
49 \r
50 \r
51 /*------------------------------------------------------------------------------\r
52  *         Exported functions\r
53  *------------------------------------------------------------------------------*/\r
54 \r
55 /**\r
56  * \brief Configures an USART peripheral with the specified parameters.\r
57  *\r
58  *\r
59  *  \param usart  Pointer to the USART peripheral to configure.\r
60  *  \param mode  Desired value for the USART mode register (see the datasheet).\r
61  *  \param baudrate  Baudrate at which the USART should operate (in Hz).\r
62  *  \param masterClock  Frequency of the system master clock (in Hz).\r
63  */\r
64 void USART_Configure(Usart *pUsart,\r
65                             uint32_t mode,\r
66                             uint32_t baudrate,\r
67                             uint32_t masterClock)\r
68 {\r
69   \r
70    unsigned int CD, FP, BaudError, OVER, ActualBaudRate;\r
71   \r
72     /* Reset and disable receiver & transmitter*/\r
73     pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX\r
74                   | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA;\r
75     \r
76     pUsart->US_IDR = 0xFFFFFFFF;\r
77     \r
78     /* Configure baudrate*/  \r
79     BaudError = 10;\r
80     OVER = 0;\r
81     \r
82     // Configure baud rate\r
83     while (BaudError > 5)\r
84     {\r
85       \r
86       CD = (masterClock / (baudrate * 8*(2-OVER)));\r
87       FP = ((masterClock / (baudrate * (2-OVER)) ) - CD * 8);     \r
88       ActualBaudRate = (masterClock/(CD*8 + FP))/(2-OVER);\r
89       BaudError = (100-((baudrate*100/ActualBaudRate)));\r
90         \r
91       if (BaudError > 5)\r
92       {\r
93         OVER++;\r
94         if(OVER>=2)\r
95         {\r
96           assert( 0 ) ;\r
97         }\r
98       }\r
99     }\r
100     \r
101     pUsart->US_BRGR = ( US_BRGR_CD(CD) | US_BRGR_FP(FP));\r
102     \r
103     /* Configure mode*/\r
104     pUsart->US_MR = (mode |  (OVER << 19) );\r
105 \r
106     // Enable receiver and transmitter\r
107     pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;\r
108     \r
109 \r
110     /* Disable buffering for printf(). */\r
111 #if ( defined (__GNUC__) && !defined (__SAMBA__) )\r
112         setvbuf(stdout, (char *)NULL, _IONBF, 0);\r
113 #endif\r
114 \r
115 }\r
116 /**\r
117  * \brief Enables or disables the transmitter of an USART peripheral.\r
118  *\r
119  *\r
120  * \param usart  Pointer to an USART peripheral\r
121  * \param enabled  If true, the transmitter is enabled; otherwise it is\r
122  *                disabled.\r
123  */\r
124 void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled)\r
125 {\r
126     if (enabled) {\r
127 \r
128         usart->US_CR = US_CR_TXEN;\r
129     }\r
130     else {\r
131 \r
132         usart->US_CR = US_CR_TXDIS;\r
133     }\r
134 }\r
135 \r
136 /**\r
137  * \brief Enables or disables the receiver of an USART peripheral\r
138  *\r
139  *\r
140  * \param usart  Pointer to an USART peripheral\r
141  * \param enabled  If true, the receiver is enabled; otherwise it is disabled.\r
142  */\r
143 void USART_SetReceiverEnabled(Usart *usart, uint8_t enabled)\r
144 {\r
145     if (enabled) {\r
146 \r
147         usart->US_CR = US_CR_RXEN;\r
148     }\r
149     else {\r
150 \r
151         usart->US_CR = US_CR_RXDIS;\r
152     }\r
153 }\r
154 \r
155 /**\r
156  * \brief Enables or disables the Request To Send (RTS) of an USART peripheral\r
157  *\r
158  *\r
159  * \param usart  Pointer to an USART peripheral\r
160  * \param enabled  If true, the RTS is enabled (0); otherwise it is disabled.\r
161  */\r
162 void USART_SetRTSEnabled( Usart *usart, uint8_t enabled)\r
163 {\r
164     if (enabled) {\r
165     \r
166         usart->US_CR = US_CR_RTSEN;\r
167     }\r
168     else {\r
169         \r
170         usart->US_CR = US_CR_RTSDIS;\r
171     }\r
172 }\r
173 \r
174 /**\r
175  * \brief Sends one packet of data through the specified USART peripheral. This\r
176  * function operates synchronously, so it only returns when the data has been\r
177  * actually sent.\r
178  *\r
179  *\r
180  * \param usart  Pointer to an USART peripheral.\r
181  * \param data  Data to send including 9nth bit and sync field if necessary (in\r
182  *        the same format as the US_THR register in the datasheet).\r
183  * \param timeOut  Time out value (0 = no timeout).\r
184  */\r
185 void USART_Write( Usart *usart, uint16_t data, volatile uint32_t timeOut)\r
186 {\r
187     if (timeOut == 0) {\r
188 \r
189         while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);\r
190     }\r
191     else {\r
192 \r
193         while ((usart->US_CSR & US_CSR_TXEMPTY) == 0) {\r
194 \r
195             if (timeOut == 0) {\r
196 \r
197                 TRACE_ERROR("USART_Write: Timed out.\n\r");\r
198                 return;\r
199             }\r
200             timeOut--;\r
201         }\r
202     }\r
203 \r
204     usart->US_THR = data;\r
205 }\r
206 \r
207 \r
208 /**\r
209  * \brief  Reads and return a packet of data on the specified USART peripheral. This\r
210  * function operates asynchronously, so it waits until some data has been\r
211  * received.\r
212  *\r
213  * \param usart  Pointer to an USART peripheral.\r
214  * \param timeOut  Time out value (0 -> no timeout).\r
215  */\r
216 uint16_t USART_Read( Usart *usart, volatile uint32_t timeOut)\r
217 {\r
218     if (timeOut == 0) {\r
219 \r
220         while ((usart->US_CSR & US_CSR_RXRDY) == 0);\r
221     }\r
222     else {\r
223 \r
224         while ((usart->US_CSR & US_CSR_RXRDY) == 0) {\r
225 \r
226             if (timeOut == 0) {\r
227 \r
228                 TRACE_ERROR( "USART_Read: Timed out.\n\r" ) ;\r
229                 return 0;\r
230             }\r
231             timeOut--;\r
232         }\r
233     }\r
234 \r
235     return usart->US_RHR;\r
236 }\r
237 \r
238 /**\r
239  * \brief  Returns 1 if some data has been received and can be read from an USART;\r
240  * otherwise returns 0.\r
241  *\r
242  * \param usart  Pointer to an Usart instance.\r
243  */\r
244 uint8_t USART_IsDataAvailable(Usart *usart)\r
245 {\r
246     if ((usart->US_CSR & US_CSR_RXRDY) != 0) {\r
247 \r
248         return 1;\r
249     }\r
250     else {\r
251 \r
252         return 0;\r
253     }\r
254 }\r
255 \r
256 /**\r
257  * \brief  Sets the filter value for the IRDA demodulator.\r
258  *\r
259  * \param pUsart  Pointer to an Usart instance.\r
260  * \param filter  Filter value.\r
261  */\r
262 void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter)\r
263 {\r
264     assert( pUsart != NULL ) ;\r
265 \r
266     pUsart->US_IF = filter;\r
267 }\r
268 \r
269 /**\r
270  * \brief  Sends one packet of data through the specified USART peripheral. This\r
271  * function operates synchronously, so it only returns when the data has been\r
272  * actually sent.\r
273  *\r
274  * \param usart  Pointer to an USART peripheral.\r
275  * \param c  Character to send\r
276  */\r
277 void USART_PutChar( Usart *usart, uint8_t c)\r
278 {\r
279     /* Wait for the transmitter to be ready*/\r
280     while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);\r
281 \r
282     /* Send character*/\r
283     usart->US_THR = c;\r
284 \r
285     /* Wait for the transfer to complete*/\r
286     while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);\r
287 }\r
288 \r
289 /**\r
290  * \brief   Return 1 if a character can be read in USART\r
291  * \param usart  Pointer to an USART peripheral.\r
292  */\r
293 uint32_t USART_IsRxReady(Usart *usart)\r
294 {\r
295     return (usart->US_CSR & US_CSR_RXRDY);\r
296 }\r
297 \r
298 /**\r
299  * \brief   Get present status\r
300  * \param usart  Pointer to an USART peripheral.\r
301  */\r
302 uint32_t USART_GetStatus(Usart *usart)\r
303 {\r
304     return usart->US_CSR;\r
305 }\r
306 \r
307 /**\r
308  * \brief   Enable interrupt\r
309  * \param usart  Pointer to an USART peripheral.\r
310  * \param mode  Interrupt mode.\r
311  */\r
312 void USART_EnableIt(Usart *usart,uint32_t mode)\r
313 {\r
314     usart->US_IER = mode;\r
315 }\r
316 \r
317 /**\r
318  * \brief   Disable interrupt\r
319  * \param usart  Pointer to an USART peripheral.\r
320  * \param mode  Interrupt mode.\r
321  */\r
322 void USART_DisableIt(Usart *usart,uint32_t mode)\r
323 {\r
324     usart->US_IDR = mode;\r
325 }\r
326 \r
327 /**\r
328  * \brief   Return interrupt mask\r
329  * \param usart  Pointer to an USART peripheral.\r
330  */\r
331 uint32_t USART_GetItMask(Usart *usart)\r
332 {\r
333     return usart->US_IMR;\r
334 }\r
335 \r
336 /**\r
337  * \brief  Reads and returns a character from the USART.\r
338  *\r
339  * \note This function is synchronous (i.e. uses polling).\r
340  * \param usart  Pointer to an USART peripheral.\r
341  * \return Character received.\r
342  */\r
343 uint8_t USART_GetChar(Usart *usart)\r
344 {\r
345     while ((usart->US_CSR & US_CSR_RXRDY) == 0);\r
346     return usart->US_RHR;\r
347 }\r