added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

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?

UserRevisionLine numberNew 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_flexcan.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 /*******************************************************************************
<> 144:ef7eb2e8f9f7 34 * Definitons
<> 144:ef7eb2e8f9f7 35 ******************************************************************************/
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 #define FLEXCAN_TIME_QUANTA_NUM (10)
<> 144:ef7eb2e8f9f7 38
<> 144:ef7eb2e8f9f7 39 /*! @brief FlexCAN Internal State. */
<> 144:ef7eb2e8f9f7 40 enum _flexcan_state
<> 144:ef7eb2e8f9f7 41 {
<> 144:ef7eb2e8f9f7 42 kFLEXCAN_StateIdle = 0x0, /*!< MB/RxFIFO idle.*/
<> 144:ef7eb2e8f9f7 43 kFLEXCAN_StateRxData = 0x1, /*!< MB receiving.*/
<> 144:ef7eb2e8f9f7 44 kFLEXCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/
<> 144:ef7eb2e8f9f7 45 kFLEXCAN_StateTxData = 0x3, /*!< MB transmitting.*/
<> 144:ef7eb2e8f9f7 46 kFLEXCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/
<> 144:ef7eb2e8f9f7 47 kFLEXCAN_StateRxFifo = 0x5, /*!< RxFIFO receiving.*/
<> 144:ef7eb2e8f9f7 48 };
<> 144:ef7eb2e8f9f7 49
<> 144:ef7eb2e8f9f7 50 /*! @brief FlexCAN message buffer CODE for Rx buffers. */
<> 144:ef7eb2e8f9f7 51 enum _flexcan_mb_code_rx
<> 144:ef7eb2e8f9f7 52 {
<> 144:ef7eb2e8f9f7 53 kFLEXCAN_RxMbInactive = 0x0, /*!< MB is not active.*/
<> 144:ef7eb2e8f9f7 54 kFLEXCAN_RxMbFull = 0x2, /*!< MB is full.*/
<> 144:ef7eb2e8f9f7 55 kFLEXCAN_RxMbEmpty = 0x4, /*!< MB is active and empty.*/
<> 144:ef7eb2e8f9f7 56 kFLEXCAN_RxMbOverrun = 0x6, /*!< MB is overwritten into a full buffer.*/
<> 144:ef7eb2e8f9f7 57 kFLEXCAN_RxMbBusy = 0x8, /*!< FlexCAN is updating the contents of the MB.*/
<> 144:ef7eb2e8f9f7 58 /*! The CPU must not access the MB.*/
<> 144:ef7eb2e8f9f7 59 kFLEXCAN_RxMbRanswer = 0xA, /*!< A frame was configured to recognize a Remote Request Frame */
<> 144:ef7eb2e8f9f7 60 /*! and transmit a Response Frame in return.*/
<> 144:ef7eb2e8f9f7 61 kFLEXCAN_RxMbNotUsed = 0xF, /*!< Not used.*/
<> 144:ef7eb2e8f9f7 62 };
<> 144:ef7eb2e8f9f7 63
<> 144:ef7eb2e8f9f7 64 /*! @brief FlexCAN message buffer CODE FOR Tx buffers. */
<> 144:ef7eb2e8f9f7 65 enum _flexcan_mb_code_tx
<> 144:ef7eb2e8f9f7 66 {
<> 144:ef7eb2e8f9f7 67 kFLEXCAN_TxMbInactive = 0x8, /*!< MB is not active.*/
<> 144:ef7eb2e8f9f7 68 kFLEXCAN_TxMbAbort = 0x9, /*!< MB is aborted.*/
<> 144:ef7eb2e8f9f7 69 kFLEXCAN_TxMbDataOrRemote = 0xC, /*!< MB is a TX Data Frame(when MB RTR = 0) or */
<> 144:ef7eb2e8f9f7 70 /*!< MB is a TX Remote Request Frame (when MB RTR = 1).*/
<> 144:ef7eb2e8f9f7 71 kFLEXCAN_TxMbTanswer = 0xE, /*!< MB is a TX Response Request Frame from */
<> 144:ef7eb2e8f9f7 72 /*! an incoming Remote Request Frame.*/
<> 144:ef7eb2e8f9f7 73 kFLEXCAN_TxMbNotUsed = 0xF, /*!< Not used.*/
<> 144:ef7eb2e8f9f7 74 };
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 /*******************************************************************************
<> 144:ef7eb2e8f9f7 77 * Prototypes
<> 144:ef7eb2e8f9f7 78 ******************************************************************************/
<> 144:ef7eb2e8f9f7 79
<> 144:ef7eb2e8f9f7 80 /*!
<> 144:ef7eb2e8f9f7 81 * @brief Get the FlexCAN instance from peripheral base address.
<> 144:ef7eb2e8f9f7 82 *
<> 144:ef7eb2e8f9f7 83 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 84 * @return FlexCAN instance.
<> 144:ef7eb2e8f9f7 85 */
<> 144:ef7eb2e8f9f7 86 uint32_t FLEXCAN_GetInstance(CAN_Type *base);
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 /*!
<> 144:ef7eb2e8f9f7 89 * @brief Enter FlexCAN Fraze Mode.
<> 144:ef7eb2e8f9f7 90 *
<> 144:ef7eb2e8f9f7 91 * This function makes the FlexCAN work under Fraze Mode.
<> 144:ef7eb2e8f9f7 92 *
<> 144:ef7eb2e8f9f7 93 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 94 */
<> 144:ef7eb2e8f9f7 95 static void FLEXCAN_EnterFrazeMode(CAN_Type *base);
<> 144:ef7eb2e8f9f7 96
<> 144:ef7eb2e8f9f7 97 /*!
<> 144:ef7eb2e8f9f7 98 * @brief Exit FlexCAN Fraze Mode.
<> 144:ef7eb2e8f9f7 99 *
<> 144:ef7eb2e8f9f7 100 * This function makes the FlexCAN leave Fraze Mode.
<> 144:ef7eb2e8f9f7 101 *
<> 144:ef7eb2e8f9f7 102 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 103 */
<> 144:ef7eb2e8f9f7 104 static void FLEXCAN_ExitFrazeMode(CAN_Type *base);
<> 144:ef7eb2e8f9f7 105
<> 144:ef7eb2e8f9f7 106 /*!
<> 144:ef7eb2e8f9f7 107 * @brief Check if Message Buffer is occupied by Rx FIFO.
<> 144:ef7eb2e8f9f7 108 *
<> 144:ef7eb2e8f9f7 109 * This function check if Message Buffer is occupied by Rx FIFO.
<> 144:ef7eb2e8f9f7 110 *
<> 144:ef7eb2e8f9f7 111 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 112 * @param mbIdx The FlexCAN Message Buffer index.
<> 144:ef7eb2e8f9f7 113 */
<> 144:ef7eb2e8f9f7 114 static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx);
<> 144:ef7eb2e8f9f7 115
<> 144:ef7eb2e8f9f7 116 /*!
<> 144:ef7eb2e8f9f7 117 * @brief Check if Message Buffer interrupt is enabled.
<> 144:ef7eb2e8f9f7 118 *
<> 144:ef7eb2e8f9f7 119 * This function check if Message Buffer interrupt is enabled.
<> 144:ef7eb2e8f9f7 120 *
<> 144:ef7eb2e8f9f7 121 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 122 * @param mbIdx The FlexCAN Message Buffer index.
<> 144:ef7eb2e8f9f7 123 */
<> 144:ef7eb2e8f9f7 124 static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx);
<> 144:ef7eb2e8f9f7 125
<> 144:ef7eb2e8f9f7 126 /*!
<> 144:ef7eb2e8f9f7 127 * @brief Reset the FlexCAN Instance.
<> 144:ef7eb2e8f9f7 128 *
<> 144:ef7eb2e8f9f7 129 * Restores the FlexCAN module to reset state, notice that this function
<> 144:ef7eb2e8f9f7 130 * will set all the registers to reset state so the FlexCAN module can not work
<> 144:ef7eb2e8f9f7 131 * after calling this API.
<> 144:ef7eb2e8f9f7 132 *
<> 144:ef7eb2e8f9f7 133 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 134 */
<> 144:ef7eb2e8f9f7 135 static void FLEXCAN_Reset(CAN_Type *base);
<> 144:ef7eb2e8f9f7 136
<> 144:ef7eb2e8f9f7 137 /*!
<> 144:ef7eb2e8f9f7 138 * @brief Set Baud Rate of FlexCAN.
<> 144:ef7eb2e8f9f7 139 *
<> 144:ef7eb2e8f9f7 140 * This function set the baud rate of FlexCAN.
<> 144:ef7eb2e8f9f7 141 *
<> 144:ef7eb2e8f9f7 142 * @param base FlexCAN peripheral base address.
<> 144:ef7eb2e8f9f7 143 * @param sourceClock_Hz Source Clock in Hz.
<> 144:ef7eb2e8f9f7 144 * @param baudRate_Bps Baud Rate in Bps.
<> 144:ef7eb2e8f9f7 145 */
<> 144:ef7eb2e8f9f7 146 static void FLEXCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps);
<> 144:ef7eb2e8f9f7 147
<> 144:ef7eb2e8f9f7 148 /*******************************************************************************
<> 144:ef7eb2e8f9f7 149 * Variables
<> 144:ef7eb2e8f9f7 150 ******************************************************************************/
<> 144:ef7eb2e8f9f7 151 /* Array of FlexCAN handle. */
<> 144:ef7eb2e8f9f7 152 static flexcan_handle_t *s_flexcanHandle[FSL_FEATURE_SOC_FLEXCAN_COUNT];
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 /* Array of FlexCAN peripheral base address. */
<> 144:ef7eb2e8f9f7 155 static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS;
<> 144:ef7eb2e8f9f7 156
<> 144:ef7eb2e8f9f7 157 /* Array of FlexCAN IRQ number. */
<> 144:ef7eb2e8f9f7 158 static const IRQn_Type s_flexcanRxWarningIRQ[] = CAN_Rx_Warning_IRQS;
<> 144:ef7eb2e8f9f7 159 static const IRQn_Type s_flexcanTxWarningIRQ[] = CAN_Tx_Warning_IRQS;
<> 144:ef7eb2e8f9f7 160 static const IRQn_Type s_flexcanWakeUpIRQ[] = CAN_Wake_Up_IRQS;
<> 144:ef7eb2e8f9f7 161 static const IRQn_Type s_flexcanErrorIRQ[] = CAN_Error_IRQS;
<> 144:ef7eb2e8f9f7 162 static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS;
<> 144:ef7eb2e8f9f7 163 static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS;
<> 144:ef7eb2e8f9f7 164
<> 144:ef7eb2e8f9f7 165 /* Array of FlexCAN clock name. */
<> 144:ef7eb2e8f9f7 166 static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS;
<> 144:ef7eb2e8f9f7 167
<> 144:ef7eb2e8f9f7 168 /*******************************************************************************
<> 144:ef7eb2e8f9f7 169 * Code
<> 144:ef7eb2e8f9f7 170 ******************************************************************************/
<> 144:ef7eb2e8f9f7 171
<> 144:ef7eb2e8f9f7 172 uint32_t FLEXCAN_GetInstance(CAN_Type *base)
<> 144:ef7eb2e8f9f7 173 {
<> 144:ef7eb2e8f9f7 174 uint32_t instance;
<> 144:ef7eb2e8f9f7 175
<> 144:ef7eb2e8f9f7 176 /* Find the instance index from base address mappings. */
<> 144:ef7eb2e8f9f7 177 for (instance = 0; instance < FSL_FEATURE_SOC_FLEXCAN_COUNT; instance++)
<> 144:ef7eb2e8f9f7 178 {
<> 144:ef7eb2e8f9f7 179 if (s_flexcanBases[instance] == base)
<> 144:ef7eb2e8f9f7 180 {
<> 144:ef7eb2e8f9f7 181 break;
<> 144:ef7eb2e8f9f7 182 }
<> 144:ef7eb2e8f9f7 183 }
<> 144:ef7eb2e8f9f7 184
<> 144:ef7eb2e8f9f7 185 assert(instance < FSL_FEATURE_SOC_FLEXCAN_COUNT);
<> 144:ef7eb2e8f9f7 186
<> 144:ef7eb2e8f9f7 187 return instance;
<> 144:ef7eb2e8f9f7 188 }
<> 144:ef7eb2e8f9f7 189
<> 144:ef7eb2e8f9f7 190 static void FLEXCAN_EnterFrazeMode(CAN_Type *base)
<> 144:ef7eb2e8f9f7 191 {
<> 144:ef7eb2e8f9f7 192 /* Set Freeze, Halt bits. */
<> 144:ef7eb2e8f9f7 193 base->MCR |= CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK;
<> 144:ef7eb2e8f9f7 194
<> 144:ef7eb2e8f9f7 195 /* Wait until the FlexCAN Module enter freeze mode. */
<> 144:ef7eb2e8f9f7 196 while (!(base->MCR & CAN_MCR_FRZACK_MASK))
<> 144:ef7eb2e8f9f7 197 {
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199 }
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 static void FLEXCAN_ExitFrazeMode(CAN_Type *base)
<> 144:ef7eb2e8f9f7 202 {
<> 144:ef7eb2e8f9f7 203 /* Clear Freeze, Halt bits. */
<> 144:ef7eb2e8f9f7 204 base->MCR &= ~(CAN_MCR_FRZ_MASK | CAN_MCR_HALT_MASK);
<> 144:ef7eb2e8f9f7 205
<> 144:ef7eb2e8f9f7 206 /* Wait until the FlexCAN Module exit freeze mode. */
<> 144:ef7eb2e8f9f7 207 while (base->MCR & CAN_MCR_FRZACK_MASK)
<> 144:ef7eb2e8f9f7 208 {
<> 144:ef7eb2e8f9f7 209 }
<> 144:ef7eb2e8f9f7 210 }
<> 144:ef7eb2e8f9f7 211
<> 144:ef7eb2e8f9f7 212 static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx)
<> 144:ef7eb2e8f9f7 213 {
<> 144:ef7eb2e8f9f7 214 uint8_t lastOccupiedMb;
<> 144:ef7eb2e8f9f7 215
<> 144:ef7eb2e8f9f7 216 /* Is Rx FIFO enabled? */
<> 144:ef7eb2e8f9f7 217 if (base->MCR & CAN_MCR_RFEN_MASK)
<> 144:ef7eb2e8f9f7 218 {
<> 144:ef7eb2e8f9f7 219 /* Get RFFN value. */
<> 144:ef7eb2e8f9f7 220 lastOccupiedMb = ((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
<> 144:ef7eb2e8f9f7 221 /* Calculate the number of last Message Buffer occupied by Rx FIFO. */
<> 144:ef7eb2e8f9f7 222 lastOccupiedMb = ((lastOccupiedMb + 1) * 2) + 5;
<> 144:ef7eb2e8f9f7 223
<> 144:ef7eb2e8f9f7 224 if (mbIdx <= lastOccupiedMb)
<> 144:ef7eb2e8f9f7 225 {
<> 144:ef7eb2e8f9f7 226 return true;
<> 144:ef7eb2e8f9f7 227 }
<> 144:ef7eb2e8f9f7 228 else
<> 144:ef7eb2e8f9f7 229 {
<> 144:ef7eb2e8f9f7 230 return false;
<> 144:ef7eb2e8f9f7 231 }
<> 144:ef7eb2e8f9f7 232 }
<> 144:ef7eb2e8f9f7 233 else
<> 144:ef7eb2e8f9f7 234 {
<> 144:ef7eb2e8f9f7 235 return false;
<> 144:ef7eb2e8f9f7 236 }
<> 144:ef7eb2e8f9f7 237 }
<> 144:ef7eb2e8f9f7 238
<> 144:ef7eb2e8f9f7 239 static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx)
<> 144:ef7eb2e8f9f7 240 {
<> 144:ef7eb2e8f9f7 241 /* Assertion. */
<> 144:ef7eb2e8f9f7 242 assert(mbIdx < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base));
<> 144:ef7eb2e8f9f7 243
<> 144:ef7eb2e8f9f7 244 #if (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
<> 144:ef7eb2e8f9f7 245 if (mbIdx < 32)
<> 144:ef7eb2e8f9f7 246 {
<> 144:ef7eb2e8f9f7 247 #endif
<> 144:ef7eb2e8f9f7 248 if (base->IMASK1 & ((uint32_t)(1 << mbIdx)))
<> 144:ef7eb2e8f9f7 249 {
<> 144:ef7eb2e8f9f7 250 return true;
<> 144:ef7eb2e8f9f7 251 }
<> 144:ef7eb2e8f9f7 252 else
<> 144:ef7eb2e8f9f7 253 {
<> 144:ef7eb2e8f9f7 254 return false;
<> 144:ef7eb2e8f9f7 255 }
<> 144:ef7eb2e8f9f7 256 #if (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
<> 144:ef7eb2e8f9f7 257 }
<> 144:ef7eb2e8f9f7 258 else
<> 144:ef7eb2e8f9f7 259 {
<> 144:ef7eb2e8f9f7 260 if (base->IMASK2 & ((uint32_t)(1 << (mbIdx - 32))))
<> 144:ef7eb2e8f9f7 261 return true;
<> 144:ef7eb2e8f9f7 262 else
<> 144:ef7eb2e8f9f7 263 return false;
<> 144:ef7eb2e8f9f7 264 }
<> 144:ef7eb2e8f9f7 265 #endif
<> 144:ef7eb2e8f9f7 266 }
<> 144:ef7eb2e8f9f7 267
<> 144:ef7eb2e8f9f7 268 static void FLEXCAN_Reset(CAN_Type *base)
<> 144:ef7eb2e8f9f7 269 {
<> 144:ef7eb2e8f9f7 270 /* The module must should be first exit from low power
<> 144:ef7eb2e8f9f7 271 * mode, and then soft reset can be applied.
<> 144:ef7eb2e8f9f7 272 */
<> 144:ef7eb2e8f9f7 273 assert(!(base->MCR & CAN_MCR_MDIS_MASK));
<> 144:ef7eb2e8f9f7 274
<> 144:ef7eb2e8f9f7 275 uint8_t i;
<> 144:ef7eb2e8f9f7 276
<> 144:ef7eb2e8f9f7 277 #if (FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT != 0)
<> 144:ef7eb2e8f9f7 278 /* De-assert DOZE Enable Bit. */
<> 144:ef7eb2e8f9f7 279 base->MCR &= ~CAN_MCR_DOZE_MASK;
<> 144:ef7eb2e8f9f7 280 #endif
<> 144:ef7eb2e8f9f7 281
<> 144:ef7eb2e8f9f7 282 /* Wait until FlexCAN exit from any Low Power Mode. */
<> 144:ef7eb2e8f9f7 283 while (base->MCR & CAN_MCR_LPMACK_MASK)
<> 144:ef7eb2e8f9f7 284 {
<> 144:ef7eb2e8f9f7 285 }
<> 144:ef7eb2e8f9f7 286
<> 144:ef7eb2e8f9f7 287 /* Assert Soft Reset Signal. */
<> 144:ef7eb2e8f9f7 288 base->MCR |= CAN_MCR_SOFTRST_MASK;
<> 144:ef7eb2e8f9f7 289 /* Wait until FlexCAN reset completes. */
<> 144:ef7eb2e8f9f7 290 while (base->MCR & CAN_MCR_SOFTRST_MASK)
<> 144:ef7eb2e8f9f7 291 {
<> 144:ef7eb2e8f9f7 292 }
<> 144:ef7eb2e8f9f7 293
<> 144:ef7eb2e8f9f7 294 /* Reset MCR rigister. */
<> 144:ef7eb2e8f9f7 295 #if (defined(FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER) && FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER)
<> 144:ef7eb2e8f9f7 296 base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_WAKSRC_MASK |
<> 144:ef7eb2e8f9f7 297 CAN_MCR_MAXMB(FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1);
<> 144:ef7eb2e8f9f7 298 #else
<> 144:ef7eb2e8f9f7 299 base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_MAXMB(FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1);
<> 144:ef7eb2e8f9f7 300 #endif
<> 144:ef7eb2e8f9f7 301
<> 144:ef7eb2e8f9f7 302 /* Reset CTRL1 and CTRL2 rigister. */
<> 144:ef7eb2e8f9f7 303 base->CTRL1 = CAN_CTRL1_SMP_MASK;
<> 144:ef7eb2e8f9f7 304 base->CTRL2 = CAN_CTRL2_TASD(0x16) | CAN_CTRL2_RRS_MASK | CAN_CTRL2_EACEN_MASK;
<> 144:ef7eb2e8f9f7 305
<> 144:ef7eb2e8f9f7 306 /* Clean all individual Rx Mask of Message Buffers. */
<> 144:ef7eb2e8f9f7 307 for (i = 0; i < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
<> 144:ef7eb2e8f9f7 308 {
<> 144:ef7eb2e8f9f7 309 base->RXIMR[i] = 0x3FFFFFFF;
<> 144:ef7eb2e8f9f7 310 }
<> 144:ef7eb2e8f9f7 311
<> 144:ef7eb2e8f9f7 312 /* Clean Global Mask of Message Buffers. */
<> 144:ef7eb2e8f9f7 313 base->RXMGMASK = 0x3FFFFFFF;
<> 144:ef7eb2e8f9f7 314 /* Clean Global Mask of Message Buffer 14. */
<> 144:ef7eb2e8f9f7 315 base->RX14MASK = 0x3FFFFFFF;
<> 144:ef7eb2e8f9f7 316 /* Clean Global Mask of Message Buffer 15. */
<> 144:ef7eb2e8f9f7 317 base->RX15MASK = 0x3FFFFFFF;
<> 144:ef7eb2e8f9f7 318 /* Clean Global Mask of Rx FIFO. */
<> 144:ef7eb2e8f9f7 319 base->RXFGMASK = 0x3FFFFFFF;
<> 144:ef7eb2e8f9f7 320
<> 144:ef7eb2e8f9f7 321 /* Clean all Message Buffer CS fields. */
<> 144:ef7eb2e8f9f7 322 for (i = 0; i < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
<> 144:ef7eb2e8f9f7 323 {
<> 144:ef7eb2e8f9f7 324 base->MB[i].CS = 0x0;
<> 144:ef7eb2e8f9f7 325 }
<> 144:ef7eb2e8f9f7 326 }
<> 144:ef7eb2e8f9f7 327
<> 144:ef7eb2e8f9f7 328 static void FLEXCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps)
<> 144:ef7eb2e8f9f7 329 {
<> 144:ef7eb2e8f9f7 330 flexcan_timing_config_t timingConfig;
<> 144:ef7eb2e8f9f7 331 uint32_t priDiv = baudRate_Bps * FLEXCAN_TIME_QUANTA_NUM;
<> 144:ef7eb2e8f9f7 332
<> 144:ef7eb2e8f9f7 333 /* Assertion: Desired baud rate is too high. */
<> 144:ef7eb2e8f9f7 334 assert(baudRate_Bps <= 1000000U);
<> 144:ef7eb2e8f9f7 335 /* Assertion: Source clock should greater than baud rate * FLEXCAN_TIME_QUANTA_NUM. */
<> 144:ef7eb2e8f9f7 336 assert(priDiv <= sourceClock_Hz);
<> 144:ef7eb2e8f9f7 337
<> 144:ef7eb2e8f9f7 338 if (0 == priDiv)
<> 144:ef7eb2e8f9f7 339 {
<> 144:ef7eb2e8f9f7 340 priDiv = 1;
<> 144:ef7eb2e8f9f7 341 }
<> 144:ef7eb2e8f9f7 342
<> 144:ef7eb2e8f9f7 343 priDiv = (sourceClock_Hz / priDiv) - 1;
<> 144:ef7eb2e8f9f7 344
<> 144:ef7eb2e8f9f7 345 /* Desired baud rate is too low. */
<> 144:ef7eb2e8f9f7 346 if (priDiv > 0xFF)
<> 144:ef7eb2e8f9f7 347 {
<> 144:ef7eb2e8f9f7 348 priDiv = 0xFF;
<> 144:ef7eb2e8f9f7 349 }
<> 144:ef7eb2e8f9f7 350
<> 144:ef7eb2e8f9f7 351 /* FlexCAN timing setting formula:
<> 144:ef7eb2e8f9f7 352 * FLEXCAN_TIME_QUANTA_NUM = 1 + (PSEG1 + 1) + (PSEG2 + 1) + (PROPSEG + 1);
<> 144:ef7eb2e8f9f7 353 */
<> 144:ef7eb2e8f9f7 354 timingConfig.preDivider = priDiv;
<> 144:ef7eb2e8f9f7 355 timingConfig.phaseSeg1 = 3;
<> 144:ef7eb2e8f9f7 356 timingConfig.phaseSeg2 = 2;
<> 144:ef7eb2e8f9f7 357 timingConfig.propSeg = 1;
<> 144:ef7eb2e8f9f7 358 timingConfig.rJumpwidth = 1;
<> 144:ef7eb2e8f9f7 359
<> 144:ef7eb2e8f9f7 360 /* Update actual timing characteristic. */
<> 144:ef7eb2e8f9f7 361 FLEXCAN_SetTimingConfig(base, &timingConfig);
<> 144:ef7eb2e8f9f7 362 }
<> 144:ef7eb2e8f9f7 363
<> 144:ef7eb2e8f9f7 364 void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz)
<> 144:ef7eb2e8f9f7 365 {
<> 144:ef7eb2e8f9f7 366 uint32_t mcrTemp;
<> 144:ef7eb2e8f9f7 367
<> 144:ef7eb2e8f9f7 368 /* Assertion. */
<> 144:ef7eb2e8f9f7 369 assert(config);
<> 144:ef7eb2e8f9f7 370 assert((config->maxMbNum > 0) && (config->maxMbNum <= FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)));
<> 144:ef7eb2e8f9f7 371
<> 144:ef7eb2e8f9f7 372 /* Enable FlexCAN clock. */
<> 144:ef7eb2e8f9f7 373 CLOCK_EnableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 374
<> 144:ef7eb2e8f9f7 375 /* Disable FlexCAN Module. */
<> 144:ef7eb2e8f9f7 376 FLEXCAN_Enable(base, false);
<> 144:ef7eb2e8f9f7 377
<> 144:ef7eb2e8f9f7 378 /* Protocol-Engine clock source selection, This bit must be set
<> 144:ef7eb2e8f9f7 379 * when FlexCAN Module in Disable Mode.
<> 144:ef7eb2e8f9f7 380 */
<> 144:ef7eb2e8f9f7 381 base->CTRL1 = (kFLEXCAN_ClkSrcOsc == config->clkSrc) ? base->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK :
<> 144:ef7eb2e8f9f7 382 base->CTRL1 | CAN_CTRL1_CLKSRC_MASK;
<> 144:ef7eb2e8f9f7 383
<> 144:ef7eb2e8f9f7 384 /* Enable FlexCAN Module for configuartion. */
<> 144:ef7eb2e8f9f7 385 FLEXCAN_Enable(base, true);
<> 144:ef7eb2e8f9f7 386
<> 144:ef7eb2e8f9f7 387 /* Reset to known status. */
<> 144:ef7eb2e8f9f7 388 FLEXCAN_Reset(base);
<> 144:ef7eb2e8f9f7 389
<> 144:ef7eb2e8f9f7 390 /* Save current MCR value. */
<> 144:ef7eb2e8f9f7 391 mcrTemp = base->MCR;
<> 144:ef7eb2e8f9f7 392
<> 144:ef7eb2e8f9f7 393 /* Set the maximum number of Message Buffers */
<> 144:ef7eb2e8f9f7 394 mcrTemp = (mcrTemp & ~CAN_MCR_MAXMB_MASK) | CAN_MCR_MAXMB(config->maxMbNum - 1);
<> 144:ef7eb2e8f9f7 395
<> 144:ef7eb2e8f9f7 396 /* Enable Loop Back Mode? */
<> 144:ef7eb2e8f9f7 397 base->CTRL1 = (config->enableLoopBack) ? base->CTRL1 | CAN_CTRL1_LPB_MASK : base->CTRL1 & ~CAN_CTRL1_LPB_MASK;
<> 144:ef7eb2e8f9f7 398
<> 144:ef7eb2e8f9f7 399 /* Enable Self Wake Up Mode? */
<> 144:ef7eb2e8f9f7 400 mcrTemp = (config->enableSelfWakeup) ? mcrTemp | CAN_MCR_SLFWAK_MASK : mcrTemp & ~CAN_MCR_SLFWAK_MASK;
<> 144:ef7eb2e8f9f7 401
<> 144:ef7eb2e8f9f7 402 /* Enable Individual Rx Masking? */
<> 144:ef7eb2e8f9f7 403 mcrTemp = (config->enableIndividMask) ? mcrTemp | CAN_MCR_IRMQ_MASK : mcrTemp & ~CAN_MCR_IRMQ_MASK;
<> 144:ef7eb2e8f9f7 404
<> 144:ef7eb2e8f9f7 405 #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
<> 144:ef7eb2e8f9f7 406 /* Enable Doze Mode? */
<> 144:ef7eb2e8f9f7 407 mcrTemp = (config->enableDoze) ? mcrTemp | CAN_MCR_DOZE_MASK : mcrTemp & ~CAN_MCR_DOZE_MASK;
<> 144:ef7eb2e8f9f7 408 #endif
<> 144:ef7eb2e8f9f7 409
<> 144:ef7eb2e8f9f7 410 /* Save MCR Configuation. */
<> 144:ef7eb2e8f9f7 411 base->MCR = mcrTemp;
<> 144:ef7eb2e8f9f7 412
<> 144:ef7eb2e8f9f7 413 /* Baud Rate Configuration.*/
<> 144:ef7eb2e8f9f7 414 FLEXCAN_SetBaudRate(base, sourceClock_Hz, config->baudRate);
<> 144:ef7eb2e8f9f7 415 }
<> 144:ef7eb2e8f9f7 416
<> 144:ef7eb2e8f9f7 417 void FLEXCAN_Deinit(CAN_Type *base)
<> 144:ef7eb2e8f9f7 418 {
<> 144:ef7eb2e8f9f7 419 /* Reset all Register Contents. */
<> 144:ef7eb2e8f9f7 420 FLEXCAN_Reset(base);
<> 144:ef7eb2e8f9f7 421
<> 144:ef7eb2e8f9f7 422 /* Disable FlexCAN module. */
<> 144:ef7eb2e8f9f7 423 FLEXCAN_Enable(base, false);
<> 144:ef7eb2e8f9f7 424
<> 144:ef7eb2e8f9f7 425 /* Disable FlexCAN clock. */
<> 144:ef7eb2e8f9f7 426 CLOCK_DisableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 427 }
<> 144:ef7eb2e8f9f7 428
<> 144:ef7eb2e8f9f7 429 void FLEXCAN_GetDefaultConfig(flexcan_config_t *config)
<> 144:ef7eb2e8f9f7 430 {
<> 144:ef7eb2e8f9f7 431 /* Assertion. */
<> 144:ef7eb2e8f9f7 432 assert(config);
<> 144:ef7eb2e8f9f7 433
<> 144:ef7eb2e8f9f7 434 /* Initialize FlexCAN Module config struct with default value. */
<> 144:ef7eb2e8f9f7 435 config->clkSrc = kFLEXCAN_ClkSrcOsc;
<> 144:ef7eb2e8f9f7 436 config->baudRate = 125000U;
<> 144:ef7eb2e8f9f7 437 config->maxMbNum = 16;
<> 144:ef7eb2e8f9f7 438 config->enableLoopBack = false;
<> 144:ef7eb2e8f9f7 439 config->enableSelfWakeup = false;
<> 144:ef7eb2e8f9f7 440 config->enableIndividMask = false;
<> 144:ef7eb2e8f9f7 441 #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
<> 144:ef7eb2e8f9f7 442 config->enableDoze = false;
<> 144:ef7eb2e8f9f7 443 #endif
<> 144:ef7eb2e8f9f7 444 }
<> 144:ef7eb2e8f9f7 445
<> 144:ef7eb2e8f9f7 446 void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *config)
<> 144:ef7eb2e8f9f7 447 {
<> 144:ef7eb2e8f9f7 448 /* Assertion. */
<> 144:ef7eb2e8f9f7 449 assert(config);
<> 144:ef7eb2e8f9f7 450
<> 144:ef7eb2e8f9f7 451 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 452 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 453
<> 144:ef7eb2e8f9f7 454 /* Cleaning previous Timing Setting. */
<> 144:ef7eb2e8f9f7 455 base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
<> 144:ef7eb2e8f9f7 456 CAN_CTRL1_PROPSEG_MASK);
<> 144:ef7eb2e8f9f7 457
<> 144:ef7eb2e8f9f7 458 /* Updating Timing Setting according to configuration structure. */
<> 144:ef7eb2e8f9f7 459 base->CTRL1 |=
<> 144:ef7eb2e8f9f7 460 (CAN_CTRL1_PRESDIV(config->preDivider) | CAN_CTRL1_RJW(config->rJumpwidth) |
<> 144:ef7eb2e8f9f7 461 CAN_CTRL1_PSEG1(config->phaseSeg1) | CAN_CTRL1_PSEG2(config->phaseSeg2) | CAN_CTRL1_PROPSEG(config->propSeg));
<> 144:ef7eb2e8f9f7 462
<> 144:ef7eb2e8f9f7 463 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 464 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 465 }
<> 144:ef7eb2e8f9f7 466
<> 144:ef7eb2e8f9f7 467 void FlEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask)
<> 144:ef7eb2e8f9f7 468 {
<> 144:ef7eb2e8f9f7 469 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 470 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 471
<> 144:ef7eb2e8f9f7 472 /* Setting Rx Message Buffer Global Mask value. */
<> 144:ef7eb2e8f9f7 473 base->RXMGMASK = mask;
<> 144:ef7eb2e8f9f7 474 base->RX14MASK = mask;
<> 144:ef7eb2e8f9f7 475 base->RX15MASK = mask;
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 478 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 479 }
<> 144:ef7eb2e8f9f7 480
<> 144:ef7eb2e8f9f7 481 void FlEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask)
<> 144:ef7eb2e8f9f7 482 {
<> 144:ef7eb2e8f9f7 483 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 484 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 485
<> 144:ef7eb2e8f9f7 486 /* Setting Rx FIFO Global Mask value. */
<> 144:ef7eb2e8f9f7 487 base->RXFGMASK = mask;
<> 144:ef7eb2e8f9f7 488
<> 144:ef7eb2e8f9f7 489 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 490 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 491 }
<> 144:ef7eb2e8f9f7 492
<> 144:ef7eb2e8f9f7 493 void FlEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)
<> 144:ef7eb2e8f9f7 494 {
<> 144:ef7eb2e8f9f7 495 assert(maskIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 496
<> 144:ef7eb2e8f9f7 497 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 498 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 499
<> 144:ef7eb2e8f9f7 500 /* Setting Rx Individual Mask value. */
<> 144:ef7eb2e8f9f7 501 base->RXIMR[maskIdx] = mask;
<> 144:ef7eb2e8f9f7 502
<> 144:ef7eb2e8f9f7 503 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 504 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 505 }
<> 144:ef7eb2e8f9f7 506
<> 144:ef7eb2e8f9f7 507 void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable)
<> 144:ef7eb2e8f9f7 508 {
<> 144:ef7eb2e8f9f7 509 /* Assertion. */
<> 144:ef7eb2e8f9f7 510 assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 511
<> 144:ef7eb2e8f9f7 512 if (FLEXCAN_IsMbOccupied(base, mbIdx))
<> 144:ef7eb2e8f9f7 513 {
<> 144:ef7eb2e8f9f7 514 assert(false);
<> 144:ef7eb2e8f9f7 515 }
<> 144:ef7eb2e8f9f7 516
<> 144:ef7eb2e8f9f7 517 /* Inactivate Message Buffer. */
<> 144:ef7eb2e8f9f7 518 if (enable)
<> 144:ef7eb2e8f9f7 519 {
<> 144:ef7eb2e8f9f7 520 base->MB[mbIdx].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
<> 144:ef7eb2e8f9f7 521 }
<> 144:ef7eb2e8f9f7 522 else
<> 144:ef7eb2e8f9f7 523 {
<> 144:ef7eb2e8f9f7 524 base->MB[mbIdx].CS = 0;
<> 144:ef7eb2e8f9f7 525 }
<> 144:ef7eb2e8f9f7 526
<> 144:ef7eb2e8f9f7 527 /* Clean Message Buffer content. */
<> 144:ef7eb2e8f9f7 528 base->MB[mbIdx].ID = 0x0;
<> 144:ef7eb2e8f9f7 529 base->MB[mbIdx].WORD0 = 0x0;
<> 144:ef7eb2e8f9f7 530 base->MB[mbIdx].WORD1 = 0x0;
<> 144:ef7eb2e8f9f7 531 }
<> 144:ef7eb2e8f9f7 532
<> 144:ef7eb2e8f9f7 533 void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *config, bool enable)
<> 144:ef7eb2e8f9f7 534 {
<> 144:ef7eb2e8f9f7 535 /* Assertion. */
<> 144:ef7eb2e8f9f7 536 assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 537 assert(((config) || (false == enable)));
<> 144:ef7eb2e8f9f7 538
<> 144:ef7eb2e8f9f7 539 uint32_t cs_temp = 0;
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541 if (FLEXCAN_IsMbOccupied(base, mbIdx))
<> 144:ef7eb2e8f9f7 542 {
<> 144:ef7eb2e8f9f7 543 assert(false);
<> 144:ef7eb2e8f9f7 544 }
<> 144:ef7eb2e8f9f7 545
<> 144:ef7eb2e8f9f7 546 /* Inactivate Message Buffer. */
<> 144:ef7eb2e8f9f7 547 base->MB[mbIdx].CS = 0;
<> 144:ef7eb2e8f9f7 548
<> 144:ef7eb2e8f9f7 549 /* Clean Message Buffer content. */
<> 144:ef7eb2e8f9f7 550 base->MB[mbIdx].ID = 0x0;
<> 144:ef7eb2e8f9f7 551 base->MB[mbIdx].WORD0 = 0x0;
<> 144:ef7eb2e8f9f7 552 base->MB[mbIdx].WORD1 = 0x0;
<> 144:ef7eb2e8f9f7 553
<> 144:ef7eb2e8f9f7 554 if (enable)
<> 144:ef7eb2e8f9f7 555 {
<> 144:ef7eb2e8f9f7 556 /* Setup Message Buffer ID. */
<> 144:ef7eb2e8f9f7 557 base->MB[mbIdx].ID = config->id;
<> 144:ef7eb2e8f9f7 558
<> 144:ef7eb2e8f9f7 559 /* Setup Message Buffer format. */
<> 144:ef7eb2e8f9f7 560 if (kFLEXCAN_FrameFormatExtend == config->format)
<> 144:ef7eb2e8f9f7 561 {
<> 144:ef7eb2e8f9f7 562 cs_temp |= CAN_CS_IDE_MASK;
<> 144:ef7eb2e8f9f7 563 }
<> 144:ef7eb2e8f9f7 564
<> 144:ef7eb2e8f9f7 565 /* Setup Message Buffer type. */
<> 144:ef7eb2e8f9f7 566 if (kFLEXCAN_FrameTypeRemote == config->type)
<> 144:ef7eb2e8f9f7 567 {
<> 144:ef7eb2e8f9f7 568 cs_temp |= CAN_CS_RTR_MASK;
<> 144:ef7eb2e8f9f7 569 }
<> 144:ef7eb2e8f9f7 570
<> 144:ef7eb2e8f9f7 571 /* Activate Rx Message Buffer. */
<> 144:ef7eb2e8f9f7 572 cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty);
<> 144:ef7eb2e8f9f7 573 base->MB[mbIdx].CS = cs_temp;
<> 144:ef7eb2e8f9f7 574 }
<> 144:ef7eb2e8f9f7 575 }
<> 144:ef7eb2e8f9f7 576
<> 144:ef7eb2e8f9f7 577 void FlEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *config, bool enable)
<> 144:ef7eb2e8f9f7 578 {
<> 144:ef7eb2e8f9f7 579 /* Assertion. */
<> 144:ef7eb2e8f9f7 580 assert((config) || (false == enable));
<> 144:ef7eb2e8f9f7 581
<> 144:ef7eb2e8f9f7 582 volatile uint32_t *idFilterRegion = (volatile uint32_t *)(&base->MB[6].CS);
<> 144:ef7eb2e8f9f7 583 uint8_t setup_mb, i, rffn = 0;
<> 144:ef7eb2e8f9f7 584
<> 144:ef7eb2e8f9f7 585 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 586 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 587
<> 144:ef7eb2e8f9f7 588 if (enable)
<> 144:ef7eb2e8f9f7 589 {
<> 144:ef7eb2e8f9f7 590 assert(config->idFilterNum <= 128);
<> 144:ef7eb2e8f9f7 591
<> 144:ef7eb2e8f9f7 592 /* Get the setup_mb value. */
<> 144:ef7eb2e8f9f7 593 setup_mb = (base->MCR & CAN_MCR_MAXMB_MASK) >> CAN_MCR_MAXMB_SHIFT;
<> 144:ef7eb2e8f9f7 594 setup_mb = (setup_mb < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) ?
<> 144:ef7eb2e8f9f7 595 setup_mb :
<> 144:ef7eb2e8f9f7 596 FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base);
<> 144:ef7eb2e8f9f7 597
<> 144:ef7eb2e8f9f7 598 /* Determine RFFN value. */
<> 144:ef7eb2e8f9f7 599 for (i = 0; i <= 0xF; i++)
<> 144:ef7eb2e8f9f7 600 {
<> 144:ef7eb2e8f9f7 601 if ((8 * (i + 1)) >= config->idFilterNum)
<> 144:ef7eb2e8f9f7 602 {
<> 144:ef7eb2e8f9f7 603 rffn = i;
<> 144:ef7eb2e8f9f7 604 assert(((setup_mb - 8) - (2 * rffn)) > 0);
<> 144:ef7eb2e8f9f7 605
<> 144:ef7eb2e8f9f7 606 base->CTRL2 = (base->CTRL2 & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(rffn);
<> 144:ef7eb2e8f9f7 607 break;
<> 144:ef7eb2e8f9f7 608 }
<> 144:ef7eb2e8f9f7 609 }
<> 144:ef7eb2e8f9f7 610 }
<> 144:ef7eb2e8f9f7 611 else
<> 144:ef7eb2e8f9f7 612 {
<> 144:ef7eb2e8f9f7 613 rffn = (base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT;
<> 144:ef7eb2e8f9f7 614 }
<> 144:ef7eb2e8f9f7 615
<> 144:ef7eb2e8f9f7 616 /* Clean ID filter table occuyied Message Buffer Region. */
<> 144:ef7eb2e8f9f7 617 rffn = (rffn + 1) * 8;
<> 144:ef7eb2e8f9f7 618 for (i = 0; i < rffn; i++)
<> 144:ef7eb2e8f9f7 619 {
<> 144:ef7eb2e8f9f7 620 idFilterRegion[i] = 0x0;
<> 144:ef7eb2e8f9f7 621 }
<> 144:ef7eb2e8f9f7 622
<> 144:ef7eb2e8f9f7 623 if (enable)
<> 144:ef7eb2e8f9f7 624 {
<> 144:ef7eb2e8f9f7 625 /* Disable unused Rx FIFO Filter. */
<> 144:ef7eb2e8f9f7 626 for (i = config->idFilterNum; i < rffn; i++)
<> 144:ef7eb2e8f9f7 627 {
<> 144:ef7eb2e8f9f7 628 idFilterRegion[i] = 0xFFFFFFFFU;
<> 144:ef7eb2e8f9f7 629 }
<> 144:ef7eb2e8f9f7 630
<> 144:ef7eb2e8f9f7 631 /* Copy ID filter table to Message Buffer Region. */
<> 144:ef7eb2e8f9f7 632 for (i = 0; i < config->idFilterNum; i++)
<> 144:ef7eb2e8f9f7 633 {
<> 144:ef7eb2e8f9f7 634 idFilterRegion[i] = config->idFilterTable[i];
<> 144:ef7eb2e8f9f7 635 }
<> 144:ef7eb2e8f9f7 636
<> 144:ef7eb2e8f9f7 637 /* Setup ID Fitlter Type. */
<> 144:ef7eb2e8f9f7 638 switch (config->idFilterType)
<> 144:ef7eb2e8f9f7 639 {
<> 144:ef7eb2e8f9f7 640 case kFLEXCAN_RxFifoFilterTypeA:
<> 144:ef7eb2e8f9f7 641 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x0);
<> 144:ef7eb2e8f9f7 642 break;
<> 144:ef7eb2e8f9f7 643 case kFLEXCAN_RxFifoFilterTypeB:
<> 144:ef7eb2e8f9f7 644 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x1);
<> 144:ef7eb2e8f9f7 645 break;
<> 144:ef7eb2e8f9f7 646 case kFLEXCAN_RxFifoFilterTypeC:
<> 144:ef7eb2e8f9f7 647 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x2);
<> 144:ef7eb2e8f9f7 648 break;
<> 144:ef7eb2e8f9f7 649 case kFLEXCAN_RxFifoFilterTypeD:
<> 144:ef7eb2e8f9f7 650 /* All frames rejected. */
<> 144:ef7eb2e8f9f7 651 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x3);
<> 144:ef7eb2e8f9f7 652 break;
<> 144:ef7eb2e8f9f7 653 default:
<> 144:ef7eb2e8f9f7 654 break;
<> 144:ef7eb2e8f9f7 655 }
<> 144:ef7eb2e8f9f7 656
<> 144:ef7eb2e8f9f7 657 /* Setting Message Reception Priority. */
<> 144:ef7eb2e8f9f7 658 base->CTRL2 = (config->priority == kFLEXCAN_RxFifoPrioHigh) ? base->CTRL2 & ~CAN_CTRL2_MRP_MASK :
<> 144:ef7eb2e8f9f7 659 base->CTRL2 | CAN_CTRL2_MRP_MASK;
<> 144:ef7eb2e8f9f7 660
<> 144:ef7eb2e8f9f7 661 /* Enable Rx Message FIFO. */
<> 144:ef7eb2e8f9f7 662 base->MCR |= CAN_MCR_RFEN_MASK;
<> 144:ef7eb2e8f9f7 663 }
<> 144:ef7eb2e8f9f7 664 else
<> 144:ef7eb2e8f9f7 665 {
<> 144:ef7eb2e8f9f7 666 /* Disable Rx Message FIFO. */
<> 144:ef7eb2e8f9f7 667 base->MCR &= ~CAN_MCR_RFEN_MASK;
<> 144:ef7eb2e8f9f7 668
<> 144:ef7eb2e8f9f7 669 /* Clean MB0 ~ MB5. */
<> 144:ef7eb2e8f9f7 670 FLEXCAN_SetRxMbConfig(base, 0, NULL, false);
<> 144:ef7eb2e8f9f7 671 FLEXCAN_SetRxMbConfig(base, 1, NULL, false);
<> 144:ef7eb2e8f9f7 672 FLEXCAN_SetRxMbConfig(base, 2, NULL, false);
<> 144:ef7eb2e8f9f7 673 FLEXCAN_SetRxMbConfig(base, 3, NULL, false);
<> 144:ef7eb2e8f9f7 674 FLEXCAN_SetRxMbConfig(base, 4, NULL, false);
<> 144:ef7eb2e8f9f7 675 FLEXCAN_SetRxMbConfig(base, 5, NULL, false);
<> 144:ef7eb2e8f9f7 676 }
<> 144:ef7eb2e8f9f7 677
<> 144:ef7eb2e8f9f7 678 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 679 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 680 }
<> 144:ef7eb2e8f9f7 681
<> 144:ef7eb2e8f9f7 682 #if (defined(FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) && FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA)
<> 144:ef7eb2e8f9f7 683 void FLEXCAN_EnableRxFifoDMA(CAN_Type *base, bool enable)
<> 144:ef7eb2e8f9f7 684 {
<> 144:ef7eb2e8f9f7 685 if (enable)
<> 144:ef7eb2e8f9f7 686 {
<> 144:ef7eb2e8f9f7 687 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 688 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 689
<> 144:ef7eb2e8f9f7 690 /* Enable FlexCAN DMA. */
<> 144:ef7eb2e8f9f7 691 base->MCR |= CAN_MCR_DMA_MASK;
<> 144:ef7eb2e8f9f7 692
<> 144:ef7eb2e8f9f7 693 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 694 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 695 }
<> 144:ef7eb2e8f9f7 696 else
<> 144:ef7eb2e8f9f7 697 {
<> 144:ef7eb2e8f9f7 698 /* Enter Fraze Mode. */
<> 144:ef7eb2e8f9f7 699 FLEXCAN_EnterFrazeMode(base);
<> 144:ef7eb2e8f9f7 700
<> 144:ef7eb2e8f9f7 701 /* Disable FlexCAN DMA. */
<> 144:ef7eb2e8f9f7 702 base->MCR &= ~CAN_MCR_DMA_MASK;
<> 144:ef7eb2e8f9f7 703
<> 144:ef7eb2e8f9f7 704 /* Exit Fraze Mode. */
<> 144:ef7eb2e8f9f7 705 FLEXCAN_ExitFrazeMode(base);
<> 144:ef7eb2e8f9f7 706 }
<> 144:ef7eb2e8f9f7 707 }
<> 144:ef7eb2e8f9f7 708 #endif /* FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA */
<> 144:ef7eb2e8f9f7 709
<> 144:ef7eb2e8f9f7 710 status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *txFrame)
<> 144:ef7eb2e8f9f7 711 {
<> 144:ef7eb2e8f9f7 712 /* Assertion. */
<> 144:ef7eb2e8f9f7 713 assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 714 assert(txFrame);
<> 144:ef7eb2e8f9f7 715 assert(txFrame->length <= 8);
<> 144:ef7eb2e8f9f7 716
<> 144:ef7eb2e8f9f7 717 uint32_t cs_temp = 0;
<> 144:ef7eb2e8f9f7 718
<> 144:ef7eb2e8f9f7 719 if (FLEXCAN_IsMbOccupied(base, mbIdx))
<> 144:ef7eb2e8f9f7 720 {
<> 144:ef7eb2e8f9f7 721 assert(false);
<> 144:ef7eb2e8f9f7 722 }
<> 144:ef7eb2e8f9f7 723
<> 144:ef7eb2e8f9f7 724 /* Check if Message Buffer is available. */
<> 144:ef7eb2e8f9f7 725 if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK))
<> 144:ef7eb2e8f9f7 726 {
<> 144:ef7eb2e8f9f7 727 /* Inactive Tx Message Buffer. */
<> 144:ef7eb2e8f9f7 728 base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);
<> 144:ef7eb2e8f9f7 729
<> 144:ef7eb2e8f9f7 730 /* Fill Message ID field. */
<> 144:ef7eb2e8f9f7 731 base->MB[mbIdx].ID = txFrame->id;
<> 144:ef7eb2e8f9f7 732
<> 144:ef7eb2e8f9f7 733 /* Fill Message Format field. */
<> 144:ef7eb2e8f9f7 734 if (kFLEXCAN_FrameFormatExtend == txFrame->format)
<> 144:ef7eb2e8f9f7 735 {
<> 144:ef7eb2e8f9f7 736 cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
<> 144:ef7eb2e8f9f7 737 }
<> 144:ef7eb2e8f9f7 738
<> 144:ef7eb2e8f9f7 739 /* Fill Message Type field. */
<> 144:ef7eb2e8f9f7 740 if (kFLEXCAN_FrameTypeRemote == txFrame->type)
<> 144:ef7eb2e8f9f7 741 {
<> 144:ef7eb2e8f9f7 742 cs_temp |= CAN_CS_RTR_MASK;
<> 144:ef7eb2e8f9f7 743 }
<> 144:ef7eb2e8f9f7 744
<> 144:ef7eb2e8f9f7 745 cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(txFrame->length);
<> 144:ef7eb2e8f9f7 746
<> 144:ef7eb2e8f9f7 747 /* Load Message Payload. */
<> 144:ef7eb2e8f9f7 748 base->MB[mbIdx].WORD0 = txFrame->dataWord0;
<> 144:ef7eb2e8f9f7 749 base->MB[mbIdx].WORD1 = txFrame->dataWord1;
<> 144:ef7eb2e8f9f7 750
<> 144:ef7eb2e8f9f7 751 /* Activate Tx Message Buffer. */
<> 144:ef7eb2e8f9f7 752 base->MB[mbIdx].CS = cs_temp;
<> 144:ef7eb2e8f9f7 753
<> 144:ef7eb2e8f9f7 754 return kStatus_Success;
<> 144:ef7eb2e8f9f7 755 }
<> 144:ef7eb2e8f9f7 756 else
<> 144:ef7eb2e8f9f7 757 {
<> 144:ef7eb2e8f9f7 758 /* Tx Message Buffer is activated, return immediately. */
<> 144:ef7eb2e8f9f7 759 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 760 }
<> 144:ef7eb2e8f9f7 761 }
<> 144:ef7eb2e8f9f7 762
<> 144:ef7eb2e8f9f7 763 status_t FLEXCAN_ReadRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *rxFrame)
<> 144:ef7eb2e8f9f7 764 {
<> 144:ef7eb2e8f9f7 765 /* Assertion. */
<> 144:ef7eb2e8f9f7 766 assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 767 assert(rxFrame);
<> 144:ef7eb2e8f9f7 768
<> 144:ef7eb2e8f9f7 769 uint32_t cs_temp;
<> 144:ef7eb2e8f9f7 770 uint8_t rx_code;
<> 144:ef7eb2e8f9f7 771
<> 144:ef7eb2e8f9f7 772 if (FLEXCAN_IsMbOccupied(base, mbIdx))
<> 144:ef7eb2e8f9f7 773 {
<> 144:ef7eb2e8f9f7 774 assert(false);
<> 144:ef7eb2e8f9f7 775 }
<> 144:ef7eb2e8f9f7 776
<> 144:ef7eb2e8f9f7 777 /* Read CS field of Rx Message Buffer to lock Message Buffer. */
<> 144:ef7eb2e8f9f7 778 cs_temp = base->MB[mbIdx].CS;
<> 144:ef7eb2e8f9f7 779 /* Get Rx Message Buffer Code field. */
<> 144:ef7eb2e8f9f7 780 rx_code = (cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT;
<> 144:ef7eb2e8f9f7 781
<> 144:ef7eb2e8f9f7 782 /* Check to see if Rx Message Buffer is full. */
<> 144:ef7eb2e8f9f7 783 if ((kFLEXCAN_RxMbFull == rx_code) || (kFLEXCAN_RxMbOverrun == rx_code))
<> 144:ef7eb2e8f9f7 784 {
<> 144:ef7eb2e8f9f7 785 /* Store Message ID. */
<> 144:ef7eb2e8f9f7 786 rxFrame->id = base->MB[mbIdx].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
<> 144:ef7eb2e8f9f7 787
<> 144:ef7eb2e8f9f7 788 /* Get the message ID and format. */
<> 144:ef7eb2e8f9f7 789 rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
<> 144:ef7eb2e8f9f7 790
<> 144:ef7eb2e8f9f7 791 /* Get the message type. */
<> 144:ef7eb2e8f9f7 792 rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
<> 144:ef7eb2e8f9f7 793
<> 144:ef7eb2e8f9f7 794 /* Get the message length. */
<> 144:ef7eb2e8f9f7 795 rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
<> 144:ef7eb2e8f9f7 796
<> 144:ef7eb2e8f9f7 797 /* Store Message Payload. */
<> 144:ef7eb2e8f9f7 798 rxFrame->dataWord0 = base->MB[mbIdx].WORD0;
<> 144:ef7eb2e8f9f7 799 rxFrame->dataWord1 = base->MB[mbIdx].WORD1;
<> 144:ef7eb2e8f9f7 800
<> 144:ef7eb2e8f9f7 801 /* Read free-running timer to unlock Rx Message Buffer. */
<> 144:ef7eb2e8f9f7 802 (void)base->TIMER;
<> 144:ef7eb2e8f9f7 803
<> 144:ef7eb2e8f9f7 804 if (kFLEXCAN_RxMbFull == rx_code)
<> 144:ef7eb2e8f9f7 805 {
<> 144:ef7eb2e8f9f7 806 return kStatus_Success;
<> 144:ef7eb2e8f9f7 807 }
<> 144:ef7eb2e8f9f7 808 else
<> 144:ef7eb2e8f9f7 809 {
<> 144:ef7eb2e8f9f7 810 return kStatus_FLEXCAN_RxOverflow;
<> 144:ef7eb2e8f9f7 811 }
<> 144:ef7eb2e8f9f7 812 }
<> 144:ef7eb2e8f9f7 813 else
<> 144:ef7eb2e8f9f7 814 {
<> 144:ef7eb2e8f9f7 815 /* Read free-running timer to unlock Rx Message Buffer. */
<> 144:ef7eb2e8f9f7 816 (void)base->TIMER;
<> 144:ef7eb2e8f9f7 817
<> 144:ef7eb2e8f9f7 818 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 819 }
<> 144:ef7eb2e8f9f7 820 }
<> 144:ef7eb2e8f9f7 821
<> 144:ef7eb2e8f9f7 822 status_t FlEXCAN_ReadRxFifo(CAN_Type *base, flexcan_frame_t *rxFrame)
<> 144:ef7eb2e8f9f7 823 {
<> 144:ef7eb2e8f9f7 824 /* Assertion. */
<> 144:ef7eb2e8f9f7 825 assert(rxFrame);
<> 144:ef7eb2e8f9f7 826
<> 144:ef7eb2e8f9f7 827 uint32_t cs_temp;
<> 144:ef7eb2e8f9f7 828
<> 144:ef7eb2e8f9f7 829 /* Check if Rx FIFO is Enabled. */
<> 144:ef7eb2e8f9f7 830 if (base->MCR & CAN_MCR_RFEN_MASK)
<> 144:ef7eb2e8f9f7 831 {
<> 144:ef7eb2e8f9f7 832 /* Read CS field of Rx Message Buffer to lock Message Buffer. */
<> 144:ef7eb2e8f9f7 833 cs_temp = base->MB[0].CS;
<> 144:ef7eb2e8f9f7 834
<> 144:ef7eb2e8f9f7 835 /* Read data from Rx FIFO output port. */
<> 144:ef7eb2e8f9f7 836 /* Store Message ID. */
<> 144:ef7eb2e8f9f7 837 rxFrame->id = base->MB[0].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
<> 144:ef7eb2e8f9f7 838
<> 144:ef7eb2e8f9f7 839 /* Get the message ID and format. */
<> 144:ef7eb2e8f9f7 840 rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
<> 144:ef7eb2e8f9f7 841
<> 144:ef7eb2e8f9f7 842 /* Get the message type. */
<> 144:ef7eb2e8f9f7 843 rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
<> 144:ef7eb2e8f9f7 844
<> 144:ef7eb2e8f9f7 845 /* Get the message length. */
<> 144:ef7eb2e8f9f7 846 rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
<> 144:ef7eb2e8f9f7 847
<> 144:ef7eb2e8f9f7 848 /* Store Message Payload. */
<> 144:ef7eb2e8f9f7 849 rxFrame->dataWord0 = base->MB[0].WORD0;
<> 144:ef7eb2e8f9f7 850 rxFrame->dataWord1 = base->MB[0].WORD1;
<> 144:ef7eb2e8f9f7 851
<> 144:ef7eb2e8f9f7 852 /* Store ID Filter Hit Index. */
<> 144:ef7eb2e8f9f7 853 rxFrame->idhit = (uint8_t)(base->RXFIR & CAN_RXFIR_IDHIT_MASK);
<> 144:ef7eb2e8f9f7 854
<> 144:ef7eb2e8f9f7 855 /* Read free-running timer to unlock Rx Message Buffer. */
<> 144:ef7eb2e8f9f7 856 (void)base->TIMER;
<> 144:ef7eb2e8f9f7 857
<> 144:ef7eb2e8f9f7 858 return kStatus_Success;
<> 144:ef7eb2e8f9f7 859 }
<> 144:ef7eb2e8f9f7 860 else
<> 144:ef7eb2e8f9f7 861 {
<> 144:ef7eb2e8f9f7 862 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 863 }
<> 144:ef7eb2e8f9f7 864 }
<> 144:ef7eb2e8f9f7 865
<> 144:ef7eb2e8f9f7 866 status_t FlEXCAN_TransferSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *txFrame)
<> 144:ef7eb2e8f9f7 867 {
<> 144:ef7eb2e8f9f7 868 /* Write Tx Message Buffer to initiate a data sending. */
<> 144:ef7eb2e8f9f7 869 if (kStatus_Success == FLEXCAN_WriteTxMb(base, mbIdx, txFrame))
<> 144:ef7eb2e8f9f7 870 {
<> 144:ef7eb2e8f9f7 871 /* Wait until CAN Message send out. */
<> 144:ef7eb2e8f9f7 872 while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
<> 144:ef7eb2e8f9f7 873 {
<> 144:ef7eb2e8f9f7 874 }
<> 144:ef7eb2e8f9f7 875
<> 144:ef7eb2e8f9f7 876 /* Clean Tx Message Buffer Flag. */
<> 144:ef7eb2e8f9f7 877 FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
<> 144:ef7eb2e8f9f7 878
<> 144:ef7eb2e8f9f7 879 return kStatus_Success;
<> 144:ef7eb2e8f9f7 880 }
<> 144:ef7eb2e8f9f7 881 else
<> 144:ef7eb2e8f9f7 882 {
<> 144:ef7eb2e8f9f7 883 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 884 }
<> 144:ef7eb2e8f9f7 885 }
<> 144:ef7eb2e8f9f7 886
<> 144:ef7eb2e8f9f7 887 status_t FlEXCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *rxFrame)
<> 144:ef7eb2e8f9f7 888 {
<> 144:ef7eb2e8f9f7 889 /* Wait until Rx Message Buffer non-empty. */
<> 144:ef7eb2e8f9f7 890 while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
<> 144:ef7eb2e8f9f7 891 {
<> 144:ef7eb2e8f9f7 892 }
<> 144:ef7eb2e8f9f7 893
<> 144:ef7eb2e8f9f7 894 /* Clean Rx Message Buffer Flag. */
<> 144:ef7eb2e8f9f7 895 FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
<> 144:ef7eb2e8f9f7 896
<> 144:ef7eb2e8f9f7 897 /* Read Received CAN Message. */
<> 144:ef7eb2e8f9f7 898 return FLEXCAN_ReadRxMb(base, mbIdx, rxFrame);
<> 144:ef7eb2e8f9f7 899 }
<> 144:ef7eb2e8f9f7 900
<> 144:ef7eb2e8f9f7 901 status_t FlEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *rxFrame)
<> 144:ef7eb2e8f9f7 902 {
<> 144:ef7eb2e8f9f7 903 status_t rxFifoStatus;
<> 144:ef7eb2e8f9f7 904
<> 144:ef7eb2e8f9f7 905 /* Wait until Rx FIFO non-empty. */
<> 144:ef7eb2e8f9f7 906 while (!FLEXCAN_GetMbStatusFlags(base, kFLEXCAN_RxFifoFrameAvlFlag))
<> 144:ef7eb2e8f9f7 907 {
<> 144:ef7eb2e8f9f7 908 }
<> 144:ef7eb2e8f9f7 909
<> 144:ef7eb2e8f9f7 910 /* */
<> 144:ef7eb2e8f9f7 911 rxFifoStatus = FlEXCAN_ReadRxFifo(base, rxFrame);
<> 144:ef7eb2e8f9f7 912
<> 144:ef7eb2e8f9f7 913 /* Clean Rx Fifo available flag. */
<> 144:ef7eb2e8f9f7 914 FLEXCAN_ClearMbStatusFlags(base, kFLEXCAN_RxFifoFrameAvlFlag);
<> 144:ef7eb2e8f9f7 915
<> 144:ef7eb2e8f9f7 916 return rxFifoStatus;
<> 144:ef7eb2e8f9f7 917 }
<> 144:ef7eb2e8f9f7 918
<> 144:ef7eb2e8f9f7 919 void FLEXCAN_TransferCreateHandle(CAN_Type *base,
<> 144:ef7eb2e8f9f7 920 flexcan_handle_t *handle,
<> 144:ef7eb2e8f9f7 921 flexcan_transfer_callback_t callback,
<> 144:ef7eb2e8f9f7 922 void *userData)
<> 144:ef7eb2e8f9f7 923 {
<> 144:ef7eb2e8f9f7 924 assert(handle);
<> 144:ef7eb2e8f9f7 925
<> 144:ef7eb2e8f9f7 926 uint8_t instance;
<> 144:ef7eb2e8f9f7 927
<> 144:ef7eb2e8f9f7 928 /* Clean FlexCAN transfer handle. */
<> 144:ef7eb2e8f9f7 929 memset(handle, 0, sizeof(*handle));
<> 144:ef7eb2e8f9f7 930
<> 144:ef7eb2e8f9f7 931 /* Get instance from peripheral base address. */
<> 144:ef7eb2e8f9f7 932 instance = FLEXCAN_GetInstance(base);
<> 144:ef7eb2e8f9f7 933
<> 144:ef7eb2e8f9f7 934 /* Save the context in global variables to support the double weak mechanism. */
<> 144:ef7eb2e8f9f7 935 s_flexcanHandle[instance] = handle;
<> 144:ef7eb2e8f9f7 936
<> 144:ef7eb2e8f9f7 937 /* Register Callback function. */
<> 144:ef7eb2e8f9f7 938 handle->callback = callback;
<> 144:ef7eb2e8f9f7 939 handle->userData = userData;
<> 144:ef7eb2e8f9f7 940
<> 144:ef7eb2e8f9f7 941 /* We Enable Error & Status interrupt here, because this interrupt just
<> 144:ef7eb2e8f9f7 942 * report current status of FlexCAN module through Callback function.
<> 144:ef7eb2e8f9f7 943 * It is insignificance without a available callback function.
<> 144:ef7eb2e8f9f7 944 */
<> 144:ef7eb2e8f9f7 945 if (handle->callback != NULL)
<> 144:ef7eb2e8f9f7 946 {
<> 144:ef7eb2e8f9f7 947 FLEXCAN_EnableInterrupts(base, kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable |
<> 144:ef7eb2e8f9f7 948 kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable |
<> 144:ef7eb2e8f9f7 949 kFLEXCAN_WakeUpInterruptEnable);
<> 144:ef7eb2e8f9f7 950 }
<> 144:ef7eb2e8f9f7 951 else
<> 144:ef7eb2e8f9f7 952 {
<> 144:ef7eb2e8f9f7 953 FLEXCAN_DisableInterrupts(base, kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable |
<> 144:ef7eb2e8f9f7 954 kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable |
<> 144:ef7eb2e8f9f7 955 kFLEXCAN_WakeUpInterruptEnable);
<> 144:ef7eb2e8f9f7 956 }
<> 144:ef7eb2e8f9f7 957
<> 144:ef7eb2e8f9f7 958 /* Enable interrupts in NVIC. */
<> 144:ef7eb2e8f9f7 959 EnableIRQ((IRQn_Type)(s_flexcanRxWarningIRQ[instance]));
<> 144:ef7eb2e8f9f7 960 EnableIRQ((IRQn_Type)(s_flexcanTxWarningIRQ[instance]));
<> 144:ef7eb2e8f9f7 961 EnableIRQ((IRQn_Type)(s_flexcanWakeUpIRQ[instance]));
<> 144:ef7eb2e8f9f7 962 EnableIRQ((IRQn_Type)(s_flexcanErrorIRQ[instance]));
<> 144:ef7eb2e8f9f7 963 EnableIRQ((IRQn_Type)(s_flexcanBusOffIRQ[instance]));
<> 144:ef7eb2e8f9f7 964 EnableIRQ((IRQn_Type)(s_flexcanMbIRQ[instance]));
<> 144:ef7eb2e8f9f7 965 }
<> 144:ef7eb2e8f9f7 966
<> 144:ef7eb2e8f9f7 967 status_t FLEXCAN_TransferSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
<> 144:ef7eb2e8f9f7 968 {
<> 144:ef7eb2e8f9f7 969 /* Assertion. */
<> 144:ef7eb2e8f9f7 970 assert(handle);
<> 144:ef7eb2e8f9f7 971 assert(xfer);
<> 144:ef7eb2e8f9f7 972 assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 973
<> 144:ef7eb2e8f9f7 974 if (FLEXCAN_IsMbOccupied(base, xfer->mbIdx))
<> 144:ef7eb2e8f9f7 975 {
<> 144:ef7eb2e8f9f7 976 assert(false);
<> 144:ef7eb2e8f9f7 977 }
<> 144:ef7eb2e8f9f7 978
<> 144:ef7eb2e8f9f7 979 /* Check if Message Buffer is idle. */
<> 144:ef7eb2e8f9f7 980 if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
<> 144:ef7eb2e8f9f7 981 {
<> 144:ef7eb2e8f9f7 982 /* Distinguish transmit type. */
<> 144:ef7eb2e8f9f7 983 if (kFLEXCAN_FrameTypeRemote == xfer->frame->type)
<> 144:ef7eb2e8f9f7 984 {
<> 144:ef7eb2e8f9f7 985 handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxRemote;
<> 144:ef7eb2e8f9f7 986
<> 144:ef7eb2e8f9f7 987 /* Register user Frame buffer to receive remote Frame. */
<> 144:ef7eb2e8f9f7 988 handle->mbFrameBuf[xfer->mbIdx] = xfer->frame;
<> 144:ef7eb2e8f9f7 989 }
<> 144:ef7eb2e8f9f7 990 else
<> 144:ef7eb2e8f9f7 991 {
<> 144:ef7eb2e8f9f7 992 handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxData;
<> 144:ef7eb2e8f9f7 993 }
<> 144:ef7eb2e8f9f7 994
<> 144:ef7eb2e8f9f7 995 if (kStatus_Success == FLEXCAN_WriteTxMb(base, xfer->mbIdx, xfer->frame))
<> 144:ef7eb2e8f9f7 996 {
<> 144:ef7eb2e8f9f7 997 /* Enable Message Buffer Interrupt. */
<> 144:ef7eb2e8f9f7 998 FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
<> 144:ef7eb2e8f9f7 999
<> 144:ef7eb2e8f9f7 1000 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1001 }
<> 144:ef7eb2e8f9f7 1002 else
<> 144:ef7eb2e8f9f7 1003 {
<> 144:ef7eb2e8f9f7 1004 handle->mbState[xfer->mbIdx] = kFLEXCAN_StateIdle;
<> 144:ef7eb2e8f9f7 1005 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 1006 }
<> 144:ef7eb2e8f9f7 1007 }
<> 144:ef7eb2e8f9f7 1008 else
<> 144:ef7eb2e8f9f7 1009 {
<> 144:ef7eb2e8f9f7 1010 return kStatus_FLEXCAN_TxBusy;
<> 144:ef7eb2e8f9f7 1011 }
<> 144:ef7eb2e8f9f7 1012 }
<> 144:ef7eb2e8f9f7 1013
<> 144:ef7eb2e8f9f7 1014 status_t FLEXCAN_TransferReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
<> 144:ef7eb2e8f9f7 1015 {
<> 144:ef7eb2e8f9f7 1016 /* Assertion. */
<> 144:ef7eb2e8f9f7 1017 assert(handle);
<> 144:ef7eb2e8f9f7 1018 assert(xfer);
<> 144:ef7eb2e8f9f7 1019 assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 1020
<> 144:ef7eb2e8f9f7 1021 if (FLEXCAN_IsMbOccupied(base, xfer->mbIdx))
<> 144:ef7eb2e8f9f7 1022 {
<> 144:ef7eb2e8f9f7 1023 assert(false);
<> 144:ef7eb2e8f9f7 1024 }
<> 144:ef7eb2e8f9f7 1025
<> 144:ef7eb2e8f9f7 1026 /* Check if Message Buffer is idle. */
<> 144:ef7eb2e8f9f7 1027 if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
<> 144:ef7eb2e8f9f7 1028 {
<> 144:ef7eb2e8f9f7 1029 handle->mbState[xfer->mbIdx] = kFLEXCAN_StateRxData;
<> 144:ef7eb2e8f9f7 1030
<> 144:ef7eb2e8f9f7 1031 /* Register Message Buffer. */
<> 144:ef7eb2e8f9f7 1032 handle->mbFrameBuf[xfer->mbIdx] = xfer->frame;
<> 144:ef7eb2e8f9f7 1033
<> 144:ef7eb2e8f9f7 1034 /* Enable Message Buffer Interrupt. */
<> 144:ef7eb2e8f9f7 1035 FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
<> 144:ef7eb2e8f9f7 1036
<> 144:ef7eb2e8f9f7 1037 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1038 }
<> 144:ef7eb2e8f9f7 1039 else
<> 144:ef7eb2e8f9f7 1040 {
<> 144:ef7eb2e8f9f7 1041 return kStatus_FLEXCAN_RxBusy;
<> 144:ef7eb2e8f9f7 1042 }
<> 144:ef7eb2e8f9f7 1043 }
<> 144:ef7eb2e8f9f7 1044
<> 144:ef7eb2e8f9f7 1045 status_t FLEXCAN_TransferReceiveFifoNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_fifo_transfer_t *xfer)
<> 144:ef7eb2e8f9f7 1046 {
<> 144:ef7eb2e8f9f7 1047 /* Assertion. */
<> 144:ef7eb2e8f9f7 1048 assert(handle);
<> 144:ef7eb2e8f9f7 1049 assert(xfer);
<> 144:ef7eb2e8f9f7 1050
<> 144:ef7eb2e8f9f7 1051 /* Check if Message Buffer is idle. */
<> 144:ef7eb2e8f9f7 1052 if (kFLEXCAN_StateIdle == handle->rxFifoState)
<> 144:ef7eb2e8f9f7 1053 {
<> 144:ef7eb2e8f9f7 1054 handle->rxFifoState = kFLEXCAN_StateRxFifo;
<> 144:ef7eb2e8f9f7 1055
<> 144:ef7eb2e8f9f7 1056 /* Register Message Buffer. */
<> 144:ef7eb2e8f9f7 1057 handle->rxFifoFrameBuf = xfer->frame;
<> 144:ef7eb2e8f9f7 1058
<> 144:ef7eb2e8f9f7 1059 /* Enable Message Buffer Interrupt. */
<> 144:ef7eb2e8f9f7 1060 FLEXCAN_EnableMbInterrupts(
<> 144:ef7eb2e8f9f7 1061 base, kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag);
<> 144:ef7eb2e8f9f7 1062
<> 144:ef7eb2e8f9f7 1063 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1064 }
<> 144:ef7eb2e8f9f7 1065 else
<> 144:ef7eb2e8f9f7 1066 {
<> 144:ef7eb2e8f9f7 1067 return kStatus_FLEXCAN_RxFifoBusy;
<> 144:ef7eb2e8f9f7 1068 }
<> 144:ef7eb2e8f9f7 1069 }
<> 144:ef7eb2e8f9f7 1070
<> 144:ef7eb2e8f9f7 1071 void FLEXCAN_TransferAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
<> 144:ef7eb2e8f9f7 1072 {
<> 144:ef7eb2e8f9f7 1073 /* Assertion. */
<> 144:ef7eb2e8f9f7 1074 assert(handle);
<> 144:ef7eb2e8f9f7 1075 assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 1076
<> 144:ef7eb2e8f9f7 1077 if (FLEXCAN_IsMbOccupied(base, mbIdx))
<> 144:ef7eb2e8f9f7 1078 {
<> 144:ef7eb2e8f9f7 1079 assert(false);
<> 144:ef7eb2e8f9f7 1080 }
<> 144:ef7eb2e8f9f7 1081
<> 144:ef7eb2e8f9f7 1082 /* Disable Message Buffer Interrupt. */
<> 144:ef7eb2e8f9f7 1083 FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
<> 144:ef7eb2e8f9f7 1084
<> 144:ef7eb2e8f9f7 1085 /* Un-register handle. */
<> 144:ef7eb2e8f9f7 1086 handle->mbFrameBuf[mbIdx] = 0x0;
<> 144:ef7eb2e8f9f7 1087
<> 144:ef7eb2e8f9f7 1088 /* Clean Message Buffer. */
<> 144:ef7eb2e8f9f7 1089 FLEXCAN_SetTxMbConfig(base, mbIdx, true);
<> 144:ef7eb2e8f9f7 1090
<> 144:ef7eb2e8f9f7 1091 handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
<> 144:ef7eb2e8f9f7 1092 }
<> 144:ef7eb2e8f9f7 1093
<> 144:ef7eb2e8f9f7 1094 void FLEXCAN_TransferAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
<> 144:ef7eb2e8f9f7 1095 {
<> 144:ef7eb2e8f9f7 1096 /* Assertion. */
<> 144:ef7eb2e8f9f7 1097 assert(handle);
<> 144:ef7eb2e8f9f7 1098 assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
<> 144:ef7eb2e8f9f7 1099
<> 144:ef7eb2e8f9f7 1100 if (FLEXCAN_IsMbOccupied(base, mbIdx))
<> 144:ef7eb2e8f9f7 1101 {
<> 144:ef7eb2e8f9f7 1102 assert(false);
<> 144:ef7eb2e8f9f7 1103 }
<> 144:ef7eb2e8f9f7 1104
<> 144:ef7eb2e8f9f7 1105 /* Disable Message Buffer Interrupt. */
<> 144:ef7eb2e8f9f7 1106 FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
<> 144:ef7eb2e8f9f7 1107
<> 144:ef7eb2e8f9f7 1108 /* Un-register handle. */
<> 144:ef7eb2e8f9f7 1109 handle->mbFrameBuf[mbIdx] = 0x0;
<> 144:ef7eb2e8f9f7 1110 handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
<> 144:ef7eb2e8f9f7 1111 }
<> 144:ef7eb2e8f9f7 1112
<> 144:ef7eb2e8f9f7 1113 void FLEXCAN_TransferAbortReceiveFifo(CAN_Type *base, flexcan_handle_t *handle)
<> 144:ef7eb2e8f9f7 1114 {
<> 144:ef7eb2e8f9f7 1115 /* Assertion. */
<> 144:ef7eb2e8f9f7 1116 assert(handle);
<> 144:ef7eb2e8f9f7 1117
<> 144:ef7eb2e8f9f7 1118 /* Check if Rx FIFO is enabled. */
<> 144:ef7eb2e8f9f7 1119 if (base->MCR & CAN_MCR_RFEN_MASK)
<> 144:ef7eb2e8f9f7 1120 {
<> 144:ef7eb2e8f9f7 1121 /* Disable Rx Message FIFO Interrupts. */
<> 144:ef7eb2e8f9f7 1122 FLEXCAN_DisableMbInterrupts(
<> 144:ef7eb2e8f9f7 1123 base, kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag);
<> 144:ef7eb2e8f9f7 1124
<> 144:ef7eb2e8f9f7 1125 /* Un-register handle. */
<> 144:ef7eb2e8f9f7 1126 handle->rxFifoFrameBuf = 0x0;
<> 144:ef7eb2e8f9f7 1127 }
<> 144:ef7eb2e8f9f7 1128
<> 144:ef7eb2e8f9f7 1129 handle->rxFifoState = kFLEXCAN_StateIdle;
<> 144:ef7eb2e8f9f7 1130 }
<> 144:ef7eb2e8f9f7 1131
<> 144:ef7eb2e8f9f7 1132 void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
<> 144:ef7eb2e8f9f7 1133 {
<> 144:ef7eb2e8f9f7 1134 /* Assertion. */
<> 144:ef7eb2e8f9f7 1135 assert(handle);
<> 144:ef7eb2e8f9f7 1136
<> 144:ef7eb2e8f9f7 1137 status_t status = kStatus_FLEXCAN_UnHandled;
<> 144:ef7eb2e8f9f7 1138 uint32_t result;
<> 144:ef7eb2e8f9f7 1139
<> 144:ef7eb2e8f9f7 1140 /* Store Current FlexCAN Module Error and Status. */
<> 144:ef7eb2e8f9f7 1141 result = base->ESR1;
<> 144:ef7eb2e8f9f7 1142
<> 144:ef7eb2e8f9f7 1143 do
<> 144:ef7eb2e8f9f7 1144 {
<> 144:ef7eb2e8f9f7 1145 /* Solve FlexCAN Error and Status Interrupt. */
<> 144:ef7eb2e8f9f7 1146 if (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
<> 144:ef7eb2e8f9f7 1147 kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))
<> 144:ef7eb2e8f9f7 1148 {
<> 144:ef7eb2e8f9f7 1149 status = kStatus_FLEXCAN_ErrorStatus;
<> 144:ef7eb2e8f9f7 1150
<> 144:ef7eb2e8f9f7 1151 /* Clear FlexCAN Error and Status Interrupt. */
<> 144:ef7eb2e8f9f7 1152 FLEXCAN_ClearStatusFlags(base, kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag |
<> 144:ef7eb2e8f9f7 1153 kFLEXCAN_BusOffIntFlag | kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag);
<> 144:ef7eb2e8f9f7 1154 }
<> 144:ef7eb2e8f9f7 1155 /* Solve FlexCAN Rx FIFO & Message Buffer Interrupt. */
<> 144:ef7eb2e8f9f7 1156 else
<> 144:ef7eb2e8f9f7 1157 {
<> 144:ef7eb2e8f9f7 1158 /* For this implementation, we solve the Message with lowest MB index first. */
<> 144:ef7eb2e8f9f7 1159 for (result = 0; result < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++)
<> 144:ef7eb2e8f9f7 1160 {
<> 144:ef7eb2e8f9f7 1161 /* Get the lowest unhandled Message Buffer */
<> 144:ef7eb2e8f9f7 1162 if ((FLEXCAN_GetMbStatusFlags(base, 1 << result)) && (FLEXCAN_IsMbIntEnabled(base, result)))
<> 144:ef7eb2e8f9f7 1163 {
<> 144:ef7eb2e8f9f7 1164 break;
<> 144:ef7eb2e8f9f7 1165 }
<> 144:ef7eb2e8f9f7 1166 }
<> 144:ef7eb2e8f9f7 1167
<> 144:ef7eb2e8f9f7 1168 /* Does not find Message to deal with. */
<> 144:ef7eb2e8f9f7 1169 if (result == FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))
<> 144:ef7eb2e8f9f7 1170 {
<> 144:ef7eb2e8f9f7 1171 break;
<> 144:ef7eb2e8f9f7 1172 }
<> 144:ef7eb2e8f9f7 1173
<> 144:ef7eb2e8f9f7 1174 /* Solve Rx FIFO interrupt. */
<> 144:ef7eb2e8f9f7 1175 if ((kFLEXCAN_StateIdle != handle->rxFifoState) && ((1 << result) <= kFLEXCAN_RxFifoOverflowFlag))
<> 144:ef7eb2e8f9f7 1176 {
<> 144:ef7eb2e8f9f7 1177 switch (1 << result)
<> 144:ef7eb2e8f9f7 1178 {
<> 144:ef7eb2e8f9f7 1179 case kFLEXCAN_RxFifoOverflowFlag:
<> 144:ef7eb2e8f9f7 1180 status = kStatus_FLEXCAN_RxFifoOverflow;
<> 144:ef7eb2e8f9f7 1181 break;
<> 144:ef7eb2e8f9f7 1182
<> 144:ef7eb2e8f9f7 1183 case kFLEXCAN_RxFifoWarningFlag:
<> 144:ef7eb2e8f9f7 1184 status = kStatus_FLEXCAN_RxFifoWarning;
<> 144:ef7eb2e8f9f7 1185 break;
<> 144:ef7eb2e8f9f7 1186
<> 144:ef7eb2e8f9f7 1187 case kFLEXCAN_RxFifoFrameAvlFlag:
<> 144:ef7eb2e8f9f7 1188 status = FlEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
<> 144:ef7eb2e8f9f7 1189 if (kStatus_Success == status)
<> 144:ef7eb2e8f9f7 1190 {
<> 144:ef7eb2e8f9f7 1191 status = kStatus_FLEXCAN_RxFifoIdle;
<> 144:ef7eb2e8f9f7 1192 }
<> 144:ef7eb2e8f9f7 1193 FLEXCAN_TransferAbortReceiveFifo(base, handle);
<> 144:ef7eb2e8f9f7 1194 break;
<> 144:ef7eb2e8f9f7 1195
<> 144:ef7eb2e8f9f7 1196 default:
<> 144:ef7eb2e8f9f7 1197 status = kStatus_FLEXCAN_UnHandled;
<> 144:ef7eb2e8f9f7 1198 break;
<> 144:ef7eb2e8f9f7 1199 }
<> 144:ef7eb2e8f9f7 1200 }
<> 144:ef7eb2e8f9f7 1201 else
<> 144:ef7eb2e8f9f7 1202 {
<> 144:ef7eb2e8f9f7 1203 /* Get current State of Message Buffer. */
<> 144:ef7eb2e8f9f7 1204 switch (handle->mbState[result])
<> 144:ef7eb2e8f9f7 1205 {
<> 144:ef7eb2e8f9f7 1206 /* Solve Rx Data Frame. */
<> 144:ef7eb2e8f9f7 1207 case kFLEXCAN_StateRxData:
<> 144:ef7eb2e8f9f7 1208 status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
<> 144:ef7eb2e8f9f7 1209 if (kStatus_Success == status)
<> 144:ef7eb2e8f9f7 1210 {
<> 144:ef7eb2e8f9f7 1211 status = kStatus_FLEXCAN_RxIdle;
<> 144:ef7eb2e8f9f7 1212 }
<> 144:ef7eb2e8f9f7 1213 FLEXCAN_TransferAbortReceive(base, handle, result);
<> 144:ef7eb2e8f9f7 1214 break;
<> 144:ef7eb2e8f9f7 1215
<> 144:ef7eb2e8f9f7 1216 /* Solve Rx Remote Frame. */
<> 144:ef7eb2e8f9f7 1217 case kFLEXCAN_StateRxRemote:
<> 144:ef7eb2e8f9f7 1218 status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
<> 144:ef7eb2e8f9f7 1219 if (kStatus_Success == status)
<> 144:ef7eb2e8f9f7 1220 {
<> 144:ef7eb2e8f9f7 1221 status = kStatus_FLEXCAN_RxIdle;
<> 144:ef7eb2e8f9f7 1222 }
<> 144:ef7eb2e8f9f7 1223 FLEXCAN_TransferAbortReceive(base, handle, result);
<> 144:ef7eb2e8f9f7 1224 break;
<> 144:ef7eb2e8f9f7 1225
<> 144:ef7eb2e8f9f7 1226 /* Solve Tx Data Frame. */
<> 144:ef7eb2e8f9f7 1227 case kFLEXCAN_StateTxData:
<> 144:ef7eb2e8f9f7 1228 status = kStatus_FLEXCAN_TxIdle;
<> 144:ef7eb2e8f9f7 1229 FLEXCAN_TransferAbortSend(base, handle, result);
<> 144:ef7eb2e8f9f7 1230 break;
<> 144:ef7eb2e8f9f7 1231
<> 144:ef7eb2e8f9f7 1232 /* Solve Tx Remote Frame. */
<> 144:ef7eb2e8f9f7 1233 case kFLEXCAN_StateTxRemote:
<> 144:ef7eb2e8f9f7 1234 handle->mbState[result] = kFLEXCAN_StateRxRemote;
<> 144:ef7eb2e8f9f7 1235 status = kStatus_FLEXCAN_TxSwitchToRx;
<> 144:ef7eb2e8f9f7 1236 break;
<> 144:ef7eb2e8f9f7 1237
<> 144:ef7eb2e8f9f7 1238 default:
<> 144:ef7eb2e8f9f7 1239 status = kStatus_FLEXCAN_UnHandled;
<> 144:ef7eb2e8f9f7 1240 break;
<> 144:ef7eb2e8f9f7 1241 }
<> 144:ef7eb2e8f9f7 1242 }
<> 144:ef7eb2e8f9f7 1243
<> 144:ef7eb2e8f9f7 1244 /* Clear resolved Message Buffer IRQ. */
<> 144:ef7eb2e8f9f7 1245 FLEXCAN_ClearMbStatusFlags(base, 1 << result);
<> 144:ef7eb2e8f9f7 1246 }
<> 144:ef7eb2e8f9f7 1247
<> 144:ef7eb2e8f9f7 1248 /* Calling Callback Function if has one. */
<> 144:ef7eb2e8f9f7 1249 if (handle->callback != NULL)
<> 144:ef7eb2e8f9f7 1250 {
<> 144:ef7eb2e8f9f7 1251 handle->callback(base, handle, status, result, handle->userData);
<> 144:ef7eb2e8f9f7 1252 }
<> 144:ef7eb2e8f9f7 1253
<> 144:ef7eb2e8f9f7 1254 /* Reset return status */
<> 144:ef7eb2e8f9f7 1255 status = kStatus_FLEXCAN_UnHandled;
<> 144:ef7eb2e8f9f7 1256
<> 144:ef7eb2e8f9f7 1257 /* Store Current FlexCAN Module Error and Status. */
<> 144:ef7eb2e8f9f7 1258 result = base->ESR1;
<> 144:ef7eb2e8f9f7 1259 }
<> 144:ef7eb2e8f9f7 1260 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
<> 144:ef7eb2e8f9f7 1261 while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFFFFFFFFFU)) ||
<> 144:ef7eb2e8f9f7 1262 (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
<> 144:ef7eb2e8f9f7 1263 kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))));
<> 144:ef7eb2e8f9f7 1264 #else
<> 144:ef7eb2e8f9f7 1265 while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFU)) ||
<> 144:ef7eb2e8f9f7 1266 (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
<> 144:ef7eb2e8f9f7 1267 kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))));
<> 144:ef7eb2e8f9f7 1268 #endif
<> 144:ef7eb2e8f9f7 1269 }
<> 144:ef7eb2e8f9f7 1270
<> 144:ef7eb2e8f9f7 1271 #if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 0)
<> 144:ef7eb2e8f9f7 1272 void CAN0_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1273 {
<> 144:ef7eb2e8f9f7 1274 assert(s_flexcanHandle[0]);
<> 144:ef7eb2e8f9f7 1275
<> 144:ef7eb2e8f9f7 1276 FLEXCAN_TransferHandleIRQ(CAN0, s_flexcanHandle[0]);
<> 144:ef7eb2e8f9f7 1277 }
<> 144:ef7eb2e8f9f7 1278 #endif
<> 144:ef7eb2e8f9f7 1279
<> 144:ef7eb2e8f9f7 1280 #if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 1)
<> 144:ef7eb2e8f9f7 1281 void CAN1_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1282 {
<> 144:ef7eb2e8f9f7 1283 assert(s_flexcanHandle[1]);
<> 144:ef7eb2e8f9f7 1284
<> 144:ef7eb2e8f9f7 1285 FLEXCAN_TransferHandleIRQ(CAN1, s_flexcanHandle[1]);
<> 144:ef7eb2e8f9f7 1286 }
<> 144:ef7eb2e8f9f7 1287 #endif
<> 144:ef7eb2e8f9f7 1288
<> 144:ef7eb2e8f9f7 1289 #if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 2)
<> 144:ef7eb2e8f9f7 1290 void CAN2_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1291 {
<> 144:ef7eb2e8f9f7 1292 assert(s_flexcanHandle[2]);
<> 144:ef7eb2e8f9f7 1293
<> 144:ef7eb2e8f9f7 1294 FLEXCAN_TransferHandleIRQ(CAN2, s_flexcanHandle[2]);
<> 144:ef7eb2e8f9f7 1295 }
<> 144:ef7eb2e8f9f7 1296 #endif
<> 144:ef7eb2e8f9f7 1297
<> 144:ef7eb2e8f9f7 1298 #if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 3)
<> 144:ef7eb2e8f9f7 1299 void CAN3_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1300 {
<> 144:ef7eb2e8f9f7 1301 assert(s_flexcanHandle[3]);
<> 144:ef7eb2e8f9f7 1302
<> 144:ef7eb2e8f9f7 1303 FLEXCAN_TransferHandleIRQ(CAN3, s_flexcanHandle[3]);
<> 144:ef7eb2e8f9f7 1304 }
<> 144:ef7eb2e8f9f7 1305 #endif
<> 144:ef7eb2e8f9f7 1306
<> 144:ef7eb2e8f9f7 1307 #if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 4)
<> 144:ef7eb2e8f9f7 1308 void CAN4_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1309 {
<> 144:ef7eb2e8f9f7 1310 assert(s_flexcanHandle[4]);
<> 144:ef7eb2e8f9f7 1311
<> 144:ef7eb2e8f9f7 1312 FLEXCAN_TransferHandleIRQ(CAN4, s_flexcanHandle[4]);
<> 144:ef7eb2e8f9f7 1313 }
<> 144:ef7eb2e8f9f7 1314 #endif