diff options
Diffstat (limited to 'platform/drivers/src/flexcan.c')
-rw-r--r-- | platform/drivers/src/flexcan.c | 1068 |
1 files changed, 1068 insertions, 0 deletions
diff --git a/platform/drivers/src/flexcan.c b/platform/drivers/src/flexcan.c new file mode 100644 index 0000000..25177ad --- /dev/null +++ b/platform/drivers/src/flexcan.c @@ -0,0 +1,1068 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "flexcan.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT (31U) /*! format A&B RTR mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT (30U) /*! format A&B IDE mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_RTR_SHIFT (15U) /*! format B RTR-2 mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_IDE_SHIFT (14U) /*! format B IDE-2 mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK (0x3FFFFFFFU) /*! format A extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT (1U) /*! format A extended shift.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK (0x3FF80000U) /*! format A standard mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT (19U) /*! format A standard shift.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK (0x3FFFU) /*! format B extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1 (16U) /*! format B extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2 (0U) /*! format B extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK (0x7FFU) /*! format B standard mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1 (19U) /*! format B standard shift1.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2 (3U) /*! format B standard shift2.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK (0xFFU) /*! format C mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1 (24U) /*! format C shift1.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2 (16U) /*! format C shift2.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3 (8U) /*! format C shift3.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4 (0U) /*! format C shift4.*/ +#define FLEXCAN_BYTE_DATA_FIELD_MASK (0xFFU) /*! masks for byte data field.*/ +#define RxFifoFilterElementNum(x) ((x + 1) * 8) + +/******************************************************************************* + * Code + ******************************************************************************/ + +/******************************************************************************* + * FLEXCAN Freeze control function + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_EnterFreezeMode + * Description : Set FlexCAN module enter freeze mode. + * + *END**************************************************************************/ +static void FLEXCAN_EnterFreezeMode(CAN_Type* base) +{ + /* Set Freeze, Halt */ + CAN_MCR_REG(base) |= CAN_MCR_FRZ_MASK; + CAN_MCR_REG(base) |= CAN_MCR_HALT_MASK; + /* Wait for entering the freeze mode */ + while (!(CAN_MCR_REG(base) & CAN_MCR_FRZ_ACK_MASK)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_ExitFreezeMode + * Description : Set FlexCAN module exit freeze mode. + * + *END**************************************************************************/ +static void FLEXCAN_ExitFreezeMode(CAN_Type* base) +{ + /* De-assert Freeze Mode */ + CAN_MCR_REG(base) &= ~CAN_MCR_HALT_MASK; + CAN_MCR_REG(base) &= ~CAN_MCR_FRZ_MASK; + /* Wait for entering the freeze mode */ + while (CAN_MCR_REG(base) & CAN_MCR_FRZ_ACK_MASK); +} + +/******************************************************************************* + * FlexCAN Initialization and Configuration functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Init + * Description : Initialize Flexcan module with given initialize structure. + * + *END**************************************************************************/ +void FLEXCAN_Init(CAN_Type* base, flexcan_init_config_t* initConfig) +{ + assert(initConfig); + + /* Enable Flexcan module */ + FLEXCAN_Enable(base); + + /* Reset Flexcan module register content to default value */ + FLEXCAN_Deinit(base); + + /* Set maximum MessageBox numbers and + * Initialize all message buffers as inactive + */ + FLEXCAN_SetMaxMsgBufNum(base, initConfig->maxMsgBufNum); + + /* Initialize Flexcan module timing character */ + FLEXCAN_SetTiming(base, &initConfig->timing); + + /* Set desired operating mode */ + FLEXCAN_SetOperatingMode(base, initConfig->operatingMode); + + /* Disable Flexcan module */ + FLEXCAN_Disable(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Deinit + * Description : This function reset Flexcan module register content to its + * default value. + * + *END**************************************************************************/ +void FLEXCAN_Deinit(CAN_Type* base) +{ + /* Reset the FLEXCAN module */ + CAN_MCR_REG(base) |= CAN_MCR_SOFT_RST_MASK; + /* Wait for reset cycle to complete */ + while (CAN_MCR_REG(base) & CAN_MCR_SOFT_RST_MASK); + + /* Assert Flexcan module Freeze */ + FLEXCAN_EnterFreezeMode(base); + + /* Reset CTRL1 Register */ + CAN_CTRL1_REG(base) = 0x0; + + /* Reset CTRL2 Register */ + CAN_CTRL2_REG(base) = 0x0; + + /* Reset Rx Individual Mask */ + for (uint8_t i=0; i < CAN_RXIMR_COUNT; i++) + CAN_RXIMR_REG(base, i) = 0x0; + + /* Reset Rx Mailboxes Global Mask */ + CAN_RXMGMASK_REG(base) = 0xFFFFFFFF; + + /* Reset Rx Buffer 14 Mask */ + CAN_RX14MASK_REG(base) = 0xFFFFFFFF; + + /* Reset Rx Buffer 15 Mask */ + CAN_RX15MASK_REG(base) = 0xFFFFFFFF; + + /* Rx FIFO Global Mask */ + CAN_RXFGMASK_REG(base) = 0xFFFFFFFF; + + /* Disable all MB interrupts */ + CAN_IMASK1_REG(base) = 0X0; + CAN_IMASK2_REG(base) = 0X0; + + // Clear all MB interrupt flags + CAN_IFLAG1_REG(base) = 0xFFFFFFFF; + CAN_IFLAG2_REG(base) = 0xFFFFFFFF; + + // Clear all Error interrupt flags + CAN_ESR1_REG(base) = 0xFFFFFFFF; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Enable + * Description : This function is used to Enable the Flexcan Module. + * + *END**************************************************************************/ +void FLEXCAN_Enable(CAN_Type* base) +{ + /* Enable clock */ + CAN_MCR_REG(base) &= ~CAN_MCR_MDIS_MASK; + /* Wait until enabled */ + while (CAN_MCR_REG(base) & CAN_MCR_LPM_ACK_MASK); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Disable + * Description : This function is used to Disable the CAN Module. + * + *END**************************************************************************/ +void FLEXCAN_Disable(CAN_Type* base) +{ + /* Disable clock*/ + CAN_MCR_REG(base) |= CAN_MCR_MDIS_MASK; + /* Wait until disabled */ + while (!(CAN_MCR_REG(base) & CAN_MCR_LPM_ACK_MASK)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetTiming + * Description : Sets the FlexCAN time segments for setting up bit rate. + * + *END**************************************************************************/ +void FLEXCAN_SetTiming(CAN_Type* base, flexcan_timing_t* timing) +{ + assert(timing); + + /* Assert Flexcan module Freeze */ + FLEXCAN_EnterFreezeMode(base); + + /* Set Flexcan module Timing Character */ + CAN_CTRL1_REG(base) &= ~(CAN_CTRL1_PRESDIV_MASK | \ + CAN_CTRL1_RJW_MASK | \ + CAN_CTRL1_PSEG1_MASK | \ + CAN_CTRL1_PSEG2_MASK | \ + CAN_CTRL1_PROP_SEG_MASK); + CAN_CTRL1_REG(base) |= (CAN_CTRL1_PRESDIV(timing->preDiv) | \ + CAN_CTRL1_RJW(timing->rJumpwidth) | \ + CAN_CTRL1_PSEG1(timing->phaseSeg1) | \ + CAN_CTRL1_PSEG2(timing->phaseSeg2) | \ + CAN_CTRL1_PROP_SEG(timing->propSeg)); + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetOperatingMode + * Description : Set operation mode. + * + *END**************************************************************************/ +void FLEXCAN_SetOperatingMode(CAN_Type* base, uint8_t mode) +{ + assert((mode & flexCanNormalMode) || + (mode & flexcanListenOnlyMode) || + (mode & flexcanLoopBackMode)); + + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (mode & flexCanNormalMode) + CAN_MCR_REG(base) &= ~CAN_MCR_SUPV_MASK; + else + CAN_MCR_REG(base) |= CAN_MCR_SUPV_MASK; + + if (mode & flexcanListenOnlyMode) + CAN_CTRL1_REG(base) |= CAN_CTRL1_LOM_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_LOM_MASK; + + if (mode & flexcanLoopBackMode) + CAN_CTRL1_REG(base) |= CAN_CTRL1_LPB_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_LPB_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetMaxMsgBufNum + * Description : Set the maximum number of Message Buffers. + * + *END**************************************************************************/ +void FLEXCAN_SetMaxMsgBufNum(CAN_Type* base, uint32_t bufNum) +{ + assert((bufNum <= CAN_CS_COUNT) && (bufNum > 0)); + + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Set the maximum number of MBs*/ + CAN_MCR_REG(base) = (CAN_MCR_REG(base) & (~CAN_MCR_MAXMB_MASK)) | CAN_MCR_MAXMB(bufNum-1); + + /* Clean MBs content to default value */ + for (uint8_t i = 0; i < bufNum; i++) + { + base->MB[i].CS = 0x0; + base->MB[i].ID = 0x0; + base->MB[i].WORD0 = 0x0; + base->MB[i].WORD1 = 0x0; + } + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetAbortCmd + * Description : Set the Transmit abort feature enablement. + * + *END**************************************************************************/ +void FLEXCAN_SetAbortCmd(CAN_Type* base, bool enable) +{ + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_MCR_REG(base) |= CAN_MCR_AEN_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_AEN_MASK; + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetLocalPrioCmd + * Description : Set the local transmit priority enablement. + * + *END**************************************************************************/ +void FLEXCAN_SetLocalPrioCmd(CAN_Type* base, bool enable) +{ + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + { + CAN_MCR_REG(base) |= CAN_MCR_LPRIO_EN_MASK; + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_LBUF_MASK; + } + else + { + CAN_CTRL1_REG(base) |= CAN_CTRL1_LBUF_MASK; + CAN_MCR_REG(base) &= ~CAN_MCR_LPRIO_EN_MASK; + } + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetMatchPrioCmd + * Description : Set the Rx matching process priority. + * + *END**************************************************************************/ +void FLEXCAN_SetMatchPrioCmd(CAN_Type* base, bool priority) +{ + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (priority) + CAN_CTRL2_REG(base) |= CAN_CTRL2_MRP_MASK; + else + CAN_CTRL2_REG(base) &= ~CAN_CTRL2_MRP_MASK; + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/******************************************************************************* + * FlexCAN Message buffer control functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetMsgBufPtr + * Description : Get message buffer pointer for transition. + * + *END**************************************************************************/ +flexcan_msgbuf_t* FLEXCAN_GetMsgBufPtr(CAN_Type* base, uint8_t msgBufIdx) +{ + assert(msgBufIdx < CAN_CS_COUNT); + + return (flexcan_msgbuf_t*) &base->MB[msgBufIdx]; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_LockRxMsgBuf + * Description : Locks the FlexCAN Rx message buffer. + * + *END**************************************************************************/ +bool FLEXCAN_LockRxMsgBuf(CAN_Type* base, uint8_t msgBufIdx) +{ + volatile uint32_t temp; + + /* Check if the MB to be Locked is enabled */ + if (msgBufIdx > (CAN_MCR_REG(base) & CAN_MCR_MAXMB_MASK)) + return false; + + /* ARM Core read MB's CS to lock MB */ + temp = base->MB[msgBufIdx].CS; + + /* Read temp itself to avoid ARMGCC warning */ + temp++; + + return true; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_UnlockAllRxMsgBuf + * Description : Unlocks the FlexCAN Rx message buffer. + * + *END**************************************************************************/ +uint16_t FLEXCAN_UnlockAllRxMsgBuf(CAN_Type* base) +{ + /* Read Free Running Timer to unlock all MessageBox */ + return CAN_TIMER_REG(base); +} + +/******************************************************************************* + * FlexCAN Interrupts and flags management functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetMsgBufIntCmd + * Description : Enables/Disables the FlexCAN Message Buffer interrupt. + * + *END**************************************************************************/ +void FLEXCAN_SetMsgBufIntCmd(CAN_Type* base, uint8_t msgBufIdx, bool enable) +{ + volatile uint32_t* interruptMaskPtr; + uint8_t index; + + assert(msgBufIdx < CAN_CS_COUNT); + + if (msgBufIdx > 0x31) + { + index = msgBufIdx - 32; + interruptMaskPtr = &base->IMASK2; + } + else + { + index = msgBufIdx; + interruptMaskPtr = &base->IMASK1; + } + + if (enable) + *interruptMaskPtr |= 0x1 << index; + else + *interruptMaskPtr &= ~(0x1 << index); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetMsgBufStatusFlag + * Description : Gets the individual FlexCAN MB interrupt flag. + * + *END**************************************************************************/ +bool FLEXCAN_GetMsgBufStatusFlag(CAN_Type* base, uint8_t msgBufIdx) +{ + volatile uint32_t* interruptFlagPtr; + volatile uint8_t index; + + assert(msgBufIdx < CAN_CS_COUNT); + + if (msgBufIdx > 0x31) + { + index = msgBufIdx - 32; + interruptFlagPtr = &base->IFLAG2; + } + else + { + index = msgBufIdx; + interruptFlagPtr = &base->IFLAG1; + } + + return (bool)((*interruptFlagPtr >> index) & 0x1); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_ClearMsgBufStatusFlag + * Description : Clears the interrupt flag of the message buffers. + * + *END**************************************************************************/ +void FLEXCAN_ClearMsgBufStatusFlag(CAN_Type* base, uint32_t msgBufIdx) +{ + volatile uint8_t index; + + assert(msgBufIdx < CAN_CS_COUNT); + + if (msgBufIdx > 0x31) + index = msgBufIdx - 32; + else + index = msgBufIdx; + + /* The Interrupt flag must be cleared by writing it to '1'. + * Writing '0' has no effect. + */ + base->IFLAG1 = 0x1 << index; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetErrIntCmd + * Description : Enables error interrupt of the FlexCAN module. + * + *END**************************************************************************/ +void FLEXCAN_SetErrIntCmd(CAN_Type* base, uint32_t errorType, bool enable) +{ + assert((errorType & flexcanIntRxWarning) || + (errorType & flexcanIntTxWarning) || + (errorType & flexcanIntWakeUp) || + (errorType & flexcanIntBusOff) || + (errorType & flexcanIntError)); + + if (enable) + { + if (errorType & flexcanIntRxWarning) + { + CAN_MCR_REG(base) |= CAN_MCR_WRN_EN_MASK; + CAN_CTRL1_REG(base) |= CAN_CTRL1_RWRN_MSK_MASK; + } + + if (errorType & flexcanIntTxWarning) + { + CAN_MCR_REG(base) |= CAN_MCR_WRN_EN_MASK; + CAN_CTRL1_REG(base) |= CAN_CTRL1_TWRN_MSK_MASK; + } + + if (errorType & flexcanIntWakeUp) + CAN_MCR_REG(base) |= CAN_MCR_WAK_MSK_MASK; + + if (errorType & flexcanIntBusOff) + CAN_CTRL1_REG(base) |= CAN_CTRL1_BOFF_MSK_MASK; + + if (errorType & flexcanIntError) + CAN_CTRL1_REG(base) |= CAN_CTRL1_ERR_MSK_MASK; + } + else + { + if (errorType & flexcanIntRxWarning) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_RWRN_MSK_MASK; + + if (errorType & flexcanIntTxWarning) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_TWRN_MSK_MASK; + + if (errorType & flexcanIntWakeUp) + CAN_MCR_REG(base) &= ~CAN_MCR_WAK_MSK_MASK; + + if (errorType & flexcanIntBusOff) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_BOFF_MSK_MASK; + + if (errorType & flexcanIntError) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_ERR_MSK_MASK; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetErrStatusFlag + * Description : Gets the FlexCAN module interrupt flag. + * + *END**************************************************************************/ +uint32_t FLEXCAN_GetErrStatusFlag(CAN_Type* base, uint32_t errFlags) +{ + return CAN_ESR1_REG(base) & errFlags; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_ClearErrStatusFlag + * Description : Clears the interrupt flag of the FlexCAN module. + * + *END**************************************************************************/ +void FLEXCAN_ClearErrStatusFlag(CAN_Type* base, uint32_t errorType) +{ + /* The Interrupt flag must be cleared by writing it to '1'. + * Writing '0' has no effect. + */ + CAN_ESR1_REG(base) = errorType; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetErrCounter + * Description : Get the error counter of FlexCAN module. + * + *END**************************************************************************/ +void FLEXCAN_GetErrCounter(CAN_Type* base, uint8_t* txError, uint8_t* rxError) +{ + *txError = CAN_ECR_REG(base) & CAN_ECR_Tx_Err_Counter_MASK; + *rxError = (CAN_ECR_REG(base) & CAN_ECR_Rx_Err_Counter_MASK) >> \ + CAN_ECR_Rx_Err_Counter_SHIFT; +} + +/******************************************************************************* + * Rx FIFO management functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_EnableRxFifo + * Description : Enables the Rx FIFO. + * + *END**************************************************************************/ +void FLEXCAN_EnableRxFifo(CAN_Type* base, uint8_t numOfFilters) +{ + uint8_t maxNumMb; + + assert(numOfFilters <= 0xF); + + /* Set Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Set the number of the RX FIFO filters needed*/ + CAN_CTRL2_REG(base) = (CAN_CTRL2_REG(base) & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(numOfFilters); + + /* Enable RX FIFO*/ + CAN_MCR_REG(base) |= CAN_MCR_RFEN_MASK; + + /* RX FIFO global mask*/ + CAN_RXFGMASK_REG(base) = CAN_RXFGMASK_FGM31_FGM0_MASK; + + maxNumMb = (CAN_MCR_REG(base) & CAN_MCR_MAXMB_MASK) + 1; + + for (uint8_t i = 0; i < maxNumMb; i++) + { + /* RX individual mask*/ + CAN_RXIMR_REG(base,i) = CAN_RXIMR0_RXIMR63_MI31_MI0_MASK; + } + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DisableRxFifo + * Description : Disables the Rx FIFO. + * + *END**************************************************************************/ +void FLEXCAN_DisableRxFifo(CAN_Type* base) +{ + /* Set Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Disable RX FIFO*/ + CAN_MCR_REG(base) &= ~CAN_MCR_RFEN_MASK; + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxFifoFilterNum + * Description : Set the number of the Rx FIFO filters. + * + *END**************************************************************************/ +void FLEXCAN_SetRxFifoFilterNum(CAN_Type* base, uint32_t numOfFilters) +{ + assert(numOfFilters <= 0xF); + + /* Set Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Set the number of RX FIFO ID filters*/ + CAN_CTRL2_REG(base) = (CAN_CTRL2_REG(base) & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(numOfFilters); + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxFifoFilter + * Description : Set the FlexCAN Rx FIFO fields. + * + *END**************************************************************************/ +void FLEXCAN_SetRxFifoFilter(CAN_Type* base, uint32_t idFormat, flexcan_id_table_t *idFilterTable) +{ + /* Set RX FIFO ID filter table elements*/ + uint32_t i, j, numOfFilters; + uint32_t val1 = 0, val2 = 0, val = 0; + volatile uint32_t *filterTable; + + numOfFilters = (CAN_CTRL2_REG(base) & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT; + /* Rx FIFO Ocuppied First Message Box is MB6 */ + filterTable = (volatile uint32_t *)&(base->MB[6]); + + CAN_MCR_REG(base) |= CAN_MCR_IDAM(idFormat); + + switch (idFormat) + { + case flexcanFxFifoIdElementFormatA: + /* One full ID (standard and extended) per ID Filter Table element.*/ + if (idFilterTable->isRemoteFrame) + { + val = (uint32_t)0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT; + } + if (idFilterTable->isExtendedFrame) + { + val |= 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT; + } + for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++) + { + if(idFilterTable->isExtendedFrame) + { + filterTable[i] = val + ((*(idFilterTable->idFilter + i)) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK); + }else + { + filterTable[i] = val + ((*(idFilterTable->idFilter + i)) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK); + } + } + break; + case flexcanFxFifoIdElementFormatB: + /* Two full standard IDs or two partial 14-bit (standard and extended) IDs*/ + /* per ID Filter Table element.*/ + if (idFilterTable->isRemoteFrame) + { + val1 = (uint32_t)0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT; + val2 = 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_RTR_SHIFT; + } + if (idFilterTable->isExtendedFrame) + { + val1 |= 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT; + val2 |= 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_IDE_SHIFT; + } + j = 0; + for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++) + { + if (idFilterTable->isExtendedFrame) + { + filterTable[i] = val1 + (((*(idFilterTable->idFilter + j)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1); + filterTable[i] |= val2 + (((*(idFilterTable->idFilter + j + 1)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2); + }else + { + filterTable[i] = val1 + (((*(idFilterTable->idFilter + j)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1); + filterTable[i] |= val2 + (((*(idFilterTable->idFilter + j + 1)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2); + } + j = j + 2; + } + break; + case flexcanFxFifoIdElementFormatC: + /* Four partial 8-bit Standard IDs per ID Filter Table element.*/ + j = 0; + for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++) + { + filterTable[i] = (((*(idFilterTable->idFilter + j)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1); + filterTable[i] = (((*(idFilterTable->idFilter + j + 1)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2); + filterTable[i] = (((*(idFilterTable->idFilter + j + 2)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3); + filterTable[i] = (((*(idFilterTable->idFilter + j + 3)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4); + j = j + 4; + } + break; + case flexcanFxFifoIdElementFormatD: + /* All frames rejected.*/ + break; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetRxFifoPtr + * Description : Gets the FlexCAN Rx FIFO data pointer. + * + *END**************************************************************************/ +flexcan_msgbuf_t* FLEXCAN_GetRxFifoPtr(CAN_Type* base) +{ + /* Rx-Fifo occupy MB0 ~ MB5 */ + return (flexcan_msgbuf_t*)&base->MB; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetRxFifoInfo + * Description : Set the FlexCAN RX Fifo global mask. + * + *END**************************************************************************/ +uint16_t FLEXCAN_GetRxFifoInfo(CAN_Type* base) +{ + return CAN_RXFIR_REG(base) & CAN_RXFIR_IDHIT_MASK; +} + +/******************************************************************************* + * Rx Mask Setting functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMaskMode + * Description : Set the Rx masking mode. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMaskMode(CAN_Type* base, uint32_t mode) +{ + assert((mode == flexcanRxMaskGlobal) || + (mode == flexcanRxMaskIndividual)); + + /* Assert Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (mode == flexcanRxMaskIndividual) + CAN_MCR_REG(base) |= CAN_MCR_IRMQ_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_IRMQ_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMaskRtrCmd + * Description : Set the remote trasmit request mask enablement. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMaskRtrCmd(CAN_Type* base, uint32_t enable) +{ + /* Assert Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL2_REG(base) |= CAN_CTRL2_EACEN_MASK; + else + CAN_CTRL2_REG(base) &= ~CAN_CTRL2_EACEN_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxGlobalMask + * Description : Set the FlexCAN RX global mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxGlobalMask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RXMGMASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxIndividualMask + * Description : Set the FlexCAN Rx individual mask for ID filtering in + * the Rx MBs and the Rx FIFO. + * + *END**************************************************************************/ +void FLEXCAN_SetRxIndividualMask(CAN_Type* base, uint32_t msgBufIdx, uint32_t mask) +{ + assert(msgBufIdx < CAN_RXIMR_COUNT); + + /* Assert Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + CAN_RXIMR_REG(base,msgBufIdx) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMsgBuff14Mask + * Description : Set the FlexCAN RX Message Buffer BUF14 mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMsgBuff14Mask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RX14MASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMsgBuff15Mask + * Description : Set the FlexCAN RX Message Buffer BUF15 mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMsgBuff15Mask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RX15MASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxFifoGlobalMask + * Description : Set the FlexCAN RX Fifo global mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxFifoGlobalMask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RXFGMASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/******************************************************************************* + * Misc. Functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetSelfWakeUpCmd + * Description : Enable/disable the FlexCAN self wakeup feature. + * + *END**************************************************************************/ +void FLEXCAN_SetSelfWakeUpCmd(CAN_Type* base, bool lpfEnable, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (lpfEnable) + CAN_MCR_REG(base) |= CAN_MCR_WAK_SRC_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_WAK_SRC_MASK; + + if (enable) + CAN_MCR_REG(base) |= CAN_MCR_SLF_WAK_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_SLF_WAK_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetSelfReceptionCmd + * Description : Enable/disable the FlexCAN self reception feature. + * + *END**************************************************************************/ +void FLEXCAN_SetSelfReceptionCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_MCR_REG(base) &= ~CAN_MCR_SRX_DIS_MASK; + else + CAN_MCR_REG(base) |= CAN_MCR_SRX_DIS_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxVoteCmd + * Description : Enable/disable the enhance FlexCAN Rx vote. + * + *END**************************************************************************/ +void FLEXCAN_SetRxVoteCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL1_REG(base) |= CAN_CTRL1_SMP_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_SMP_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetAutoBusOffRecoverCmd + * Description : Enable/disable the Auto Busoff recover feature. + * + *END**************************************************************************/ +void FLEXCAN_SetAutoBusOffRecoverCmd(CAN_Type* base, bool enable) +{ + if (enable) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_BOFF_MSK_MASK; + else + CAN_CTRL1_REG(base) |= CAN_CTRL1_BOFF_MSK_MASK; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetTimeSyncCmd + * Description : Enable/disable the Time Sync feature. + * + *END**************************************************************************/ +void FLEXCAN_SetTimeSyncCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL1_REG(base) |= CAN_CTRL1_TSYN_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_TSYN_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetAutoRemoteResponseCmd + * Description : Enable/disable the Auto Remote Response feature. + * + *END**************************************************************************/ +void FLEXCAN_SetAutoRemoteResponseCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL2_REG(base) &= ~CAN_CTRL2_RRS_MASK; + else + CAN_CTRL2_REG(base) |= CAN_CTRL2_RRS_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ |