summaryrefslogtreecommitdiff
path: root/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c')
-rw-r--r--tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c1845
1 files changed, 1845 insertions, 0 deletions
diff --git a/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c
new file mode 100644
index 0000000000..cf0e94d5fd
--- /dev/null
+++ b/tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c
@@ -0,0 +1,1845 @@
+/*
+ * Copyright (c) 2013 - 2014, 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 "fsl_flexcan_hal.h"
+
+#ifndef MBED_NO_FLEXCAN
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK (0x3FFFFFFFU) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format A extended mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT (1U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format A extended shift.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK (0x3FF80000U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format A standard mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT (19U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format A standard shift.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK (0x3FFFU) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format B extended mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1 (16U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format B extended mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2 (0U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format B extended mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK (0x3FF8U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format B standard mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1 (19U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format B standard shift1.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2 (3U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format B standard shift2.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK (0xFFU) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format C mask.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1 (24U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format C shift1.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2 (16U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format C shift2.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3 (8U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format C shift3.*/
+#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4 (0U) /*!< FlexCAN RX FIFO ID filter*/
+ /*! format C shift4.*/
+#define FLEXCAN_ALL_INT (0x0007U) /*!< Masks for wakeup, error, bus off*/
+ /*! interrupts*/
+#define FLEXCAN_BYTE_DATA_FIELD_MASK (0xFFU) /*!< Masks for byte data field.*/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_Enable
+ * Description : Enable FlexCAN module.
+ * This function will enable FlexCAN module clock.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_Enable(uint32_t canBaseAddr)
+{
+ /* Check for low power mode*/
+ if(BR_CAN_MCR_LPMACK(canBaseAddr))
+ {
+ /* Enable clock*/
+ HW_CAN_MCR_CLR(canBaseAddr, BM_CAN_MCR_MDIS);
+ /* Wait until enabled*/
+ while (BR_CAN_MCR_LPMACK(canBaseAddr)){}
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_Disable
+ * Description : Disable FlexCAN module.
+ * This function will disable FlexCAN module clock.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_Disable(uint32_t canBaseAddr)
+{
+ /* To access the memory mapped registers*/
+ /* Entre disable mode (hard reset).*/
+ if(BR_CAN_MCR_MDIS(canBaseAddr) == 0x0)
+ {
+ /* Clock disable (module)*/
+ BW_CAN_MCR_MDIS(canBaseAddr, 0x1);
+
+ /* Wait until disable mode acknowledged*/
+ while (!(BR_CAN_MCR_LPMACK(canBaseAddr))){}
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SelectClock
+ * Description : Select FlexCAN clock source.
+ * This function will select either internal bus clock or external clock as
+ * FlexCAN clock source.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SelectClock(
+ uint32_t canBaseAddr,
+ flexcan_clk_source_t clk)
+{
+ if (clk == kFlexCanClkSource_Ipbus)
+ {
+ /* Internal bus clock (fsys/2)*/
+ BW_CAN_CTRL1_CLKSRC(canBaseAddr, 0x1);
+ }
+ else if (clk == kFlexCanClkSource_Osc)
+ {
+ /* External clock*/
+ BW_CAN_CTRL1_CLKSRC(canBaseAddr, 0x0);
+ }
+ else
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_Init
+ * Description : Initialize FlexCAN module.
+ * This function will reset FlexCAN module, set maximum number of message
+ * buffers, initialize all message buffers as inactive, enable RX FIFO
+ * if needed, mask all mask bits, and disable all MB interrupts.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_Init(uint32_t canBaseAddr, const flexcan_user_config_t *data)
+{
+ uint32_t i;
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ assert(data);
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ /* Reset the FLEXCAN*/
+ BW_CAN_MCR_SOFTRST(canBaseAddr, 0x1);
+
+ /* Wait for reset cycle to complete*/
+ while (BR_CAN_MCR_SOFTRST(canBaseAddr)){}
+
+ /* Set Freeze, Halt*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* check for freeze Ack*/
+ while ((!BR_CAN_MCR_FRZACK(canBaseAddr)) ||
+ (!BR_CAN_MCR_NOTRDY(canBaseAddr))){}
+
+ /* Set maximum number of message buffers*/
+ BW_CAN_MCR_MAXMB(canBaseAddr, data->max_num_mb);
+
+ /* Initialize all message buffers as inactive*/
+ for (i = 0; i < data->max_num_mb; i++)
+ {
+ flexcan_reg_ptr->MB[i].CS = 0x0;
+ flexcan_reg_ptr->MB[i].ID = 0x0;
+ flexcan_reg_ptr->MB[i].WORD0 = 0x0;
+ flexcan_reg_ptr->MB[i].WORD1 = 0x0;
+ }
+
+ /* Enable RX FIFO if need*/
+ if (data->is_rx_fifo_needed)
+ {
+ /* Enable RX FIFO*/
+ BW_CAN_MCR_RFEN(canBaseAddr, 0x1);
+ /* Set the number of the RX FIFO filters needed*/
+ BW_CAN_CTRL2_RFFN(canBaseAddr, data->num_id_filters);
+ /* RX FIFO global mask*/
+ HW_CAN_RXFGMASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RXFGMASK_FGM_MASK));
+ for (i = 0; i < data->max_num_mb; i++)
+ {
+ /* RX individual mask*/
+ HW_CAN_RXIMRn_WR(canBaseAddr, i, CAN_ID_EXT(CAN_RXIMR_MI_MASK));
+ }
+ }
+
+ /* Rx global mask*/
+ HW_CAN_RXMGMASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RXMGMASK_MG_MASK));
+
+ /* Rx reg 14 mask*/
+ HW_CAN_RX14MASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RX14MASK_RX14M_MASK));
+
+ /* Rx reg 15 mask*/
+ HW_CAN_RX15MASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RX15MASK_RX15M_MASK));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while(BR_CAN_MCR_FRZACK(canBaseAddr)){}
+
+ /* Disable all MB interrupts*/
+ HW_CAN_IMASK1_WR(canBaseAddr, 0x0);
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetTimeSegments
+ * Description : Set FlexCAN time segments.
+ * This function will set all FlexCAN time segments which define the length of
+ * Propagation Segment in the bit time, the length of Phase Buffer Segment 2 in
+ * the bit time, the length of Phase Buffer Segment 1 in the bit time, the ratio
+ * between the PE clock frequency and the Serial Clock (Sclock) frequency, and
+ * the maximum number of time quanta that a bit time can be changed by one
+ * resynchronization. (One time quantum is equal to the Sclock period.)
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetTimeSegments(
+ uint32_t canBaseAddr,
+ flexcan_time_segment_t *time_seg)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while(!(BR_CAN_MCR_FRZACK(canBaseAddr))) {}
+
+ /* Set FlexCAN time segments*/
+ HW_CAN_CTRL1_CLR(canBaseAddr, (CAN_CTRL1_PROPSEG_MASK | CAN_CTRL1_PSEG2_MASK |
+ CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PRESDIV_MASK) |
+ CAN_CTRL1_RJW_MASK);
+ HW_CAN_CTRL1_SET(canBaseAddr, (CAN_CTRL1_PROPSEG(time_seg->propseg) |
+ CAN_CTRL1_PSEG2(time_seg->pseg2) |
+ CAN_CTRL1_PSEG1(time_seg->pseg1) |
+ CAN_CTRL1_PRESDIV(time_seg->pre_divider) |
+ CAN_CTRL1_RJW(time_seg->rjw)));
+
+ /* De-assert Freeze mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while(BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_GetTimeSegments
+ * Description : Get FlexCAN time segments.
+ * This function will get all FlexCAN time segments defined.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_GetTimeSegments(
+ uint32_t canBaseAddr,
+ flexcan_time_segment_t *time_seg)
+{
+ time_seg->pre_divider = BR_CAN_CTRL1_PRESDIV(canBaseAddr);
+ time_seg->propseg = BR_CAN_CTRL1_PROPSEG(canBaseAddr);
+ time_seg->pseg1 = BR_CAN_CTRL1_PSEG1(canBaseAddr);
+ time_seg->pseg2 = BR_CAN_CTRL1_PSEG2(canBaseAddr);
+ time_seg->rjw = BR_CAN_CTRL1_RJW(canBaseAddr);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetMbTx
+ * Description : Configure a message buffer for transmission.
+ * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
+ * the function will make sure if the MB requested is not occupied by RX FIFO
+ * and ID filter table. Then this function will copy user's buffer into the
+ * message buffer data area and configure the message buffer as required for
+ * transmission.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SetMbTx(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx,
+ flexcan_mb_code_status_t *cs,
+ uint32_t msg_id,
+ uint8_t *mb_data)
+{
+ uint32_t i;
+ uint32_t val1, val2 = 1, temp, temp1;
+
+ assert(data);
+
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Check if RX FIFO is enabled*/
+ if (BR_CAN_MCR_RFEN(canBaseAddr))
+ {
+ /* Get the number of RX FIFO Filters*/
+ val1 = (BR_CAN_CTRL2_RFFN(canBaseAddr));
+ /* Get the number if MBs occupied by RX FIFO and ID filter table*/
+ /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
+ /* Every number of RFFN means 8 number of RX FIFO filters*/
+ /* and every 4 number of RX FIFO filters occupied one MB*/
+ val2 = 6 + (val1 + 1) * 8 / 4;
+
+ if (mb_idx <= (val2 - 1))
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+ }
+
+ /* Copy user's buffer into the message buffer data area*/
+ if (mb_data != NULL)
+ {
+ flexcan_reg_ptr->MB[mb_idx].WORD0 = 0x0;
+ flexcan_reg_ptr->MB[mb_idx].WORD1 = 0x0;
+
+ for (i = 0; i < cs->data_length; i++ )
+ {
+ temp1 = (*(mb_data + i));
+ if (i < 4)
+ {
+ temp = temp1 << ((3 - i) * 8);
+ flexcan_reg_ptr->MB[mb_idx].WORD0 |= temp;
+ }
+ else
+ {
+ temp = temp1 << ((7 - i) * 8);
+ flexcan_reg_ptr->MB[mb_idx].WORD1 |= temp;
+ }
+ }
+ }
+
+ /* Set the ID according the format structure*/
+ if (cs->msg_id_type == kFlexCanMbId_Ext)
+ {
+ /* ID [28-0]*/
+ flexcan_reg_ptr->MB[mb_idx].ID &= ~(CAN_ID_STD_MASK | CAN_ID_EXT_MASK);
+ flexcan_reg_ptr->MB[mb_idx].ID |= (msg_id & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));
+
+ /* Set IDE*/
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_IDE_MASK;
+
+ /* Clear SRR bit*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_SRR_MASK;
+
+ /* Set the length of data in bytes*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_DLC(cs->data_length);
+
+ /* Set MB CODE*/
+ /* Reset the code*/
+ if (cs->code != kFlexCanTX_NotUsed)
+ {
+ if (cs->code == kFlexCanTX_Remote)
+ {
+ /* Set RTR bit*/
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_RTR_MASK;
+ cs->code = kFlexCanTX_Data;
+ }
+
+ /* Reset the code*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~(CAN_CS_CODE_MASK);
+
+ /* Activating message buffer*/
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
+ }
+ }
+ else if(cs->msg_id_type == kFlexCanMbId_Std)
+ {
+ /* ID[28-18]*/
+ flexcan_reg_ptr->MB[mb_idx].ID &= ~CAN_ID_STD_MASK;
+ flexcan_reg_ptr->MB[mb_idx].ID |= CAN_ID_STD(msg_id);
+
+ /* make sure IDE and SRR are not set*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~(CAN_CS_IDE_MASK | CAN_CS_SRR_MASK);
+
+ /* Set the length of data in bytes*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
+ flexcan_reg_ptr->MB[mb_idx].CS |= (cs->data_length) << CAN_CS_DLC_SHIFT;
+
+ /* Set MB CODE*/
+ if (cs->code != kFlexCanTX_NotUsed)
+ {
+ if (cs->code == kFlexCanTX_Remote)
+ {
+ /* Set RTR bit*/
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_RTR_MASK;
+ cs->code = kFlexCanTX_Data;
+ }
+
+ /* Reset the code*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_CODE_MASK;
+
+ /* Set the code*/
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
+ }
+ }
+ else
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetMbRx
+ * Description : Configure a message buffer for receiving.
+ * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
+ * the function will make sure if the MB requested is not occupied by RX FIFO
+ * and ID filter table. Then this function will configure the message buffer as
+ * required for receiving.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SetMbRx(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx,
+ flexcan_mb_code_status_t *cs,
+ uint32_t msg_id)
+{
+ uint32_t val1, val2 = 1;
+
+ assert(data);
+
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Check if RX FIFO is enabled*/
+ if (BR_CAN_MCR_RFEN(canBaseAddr))
+ {
+ /* Get the number of RX FIFO Filters*/
+ val1 = BR_CAN_CTRL2_RFFN(canBaseAddr);
+ /* Get the number if MBs occupied by RX FIFO and ID filter table*/
+ /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
+ /* Every number of RFFN means 8 number of RX FIFO filters*/
+ /* and every 4 number of RX FIFO filters occupied one MB*/
+ val2 = 6 + (val1 + 1) * 8 / 4;
+
+ if (mb_idx <= (val2 - 1))
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+ }
+
+ /* Set the ID according the format structure*/
+ if (cs->msg_id_type == kFlexCanMbId_Ext)
+ {
+ /* Set IDE*/
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_IDE_MASK;
+
+ /* Clear SRR bit*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_SRR_MASK;
+
+ /* Set the length of data in bytes*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_DLC(cs->data_length);
+
+ /* ID [28-0]*/
+ flexcan_reg_ptr->MB[mb_idx].ID &= ~(CAN_ID_STD_MASK | CAN_ID_EXT_MASK);
+ flexcan_reg_ptr->MB[mb_idx].ID |= (msg_id & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));
+
+ /* Set MB CODE*/
+ if (cs->code != kFlexCanRX_NotUsed)
+ {
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_CODE_MASK;
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
+ }
+ }
+ else if(cs->msg_id_type == kFlexCanMbId_Std)
+ {
+ /* Make sure IDE and SRR are not set*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~(CAN_CS_IDE_MASK | CAN_CS_SRR_MASK);
+
+ /* Set the length of data in bytes*/
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
+ flexcan_reg_ptr->MB[mb_idx].CS |= (cs->data_length) << CAN_CS_DLC_SHIFT;
+
+ /* ID[28-18]*/
+ flexcan_reg_ptr->MB[mb_idx].ID &= ~CAN_ID_STD_MASK;
+ flexcan_reg_ptr->MB[mb_idx].ID |= CAN_ID_STD(msg_id);
+
+ /* Set MB CODE*/
+ if (cs->code != kFlexCanRX_NotUsed)
+ {
+ flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_CODE_MASK;
+ flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
+ }
+ }
+ else
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_GetMb
+ * Description : Get a message buffer field values.
+ * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
+ * the function will make sure if the MB requested is not occupied by RX FIFO
+ * and ID filter table. Then this function will get the message buffer field
+ * values and copy the MB data field into user's buffer.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_GetMb(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx,
+ flexcan_mb_t *mb)
+{
+ uint32_t i;
+ uint32_t val1, val2 = 1;
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ assert(data);
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Check if RX FIFO is enabled*/
+ if (BR_CAN_MCR_RFEN(canBaseAddr))
+ {
+ /* Get the number of RX FIFO Filters*/
+ val1 = BR_CAN_CTRL2_RFFN(canBaseAddr);
+ /* Get the number if MBs occupied by RX FIFO and ID filter table*/
+ /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
+ /* Every number of RFFN means 8 number of RX FIFO filters*/
+ /* and every 4 number of RX FIFO filters occupied one MB*/
+ val2 = 6 + (val1 + 1) * 8 / 4;
+
+ if (mb_idx <= (val2 - 1))
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+ }
+
+ /* Get a MB field values*/
+ mb->cs = flexcan_reg_ptr->MB[mb_idx].CS;
+ if ((mb->cs) & CAN_CS_IDE_MASK)
+ {
+ mb->msg_id = flexcan_reg_ptr->MB[mb_idx].ID;
+ }
+ else
+ {
+ mb->msg_id = (flexcan_reg_ptr->MB[mb_idx].ID) >> CAN_ID_STD_SHIFT;
+ }
+
+ /* Copy MB data field into user's buffer*/
+ for (i = 0 ; i < kFlexCanMessageSize ; i++)
+ {
+ if (i < 4)
+ {
+ mb->data[3 - i] = ((flexcan_reg_ptr->MB[mb_idx].WORD0) >> (i * 8)) &
+ FLEXCAN_BYTE_DATA_FIELD_MASK;
+ }
+ else
+ {
+ mb->data[11 - i] = ((flexcan_reg_ptr->MB[mb_idx].WORD1) >> ((i - 4) * 8)) &
+ FLEXCAN_BYTE_DATA_FIELD_MASK;
+ }
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_LockRxMb
+ * Description : Lock the RX message buffer.
+ * This function will the RX message buffer.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_LockRxMb(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx)
+{
+ assert(data);
+
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Lock the mailbox*/
+ flexcan_reg_ptr->MB[mb_idx].CS;
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableRxFifo
+ * Description : Enable Rx FIFO feature.
+ * This function will enable the Rx FIFO feature.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnableRxFifo(uint32_t canBaseAddr)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* Enable RX FIFO*/
+ BW_CAN_MCR_RFEN(canBaseAddr, 0x1);
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableRxFifo
+ * Description : Disable Rx FIFO feature.
+ * This function will disable the Rx FIFO feature.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_DisableRxFifo(uint32_t canBaseAddr)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while(!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* Disable RX FIFO*/
+ BW_CAN_MCR_RFEN(canBaseAddr, 0x0);
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxFifoFiltersNumber
+ * Description : Set the number of Rx FIFO filters.
+ * This function will define the number of Rx FIFO filters.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxFifoFiltersNumber(
+ uint32_t canBaseAddr,
+ uint32_t number)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while(!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* Set the number of RX FIFO ID filters*/
+ BW_CAN_CTRL2_RFFN(canBaseAddr, number);
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetMaxMbNumber
+ * Description : Set the number of the last Message Buffers.
+ * This function will define the number of the last Message Buffers
+ *
+*END**************************************************************************/
+void FLEXCAN_HAL_SetMaxMbNumber(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data)
+{
+ assert(data);
+
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while(!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* Set the maximum number of MBs*/
+ BW_CAN_MCR_MAXMB(canBaseAddr, data->max_num_mb);
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetIdFilterTableElements
+ * Description : Set ID filter table elements.
+ * This function will set up ID filter table elements.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SetIdFilterTableElements(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ flexcan_rx_fifo_id_element_format_t id_format,
+ flexcan_id_table_t *id_filter_table)
+{
+ uint32_t i, j;
+ uint32_t val1, val2, val;
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ assert(data);
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ switch(id_format)
+ {
+ case (kFlexCanRxFifoIdElementFormat_A):
+ /* One full ID (standard and extended) per ID Filter Table element.*/
+ BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_A);
+ if (id_filter_table->is_remote_mb)
+ {
+ val = 1U << 31U;
+ }
+ if (id_filter_table->is_extended_mb)
+ {
+ val |= 1 << 30;
+ j = 0;
+ for (i = 0; i < (data->num_id_filters + 1) * 8; i += 4)
+ {
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS = val +
+ ((*(id_filter_table->id_filter + i)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID = val +
+ ((*(id_filter_table->id_filter + i + 1)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val +
+ ((*(id_filter_table->id_filter + i + 2)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val +
+ ((*(id_filter_table->id_filter + i + 3)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
+ j++;
+ }
+ }
+ else
+ {
+ j = 0;
+ for (i = 0; i < (data->num_id_filters + 1) * 8; i += 4)
+ {
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS = val +
+ ((*(id_filter_table->id_filter + i)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID = val +
+ ((*(id_filter_table->id_filter + i + 1)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val +
+ ((*(id_filter_table->id_filter + i + 2)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val +
+ ((*(id_filter_table->id_filter + i + 3)) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
+ j++;
+ }
+ }
+ break;
+ case (kFlexCanRxFifoIdElementFormat_B):
+ /* Two full standard IDs or two partial 14-bit (standard and extended) IDs*/
+ /* per ID Filter Table element.*/
+ BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_B);
+ if (id_filter_table->is_remote_mb)
+ {
+ val1 = 1U << 31U;
+ val2 = 1 << 15;
+ }
+ if (id_filter_table->is_extended_mb)
+ {
+ val1 |= 1 << 30;
+ val2 |= 1 << 14;
+ j = 0;
+ for (i = 0; i < (data->num_id_filters + 1) * 8; i += 8)
+ {
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS = val1 +
+ ((*(id_filter_table->id_filter + i)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS |= val2 +
+ ((*(id_filter_table->id_filter + i + 1)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID = val1 +
+ ((*(id_filter_table->id_filter + i + 2)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID |= val2 +
+ ((*(id_filter_table->id_filter + i + 3)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val1 +
+ ((*(id_filter_table->id_filter + i + 4)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= val2 +
+ ((*(id_filter_table->id_filter + i + 5)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val1 +
+ ((*(id_filter_table->id_filter + i + 6)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= val2 +
+ ((*(id_filter_table->id_filter + i + 7)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
+ j++;
+ }
+ }
+ else
+ {
+ j = 0;
+ for (i = 0; i < (data->num_id_filters + 1) * 8; i += 8)
+ {
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS = val1 +
+ (((*(id_filter_table->id_filter + i)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS |= val2 +
+ (((*(id_filter_table->id_filter + i + 1)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID = val1 +
+ (((*(id_filter_table->id_filter + i + 2)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID |= val2 +
+ (((*(id_filter_table->id_filter + i + 3)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val1 +
+ (((*(id_filter_table->id_filter + i + 4)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= val2 +
+ (((*(id_filter_table->id_filter + i + 5)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val1 +
+ (((*(id_filter_table->id_filter + i + 6)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= val2 +
+ (((*(id_filter_table->id_filter + i + 7)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
+ j++;
+ }
+ }
+ break;
+ case (kFlexCanRxFifoIdElementFormat_C):
+ /* Four partial 8-bit Standard IDs per ID Filter Table element.*/
+ BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_C);
+ j = 0;
+ for (i = 0; i < (data->num_id_filters + 1) * 8; i += 16)
+ {
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS = ((*(id_filter_table->id_filter + i)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS |= ((*(id_filter_table->id_filter + i + 1)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS |= ((*(id_filter_table->id_filter + i + 2)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
+ flexcan_reg_ptr->MB[6 + i - j * 3].CS |= ((*(id_filter_table->id_filter + i + 3)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID = ((*(id_filter_table->id_filter + i + 4)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID |= ((*(id_filter_table->id_filter + i + 5)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID |= ((*(id_filter_table->id_filter + i + 6)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
+ flexcan_reg_ptr->MB[6 + i - j * 3].ID |= ((*(id_filter_table->id_filter + i + 7)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = ((*(id_filter_table->id_filter + i + 8)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= ((*(id_filter_table->id_filter + i + 9)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= ((*(id_filter_table->id_filter + i + 10)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= ((*(id_filter_table->id_filter + i + 11)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
+
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = ((*(id_filter_table->id_filter + i + 12)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= ((*(id_filter_table->id_filter + i + 13)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= ((*(id_filter_table->id_filter + i + 14)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
+ flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= ((*(id_filter_table->id_filter + i + 15)) &
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
+ FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
+
+ j++;
+ }
+ break;
+ case (kFlexCanRxFifoIdElementFormat_D):
+ /* All frames rejected.*/
+ BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_D);
+ break;
+ default:
+ return kStatus_FLEXCAN_InvalidArgument;
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxFifo
+ * Description : Confgure RX FIFO ID filter table elements.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SetRxFifo(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ flexcan_rx_fifo_id_element_format_t id_format,
+ flexcan_id_table_t *id_filter_table)
+{
+ assert(data);
+
+ if (!data->is_rx_fifo_needed)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ /* Set RX FIFO ID filter table elements*/
+ return FLEXCAN_HAL_SetIdFilterTableElements(canBaseAddr, data, id_format, id_filter_table);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableMbInt
+ * Description : Enable the corresponding Message Buffer interrupt.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_EnableMbInt(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx)
+{
+ assert(data);
+ uint32_t temp;
+
+ if ( mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Enable the corresponding message buffer Interrupt*/
+ temp = 0x1 << mb_idx;
+ HW_CAN_IMASK1_SET(canBaseAddr, temp);
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableMbInt
+ * Description : Disable the corresponding Message Buffer interrupt.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_DisableMbInt(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx)
+{
+ assert(data);
+ uint32_t temp;
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Disable the corresponding message buffer Interrupt*/
+ temp = 0x1 << mb_idx;
+ HW_CAN_IMASK1_CLR(canBaseAddr, temp);
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableErrInt
+ * Description : Enable the error interrupts.
+ * This function will enable Error interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnableErrInt(uint32_t canBaseAddr)
+{
+ /* Enable Error interrupt*/
+ BW_CAN_CTRL1_ERRMSK(canBaseAddr, 0x1);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableErrorInt
+ * Description : Disable the error interrupts.
+ * This function will disable Error interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_DisableErrInt(uint32_t canBaseAddr)
+{
+ /* Disable Error interrupt*/
+ BW_CAN_CTRL1_ERRMSK(canBaseAddr, 0x0);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableBusOffInt
+ * Description : Enable the Bus off interrupts.
+ * This function will enable Bus Off interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnableBusOffInt(uint32_t canBaseAddr)
+{
+ /* Enable Bus Off interrupt*/
+ BW_CAN_CTRL1_BOFFMSK(canBaseAddr, 0x1);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableBusOffInt
+ * Description : Disable the Bus off interrupts.
+ * This function will disable Bus Off interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_DisableBusOffInt(uint32_t canBaseAddr)
+{
+ /* Disable Bus Off interrupt*/
+ BW_CAN_CTRL1_BOFFMSK(canBaseAddr, 0x0);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableWakeupInt
+ * Description : Enable the wakeup interrupts.
+ * This function will enable Wake up interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnableWakeupInt(uint32_t canBaseAddr)
+{
+ /* Enable Wake Up interrupt*/
+ BW_CAN_MCR_WAKMSK(canBaseAddr, 1);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableWakeupInt
+ * Description : Disable the wakeup interrupts.
+ * This function will disable Wake up interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_DisableWakeupInt(uint32_t canBaseAddr)
+{
+ /* Disable Wake Up interrupt*/
+ BW_CAN_MCR_WAKMSK(canBaseAddr, 0);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableTxWarningInt
+ * Description : Enable the TX warning interrupts.
+ * This function will enable TX warning interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnableTxWarningInt(uint32_t canBaseAddr)
+{
+ /* Enable TX warning interrupt*/
+ BW_CAN_CTRL1_TWRNMSK(canBaseAddr, 0x1);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableTxWarningInt
+ * Description : Disable the TX warning interrupts.
+ * This function will disable TX warning interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_DisableTxWarningInt(uint32_t canBaseAddr)
+{
+ /* Disable TX warning interrupt*/
+ BW_CAN_CTRL1_TWRNMSK(canBaseAddr, 0x0);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableRxWarningInt
+ * Description : Enable the RX warning interrupts.
+ * This function will enable RX warning interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnableRxWarningInt(uint32_t canBaseAddr)
+{
+ /* Enable RX warning interrupt*/
+ BW_CAN_CTRL1_RWRNMSK(canBaseAddr, 0x1);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableRxWarningInt
+ * Description : Disable the RX warning interrupts.
+ * This function will disable RX warning interrupt.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_DisableRxWarningInt(uint32_t canBaseAddr)
+{
+ /* Disable RX warning interrupt*/
+ BW_CAN_CTRL1_RWRNMSK(canBaseAddr, 0x0);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_ExitFreezeMode
+ * Description : Exit of freeze mode.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_ExitFreezeMode(uint32_t canBaseAddr)
+{
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnterFreezeMode
+ * Description : Enter the freeze mode.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_EnterFreezeMode(uint32_t canBaseAddr)
+{
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_GetMbIntFlag
+ * Description : Get the corresponding message buffer interrupt flag.
+ *
+ *END**************************************************************************/
+uint8_t FLEXCAN_HAL_GetMbIntFlag(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t *data,
+ uint32_t mb_idx)
+{
+ assert(data);
+ assert(mb_idx < data->max_num_mb);
+ uint32_t temp;
+
+ /* Get the corresponding message buffer interrupt flag*/
+ temp = 0x1 << mb_idx;
+ if (HW_CAN_IFLAG1_RD(canBaseAddr) & temp)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_GetErrCounter
+ * Description : Get transmit error counter and receive error counter.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_GetErrCounter(
+ uint32_t canBaseAddr,
+ flexcan_berr_counter_t *err_cnt)
+{
+ /* Get transmit error counter and receive error counter*/
+ err_cnt->rxerr = HW_CAN_ECR(canBaseAddr).B.RXERRCNT;
+ err_cnt->txerr = HW_CAN_ECR(canBaseAddr).B.TXERRCNT;
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_ClearErrIntStatus
+ * Description : Clear all error interrupt status.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_ClearErrIntStatus(uint32_t canBaseAddr)
+{
+ if(HW_CAN_ESR1_RD(canBaseAddr) & FLEXCAN_ALL_INT)
+ {
+ HW_CAN_ESR1_SET(canBaseAddr, FLEXCAN_ALL_INT);
+ }
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_ReadFifo
+ * Description : Read Rx FIFO data.
+ * This function will copy MB[0] data field into user's buffer.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_ReadFifo(
+ uint32_t canBaseAddr,
+ flexcan_mb_t *rx_fifo)
+{
+ uint32_t i;
+ volatile CAN_Type *flexcan_reg_ptr;
+
+ flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
+ if (NULL == flexcan_reg_ptr)
+ {
+ return (kStatus_FLEXCAN_InvalidArgument);
+ }
+
+ rx_fifo->cs = flexcan_reg_ptr->MB[0].CS;
+
+ if ((rx_fifo->cs) & CAN_CS_IDE_MASK)
+ {
+ rx_fifo->msg_id = flexcan_reg_ptr->MB[0].ID;
+ }
+ else
+ {
+ rx_fifo->msg_id = (flexcan_reg_ptr->MB[0].ID) >> CAN_ID_STD_SHIFT;
+ }
+
+ /* Copy MB[0] data field into user's buffer*/
+ for ( i=0 ; i < kFlexCanMessageSize ; i++ )
+ {
+ if (i < 4)
+ {
+ rx_fifo->data[3 - i] = ((flexcan_reg_ptr->MB[0].WORD0) >> (i * 8)) &
+ FLEXCAN_BYTE_DATA_FIELD_MASK;
+ }
+ else
+ {
+ rx_fifo->data[11 - i] = ((flexcan_reg_ptr->MB[0].WORD1) >> ((i - 4) * 8)) &
+ FLEXCAN_BYTE_DATA_FIELD_MASK;
+ }
+ }
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetMaskType
+ * Description : Set RX masking type.
+ * This function will set RX masking type as RX global mask or RX individual
+ * mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetMaskType(
+ uint32_t canBaseAddr,
+ flexcan_rx_mask_type_t type)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* Set RX masking type (RX global mask or RX individual mask)*/
+ if (type == kFlexCanRxMask_Global)
+ {
+ /* Enable Global RX masking*/
+ BW_CAN_MCR_IRMQ(canBaseAddr, 0x0);
+ }
+ else
+ {
+ /* Enable Individual Rx Masking and Queue*/
+ BW_CAN_MCR_IRMQ(canBaseAddr, 0x1);
+ }
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxFifoGlobalStdMask
+ * Description : Set Rx FIFO global mask as the 11-bit standard mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxFifoGlobalStdMask(
+ uint32_t canBaseAddr,
+ uint32_t std_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 11 bit standard mask*/
+ HW_CAN_RXFGMASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxFifoGlobalExtMask
+ * Description : Set Rx FIFO global mask as the 29-bit extended mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxFifoGlobalExtMask(
+ uint32_t canBaseAddr,
+ uint32_t ext_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 29-bit extended mask*/
+ HW_CAN_RXFGMASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxIndividualStdMask
+ * Description : Set Rx individual mask as the 11-bit standard mask.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SetRxIndividualStdMask(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t * data,
+ uint32_t mb_idx,
+ uint32_t std_mask)
+{
+ assert(data);
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 11 bit standard mask*/
+ HW_CAN_RXIMRn_WR(canBaseAddr, mb_idx, CAN_ID_STD(std_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxIndividualExtMask
+ * Description : Set Rx individual mask as the 29-bit extended mask.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_SetRxIndividualExtMask(
+ uint32_t canBaseAddr,
+ const flexcan_user_config_t * data,
+ uint32_t mb_idx,
+ uint32_t ext_mask)
+{
+ assert(data);
+
+ if (mb_idx >= data->max_num_mb)
+ {
+ return (kStatus_FLEXCAN_OutOfRange);
+ }
+
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 29-bit extended mask*/
+ HW_CAN_RXIMRn_WR(canBaseAddr, mb_idx, CAN_ID_EXT(ext_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxMbGlobalStdMask
+ * Description : Set Rx Message Buffer global mask as the 11-bit standard mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxMbGlobalStdMask(
+ uint32_t canBaseAddr,
+ uint32_t std_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 11 bit standard mask*/
+ HW_CAN_RXMGMASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxMbBuf14StdMask
+ * Description : Set Rx Message Buffer 14 mask as the 11-bit standard mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxMbBuf14StdMask(
+ uint32_t canBaseAddr,
+ uint32_t std_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 11 bit standard mask*/
+ HW_CAN_RX14MASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxMbBuf15StdMask
+ * Description : Set Rx Message Buffer 15 mask as the 11-bit standard mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxMbBuf15StdMask(
+ uint32_t canBaseAddr,
+ uint32_t std_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 11 bit standard mask*/
+ HW_CAN_RX15MASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxMbGlobalExtMask
+ * Description : Set Rx Message Buffer global mask as the 29-bit extended mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxMbGlobalExtMask(
+ uint32_t canBaseAddr,
+ uint32_t ext_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(HW_CAN_MCR_RD(canBaseAddr))){}
+
+ /* 29-bit extended mask*/
+ HW_CAN_RXMGMASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxMbBuf14ExtMask
+ * Description : Set Rx Message Buffer 14 mask as the 29-bit extended mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxMbBuf14ExtMask(
+ uint32_t canBaseAddr,
+ uint32_t ext_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 29-bit extended mask*/
+ HW_CAN_RX14MASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_SetRxMbBuf15ExtMask
+ * Description : Set Rx Message Buffer 15 mask as the 29-bit extended mask.
+ *
+ *END**************************************************************************/
+void FLEXCAN_HAL_SetRxMbBuf15ExtMask(
+ uint32_t canBaseAddr,
+ uint32_t ext_mask)
+{
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ /* 29-bit extended mask*/
+ HW_CAN_RX15MASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_EnableOperationMode
+ * Description : Enable a FlexCAN operation mode.
+ * This function will enable one of the modes listed in flexcan_operation_modes_t.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_EnableOperationMode(
+ uint32_t canBaseAddr,
+ flexcan_operation_modes_t mode)
+{
+ if (mode == kFlexCanFreezeMode)
+ {
+ /* Debug mode, Halt and Freeze*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ return (kStatus_FLEXCAN_Success);
+ }
+ else if (mode == kFlexCanDisableMode)
+ {
+ /* Debug mode, Halt and Freeze*/
+ BW_CAN_MCR_MDIS(canBaseAddr, 0x1);
+ return (kStatus_FLEXCAN_Success);
+ }
+
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ if (mode == kFlexCanNormalMode)
+ {
+ BW_CAN_MCR_SUPV(canBaseAddr, 0x0);
+ }
+ else if (mode == kFlexCanListenOnlyMode)
+ {
+ BW_CAN_CTRL1_LOM(canBaseAddr, 0x1);
+ }
+ else if (mode == kFlexCanLoopBackMode)
+ {
+ BW_CAN_CTRL1_LPB(canBaseAddr, 0x1);
+ }
+ else
+ {
+ return kStatus_FLEXCAN_InvalidArgument;
+ }
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+/*FUNCTION**********************************************************************
+ *
+ * Function Name : FLEXCAN_HAL_DisableOperationMode
+ * Description : Disable a FlexCAN operation mode.
+ * This function will disable one of the modes listed in flexcan_operation_modes_t.
+ *
+ *END**************************************************************************/
+flexcan_status_t FLEXCAN_HAL_DisableOperationMode(
+ uint32_t canBaseAddr,
+ flexcan_operation_modes_t mode)
+{
+ if (mode == kFlexCanFreezeMode)
+ {
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+
+ return (kStatus_FLEXCAN_Success);
+ }
+ else if (mode == kFlexCanDisableMode)
+ {
+ /* Disable module mode*/
+ BW_CAN_MCR_MDIS(canBaseAddr, 0x0);
+ return (kStatus_FLEXCAN_Success);
+ }
+
+ /* Set Freeze mode*/
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
+ BW_CAN_MCR_HALT(canBaseAddr, 0x1);
+
+ /* Wait for entering the freeze mode*/
+ while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
+
+ if (mode == kFlexCanNormalMode)
+ {
+ BW_CAN_MCR_SUPV(canBaseAddr, 0x1);
+ }
+ else if (mode == kFlexCanListenOnlyMode)
+ {
+ BW_CAN_CTRL1_LOM(canBaseAddr, 0x0);
+ }
+ else if (mode == kFlexCanLoopBackMode)
+ {
+ BW_CAN_CTRL1_LPB(canBaseAddr, 0x0);
+ }
+ else
+ {
+ return kStatus_FLEXCAN_InvalidArgument;
+ }
+
+ /* De-assert Freeze Mode*/
+ BW_CAN_MCR_HALT(canBaseAddr, 0x0);
+ BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
+
+ /* Wait till exit of freeze mode*/
+ while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
+
+ return (kStatus_FLEXCAN_Success);
+}
+
+#endif /* MBED_NO_FLEXCAN */
+
+/*******************************************************************************
+ * EOF
+ ******************************************************************************/
+