]> git.sur5r.net Git - freertos/blob
e3bae121e05a5f8fab3dc53b4c37101eba15b6ac
[freertos] /
1 /***************************************************************************//**\r
2  * @file em_leuart.h\r
3  * @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)\r
4  *   peripheral API\r
5  * @version 4.0.0\r
6  *******************************************************************************\r
7  * @section License\r
8  * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
9  *******************************************************************************\r
10  *\r
11  * Permission is granted to anyone to use this software for any purpose,\r
12  * including commercial applications, and to alter it and redistribute it\r
13  * freely, subject to the following restrictions:\r
14  *\r
15  * 1. The origin of this software must not be misrepresented; you must not\r
16  *    claim that you wrote the original software.\r
17  * 2. Altered source versions must be plainly marked as such, and must not be\r
18  *    misrepresented as being the original software.\r
19  * 3. This notice may not be removed or altered from any source distribution.\r
20  *\r
21  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
22  * obligation to support this Software. Silicon Labs is providing the\r
23  * Software "AS IS", with no express or implied warranties of any kind,\r
24  * including, but not limited to, any implied warranties of merchantability\r
25  * or fitness for any particular purpose or warranties against infringement\r
26  * of any proprietary rights of a third party.\r
27  *\r
28  * Silicon Labs will not be liable for any consequential, incidental, or\r
29  * special damages, or any other relief, or for any claim by any third party,\r
30  * arising from your use of this Software.\r
31  *\r
32  ******************************************************************************/\r
33 \r
34 \r
35 #ifndef __SILICON_LABS_EM_LEUART_H_\r
36 #define __SILICON_LABS_EM_LEUART_H_\r
37 \r
38 #include "em_device.h"\r
39 #if defined(LEUART_COUNT) && (LEUART_COUNT > 0)\r
40 \r
41 #include <stdbool.h>\r
42 \r
43 #ifdef __cplusplus\r
44 extern "C" {\r
45 #endif\r
46 \r
47 /***************************************************************************//**\r
48  * @addtogroup EM_Library\r
49  * @{\r
50  ******************************************************************************/\r
51 \r
52 /***************************************************************************//**\r
53  * @addtogroup LEUART\r
54  * @{\r
55  ******************************************************************************/\r
56 \r
57 /*******************************************************************************\r
58  ********************************   ENUMS   ************************************\r
59  ******************************************************************************/\r
60 \r
61 /** Databit selection. */\r
62 typedef enum\r
63 {\r
64   leuartDatabits8 = LEUART_CTRL_DATABITS_EIGHT,     /**< 8 databits. */\r
65   leuartDatabits9 = LEUART_CTRL_DATABITS_NINE       /**< 9 databits. */\r
66 } LEUART_Databits_TypeDef;\r
67 \r
68 \r
69 /** Enable selection. */\r
70 typedef enum\r
71 {\r
72   /** Disable both receiver and transmitter. */\r
73   leuartDisable  = 0x0,\r
74 \r
75   /** Enable receiver only, transmitter disabled. */\r
76   leuartEnableRx = LEUART_CMD_RXEN,\r
77 \r
78   /** Enable transmitter only, receiver disabled. */\r
79   leuartEnableTx = LEUART_CMD_TXEN,\r
80 \r
81   /** Enable both receiver and transmitter. */\r
82   leuartEnable   = (LEUART_CMD_RXEN | LEUART_CMD_TXEN)\r
83 } LEUART_Enable_TypeDef;\r
84 \r
85 \r
86 /** Parity selection. */\r
87 typedef enum\r
88 {\r
89   leuartNoParity   = LEUART_CTRL_PARITY_NONE,    /**< No parity. */\r
90   leuartEvenParity = LEUART_CTRL_PARITY_EVEN,    /**< Even parity. */\r
91   leuartOddParity  = LEUART_CTRL_PARITY_ODD      /**< Odd parity. */\r
92 } LEUART_Parity_TypeDef;\r
93 \r
94 \r
95 /** Stopbits selection. */\r
96 typedef enum\r
97 {\r
98   leuartStopbits1 = LEUART_CTRL_STOPBITS_ONE,           /**< 1 stopbits. */\r
99   leuartStopbits2 = LEUART_CTRL_STOPBITS_TWO            /**< 2 stopbits. */\r
100 } LEUART_Stopbits_TypeDef;\r
101 \r
102 \r
103 /*******************************************************************************\r
104  *******************************   STRUCTS   ***********************************\r
105  ******************************************************************************/\r
106 \r
107 /** Init structure. */\r
108 typedef struct\r
109 {\r
110   /** Specifies whether TX and/or RX shall be enabled when init completed. */\r
111   LEUART_Enable_TypeDef   enable;\r
112 \r
113   /**\r
114    * LEUART reference clock assumed when configuring baudrate setup. Set\r
115    * it to 0 if currently configurated reference clock shall be used.\r
116    */\r
117   uint32_t                refFreq;\r
118 \r
119   /** Desired baudrate. */\r
120   uint32_t                baudrate;\r
121 \r
122   /** Number of databits in frame. */\r
123   LEUART_Databits_TypeDef databits;\r
124 \r
125   /** Parity mode to use. */\r
126   LEUART_Parity_TypeDef   parity;\r
127 \r
128   /** Number of stopbits to use. */\r
129   LEUART_Stopbits_TypeDef stopbits;\r
130 } LEUART_Init_TypeDef;\r
131 \r
132 /** Default config for LEUART init structure. */\r
133 #define LEUART_INIT_DEFAULT                                                                   \\r
134   { leuartEnable,      /* Enable RX/TX when init completed. */                                \\r
135     0,                 /* Use current configured reference clock for configuring baudrate. */ \\r
136     9600,              /* 9600 bits/s. */                                                     \\r
137     leuartDatabits8,   /* 8 databits. */                                                      \\r
138     leuartNoParity,    /* No parity. */                                                       \\r
139     leuartStopbits1    /* 1 stopbit. */                                                       \\r
140   }\r
141 \r
142 \r
143 /*******************************************************************************\r
144  *****************************   PROTOTYPES   **********************************\r
145  ******************************************************************************/\r
146 \r
147 uint32_t LEUART_BaudrateCalc(uint32_t refFreq, uint32_t clkdiv);\r
148 uint32_t LEUART_BaudrateGet(LEUART_TypeDef *leuart);\r
149 void LEUART_BaudrateSet(LEUART_TypeDef *leuart,\r
150                         uint32_t refFreq,\r
151                         uint32_t baudrate);\r
152 void LEUART_Enable(LEUART_TypeDef *leuart, LEUART_Enable_TypeDef enable);\r
153 void LEUART_FreezeEnable(LEUART_TypeDef *leuart, bool enable);\r
154 void LEUART_Init(LEUART_TypeDef *leuart, LEUART_Init_TypeDef const *init);\r
155 void LEUART_TxDmaInEM2Enable(LEUART_TypeDef *leuart, bool enable);\r
156 void LEUART_RxDmaInEM2Enable(LEUART_TypeDef *leuart, bool enable);\r
157 \r
158 /***************************************************************************//**\r
159  * @brief\r
160  *   Clear one or more pending LEUART interrupts.\r
161  *\r
162  * @param[in] leuart\r
163  *   Pointer to LEUART peripheral register block.\r
164  *\r
165  * @param[in] flags\r
166  *   Pending LEUART interrupt source to clear. Use a bitwise logic OR\r
167  *   combination of valid interrupt flags for the LEUART module (LEUART_IF_nnn).\r
168  ******************************************************************************/\r
169 __STATIC_INLINE void LEUART_IntClear(LEUART_TypeDef *leuart, uint32_t flags)\r
170 {\r
171   leuart->IFC = flags;\r
172 }\r
173 \r
174 \r
175 /***************************************************************************//**\r
176  * @brief\r
177  *   Disable one or more LEUART interrupts.\r
178  *\r
179  * @param[in] leuart\r
180  *   Pointer to LEUART peripheral register block.\r
181  *\r
182  * @param[in] flags\r
183  *   LEUART interrupt sources to disable. Use a bitwise logic OR combination of\r
184  *   valid interrupt flags for the LEUART module (LEUART_IF_nnn).\r
185  ******************************************************************************/\r
186 __STATIC_INLINE void LEUART_IntDisable(LEUART_TypeDef *leuart, uint32_t flags)\r
187 {\r
188   leuart->IEN &= ~(flags);\r
189 }\r
190 \r
191 \r
192 /***************************************************************************//**\r
193  * @brief\r
194  *   Enable one or more LEUART interrupts.\r
195  *\r
196  * @note\r
197  *   Depending on the use, a pending interrupt may already be set prior to\r
198  *   enabling the interrupt. Consider using LEUART_IntClear() prior to enabling\r
199  *   if such a pending interrupt should be ignored.\r
200  *\r
201  * @param[in] leuart\r
202  *   Pointer to LEUART peripheral register block.\r
203  *\r
204  * @param[in] flags\r
205  *   LEUART interrupt sources to enable. Use a bitwise logic OR combination of\r
206  *   valid interrupt flags for the LEUART module (LEUART_IF_nnn).\r
207  ******************************************************************************/\r
208 __STATIC_INLINE void LEUART_IntEnable(LEUART_TypeDef *leuart, uint32_t flags)\r
209 {\r
210   leuart->IEN |= flags;\r
211 }\r
212 \r
213 \r
214 /***************************************************************************//**\r
215  * @brief\r
216  *   Get pending LEUART interrupt flags.\r
217  *\r
218  * @note\r
219  *   The event bits are not cleared by the use of this function.\r
220  *\r
221  * @param[in] leuart\r
222  *   Pointer to LEUART peripheral register block.\r
223  *\r
224  * @return\r
225  *   LEUART interrupt sources pending. A bitwise logic OR combination of valid\r
226  *   interrupt flags for the LEUART module (LEUART_IF_nnn).\r
227  ******************************************************************************/\r
228 __STATIC_INLINE uint32_t LEUART_IntGet(LEUART_TypeDef *leuart)\r
229 {\r
230   return(leuart->IF);\r
231 }\r
232 \r
233 \r
234 /***************************************************************************//**\r
235  * @brief\r
236  *   Get enabled and pending LEUART interrupt flags.\r
237  *   Useful for handling more interrupt sources in the same interrupt handler.\r
238  *\r
239  * @param[in] leuart\r
240  *   Pointer to LEUART peripheral register block.\r
241  *\r
242  * @note\r
243  *   Interrupt flags are not cleared by the use of this function.\r
244  *\r
245  * @return\r
246  *   Pending and enabled LEUART interrupt sources.\r
247  *   The return value is the bitwise AND combination of\r
248  *   - the OR combination of enabled interrupt sources in LEUARTx_IEN_nnn\r
249  *     register (LEUARTx_IEN_nnn) and\r
250  *   - the OR combination of valid interrupt flags of the LEUART module\r
251  *     (LEUARTx_IF_nnn).\r
252  ******************************************************************************/\r
253 __STATIC_INLINE uint32_t LEUART_IntGetEnabled(LEUART_TypeDef *leuart)\r
254 {\r
255   uint32_t tmp;\r
256 \r
257   /* Store LEUARTx->IEN in temporary variable in order to define explicit order\r
258    * of volatile accesses. */\r
259   tmp = leuart->IEN;\r
260 \r
261   /* Bitwise AND of pending and enabled interrupts */\r
262   return leuart->IF & tmp;\r
263 }\r
264 \r
265 \r
266 /***************************************************************************//**\r
267  * @brief\r
268  *   Set one or more pending LEUART interrupts from SW.\r
269  *\r
270  * @param[in] leuart\r
271  *   Pointer to LEUART peripheral register block.\r
272  *\r
273  * @param[in] flags\r
274  *   LEUART interrupt sources to set to pending. Use a bitwise logic OR\r
275  *   combination of valid interrupt flags for the LEUART module (LEUART_IF_nnn).\r
276  ******************************************************************************/\r
277 __STATIC_INLINE void LEUART_IntSet(LEUART_TypeDef *leuart, uint32_t flags)\r
278 {\r
279   leuart->IFS = flags;\r
280 }\r
281 \r
282 \r
283 /***************************************************************************//**\r
284  * @brief\r
285  *   Get LEUART STATUS register.\r
286  *\r
287  * @param[in] leuart\r
288  *   Pointer to LEUART peripheral register block.\r
289  *\r
290  * @return\r
291  *  STATUS register value.\r
292  *\r
293  ******************************************************************************/\r
294 __STATIC_INLINE uint32_t LEUART_StatusGet(LEUART_TypeDef *leuart)\r
295 {\r
296   return leuart->STATUS;\r
297 }\r
298 \r
299 void LEUART_Reset(LEUART_TypeDef *leuart);\r
300 uint8_t LEUART_Rx(LEUART_TypeDef *leuart);\r
301 uint16_t LEUART_RxExt(LEUART_TypeDef *leuart);\r
302 void LEUART_Tx(LEUART_TypeDef *leuart, uint8_t data);\r
303 void LEUART_TxExt(LEUART_TypeDef *leuart, uint16_t data);\r
304 \r
305 \r
306 /***************************************************************************//**\r
307  * @brief\r
308  *   Receive one 8 bit frame, (or part of a 9 bit frame).\r
309  *\r
310  * @details\r
311  *   This function is used to quickly receive one 8 bit frame by reading the\r
312  *   RXDATA register directly, without checking the STATUS register for the\r
313  *   RXDATAV flag. This can be useful from the RXDATAV interrupt handler,\r
314  *   i.e. waiting is superfluous, in order to quickly read the received data.\r
315  *   Please refer to @ref LEUART_RxDataXGet() for reception of 9 bit frames.\r
316  *\r
317  * @note\r
318  *   Since this function does not check whether the RXDATA register actually\r
319  *   holds valid data, it should only be used in situations when it is certain\r
320  *   that there is valid data, ensured by some external program routine, e.g.\r
321  *   like when handling an RXDATAV interrupt. The @ref LEUART_Rx() is normally a\r
322  *   better choice if the validity of the RXDATA register is not certain.\r
323  *\r
324  * @note\r
325  *   Notice that possible parity/stop bits are not\r
326  *   considered part of specified frame bit length.\r
327  *\r
328  * @param[in] leuart\r
329  *   Pointer to LEUART peripheral register block.\r
330  *\r
331  * @return\r
332  *   Data received.\r
333  ******************************************************************************/\r
334 __STATIC_INLINE uint8_t LEUART_RxDataGet(LEUART_TypeDef *leuart)\r
335 {\r
336   return (uint8_t) (leuart->RXDATA);\r
337 }\r
338 \r
339 \r
340 /***************************************************************************//**\r
341  * @brief\r
342  *   Receive one 8-9 bit frame, with extended information.\r
343  *\r
344  * @details\r
345  *   This function is used to quickly receive one 8-9 bit frame with extended \r
346  *   information by reading the RXDATAX register directly, without checking the \r
347  *   STATUS register for the RXDATAV flag. This can be useful from the RXDATAV \r
348  *   interrupt handler, i.e. waiting is superfluous, in order to quickly read \r
349  *   the received data.\r
350  *\r
351  * @note\r
352  *   Since this function does not check whether the RXDATAX register actually\r
353  *   holds valid data, it should only be used in situations when it is certain\r
354  *   that there is valid data, ensured by some external program routine, e.g.\r
355  *   like when handling an RXDATAV interrupt. The @ref LEUART_RxExt() is normally\r
356  *   a better choice if the validity of the RXDATAX register is not certain.\r
357  *\r
358  * @note\r
359  *   Notice that possible parity/stop bits are not\r
360  *   considered part of specified frame bit length.\r
361  *\r
362  * @param[in] leuart\r
363  *   Pointer to LEUART peripheral register block.\r
364  *\r
365  * @return\r
366  *   Data received.\r
367  ******************************************************************************/\r
368 __STATIC_INLINE uint16_t LEUART_RxDataXGet(LEUART_TypeDef *leuart)\r
369 {\r
370   return (uint16_t) (leuart->RXDATAX);\r
371 }\r
372 \r
373 \r
374 /** @} (end addtogroup LEUART) */\r
375 /** @} (end addtogroup EM_Library) */\r
376 \r
377 #ifdef __cplusplus\r
378 }\r
379 #endif\r
380 \r
381 #endif /* defined(LEUART_COUNT) && (LEUART_COUNT > 0) */\r
382 \r
383 #endif /* __SILICON_LABS_EM_LEUART_H_ */\r