Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
kadonotakashi 0:8fdf9a60065b 3 * All rights reserved.
kadonotakashi 0:8fdf9a60065b 4 *
kadonotakashi 0:8fdf9a60065b 5 * Redistribution and use in source and binary forms, with or without modification,
kadonotakashi 0:8fdf9a60065b 6 * are permitted provided that the following conditions are met:
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * o Redistributions of source code must retain the above copyright notice, this list
kadonotakashi 0:8fdf9a60065b 9 * of conditions and the following disclaimer.
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * o Redistributions in binary form must reproduce the above copyright notice, this
kadonotakashi 0:8fdf9a60065b 12 * list of conditions and the following disclaimer in the documentation and/or
kadonotakashi 0:8fdf9a60065b 13 * other materials provided with the distribution.
kadonotakashi 0:8fdf9a60065b 14 *
kadonotakashi 0:8fdf9a60065b 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
kadonotakashi 0:8fdf9a60065b 16 * contributors may be used to endorse or promote products derived from this
kadonotakashi 0:8fdf9a60065b 17 * software without specific prior written permission.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
kadonotakashi 0:8fdf9a60065b 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
kadonotakashi 0:8fdf9a60065b 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
kadonotakashi 0:8fdf9a60065b 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
kadonotakashi 0:8fdf9a60065b 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
kadonotakashi 0:8fdf9a60065b 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
kadonotakashi 0:8fdf9a60065b 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
kadonotakashi 0:8fdf9a60065b 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
kadonotakashi 0:8fdf9a60065b 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
kadonotakashi 0:8fdf9a60065b 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kadonotakashi 0:8fdf9a60065b 29 */
kadonotakashi 0:8fdf9a60065b 30
kadonotakashi 0:8fdf9a60065b 31 #include "fsl_lpuart.h"
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 34 * Definitions
kadonotakashi 0:8fdf9a60065b 35 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 36 /* LPUART transfer state. */
kadonotakashi 0:8fdf9a60065b 37 enum _lpuart_transfer_states
kadonotakashi 0:8fdf9a60065b 38 {
kadonotakashi 0:8fdf9a60065b 39 kLPUART_TxIdle, /*!< TX idle. */
kadonotakashi 0:8fdf9a60065b 40 kLPUART_TxBusy, /*!< TX busy. */
kadonotakashi 0:8fdf9a60065b 41 kLPUART_RxIdle, /*!< RX idle. */
kadonotakashi 0:8fdf9a60065b 42 kLPUART_RxBusy /*!< RX busy. */
kadonotakashi 0:8fdf9a60065b 43 };
kadonotakashi 0:8fdf9a60065b 44
kadonotakashi 0:8fdf9a60065b 45 /* Typedef for interrupt handler. */
kadonotakashi 0:8fdf9a60065b 46 typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle);
kadonotakashi 0:8fdf9a60065b 47
kadonotakashi 0:8fdf9a60065b 48 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 49 * Prototypes
kadonotakashi 0:8fdf9a60065b 50 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 51 /*!
kadonotakashi 0:8fdf9a60065b 52 * @brief Get the LPUART instance from peripheral base address.
kadonotakashi 0:8fdf9a60065b 53 *
kadonotakashi 0:8fdf9a60065b 54 * @param base LPUART peripheral base address.
kadonotakashi 0:8fdf9a60065b 55 * @return LPUART instance.
kadonotakashi 0:8fdf9a60065b 56 */
kadonotakashi 0:8fdf9a60065b 57 uint32_t LPUART_GetInstance(LPUART_Type *base);
kadonotakashi 0:8fdf9a60065b 58
kadonotakashi 0:8fdf9a60065b 59 /*!
kadonotakashi 0:8fdf9a60065b 60 * @brief Get the length of received data in RX ring buffer.
kadonotakashi 0:8fdf9a60065b 61 *
kadonotakashi 0:8fdf9a60065b 62 * @userData handle LPUART handle pointer.
kadonotakashi 0:8fdf9a60065b 63 * @return Length of received data in RX ring buffer.
kadonotakashi 0:8fdf9a60065b 64 */
kadonotakashi 0:8fdf9a60065b 65 static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle);
kadonotakashi 0:8fdf9a60065b 66
kadonotakashi 0:8fdf9a60065b 67 /*!
kadonotakashi 0:8fdf9a60065b 68 * @brief Check whether the RX ring buffer is full.
kadonotakashi 0:8fdf9a60065b 69 *
kadonotakashi 0:8fdf9a60065b 70 * @userData handle LPUART handle pointer.
kadonotakashi 0:8fdf9a60065b 71 * @retval true RX ring buffer is full.
kadonotakashi 0:8fdf9a60065b 72 * @retval false RX ring buffer is not full.
kadonotakashi 0:8fdf9a60065b 73 */
kadonotakashi 0:8fdf9a60065b 74 static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle);
kadonotakashi 0:8fdf9a60065b 75
kadonotakashi 0:8fdf9a60065b 76 /*!
kadonotakashi 0:8fdf9a60065b 77 * @brief Write to TX register using non-blocking method.
kadonotakashi 0:8fdf9a60065b 78 *
kadonotakashi 0:8fdf9a60065b 79 * This function writes data to the TX register directly, upper layer must make
kadonotakashi 0:8fdf9a60065b 80 * sure the TX register is empty or TX FIFO has empty room before calling this function.
kadonotakashi 0:8fdf9a60065b 81 *
kadonotakashi 0:8fdf9a60065b 82 * @note This function does not check whether all the data has been sent out to bus,
kadonotakashi 0:8fdf9a60065b 83 * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is
kadonotakashi 0:8fdf9a60065b 84 * finished.
kadonotakashi 0:8fdf9a60065b 85 *
kadonotakashi 0:8fdf9a60065b 86 * @param base LPUART peripheral base address.
kadonotakashi 0:8fdf9a60065b 87 * @param data Start addresss of the data to write.
kadonotakashi 0:8fdf9a60065b 88 * @param length Size of the buffer to be sent.
kadonotakashi 0:8fdf9a60065b 89 */
kadonotakashi 0:8fdf9a60065b 90 static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length);
kadonotakashi 0:8fdf9a60065b 91
kadonotakashi 0:8fdf9a60065b 92 /*!
kadonotakashi 0:8fdf9a60065b 93 * @brief Read RX register using non-blocking method.
kadonotakashi 0:8fdf9a60065b 94 *
kadonotakashi 0:8fdf9a60065b 95 * This function reads data from the TX register directly, upper layer must make
kadonotakashi 0:8fdf9a60065b 96 * sure the RX register is full or TX FIFO has data before calling this function.
kadonotakashi 0:8fdf9a60065b 97 *
kadonotakashi 0:8fdf9a60065b 98 * @param base LPUART peripheral base address.
kadonotakashi 0:8fdf9a60065b 99 * @param data Start addresss of the buffer to store the received data.
kadonotakashi 0:8fdf9a60065b 100 * @param length Size of the buffer.
kadonotakashi 0:8fdf9a60065b 101 */
kadonotakashi 0:8fdf9a60065b 102 static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length);
kadonotakashi 0:8fdf9a60065b 103
kadonotakashi 0:8fdf9a60065b 104 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 105 * Variables
kadonotakashi 0:8fdf9a60065b 106 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 107 /* Array of LPUART handle. */
kadonotakashi 0:8fdf9a60065b 108 static lpuart_handle_t *s_lpuartHandle[FSL_FEATURE_SOC_LPUART_COUNT];
kadonotakashi 0:8fdf9a60065b 109 /* Array of LPUART peripheral base address. */
kadonotakashi 0:8fdf9a60065b 110 static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS;
kadonotakashi 0:8fdf9a60065b 111 /* Array of LPUART IRQ number. */
kadonotakashi 0:8fdf9a60065b 112 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 113 static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS;
kadonotakashi 0:8fdf9a60065b 114 static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS;
kadonotakashi 0:8fdf9a60065b 115 #else
kadonotakashi 0:8fdf9a60065b 116 static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS;
kadonotakashi 0:8fdf9a60065b 117 #endif
kadonotakashi 0:8fdf9a60065b 118 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
kadonotakashi 0:8fdf9a60065b 119 /* Array of LPUART clock name. */
kadonotakashi 0:8fdf9a60065b 120 static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS;
kadonotakashi 0:8fdf9a60065b 121 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
kadonotakashi 0:8fdf9a60065b 122 /* LPUART ISR for transactional APIs. */
kadonotakashi 0:8fdf9a60065b 123 static lpuart_isr_t s_lpuartIsr;
kadonotakashi 0:8fdf9a60065b 124
kadonotakashi 0:8fdf9a60065b 125 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 126 * Code
kadonotakashi 0:8fdf9a60065b 127 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 128 uint32_t LPUART_GetInstance(LPUART_Type *base)
kadonotakashi 0:8fdf9a60065b 129 {
kadonotakashi 0:8fdf9a60065b 130 uint32_t instance;
kadonotakashi 0:8fdf9a60065b 131
kadonotakashi 0:8fdf9a60065b 132 /* Find the instance index from base address mappings. */
kadonotakashi 0:8fdf9a60065b 133 for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++)
kadonotakashi 0:8fdf9a60065b 134 {
kadonotakashi 0:8fdf9a60065b 135 if (s_lpuartBases[instance] == base)
kadonotakashi 0:8fdf9a60065b 136 {
kadonotakashi 0:8fdf9a60065b 137 break;
kadonotakashi 0:8fdf9a60065b 138 }
kadonotakashi 0:8fdf9a60065b 139 }
kadonotakashi 0:8fdf9a60065b 140
kadonotakashi 0:8fdf9a60065b 141 assert(instance < FSL_FEATURE_SOC_LPUART_COUNT);
kadonotakashi 0:8fdf9a60065b 142
kadonotakashi 0:8fdf9a60065b 143 return instance;
kadonotakashi 0:8fdf9a60065b 144 }
kadonotakashi 0:8fdf9a60065b 145
kadonotakashi 0:8fdf9a60065b 146 static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 147 {
kadonotakashi 0:8fdf9a60065b 148 assert(handle);
kadonotakashi 0:8fdf9a60065b 149
kadonotakashi 0:8fdf9a60065b 150 size_t size;
kadonotakashi 0:8fdf9a60065b 151
kadonotakashi 0:8fdf9a60065b 152 if (handle->rxRingBufferTail > handle->rxRingBufferHead)
kadonotakashi 0:8fdf9a60065b 153 {
kadonotakashi 0:8fdf9a60065b 154 size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail);
kadonotakashi 0:8fdf9a60065b 155 }
kadonotakashi 0:8fdf9a60065b 156 else
kadonotakashi 0:8fdf9a60065b 157 {
kadonotakashi 0:8fdf9a60065b 158 size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail);
kadonotakashi 0:8fdf9a60065b 159 }
kadonotakashi 0:8fdf9a60065b 160
kadonotakashi 0:8fdf9a60065b 161 return size;
kadonotakashi 0:8fdf9a60065b 162 }
kadonotakashi 0:8fdf9a60065b 163
kadonotakashi 0:8fdf9a60065b 164 static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 165 {
kadonotakashi 0:8fdf9a60065b 166 assert(handle);
kadonotakashi 0:8fdf9a60065b 167
kadonotakashi 0:8fdf9a60065b 168 bool full;
kadonotakashi 0:8fdf9a60065b 169
kadonotakashi 0:8fdf9a60065b 170 if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U))
kadonotakashi 0:8fdf9a60065b 171 {
kadonotakashi 0:8fdf9a60065b 172 full = true;
kadonotakashi 0:8fdf9a60065b 173 }
kadonotakashi 0:8fdf9a60065b 174 else
kadonotakashi 0:8fdf9a60065b 175 {
kadonotakashi 0:8fdf9a60065b 176 full = false;
kadonotakashi 0:8fdf9a60065b 177 }
kadonotakashi 0:8fdf9a60065b 178 return full;
kadonotakashi 0:8fdf9a60065b 179 }
kadonotakashi 0:8fdf9a60065b 180
kadonotakashi 0:8fdf9a60065b 181 static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
kadonotakashi 0:8fdf9a60065b 182 {
kadonotakashi 0:8fdf9a60065b 183 assert(data);
kadonotakashi 0:8fdf9a60065b 184
kadonotakashi 0:8fdf9a60065b 185 size_t i;
kadonotakashi 0:8fdf9a60065b 186
kadonotakashi 0:8fdf9a60065b 187 /* The Non Blocking write data API assume user have ensured there is enough space in
kadonotakashi 0:8fdf9a60065b 188 peripheral to write. */
kadonotakashi 0:8fdf9a60065b 189 for (i = 0; i < length; i++)
kadonotakashi 0:8fdf9a60065b 190 {
kadonotakashi 0:8fdf9a60065b 191 base->DATA = data[i];
kadonotakashi 0:8fdf9a60065b 192 }
kadonotakashi 0:8fdf9a60065b 193 }
kadonotakashi 0:8fdf9a60065b 194
kadonotakashi 0:8fdf9a60065b 195 static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length)
kadonotakashi 0:8fdf9a60065b 196 {
kadonotakashi 0:8fdf9a60065b 197 assert(data);
kadonotakashi 0:8fdf9a60065b 198
kadonotakashi 0:8fdf9a60065b 199 size_t i;
kadonotakashi 0:8fdf9a60065b 200 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 201 uint32_t ctrl = base->CTRL;
kadonotakashi 0:8fdf9a60065b 202 bool isSevenDataBits =
kadonotakashi 0:8fdf9a60065b 203 ((ctrl & LPUART_CTRL_M7_MASK) ||
kadonotakashi 0:8fdf9a60065b 204 ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
kadonotakashi 0:8fdf9a60065b 205 #endif
kadonotakashi 0:8fdf9a60065b 206
kadonotakashi 0:8fdf9a60065b 207 /* The Non Blocking read data API assume user have ensured there is enough space in
kadonotakashi 0:8fdf9a60065b 208 peripheral to write. */
kadonotakashi 0:8fdf9a60065b 209 for (i = 0; i < length; i++)
kadonotakashi 0:8fdf9a60065b 210 {
kadonotakashi 0:8fdf9a60065b 211 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 212 if (isSevenDataBits)
kadonotakashi 0:8fdf9a60065b 213 {
kadonotakashi 0:8fdf9a60065b 214 data[i] = (base->DATA & 0x7F);
kadonotakashi 0:8fdf9a60065b 215 }
kadonotakashi 0:8fdf9a60065b 216 else
kadonotakashi 0:8fdf9a60065b 217 {
kadonotakashi 0:8fdf9a60065b 218 data[i] = base->DATA;
kadonotakashi 0:8fdf9a60065b 219 }
kadonotakashi 0:8fdf9a60065b 220 #else
kadonotakashi 0:8fdf9a60065b 221 data[i] = base->DATA;
kadonotakashi 0:8fdf9a60065b 222 #endif
kadonotakashi 0:8fdf9a60065b 223 }
kadonotakashi 0:8fdf9a60065b 224 }
kadonotakashi 0:8fdf9a60065b 225
kadonotakashi 0:8fdf9a60065b 226 status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz)
kadonotakashi 0:8fdf9a60065b 227 {
kadonotakashi 0:8fdf9a60065b 228 assert(config);
kadonotakashi 0:8fdf9a60065b 229 assert(config->baudRate_Bps);
kadonotakashi 0:8fdf9a60065b 230 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 231 assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark);
kadonotakashi 0:8fdf9a60065b 232 assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark);
kadonotakashi 0:8fdf9a60065b 233 #endif
kadonotakashi 0:8fdf9a60065b 234
kadonotakashi 0:8fdf9a60065b 235 uint32_t temp;
kadonotakashi 0:8fdf9a60065b 236 uint16_t sbr, sbrTemp;
kadonotakashi 0:8fdf9a60065b 237 uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
kadonotakashi 0:8fdf9a60065b 238
kadonotakashi 0:8fdf9a60065b 239 /* This LPUART instantiation uses a slightly different baud rate calculation
kadonotakashi 0:8fdf9a60065b 240 * The idea is to use the best OSR (over-sampling rate) possible
kadonotakashi 0:8fdf9a60065b 241 * Note, OSR is typically hard-set to 16 in other LPUART instantiations
kadonotakashi 0:8fdf9a60065b 242 * loop to find the best OSR value possible, one that generates minimum baudDiff
kadonotakashi 0:8fdf9a60065b 243 * iterate through the rest of the supported values of OSR */
kadonotakashi 0:8fdf9a60065b 244
kadonotakashi 0:8fdf9a60065b 245 baudDiff = config->baudRate_Bps;
kadonotakashi 0:8fdf9a60065b 246 osr = 0;
kadonotakashi 0:8fdf9a60065b 247 sbr = 0;
kadonotakashi 0:8fdf9a60065b 248 for (osrTemp = 4; osrTemp <= 32; osrTemp++)
kadonotakashi 0:8fdf9a60065b 249 {
kadonotakashi 0:8fdf9a60065b 250 /* calculate the temporary sbr value */
kadonotakashi 0:8fdf9a60065b 251 sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp));
kadonotakashi 0:8fdf9a60065b 252 /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
kadonotakashi 0:8fdf9a60065b 253 if (sbrTemp == 0)
kadonotakashi 0:8fdf9a60065b 254 {
kadonotakashi 0:8fdf9a60065b 255 sbrTemp = 1;
kadonotakashi 0:8fdf9a60065b 256 }
kadonotakashi 0:8fdf9a60065b 257 /* Calculate the baud rate based on the temporary OSR and SBR values */
kadonotakashi 0:8fdf9a60065b 258 calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp));
kadonotakashi 0:8fdf9a60065b 259
kadonotakashi 0:8fdf9a60065b 260 tempDiff = calculatedBaud - config->baudRate_Bps;
kadonotakashi 0:8fdf9a60065b 261
kadonotakashi 0:8fdf9a60065b 262 /* Select the better value between srb and (sbr + 1) */
kadonotakashi 0:8fdf9a60065b 263 if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)))))
kadonotakashi 0:8fdf9a60065b 264 {
kadonotakashi 0:8fdf9a60065b 265 tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)));
kadonotakashi 0:8fdf9a60065b 266 sbrTemp++;
kadonotakashi 0:8fdf9a60065b 267 }
kadonotakashi 0:8fdf9a60065b 268
kadonotakashi 0:8fdf9a60065b 269 if (tempDiff <= baudDiff)
kadonotakashi 0:8fdf9a60065b 270 {
kadonotakashi 0:8fdf9a60065b 271 baudDiff = tempDiff;
kadonotakashi 0:8fdf9a60065b 272 osr = osrTemp; /* update and store the best OSR value calculated */
kadonotakashi 0:8fdf9a60065b 273 sbr = sbrTemp; /* update store the best SBR value calculated */
kadonotakashi 0:8fdf9a60065b 274 }
kadonotakashi 0:8fdf9a60065b 275 }
kadonotakashi 0:8fdf9a60065b 276
kadonotakashi 0:8fdf9a60065b 277 /* Check to see if actual baud rate is within 3% of desired baud rate
kadonotakashi 0:8fdf9a60065b 278 * based on the best calculate OSR value */
kadonotakashi 0:8fdf9a60065b 279 if (baudDiff > ((config->baudRate_Bps / 100) * 3))
kadonotakashi 0:8fdf9a60065b 280 {
kadonotakashi 0:8fdf9a60065b 281 /* Unacceptable baud rate difference of more than 3%*/
kadonotakashi 0:8fdf9a60065b 282 return kStatus_LPUART_BaudrateNotSupport;
kadonotakashi 0:8fdf9a60065b 283 }
kadonotakashi 0:8fdf9a60065b 284
kadonotakashi 0:8fdf9a60065b 285 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
kadonotakashi 0:8fdf9a60065b 286 /* Enable lpuart clock */
kadonotakashi 0:8fdf9a60065b 287 CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 288 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
kadonotakashi 0:8fdf9a60065b 289
kadonotakashi 0:8fdf9a60065b 290 #if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL
kadonotakashi 0:8fdf9a60065b 291 /*Reset all internal logic and registers, except the Global Register */
kadonotakashi 0:8fdf9a60065b 292 LPUART_SoftwareReset(base);
kadonotakashi 0:8fdf9a60065b 293 #else
kadonotakashi 0:8fdf9a60065b 294 /* Disable LPUART TX RX before setting. */
kadonotakashi 0:8fdf9a60065b 295 base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
kadonotakashi 0:8fdf9a60065b 296 #endif
kadonotakashi 0:8fdf9a60065b 297
kadonotakashi 0:8fdf9a60065b 298 temp = base->BAUD;
kadonotakashi 0:8fdf9a60065b 299
kadonotakashi 0:8fdf9a60065b 300 /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
kadonotakashi 0:8fdf9a60065b 301 * If so, then "BOTHEDGE" sampling must be turned on */
kadonotakashi 0:8fdf9a60065b 302 if ((osr > 3) && (osr < 8))
kadonotakashi 0:8fdf9a60065b 303 {
kadonotakashi 0:8fdf9a60065b 304 temp |= LPUART_BAUD_BOTHEDGE_MASK;
kadonotakashi 0:8fdf9a60065b 305 }
kadonotakashi 0:8fdf9a60065b 306
kadonotakashi 0:8fdf9a60065b 307 /* program the osr value (bit value is one less than actual value) */
kadonotakashi 0:8fdf9a60065b 308 temp &= ~LPUART_BAUD_OSR_MASK;
kadonotakashi 0:8fdf9a60065b 309 temp |= LPUART_BAUD_OSR(osr - 1);
kadonotakashi 0:8fdf9a60065b 310
kadonotakashi 0:8fdf9a60065b 311 /* write the sbr value to the BAUD registers */
kadonotakashi 0:8fdf9a60065b 312 temp &= ~LPUART_BAUD_SBR_MASK;
kadonotakashi 0:8fdf9a60065b 313 base->BAUD = temp | LPUART_BAUD_SBR(sbr);
kadonotakashi 0:8fdf9a60065b 314
kadonotakashi 0:8fdf9a60065b 315 /* Set bit count and parity mode. */
kadonotakashi 0:8fdf9a60065b 316 base->BAUD &= ~LPUART_BAUD_M10_MASK;
kadonotakashi 0:8fdf9a60065b 317
kadonotakashi 0:8fdf9a60065b 318 temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK);
kadonotakashi 0:8fdf9a60065b 319
kadonotakashi 0:8fdf9a60065b 320 temp |= (uint8_t)config->parityMode;
kadonotakashi 0:8fdf9a60065b 321
kadonotakashi 0:8fdf9a60065b 322 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 323 if (kLPUART_SevenDataBits == config->dataBitsCount)
kadonotakashi 0:8fdf9a60065b 324 {
kadonotakashi 0:8fdf9a60065b 325 if (kLPUART_ParityDisabled != config->parityMode)
kadonotakashi 0:8fdf9a60065b 326 {
kadonotakashi 0:8fdf9a60065b 327 temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */
kadonotakashi 0:8fdf9a60065b 328 }
kadonotakashi 0:8fdf9a60065b 329 else
kadonotakashi 0:8fdf9a60065b 330 {
kadonotakashi 0:8fdf9a60065b 331 temp |= LPUART_CTRL_M7_MASK;
kadonotakashi 0:8fdf9a60065b 332 }
kadonotakashi 0:8fdf9a60065b 333 }
kadonotakashi 0:8fdf9a60065b 334 else
kadonotakashi 0:8fdf9a60065b 335 #endif
kadonotakashi 0:8fdf9a60065b 336 {
kadonotakashi 0:8fdf9a60065b 337 if (kLPUART_ParityDisabled != config->parityMode)
kadonotakashi 0:8fdf9a60065b 338 {
kadonotakashi 0:8fdf9a60065b 339 temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */
kadonotakashi 0:8fdf9a60065b 340 }
kadonotakashi 0:8fdf9a60065b 341 }
kadonotakashi 0:8fdf9a60065b 342
kadonotakashi 0:8fdf9a60065b 343 base->CTRL = temp;
kadonotakashi 0:8fdf9a60065b 344
kadonotakashi 0:8fdf9a60065b 345 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
kadonotakashi 0:8fdf9a60065b 346 /* set stop bit per char */
kadonotakashi 0:8fdf9a60065b 347 temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK;
kadonotakashi 0:8fdf9a60065b 348 base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount);
kadonotakashi 0:8fdf9a60065b 349 #endif
kadonotakashi 0:8fdf9a60065b 350
kadonotakashi 0:8fdf9a60065b 351 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 352 /* Set tx/rx WATER watermark */
kadonotakashi 0:8fdf9a60065b 353 base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark);
kadonotakashi 0:8fdf9a60065b 354
kadonotakashi 0:8fdf9a60065b 355 /* Enable tx/rx FIFO */
kadonotakashi 0:8fdf9a60065b 356 base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK);
kadonotakashi 0:8fdf9a60065b 357
kadonotakashi 0:8fdf9a60065b 358 /* Flush FIFO */
kadonotakashi 0:8fdf9a60065b 359 base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK);
kadonotakashi 0:8fdf9a60065b 360 #endif
kadonotakashi 0:8fdf9a60065b 361
kadonotakashi 0:8fdf9a60065b 362 /* Clear all status flags */
kadonotakashi 0:8fdf9a60065b 363 temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
kadonotakashi 0:8fdf9a60065b 364 LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
kadonotakashi 0:8fdf9a60065b 365
kadonotakashi 0:8fdf9a60065b 366 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
kadonotakashi 0:8fdf9a60065b 367 temp |= LPUART_STAT_LBKDIF_MASK;
kadonotakashi 0:8fdf9a60065b 368 #endif
kadonotakashi 0:8fdf9a60065b 369
kadonotakashi 0:8fdf9a60065b 370 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
kadonotakashi 0:8fdf9a60065b 371 temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
kadonotakashi 0:8fdf9a60065b 372 #endif
kadonotakashi 0:8fdf9a60065b 373
kadonotakashi 0:8fdf9a60065b 374 /* Set data bits order. */
kadonotakashi 0:8fdf9a60065b 375 if (config->isMsb)
kadonotakashi 0:8fdf9a60065b 376 {
kadonotakashi 0:8fdf9a60065b 377 temp |= LPUART_STAT_MSBF_MASK;
kadonotakashi 0:8fdf9a60065b 378 }
kadonotakashi 0:8fdf9a60065b 379 else
kadonotakashi 0:8fdf9a60065b 380 {
kadonotakashi 0:8fdf9a60065b 381 temp &= ~LPUART_STAT_MSBF_MASK;
kadonotakashi 0:8fdf9a60065b 382 }
kadonotakashi 0:8fdf9a60065b 383
kadonotakashi 0:8fdf9a60065b 384 base->STAT |= temp;
kadonotakashi 0:8fdf9a60065b 385
kadonotakashi 0:8fdf9a60065b 386 /* Enable TX/RX base on configure structure. */
kadonotakashi 0:8fdf9a60065b 387 temp = base->CTRL;
kadonotakashi 0:8fdf9a60065b 388 if (config->enableTx)
kadonotakashi 0:8fdf9a60065b 389 {
kadonotakashi 0:8fdf9a60065b 390 temp |= LPUART_CTRL_TE_MASK;
kadonotakashi 0:8fdf9a60065b 391 }
kadonotakashi 0:8fdf9a60065b 392
kadonotakashi 0:8fdf9a60065b 393 if (config->enableRx)
kadonotakashi 0:8fdf9a60065b 394 {
kadonotakashi 0:8fdf9a60065b 395 temp |= LPUART_CTRL_RE_MASK;
kadonotakashi 0:8fdf9a60065b 396 }
kadonotakashi 0:8fdf9a60065b 397
kadonotakashi 0:8fdf9a60065b 398 base->CTRL = temp;
kadonotakashi 0:8fdf9a60065b 399
kadonotakashi 0:8fdf9a60065b 400 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 401 }
kadonotakashi 0:8fdf9a60065b 402 void LPUART_Deinit(LPUART_Type *base)
kadonotakashi 0:8fdf9a60065b 403 {
kadonotakashi 0:8fdf9a60065b 404 uint32_t temp;
kadonotakashi 0:8fdf9a60065b 405
kadonotakashi 0:8fdf9a60065b 406 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 407 /* Wait tx FIFO send out*/
kadonotakashi 0:8fdf9a60065b 408 while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT))
kadonotakashi 0:8fdf9a60065b 409 {
kadonotakashi 0:8fdf9a60065b 410 }
kadonotakashi 0:8fdf9a60065b 411 #endif
kadonotakashi 0:8fdf9a60065b 412 /* Wait last char shoft out */
kadonotakashi 0:8fdf9a60065b 413 while (0 == (base->STAT & LPUART_STAT_TC_MASK))
kadonotakashi 0:8fdf9a60065b 414 {
kadonotakashi 0:8fdf9a60065b 415 }
kadonotakashi 0:8fdf9a60065b 416
kadonotakashi 0:8fdf9a60065b 417 /* Clear all status flags */
kadonotakashi 0:8fdf9a60065b 418 temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
kadonotakashi 0:8fdf9a60065b 419 LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
kadonotakashi 0:8fdf9a60065b 420
kadonotakashi 0:8fdf9a60065b 421 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
kadonotakashi 0:8fdf9a60065b 422 temp |= LPUART_STAT_LBKDIF_MASK;
kadonotakashi 0:8fdf9a60065b 423 #endif
kadonotakashi 0:8fdf9a60065b 424
kadonotakashi 0:8fdf9a60065b 425 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
kadonotakashi 0:8fdf9a60065b 426 temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK);
kadonotakashi 0:8fdf9a60065b 427 #endif
kadonotakashi 0:8fdf9a60065b 428
kadonotakashi 0:8fdf9a60065b 429 base->STAT |= temp;
kadonotakashi 0:8fdf9a60065b 430
kadonotakashi 0:8fdf9a60065b 431 /* Disable the module. */
kadonotakashi 0:8fdf9a60065b 432 base->CTRL = 0;
kadonotakashi 0:8fdf9a60065b 433
kadonotakashi 0:8fdf9a60065b 434 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
kadonotakashi 0:8fdf9a60065b 435 /* Disable lpuart clock */
kadonotakashi 0:8fdf9a60065b 436 CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 437 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
kadonotakashi 0:8fdf9a60065b 438 }
kadonotakashi 0:8fdf9a60065b 439
kadonotakashi 0:8fdf9a60065b 440 void LPUART_GetDefaultConfig(lpuart_config_t *config)
kadonotakashi 0:8fdf9a60065b 441 {
kadonotakashi 0:8fdf9a60065b 442 assert(config);
kadonotakashi 0:8fdf9a60065b 443
kadonotakashi 0:8fdf9a60065b 444 config->baudRate_Bps = 115200U;
kadonotakashi 0:8fdf9a60065b 445 config->parityMode = kLPUART_ParityDisabled;
kadonotakashi 0:8fdf9a60065b 446 config->dataBitsCount = kLPUART_EightDataBits;
kadonotakashi 0:8fdf9a60065b 447 config->isMsb = false;
kadonotakashi 0:8fdf9a60065b 448 #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT
kadonotakashi 0:8fdf9a60065b 449 config->stopBitCount = kLPUART_OneStopBit;
kadonotakashi 0:8fdf9a60065b 450 #endif
kadonotakashi 0:8fdf9a60065b 451 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 452 config->txFifoWatermark = 0;
kadonotakashi 0:8fdf9a60065b 453 config->rxFifoWatermark = 0;
kadonotakashi 0:8fdf9a60065b 454 #endif
kadonotakashi 0:8fdf9a60065b 455 config->enableTx = false;
kadonotakashi 0:8fdf9a60065b 456 config->enableRx = false;
kadonotakashi 0:8fdf9a60065b 457 }
kadonotakashi 0:8fdf9a60065b 458
kadonotakashi 0:8fdf9a60065b 459 status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
kadonotakashi 0:8fdf9a60065b 460 {
kadonotakashi 0:8fdf9a60065b 461 assert(baudRate_Bps);
kadonotakashi 0:8fdf9a60065b 462
kadonotakashi 0:8fdf9a60065b 463 uint32_t temp, oldCtrl;
kadonotakashi 0:8fdf9a60065b 464 uint16_t sbr, sbrTemp;
kadonotakashi 0:8fdf9a60065b 465 uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff;
kadonotakashi 0:8fdf9a60065b 466
kadonotakashi 0:8fdf9a60065b 467 /* This LPUART instantiation uses a slightly different baud rate calculation
kadonotakashi 0:8fdf9a60065b 468 * The idea is to use the best OSR (over-sampling rate) possible
kadonotakashi 0:8fdf9a60065b 469 * Note, OSR is typically hard-set to 16 in other LPUART instantiations
kadonotakashi 0:8fdf9a60065b 470 * loop to find the best OSR value possible, one that generates minimum baudDiff
kadonotakashi 0:8fdf9a60065b 471 * iterate through the rest of the supported values of OSR */
kadonotakashi 0:8fdf9a60065b 472
kadonotakashi 0:8fdf9a60065b 473 baudDiff = baudRate_Bps;
kadonotakashi 0:8fdf9a60065b 474 osr = 0;
kadonotakashi 0:8fdf9a60065b 475 sbr = 0;
kadonotakashi 0:8fdf9a60065b 476 for (osrTemp = 4; osrTemp <= 32; osrTemp++)
kadonotakashi 0:8fdf9a60065b 477 {
kadonotakashi 0:8fdf9a60065b 478 /* calculate the temporary sbr value */
kadonotakashi 0:8fdf9a60065b 479 sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp));
kadonotakashi 0:8fdf9a60065b 480 /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/
kadonotakashi 0:8fdf9a60065b 481 if (sbrTemp == 0)
kadonotakashi 0:8fdf9a60065b 482 {
kadonotakashi 0:8fdf9a60065b 483 sbrTemp = 1;
kadonotakashi 0:8fdf9a60065b 484 }
kadonotakashi 0:8fdf9a60065b 485 /* Calculate the baud rate based on the temporary OSR and SBR values */
kadonotakashi 0:8fdf9a60065b 486 calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp));
kadonotakashi 0:8fdf9a60065b 487
kadonotakashi 0:8fdf9a60065b 488 tempDiff = calculatedBaud - baudRate_Bps;
kadonotakashi 0:8fdf9a60065b 489
kadonotakashi 0:8fdf9a60065b 490 /* Select the better value between srb and (sbr + 1) */
kadonotakashi 0:8fdf9a60065b 491 if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)))))
kadonotakashi 0:8fdf9a60065b 492 {
kadonotakashi 0:8fdf9a60065b 493 tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1)));
kadonotakashi 0:8fdf9a60065b 494 sbrTemp++;
kadonotakashi 0:8fdf9a60065b 495 }
kadonotakashi 0:8fdf9a60065b 496
kadonotakashi 0:8fdf9a60065b 497 if (tempDiff <= baudDiff)
kadonotakashi 0:8fdf9a60065b 498 {
kadonotakashi 0:8fdf9a60065b 499 baudDiff = tempDiff;
kadonotakashi 0:8fdf9a60065b 500 osr = osrTemp; /* update and store the best OSR value calculated */
kadonotakashi 0:8fdf9a60065b 501 sbr = sbrTemp; /* update store the best SBR value calculated */
kadonotakashi 0:8fdf9a60065b 502 }
kadonotakashi 0:8fdf9a60065b 503 }
kadonotakashi 0:8fdf9a60065b 504
kadonotakashi 0:8fdf9a60065b 505 /* Check to see if actual baud rate is within 3% of desired baud rate
kadonotakashi 0:8fdf9a60065b 506 * based on the best calculate OSR value */
kadonotakashi 0:8fdf9a60065b 507 if (baudDiff < ((baudRate_Bps / 100) * 3))
kadonotakashi 0:8fdf9a60065b 508 {
kadonotakashi 0:8fdf9a60065b 509 /* Store CTRL before disable Tx and Rx */
kadonotakashi 0:8fdf9a60065b 510 oldCtrl = base->CTRL;
kadonotakashi 0:8fdf9a60065b 511
kadonotakashi 0:8fdf9a60065b 512 /* Disable LPUART TX RX before setting. */
kadonotakashi 0:8fdf9a60065b 513 base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK);
kadonotakashi 0:8fdf9a60065b 514
kadonotakashi 0:8fdf9a60065b 515 temp = base->BAUD;
kadonotakashi 0:8fdf9a60065b 516
kadonotakashi 0:8fdf9a60065b 517 /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling.
kadonotakashi 0:8fdf9a60065b 518 * If so, then "BOTHEDGE" sampling must be turned on */
kadonotakashi 0:8fdf9a60065b 519 if ((osr > 3) && (osr < 8))
kadonotakashi 0:8fdf9a60065b 520 {
kadonotakashi 0:8fdf9a60065b 521 temp |= LPUART_BAUD_BOTHEDGE_MASK;
kadonotakashi 0:8fdf9a60065b 522 }
kadonotakashi 0:8fdf9a60065b 523
kadonotakashi 0:8fdf9a60065b 524 /* program the osr value (bit value is one less than actual value) */
kadonotakashi 0:8fdf9a60065b 525 temp &= ~LPUART_BAUD_OSR_MASK;
kadonotakashi 0:8fdf9a60065b 526 temp |= LPUART_BAUD_OSR(osr - 1);
kadonotakashi 0:8fdf9a60065b 527
kadonotakashi 0:8fdf9a60065b 528 /* write the sbr value to the BAUD registers */
kadonotakashi 0:8fdf9a60065b 529 temp &= ~LPUART_BAUD_SBR_MASK;
kadonotakashi 0:8fdf9a60065b 530 base->BAUD = temp | LPUART_BAUD_SBR(sbr);
kadonotakashi 0:8fdf9a60065b 531
kadonotakashi 0:8fdf9a60065b 532 /* Restore CTRL. */
kadonotakashi 0:8fdf9a60065b 533 base->CTRL = oldCtrl;
kadonotakashi 0:8fdf9a60065b 534
kadonotakashi 0:8fdf9a60065b 535 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 536 }
kadonotakashi 0:8fdf9a60065b 537 else
kadonotakashi 0:8fdf9a60065b 538 {
kadonotakashi 0:8fdf9a60065b 539 /* Unacceptable baud rate difference of more than 3%*/
kadonotakashi 0:8fdf9a60065b 540 return kStatus_LPUART_BaudrateNotSupport;
kadonotakashi 0:8fdf9a60065b 541 }
kadonotakashi 0:8fdf9a60065b 542 }
kadonotakashi 0:8fdf9a60065b 543
kadonotakashi 0:8fdf9a60065b 544 void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 545 {
kadonotakashi 0:8fdf9a60065b 546 base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
kadonotakashi 0:8fdf9a60065b 547 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 548 base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) |
kadonotakashi 0:8fdf9a60065b 549 ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
kadonotakashi 0:8fdf9a60065b 550 #endif
kadonotakashi 0:8fdf9a60065b 551 mask &= 0xFFFFFF00U;
kadonotakashi 0:8fdf9a60065b 552 base->CTRL |= mask;
kadonotakashi 0:8fdf9a60065b 553 }
kadonotakashi 0:8fdf9a60065b 554
kadonotakashi 0:8fdf9a60065b 555 void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 556 {
kadonotakashi 0:8fdf9a60065b 557 base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK));
kadonotakashi 0:8fdf9a60065b 558 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 559 base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) &
kadonotakashi 0:8fdf9a60065b 560 ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK));
kadonotakashi 0:8fdf9a60065b 561 #endif
kadonotakashi 0:8fdf9a60065b 562 mask &= 0xFFFFFF00U;
kadonotakashi 0:8fdf9a60065b 563 base->CTRL &= ~mask;
kadonotakashi 0:8fdf9a60065b 564 }
kadonotakashi 0:8fdf9a60065b 565
kadonotakashi 0:8fdf9a60065b 566 uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base)
kadonotakashi 0:8fdf9a60065b 567 {
kadonotakashi 0:8fdf9a60065b 568 uint32_t temp;
kadonotakashi 0:8fdf9a60065b 569 temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8;
kadonotakashi 0:8fdf9a60065b 570 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 571 temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8;
kadonotakashi 0:8fdf9a60065b 572 #endif
kadonotakashi 0:8fdf9a60065b 573 temp |= (base->CTRL & 0xFF0C000);
kadonotakashi 0:8fdf9a60065b 574
kadonotakashi 0:8fdf9a60065b 575 return temp;
kadonotakashi 0:8fdf9a60065b 576 }
kadonotakashi 0:8fdf9a60065b 577
kadonotakashi 0:8fdf9a60065b 578 uint32_t LPUART_GetStatusFlags(LPUART_Type *base)
kadonotakashi 0:8fdf9a60065b 579 {
kadonotakashi 0:8fdf9a60065b 580 uint32_t temp;
kadonotakashi 0:8fdf9a60065b 581 temp = base->STAT;
kadonotakashi 0:8fdf9a60065b 582 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 583 temp |= (base->FIFO &
kadonotakashi 0:8fdf9a60065b 584 (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >>
kadonotakashi 0:8fdf9a60065b 585 16;
kadonotakashi 0:8fdf9a60065b 586 #endif
kadonotakashi 0:8fdf9a60065b 587 return temp;
kadonotakashi 0:8fdf9a60065b 588 }
kadonotakashi 0:8fdf9a60065b 589
kadonotakashi 0:8fdf9a60065b 590 status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 591 {
kadonotakashi 0:8fdf9a60065b 592 uint32_t temp;
kadonotakashi 0:8fdf9a60065b 593 status_t status;
kadonotakashi 0:8fdf9a60065b 594 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 595 temp = (uint32_t)base->FIFO;
kadonotakashi 0:8fdf9a60065b 596 temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK));
kadonotakashi 0:8fdf9a60065b 597 temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK);
kadonotakashi 0:8fdf9a60065b 598 base->FIFO = temp;
kadonotakashi 0:8fdf9a60065b 599 #endif
kadonotakashi 0:8fdf9a60065b 600 temp = (uint32_t)base->STAT;
kadonotakashi 0:8fdf9a60065b 601 #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT
kadonotakashi 0:8fdf9a60065b 602 temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK));
kadonotakashi 0:8fdf9a60065b 603 temp |= mask & LPUART_STAT_LBKDIF_MASK;
kadonotakashi 0:8fdf9a60065b 604 #endif
kadonotakashi 0:8fdf9a60065b 605 temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
kadonotakashi 0:8fdf9a60065b 606 LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK));
kadonotakashi 0:8fdf9a60065b 607 temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK |
kadonotakashi 0:8fdf9a60065b 608 LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK);
kadonotakashi 0:8fdf9a60065b 609 #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING
kadonotakashi 0:8fdf9a60065b 610 temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK));
kadonotakashi 0:8fdf9a60065b 611 temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK);
kadonotakashi 0:8fdf9a60065b 612 #endif
kadonotakashi 0:8fdf9a60065b 613 base->STAT = temp;
kadonotakashi 0:8fdf9a60065b 614 /* If some flags still pending. */
kadonotakashi 0:8fdf9a60065b 615 if (mask & LPUART_GetStatusFlags(base))
kadonotakashi 0:8fdf9a60065b 616 {
kadonotakashi 0:8fdf9a60065b 617 /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag,
kadonotakashi 0:8fdf9a60065b 618 kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag,
kadonotakashi 0:8fdf9a60065b 619 kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag,
kadonotakashi 0:8fdf9a60065b 620 kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */
kadonotakashi 0:8fdf9a60065b 621 status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */
kadonotakashi 0:8fdf9a60065b 622 }
kadonotakashi 0:8fdf9a60065b 623 else
kadonotakashi 0:8fdf9a60065b 624 {
kadonotakashi 0:8fdf9a60065b 625 status = kStatus_Success;
kadonotakashi 0:8fdf9a60065b 626 }
kadonotakashi 0:8fdf9a60065b 627
kadonotakashi 0:8fdf9a60065b 628 return status;
kadonotakashi 0:8fdf9a60065b 629 }
kadonotakashi 0:8fdf9a60065b 630
kadonotakashi 0:8fdf9a60065b 631 void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length)
kadonotakashi 0:8fdf9a60065b 632 {
kadonotakashi 0:8fdf9a60065b 633 assert(data);
kadonotakashi 0:8fdf9a60065b 634
kadonotakashi 0:8fdf9a60065b 635 /* This API can only ensure that the data is written into the data buffer but can't
kadonotakashi 0:8fdf9a60065b 636 ensure all data in the data buffer are sent into the transmit shift buffer. */
kadonotakashi 0:8fdf9a60065b 637 while (length--)
kadonotakashi 0:8fdf9a60065b 638 {
kadonotakashi 0:8fdf9a60065b 639 while (!(base->STAT & LPUART_STAT_TDRE_MASK))
kadonotakashi 0:8fdf9a60065b 640 {
kadonotakashi 0:8fdf9a60065b 641 }
kadonotakashi 0:8fdf9a60065b 642 base->DATA = *(data++);
kadonotakashi 0:8fdf9a60065b 643 }
kadonotakashi 0:8fdf9a60065b 644 }
kadonotakashi 0:8fdf9a60065b 645
kadonotakashi 0:8fdf9a60065b 646 status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length)
kadonotakashi 0:8fdf9a60065b 647 {
kadonotakashi 0:8fdf9a60065b 648 assert(data);
kadonotakashi 0:8fdf9a60065b 649
kadonotakashi 0:8fdf9a60065b 650 uint32_t statusFlag;
kadonotakashi 0:8fdf9a60065b 651 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 652 uint32_t ctrl = base->CTRL;
kadonotakashi 0:8fdf9a60065b 653 bool isSevenDataBits =
kadonotakashi 0:8fdf9a60065b 654 ((ctrl & LPUART_CTRL_M7_MASK) ||
kadonotakashi 0:8fdf9a60065b 655 ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
kadonotakashi 0:8fdf9a60065b 656 #endif
kadonotakashi 0:8fdf9a60065b 657
kadonotakashi 0:8fdf9a60065b 658 while (length--)
kadonotakashi 0:8fdf9a60065b 659 {
kadonotakashi 0:8fdf9a60065b 660 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 661 while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT))
kadonotakashi 0:8fdf9a60065b 662 #else
kadonotakashi 0:8fdf9a60065b 663 while (!(base->STAT & LPUART_STAT_RDRF_MASK))
kadonotakashi 0:8fdf9a60065b 664 #endif
kadonotakashi 0:8fdf9a60065b 665 {
kadonotakashi 0:8fdf9a60065b 666 statusFlag = LPUART_GetStatusFlags(base);
kadonotakashi 0:8fdf9a60065b 667
kadonotakashi 0:8fdf9a60065b 668 if (statusFlag & kLPUART_RxOverrunFlag)
kadonotakashi 0:8fdf9a60065b 669 {
kadonotakashi 0:8fdf9a60065b 670 LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag);
kadonotakashi 0:8fdf9a60065b 671 return kStatus_LPUART_RxHardwareOverrun;
kadonotakashi 0:8fdf9a60065b 672 }
kadonotakashi 0:8fdf9a60065b 673
kadonotakashi 0:8fdf9a60065b 674 if (statusFlag & kLPUART_NoiseErrorFlag)
kadonotakashi 0:8fdf9a60065b 675 {
kadonotakashi 0:8fdf9a60065b 676 LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag);
kadonotakashi 0:8fdf9a60065b 677 return kStatus_LPUART_NoiseError;
kadonotakashi 0:8fdf9a60065b 678 }
kadonotakashi 0:8fdf9a60065b 679
kadonotakashi 0:8fdf9a60065b 680 if (statusFlag & kLPUART_FramingErrorFlag)
kadonotakashi 0:8fdf9a60065b 681 {
kadonotakashi 0:8fdf9a60065b 682 LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag);
kadonotakashi 0:8fdf9a60065b 683 return kStatus_LPUART_FramingError;
kadonotakashi 0:8fdf9a60065b 684 }
kadonotakashi 0:8fdf9a60065b 685
kadonotakashi 0:8fdf9a60065b 686 if (statusFlag & kLPUART_ParityErrorFlag)
kadonotakashi 0:8fdf9a60065b 687 {
kadonotakashi 0:8fdf9a60065b 688 LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag);
kadonotakashi 0:8fdf9a60065b 689 return kStatus_LPUART_ParityError;
kadonotakashi 0:8fdf9a60065b 690 }
kadonotakashi 0:8fdf9a60065b 691 }
kadonotakashi 0:8fdf9a60065b 692 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 693 if (isSevenDataBits)
kadonotakashi 0:8fdf9a60065b 694 {
kadonotakashi 0:8fdf9a60065b 695 *(data++) = (base->DATA & 0x7F);
kadonotakashi 0:8fdf9a60065b 696 }
kadonotakashi 0:8fdf9a60065b 697 else
kadonotakashi 0:8fdf9a60065b 698 {
kadonotakashi 0:8fdf9a60065b 699 *(data++) = base->DATA;
kadonotakashi 0:8fdf9a60065b 700 }
kadonotakashi 0:8fdf9a60065b 701 #else
kadonotakashi 0:8fdf9a60065b 702 *(data++) = base->DATA;
kadonotakashi 0:8fdf9a60065b 703 #endif
kadonotakashi 0:8fdf9a60065b 704 }
kadonotakashi 0:8fdf9a60065b 705
kadonotakashi 0:8fdf9a60065b 706 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 707 }
kadonotakashi 0:8fdf9a60065b 708
kadonotakashi 0:8fdf9a60065b 709 void LPUART_TransferCreateHandle(LPUART_Type *base,
kadonotakashi 0:8fdf9a60065b 710 lpuart_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 711 lpuart_transfer_callback_t callback,
kadonotakashi 0:8fdf9a60065b 712 void *userData)
kadonotakashi 0:8fdf9a60065b 713 {
kadonotakashi 0:8fdf9a60065b 714 assert(handle);
kadonotakashi 0:8fdf9a60065b 715
kadonotakashi 0:8fdf9a60065b 716 uint32_t instance;
kadonotakashi 0:8fdf9a60065b 717 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 718 uint32_t ctrl = base->CTRL;
kadonotakashi 0:8fdf9a60065b 719 bool isSevenDataBits =
kadonotakashi 0:8fdf9a60065b 720 ((ctrl & LPUART_CTRL_M7_MASK) ||
kadonotakashi 0:8fdf9a60065b 721 ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK)));
kadonotakashi 0:8fdf9a60065b 722 #endif
kadonotakashi 0:8fdf9a60065b 723
kadonotakashi 0:8fdf9a60065b 724 /* Zero the handle. */
kadonotakashi 0:8fdf9a60065b 725 memset(handle, 0, sizeof(lpuart_handle_t));
kadonotakashi 0:8fdf9a60065b 726
kadonotakashi 0:8fdf9a60065b 727 /* Set the TX/RX state. */
kadonotakashi 0:8fdf9a60065b 728 handle->rxState = kLPUART_RxIdle;
kadonotakashi 0:8fdf9a60065b 729 handle->txState = kLPUART_TxIdle;
kadonotakashi 0:8fdf9a60065b 730
kadonotakashi 0:8fdf9a60065b 731 /* Set the callback and user data. */
kadonotakashi 0:8fdf9a60065b 732 handle->callback = callback;
kadonotakashi 0:8fdf9a60065b 733 handle->userData = userData;
kadonotakashi 0:8fdf9a60065b 734
kadonotakashi 0:8fdf9a60065b 735 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 736 /* Initial seven data bits flag */
kadonotakashi 0:8fdf9a60065b 737 handle->isSevenDataBits = isSevenDataBits;
kadonotakashi 0:8fdf9a60065b 738 #endif
kadonotakashi 0:8fdf9a60065b 739
kadonotakashi 0:8fdf9a60065b 740 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 741 /* Note:
kadonotakashi 0:8fdf9a60065b 742 Take care of the RX FIFO, RX interrupt request only assert when received bytes
kadonotakashi 0:8fdf9a60065b 743 equal or more than RX water mark, there is potential issue if RX water
kadonotakashi 0:8fdf9a60065b 744 mark larger than 1.
kadonotakashi 0:8fdf9a60065b 745 For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and
kadonotakashi 0:8fdf9a60065b 746 5 bytes are received. the last byte will be saved in FIFO but not trigger
kadonotakashi 0:8fdf9a60065b 747 RX interrupt because the water mark is 2.
kadonotakashi 0:8fdf9a60065b 748 */
kadonotakashi 0:8fdf9a60065b 749 base->WATER &= (~LPUART_WATER_RXWATER_MASK);
kadonotakashi 0:8fdf9a60065b 750 #endif
kadonotakashi 0:8fdf9a60065b 751
kadonotakashi 0:8fdf9a60065b 752 /* Get instance from peripheral base address. */
kadonotakashi 0:8fdf9a60065b 753 instance = LPUART_GetInstance(base);
kadonotakashi 0:8fdf9a60065b 754
kadonotakashi 0:8fdf9a60065b 755 /* Save the handle in global variables to support the double weak mechanism. */
kadonotakashi 0:8fdf9a60065b 756 s_lpuartHandle[instance] = handle;
kadonotakashi 0:8fdf9a60065b 757
kadonotakashi 0:8fdf9a60065b 758 s_lpuartIsr = LPUART_TransferHandleIRQ;
kadonotakashi 0:8fdf9a60065b 759
kadonotakashi 0:8fdf9a60065b 760 /* Enable interrupt in NVIC. */
kadonotakashi 0:8fdf9a60065b 761 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 762 EnableIRQ(s_lpuartRxIRQ[instance]);
kadonotakashi 0:8fdf9a60065b 763 EnableIRQ(s_lpuartTxIRQ[instance]);
kadonotakashi 0:8fdf9a60065b 764 #else
kadonotakashi 0:8fdf9a60065b 765 EnableIRQ(s_lpuartIRQ[instance]);
kadonotakashi 0:8fdf9a60065b 766 #endif
kadonotakashi 0:8fdf9a60065b 767 }
kadonotakashi 0:8fdf9a60065b 768
kadonotakashi 0:8fdf9a60065b 769 void LPUART_TransferStartRingBuffer(LPUART_Type *base,
kadonotakashi 0:8fdf9a60065b 770 lpuart_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 771 uint8_t *ringBuffer,
kadonotakashi 0:8fdf9a60065b 772 size_t ringBufferSize)
kadonotakashi 0:8fdf9a60065b 773 {
kadonotakashi 0:8fdf9a60065b 774 assert(handle);
kadonotakashi 0:8fdf9a60065b 775 assert(ringBuffer);
kadonotakashi 0:8fdf9a60065b 776
kadonotakashi 0:8fdf9a60065b 777 /* Setup the ring buffer address */
kadonotakashi 0:8fdf9a60065b 778 handle->rxRingBuffer = ringBuffer;
kadonotakashi 0:8fdf9a60065b 779 handle->rxRingBufferSize = ringBufferSize;
kadonotakashi 0:8fdf9a60065b 780 handle->rxRingBufferHead = 0U;
kadonotakashi 0:8fdf9a60065b 781 handle->rxRingBufferTail = 0U;
kadonotakashi 0:8fdf9a60065b 782
kadonotakashi 0:8fdf9a60065b 783 /* Enable the interrupt to accept the data when user need the ring buffer. */
kadonotakashi 0:8fdf9a60065b 784 LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
kadonotakashi 0:8fdf9a60065b 785 }
kadonotakashi 0:8fdf9a60065b 786
kadonotakashi 0:8fdf9a60065b 787 void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 788 {
kadonotakashi 0:8fdf9a60065b 789 assert(handle);
kadonotakashi 0:8fdf9a60065b 790
kadonotakashi 0:8fdf9a60065b 791 if (handle->rxState == kLPUART_RxIdle)
kadonotakashi 0:8fdf9a60065b 792 {
kadonotakashi 0:8fdf9a60065b 793 LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
kadonotakashi 0:8fdf9a60065b 794 }
kadonotakashi 0:8fdf9a60065b 795
kadonotakashi 0:8fdf9a60065b 796 handle->rxRingBuffer = NULL;
kadonotakashi 0:8fdf9a60065b 797 handle->rxRingBufferSize = 0U;
kadonotakashi 0:8fdf9a60065b 798 handle->rxRingBufferHead = 0U;
kadonotakashi 0:8fdf9a60065b 799 handle->rxRingBufferTail = 0U;
kadonotakashi 0:8fdf9a60065b 800 }
kadonotakashi 0:8fdf9a60065b 801
kadonotakashi 0:8fdf9a60065b 802 status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer)
kadonotakashi 0:8fdf9a60065b 803 {
kadonotakashi 0:8fdf9a60065b 804 assert(handle);
kadonotakashi 0:8fdf9a60065b 805 assert(xfer);
kadonotakashi 0:8fdf9a60065b 806 assert(xfer->data);
kadonotakashi 0:8fdf9a60065b 807 assert(xfer->dataSize);
kadonotakashi 0:8fdf9a60065b 808
kadonotakashi 0:8fdf9a60065b 809 status_t status;
kadonotakashi 0:8fdf9a60065b 810
kadonotakashi 0:8fdf9a60065b 811 /* Return error if current TX busy. */
kadonotakashi 0:8fdf9a60065b 812 if (kLPUART_TxBusy == handle->txState)
kadonotakashi 0:8fdf9a60065b 813 {
kadonotakashi 0:8fdf9a60065b 814 status = kStatus_LPUART_TxBusy;
kadonotakashi 0:8fdf9a60065b 815 }
kadonotakashi 0:8fdf9a60065b 816 else
kadonotakashi 0:8fdf9a60065b 817 {
kadonotakashi 0:8fdf9a60065b 818 handle->txData = xfer->data;
kadonotakashi 0:8fdf9a60065b 819 handle->txDataSize = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 820 handle->txDataSizeAll = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 821 handle->txState = kLPUART_TxBusy;
kadonotakashi 0:8fdf9a60065b 822
kadonotakashi 0:8fdf9a60065b 823 /* Enable transmiter interrupt. */
kadonotakashi 0:8fdf9a60065b 824 LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable);
kadonotakashi 0:8fdf9a60065b 825
kadonotakashi 0:8fdf9a60065b 826 status = kStatus_Success;
kadonotakashi 0:8fdf9a60065b 827 }
kadonotakashi 0:8fdf9a60065b 828
kadonotakashi 0:8fdf9a60065b 829 return status;
kadonotakashi 0:8fdf9a60065b 830 }
kadonotakashi 0:8fdf9a60065b 831
kadonotakashi 0:8fdf9a60065b 832 void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 833 {
kadonotakashi 0:8fdf9a60065b 834 assert(handle);
kadonotakashi 0:8fdf9a60065b 835
kadonotakashi 0:8fdf9a60065b 836 LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable);
kadonotakashi 0:8fdf9a60065b 837
kadonotakashi 0:8fdf9a60065b 838 handle->txDataSize = 0;
kadonotakashi 0:8fdf9a60065b 839 handle->txState = kLPUART_TxIdle;
kadonotakashi 0:8fdf9a60065b 840 }
kadonotakashi 0:8fdf9a60065b 841
kadonotakashi 0:8fdf9a60065b 842 status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
kadonotakashi 0:8fdf9a60065b 843 {
kadonotakashi 0:8fdf9a60065b 844 assert(handle);
kadonotakashi 0:8fdf9a60065b 845 assert(count);
kadonotakashi 0:8fdf9a60065b 846
kadonotakashi 0:8fdf9a60065b 847 if (kLPUART_TxIdle == handle->txState)
kadonotakashi 0:8fdf9a60065b 848 {
kadonotakashi 0:8fdf9a60065b 849 return kStatus_NoTransferInProgress;
kadonotakashi 0:8fdf9a60065b 850 }
kadonotakashi 0:8fdf9a60065b 851
kadonotakashi 0:8fdf9a60065b 852 *count = handle->txDataSizeAll - handle->txDataSize;
kadonotakashi 0:8fdf9a60065b 853
kadonotakashi 0:8fdf9a60065b 854 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 855 }
kadonotakashi 0:8fdf9a60065b 856
kadonotakashi 0:8fdf9a60065b 857 status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base,
kadonotakashi 0:8fdf9a60065b 858 lpuart_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 859 lpuart_transfer_t *xfer,
kadonotakashi 0:8fdf9a60065b 860 size_t *receivedBytes)
kadonotakashi 0:8fdf9a60065b 861 {
kadonotakashi 0:8fdf9a60065b 862 assert(handle);
kadonotakashi 0:8fdf9a60065b 863 assert(xfer);
kadonotakashi 0:8fdf9a60065b 864 assert(xfer->data);
kadonotakashi 0:8fdf9a60065b 865 assert(xfer->dataSize);
kadonotakashi 0:8fdf9a60065b 866
kadonotakashi 0:8fdf9a60065b 867 uint32_t i;
kadonotakashi 0:8fdf9a60065b 868 status_t status;
kadonotakashi 0:8fdf9a60065b 869 /* How many bytes to copy from ring buffer to user memory. */
kadonotakashi 0:8fdf9a60065b 870 size_t bytesToCopy = 0U;
kadonotakashi 0:8fdf9a60065b 871 /* How many bytes to receive. */
kadonotakashi 0:8fdf9a60065b 872 size_t bytesToReceive;
kadonotakashi 0:8fdf9a60065b 873 /* How many bytes currently have received. */
kadonotakashi 0:8fdf9a60065b 874 size_t bytesCurrentReceived;
kadonotakashi 0:8fdf9a60065b 875
kadonotakashi 0:8fdf9a60065b 876 /* How to get data:
kadonotakashi 0:8fdf9a60065b 877 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize
kadonotakashi 0:8fdf9a60065b 878 to lpuart handle, enable interrupt to store received data to xfer->data. When
kadonotakashi 0:8fdf9a60065b 879 all data received, trigger callback.
kadonotakashi 0:8fdf9a60065b 880 2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
kadonotakashi 0:8fdf9a60065b 881 If there are enough data in ring buffer, copy them to xfer->data and return.
kadonotakashi 0:8fdf9a60065b 882 If there are not enough data in ring buffer, copy all of them to xfer->data,
kadonotakashi 0:8fdf9a60065b 883 save the xfer->data remained empty space to lpuart handle, receive data
kadonotakashi 0:8fdf9a60065b 884 to this empty space and trigger callback when finished. */
kadonotakashi 0:8fdf9a60065b 885
kadonotakashi 0:8fdf9a60065b 886 if (kLPUART_RxBusy == handle->rxState)
kadonotakashi 0:8fdf9a60065b 887 {
kadonotakashi 0:8fdf9a60065b 888 status = kStatus_LPUART_RxBusy;
kadonotakashi 0:8fdf9a60065b 889 }
kadonotakashi 0:8fdf9a60065b 890 else
kadonotakashi 0:8fdf9a60065b 891 {
kadonotakashi 0:8fdf9a60065b 892 bytesToReceive = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 893 bytesCurrentReceived = 0;
kadonotakashi 0:8fdf9a60065b 894
kadonotakashi 0:8fdf9a60065b 895 /* If RX ring buffer is used. */
kadonotakashi 0:8fdf9a60065b 896 if (handle->rxRingBuffer)
kadonotakashi 0:8fdf9a60065b 897 {
kadonotakashi 0:8fdf9a60065b 898 /* Disable LPUART RX IRQ, protect ring buffer. */
kadonotakashi 0:8fdf9a60065b 899 LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
kadonotakashi 0:8fdf9a60065b 900
kadonotakashi 0:8fdf9a60065b 901 /* How many bytes in RX ring buffer currently. */
kadonotakashi 0:8fdf9a60065b 902 bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle);
kadonotakashi 0:8fdf9a60065b 903
kadonotakashi 0:8fdf9a60065b 904 if (bytesToCopy)
kadonotakashi 0:8fdf9a60065b 905 {
kadonotakashi 0:8fdf9a60065b 906 bytesToCopy = MIN(bytesToReceive, bytesToCopy);
kadonotakashi 0:8fdf9a60065b 907
kadonotakashi 0:8fdf9a60065b 908 bytesToReceive -= bytesToCopy;
kadonotakashi 0:8fdf9a60065b 909
kadonotakashi 0:8fdf9a60065b 910 /* Copy data from ring buffer to user memory. */
kadonotakashi 0:8fdf9a60065b 911 for (i = 0U; i < bytesToCopy; i++)
kadonotakashi 0:8fdf9a60065b 912 {
kadonotakashi 0:8fdf9a60065b 913 xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
kadonotakashi 0:8fdf9a60065b 914
kadonotakashi 0:8fdf9a60065b 915 /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
kadonotakashi 0:8fdf9a60065b 916 if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
kadonotakashi 0:8fdf9a60065b 917 {
kadonotakashi 0:8fdf9a60065b 918 handle->rxRingBufferTail = 0U;
kadonotakashi 0:8fdf9a60065b 919 }
kadonotakashi 0:8fdf9a60065b 920 else
kadonotakashi 0:8fdf9a60065b 921 {
kadonotakashi 0:8fdf9a60065b 922 handle->rxRingBufferTail++;
kadonotakashi 0:8fdf9a60065b 923 }
kadonotakashi 0:8fdf9a60065b 924 }
kadonotakashi 0:8fdf9a60065b 925 }
kadonotakashi 0:8fdf9a60065b 926
kadonotakashi 0:8fdf9a60065b 927 /* If ring buffer does not have enough data, still need to read more data. */
kadonotakashi 0:8fdf9a60065b 928 if (bytesToReceive)
kadonotakashi 0:8fdf9a60065b 929 {
kadonotakashi 0:8fdf9a60065b 930 /* No data in ring buffer, save the request to LPUART handle. */
kadonotakashi 0:8fdf9a60065b 931 handle->rxData = xfer->data + bytesCurrentReceived;
kadonotakashi 0:8fdf9a60065b 932 handle->rxDataSize = bytesToReceive;
kadonotakashi 0:8fdf9a60065b 933 handle->rxDataSizeAll = bytesToReceive;
kadonotakashi 0:8fdf9a60065b 934 handle->rxState = kLPUART_RxBusy;
kadonotakashi 0:8fdf9a60065b 935 }
kadonotakashi 0:8fdf9a60065b 936 /* Enable LPUART RX IRQ if previously enabled. */
kadonotakashi 0:8fdf9a60065b 937 LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable);
kadonotakashi 0:8fdf9a60065b 938
kadonotakashi 0:8fdf9a60065b 939 /* Call user callback since all data are received. */
kadonotakashi 0:8fdf9a60065b 940 if (0 == bytesToReceive)
kadonotakashi 0:8fdf9a60065b 941 {
kadonotakashi 0:8fdf9a60065b 942 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 943 {
kadonotakashi 0:8fdf9a60065b 944 handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
kadonotakashi 0:8fdf9a60065b 945 }
kadonotakashi 0:8fdf9a60065b 946 }
kadonotakashi 0:8fdf9a60065b 947 }
kadonotakashi 0:8fdf9a60065b 948 /* Ring buffer not used. */
kadonotakashi 0:8fdf9a60065b 949 else
kadonotakashi 0:8fdf9a60065b 950 {
kadonotakashi 0:8fdf9a60065b 951 handle->rxData = xfer->data + bytesCurrentReceived;
kadonotakashi 0:8fdf9a60065b 952 handle->rxDataSize = bytesToReceive;
kadonotakashi 0:8fdf9a60065b 953 handle->rxDataSizeAll = bytesToReceive;
kadonotakashi 0:8fdf9a60065b 954 handle->rxState = kLPUART_RxBusy;
kadonotakashi 0:8fdf9a60065b 955
kadonotakashi 0:8fdf9a60065b 956 /* Enable RX interrupt. */
kadonotakashi 0:8fdf9a60065b 957 LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
kadonotakashi 0:8fdf9a60065b 958 }
kadonotakashi 0:8fdf9a60065b 959
kadonotakashi 0:8fdf9a60065b 960 /* Return the how many bytes have read. */
kadonotakashi 0:8fdf9a60065b 961 if (receivedBytes)
kadonotakashi 0:8fdf9a60065b 962 {
kadonotakashi 0:8fdf9a60065b 963 *receivedBytes = bytesCurrentReceived;
kadonotakashi 0:8fdf9a60065b 964 }
kadonotakashi 0:8fdf9a60065b 965
kadonotakashi 0:8fdf9a60065b 966 status = kStatus_Success;
kadonotakashi 0:8fdf9a60065b 967 }
kadonotakashi 0:8fdf9a60065b 968
kadonotakashi 0:8fdf9a60065b 969 return status;
kadonotakashi 0:8fdf9a60065b 970 }
kadonotakashi 0:8fdf9a60065b 971
kadonotakashi 0:8fdf9a60065b 972 void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 973 {
kadonotakashi 0:8fdf9a60065b 974 assert(handle);
kadonotakashi 0:8fdf9a60065b 975
kadonotakashi 0:8fdf9a60065b 976 /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
kadonotakashi 0:8fdf9a60065b 977 if (!handle->rxRingBuffer)
kadonotakashi 0:8fdf9a60065b 978 {
kadonotakashi 0:8fdf9a60065b 979 /* Disable RX interrupt. */
kadonotakashi 0:8fdf9a60065b 980 LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
kadonotakashi 0:8fdf9a60065b 981 }
kadonotakashi 0:8fdf9a60065b 982
kadonotakashi 0:8fdf9a60065b 983 handle->rxDataSize = 0U;
kadonotakashi 0:8fdf9a60065b 984 handle->rxState = kLPUART_RxIdle;
kadonotakashi 0:8fdf9a60065b 985 }
kadonotakashi 0:8fdf9a60065b 986
kadonotakashi 0:8fdf9a60065b 987 status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count)
kadonotakashi 0:8fdf9a60065b 988 {
kadonotakashi 0:8fdf9a60065b 989 assert(handle);
kadonotakashi 0:8fdf9a60065b 990 assert(count);
kadonotakashi 0:8fdf9a60065b 991
kadonotakashi 0:8fdf9a60065b 992 if (kLPUART_RxIdle == handle->rxState)
kadonotakashi 0:8fdf9a60065b 993 {
kadonotakashi 0:8fdf9a60065b 994 return kStatus_NoTransferInProgress;
kadonotakashi 0:8fdf9a60065b 995 }
kadonotakashi 0:8fdf9a60065b 996
kadonotakashi 0:8fdf9a60065b 997 *count = handle->rxDataSizeAll - handle->rxDataSize;
kadonotakashi 0:8fdf9a60065b 998
kadonotakashi 0:8fdf9a60065b 999 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 1000 }
kadonotakashi 0:8fdf9a60065b 1001
kadonotakashi 0:8fdf9a60065b 1002 void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 1003 {
kadonotakashi 0:8fdf9a60065b 1004 assert(handle);
kadonotakashi 0:8fdf9a60065b 1005
kadonotakashi 0:8fdf9a60065b 1006 uint8_t count;
kadonotakashi 0:8fdf9a60065b 1007 uint8_t tempCount;
kadonotakashi 0:8fdf9a60065b 1008
kadonotakashi 0:8fdf9a60065b 1009 /* If RX overrun. */
kadonotakashi 0:8fdf9a60065b 1010 if (LPUART_STAT_OR_MASK & base->STAT)
kadonotakashi 0:8fdf9a60065b 1011 {
kadonotakashi 0:8fdf9a60065b 1012 /* Clear overrun flag, otherwise the RX does not work. */
kadonotakashi 0:8fdf9a60065b 1013 base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK);
kadonotakashi 0:8fdf9a60065b 1014
kadonotakashi 0:8fdf9a60065b 1015 /* Trigger callback. */
kadonotakashi 0:8fdf9a60065b 1016 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 1017 {
kadonotakashi 0:8fdf9a60065b 1018 handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData);
kadonotakashi 0:8fdf9a60065b 1019 }
kadonotakashi 0:8fdf9a60065b 1020 }
kadonotakashi 0:8fdf9a60065b 1021
kadonotakashi 0:8fdf9a60065b 1022 /* Receive data register full */
kadonotakashi 0:8fdf9a60065b 1023 if ((LPUART_STAT_RDRF_MASK & base->STAT) && (LPUART_CTRL_RIE_MASK & base->CTRL))
kadonotakashi 0:8fdf9a60065b 1024 {
kadonotakashi 0:8fdf9a60065b 1025 /* Get the size that can be stored into buffer for this interrupt. */
kadonotakashi 0:8fdf9a60065b 1026 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 1027 count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT));
kadonotakashi 0:8fdf9a60065b 1028 #else
kadonotakashi 0:8fdf9a60065b 1029 count = 1;
kadonotakashi 0:8fdf9a60065b 1030 #endif
kadonotakashi 0:8fdf9a60065b 1031
kadonotakashi 0:8fdf9a60065b 1032 /* If handle->rxDataSize is not 0, first save data to handle->rxData. */
kadonotakashi 0:8fdf9a60065b 1033 while ((count) && (handle->rxDataSize))
kadonotakashi 0:8fdf9a60065b 1034 {
kadonotakashi 0:8fdf9a60065b 1035 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 1036 tempCount = MIN(handle->rxDataSize, count);
kadonotakashi 0:8fdf9a60065b 1037 #else
kadonotakashi 0:8fdf9a60065b 1038 tempCount = 1;
kadonotakashi 0:8fdf9a60065b 1039 #endif
kadonotakashi 0:8fdf9a60065b 1040
kadonotakashi 0:8fdf9a60065b 1041 /* Using non block API to read the data from the registers. */
kadonotakashi 0:8fdf9a60065b 1042 LPUART_ReadNonBlocking(base, handle->rxData, tempCount);
kadonotakashi 0:8fdf9a60065b 1043 handle->rxData += tempCount;
kadonotakashi 0:8fdf9a60065b 1044 handle->rxDataSize -= tempCount;
kadonotakashi 0:8fdf9a60065b 1045 count -= tempCount;
kadonotakashi 0:8fdf9a60065b 1046
kadonotakashi 0:8fdf9a60065b 1047 /* If all the data required for upper layer is ready, trigger callback. */
kadonotakashi 0:8fdf9a60065b 1048 if (!handle->rxDataSize)
kadonotakashi 0:8fdf9a60065b 1049 {
kadonotakashi 0:8fdf9a60065b 1050 handle->rxState = kLPUART_RxIdle;
kadonotakashi 0:8fdf9a60065b 1051
kadonotakashi 0:8fdf9a60065b 1052 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 1053 {
kadonotakashi 0:8fdf9a60065b 1054 handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData);
kadonotakashi 0:8fdf9a60065b 1055 }
kadonotakashi 0:8fdf9a60065b 1056 }
kadonotakashi 0:8fdf9a60065b 1057 }
kadonotakashi 0:8fdf9a60065b 1058
kadonotakashi 0:8fdf9a60065b 1059 /* If use RX ring buffer, receive data to ring buffer. */
kadonotakashi 0:8fdf9a60065b 1060 if (handle->rxRingBuffer)
kadonotakashi 0:8fdf9a60065b 1061 {
kadonotakashi 0:8fdf9a60065b 1062 while (count--)
kadonotakashi 0:8fdf9a60065b 1063 {
kadonotakashi 0:8fdf9a60065b 1064 /* If RX ring buffer is full, trigger callback to notify over run. */
kadonotakashi 0:8fdf9a60065b 1065 if (LPUART_TransferIsRxRingBufferFull(base, handle))
kadonotakashi 0:8fdf9a60065b 1066 {
kadonotakashi 0:8fdf9a60065b 1067 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 1068 {
kadonotakashi 0:8fdf9a60065b 1069 handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData);
kadonotakashi 0:8fdf9a60065b 1070 }
kadonotakashi 0:8fdf9a60065b 1071 }
kadonotakashi 0:8fdf9a60065b 1072
kadonotakashi 0:8fdf9a60065b 1073 /* If ring buffer is still full after callback function, the oldest data is overrided. */
kadonotakashi 0:8fdf9a60065b 1074 if (LPUART_TransferIsRxRingBufferFull(base, handle))
kadonotakashi 0:8fdf9a60065b 1075 {
kadonotakashi 0:8fdf9a60065b 1076 /* Increase handle->rxRingBufferTail to make room for new data. */
kadonotakashi 0:8fdf9a60065b 1077 if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
kadonotakashi 0:8fdf9a60065b 1078 {
kadonotakashi 0:8fdf9a60065b 1079 handle->rxRingBufferTail = 0U;
kadonotakashi 0:8fdf9a60065b 1080 }
kadonotakashi 0:8fdf9a60065b 1081 else
kadonotakashi 0:8fdf9a60065b 1082 {
kadonotakashi 0:8fdf9a60065b 1083 handle->rxRingBufferTail++;
kadonotakashi 0:8fdf9a60065b 1084 }
kadonotakashi 0:8fdf9a60065b 1085 }
kadonotakashi 0:8fdf9a60065b 1086
kadonotakashi 0:8fdf9a60065b 1087 /* Read data. */
kadonotakashi 0:8fdf9a60065b 1088 #if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
kadonotakashi 0:8fdf9a60065b 1089 if (handle->isSevenDataBits)
kadonotakashi 0:8fdf9a60065b 1090 {
kadonotakashi 0:8fdf9a60065b 1091 handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F);
kadonotakashi 0:8fdf9a60065b 1092 }
kadonotakashi 0:8fdf9a60065b 1093 else
kadonotakashi 0:8fdf9a60065b 1094 {
kadonotakashi 0:8fdf9a60065b 1095 handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
kadonotakashi 0:8fdf9a60065b 1096 }
kadonotakashi 0:8fdf9a60065b 1097 #else
kadonotakashi 0:8fdf9a60065b 1098 handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA;
kadonotakashi 0:8fdf9a60065b 1099 #endif
kadonotakashi 0:8fdf9a60065b 1100
kadonotakashi 0:8fdf9a60065b 1101 /* Increase handle->rxRingBufferHead. */
kadonotakashi 0:8fdf9a60065b 1102 if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
kadonotakashi 0:8fdf9a60065b 1103 {
kadonotakashi 0:8fdf9a60065b 1104 handle->rxRingBufferHead = 0U;
kadonotakashi 0:8fdf9a60065b 1105 }
kadonotakashi 0:8fdf9a60065b 1106 else
kadonotakashi 0:8fdf9a60065b 1107 {
kadonotakashi 0:8fdf9a60065b 1108 handle->rxRingBufferHead++;
kadonotakashi 0:8fdf9a60065b 1109 }
kadonotakashi 0:8fdf9a60065b 1110 }
kadonotakashi 0:8fdf9a60065b 1111 }
kadonotakashi 0:8fdf9a60065b 1112 /* If no receive requst pending, stop RX interrupt. */
kadonotakashi 0:8fdf9a60065b 1113 else if (!handle->rxDataSize)
kadonotakashi 0:8fdf9a60065b 1114 {
kadonotakashi 0:8fdf9a60065b 1115 LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
kadonotakashi 0:8fdf9a60065b 1116 }
kadonotakashi 0:8fdf9a60065b 1117 else
kadonotakashi 0:8fdf9a60065b 1118 {
kadonotakashi 0:8fdf9a60065b 1119 }
kadonotakashi 0:8fdf9a60065b 1120 }
kadonotakashi 0:8fdf9a60065b 1121
kadonotakashi 0:8fdf9a60065b 1122 /* Send data register empty and the interrupt is enabled. */
kadonotakashi 0:8fdf9a60065b 1123 if ((base->STAT & LPUART_STAT_TDRE_MASK) && (base->CTRL & LPUART_CTRL_TIE_MASK))
kadonotakashi 0:8fdf9a60065b 1124 {
kadonotakashi 0:8fdf9a60065b 1125 /* Get the bytes that available at this moment. */
kadonotakashi 0:8fdf9a60065b 1126 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 1127 count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) -
kadonotakashi 0:8fdf9a60065b 1128 ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT);
kadonotakashi 0:8fdf9a60065b 1129 #else
kadonotakashi 0:8fdf9a60065b 1130 count = 1;
kadonotakashi 0:8fdf9a60065b 1131 #endif
kadonotakashi 0:8fdf9a60065b 1132
kadonotakashi 0:8fdf9a60065b 1133 while ((count) && (handle->txDataSize))
kadonotakashi 0:8fdf9a60065b 1134 {
kadonotakashi 0:8fdf9a60065b 1135 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 1136 tempCount = MIN(handle->txDataSize, count);
kadonotakashi 0:8fdf9a60065b 1137 #else
kadonotakashi 0:8fdf9a60065b 1138 tempCount = 1;
kadonotakashi 0:8fdf9a60065b 1139 #endif
kadonotakashi 0:8fdf9a60065b 1140
kadonotakashi 0:8fdf9a60065b 1141 /* Using non block API to write the data to the registers. */
kadonotakashi 0:8fdf9a60065b 1142 LPUART_WriteNonBlocking(base, handle->txData, tempCount);
kadonotakashi 0:8fdf9a60065b 1143 handle->txData += tempCount;
kadonotakashi 0:8fdf9a60065b 1144 handle->txDataSize -= tempCount;
kadonotakashi 0:8fdf9a60065b 1145 count -= tempCount;
kadonotakashi 0:8fdf9a60065b 1146
kadonotakashi 0:8fdf9a60065b 1147 /* If all the data are written to data register, notify user with the callback, then TX finished. */
kadonotakashi 0:8fdf9a60065b 1148 if (!handle->txDataSize)
kadonotakashi 0:8fdf9a60065b 1149 {
kadonotakashi 0:8fdf9a60065b 1150 handle->txState = kLPUART_TxIdle;
kadonotakashi 0:8fdf9a60065b 1151
kadonotakashi 0:8fdf9a60065b 1152 /* Disable TX register empty interrupt. */
kadonotakashi 0:8fdf9a60065b 1153 base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK);
kadonotakashi 0:8fdf9a60065b 1154
kadonotakashi 0:8fdf9a60065b 1155 /* Trigger callback. */
kadonotakashi 0:8fdf9a60065b 1156 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 1157 {
kadonotakashi 0:8fdf9a60065b 1158 handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData);
kadonotakashi 0:8fdf9a60065b 1159 }
kadonotakashi 0:8fdf9a60065b 1160 }
kadonotakashi 0:8fdf9a60065b 1161 }
kadonotakashi 0:8fdf9a60065b 1162 }
kadonotakashi 0:8fdf9a60065b 1163 }
kadonotakashi 0:8fdf9a60065b 1164
kadonotakashi 0:8fdf9a60065b 1165 void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 1166 {
kadonotakashi 0:8fdf9a60065b 1167 /* To be implemented by User. */
kadonotakashi 0:8fdf9a60065b 1168 }
kadonotakashi 0:8fdf9a60065b 1169
kadonotakashi 0:8fdf9a60065b 1170 #if defined(LPUART0)
kadonotakashi 0:8fdf9a60065b 1171 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 1172 void LPUART0_TX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1173 {
kadonotakashi 0:8fdf9a60065b 1174 s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
kadonotakashi 0:8fdf9a60065b 1175 }
kadonotakashi 0:8fdf9a60065b 1176 void LPUART0_RX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1177 {
kadonotakashi 0:8fdf9a60065b 1178 s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
kadonotakashi 0:8fdf9a60065b 1179 }
kadonotakashi 0:8fdf9a60065b 1180 #else
kadonotakashi 0:8fdf9a60065b 1181 void LPUART0_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1182 {
kadonotakashi 0:8fdf9a60065b 1183 s_lpuartIsr(LPUART0, s_lpuartHandle[0]);
kadonotakashi 0:8fdf9a60065b 1184 }
kadonotakashi 0:8fdf9a60065b 1185 #endif
kadonotakashi 0:8fdf9a60065b 1186 #endif
kadonotakashi 0:8fdf9a60065b 1187
kadonotakashi 0:8fdf9a60065b 1188 #if defined(LPUART1)
kadonotakashi 0:8fdf9a60065b 1189 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 1190 void LPUART1_TX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1191 {
kadonotakashi 0:8fdf9a60065b 1192 s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
kadonotakashi 0:8fdf9a60065b 1193 }
kadonotakashi 0:8fdf9a60065b 1194 void LPUART1_RX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1195 {
kadonotakashi 0:8fdf9a60065b 1196 s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
kadonotakashi 0:8fdf9a60065b 1197 }
kadonotakashi 0:8fdf9a60065b 1198 #else
kadonotakashi 0:8fdf9a60065b 1199 void LPUART1_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1200 {
kadonotakashi 0:8fdf9a60065b 1201 s_lpuartIsr(LPUART1, s_lpuartHandle[1]);
kadonotakashi 0:8fdf9a60065b 1202 }
kadonotakashi 0:8fdf9a60065b 1203 #endif
kadonotakashi 0:8fdf9a60065b 1204 #endif
kadonotakashi 0:8fdf9a60065b 1205
kadonotakashi 0:8fdf9a60065b 1206 #if defined(LPUART2)
kadonotakashi 0:8fdf9a60065b 1207 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 1208 void LPUART2_TX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1209 {
kadonotakashi 0:8fdf9a60065b 1210 s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
kadonotakashi 0:8fdf9a60065b 1211 }
kadonotakashi 0:8fdf9a60065b 1212 void LPUART2_RX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1213 {
kadonotakashi 0:8fdf9a60065b 1214 s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
kadonotakashi 0:8fdf9a60065b 1215 }
kadonotakashi 0:8fdf9a60065b 1216 #else
kadonotakashi 0:8fdf9a60065b 1217 void LPUART2_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1218 {
kadonotakashi 0:8fdf9a60065b 1219 s_lpuartIsr(LPUART2, s_lpuartHandle[2]);
kadonotakashi 0:8fdf9a60065b 1220 }
kadonotakashi 0:8fdf9a60065b 1221 #endif
kadonotakashi 0:8fdf9a60065b 1222 #endif
kadonotakashi 0:8fdf9a60065b 1223
kadonotakashi 0:8fdf9a60065b 1224 #if defined(LPUART3)
kadonotakashi 0:8fdf9a60065b 1225 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 1226 void LPUART3_TX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1227 {
kadonotakashi 0:8fdf9a60065b 1228 s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
kadonotakashi 0:8fdf9a60065b 1229 }
kadonotakashi 0:8fdf9a60065b 1230 void LPUART3_RX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1231 {
kadonotakashi 0:8fdf9a60065b 1232 s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
kadonotakashi 0:8fdf9a60065b 1233 }
kadonotakashi 0:8fdf9a60065b 1234 #else
kadonotakashi 0:8fdf9a60065b 1235 void LPUART3_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1236 {
kadonotakashi 0:8fdf9a60065b 1237 s_lpuartIsr(LPUART3, s_lpuartHandle[3]);
kadonotakashi 0:8fdf9a60065b 1238 }
kadonotakashi 0:8fdf9a60065b 1239 #endif
kadonotakashi 0:8fdf9a60065b 1240 #endif
kadonotakashi 0:8fdf9a60065b 1241
kadonotakashi 0:8fdf9a60065b 1242 #if defined(LPUART4)
kadonotakashi 0:8fdf9a60065b 1243 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 1244 void LPUART4_TX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1245 {
kadonotakashi 0:8fdf9a60065b 1246 s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
kadonotakashi 0:8fdf9a60065b 1247 }
kadonotakashi 0:8fdf9a60065b 1248 void LPUART4_RX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1249 {
kadonotakashi 0:8fdf9a60065b 1250 s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
kadonotakashi 0:8fdf9a60065b 1251 }
kadonotakashi 0:8fdf9a60065b 1252 #else
kadonotakashi 0:8fdf9a60065b 1253 void LPUART4_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1254 {
kadonotakashi 0:8fdf9a60065b 1255 s_lpuartIsr(LPUART4, s_lpuartHandle[4]);
kadonotakashi 0:8fdf9a60065b 1256 }
kadonotakashi 0:8fdf9a60065b 1257 #endif
kadonotakashi 0:8fdf9a60065b 1258 #endif
kadonotakashi 0:8fdf9a60065b 1259
kadonotakashi 0:8fdf9a60065b 1260 #if defined(LPUART5)
kadonotakashi 0:8fdf9a60065b 1261 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
kadonotakashi 0:8fdf9a60065b 1262 void LPUART5_TX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1263 {
kadonotakashi 0:8fdf9a60065b 1264 s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
kadonotakashi 0:8fdf9a60065b 1265 }
kadonotakashi 0:8fdf9a60065b 1266 void LPUART5_RX_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1267 {
kadonotakashi 0:8fdf9a60065b 1268 s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
kadonotakashi 0:8fdf9a60065b 1269 }
kadonotakashi 0:8fdf9a60065b 1270 #else
kadonotakashi 0:8fdf9a60065b 1271 void LPUART5_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 1272 {
kadonotakashi 0:8fdf9a60065b 1273 s_lpuartIsr(LPUART5, s_lpuartHandle[5]);
kadonotakashi 0:8fdf9a60065b 1274 }
kadonotakashi 0:8fdf9a60065b 1275 #endif
kadonotakashi 0:8fdf9a60065b 1276 #endif