1 /***************************************************************************//**
\r
3 * @brief Low Energy Universal Asynchronous Receiver/Transmitter (LEUART)
\r
6 *******************************************************************************
\r
8 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
\r
9 *******************************************************************************
\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
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
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
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
32 ******************************************************************************/
\r
34 #ifndef __SILICON_LABS_EM_LEUART_H__
\r
35 #define __SILICON_LABS_EM_LEUART_H__
\r
37 #include "em_device.h"
\r
38 #if defined(LEUART_COUNT) && (LEUART_COUNT > 0)
\r
40 #include <stdbool.h>
\r
46 /***************************************************************************//**
\r
47 * @addtogroup EM_Library
\r
49 ******************************************************************************/
\r
51 /***************************************************************************//**
\r
52 * @addtogroup LEUART
\r
54 ******************************************************************************/
\r
56 /*******************************************************************************
\r
57 ******************************** ENUMS ************************************
\r
58 ******************************************************************************/
\r
60 /** Databit selection. */
\r
63 leuartDatabits8 = LEUART_CTRL_DATABITS_EIGHT, /**< 8 databits. */
\r
64 leuartDatabits9 = LEUART_CTRL_DATABITS_NINE /**< 9 databits. */
\r
65 } LEUART_Databits_TypeDef;
\r
68 /** Enable selection. */
\r
71 /** Disable both receiver and transmitter. */
\r
72 leuartDisable = 0x0,
\r
74 /** Enable receiver only, transmitter disabled. */
\r
75 leuartEnableRx = LEUART_CMD_RXEN,
\r
77 /** Enable transmitter only, receiver disabled. */
\r
78 leuartEnableTx = LEUART_CMD_TXEN,
\r
80 /** Enable both receiver and transmitter. */
\r
81 leuartEnable = (LEUART_CMD_RXEN | LEUART_CMD_TXEN)
\r
82 } LEUART_Enable_TypeDef;
\r
85 /** Parity selection. */
\r
88 leuartNoParity = LEUART_CTRL_PARITY_NONE, /**< No parity. */
\r
89 leuartEvenParity = LEUART_CTRL_PARITY_EVEN, /**< Even parity. */
\r
90 leuartOddParity = LEUART_CTRL_PARITY_ODD /**< Odd parity. */
\r
91 } LEUART_Parity_TypeDef;
\r
94 /** Stopbits selection. */
\r
97 leuartStopbits1 = LEUART_CTRL_STOPBITS_ONE, /**< 1 stopbits. */
\r
98 leuartStopbits2 = LEUART_CTRL_STOPBITS_TWO /**< 2 stopbits. */
\r
99 } LEUART_Stopbits_TypeDef;
\r
102 /*******************************************************************************
\r
103 ******************************* STRUCTS ***********************************
\r
104 ******************************************************************************/
\r
106 /** Init structure. */
\r
109 /** Specifies whether TX and/or RX shall be enabled when init completed. */
\r
110 LEUART_Enable_TypeDef enable;
\r
113 * LEUART reference clock assumed when configuring baudrate setup. Set
\r
114 * it to 0 if currently configurated reference clock shall be used.
\r
118 /** Desired baudrate. */
\r
121 /** Number of databits in frame. */
\r
122 LEUART_Databits_TypeDef databits;
\r
124 /** Parity mode to use. */
\r
125 LEUART_Parity_TypeDef parity;
\r
127 /** Number of stopbits to use. */
\r
128 LEUART_Stopbits_TypeDef stopbits;
\r
129 } LEUART_Init_TypeDef;
\r
131 /** Default config for LEUART init structure. */
\r
132 #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
143 /*******************************************************************************
\r
144 ***************************** PROTOTYPES **********************************
\r
145 ******************************************************************************/
\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
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
158 /***************************************************************************//**
\r
160 * Clear one or more pending LEUART interrupts.
\r
162 * @param[in] leuart
\r
163 * Pointer to LEUART peripheral register block.
\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
171 leuart->IFC = flags;
\r
175 /***************************************************************************//**
\r
177 * Disable one or more LEUART interrupts.
\r
179 * @param[in] leuart
\r
180 * Pointer to LEUART peripheral register block.
\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
188 leuart->IEN &= ~flags;
\r
192 /***************************************************************************//**
\r
194 * Enable one or more LEUART interrupts.
\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
201 * @param[in] leuart
\r
202 * Pointer to LEUART peripheral register block.
\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
210 leuart->IEN |= flags;
\r
214 /***************************************************************************//**
\r
216 * Get pending LEUART interrupt flags.
\r
219 * The event bits are not cleared by the use of this function.
\r
221 * @param[in] leuart
\r
222 * Pointer to LEUART peripheral register block.
\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
234 /***************************************************************************//**
\r
236 * Get enabled and pending LEUART interrupt flags.
\r
237 * Useful for handling more interrupt sources in the same interrupt handler.
\r
239 * @param[in] leuart
\r
240 * Pointer to LEUART peripheral register block.
\r
243 * Interrupt flags are not cleared by the use of this function.
\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
257 /* Store LEUARTx->IEN in temporary variable in order to define explicit order
\r
258 * of volatile accesses. */
\r
261 /* Bitwise AND of pending and enabled interrupts */
\r
262 return leuart->IF & tmp;
\r
266 /***************************************************************************//**
\r
268 * Set one or more pending LEUART interrupts from SW.
\r
270 * @param[in] leuart
\r
271 * Pointer to LEUART peripheral register block.
\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
279 leuart->IFS = flags;
\r
283 /***************************************************************************//**
\r
285 * Get LEUART STATUS register.
\r
287 * @param[in] leuart
\r
288 * Pointer to LEUART peripheral register block.
\r
291 * STATUS register value.
\r
293 ******************************************************************************/
\r
294 __STATIC_INLINE uint32_t LEUART_StatusGet(LEUART_TypeDef *leuart)
\r
296 return leuart->STATUS;
\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
306 /***************************************************************************//**
\r
308 * Receive one 8 bit frame, (or part of a 9 bit frame).
\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
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
325 * Notice that possible parity/stop bits are not
\r
326 * considered part of specified frame bit length.
\r
328 * @param[in] leuart
\r
329 * Pointer to LEUART peripheral register block.
\r
333 ******************************************************************************/
\r
334 __STATIC_INLINE uint8_t LEUART_RxDataGet(LEUART_TypeDef *leuart)
\r
336 return (uint8_t)leuart->RXDATA;
\r
340 /***************************************************************************//**
\r
342 * Receive one 8-9 bit frame, with extended information.
\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
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
359 * Notice that possible parity/stop bits are not
\r
360 * considered part of specified frame bit length.
\r
362 * @param[in] leuart
\r
363 * Pointer to LEUART peripheral register block.
\r
367 ******************************************************************************/
\r
368 __STATIC_INLINE uint16_t LEUART_RxDataXGet(LEUART_TypeDef *leuart)
\r
370 return (uint16_t)leuart->RXDATAX;
\r
374 /** @} (end addtogroup LEUART) */
\r
375 /** @} (end addtogroup EM_Library) */
\r
381 #endif /* defined(LEUART_COUNT) && (LEUART_COUNT > 0) */
\r
382 #endif /* __SILICON_LABS_EM_LEUART_H__ */
\r