1 /*
2  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of the copyright holder nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifndef _FSL_LPSCI_H_
31 #define _FSL_LPSCI_H_
32 
33 #include "fsl_common.h"
34 
35 /*!
36  * @addtogroup lpsci_driver
37  * @{
38  */
39 
40 /*******************************************************************************
41  * Definitions
42  ******************************************************************************/
43 
44 /*! @name Driver version */
45 /*@{*/
46 /*! @brief LPSCI driver version 2.0.3. */
47 #define FSL_LPSCI_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
48 /*@{*/
49 
50 /*! @brief Error codes for the LPSCI driver. */
51 enum _lpsci_status
52 {
53     kStatus_LPSCI_TxBusy = MAKE_STATUS(kStatusGroup_LPSCI, 0), /*!< Transmitter is busy. */
54     kStatus_LPSCI_RxBusy = MAKE_STATUS(kStatusGroup_LPSCI, 1), /*!< Receiver is busy. */
55     kStatus_LPSCI_TxIdle = MAKE_STATUS(kStatusGroup_LPSCI, 2), /*!< Transmitter is idle. */
56     kStatus_LPSCI_RxIdle = MAKE_STATUS(kStatusGroup_LPSCI, 3), /*!< Receiver is idle. */
57     kStatus_LPSCI_FlagCannotClearManually =
58         MAKE_STATUS(kStatusGroup_LPSCI, 4), /*!< Status flag can't be manually cleared. */
59     kStatus_LPSCI_BaudrateNotSupport =
60         MAKE_STATUS(kStatusGroup_LPSCI, 5),                   /*!< Baudrate is not support in current clock source */
61     kStatus_LPSCI_Error = MAKE_STATUS(kStatusGroup_LPSCI, 6), /*!< Error happens on LPSCI */
62     kStatus_LPSCI_RxRingBufferOverrun =
63         MAKE_STATUS(kStatusGroup_LPSCI, 7),                               /*!< LPSCI RX software ring buffer overrun. */
64     kStatus_LPSCI_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPSCI, 8), /*!< LPSCI RX receiver overrun. */
65     kStatus_LPSCI_NoiseError = MAKE_STATUS(kStatusGroup_LPSCI, 9),        /*!< LPSCI noise error. */
66     kStatus_LPSCI_FramingError = MAKE_STATUS(kStatusGroup_LPSCI, 10),     /*!< LPSCI framing error. */
67     kStatus_LPSCI_ParityError = MAKE_STATUS(kStatusGroup_LPSCI, 11),      /*!< LPSCI parity error. */
68 };
69 
70 /*! @brief LPSCI parity mode.*/
71 typedef enum _lpsci_parity_mode
72 {
73     kLPSCI_ParityDisabled = 0x0U, /*!< Parity disabled */
74     kLPSCI_ParityEven = 0x2U,     /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
75     kLPSCI_ParityOdd = 0x3U,      /*!< Parity enabled, type odd,  bit setting: PE|PT = 11 */
76 } lpsci_parity_mode_t;
77 
78 /*! @brief LPSCI stop bit count.*/
79 typedef enum _lpsci_stop_bit_count
80 {
81     kLPSCI_OneStopBit = 0U, /*!< One stop bit */
82     kLPSCI_TwoStopBit = 1U, /*!< Two stop bits */
83 } lpsci_stop_bit_count_t;
84 
85 /*!
86  * @brief LPSCI interrupt configuration structure, default settings all disabled.
87  *
88  * This structure contains the settings for all LPSCI interrupt configurations.
89  */
90 enum _lpsci_interrupt_enable_t
91 {
92 #if defined(FSL_FEATURE_LPSCI_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPSCI_HAS_LIN_BREAK_DETECT
93     kLPSCI_LinBreakInterruptEnable = (UART0_BDH_LBKDIE_MASK), /*!< LIN break detect interrupt. */
94 #endif
95     kLPSCI_RxActiveEdgeInterruptEnable = (UART0_BDH_RXEDGIE_MASK),   /*!< RX Active Edge interrupt. */
96     kLPSCI_TxDataRegEmptyInterruptEnable = (UART0_C2_TIE_MASK << 8), /*!< Transmit data register empty interrupt. */
97     kLPSCI_TransmissionCompleteInterruptEnable = (UART0_C2_TCIE_MASK << 8), /*!< Transmission complete interrupt. */
98     kLPSCI_RxDataRegFullInterruptEnable = (UART0_C2_RIE_MASK << 8),  /*!< Receiver data register full interrupt. */
99     kLPSCI_IdleLineInterruptEnable = (UART0_C2_ILIE_MASK << 8),      /*!< Idle line interrupt. */
100     kLPSCI_RxOverrunInterruptEnable = (UART0_C3_ORIE_MASK << 16),    /*!< Receiver Overrun interrupt. */
101     kLPSCI_NoiseErrorInterruptEnable = (UART0_C3_NEIE_MASK << 16),   /*!< Noise error flag interrupt. */
102     kLPSCI_FramingErrorInterruptEnable = (UART0_C3_FEIE_MASK << 16), /*!< Framing error flag interrupt. */
103     kLPSCI_ParityErrorInterruptEnable = (UART0_C3_PEIE_MASK << 16),  /*!< Parity error flag interrupt. */
104     kLPSCI_AllInterruptsEnable = kLPSCI_RxActiveEdgeInterruptEnable | kLPSCI_TxDataRegEmptyInterruptEnable |
105                                  kLPSCI_TransmissionCompleteInterruptEnable | kLPSCI_RxDataRegFullInterruptEnable |
106                                  kLPSCI_IdleLineInterruptEnable | kLPSCI_RxOverrunInterruptEnable |
107                                  kLPSCI_NoiseErrorInterruptEnable | kLPSCI_FramingErrorInterruptEnable |
108                                  kLPSCI_ParityErrorInterruptEnable
109 #if defined(FSL_FEATURE_LPSCI_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPSCI_HAS_LIN_BREAK_DETECT
110                                  |
111                                  kLPSCI_LinBreakInterruptEnable
112 #endif
113     ,
114 };
115 
116 /*!
117  * @brief LPSCI status flags.
118  *
119  * This provides constants for the LPSCI status flags for use in the LPSCI functions.
120  */
121 enum _lpsci_status_flag_t
122 {
123     kLPSCI_TxDataRegEmptyFlag = (UART0_S1_TDRE_MASK), /*!< Tx data register empty flag, sets when Tx buffer is empty */
124     kLPSCI_TransmissionCompleteFlag =
125         (UART0_S1_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */
126     kLPSCI_RxDataRegFullFlag =
127         (UART0_S1_RDRF_MASK), /*!< Rx data register full flag, sets when the receive data buffer is full */
128     kLPSCI_IdleLineFlag = (UART0_S1_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */
129     kLPSCI_RxOverrunFlag =
130         (UART0_S1_OR_MASK), /*!< Rx Overrun, sets when new data is received before data is read from receive register */
131     kLPSCI_NoiseErrorFlag = (UART0_S1_NF_MASK), /*!< Rx takes 3 samples of each received bit. If any of these samples
132                                                    differ, noise flag sets */
133     kLPSCI_FramingErrorFlag =
134         (UART0_S1_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */
135     kLPSCI_ParityErrorFlag = (UART0_S1_PF_MASK), /*!< If parity enabled, sets upon parity error detection */
136 #if defined(FSL_FEATURE_LPSCI_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPSCI_HAS_LIN_BREAK_DETECT
137     kLPSCI_LinBreakFlag =
138         (UART0_S2_LBKDIF_MASK
139          << 8), /*!< LIN break detect interrupt flag, sets when LIN break char detected and LIN circuit enabled */
140 #endif
141     kLPSCI_RxActiveEdgeFlag =
142         (UART0_S2_RXEDGIF_MASK << 8), /*!< Rx pin active edge interrupt flag, sets when active edge detected */
143     kLPSCI_RxActiveFlag =
144         (UART0_S2_RAF_MASK << 8), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */
145 #if defined(FSL_FEATURE_LPSCI_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPSCI_HAS_EXTENDED_DATA_REGISTER_FLAGS
146     kLPSCI_NoiseErrorInRxDataRegFlag =
147         (UART0_ED_NOISY_MASK << 16), /*!< NOISY bit, sets if noise detected in current data word */
148     kLPSCI_ParityErrorInRxDataRegFlag =
149         (UART0_ED_PARITYE_MASK << 16), /*!< PARITYE bit, sets if noise detected in current data word */
150 #endif
151 };
152 
153 /*! @brief LPSCI configure structure.*/
154 typedef struct _lpsci_config
155 {
156     uint32_t baudRate_Bps;          /*!< LPSCI baud rate  */
157     lpsci_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
158 #if defined(FSL_FEATURE_LPSCI_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPSCI_HAS_STOP_BIT_CONFIG_SUPPORT
159     lpsci_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits  */
160 #endif
161     bool enableTx; /*!< Enable TX */
162     bool enableRx; /*!< Enable RX */
163 } lpsci_config_t;
164 
165 /*! @brief LPSCI transfer structure. */
166 typedef struct _lpsci_transfer
167 {
168     uint8_t *data;   /*!< The buffer of data to be transfer.*/
169     size_t dataSize; /*!< The byte count to be transfer. */
170 } lpsci_transfer_t;
171 
172 /* Forward declaration of the handle typedef. */
173 typedef struct _lpsci_handle lpsci_handle_t;
174 
175 /*! @brief LPSCI transfer callback function. */
176 typedef void (*lpsci_transfer_callback_t)(UART0_Type *base, lpsci_handle_t *handle, status_t status, void *userData);
177 
178 /*<! @brief LPSCI handle used for storing the state among transactional APIs' calling. This structure is only used for
179  * transactional APIs. */
180 struct _lpsci_handle
181 {
182     uint8_t *volatile txData;   /*!< Address of remaining data to send. */
183     volatile size_t txDataSize; /*!< Size of the remaining data to send. */
184     size_t txDataSizeAll;       /*!< Size of the data to send out. */
185     uint8_t *volatile rxData;   /*!< Address of remaining data to receive. */
186     volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
187     size_t rxDataSizeAll;       /*!< Size of the data to receive. */
188 
189     uint8_t *rxRingBuffer;              /*!< Start address of the receiver ring buffer. */
190     size_t rxRingBufferSize;            /*!< Size of the ring buffer. */
191     volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
192     volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
193 
194     lpsci_transfer_callback_t callback; /*!< Callback function. */
195     void *userData;                     /*!< LPSCI callback function parameter.*/
196 
197     volatile uint8_t txState; /*!< TX transfer state. */
198     volatile uint8_t rxState; /*!< RX transfer state */
199 };
200 
201 /*******************************************************************************
202  * API
203  ******************************************************************************/
204 
205 #if defined(__cplusplus)
206 extern "C" {
207 #endif /* _cplusplus */
208 
209 /*!
210  * @name Initialization and deinitialization
211  * @{
212  */
213 
214 /*!
215 * @brief Initializes an LPSCI instance with the user configuration structure and the peripheral clock.
216 *
217 * This function configures the LPSCI module with user-defined settings. The user can configure the configuration
218 * structure and can also get the default configuration by calling the LPSCI_GetDefaultConfig() function.
219 * Example below shows how to use this API to configure the LPSCI.
220 *  @code
221 *   lpsci_config_t lpsciConfig;
222 *   lpsciConfig.baudRate_Bps = 115200U;
223 *   lpsciConfig.parityMode = kLPSCI_ParityDisabled;
224 *   lpsciConfig.stopBitCount = kLPSCI_OneStopBit;
225 *   LPSCI_Init(UART0, &lpsciConfig, 20000000U);
226 *   @endcode
227 *
228 * @param base LPSCI peripheral base address.
229 * @param config Pointer to user-defined configuration structure.
230 * @param srcClock_Hz LPSCI clock source frequency in HZ.
231 * @retval kStatus_LPSCI_BaudrateNotSupport Baudrate is not support in current clock source.
232 * @retval kStatus_Success LPSCI initialize succeed
233 */
234 status_t LPSCI_Init(UART0_Type *base, const lpsci_config_t *config, uint32_t srcClock_Hz);
235 
236 /*!
237  * @brief Deinitializes an LPSCI instance.
238  *
239  * This function waits for TX complete, disables TX and RX, and disables the LPSCI clock.
240  *
241  * @param base LPSCI peripheral base address.
242  */
243 void LPSCI_Deinit(UART0_Type *base);
244 
245 /*!
246  * @brief Gets the default configuration structure and saves the configuration to a user-provided pointer.
247  *
248  * This function initializes the LPSCI configure structure to default value. the default
249  * value are:
250  *   lpsciConfig->baudRate_Bps = 115200U;
251  *   lpsciConfig->parityMode = kLPSCI_ParityDisabled;
252  *   lpsciConfig->stopBitCount = kLPSCI_OneStopBit;
253  *   lpsciConfig->enableTx = false;
254  *   lpsciConfig->enableRx = false;
255  *
256  * @param config Pointer to configuration structure.
257  */
258 void LPSCI_GetDefaultConfig(lpsci_config_t *config);
259 
260 /*!
261  * @brief Sets the LPSCI instance baudrate.
262  *
263  * This function configures the LPSCI module baudrate. This function is used to update
264  * the LPSCI module baudrate after the LPSCI module is initialized with the LPSCI_Init.
265  * @code
266  *  LPSCI_SetBaudRate(UART0, 115200U, 20000000U);
267  * @endcode
268  *
269  * @param base LPSCI peripheral base address.
270  * @param baudRate_Bps LPSCI baudrate to be set.
271  * @param srcClock_Hz LPSCI clock source frequency in HZ.
272  * @retval kStatus_LPSCI_BaudrateNotSupport Baudrate is not supported in the current clock source.
273  * @retval kStatus_Success Set baudrate succeed
274  */
275 status_t LPSCI_SetBaudRate(UART0_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz);
276 
277 /* @} */
278 
279 /*!
280  * @name Status
281  * @{
282  */
283 
284 /*!
285  * @brief Gets LPSCI status flags.
286  *
287  * This function gets all LPSCI status flags. The flags are returned as the logical
288  * OR value of the enumerators @ref _lpsci_flags. To check a specific status,
289  * compare the return value to the enumerators in @ref _LPSCI_flags.
290  * For example, to check whether the TX is empty:
291   * @code
292  *     if (kLPSCI_TxDataRegEmptyFlag | LPSCI_GetStatusFlags(UART0))
293  *     {
294  *         ...
295  *     }
296  * @endcode
297  *
298  * @param base LPSCI peripheral base address.
299  * @return LPSCI status flags which are ORed by the enumerators in the _lpsci_flags.
300  */
301 uint32_t LPSCI_GetStatusFlags(UART0_Type *base);
302 
303 /* @brief Clears status flags with a provided mask.
304 *
305 * This function clears the LPSCI status flags with a provided mask. Automatically cleared flag
306 * can't be cleared by this function.
307 * Some flags can only be cleared or set by hardware. These flags are:
308 *    kLPSCI_TxDataRegEmptyFlag,kLPSCI_TransmissionCompleteFlag,kLPSCI_RxDataRegFullFlag,kLPSCI_RxActiveFlag,kLPSCI_NoiseErrorInRxDataRegFlag
309 *    kLPSCI_ParityErrorInRxDataRegFlag,kLPSCI_TxFifoEmptyFlag,kLPSCI_RxFifoEmptyFlag
310 * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects.
311 *
312 * @param base LPSCI peripheral base address.
313 * @param mask The status flags to be cleared, it is logical OR value of @ref _LPSCI_flagss.
314 * @retval kStatus_LPSCI_FlagCannotClearManually  can't be cleared by this function but it is cleared
315 * automatically by hardware.
316 * @retval kStatus_Success Status in the mask are cleared.
317 */
318 status_t LPSCI_ClearStatusFlags(UART0_Type *base, uint32_t mask);
319 
320 /* @} */
321 
322 /*!
323  * @name Interrupts
324  * @{
325  */
326 
327 /*!
328 * @brief Enables an LPSCI interrupt according to a provided mask.
329 *
330 * This function enables the LPSCI interrupts according to a provided mask. The mask
331 * is a logical OR of enumeration members. See @ref _lpsci_interrupt_enable.
332 * For example, to enable the TX empty interrupt and RX full interrupt:
333 * @code
334 *     LPSCI_EnableInterrupts(UART0,kLPSCI_TxDataRegEmptyInterruptEnable | kLPSCI_RxDataRegFullInterruptEnable);
335 * @endcode
336 *
337 * @param base LPSCI peripheral base address.
338 * @param mask The interrupts to enable. Logical OR of @ref _lpsci_interrupt_enable.
339 */
340 void LPSCI_EnableInterrupts(UART0_Type *base, uint32_t mask);
341 
342 /*!
343  * @brief Disables the LPSCI interrupt according to a provided mask.
344  *
345  * This function disables the LPSCI interrupts according to a provided mask. The mask
346  * is a logical OR of enumeration members. See @ref _lpsci_interrupt_enable.
347  * For example, to disable TX empty interrupt and RX full interrupt:
348  * @code
349  *     LPSCI_DisableInterrupts(UART0,kLPSCI_TxDataRegEmptyInterruptEnable | kLPSCI_RxDataRegFullInterruptEnable);
350  * @endcode
351  *
352  * @param base LPSCI peripheral base address.
353  * @param mask The interrupts to disable. Logical OR of @ref _LPSCI_interrupt_enable.
354  */
355 void LPSCI_DisableInterrupts(UART0_Type *base, uint32_t mask);
356 
357 /*!
358  * @brief Gets the enabled LPSCI interrupts.
359  *
360  * This function gets the enabled LPSCI interrupts, which are returned
361  * as the logical OR value of the enumerators @ref _lpsci_interrupt_enable. To check
362  * a specific interrupts enable status, compare the return value to the enumerators
363  * in @ref _LPSCI_interrupt_enable.
364  * For example, to check whether TX empty interrupt is enabled:
365  * @code
366  *     uint32_t enabledInterrupts = LPSCI_GetEnabledInterrupts(UART0);
367  *
368  *     if (kLPSCI_TxDataRegEmptyInterruptEnable & enabledInterrupts)
369  *     {
370  *         ...
371  *     }
372  * @endcode
373  *
374  * @param base LPSCI peripheral base address.
375  * @return LPSCI interrupt flags which are logical OR of the enumerators in @ref _LPSCI_interrupt_enable.
376  */
377 uint32_t LPSCI_GetEnabledInterrupts(UART0_Type *base);
378 
379 /* @} */
380 
381 #if defined(FSL_FEATURE_LPSCI_HAS_DMA_ENABLE) && FSL_FEATURE_LPSCI_HAS_DMA_ENABLE
382 
383 /*!
384  * @name DMA Control
385  * @{
386  */
387 
388 /*!
389  * @brief Gets the LPSCI data register address.
390  *
391  * This function returns the LPSCI data register address, which is mainly used by DMA/eDMA case.
392  *
393  * @param base LPSCI peripheral base address.
394  * @return LPSCI data register address which are used both by transmitter and receiver.
395  */
LPSCI_GetDataRegisterAddress(UART0_Type * base)396 static inline uint32_t LPSCI_GetDataRegisterAddress(UART0_Type *base)
397 {
398     return (uint32_t) & (base->D);
399 }
400 
401 /*!
402  * @brief Enables or disable LPSCI transmitter DMA request.
403  *
404  * This function enables or disables the transmit data register empty flag, S1[TDRE], to generate DMA requests.
405  *
406  * @param base LPSCI peripheral base address.
407  * @param enable True to enable, false to disable.
408  */
LPSCI_EnableTxDMA(UART0_Type * base,bool enable)409 static inline void LPSCI_EnableTxDMA(UART0_Type *base, bool enable)
410 {
411     if (enable)
412     {
413         base->C5 |= UART0_C5_TDMAE_MASK;
414         base->C2 |= UART0_C2_TIE_MASK;
415     }
416     else
417     {
418         base->C5 &= ~UART0_C5_TDMAE_MASK;
419         base->C2 &= ~UART0_C2_TIE_MASK;
420     }
421 }
422 
423 /*!
424  * @brief Enables or disables the LPSCI receiver DMA.
425  *
426  * This function enables or disables the receiver data register full flag, S1[RDRF], to generate DMA requests.
427  *
428  * @param base LPSCI peripheral base address.
429  * @param enable True to enable, false to disable.
430  */
LPSCI_EnableRxDMA(UART0_Type * base,bool enable)431 static inline void LPSCI_EnableRxDMA(UART0_Type *base, bool enable)
432 {
433     if (enable)
434     {
435         base->C5 |= UART0_C5_RDMAE_MASK;
436         base->C2 |= UART0_C2_RIE_MASK;
437     }
438     else
439     {
440         base->C5 &= ~UART0_C5_RDMAE_MASK;
441         base->C2 &= ~UART0_C2_RIE_MASK;
442     }
443 }
444 
445 /* @} */
446 #endif /* defined(FSL_FEATURE_LPSCI_HAS_DMA_ENABLE) && FSL_FEATURE_LPSCI_HAS_DMA_ENABLE */
447 
448 /*!
449  * @name Bus Operations
450  * @{
451  */
452 
453 /*!
454  * @brief Enables or disables the LPSCI transmitter.
455  *
456  * This function enables or disables the LPSCI transmitter.
457  *
458  * @param base LPSCI peripheral base address.
459  * @param enable True to enable, false to disable.
460  */
LPSCI_EnableTx(UART0_Type * base,bool enable)461 static inline void LPSCI_EnableTx(UART0_Type *base, bool enable)
462 {
463     if (enable)
464     {
465         base->C2 |= UART0_C2_TE_MASK;
466     }
467     else
468     {
469         base->C2 &= ~UART0_C2_TE_MASK;
470     }
471 }
472 
473 /*!
474  * @brief Enables or disables the LPSCI receiver.
475  *
476  * This function enables or disables the LPSCI receiver.
477  *
478  * @param base LPSCI peripheral base address.
479  * @param enable True to enable, false to disable.
480  */
LPSCI_EnableRx(UART0_Type * base,bool enable)481 static inline void LPSCI_EnableRx(UART0_Type *base, bool enable)
482 {
483     if (enable)
484     {
485         base->C2 |= UART0_C2_RE_MASK;
486     }
487     else
488     {
489         base->C2 &= ~UART0_C2_RE_MASK;
490     }
491 }
492 
493 /*!
494  * @brief Writes to the TX register.
495  *
496  * This function writes data to the TX register directly. The upper layer must ensure
497  * that the TX register is empty before calling this function.
498  *
499  * @param base LPSCI peripheral base address.
500  * @param data Data write to TX register.
501  */
LPSCI_WriteByte(UART0_Type * base,uint8_t data)502 static inline void LPSCI_WriteByte(UART0_Type *base, uint8_t data)
503 {
504     base->D = data;
505 }
506 
507 /*!
508  * @brief Reads the RX data register.
509  *
510  * This function reads data from the RX register directly. The upper layer must
511  * ensure that the RX register is full before calling this function.
512  *
513  * @param base LPSCI peripheral base address.
514  * @return Data read from RX data register.
515  */
LPSCI_ReadByte(UART0_Type * base)516 static inline uint8_t LPSCI_ReadByte(UART0_Type *base)
517 {
518     return base->D;
519 }
520 
521 /*!
522  * @brief Writes to the TX register using a blocking method.
523  *
524  * This function polls the TX register, waits for the TX register empty, and
525  * writes data to the TX buffer.
526  *
527  * @note This function does not check whether all the data has been sent out to bus,
528  * so before disable TX, check kLPSCI_TransmissionCompleteFlag to ensure the TX is
529  * finished.
530  *
531  * @param base LPSCI peripheral base address.
532  * @param data Start address of the data to write.
533  * @param length Size of the data to write.
534  */
535 void LPSCI_WriteBlocking(UART0_Type *base, const uint8_t *data, size_t length);
536 
537 /*!
538 * @brief Reads the RX register using a blocking method.
539 *
540 * This function polls the RX register, waits for the RX register to be full, and
541 * reads data from the RX register.
542 *
543 * @param base LPSCI peripheral base address.
544 * @param data Start address of the buffer to store the received data.
545 * @param length Size of the buffer.
546 * @retval kStatus_LPSCI_RxHardwareOverrun Receiver overrun happened while receiving data.
547 * @retval kStatus_LPSCI_NoiseError Noise error happened while receiving data.
548 * @retval kStatus_LPSCI_FramingError Framing error happened while receiving data.
549 * @retval kStatus_LPSCI_ParityError Parity error happened while receiving data.
550 * @retval kStatus_Success Successfully received all data.
551 */
552 status_t LPSCI_ReadBlocking(UART0_Type *base, uint8_t *data, size_t length);
553 
554 /* @} */
555 
556 /*!
557  * @name Transactional
558  * @{
559  */
560 
561 /*!
562  * @brief Initializes the LPSCI handle.
563  *
564  * This function initializes the LPSCI handle, which can be used for other LPSCI
565  * transactional APIs. Usually, for a specified LPSCI instance,
566  * call this API once to get the initialized handle.
567  *
568  * LPSCI driver supports the "background" receiving, which means that the user can set up
569  * an RX ring buffer optionally. Data received are stored into the ring buffer even when the
570  * user doesn't call the LPSCI_TransferReceiveNonBlocking() API. If there is already data received
571  * in the ring buffer, get the received data from the ring buffer directly.
572  * The ring buffer is disabled if pass NULL as @p ringBuffer.
573  *
574  * @param handle LPSCI handle pointer.
575  * @param base LPSCI peripheral base address.
576  * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer.
577  * @param ringBufferSize size of the ring buffer.
578  */
579 void LPSCI_TransferCreateHandle(UART0_Type *base,
580                                 lpsci_handle_t *handle,
581                                 lpsci_transfer_callback_t callback,
582                                 void *userData);
583 
584 /*!
585  * @brief Sets up the RX ring buffer.
586  *
587  * This function sets up the RX ring buffer to a specific LPSCI handle.
588  *
589  * When the RX ring buffer is used, data received is stored into the ring buffer even when
590  * the user doesn't call the LPSCI_TransferReceiveNonBlocking() API. If there is already data received
591  * in the ring buffer, the user can get the received data from the ring buffer directly.
592  *
593  * @note When using the RX ring buffer, one byte is reserved for internal use. In other
594  * words, if @p ringBufferSize is 32, only 31 bytes are used for saving data.
595  *
596  * @param base LPSCI peripheral base address.
597  * @param handle LPSCI handle pointer.
598  * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer.
599  * @param ringBufferSize size of the ring buffer.
600  */
601 void LPSCI_TransferStartRingBuffer(UART0_Type *base,
602                                    lpsci_handle_t *handle,
603                                    uint8_t *ringBuffer,
604                                    size_t ringBufferSize);
605 
606 /*!
607  * @brief Aborts the background transfer and uninstalls the ring buffer.
608  *
609  * This function aborts the background transfer and uninstalls the ringbuffer.
610  *
611  * @param base LPSCI peripheral base address.
612  * @param handle LPSCI handle pointer.
613  */
614 void LPSCI_TransferStopRingBuffer(UART0_Type *base, lpsci_handle_t *handle);
615 
616 /*!
617  * @brief Transmits a buffer of data using the interrupt method.
618  *
619  * This function sends data using the interrupt method. This is a non-blocking function, which
620  * returns directly without waiting for all data to be written to the TX register. When
621  * all data is written to the TX register in ISR, LPSCI driver calls the callback
622  * function and passes the @ref kStatus_LPSCI_TxIdle as status parameter.
623  *
624  * @note The kStatus_LPSCI_TxIdle is passed to the upper layer when all data is written
625  * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX,
626  * check the kLPSCI_TransmissionCompleteFlag to ensure that the TX is complete.
627  *
628  * @param handle LPSCI handle pointer.
629  * @param xfer LPSCI transfer structure, refer to #LPSCI_transfer_t.
630  * @retval kStatus_Success Successfully start the data transmission.
631  * @retval kStatus_LPSCI_TxBusy Previous transmission still not finished, data not all written to the TX register.
632  * @retval kStatus_InvalidArgument Invalid argument.
633  */
634 status_t LPSCI_TransferSendNonBlocking(UART0_Type *base, lpsci_handle_t *handle, lpsci_transfer_t *xfer);
635 
636 /*!
637  * @brief Aborts the interrupt-driven data transmit.
638  *
639  * This function aborts the interrupt driven data send.
640  *
641  * @param handle LPSCI handle pointer.
642  */
643 void LPSCI_TransferAbortSend(UART0_Type *base, lpsci_handle_t *handle);
644 
645 /*!
646  * @brief Get the number of bytes that have been written to LPSCI TX register.
647  *
648  * This function gets the number of bytes that have been written to LPSCI TX
649  * register by interrupt method.
650  *
651  * @param base LPSCI peripheral base address.
652  * @param handle LPSCI handle pointer.
653  * @param count Send bytes count.
654  * @retval kStatus_NoTransferInProgress No send in progress.
655  * @retval kStatus_InvalidArgument Parameter is invalid.
656  * @retval kStatus_Success Get successfully through the parameter \p count;
657  */
658 status_t LPSCI_TransferGetSendCount(UART0_Type *base, lpsci_handle_t *handle, uint32_t *count);
659 
660 /*!
661  * @brief Receives buffer of data using the interrupt method.
662  *
663  * This function receives data using the interrupt method. This is a non-blocking function
664  * which returns without waiting for all data to be received.
665  * If the RX ring buffer is used and not empty, the data in ring buffer is copied and
666  * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
667  * After copying, if the data in ring buffer is not enough to read, the receive
668  * request is saved by the LPSCI driver. When new data arrives, the receive request
669  * is serviced first. When all data is received, the LPSCI driver notifies the upper layer
670  * through a callback function and passes the status parameter @ref kStatus_LPSCI_RxIdle.
671  * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
672  * The 5 bytes are copied to the xfer->data and the function returns with the
673  * parameter @p receivedBytes set to 5. For the remaining 5 bytes, newly arrived data is
674  * saved from the xfer->data[5]. When 5 bytes are received, the LPSCI driver notifies the upper layer.
675  * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
676  * to receive data to the xfer->data. When all data is received, the upper layer is notified.
677  *
678  * @param handle LPSCI handle pointer.
679  * @param xfer lpsci transfer structure. See #lpsci_transfer_t.
680  * @param receivedBytes Bytes received from the ring buffer directly.
681  * @retval kStatus_Success Successfully queue the transfer into transmit queue.
682  * @retval kStatus_LPSCI_RxBusy Previous receive request is not finished.
683  * @retval kStatus_InvalidArgument Invalid argument.
684  */
685 status_t LPSCI_TransferReceiveNonBlocking(UART0_Type *base,
686                                           lpsci_handle_t *handle,
687                                           lpsci_transfer_t *xfer,
688                                           size_t *receivedBytes);
689 
690 /*!
691  * @brief Aborts interrupt driven data receiving.
692  *
693  * This function aborts interrupt driven data receiving.
694  *
695  * @param handle LPSCI handle pointer.
696  */
697 void LPSCI_TransferAbortReceive(UART0_Type *base, lpsci_handle_t *handle);
698 
699 /*!
700  * @brief Get the number of bytes that have been received.
701  *
702  * This function gets the number of bytes that have been received.
703  *
704  * @param base LPSCI peripheral base address.
705  * @param handle LPSCI handle pointer.
706  * @param count Receive bytes count.
707  * @retval kStatus_NoTransferInProgress No receive in progress.
708  * @retval kStatus_InvalidArgument Parameter is invalid.
709  * @retval kStatus_Success Get successfully through the parameter \p count;
710  */
711 status_t LPSCI_TransferGetReceiveCount(UART0_Type *base, lpsci_handle_t *handle, uint32_t *count);
712 
713 /*!
714  * @brief LPSCI IRQ handle function.
715  *
716  * This function handles the LPSCI transmit and receive IRQ request.
717  *
718  * @param handle LPSCI handle pointer.
719  */
720 void LPSCI_TransferHandleIRQ(UART0_Type *base, lpsci_handle_t *handle);
721 
722 /*!
723  * @brief LPSCI Error IRQ handle function.
724  *
725  * This function handle the LPSCI error IRQ request.
726  *
727  * @param handle LPSCI handle pointer.
728  */
729 void LPSCI_TransferHandleErrorIRQ(UART0_Type *base, lpsci_handle_t *handle);
730 
731 /* @} */
732 
733 #if defined(__cplusplus)
734 }
735 #endif
736 
737 /*! @}*/
738 
739 #endif /* _FSL_LPSCI_H_ */
740