added prescaler for 16 bit pwm in LPC1347 target
Fork of mbed-dev by
targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_uart.c@144:ef7eb2e8f9f7, 2016-09-02 (annotated)
- Committer:
- <>
- Date:
- Fri Sep 02 15:07:44 2016 +0100
- Revision:
- 144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 144:ef7eb2e8f9f7 | 1 | /* |
<> | 144:ef7eb2e8f9f7 | 2 | * Copyright (c) 2015, Freescale Semiconductor, Inc. |
<> | 144:ef7eb2e8f9f7 | 3 | * All rights reserved. |
<> | 144:ef7eb2e8f9f7 | 4 | * |
<> | 144:ef7eb2e8f9f7 | 5 | * Redistribution and use in source and binary forms, with or without modification, |
<> | 144:ef7eb2e8f9f7 | 6 | * are permitted provided that the following conditions are met: |
<> | 144:ef7eb2e8f9f7 | 7 | * |
<> | 144:ef7eb2e8f9f7 | 8 | * o Redistributions of source code must retain the above copyright notice, this list |
<> | 144:ef7eb2e8f9f7 | 9 | * of conditions and the following disclaimer. |
<> | 144:ef7eb2e8f9f7 | 10 | * |
<> | 144:ef7eb2e8f9f7 | 11 | * o Redistributions in binary form must reproduce the above copyright notice, this |
<> | 144:ef7eb2e8f9f7 | 12 | * list of conditions and the following disclaimer in the documentation and/or |
<> | 144:ef7eb2e8f9f7 | 13 | * other materials provided with the distribution. |
<> | 144:ef7eb2e8f9f7 | 14 | * |
<> | 144:ef7eb2e8f9f7 | 15 | * o Neither the name of Freescale Semiconductor, Inc. nor the names of its |
<> | 144:ef7eb2e8f9f7 | 16 | * contributors may be used to endorse or promote products derived from this |
<> | 144:ef7eb2e8f9f7 | 17 | * software without specific prior written permission. |
<> | 144:ef7eb2e8f9f7 | 18 | * |
<> | 144:ef7eb2e8f9f7 | 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
<> | 144:ef7eb2e8f9f7 | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
<> | 144:ef7eb2e8f9f7 | 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
<> | 144:ef7eb2e8f9f7 | 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
<> | 144:ef7eb2e8f9f7 | 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
<> | 144:ef7eb2e8f9f7 | 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
<> | 144:ef7eb2e8f9f7 | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
<> | 144:ef7eb2e8f9f7 | 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
<> | 144:ef7eb2e8f9f7 | 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
<> | 144:ef7eb2e8f9f7 | 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
<> | 144:ef7eb2e8f9f7 | 29 | */ |
<> | 144:ef7eb2e8f9f7 | 30 | |
<> | 144:ef7eb2e8f9f7 | 31 | #include "fsl_flexio_uart.h" |
<> | 144:ef7eb2e8f9f7 | 32 | |
<> | 144:ef7eb2e8f9f7 | 33 | /******************************************************************************* |
<> | 144:ef7eb2e8f9f7 | 34 | * Definitions |
<> | 144:ef7eb2e8f9f7 | 35 | ******************************************************************************/ |
<> | 144:ef7eb2e8f9f7 | 36 | |
<> | 144:ef7eb2e8f9f7 | 37 | /*<! @brief uart transfer state. */ |
<> | 144:ef7eb2e8f9f7 | 38 | enum _flexio_uart_transfer_states |
<> | 144:ef7eb2e8f9f7 | 39 | { |
<> | 144:ef7eb2e8f9f7 | 40 | kFLEXIO_UART_TxIdle, /* TX idle. */ |
<> | 144:ef7eb2e8f9f7 | 41 | kFLEXIO_UART_TxBusy, /* TX busy. */ |
<> | 144:ef7eb2e8f9f7 | 42 | kFLEXIO_UART_RxIdle, /* RX idle. */ |
<> | 144:ef7eb2e8f9f7 | 43 | kFLEXIO_UART_RxBusy /* RX busy. */ |
<> | 144:ef7eb2e8f9f7 | 44 | }; |
<> | 144:ef7eb2e8f9f7 | 45 | |
<> | 144:ef7eb2e8f9f7 | 46 | /******************************************************************************* |
<> | 144:ef7eb2e8f9f7 | 47 | * Prototypes |
<> | 144:ef7eb2e8f9f7 | 48 | ******************************************************************************/ |
<> | 144:ef7eb2e8f9f7 | 49 | |
<> | 144:ef7eb2e8f9f7 | 50 | /*! |
<> | 144:ef7eb2e8f9f7 | 51 | * @brief Get the length of received data in RX ring buffer. |
<> | 144:ef7eb2e8f9f7 | 52 | * |
<> | 144:ef7eb2e8f9f7 | 53 | * @param handle FLEXIO UART handle pointer. |
<> | 144:ef7eb2e8f9f7 | 54 | * @return Length of received data in RX ring buffer. |
<> | 144:ef7eb2e8f9f7 | 55 | */ |
<> | 144:ef7eb2e8f9f7 | 56 | static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle); |
<> | 144:ef7eb2e8f9f7 | 57 | |
<> | 144:ef7eb2e8f9f7 | 58 | /*! |
<> | 144:ef7eb2e8f9f7 | 59 | * @brief Check whether the RX ring buffer is full. |
<> | 144:ef7eb2e8f9f7 | 60 | * |
<> | 144:ef7eb2e8f9f7 | 61 | * @param handle FLEXIO UART handle pointer. |
<> | 144:ef7eb2e8f9f7 | 62 | * @retval true RX ring buffer is full. |
<> | 144:ef7eb2e8f9f7 | 63 | * @retval false RX ring buffer is not full. |
<> | 144:ef7eb2e8f9f7 | 64 | */ |
<> | 144:ef7eb2e8f9f7 | 65 | static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle); |
<> | 144:ef7eb2e8f9f7 | 66 | |
<> | 144:ef7eb2e8f9f7 | 67 | /******************************************************************************* |
<> | 144:ef7eb2e8f9f7 | 68 | * Codes |
<> | 144:ef7eb2e8f9f7 | 69 | ******************************************************************************/ |
<> | 144:ef7eb2e8f9f7 | 70 | |
<> | 144:ef7eb2e8f9f7 | 71 | static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle) |
<> | 144:ef7eb2e8f9f7 | 72 | { |
<> | 144:ef7eb2e8f9f7 | 73 | size_t size; |
<> | 144:ef7eb2e8f9f7 | 74 | |
<> | 144:ef7eb2e8f9f7 | 75 | if (handle->rxRingBufferTail > handle->rxRingBufferHead) |
<> | 144:ef7eb2e8f9f7 | 76 | { |
<> | 144:ef7eb2e8f9f7 | 77 | size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); |
<> | 144:ef7eb2e8f9f7 | 78 | } |
<> | 144:ef7eb2e8f9f7 | 79 | else |
<> | 144:ef7eb2e8f9f7 | 80 | { |
<> | 144:ef7eb2e8f9f7 | 81 | size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); |
<> | 144:ef7eb2e8f9f7 | 82 | } |
<> | 144:ef7eb2e8f9f7 | 83 | |
<> | 144:ef7eb2e8f9f7 | 84 | return size; |
<> | 144:ef7eb2e8f9f7 | 85 | } |
<> | 144:ef7eb2e8f9f7 | 86 | |
<> | 144:ef7eb2e8f9f7 | 87 | static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle) |
<> | 144:ef7eb2e8f9f7 | 88 | { |
<> | 144:ef7eb2e8f9f7 | 89 | bool full; |
<> | 144:ef7eb2e8f9f7 | 90 | |
<> | 144:ef7eb2e8f9f7 | 91 | if (FLEXIO_UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) |
<> | 144:ef7eb2e8f9f7 | 92 | { |
<> | 144:ef7eb2e8f9f7 | 93 | full = true; |
<> | 144:ef7eb2e8f9f7 | 94 | } |
<> | 144:ef7eb2e8f9f7 | 95 | else |
<> | 144:ef7eb2e8f9f7 | 96 | { |
<> | 144:ef7eb2e8f9f7 | 97 | full = false; |
<> | 144:ef7eb2e8f9f7 | 98 | } |
<> | 144:ef7eb2e8f9f7 | 99 | |
<> | 144:ef7eb2e8f9f7 | 100 | return full; |
<> | 144:ef7eb2e8f9f7 | 101 | } |
<> | 144:ef7eb2e8f9f7 | 102 | |
<> | 144:ef7eb2e8f9f7 | 103 | void FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz) |
<> | 144:ef7eb2e8f9f7 | 104 | { |
<> | 144:ef7eb2e8f9f7 | 105 | assert(base && userConfig); |
<> | 144:ef7eb2e8f9f7 | 106 | |
<> | 144:ef7eb2e8f9f7 | 107 | flexio_shifter_config_t shifterConfig; |
<> | 144:ef7eb2e8f9f7 | 108 | flexio_timer_config_t timerConfig; |
<> | 144:ef7eb2e8f9f7 | 109 | uint32_t ctrlReg = 0; |
<> | 144:ef7eb2e8f9f7 | 110 | uint16_t timerDiv = 0; |
<> | 144:ef7eb2e8f9f7 | 111 | uint16_t timerCmp = 0; |
<> | 144:ef7eb2e8f9f7 | 112 | |
<> | 144:ef7eb2e8f9f7 | 113 | /* Clear the shifterConfig & timerConfig struct. */ |
<> | 144:ef7eb2e8f9f7 | 114 | memset(&shifterConfig, 0, sizeof(shifterConfig)); |
<> | 144:ef7eb2e8f9f7 | 115 | memset(&timerConfig, 0, sizeof(timerConfig)); |
<> | 144:ef7eb2e8f9f7 | 116 | |
<> | 144:ef7eb2e8f9f7 | 117 | /* Ungate flexio clock. */ |
<> | 144:ef7eb2e8f9f7 | 118 | CLOCK_EnableClock(kCLOCK_Flexio0); |
<> | 144:ef7eb2e8f9f7 | 119 | |
<> | 144:ef7eb2e8f9f7 | 120 | /* Reset FLEXIO before configuration. */ |
<> | 144:ef7eb2e8f9f7 | 121 | FLEXIO_Reset(base->flexioBase); |
<> | 144:ef7eb2e8f9f7 | 122 | |
<> | 144:ef7eb2e8f9f7 | 123 | /* Configure FLEXIO UART */ |
<> | 144:ef7eb2e8f9f7 | 124 | ctrlReg = base->flexioBase->CTRL; |
<> | 144:ef7eb2e8f9f7 | 125 | ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); |
<> | 144:ef7eb2e8f9f7 | 126 | ctrlReg |= (FLEXIO_CTRL_DOZEN(userConfig->enableInDoze) | FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | |
<> | 144:ef7eb2e8f9f7 | 127 | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(userConfig->enableUart)); |
<> | 144:ef7eb2e8f9f7 | 128 | |
<> | 144:ef7eb2e8f9f7 | 129 | base->flexioBase->CTRL = ctrlReg; |
<> | 144:ef7eb2e8f9f7 | 130 | |
<> | 144:ef7eb2e8f9f7 | 131 | /* Do hardware configuration. */ |
<> | 144:ef7eb2e8f9f7 | 132 | /* 1. Configure the shifter 0 for tx. */ |
<> | 144:ef7eb2e8f9f7 | 133 | shifterConfig.timerSelect = base->timerIndex[0]; |
<> | 144:ef7eb2e8f9f7 | 134 | shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; |
<> | 144:ef7eb2e8f9f7 | 135 | shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; |
<> | 144:ef7eb2e8f9f7 | 136 | shifterConfig.pinSelect = base->TxPinIndex; |
<> | 144:ef7eb2e8f9f7 | 137 | shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; |
<> | 144:ef7eb2e8f9f7 | 138 | shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; |
<> | 144:ef7eb2e8f9f7 | 139 | shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; |
<> | 144:ef7eb2e8f9f7 | 140 | shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; |
<> | 144:ef7eb2e8f9f7 | 141 | shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; |
<> | 144:ef7eb2e8f9f7 | 142 | |
<> | 144:ef7eb2e8f9f7 | 143 | FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); |
<> | 144:ef7eb2e8f9f7 | 144 | |
<> | 144:ef7eb2e8f9f7 | 145 | /*2. Configure the timer 0 for tx. */ |
<> | 144:ef7eb2e8f9f7 | 146 | timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); |
<> | 144:ef7eb2e8f9f7 | 147 | timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; |
<> | 144:ef7eb2e8f9f7 | 148 | timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; |
<> | 144:ef7eb2e8f9f7 | 149 | timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; |
<> | 144:ef7eb2e8f9f7 | 150 | timerConfig.pinSelect = base->TxPinIndex; |
<> | 144:ef7eb2e8f9f7 | 151 | timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; |
<> | 144:ef7eb2e8f9f7 | 152 | timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; |
<> | 144:ef7eb2e8f9f7 | 153 | timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; |
<> | 144:ef7eb2e8f9f7 | 154 | timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; |
<> | 144:ef7eb2e8f9f7 | 155 | timerConfig.timerReset = kFLEXIO_TimerResetNever; |
<> | 144:ef7eb2e8f9f7 | 156 | timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; |
<> | 144:ef7eb2e8f9f7 | 157 | timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; |
<> | 144:ef7eb2e8f9f7 | 158 | timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; |
<> | 144:ef7eb2e8f9f7 | 159 | timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; |
<> | 144:ef7eb2e8f9f7 | 160 | |
<> | 144:ef7eb2e8f9f7 | 161 | timerDiv = srcClock_Hz / userConfig->baudRate_Bps; |
<> | 144:ef7eb2e8f9f7 | 162 | timerDiv = timerDiv / 2 - 1; |
<> | 144:ef7eb2e8f9f7 | 163 | |
<> | 144:ef7eb2e8f9f7 | 164 | timerCmp = ((uint32_t)(userConfig->bitCountPerChar * 2 - 1)) << 8U; |
<> | 144:ef7eb2e8f9f7 | 165 | timerCmp |= timerDiv; |
<> | 144:ef7eb2e8f9f7 | 166 | |
<> | 144:ef7eb2e8f9f7 | 167 | timerConfig.timerCompare = timerCmp; |
<> | 144:ef7eb2e8f9f7 | 168 | |
<> | 144:ef7eb2e8f9f7 | 169 | FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); |
<> | 144:ef7eb2e8f9f7 | 170 | |
<> | 144:ef7eb2e8f9f7 | 171 | /* 3. Configure the shifter 1 for rx. */ |
<> | 144:ef7eb2e8f9f7 | 172 | shifterConfig.timerSelect = base->timerIndex[1]; |
<> | 144:ef7eb2e8f9f7 | 173 | shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; |
<> | 144:ef7eb2e8f9f7 | 174 | shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; |
<> | 144:ef7eb2e8f9f7 | 175 | shifterConfig.pinSelect = base->RxPinIndex; |
<> | 144:ef7eb2e8f9f7 | 176 | shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; |
<> | 144:ef7eb2e8f9f7 | 177 | shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; |
<> | 144:ef7eb2e8f9f7 | 178 | shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; |
<> | 144:ef7eb2e8f9f7 | 179 | shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; |
<> | 144:ef7eb2e8f9f7 | 180 | shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; |
<> | 144:ef7eb2e8f9f7 | 181 | |
<> | 144:ef7eb2e8f9f7 | 182 | FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); |
<> | 144:ef7eb2e8f9f7 | 183 | |
<> | 144:ef7eb2e8f9f7 | 184 | /* 4. Configure the timer 1 for rx. */ |
<> | 144:ef7eb2e8f9f7 | 185 | timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->RxPinIndex); |
<> | 144:ef7eb2e8f9f7 | 186 | timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; |
<> | 144:ef7eb2e8f9f7 | 187 | timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; |
<> | 144:ef7eb2e8f9f7 | 188 | timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; |
<> | 144:ef7eb2e8f9f7 | 189 | timerConfig.pinSelect = base->RxPinIndex; |
<> | 144:ef7eb2e8f9f7 | 190 | timerConfig.pinPolarity = kFLEXIO_PinActiveLow; |
<> | 144:ef7eb2e8f9f7 | 191 | timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; |
<> | 144:ef7eb2e8f9f7 | 192 | timerConfig.timerOutput = kFLEXIO_TimerOutputOneAffectedByReset; |
<> | 144:ef7eb2e8f9f7 | 193 | timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; |
<> | 144:ef7eb2e8f9f7 | 194 | timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge; |
<> | 144:ef7eb2e8f9f7 | 195 | timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; |
<> | 144:ef7eb2e8f9f7 | 196 | timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; |
<> | 144:ef7eb2e8f9f7 | 197 | timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; |
<> | 144:ef7eb2e8f9f7 | 198 | timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; |
<> | 144:ef7eb2e8f9f7 | 199 | |
<> | 144:ef7eb2e8f9f7 | 200 | timerConfig.timerCompare = timerCmp; |
<> | 144:ef7eb2e8f9f7 | 201 | |
<> | 144:ef7eb2e8f9f7 | 202 | FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); |
<> | 144:ef7eb2e8f9f7 | 203 | } |
<> | 144:ef7eb2e8f9f7 | 204 | |
<> | 144:ef7eb2e8f9f7 | 205 | void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base) |
<> | 144:ef7eb2e8f9f7 | 206 | { |
<> | 144:ef7eb2e8f9f7 | 207 | /* Disable FLEXIO UART module. */ |
<> | 144:ef7eb2e8f9f7 | 208 | FLEXIO_UART_Enable(base, false); |
<> | 144:ef7eb2e8f9f7 | 209 | |
<> | 144:ef7eb2e8f9f7 | 210 | /* Gate flexio clock. */ |
<> | 144:ef7eb2e8f9f7 | 211 | CLOCK_DisableClock(kCLOCK_Flexio0); |
<> | 144:ef7eb2e8f9f7 | 212 | } |
<> | 144:ef7eb2e8f9f7 | 213 | |
<> | 144:ef7eb2e8f9f7 | 214 | void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig) |
<> | 144:ef7eb2e8f9f7 | 215 | { |
<> | 144:ef7eb2e8f9f7 | 216 | assert(userConfig); |
<> | 144:ef7eb2e8f9f7 | 217 | |
<> | 144:ef7eb2e8f9f7 | 218 | userConfig->enableUart = true; |
<> | 144:ef7eb2e8f9f7 | 219 | userConfig->enableInDoze = false; |
<> | 144:ef7eb2e8f9f7 | 220 | userConfig->enableInDebug = true; |
<> | 144:ef7eb2e8f9f7 | 221 | userConfig->enableFastAccess = false; |
<> | 144:ef7eb2e8f9f7 | 222 | /* Default baud rate 115200. */ |
<> | 144:ef7eb2e8f9f7 | 223 | userConfig->baudRate_Bps = 115200U; |
<> | 144:ef7eb2e8f9f7 | 224 | /* Default bit count at 8. */ |
<> | 144:ef7eb2e8f9f7 | 225 | userConfig->bitCountPerChar = kFLEXIO_UART_8BitsPerChar; |
<> | 144:ef7eb2e8f9f7 | 226 | } |
<> | 144:ef7eb2e8f9f7 | 227 | |
<> | 144:ef7eb2e8f9f7 | 228 | void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) |
<> | 144:ef7eb2e8f9f7 | 229 | { |
<> | 144:ef7eb2e8f9f7 | 230 | if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable) |
<> | 144:ef7eb2e8f9f7 | 231 | { |
<> | 144:ef7eb2e8f9f7 | 232 | FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); |
<> | 144:ef7eb2e8f9f7 | 233 | } |
<> | 144:ef7eb2e8f9f7 | 234 | if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable) |
<> | 144:ef7eb2e8f9f7 | 235 | { |
<> | 144:ef7eb2e8f9f7 | 236 | FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); |
<> | 144:ef7eb2e8f9f7 | 237 | } |
<> | 144:ef7eb2e8f9f7 | 238 | } |
<> | 144:ef7eb2e8f9f7 | 239 | |
<> | 144:ef7eb2e8f9f7 | 240 | void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) |
<> | 144:ef7eb2e8f9f7 | 241 | { |
<> | 144:ef7eb2e8f9f7 | 242 | if (mask & kFLEXIO_UART_TxDataRegEmptyInterruptEnable) |
<> | 144:ef7eb2e8f9f7 | 243 | { |
<> | 144:ef7eb2e8f9f7 | 244 | FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]); |
<> | 144:ef7eb2e8f9f7 | 245 | } |
<> | 144:ef7eb2e8f9f7 | 246 | if (mask & kFLEXIO_UART_RxDataRegFullInterruptEnable) |
<> | 144:ef7eb2e8f9f7 | 247 | { |
<> | 144:ef7eb2e8f9f7 | 248 | FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]); |
<> | 144:ef7eb2e8f9f7 | 249 | } |
<> | 144:ef7eb2e8f9f7 | 250 | } |
<> | 144:ef7eb2e8f9f7 | 251 | |
<> | 144:ef7eb2e8f9f7 | 252 | uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base) |
<> | 144:ef7eb2e8f9f7 | 253 | { |
<> | 144:ef7eb2e8f9f7 | 254 | uint32_t status = 0; |
<> | 144:ef7eb2e8f9f7 | 255 | status = |
<> | 144:ef7eb2e8f9f7 | 256 | ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]); |
<> | 144:ef7eb2e8f9f7 | 257 | status |= |
<> | 144:ef7eb2e8f9f7 | 258 | (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) |
<> | 144:ef7eb2e8f9f7 | 259 | << 1U); |
<> | 144:ef7eb2e8f9f7 | 260 | status |= |
<> | 144:ef7eb2e8f9f7 | 261 | (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1])) |
<> | 144:ef7eb2e8f9f7 | 262 | << 2U); |
<> | 144:ef7eb2e8f9f7 | 263 | return status; |
<> | 144:ef7eb2e8f9f7 | 264 | } |
<> | 144:ef7eb2e8f9f7 | 265 | |
<> | 144:ef7eb2e8f9f7 | 266 | void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask) |
<> | 144:ef7eb2e8f9f7 | 267 | { |
<> | 144:ef7eb2e8f9f7 | 268 | if (mask & kFLEXIO_UART_TxDataRegEmptyFlag) |
<> | 144:ef7eb2e8f9f7 | 269 | { |
<> | 144:ef7eb2e8f9f7 | 270 | FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]); |
<> | 144:ef7eb2e8f9f7 | 271 | } |
<> | 144:ef7eb2e8f9f7 | 272 | if (mask & kFLEXIO_UART_RxDataRegFullFlag) |
<> | 144:ef7eb2e8f9f7 | 273 | { |
<> | 144:ef7eb2e8f9f7 | 274 | FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]); |
<> | 144:ef7eb2e8f9f7 | 275 | } |
<> | 144:ef7eb2e8f9f7 | 276 | if (mask & kFLEXIO_UART_RxOverRunFlag) |
<> | 144:ef7eb2e8f9f7 | 277 | { |
<> | 144:ef7eb2e8f9f7 | 278 | FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]); |
<> | 144:ef7eb2e8f9f7 | 279 | } |
<> | 144:ef7eb2e8f9f7 | 280 | } |
<> | 144:ef7eb2e8f9f7 | 281 | |
<> | 144:ef7eb2e8f9f7 | 282 | void FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize) |
<> | 144:ef7eb2e8f9f7 | 283 | { |
<> | 144:ef7eb2e8f9f7 | 284 | assert(txData); |
<> | 144:ef7eb2e8f9f7 | 285 | assert(txSize); |
<> | 144:ef7eb2e8f9f7 | 286 | |
<> | 144:ef7eb2e8f9f7 | 287 | while (txSize--) |
<> | 144:ef7eb2e8f9f7 | 288 | { |
<> | 144:ef7eb2e8f9f7 | 289 | /* Wait until data transfer complete. */ |
<> | 144:ef7eb2e8f9f7 | 290 | while (!(FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))) |
<> | 144:ef7eb2e8f9f7 | 291 | { |
<> | 144:ef7eb2e8f9f7 | 292 | } |
<> | 144:ef7eb2e8f9f7 | 293 | |
<> | 144:ef7eb2e8f9f7 | 294 | base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *txData++; |
<> | 144:ef7eb2e8f9f7 | 295 | } |
<> | 144:ef7eb2e8f9f7 | 296 | } |
<> | 144:ef7eb2e8f9f7 | 297 | |
<> | 144:ef7eb2e8f9f7 | 298 | void FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize) |
<> | 144:ef7eb2e8f9f7 | 299 | { |
<> | 144:ef7eb2e8f9f7 | 300 | assert(rxData); |
<> | 144:ef7eb2e8f9f7 | 301 | assert(rxSize); |
<> | 144:ef7eb2e8f9f7 | 302 | |
<> | 144:ef7eb2e8f9f7 | 303 | while (rxSize--) |
<> | 144:ef7eb2e8f9f7 | 304 | { |
<> | 144:ef7eb2e8f9f7 | 305 | /* Wait until data transfer complete. */ |
<> | 144:ef7eb2e8f9f7 | 306 | while (!(FLEXIO_UART_GetStatusFlags(base) & kFLEXIO_UART_RxDataRegFullFlag)) |
<> | 144:ef7eb2e8f9f7 | 307 | { |
<> | 144:ef7eb2e8f9f7 | 308 | } |
<> | 144:ef7eb2e8f9f7 | 309 | |
<> | 144:ef7eb2e8f9f7 | 310 | *rxData++ = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; |
<> | 144:ef7eb2e8f9f7 | 311 | } |
<> | 144:ef7eb2e8f9f7 | 312 | } |
<> | 144:ef7eb2e8f9f7 | 313 | |
<> | 144:ef7eb2e8f9f7 | 314 | status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base, |
<> | 144:ef7eb2e8f9f7 | 315 | flexio_uart_handle_t *handle, |
<> | 144:ef7eb2e8f9f7 | 316 | flexio_uart_transfer_callback_t callback, |
<> | 144:ef7eb2e8f9f7 | 317 | void *userData) |
<> | 144:ef7eb2e8f9f7 | 318 | { |
<> | 144:ef7eb2e8f9f7 | 319 | assert(handle); |
<> | 144:ef7eb2e8f9f7 | 320 | |
<> | 144:ef7eb2e8f9f7 | 321 | IRQn_Type flexio_irqs[] = FLEXIO_IRQS; |
<> | 144:ef7eb2e8f9f7 | 322 | |
<> | 144:ef7eb2e8f9f7 | 323 | /* Zero the handle. */ |
<> | 144:ef7eb2e8f9f7 | 324 | memset(handle, 0, sizeof(*handle)); |
<> | 144:ef7eb2e8f9f7 | 325 | |
<> | 144:ef7eb2e8f9f7 | 326 | /* Set the TX/RX state. */ |
<> | 144:ef7eb2e8f9f7 | 327 | handle->rxState = kFLEXIO_UART_RxIdle; |
<> | 144:ef7eb2e8f9f7 | 328 | handle->txState = kFLEXIO_UART_TxIdle; |
<> | 144:ef7eb2e8f9f7 | 329 | |
<> | 144:ef7eb2e8f9f7 | 330 | /* Set the callback and user data. */ |
<> | 144:ef7eb2e8f9f7 | 331 | handle->callback = callback; |
<> | 144:ef7eb2e8f9f7 | 332 | handle->userData = userData; |
<> | 144:ef7eb2e8f9f7 | 333 | |
<> | 144:ef7eb2e8f9f7 | 334 | /* Enable interrupt in NVIC. */ |
<> | 144:ef7eb2e8f9f7 | 335 | EnableIRQ(flexio_irqs[0]); |
<> | 144:ef7eb2e8f9f7 | 336 | |
<> | 144:ef7eb2e8f9f7 | 337 | /* Save the context in global variables to support the double weak mechanism. */ |
<> | 144:ef7eb2e8f9f7 | 338 | return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_UART_TransferHandleIRQ); |
<> | 144:ef7eb2e8f9f7 | 339 | } |
<> | 144:ef7eb2e8f9f7 | 340 | |
<> | 144:ef7eb2e8f9f7 | 341 | void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base, |
<> | 144:ef7eb2e8f9f7 | 342 | flexio_uart_handle_t *handle, |
<> | 144:ef7eb2e8f9f7 | 343 | uint8_t *ringBuffer, |
<> | 144:ef7eb2e8f9f7 | 344 | size_t ringBufferSize) |
<> | 144:ef7eb2e8f9f7 | 345 | { |
<> | 144:ef7eb2e8f9f7 | 346 | assert(handle); |
<> | 144:ef7eb2e8f9f7 | 347 | |
<> | 144:ef7eb2e8f9f7 | 348 | /* Setup the ringbuffer address */ |
<> | 144:ef7eb2e8f9f7 | 349 | if (ringBuffer) |
<> | 144:ef7eb2e8f9f7 | 350 | { |
<> | 144:ef7eb2e8f9f7 | 351 | handle->rxRingBuffer = ringBuffer; |
<> | 144:ef7eb2e8f9f7 | 352 | handle->rxRingBufferSize = ringBufferSize; |
<> | 144:ef7eb2e8f9f7 | 353 | handle->rxRingBufferHead = 0U; |
<> | 144:ef7eb2e8f9f7 | 354 | handle->rxRingBufferTail = 0U; |
<> | 144:ef7eb2e8f9f7 | 355 | |
<> | 144:ef7eb2e8f9f7 | 356 | /* Enable the interrupt to accept the data when user need the ring buffer. */ |
<> | 144:ef7eb2e8f9f7 | 357 | FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 358 | } |
<> | 144:ef7eb2e8f9f7 | 359 | } |
<> | 144:ef7eb2e8f9f7 | 360 | |
<> | 144:ef7eb2e8f9f7 | 361 | void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) |
<> | 144:ef7eb2e8f9f7 | 362 | { |
<> | 144:ef7eb2e8f9f7 | 363 | assert(handle); |
<> | 144:ef7eb2e8f9f7 | 364 | |
<> | 144:ef7eb2e8f9f7 | 365 | if (handle->rxState == kFLEXIO_UART_RxIdle) |
<> | 144:ef7eb2e8f9f7 | 366 | { |
<> | 144:ef7eb2e8f9f7 | 367 | FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 368 | } |
<> | 144:ef7eb2e8f9f7 | 369 | |
<> | 144:ef7eb2e8f9f7 | 370 | handle->rxRingBuffer = NULL; |
<> | 144:ef7eb2e8f9f7 | 371 | handle->rxRingBufferSize = 0U; |
<> | 144:ef7eb2e8f9f7 | 372 | handle->rxRingBufferHead = 0U; |
<> | 144:ef7eb2e8f9f7 | 373 | handle->rxRingBufferTail = 0U; |
<> | 144:ef7eb2e8f9f7 | 374 | } |
<> | 144:ef7eb2e8f9f7 | 375 | |
<> | 144:ef7eb2e8f9f7 | 376 | status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base, |
<> | 144:ef7eb2e8f9f7 | 377 | flexio_uart_handle_t *handle, |
<> | 144:ef7eb2e8f9f7 | 378 | flexio_uart_transfer_t *xfer) |
<> | 144:ef7eb2e8f9f7 | 379 | { |
<> | 144:ef7eb2e8f9f7 | 380 | status_t status; |
<> | 144:ef7eb2e8f9f7 | 381 | |
<> | 144:ef7eb2e8f9f7 | 382 | /* Return error if xfer invalid. */ |
<> | 144:ef7eb2e8f9f7 | 383 | if ((0U == xfer->dataSize) || (NULL == xfer->data)) |
<> | 144:ef7eb2e8f9f7 | 384 | { |
<> | 144:ef7eb2e8f9f7 | 385 | return kStatus_InvalidArgument; |
<> | 144:ef7eb2e8f9f7 | 386 | } |
<> | 144:ef7eb2e8f9f7 | 387 | |
<> | 144:ef7eb2e8f9f7 | 388 | /* Return error if current TX busy. */ |
<> | 144:ef7eb2e8f9f7 | 389 | if (kFLEXIO_UART_TxBusy == handle->txState) |
<> | 144:ef7eb2e8f9f7 | 390 | { |
<> | 144:ef7eb2e8f9f7 | 391 | status = kStatus_FLEXIO_UART_TxBusy; |
<> | 144:ef7eb2e8f9f7 | 392 | } |
<> | 144:ef7eb2e8f9f7 | 393 | else |
<> | 144:ef7eb2e8f9f7 | 394 | { |
<> | 144:ef7eb2e8f9f7 | 395 | handle->txData = xfer->data; |
<> | 144:ef7eb2e8f9f7 | 396 | handle->txDataSize = xfer->dataSize; |
<> | 144:ef7eb2e8f9f7 | 397 | handle->txState = kFLEXIO_UART_TxBusy; |
<> | 144:ef7eb2e8f9f7 | 398 | |
<> | 144:ef7eb2e8f9f7 | 399 | /* Enable transmiter interrupt. */ |
<> | 144:ef7eb2e8f9f7 | 400 | FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 401 | |
<> | 144:ef7eb2e8f9f7 | 402 | status = kStatus_Success; |
<> | 144:ef7eb2e8f9f7 | 403 | } |
<> | 144:ef7eb2e8f9f7 | 404 | |
<> | 144:ef7eb2e8f9f7 | 405 | return status; |
<> | 144:ef7eb2e8f9f7 | 406 | } |
<> | 144:ef7eb2e8f9f7 | 407 | |
<> | 144:ef7eb2e8f9f7 | 408 | void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) |
<> | 144:ef7eb2e8f9f7 | 409 | { |
<> | 144:ef7eb2e8f9f7 | 410 | /* Disable the transmitter and disable the interrupt. */ |
<> | 144:ef7eb2e8f9f7 | 411 | FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 412 | |
<> | 144:ef7eb2e8f9f7 | 413 | handle->txDataSize = 0; |
<> | 144:ef7eb2e8f9f7 | 414 | handle->txState = kFLEXIO_UART_TxIdle; |
<> | 144:ef7eb2e8f9f7 | 415 | } |
<> | 144:ef7eb2e8f9f7 | 416 | |
<> | 144:ef7eb2e8f9f7 | 417 | status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) |
<> | 144:ef7eb2e8f9f7 | 418 | { |
<> | 144:ef7eb2e8f9f7 | 419 | assert(handle); |
<> | 144:ef7eb2e8f9f7 | 420 | |
<> | 144:ef7eb2e8f9f7 | 421 | if (!count) |
<> | 144:ef7eb2e8f9f7 | 422 | { |
<> | 144:ef7eb2e8f9f7 | 423 | return kStatus_Success; |
<> | 144:ef7eb2e8f9f7 | 424 | } |
<> | 144:ef7eb2e8f9f7 | 425 | |
<> | 144:ef7eb2e8f9f7 | 426 | *count = handle->txSize - handle->txDataSize; |
<> | 144:ef7eb2e8f9f7 | 427 | |
<> | 144:ef7eb2e8f9f7 | 428 | return kStatus_Success; |
<> | 144:ef7eb2e8f9f7 | 429 | } |
<> | 144:ef7eb2e8f9f7 | 430 | |
<> | 144:ef7eb2e8f9f7 | 431 | status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base, |
<> | 144:ef7eb2e8f9f7 | 432 | flexio_uart_handle_t *handle, |
<> | 144:ef7eb2e8f9f7 | 433 | flexio_uart_transfer_t *xfer, |
<> | 144:ef7eb2e8f9f7 | 434 | size_t *receivedBytes) |
<> | 144:ef7eb2e8f9f7 | 435 | { |
<> | 144:ef7eb2e8f9f7 | 436 | uint32_t i; |
<> | 144:ef7eb2e8f9f7 | 437 | status_t status; |
<> | 144:ef7eb2e8f9f7 | 438 | /* How many bytes to copy from ring buffer to user memory. */ |
<> | 144:ef7eb2e8f9f7 | 439 | size_t bytesToCopy = 0U; |
<> | 144:ef7eb2e8f9f7 | 440 | /* How many bytes to receive. */ |
<> | 144:ef7eb2e8f9f7 | 441 | size_t bytesToReceive; |
<> | 144:ef7eb2e8f9f7 | 442 | /* How many bytes currently have received. */ |
<> | 144:ef7eb2e8f9f7 | 443 | size_t bytesCurrentReceived; |
<> | 144:ef7eb2e8f9f7 | 444 | uint32_t regPrimask = 0U; |
<> | 144:ef7eb2e8f9f7 | 445 | |
<> | 144:ef7eb2e8f9f7 | 446 | /* Return error if xfer invalid. */ |
<> | 144:ef7eb2e8f9f7 | 447 | if ((0U == xfer->dataSize) || (NULL == xfer->data)) |
<> | 144:ef7eb2e8f9f7 | 448 | { |
<> | 144:ef7eb2e8f9f7 | 449 | return kStatus_InvalidArgument; |
<> | 144:ef7eb2e8f9f7 | 450 | } |
<> | 144:ef7eb2e8f9f7 | 451 | |
<> | 144:ef7eb2e8f9f7 | 452 | /* How to get data: |
<> | 144:ef7eb2e8f9f7 | 453 | 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize |
<> | 144:ef7eb2e8f9f7 | 454 | to uart handle, enable interrupt to store received data to xfer->data. When |
<> | 144:ef7eb2e8f9f7 | 455 | all data received, trigger callback. |
<> | 144:ef7eb2e8f9f7 | 456 | 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. |
<> | 144:ef7eb2e8f9f7 | 457 | If there are enough data in ring buffer, copy them to xfer->data and return. |
<> | 144:ef7eb2e8f9f7 | 458 | If there are not enough data in ring buffer, copy all of them to xfer->data, |
<> | 144:ef7eb2e8f9f7 | 459 | save the xfer->data remained empty space to uart handle, receive data |
<> | 144:ef7eb2e8f9f7 | 460 | to this empty space and trigger callback when finished. */ |
<> | 144:ef7eb2e8f9f7 | 461 | |
<> | 144:ef7eb2e8f9f7 | 462 | if (kFLEXIO_UART_RxBusy == handle->rxState) |
<> | 144:ef7eb2e8f9f7 | 463 | { |
<> | 144:ef7eb2e8f9f7 | 464 | status = kStatus_FLEXIO_UART_RxBusy; |
<> | 144:ef7eb2e8f9f7 | 465 | } |
<> | 144:ef7eb2e8f9f7 | 466 | else |
<> | 144:ef7eb2e8f9f7 | 467 | { |
<> | 144:ef7eb2e8f9f7 | 468 | bytesToReceive = xfer->dataSize; |
<> | 144:ef7eb2e8f9f7 | 469 | bytesCurrentReceived = 0U; |
<> | 144:ef7eb2e8f9f7 | 470 | |
<> | 144:ef7eb2e8f9f7 | 471 | /* If RX ring buffer is used. */ |
<> | 144:ef7eb2e8f9f7 | 472 | if (handle->rxRingBuffer) |
<> | 144:ef7eb2e8f9f7 | 473 | { |
<> | 144:ef7eb2e8f9f7 | 474 | /* Disable IRQ, protect ring buffer. */ |
<> | 144:ef7eb2e8f9f7 | 475 | regPrimask = __get_PRIMASK(); |
<> | 144:ef7eb2e8f9f7 | 476 | __disable_irq(); |
<> | 144:ef7eb2e8f9f7 | 477 | |
<> | 144:ef7eb2e8f9f7 | 478 | /* How many bytes in RX ring buffer currently. */ |
<> | 144:ef7eb2e8f9f7 | 479 | bytesToCopy = FLEXIO_UART_TransferGetRxRingBufferLength(handle); |
<> | 144:ef7eb2e8f9f7 | 480 | |
<> | 144:ef7eb2e8f9f7 | 481 | if (bytesToCopy) |
<> | 144:ef7eb2e8f9f7 | 482 | { |
<> | 144:ef7eb2e8f9f7 | 483 | bytesToCopy = MIN(bytesToReceive, bytesToCopy); |
<> | 144:ef7eb2e8f9f7 | 484 | |
<> | 144:ef7eb2e8f9f7 | 485 | bytesToReceive -= bytesToCopy; |
<> | 144:ef7eb2e8f9f7 | 486 | |
<> | 144:ef7eb2e8f9f7 | 487 | /* Copy data from ring buffer to user memory. */ |
<> | 144:ef7eb2e8f9f7 | 488 | for (i = 0U; i < bytesToCopy; i++) |
<> | 144:ef7eb2e8f9f7 | 489 | { |
<> | 144:ef7eb2e8f9f7 | 490 | xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; |
<> | 144:ef7eb2e8f9f7 | 491 | |
<> | 144:ef7eb2e8f9f7 | 492 | /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ |
<> | 144:ef7eb2e8f9f7 | 493 | if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) |
<> | 144:ef7eb2e8f9f7 | 494 | { |
<> | 144:ef7eb2e8f9f7 | 495 | handle->rxRingBufferTail = 0U; |
<> | 144:ef7eb2e8f9f7 | 496 | } |
<> | 144:ef7eb2e8f9f7 | 497 | else |
<> | 144:ef7eb2e8f9f7 | 498 | { |
<> | 144:ef7eb2e8f9f7 | 499 | handle->rxRingBufferTail++; |
<> | 144:ef7eb2e8f9f7 | 500 | } |
<> | 144:ef7eb2e8f9f7 | 501 | } |
<> | 144:ef7eb2e8f9f7 | 502 | } |
<> | 144:ef7eb2e8f9f7 | 503 | |
<> | 144:ef7eb2e8f9f7 | 504 | /* If ring buffer does not have enough data, still need to read more data. */ |
<> | 144:ef7eb2e8f9f7 | 505 | if (bytesToReceive) |
<> | 144:ef7eb2e8f9f7 | 506 | { |
<> | 144:ef7eb2e8f9f7 | 507 | /* No data in ring buffer, save the request to UART handle. */ |
<> | 144:ef7eb2e8f9f7 | 508 | handle->rxData = xfer->data + bytesCurrentReceived; |
<> | 144:ef7eb2e8f9f7 | 509 | handle->rxDataSize = bytesToReceive; |
<> | 144:ef7eb2e8f9f7 | 510 | handle->rxState = kFLEXIO_UART_RxBusy; |
<> | 144:ef7eb2e8f9f7 | 511 | } |
<> | 144:ef7eb2e8f9f7 | 512 | |
<> | 144:ef7eb2e8f9f7 | 513 | /* Recover PRIMASK, enable IRQ if previously enabled. */ |
<> | 144:ef7eb2e8f9f7 | 514 | __set_PRIMASK(regPrimask); |
<> | 144:ef7eb2e8f9f7 | 515 | } |
<> | 144:ef7eb2e8f9f7 | 516 | /* Ring buffer not used. */ |
<> | 144:ef7eb2e8f9f7 | 517 | else |
<> | 144:ef7eb2e8f9f7 | 518 | { |
<> | 144:ef7eb2e8f9f7 | 519 | handle->rxData = xfer->data + bytesCurrentReceived; |
<> | 144:ef7eb2e8f9f7 | 520 | handle->rxDataSize = bytesToReceive; |
<> | 144:ef7eb2e8f9f7 | 521 | handle->rxState = kFLEXIO_UART_RxBusy; |
<> | 144:ef7eb2e8f9f7 | 522 | |
<> | 144:ef7eb2e8f9f7 | 523 | /* Enable RX interrupt. */ |
<> | 144:ef7eb2e8f9f7 | 524 | FLEXIO_UART_EnableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 525 | } |
<> | 144:ef7eb2e8f9f7 | 526 | |
<> | 144:ef7eb2e8f9f7 | 527 | /* Return the how many bytes have read. */ |
<> | 144:ef7eb2e8f9f7 | 528 | if (receivedBytes) |
<> | 144:ef7eb2e8f9f7 | 529 | { |
<> | 144:ef7eb2e8f9f7 | 530 | *receivedBytes = bytesCurrentReceived; |
<> | 144:ef7eb2e8f9f7 | 531 | } |
<> | 144:ef7eb2e8f9f7 | 532 | |
<> | 144:ef7eb2e8f9f7 | 533 | status = kStatus_Success; |
<> | 144:ef7eb2e8f9f7 | 534 | } |
<> | 144:ef7eb2e8f9f7 | 535 | |
<> | 144:ef7eb2e8f9f7 | 536 | return status; |
<> | 144:ef7eb2e8f9f7 | 537 | } |
<> | 144:ef7eb2e8f9f7 | 538 | |
<> | 144:ef7eb2e8f9f7 | 539 | void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) |
<> | 144:ef7eb2e8f9f7 | 540 | { |
<> | 144:ef7eb2e8f9f7 | 541 | /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ |
<> | 144:ef7eb2e8f9f7 | 542 | if (!handle->rxRingBuffer) |
<> | 144:ef7eb2e8f9f7 | 543 | { |
<> | 144:ef7eb2e8f9f7 | 544 | /* Disable RX interrupt. */ |
<> | 144:ef7eb2e8f9f7 | 545 | FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 546 | } |
<> | 144:ef7eb2e8f9f7 | 547 | |
<> | 144:ef7eb2e8f9f7 | 548 | handle->rxDataSize = 0U; |
<> | 144:ef7eb2e8f9f7 | 549 | handle->rxState = kFLEXIO_UART_RxIdle; |
<> | 144:ef7eb2e8f9f7 | 550 | } |
<> | 144:ef7eb2e8f9f7 | 551 | |
<> | 144:ef7eb2e8f9f7 | 552 | status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) |
<> | 144:ef7eb2e8f9f7 | 553 | { |
<> | 144:ef7eb2e8f9f7 | 554 | assert(handle); |
<> | 144:ef7eb2e8f9f7 | 555 | |
<> | 144:ef7eb2e8f9f7 | 556 | if (!count) |
<> | 144:ef7eb2e8f9f7 | 557 | { |
<> | 144:ef7eb2e8f9f7 | 558 | return kStatus_Success; |
<> | 144:ef7eb2e8f9f7 | 559 | } |
<> | 144:ef7eb2e8f9f7 | 560 | |
<> | 144:ef7eb2e8f9f7 | 561 | *count = handle->rxSize - handle->rxDataSize; |
<> | 144:ef7eb2e8f9f7 | 562 | |
<> | 144:ef7eb2e8f9f7 | 563 | return kStatus_Success; |
<> | 144:ef7eb2e8f9f7 | 564 | } |
<> | 144:ef7eb2e8f9f7 | 565 | |
<> | 144:ef7eb2e8f9f7 | 566 | void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle) |
<> | 144:ef7eb2e8f9f7 | 567 | { |
<> | 144:ef7eb2e8f9f7 | 568 | uint8_t count = 1; |
<> | 144:ef7eb2e8f9f7 | 569 | FLEXIO_UART_Type *base = (FLEXIO_UART_Type *)uartType; |
<> | 144:ef7eb2e8f9f7 | 570 | flexio_uart_handle_t *handle = (flexio_uart_handle_t *)uartHandle; |
<> | 144:ef7eb2e8f9f7 | 571 | |
<> | 144:ef7eb2e8f9f7 | 572 | /* Read the status back. */ |
<> | 144:ef7eb2e8f9f7 | 573 | uint8_t status = FLEXIO_UART_GetStatusFlags(base); |
<> | 144:ef7eb2e8f9f7 | 574 | |
<> | 144:ef7eb2e8f9f7 | 575 | /* If RX overrun. */ |
<> | 144:ef7eb2e8f9f7 | 576 | if (kFLEXIO_UART_RxOverRunFlag & status) |
<> | 144:ef7eb2e8f9f7 | 577 | { |
<> | 144:ef7eb2e8f9f7 | 578 | /* Clear Overrun flag. */ |
<> | 144:ef7eb2e8f9f7 | 579 | FLEXIO_UART_ClearStatusFlags(base, kFLEXIO_UART_RxOverRunFlag); |
<> | 144:ef7eb2e8f9f7 | 580 | |
<> | 144:ef7eb2e8f9f7 | 581 | /* Trigger callback. */ |
<> | 144:ef7eb2e8f9f7 | 582 | if (handle->callback) |
<> | 144:ef7eb2e8f9f7 | 583 | { |
<> | 144:ef7eb2e8f9f7 | 584 | handle->callback(base, handle, kStatus_FLEXIO_UART_RxHardwareOverrun, handle->userData); |
<> | 144:ef7eb2e8f9f7 | 585 | } |
<> | 144:ef7eb2e8f9f7 | 586 | } |
<> | 144:ef7eb2e8f9f7 | 587 | |
<> | 144:ef7eb2e8f9f7 | 588 | /* Receive data register full */ |
<> | 144:ef7eb2e8f9f7 | 589 | if ((kFLEXIO_UART_RxDataRegFullFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[1]))) |
<> | 144:ef7eb2e8f9f7 | 590 | { |
<> | 144:ef7eb2e8f9f7 | 591 | /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ |
<> | 144:ef7eb2e8f9f7 | 592 | if (handle->rxDataSize) |
<> | 144:ef7eb2e8f9f7 | 593 | { |
<> | 144:ef7eb2e8f9f7 | 594 | /* Using non block API to read the data from the registers. */ |
<> | 144:ef7eb2e8f9f7 | 595 | FLEXIO_UART_ReadByte(base, handle->rxData); |
<> | 144:ef7eb2e8f9f7 | 596 | handle->rxDataSize--; |
<> | 144:ef7eb2e8f9f7 | 597 | handle->rxData++; |
<> | 144:ef7eb2e8f9f7 | 598 | count--; |
<> | 144:ef7eb2e8f9f7 | 599 | |
<> | 144:ef7eb2e8f9f7 | 600 | /* If all the data required for upper layer is ready, trigger callback. */ |
<> | 144:ef7eb2e8f9f7 | 601 | if (!handle->rxDataSize) |
<> | 144:ef7eb2e8f9f7 | 602 | { |
<> | 144:ef7eb2e8f9f7 | 603 | handle->rxState = kFLEXIO_UART_RxIdle; |
<> | 144:ef7eb2e8f9f7 | 604 | |
<> | 144:ef7eb2e8f9f7 | 605 | if (handle->callback) |
<> | 144:ef7eb2e8f9f7 | 606 | { |
<> | 144:ef7eb2e8f9f7 | 607 | handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData); |
<> | 144:ef7eb2e8f9f7 | 608 | } |
<> | 144:ef7eb2e8f9f7 | 609 | } |
<> | 144:ef7eb2e8f9f7 | 610 | } |
<> | 144:ef7eb2e8f9f7 | 611 | |
<> | 144:ef7eb2e8f9f7 | 612 | if (handle->rxRingBuffer) |
<> | 144:ef7eb2e8f9f7 | 613 | { |
<> | 144:ef7eb2e8f9f7 | 614 | if (count) |
<> | 144:ef7eb2e8f9f7 | 615 | { |
<> | 144:ef7eb2e8f9f7 | 616 | /* If RX ring buffer is full, trigger callback to notify over run. */ |
<> | 144:ef7eb2e8f9f7 | 617 | if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) |
<> | 144:ef7eb2e8f9f7 | 618 | { |
<> | 144:ef7eb2e8f9f7 | 619 | if (handle->callback) |
<> | 144:ef7eb2e8f9f7 | 620 | { |
<> | 144:ef7eb2e8f9f7 | 621 | handle->callback(base, handle, kStatus_FLEXIO_UART_RxRingBufferOverrun, handle->userData); |
<> | 144:ef7eb2e8f9f7 | 622 | } |
<> | 144:ef7eb2e8f9f7 | 623 | } |
<> | 144:ef7eb2e8f9f7 | 624 | |
<> | 144:ef7eb2e8f9f7 | 625 | /* If ring buffer is still full after callback function, the oldest data is overrided. */ |
<> | 144:ef7eb2e8f9f7 | 626 | if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) |
<> | 144:ef7eb2e8f9f7 | 627 | { |
<> | 144:ef7eb2e8f9f7 | 628 | /* Increase handle->rxRingBufferTail to make room for new data. */ |
<> | 144:ef7eb2e8f9f7 | 629 | if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) |
<> | 144:ef7eb2e8f9f7 | 630 | { |
<> | 144:ef7eb2e8f9f7 | 631 | handle->rxRingBufferTail = 0U; |
<> | 144:ef7eb2e8f9f7 | 632 | } |
<> | 144:ef7eb2e8f9f7 | 633 | else |
<> | 144:ef7eb2e8f9f7 | 634 | { |
<> | 144:ef7eb2e8f9f7 | 635 | handle->rxRingBufferTail++; |
<> | 144:ef7eb2e8f9f7 | 636 | } |
<> | 144:ef7eb2e8f9f7 | 637 | } |
<> | 144:ef7eb2e8f9f7 | 638 | |
<> | 144:ef7eb2e8f9f7 | 639 | /* Read data. */ |
<> | 144:ef7eb2e8f9f7 | 640 | handle->rxRingBuffer[handle->rxRingBufferHead] = base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]; |
<> | 144:ef7eb2e8f9f7 | 641 | |
<> | 144:ef7eb2e8f9f7 | 642 | /* Increase handle->rxRingBufferHead. */ |
<> | 144:ef7eb2e8f9f7 | 643 | if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) |
<> | 144:ef7eb2e8f9f7 | 644 | { |
<> | 144:ef7eb2e8f9f7 | 645 | handle->rxRingBufferHead = 0U; |
<> | 144:ef7eb2e8f9f7 | 646 | } |
<> | 144:ef7eb2e8f9f7 | 647 | else |
<> | 144:ef7eb2e8f9f7 | 648 | { |
<> | 144:ef7eb2e8f9f7 | 649 | handle->rxRingBufferHead++; |
<> | 144:ef7eb2e8f9f7 | 650 | } |
<> | 144:ef7eb2e8f9f7 | 651 | } |
<> | 144:ef7eb2e8f9f7 | 652 | } |
<> | 144:ef7eb2e8f9f7 | 653 | /* If no receive requst pending, stop RX interrupt. */ |
<> | 144:ef7eb2e8f9f7 | 654 | else if (!handle->rxDataSize) |
<> | 144:ef7eb2e8f9f7 | 655 | { |
<> | 144:ef7eb2e8f9f7 | 656 | FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_RxDataRegFullInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 657 | } |
<> | 144:ef7eb2e8f9f7 | 658 | else |
<> | 144:ef7eb2e8f9f7 | 659 | { |
<> | 144:ef7eb2e8f9f7 | 660 | } |
<> | 144:ef7eb2e8f9f7 | 661 | } |
<> | 144:ef7eb2e8f9f7 | 662 | |
<> | 144:ef7eb2e8f9f7 | 663 | /* Send data register empty and the interrupt is enabled. */ |
<> | 144:ef7eb2e8f9f7 | 664 | if ((kFLEXIO_UART_TxDataRegEmptyFlag & status) && (base->flexioBase->SHIFTSIEN & (1U << base->shifterIndex[0]))) |
<> | 144:ef7eb2e8f9f7 | 665 | { |
<> | 144:ef7eb2e8f9f7 | 666 | if (handle->txDataSize) |
<> | 144:ef7eb2e8f9f7 | 667 | { |
<> | 144:ef7eb2e8f9f7 | 668 | /* Using non block API to write the data to the registers. */ |
<> | 144:ef7eb2e8f9f7 | 669 | FLEXIO_UART_WriteByte(base, handle->txData); |
<> | 144:ef7eb2e8f9f7 | 670 | handle->txData++; |
<> | 144:ef7eb2e8f9f7 | 671 | handle->txDataSize--; |
<> | 144:ef7eb2e8f9f7 | 672 | count--; |
<> | 144:ef7eb2e8f9f7 | 673 | |
<> | 144:ef7eb2e8f9f7 | 674 | /* If all the data are written to data register, TX finished. */ |
<> | 144:ef7eb2e8f9f7 | 675 | if (!handle->txDataSize) |
<> | 144:ef7eb2e8f9f7 | 676 | { |
<> | 144:ef7eb2e8f9f7 | 677 | handle->txState = kFLEXIO_UART_TxIdle; |
<> | 144:ef7eb2e8f9f7 | 678 | |
<> | 144:ef7eb2e8f9f7 | 679 | /* Disable TX register empty interrupt. */ |
<> | 144:ef7eb2e8f9f7 | 680 | FLEXIO_UART_DisableInterrupts(base, kFLEXIO_UART_TxDataRegEmptyInterruptEnable); |
<> | 144:ef7eb2e8f9f7 | 681 | |
<> | 144:ef7eb2e8f9f7 | 682 | /* Trigger callback. */ |
<> | 144:ef7eb2e8f9f7 | 683 | if (handle->callback) |
<> | 144:ef7eb2e8f9f7 | 684 | { |
<> | 144:ef7eb2e8f9f7 | 685 | handle->callback(base, handle, kStatus_FLEXIO_UART_TxIdle, handle->userData); |
<> | 144:ef7eb2e8f9f7 | 686 | } |
<> | 144:ef7eb2e8f9f7 | 687 | } |
<> | 144:ef7eb2e8f9f7 | 688 | } |
<> | 144:ef7eb2e8f9f7 | 689 | } |
<> | 144:ef7eb2e8f9f7 | 690 | } |