added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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