]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A5_SAMA5D3x_Xplained_IAR/AtmelFiles/libchip_sama5d3x/source/usart.c
Start of SAMA5D3 XPlained demo.
[freertos] / FreeRTOS / Demo / CORTEX_A5_SAMA5D3x_Xplained_IAR / AtmelFiles / libchip_sama5d3x / source / usart.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2011, 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 /** \addtogroup usart_module Working with USART\r
31  * The USART driver provides the interface to configure and use the USART peripheral.\n\r
32  *\r
33  * The USART supports several kinds of comminication modes such as full-duplex asynchronous/\r
34  * synchronous serial commnunication,RS485 with driver control signal,ISO7816,SPI and Test modes.\r
35  *\r
36  * To start a USART transfer with \ref dmad_module "DMA" support, the user could follow these steps:\r
37  * <ul>\r
38  * <li> Configure USART with expected mode and baudrate(see \ref USART_Configure), which could be done by:\r
39  * -# Resetting and disabling transmitter and receiver by setting US_CR(Control Register). </li>\r
40  * -# Conifguring the USART in a specific mode by setting USART_MODE bits in US_MR(Mode Register) </li>\r
41  * -# Setting baudrate which is different from mode to mode.\r
42    </li>\r
43  * <li> Enable transmitter or receiver respectively by set US_CR_TXEN or US_CR_RXEN in US_CR.</li>\r
44  * <li> Read from or write to the peripheral with  \ref dmad_module </li> \r
45  * </ul>\r
46  *\r
47  * For more accurate information, please look at the USART section of the\r
48  * Datasheet.\r
49  *\r
50  * Related files :\n\r
51  * \ref usart.c\n\r
52  * \ref usart.h\n\r
53 */\r
54 \r
55 \r
56 \r
57 /**\r
58  * \file\r
59  *\r
60  * Implementation of USART (Universal Synchronous Asynchronous Receiver Transmitter)\r
61  * controller.\r
62  *\r
63  */\r
64 /*------------------------------------------------------------------------------\r
65  *         Headers\r
66  *------------------------------------------------------------------------------*/\r
67 #include "chip.h"\r
68 \r
69 #include <assert.h>\r
70 #include <string.h>\r
71 \r
72 /*------------------------------------------------------------------------------\r
73  *         Exported functions\r
74  *------------------------------------------------------------------------------*/\r
75 \r
76 /**\r
77  * \brief Configures an USART peripheral with the specified parameters.\r
78  *\r
79  *\r
80  *  \param usart  Pointer to the USART peripheral to configure.\r
81  *  \param mode  Desired value for the USART mode register (see the datasheet).\r
82  *  \param baudrate  Baudrate at which the USART should operate (in Hz).\r
83  *  \param masterClock  Frequency of the system master clock (in Hz).\r
84  */\r
85 void USART_Configure(Usart *usart,\r
86                      uint32_t mode,\r
87                      uint32_t baudrate,\r
88                      uint32_t masterClock)\r
89 {\r
90     uint32_t maxClock;\r
91     uint32_t id = ID_USART0;\r
92     maxClock = masterClock;\r
93     /* Reset and disable receiver & transmitter*/\r
94     usart->US_CR = US_CR_RSTRX | US_CR_RSTTX\r
95                    | US_CR_RXDIS | US_CR_TXDIS;\r
96     if ((uint32_t)usart == (uint32_t)USART0) id = ID_USART0;\r
97        else if ((uint32_t)usart == (uint32_t)USART1) id = ID_USART1;\r
98               else if ((uint32_t)usart == (uint32_t)USART2) id = ID_USART2;\r
99                      else if ((uint32_t)usart == (uint32_t)USART3) id = ID_USART3;\r
100     /* Configure mode*/\r
101     usart->US_MR = mode;\r
102     maxClock = PMC_SetPeriMaxClock(id, masterClock);\r
103     /* Configure baudrate*/\r
104     /* Asynchronous, no oversampling*/\r
105     if (((mode & US_MR_SYNC) == 0)\r
106         && ((mode & US_MR_OVER) == 0))\r
107     {\r
108         usart->US_BRGR = (maxClock / baudrate) / 16;\r
109     }\r
110     if( ((mode & US_MR_USART_MODE_SPI_MASTER) == US_MR_USART_MODE_SPI_MASTER)\r
111      || ((mode & US_MR_SYNC) == US_MR_SYNC))\r
112     {\r
113         if( (mode & US_MR_USCLKS_Msk) == US_MR_USCLKS_MCK)\r
114         {\r
115             usart->US_BRGR = maxClock / baudrate;\r
116         }\r
117         else\r
118         {\r
119             if ( (mode & US_MR_USCLKS_DIV) == US_MR_USCLKS_DIV)\r
120             {\r
121                 usart->US_BRGR = maxClock / baudrate / 8;\r
122             }\r
123         }\r
124     }\r
125     /* TODO other modes*/\r
126 }\r
127 /**\r
128  * \brief Enables or disables the transmitter of an USART peripheral.\r
129  *\r
130  *\r
131  * \param usart  Pointer to an USART peripheral\r
132  * \param enabled  If true, the transmitter is enabled; otherwise it is\r
133  *                disabled.\r
134  */\r
135 void USART_SetTransmitterEnabled(Usart *usart, uint8_t enabled)\r
136 {\r
137     if (enabled) {\r
138 \r
139         usart->US_CR = US_CR_TXEN;\r
140     }\r
141     else {\r
142 \r
143         usart->US_CR = US_CR_TXDIS;\r
144     }\r
145 }\r
146 \r
147 /**\r
148  * \brief Enables or disables the receiver of an USART peripheral\r
149  *\r
150  *\r
151  * \param usart  Pointer to an USART peripheral\r
152  * \param enabled  If true, the receiver is enabled; otherwise it is disabled.\r
153  */\r
154 void USART_SetReceiverEnabled(Usart *usart, uint8_t enabled)\r
155 {\r
156     if (enabled) {\r
157 \r
158         usart->US_CR = US_CR_RXEN;\r
159     }\r
160     else {\r
161 \r
162         usart->US_CR = US_CR_RXDIS;\r
163     }\r
164 }\r
165 \r
166 /**\r
167  * \brief Enables or disables the Request To Send (RTS) of an USART peripheral\r
168  *\r
169  *\r
170  * \param usart  Pointer to an USART peripheral\r
171  * \param enabled  If true, the RTS is enabled (0); otherwise it is disabled.\r
172  */\r
173 void USART_SetRTSEnabled( Usart *usart, uint8_t enabled)\r
174 {\r
175     if (enabled) {\r
176     \r
177         usart->US_CR = US_CR_RTSEN;\r
178     }\r
179     else {\r
180         \r
181         usart->US_CR = US_CR_RTSDIS;\r
182     }\r
183 }\r
184 \r
185 /**\r
186  * \brief Sends one packet of data through the specified USART peripheral. This\r
187  * function operates synchronously, so it only returns when the data has been\r
188  * actually sent.\r
189  *\r
190  *\r
191  * \param usart  Pointer to an USART peripheral.\r
192  * \param data  Data to send including 9nth bit and sync field if necessary (in\r
193  *        the same format as the US_THR register in the datasheet).\r
194  * \param timeOut  Time out value (0 = no timeout).\r
195  */\r
196 void USART_Write( Usart *usart, uint16_t data, volatile uint32_t timeOut)\r
197 {\r
198     if (timeOut == 0) {\r
199 \r
200         while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);\r
201     }\r
202     else {\r
203 \r
204         while ((usart->US_CSR & US_CSR_TXEMPTY) == 0) {\r
205 \r
206             if (timeOut == 0) {\r
207 \r
208                 TRACE_ERROR("USART_Write: Timed out.\n\r");\r
209                 return;\r
210             }\r
211             timeOut--;\r
212         }\r
213     }\r
214 \r
215     usart->US_THR = data;\r
216 }\r
217 \r
218 \r
219 /**\r
220  * \brief  Reads and return a packet of data on the specified USART peripheral. This\r
221  * function operates asynchronously, so it waits until some data has been\r
222  * received.\r
223  *\r
224  * \param usart  Pointer to an USART peripheral.\r
225  * \param timeOut  Time out value (0 -> no timeout).\r
226  */\r
227 uint16_t USART_Read( Usart *usart, volatile uint32_t timeOut)\r
228 {\r
229     if (timeOut == 0) {\r
230 \r
231         while ((usart->US_CSR & US_CSR_RXRDY) == 0);\r
232     }\r
233     else {\r
234 \r
235         while ((usart->US_CSR & US_CSR_RXRDY) == 0) {\r
236 \r
237             if (timeOut == 0) {\r
238 \r
239                 TRACE_ERROR( "USART_Read: Timed out.\n\r" ) ;\r
240                 return 0;\r
241             }\r
242             timeOut--;\r
243         }\r
244     }\r
245 \r
246     return usart->US_RHR;\r
247 }\r
248 \r
249 /**\r
250  * \brief  Returns 1 if some data has been received and can be read from an USART;\r
251  * otherwise returns 0.\r
252  *\r
253  * \param usart  Pointer to an Usart instance.\r
254  */\r
255 uint8_t USART_IsDataAvailable(Usart *usart)\r
256 {\r
257     if ((usart->US_CSR & US_CSR_RXRDY) != 0) {\r
258 \r
259         return 1;\r
260     }\r
261     else {\r
262 \r
263         return 0;\r
264     }\r
265 }\r
266 \r
267 /**\r
268  * \brief  Sets the filter value for the IRDA demodulator.\r
269  *\r
270  * \param pUsart  Pointer to an Usart instance.\r
271  * \param filter  Filter value.\r
272  */\r
273 void USART_SetIrdaFilter(Usart *pUsart, uint8_t filter)\r
274 {\r
275     assert( pUsart != NULL ) ;\r
276 \r
277     pUsart->US_IF = filter;\r
278 }\r
279 \r
280 /**\r
281  * \brief  Sends one packet of data through the specified USART peripheral. This\r
282  * function operates synchronously, so it only returns when the data has been\r
283  * actually sent.\r
284  *\r
285  * \param usart  Pointer to an USART peripheral.\r
286  * \param c  Character to send\r
287  */\r
288 void USART_PutChar( Usart *usart, uint8_t c)\r
289 {\r
290     /* Wait for the transmitter to be ready*/\r
291     while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);\r
292 \r
293     /* Send character*/\r
294     usart->US_THR = c;\r
295 \r
296     /* Wait for the transfer to complete*/\r
297     while ((usart->US_CSR & US_CSR_TXEMPTY) == 0);\r
298 }\r
299 \r
300 /**\r
301  * \brief   Return 1 if a character can be read in USART\r
302  * \param usart  Pointer to an USART peripheral.\r
303  */\r
304 uint32_t USART_IsRxReady(Usart *usart)\r
305 {\r
306     return (usart->US_CSR & US_CSR_RXRDY);\r
307 }\r
308 \r
309 /**\r
310  * \brief   Get present status\r
311  * \param usart  Pointer to an USART peripheral.\r
312  */\r
313 uint32_t USART_GetStatus(Usart *usart)\r
314 {\r
315     return usart->US_CSR;\r
316 }\r
317 \r
318 /**\r
319  * \brief   Enable interrupt\r
320  * \param usart  Pointer to an USART peripheral.\r
321  * \param mode  Interrupt mode.\r
322  */\r
323 void USART_EnableIt(Usart *usart,uint32_t mode)\r
324 {\r
325     usart->US_IER = mode;\r
326 }\r
327 \r
328 /**\r
329  * \brief   Disable interrupt\r
330  * \param usart  Pointer to an USART peripheral.\r
331  * \param mode  Interrupt mode.\r
332  */\r
333 void USART_DisableIt(Usart *usart,uint32_t mode)\r
334 {\r
335     usart->US_IDR = mode;\r
336 }\r
337 \r
338 /**\r
339  * \brief   Return interrupt mask\r
340  * \param usart  Pointer to an USART peripheral.\r
341  */\r
342 uint32_t USART_GetItMask(Usart *usart)\r
343 {\r
344     return usart->US_IMR;\r
345 }\r
346 \r
347 /**\r
348  * \brief  Reads and returns a character from the USART.\r
349  *\r
350  * \note This function is synchronous (i.e. uses polling).\r
351  * \param usart  Pointer to an USART peripheral.\r
352  * \return Character received.\r
353  */\r
354 uint8_t USART_GetChar(Usart *usart)\r
355 {\r
356     while ((usart->US_CSR & US_CSR_RXRDY) == 0);\r
357     return usart->US_RHR;\r
358 }\r