mirror of
https://github.com/Dev-KATECH/ADM.git
synced 2026-05-17 09:53:59 +09:00
4394 lines
163 KiB
C
4394 lines
163 KiB
C
/*
|
|
* FlexCAN_Ip.c
|
|
*
|
|
* Created on: Apr 9, 2020
|
|
* Author: nxf31634
|
|
*/
|
|
/**
|
|
* @file FlexCAN_Ip.c
|
|
* @brief FlexCAN Driver File
|
|
* @addtogroup FlexCAN
|
|
* @{
|
|
*/
|
|
|
|
/*==================================================================================================
|
|
* Project : RTD AUTOSAR 4.4
|
|
* Platform : CORTEXM
|
|
* Peripheral : FLEXCAN
|
|
* Dependencies :
|
|
*
|
|
* Autosar Version : 4.4.0
|
|
* Autosar Revision : ASR_REL_4_4_REV_0000
|
|
* Autosar Conf.Variant :
|
|
* SW Version : 0.9.0
|
|
* Build Version : S32K3_RTD_0_9_0__ASR_REL_4_4_REV_0000_20210326
|
|
*
|
|
* (c) Copyright 2020 - 2021 NXP Semiconductors
|
|
* All Rights Reserved.
|
|
*
|
|
* NXP Confidential. This software is owned or controlled by NXP and may only be
|
|
* used strictly in accordance with the applicable license terms. By expressly
|
|
* accepting such terms or by downloading, installing, activating and/or otherwise
|
|
* using the software, you are agreeing that you have read, and that you agree to
|
|
* comply with and are bound by, such license terms. If you do not agree to be
|
|
* bound by the applicable license terms, then you may not retain, install,
|
|
* activate or otherwise use the software.
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* INCLUDE FILES
|
|
* 1) system and project includes
|
|
* 2) needed interfaces from external units
|
|
* 3) internal and external interfaces from this unit
|
|
==================================================================================================*/
|
|
#include "FlexCAN_Ip.h"
|
|
#include "Devassert.h"
|
|
#include "FlexCAN_Ip_Irq.h"
|
|
#include "FlexCAN_Ip_HwAccess.h"
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
#include "Dma_Ip.h"
|
|
#endif
|
|
|
|
#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
|
|
#define USER_MODE_REG_PROT_ENABLED (STD_ON)
|
|
#include "RegLockMacros.h"
|
|
#endif /* (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE) */
|
|
|
|
#include "SchM_Can.h"
|
|
|
|
#ifdef MCAL_ENABLE_FAULT_INJECTION
|
|
#include "Mcal.h"
|
|
#endif
|
|
/*==================================================================================================
|
|
* SOURCE FILE VERSION INFORMATION
|
|
==================================================================================================*/
|
|
#define FLEXCAN_IP_VENDOR_ID_C 43
|
|
#define FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C 4
|
|
#define FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C 4
|
|
#define FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C 0
|
|
#define FLEXCAN_IP_SW_MAJOR_VERSION_C 0
|
|
#define FLEXCAN_IP_SW_MINOR_VERSION_C 9
|
|
#define FLEXCAN_IP_SW_PATCH_VERSION_C 0
|
|
/*==================================================================================================
|
|
* FILE VERSION CHECKS
|
|
==================================================================================================*/
|
|
/* Check if current file and FlexCAN_Ip.h header file are of the same vendor */
|
|
#if (FLEXCAN_IP_VENDOR_ID_C != FLEXCAN_IP_VENDOR_ID_H)
|
|
#error "FlexCAN_Ip.c and FlexCAN_Ip.h have different vendor ids"
|
|
#endif
|
|
/* Check if current file and FlexCAN_Ip.h header file are of the same Autosar version */
|
|
#if ((FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C != FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_H) || \
|
|
(FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C != FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_H) || \
|
|
(FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C != FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_H))
|
|
#error "AutoSar Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip.h are different"
|
|
#endif
|
|
/* Check if current file and FlexCAN_Ip.h header file are of the same Software version */
|
|
#if ((FLEXCAN_IP_SW_MAJOR_VERSION_C != FLEXCAN_IP_SW_MAJOR_VERSION_H) || \
|
|
(FLEXCAN_IP_SW_MINOR_VERSION_C != FLEXCAN_IP_SW_MINOR_VERSION_H) || \
|
|
(FLEXCAN_IP_SW_PATCH_VERSION_C != FLEXCAN_IP_SW_PATCH_VERSION_H))
|
|
#error "Software Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip.h are different"
|
|
#endif
|
|
|
|
/* Check if current file and FlexCAN_Ip_Irq.h header file are of the same vendor */
|
|
#if (FLEXCAN_IP_VENDOR_ID_C != FLEXCAN_IP_IRQ_VENDOR_ID_H)
|
|
#error "FlexCAN_Ip.c and FlexCAN_Ip_Irq.h have different vendor ids"
|
|
#endif
|
|
/* Check if current file and FlexCAN_Ip_Irq.h header file are of the same Autosar version */
|
|
#if ((FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C != FLEXCAN_IP_IRQ_AR_RELEASE_MAJOR_VERSION_H) || \
|
|
(FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C != FLEXCAN_IP_IRQ_AR_RELEASE_MINOR_VERSION_H) || \
|
|
(FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C != FLEXCAN_IP_IRQ_AR_RELEASE_REVISION_VERSION_H))
|
|
#error "AutoSar Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_Irq.h are different"
|
|
#endif
|
|
/* Check if current file and FlexCAN_Ip_Irq.h header file are of the same Software version */
|
|
#if ((FLEXCAN_IP_SW_MAJOR_VERSION_C != FLEXCAN_IP_IRQ_SW_MAJOR_VERSION_H) || \
|
|
(FLEXCAN_IP_SW_MINOR_VERSION_C != FLEXCAN_IP_IRQ_SW_MINOR_VERSION_H) || \
|
|
(FLEXCAN_IP_SW_PATCH_VERSION_C != FLEXCAN_IP_IRQ_SW_PATCH_VERSION_H))
|
|
#error "Software Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_Irq.h are different"
|
|
#endif
|
|
|
|
/* Check if current file and FlexCAN_Ip_HwAccess.h header file are of the same vendor */
|
|
#if (FLEXCAN_IP_VENDOR_ID_C != FLEXCAN_IP_HWACCESS_VENDOR_ID_H)
|
|
#error "FlexCAN_Ip.c and FlexCAN_Ip_HwAccess.h have different vendor ids"
|
|
#endif
|
|
/* Check if current file and FlexCAN_Ip_HwAccess.h header file are of the same Autosar version */
|
|
#if ((FLEXCAN_IP_AR_RELEASE_MAJOR_VERSION_C != FLEXCAN_IP_HWACCESS_AR_RELEASE_MAJOR_VERSION_H) || \
|
|
(FLEXCAN_IP_AR_RELEASE_MINOR_VERSION_C != FLEXCAN_IP_HWACCESS_AR_RELEASE_MINOR_VERSION_H) || \
|
|
(FLEXCAN_IP_AR_RELEASE_REVISION_VERSION_C != FLEXCAN_IP_HWACCESS_AR_RELEASE_REVISION_VERSION_H))
|
|
#error "AutoSar Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_HwAccess.h are different"
|
|
#endif
|
|
/* Check if current file and FlexCAN_Ip_HwAccess.h header file are of the same Software version */
|
|
#if ((FLEXCAN_IP_SW_MAJOR_VERSION_C != FLEXCAN_IP_HWACCESS_SW_MAJOR_VERSION_H) || \
|
|
(FLEXCAN_IP_SW_MINOR_VERSION_C != FLEXCAN_IP_HWACCESS_SW_MINOR_VERSION_H) || \
|
|
(FLEXCAN_IP_SW_PATCH_VERSION_C != FLEXCAN_IP_HWACCESS_SW_PATCH_VERSION_H))
|
|
#error "Software Version Numbers of FlexCAN_Ip.c and FlexCAN_Ip_HwAccess.h are different"
|
|
#endif
|
|
|
|
#ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
|
|
/* Check if current file and SchM_Can header file are of the same version */
|
|
#endif
|
|
/*==================================================================================================
|
|
* LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* LOCAL MACROS
|
|
==================================================================================================*/
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
#define CAN_ENHANCE_TRASNFER_DIMENSION_LIST (13U)
|
|
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
|
|
|
|
#define CAN_TRASNFER_DIMENSION_LIST (10U)
|
|
#endif /*(FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)*/
|
|
/*==================================================================================================
|
|
* LOCAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL CONSTANTS
|
|
==================================================================================================*/
|
|
|
|
/*==================================================================================================
|
|
* GLOBAL VARIABLES
|
|
==================================================================================================*/
|
|
#define CAN_START_SEC_CONST_UNSPECIFIED
|
|
#include "Can_MemMap.h"
|
|
|
|
/* Table of base addresses for CAN instances. */
|
|
static FLEXCAN_Type * const g_Flexcan_Ip_aBase[] = FLEXCAN_BASE_PTRS;
|
|
|
|
#define CAN_STOP_SEC_CONST_UNSPECIFIED
|
|
#include "Can_MemMap.h"
|
|
|
|
#define CAN_START_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
|
|
#include "Can_MemMap.h"
|
|
|
|
/* Pointer to runtime state structure.*/
|
|
static Flexcan_Ip_StateType * g_flexcan_Ip_StatePtr[FLEXCAN_INSTANCE_COUNT];
|
|
|
|
#define CAN_STOP_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
|
|
#include "Can_MemMap.h"
|
|
|
|
|
|
#define CAN_START_SEC_CODE
|
|
#include "Can_MemMap.h"
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTION PROTOTYPES
|
|
==================================================================================================*/
|
|
/* Init legacy, enhanced fifo if requested, if no fifo request, return success. */
|
|
static Flexcan_Ip_StatusType FlexCAN_InitRxFifo(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData);
|
|
|
|
/* Init basically controller , this function is called in FlexCAN_Ip_Init only */
|
|
static Flexcan_Ip_StatusType FlexCAN_InitController(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData);
|
|
|
|
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageBufferData(uint8 instance,
|
|
uint8 mb_idx,
|
|
Flexcan_Ip_MsgBuffType * data,
|
|
boolean isPolling);
|
|
|
|
static Flexcan_Ip_StatusType FlexCAN_StartSendData(uint8 Flexcan_Ip_u8Instance,
|
|
uint8 mb_idx,
|
|
const Flexcan_Ip_DataInfoType * tx_info,
|
|
uint32 msg_id,
|
|
const uint8 * mb_data);
|
|
|
|
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageFifoData(uint8 instance,
|
|
Flexcan_Ip_MsgBuffType * data);
|
|
|
|
static Flexcan_Ip_StatusType FlexCAN_ProccessLegacyRxFIFO(uint8 u8Instance, uint32 u32TimeoutMs);
|
|
|
|
static void FlexCAN_IRQHandlerRxMB(uint8 instance,
|
|
uint32 mb_idx);
|
|
|
|
static void FlexCAN_IRQHandlerTxMB(uint8 u8Instance, uint32 u32MbIdx);
|
|
|
|
static inline void FlexCAN_IRQHandlerRxFIFO(uint8 instance,
|
|
uint32 mb_idx);
|
|
|
|
static inline void FlexCAN_ProcessSpuriousInterruptMB(uint8 instance, uint32 startMbIdx, uint32 endMbIdx);
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
static void DMA_Can_Callback(uint8 instance);
|
|
#endif
|
|
|
|
#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
|
|
static void FlexCAN_SetUserAccessAllowed(const FLEXCAN_Type * pBase);
|
|
static void FlexCAN_ClrUserAccessAllowed(const FLEXCAN_Type * pBase);
|
|
#endif
|
|
|
|
static Flexcan_Ip_StatusType FlexCAN_AbortTxTransfer(uint8 u8Instance, uint8 mb_idx);
|
|
static void FlexCAN_AbortRxTransfer(uint8 u8Instance, uint8 mb_idx);
|
|
|
|
static void FlexCAN_CompleteRxMessageFifoData(uint8 instance);
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
static void FlexCAN_IRQHandlerEnhancedRxFIFO(uint8 instance, uint32 intType);
|
|
static inline boolean FlexCAN_ProcessIRQHandlerEnhancedRxFIFO(uint8 u8Instance, boolean bIsSpuriousIntPrevious);
|
|
static void FlexCAN_CompleteRxMessageEnhancedFifoData(uint8 instance);
|
|
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageEnhancedFifoData(uint8 instance,
|
|
Flexcan_Ip_MsgBuffType * data);
|
|
static Flexcan_Ip_StatusType FlexCAN_ProccessEnhancedRxFifo(uint8 u8Instance, uint32 u32TimeoutMs);
|
|
/*==================================================================================================
|
|
* LOCAL FUNCTIONS
|
|
==================================================================================================*/
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_InitRxFifo
|
|
* Description : Initialize fifo and dma if requested.
|
|
*
|
|
* This is not a public API as it is called from other driver functions.
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_InitRxFifo(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
/* Enable RxFIFO feature, if requested. This might fail if the FD mode is enabled. */
|
|
if (Flexcan_Ip_pData->is_rx_fifo_needed)
|
|
{
|
|
eResult = FlexCAN_EnableRxFifo(pBase, (uint32)Flexcan_Ip_pData->num_id_filters);
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
/* Enable Enhanced RxFIFO feature, if requested.
|
|
* This might fail if the current CAN instance does not support Enhaneced RxFIFO or the Rx FIFO is enabled. */
|
|
if ((FLEXCAN_STATUS_SUCCESS == eResult) && (Flexcan_Ip_pData->is_enhanced_rx_fifo_needed))
|
|
{
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (Flexcan_Ip_pData->transfer_type == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
eResult = FlexCAN_EnableEnhancedRxFifo(pBase,
|
|
(uint32)Flexcan_Ip_pData->num_enhanced_std_id_filters,
|
|
(uint32)Flexcan_Ip_pData->num_enhanced_ext_id_filters,
|
|
(uint32)0U); /* for dma, each a frame received -> a minor loop */
|
|
}
|
|
else
|
|
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */
|
|
{
|
|
eResult = FlexCAN_EnableEnhancedRxFifo(pBase,
|
|
(uint32)Flexcan_Ip_pData->num_enhanced_std_id_filters,
|
|
(uint32)Flexcan_Ip_pData->num_enhanced_ext_id_filters,
|
|
(uint32)Flexcan_Ip_pData->num_enhanced_watermark);
|
|
}
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (FLEXCAN_STATUS_SUCCESS == eResult)
|
|
{
|
|
/* Enable DMA support for RxFIFO transfer, if requested. */
|
|
if (Flexcan_Ip_pData->transfer_type == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
if (((pBase->MCR & FLEXCAN_MCR_RFEN_MASK) >> FLEXCAN_MCR_RFEN_SHIFT) != 0U)
|
|
{
|
|
FlexCAN_SetRxFifoDMA(pBase, TRUE);
|
|
}
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
else if (FlexCAN_IsEnhancedRxFifoAvailable(pBase))
|
|
{
|
|
if (FlexCAN_IsEnhancedRxFifoEnabled(pBase))
|
|
{
|
|
FlexCAN_SetRxFifoDMA(pBase, TRUE);
|
|
FlexCAN_ConfigEnhancedRxFifoDMA(pBase, 20U); /* always transfer 80 bytes (DMALW = 19)*/
|
|
}
|
|
else
|
|
{
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
else
|
|
{
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
if (FlexCAN_IsEnhancedRxFifoAvailable(pBase))
|
|
{
|
|
/* Clear Enhanced Rx FIFO status.*/
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_WATERMARK);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_OVERFLOW);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_UNDERFLOW);
|
|
/* Clear the Enhanced RX FIFO engine */
|
|
FlexCAN_ClearEnhancedRxFifoEngine(pBase);
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
FlexCAN_SetRxFifoDMA(pBase, FALSE);
|
|
}
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */
|
|
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_InitController
|
|
* Description : Initialize basically controller.
|
|
*
|
|
* This is not a public API as it is called from other driver functions.
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_InitController(FLEXCAN_Type * pBase, const Flexcan_Ip_ConfigType * Flexcan_Ip_pData)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
if (FlexCAN_IsEnabled(pBase))
|
|
{
|
|
/* To enter Disable Mode requires FreezMode first */
|
|
eResult = FlexCAN_EnterFreezeMode(pBase);
|
|
if(FLEXCAN_STATUS_SUCCESS == eResult)
|
|
{
|
|
eResult = FlexCAN_Disable(pBase);
|
|
}
|
|
}
|
|
|
|
if(FLEXCAN_STATUS_SUCCESS == eResult)
|
|
{
|
|
/* Start critical section: implementation depends on integrator */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();
|
|
/* Enable FlexCAN Module need to perform SoftReset & ClearRam */
|
|
pBase->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
|
|
/* End critical section: implementation depends on integrator */
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
|
|
/* Initialize FLEXCAN device */
|
|
eResult = FlexCAN_Init(pBase);
|
|
if (eResult != FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* To enter Disable Mode requires FreezMode first */
|
|
(void)FlexCAN_EnterFreezeMode(pBase);
|
|
(void)FlexCAN_Disable(pBase);
|
|
}
|
|
else
|
|
{
|
|
#if (FEATURE_CAN_HAS_MEM_ERR_DET == STD_ON)
|
|
/* Disable the Protection again because is enabled by soft reset */
|
|
FlexCAN_DisableMemErrorDetection(pBase);
|
|
#endif
|
|
|
|
/* Enable/Disable FD and check FD was set as expected. Setting FD as enabled
|
|
* might fail if the current CAN instance does not support FD. */
|
|
FlexCAN_SetFDEnabled(pBase, Flexcan_Ip_pData->fd_enable, Flexcan_Ip_pData->bitRateSwitch);
|
|
/* No more required, I don't expect any other NPIs with and without Interfaces with FD support
|
|
* if (FLEXCAN_IsFDEnabled(base) != Flexcan_Ip_pData->fd_enable)
|
|
{
|
|
return FLEXCAN_STATUS_ERROR;
|
|
}*/
|
|
|
|
/* configure depends on controller options. */
|
|
FlexCAN_ConfigCtrlOptions(pBase, Flexcan_Ip_pData->ctrlOptions);
|
|
|
|
/* Disable the self reception feature if FlexCAN is not in loopback mode. */
|
|
if (Flexcan_Ip_pData->flexcanMode != FLEXCAN_LOOPBACK_MODE)
|
|
{
|
|
FlexCAN_SetSelfReception(pBase, FALSE);
|
|
}
|
|
|
|
/* Init legacy fifo, enhanced fifo if requested. */
|
|
eResult = FlexCAN_InitRxFifo(pBase, Flexcan_Ip_pData);
|
|
if (eResult != FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* To enter Disable Mode requires FreezMode first */
|
|
(void)FlexCAN_EnterFreezeMode(pBase);
|
|
(void)FlexCAN_Disable(pBase);
|
|
}
|
|
else
|
|
{
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
/* Set payload size. */
|
|
FlexCAN_SetPayloadSize(pBase, &Flexcan_Ip_pData->payload);
|
|
#endif /* FEATURE_CAN_HAS_FD */
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
eResult = FlexCAN_SetMaxMsgBuffNum(pBase, Flexcan_Ip_pData->max_num_mb);
|
|
if (eResult != FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* To enter Disable Mode requires FreezMode first */
|
|
(void)FlexCAN_EnterFreezeMode(pBase);
|
|
(void)FlexCAN_Disable(pBase);
|
|
}
|
|
#else
|
|
(void)FlexCAN_SetMaxMsgBuffNum(pBase, Flexcan_Ip_pData->max_num_mb);
|
|
#endif /* FLEXCAN_DEV_ERROR_DETECT */
|
|
}
|
|
}
|
|
}
|
|
|
|
return eResult;
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_CompleteRxMessageEnhancedFifoData
|
|
* Description : Finish up a receive by completing the process of receiving
|
|
* data and disabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static void FlexCAN_CompleteRxMessageEnhancedFifoData(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
uint32 u32MbCnt = 0U;
|
|
uint8 j;
|
|
Flexcan_Ip_MsgBuffType * fifo_message = NULL_PTR;
|
|
uint32 * msgData_32 = NULL_PTR;
|
|
uint8 flexcan_mb_dlc_value = 0U;
|
|
uint8 can_dlc_payload = 0U;
|
|
uint8 can_real_payload = 0U;
|
|
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(FlexCAN_IsEnhancedRxFifoAvailable(base));
|
|
#endif /* (FLEXCAN_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
if (state->enhancedFifoOutput.isPolling == FALSE)
|
|
{
|
|
/* Reset to default value to avoid re-enable when calling Ip_EnableInterrupt */
|
|
state->enhancedFifoOutput.isPolling = TRUE;
|
|
/* Disable Enhanced RX FIFO interrupts*/
|
|
FlexCAN_SetEnhancedRxFifoIntAll(base, FALSE);
|
|
}
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
else if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
Dma_Ip_LogicChannelStatusType dmaStatus;
|
|
Dma_Ip_GetLogicChannelStatus(state->rxFifoDMAChannel, &dmaStatus);
|
|
|
|
if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
|
|
{
|
|
(void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_ERROR);
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_DMA_ERROR;
|
|
}
|
|
|
|
(void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
|
|
if (state->enhancedFifoOutput.state != FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
fifo_message = state->enhancedFifoOutput.pMBmessage;
|
|
msgData_32 = (uint32 *)fifo_message->data;
|
|
|
|
for (u32MbCnt = 0U; u32MbCnt < state->u32NumOfMbTransferByDMA; u32MbCnt++)
|
|
{
|
|
/* Adjust the ID if it is not extended */
|
|
if (((fifo_message->cs) & CAN_CS_IDE_MASK) == 0U)
|
|
{
|
|
fifo_message->msgId = fifo_message->msgId >> CAN_ID_STD_SHIFT;
|
|
}
|
|
|
|
/* Extract the data length */
|
|
flexcan_mb_dlc_value = (uint8)((fifo_message->cs & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
|
|
can_dlc_payload = FlexCAN_ComputePayloadSize(flexcan_mb_dlc_value);
|
|
can_real_payload = 0U;
|
|
/* Extract the IDHIT and Time Stamp */
|
|
if ((fifo_message->cs & CAN_CS_RTR_MASK) != 0U)
|
|
{
|
|
can_real_payload = 0U;
|
|
}
|
|
else
|
|
{
|
|
can_real_payload = can_dlc_payload;
|
|
}
|
|
|
|
uint8 idhit_offset = (can_real_payload >> 2U) + (((can_real_payload % 4U) != 0U) ? 1U : 0U);
|
|
#if (FEATURE_CAN_HAS_HR_TIMER == STD_ON)
|
|
/* Extract the Time Stamp */
|
|
if (FLEXCAN_IsHRTimeStampEnabled(base))
|
|
{
|
|
fifo_message->time_stamp = (uint32)(msgData_32[idhit_offset + 1U]);
|
|
}
|
|
else
|
|
#endif /* FEATURE_CAN_HAS_HR_TIMER */
|
|
{
|
|
fifo_message->time_stamp = (uint32)((fifo_message->cs & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
|
|
}
|
|
|
|
/* Extract the IDHIT */
|
|
fifo_message->id_hit = (uint8)(((msgData_32[idhit_offset]) & CAN_ENHANCED_IDHIT_MASK) >> CAN_ENHANCED_IDHIT_SHIFT);
|
|
/* Extract the dataLen */
|
|
fifo_message->dataLen = can_dlc_payload;
|
|
/* Reverse the endianness */
|
|
for (j = 0U; j < idhit_offset; j++)
|
|
{
|
|
FlexcanSwapBytesInWord(msgData_32[j], msgData_32[j]);
|
|
}
|
|
|
|
fifo_message++;
|
|
msgData_32 = (uint32 *)fifo_message->data;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* If Enhanced Rx FIFO has Pending Request that generated error,
|
|
* the EnhancedRxFIFO need to be empty to activate DMA */
|
|
FlexCAN_ClearOutputEnhanceFIFO(base);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* avoid misra */
|
|
}
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
|
|
/* Clear enhanced rx fifo message*/
|
|
state->enhancedFifoOutput.pMBmessage = NULL_PTR;
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (state->enhancedFifoOutput.state != FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
if ((state->callback != NULL_PTR) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_DMA_COMPLETE, FLEXCAN_MB_ENHANCED_RXFIFO, state);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback((uint8)instance, FLEXCAN_EVENT_DMA_ERROR, FLEXCAN_MB_ENHANCED_RXFIFO, state);
|
|
}
|
|
}
|
|
#else /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_StartRxMessageEnhancedFifoData
|
|
* Description : Initiate (start) a receive by beginning the process of
|
|
* receiving data and enabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageEnhancedFifoData(uint8 instance,
|
|
Flexcan_Ip_MsgBuffType * data)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif /* (FLEXCAN_DEV_ERROR_DETECT == STD_ON) */
|
|
|
|
/* Start receiving fifo */
|
|
if (state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY)
|
|
{
|
|
eResult = FLEXCAN_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_RX_BUSY;
|
|
/* This will get filled by the interrupt handler */
|
|
state->enhancedFifoOutput.pMBmessage = data;
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_INTERRUPTS)
|
|
{
|
|
state->enhancedFifoOutput.isPolling = FALSE;
|
|
if ((boolean)TRUE == state->isIntActive)
|
|
{
|
|
/* Enable All Enhanced RX FIFO interrupts*/
|
|
FlexCAN_SetEnhancedRxFifoIntAll(base, TRUE);
|
|
}
|
|
}
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_POLLING)
|
|
{
|
|
state->enhancedFifoOutput.isPolling = TRUE;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
/* reset to default to avoid enabling interrupt */
|
|
state->enhancedFifoOutput.isPolling = TRUE;
|
|
Dma_Ip_ReturnType edmaStatus;
|
|
|
|
Dma_Ip_LogicChannelTransferListType trasfer[CAN_ENHANCE_TRASNFER_DIMENSION_LIST] = {
|
|
{
|
|
.Param = DMA_IP_CH_SET_SOURCE_ADDRESS,
|
|
.Value = ((uint32)base + (uint32)FEATURE_CAN_ENHANCED_FIFO_RAM_OFFSET),
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET ,
|
|
.Value = 4,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE,
|
|
.Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_DESTINATION_ADDRESS,
|
|
.Value = (uint32)(state->enhancedFifoOutput.pMBmessage),
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET,
|
|
.Value = 4,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE,
|
|
.Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MINORLOOP_SIZE,
|
|
.Value = 80,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MAJORLOOP_COUNT,
|
|
.Value = state->u32NumOfMbTransferByDMA,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT,
|
|
.Value = 1,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST,
|
|
.Value = 1,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MINORLOOP_EN_SRC_OFFSET,
|
|
.Value = 1, /* enable for src address: after each minor loop, jump back to output of enhance fifo */
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MINORLOOP_EN_DST_OFFSET,
|
|
.Value = 0, /* disable for dst address: after each minor loop: standing on next element of pMBmessage array */
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MINORLOOP_SIGNED_OFFSET,
|
|
.Value = (uint32)((sint32)(-80)), /* enable for src address: after each minor loop, jump back to output of enhance fifo */
|
|
}
|
|
};
|
|
|
|
edmaStatus = Dma_Ip_SetLogicChannelTransferList(state->rxFifoDMAChannel, &trasfer[0], CAN_ENHANCE_TRASNFER_DIMENSION_LIST);
|
|
|
|
if (edmaStatus != DMA_IP_STATUS_SUCCESS)
|
|
{
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
edmaStatus = Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
|
|
if (edmaStatus != DMA_IP_STATUS_SUCCESS)
|
|
{
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
}
|
|
}
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
}
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_ProccessEnhancedRxFifo
|
|
* Description : This function will process the enhanced RxFIFO in blocking mode.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_ProccessEnhancedRxFifo(uint8 u8Instance, uint32 u32TimeoutMs)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StateType * pState = g_flexcan_Ip_StatePtr[u8Instance];
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
uint32 timeStart = 0U;
|
|
uint32 timeElapsed = 0U;
|
|
uint32 mS2Ticks = OsIf_MicrosToTicks((u32TimeoutMs * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
|
|
uint32 u32intType = 0U;
|
|
|
|
timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
|
|
while (FLEXCAN_MB_RX_BUSY == pState->enhancedFifoOutput.state)
|
|
{
|
|
if (FLEXCAN_RXFIFO_USING_POLLING == pState->transferType)
|
|
{
|
|
for (u32intType = CAN_ENHANCED_RXFIFO_UNDERFLOW; \
|
|
u32intType >= CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE; \
|
|
u32intType--)
|
|
{
|
|
if (FlexCAN_GetEnhancedRxFIFOStatusFlag(pBase, u32intType) != 0U)
|
|
{
|
|
FlexCAN_IRQHandlerEnhancedRxFIFO(u8Instance, u32intType);
|
|
}
|
|
}
|
|
}
|
|
|
|
timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
|
|
if (timeElapsed >= mS2Ticks)
|
|
{
|
|
eResult = FLEXCAN_STATUS_TIMEOUT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((FLEXCAN_STATUS_TIMEOUT == eResult) && (FLEXCAN_RXFIFO_USING_POLLING != pState->transferType))
|
|
{
|
|
/* Disable Enhanced RX FIFO interrupts*/
|
|
FlexCAN_SetEnhancedRxFifoIntAll(pBase, (boolean)FALSE);
|
|
#if FEATURE_CAN_HAS_DMA_ENABLE
|
|
/* Check if transfer is done over DMA and stop transfer */
|
|
if ((FLEXCAN_MB_RX_BUSY == pState->enhancedFifoOutput.state) && (FLEXCAN_RXFIFO_USING_DMA == pState->transferType))
|
|
{
|
|
(void)Dma_Ip_SetLogicChannelCommand(pState->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
/* Reset Entire Enhance FIFO if timeout occurred */
|
|
if (FLEXCAN_MB_RX_BUSY == pState->enhancedFifoOutput.state)
|
|
{
|
|
#if ((STD_ON == FLEXCAN_ENABLE_USER_MODE_SUPPORT) && (STD_OFF == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE))
|
|
OsIf_Trusted_Call1param(FlexCAN_ClearOutputEnhanceFIFO, pBase);
|
|
#else
|
|
FlexCAN_ClearOutputEnhanceFIFO(pBase);
|
|
#endif
|
|
}
|
|
}
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
}
|
|
|
|
switch (pState->enhancedFifoOutput.state)
|
|
{
|
|
case FLEXCAN_MB_RX_BUSY:
|
|
pState->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
break;
|
|
case FLEXCAN_MB_IDLE:
|
|
eResult = FLEXCAN_STATUS_SUCCESS;
|
|
break;
|
|
#if FEATURE_CAN_HAS_DMA_ENABLE
|
|
case FLEXCAN_MB_DMA_ERROR:
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
break;
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
default:
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
break;
|
|
}
|
|
|
|
return eResult;
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_ProccessLegacyRxFIFO
|
|
* Description : This function will process the enhanced RxFIFO in blocking mode.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_ProccessLegacyRxFIFO(uint8 u8Instance, uint32 u32TimeoutMs)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StateType * pState = g_flexcan_Ip_StatePtr[u8Instance];
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
uint32 timeStart = 0U;
|
|
uint32 timeElapsed = 0U;
|
|
uint32 mS2Ticks = OsIf_MicrosToTicks((u32TimeoutMs * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
|
|
uint32 u32intType = 0U;
|
|
|
|
timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
|
|
|
|
while (FLEXCAN_MB_RX_BUSY == pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state)
|
|
{
|
|
if (FLEXCAN_RXFIFO_USING_POLLING == pState->transferType)
|
|
{
|
|
for (u32intType = CAN_LEGACY_RXFIFO_OVERFLOW; \
|
|
u32intType >= CAN_LEGACY_RXFIFO_FRAME_AVAILABLE; \
|
|
u32intType--)
|
|
{
|
|
if (FlexCAN_GetBuffStatusFlag(pBase, u32intType) != 0U)
|
|
{
|
|
FlexCAN_IRQHandlerRxFIFO(u8Instance, u32intType);
|
|
}
|
|
}
|
|
}
|
|
|
|
timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
|
|
if (timeElapsed >= mS2Ticks)
|
|
{
|
|
eResult = FLEXCAN_STATUS_TIMEOUT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((FLEXCAN_STATUS_TIMEOUT == eResult) && (FLEXCAN_RXFIFO_USING_POLLING != pState->transferType))
|
|
{
|
|
/* Disable RX FIFO interrupts*/
|
|
(void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, (boolean)FALSE, pState->isIntActive);
|
|
(void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_WARNING, (boolean)FALSE, pState->isIntActive);
|
|
(void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_OVERFLOW, (boolean)FALSE, pState->isIntActive);
|
|
#if FEATURE_CAN_HAS_DMA_ENABLE
|
|
/* Check if transfer is done over DMA and stop transfer */
|
|
if ((FLEXCAN_MB_RX_BUSY == pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state) && (FLEXCAN_RXFIFO_USING_DMA == pState->transferType))
|
|
{
|
|
/* This function always return status success */
|
|
(void)Dma_Ip_SetLogicChannelCommand(pState->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
switch (pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state)
|
|
{
|
|
case FLEXCAN_MB_RX_BUSY:
|
|
pState->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
break;
|
|
case FLEXCAN_MB_IDLE:
|
|
eResult = FLEXCAN_STATUS_SUCCESS;
|
|
break;
|
|
#if FEATURE_CAN_HAS_DMA_ENABLE
|
|
case FLEXCAN_MB_DMA_ERROR:
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
break;
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
default:
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
break;
|
|
}
|
|
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_DRV_StartRxMessageBufferData
|
|
* Description : Initiate (start) a receive by beginning the process of
|
|
* receiving data and enabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageBufferData(uint8 instance,
|
|
uint8 mb_idx,
|
|
Flexcan_Ip_MsgBuffType * data,
|
|
boolean isPolling)
|
|
{
|
|
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#endif
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
|
|
if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(base, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
|
|
{
|
|
result = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
/* Start receiving mailbox */
|
|
if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
|
|
{
|
|
result = FLEXCAN_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_RX_BUSY;
|
|
state->mbs[mb_idx].pMBmessage = data;
|
|
state->mbs[mb_idx].isPolling = isPolling;
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
}
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_DRV_StartSendData
|
|
* Description : Initiate (start) a transmit by beginning the process of
|
|
* sending data.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_StartSendData(uint8 Flexcan_Ip_u8Instance,
|
|
uint8 mb_idx,
|
|
const Flexcan_Ip_DataInfoType * tx_info,
|
|
uint32 msg_id,
|
|
const uint8 * mb_data)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_MsbuffCodeStatusType cs;
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[Flexcan_Ip_u8Instance];
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[Flexcan_Ip_u8Instance];
|
|
/* aici e ilogic ca nu are rost sa faci checkul dupa ce ai alocat aiurea */
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(Flexcan_Ip_u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(tx_info != NULL_PTR);
|
|
|
|
if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(base, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
|
|
{
|
|
eResult = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
|
|
{
|
|
eResult = FLEXCAN_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
/* Clear message buffer flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_TX_BUSY;
|
|
state->mbs[mb_idx].time_stamp = 0U;
|
|
state->mbs[mb_idx].isPolling = tx_info->is_polling;
|
|
state->mbs[mb_idx].isRemote = tx_info->is_remote;
|
|
|
|
cs.dataLen = tx_info->data_length;
|
|
cs.msgIdType = tx_info->msg_id_type;
|
|
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
cs.fd_enable = tx_info->fd_enable;
|
|
cs.fd_padding = tx_info->fd_padding;
|
|
cs.enable_brs = tx_info->enable_brs;
|
|
#endif
|
|
|
|
if (tx_info->is_remote)
|
|
{
|
|
cs.code = (uint32)FLEXCAN_TX_REMOTE;
|
|
}
|
|
else
|
|
{
|
|
cs.code = (uint32)FLEXCAN_TX_DATA;
|
|
}
|
|
|
|
FlexCAN_SetTxMsgBuff(base, mb_idx, &cs, msg_id, mb_data, FALSE);
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
}
|
|
#endif
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_StartRxMessageFifoData
|
|
* Description : Initiate (start) a receive by beginning the process of
|
|
* receiving data and enabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_StartRxMessageFifoData(uint8 instance,
|
|
Flexcan_Ip_MsgBuffType * data)
|
|
{
|
|
|
|
FLEXCAN_Type * base = NULL_PTR;
|
|
Flexcan_Ip_StateType * state = NULL_PTR;
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
base = g_Flexcan_Ip_aBase[instance];
|
|
state = g_flexcan_Ip_StatePtr[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
/* Check if RxFIFO feature is enabled */
|
|
if (state->bIsLegacyFifoEn == FALSE)
|
|
{
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
/* Check if FIFO has Pending Request that generated error,
|
|
* the RxFIFO need to be empty to activate DMA */
|
|
#if ((STD_ON == FLEXCAN_ENABLE_USER_MODE_SUPPORT) && (STD_OFF == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE))
|
|
OsIf_Trusted_Call1param(FlexCAN_ClearOutputLegacyFIFO, base);
|
|
#else
|
|
FlexCAN_ClearOutputLegacyFIFO(base);
|
|
#endif
|
|
/* Change status of MB to be reconfigured with DMA transfer */
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
}
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */
|
|
|
|
/* Start receiving fifo */
|
|
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state != FLEXCAN_MB_IDLE)
|
|
{
|
|
eResult = FLEXCAN_STATUS_BUSY;
|
|
}
|
|
else
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_RX_BUSY;
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_POLLING)
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isPolling = TRUE;
|
|
}
|
|
|
|
/* This will get filled by the interrupt handler */
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage = data;
|
|
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_INTERRUPTS)
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isPolling = FALSE;
|
|
/* Enable RX FIFO interrupts*/
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_WARNING, TRUE, state->isIntActive);
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_OVERFLOW, TRUE, state->isIntActive);
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, TRUE, state->isIntActive);
|
|
}
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
Dma_Ip_ReturnType edmaStatus;
|
|
|
|
Dma_Ip_LogicChannelTransferListType trasfer[CAN_TRASNFER_DIMENSION_LIST] = {
|
|
{
|
|
.Param = DMA_IP_CH_SET_SOURCE_ADDRESS,
|
|
.Value = (uint32)FlexCAN_GetMsgBuffRegion(base, FLEXCAN_MB_HANDLE_RXFIFO)
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_SOURCE_SIGNED_OFFSET ,
|
|
.Value = 4,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_SOURCE_TRANSFER_SIZE,
|
|
.Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_DESTINATION_ADDRESS,
|
|
.Value = (uint32)(state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage)
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_DESTINATION_SIGNED_OFFSET,
|
|
.Value = 4,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_DESTINATION_TRANSFER_SIZE,
|
|
.Value = DMA_IP_TRANSFER_SIZE_4_BYTE,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MINORLOOP_SIZE,
|
|
.Value = 16,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_MAJORLOOP_COUNT,
|
|
.Value = 1,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_CONTROL_EN_MAJOR_INTERRUPT,
|
|
.Value = 1,
|
|
},
|
|
{
|
|
.Param = DMA_IP_CH_SET_CONTROL_DIS_AUTO_REQUEST,
|
|
.Value = 1,
|
|
},
|
|
};
|
|
edmaStatus = Dma_Ip_SetLogicChannelTransferList(state->rxFifoDMAChannel, &trasfer[0], CAN_TRASNFER_DIMENSION_LIST);
|
|
|
|
if (edmaStatus != DMA_IP_STATUS_SUCCESS)
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
else
|
|
{
|
|
edmaStatus = Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_SET_HARDWARE_REQUEST);
|
|
if (edmaStatus != DMA_IP_STATUS_SUCCESS)
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
|
|
eResult = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
}
|
|
#endif
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_IRQHandlerRxMB
|
|
* Description : Process IRQHandler in case of Rx MessageBuffer selection
|
|
* for CAN interface.
|
|
*
|
|
* This is not a public API as it is called whenever an interrupt and receive
|
|
* individual MB occurs
|
|
*END**************************************************************************/
|
|
static void FlexCAN_IRQHandlerRxMB(uint8 instance,
|
|
uint32 mb_idx)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
Flexcan_Ip_MsgBuffType data;
|
|
boolean bCurrentIntStat = (boolean)FALSE;
|
|
|
|
/* If use pass NULL_PTR, they can get data in callback function by getting state->mbs[mb_idx].pMBmessage */
|
|
if (NULL_PTR == state->mbs[mb_idx].pMBmessage)
|
|
{
|
|
state->mbs[mb_idx].pMBmessage = &data;
|
|
}
|
|
|
|
/* Lock RX message buffer and RX FIFO*/
|
|
FlexCAN_LockRxMsgBuff(base, mb_idx);
|
|
|
|
/* Get RX MB field values*/
|
|
FlexCAN_GetMsgBuff(base, mb_idx, state->mbs[mb_idx].pMBmessage);
|
|
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
/* Unlock RX message buffer and RX FIFO*/
|
|
FlexCAN_UnlockRxMsgBuff(base);
|
|
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
|
|
|
|
bCurrentIntStat = state->mbs[mb_idx].isPolling;
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_RX_COMPLETE, mb_idx, state);
|
|
}
|
|
|
|
if ((FLEXCAN_MB_IDLE == state->mbs[mb_idx].state) && ((boolean)FALSE == state->mbs[mb_idx].isPolling))
|
|
{
|
|
/* callback is not called, need to reset to default value */
|
|
state->mbs[mb_idx].isPolling = (boolean)TRUE;
|
|
/* Disable the transmitter data register empty interrupt for case: mb is interrupt (it was not use in above callback with the same index) */
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, FALSE, state->isIntActive);
|
|
}
|
|
else if (((boolean)FALSE == bCurrentIntStat) && ((boolean)TRUE == state->mbs[mb_idx].isPolling))
|
|
{
|
|
/* Disable the transmitter data register empty interrupt for case: switch from interrupt to polling for the same MB (called in above callback with same mb index) */
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, FALSE, state->isIntActive);
|
|
}
|
|
else
|
|
{
|
|
/* Prevent misra */
|
|
/* When processing type change from POLL->POLL or INTERRUPT -> INTERRUPT(this Mb is used continously in callback), no need to disable interrupt in the ISR */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_IRQHandlerTxMB
|
|
* Description : Process IRQHandler in case of Tx MessageBuffer selection
|
|
* for CAN interface.
|
|
* note: just using in interrupt mode
|
|
* This is not a public API as it is called whenever an interrupt and receive
|
|
* individual MB occurs
|
|
*END**************************************************************************/
|
|
static void FlexCAN_IRQHandlerTxMB(uint8 u8Instance, uint32 u32MbIdx)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
Flexcan_Ip_StateType * pState = g_flexcan_Ip_StatePtr[u8Instance];
|
|
Flexcan_Ip_MsgBuffType mb;
|
|
boolean bCurrentIntStat = (boolean)FALSE;
|
|
|
|
if (pState->mbs[u32MbIdx].isRemote)
|
|
{
|
|
FlexCAN_LockRxMsgBuff(pBase, u32MbIdx);
|
|
FlexCAN_GetMsgBuff(pBase, u32MbIdx, &mb);
|
|
FlexCAN_UnlockRxMsgBuff(pBase);
|
|
pState->mbs[u32MbIdx].time_stamp = mb.time_stamp;
|
|
/* If the frame was a remote frame, clear the flag only if the response was
|
|
* not received yet. If the response was received, leave the flag set in order
|
|
* to be handled when the user calls FLEXCAN_DRV_RxMessageBuffer. */
|
|
if (((mb.cs & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_RX_EMPTY)
|
|
{
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(pBase, u32MbIdx);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pState->mbs[u32MbIdx].time_stamp = FlexCAN_GetMsgBuffTimestamp(pBase, u32MbIdx);
|
|
FlexCAN_UnlockRxMsgBuff(pBase);
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(pBase, u32MbIdx);
|
|
}
|
|
|
|
pState->mbs[u32MbIdx].state = FLEXCAN_MB_IDLE;
|
|
|
|
bCurrentIntStat = pState->mbs[u32MbIdx].isPolling;
|
|
|
|
/* Invoke callback */
|
|
if (pState->callback != NULL_PTR)
|
|
{
|
|
pState->callback(u8Instance, FLEXCAN_EVENT_TX_COMPLETE, u32MbIdx, pState);
|
|
}
|
|
|
|
if ((FLEXCAN_MB_IDLE == pState->mbs[u32MbIdx].state) && ((boolean)FALSE == pState->mbs[u32MbIdx].isPolling))
|
|
{
|
|
/* callback is not called, need to reset to default value */
|
|
pState->mbs[u32MbIdx].isPolling = (boolean)TRUE;
|
|
/* Disable the transmitter data register empty interrupt for case: mb is interrupt (it was not use in above callback with the same index) */
|
|
(void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, u32MbIdx, FALSE, pState->isIntActive);
|
|
}
|
|
else if (((boolean)FALSE == bCurrentIntStat) && ((boolean)TRUE == pState->mbs[u32MbIdx].isPolling))
|
|
{
|
|
/* Disable the transmitter data register empty interrupt for case: switch from interrupt to polling for the same MB (called in above callback with same mb index) */
|
|
(void)FlexCAN_SetMsgBuffIntCmd(pBase, u8Instance, u32MbIdx, FALSE, pState->isIntActive);
|
|
}
|
|
else
|
|
{
|
|
/* Prevent misra */
|
|
/* When processing type change from POLL->POLL or INTERRUPT -> INTERRUPT(this Mb is used continously in callback), no need to disable interrupt in the ISR */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_IRQHandlerRxFIFO
|
|
* Description : Process IRQHandler in case of RxFIFO mode selection for CAN interface.
|
|
*
|
|
*END**************************************************************************/
|
|
static inline void FlexCAN_IRQHandlerRxFIFO(uint8 instance,
|
|
uint32 mb_idx)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
Flexcan_Ip_MsgBuffType data;
|
|
|
|
/* If use pass NULL_PTR, they can get data in callback function by getting state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage */
|
|
if (NULL_PTR == state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage)
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage = &data;
|
|
}
|
|
switch (mb_idx)
|
|
{
|
|
case CAN_LEGACY_RXFIFO_FRAME_AVAILABLE:
|
|
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_RX_BUSY)
|
|
{
|
|
/* Get RX FIFO field values */
|
|
FlexCAN_ReadRxFifo(base, state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage);
|
|
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_RXFIFO_COMPLETE, FLEXCAN_MB_HANDLE_RXFIFO, state);
|
|
}
|
|
|
|
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_IDLE)
|
|
{
|
|
/* reset to default value */
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].isPolling = (boolean)TRUE;
|
|
/* Complete receive data */
|
|
FlexCAN_CompleteRxMessageFifoData(instance);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case CAN_LEGACY_RXFIFO_WARNING:
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_RXFIFO_WARNING, FLEXCAN_MB_HANDLE_RXFIFO, state);
|
|
}
|
|
|
|
break;
|
|
case CAN_LEGACY_RXFIFO_OVERFLOW:
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_RXFIFO_OVERFLOW, FLEXCAN_MB_HANDLE_RXFIFO, state);
|
|
}
|
|
|
|
break;
|
|
default:
|
|
/* Do Nothing */
|
|
break;
|
|
}
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_ProcessSpuriousInterruptMB
|
|
* Description : clear Iflag when spurious interrupt occurred.
|
|
* note: just use in FlexCAN_IRQHandler
|
|
*END**************************************************************************/
|
|
static inline void FlexCAN_ProcessSpuriousInterruptMB(uint8 instance, uint32 startMbIdx, uint32 endMbIdx)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
uint32 mb_idx = 0U;
|
|
uint32 u32MbHandle = 0U;
|
|
|
|
/* Process spurious interrupt */
|
|
for (mb_idx = startMbIdx; mb_idx <= endMbIdx; mb_idx++)
|
|
{
|
|
if (((uint8)0U != FlexCAN_GetBuffStatusFlag(base, mb_idx)) && ((uint8)0U == FlexCAN_GetBuffStatusImask(base, mb_idx)))
|
|
{
|
|
u32MbHandle = mb_idx;
|
|
if (((boolean)TRUE == state->bIsLegacyFifoEn) && (mb_idx <= CAN_LEGACY_RXFIFO_OVERFLOW))
|
|
{
|
|
u32MbHandle = (uint32)FLEXCAN_MB_HANDLE_RXFIFO;
|
|
}
|
|
if (((boolean)FALSE == state->mbs[u32MbHandle].isPolling))
|
|
{
|
|
/* clear the MB flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
if (FLEXCAN_MB_TX_BUSY == state->mbs[u32MbHandle].state)
|
|
{
|
|
/* reset to default state */
|
|
state->mbs[u32MbHandle].state = FLEXCAN_MB_IDLE;
|
|
state->mbs[u32MbHandle].isPolling = (boolean)TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_ProcessIRQHandlerEnhancedRxFIFO
|
|
* Description : Process IRQHandler in case of Enhanced RxFIFO mode selection for CAN interface.
|
|
* note: just use in FlexCAN_IRQHandler
|
|
*END**************************************************************************/
|
|
static inline boolean FlexCAN_ProcessIRQHandlerEnhancedRxFIFO(uint8 u8Instance, boolean bIsSpuriousIntPrevious)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[u8Instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
uint32 u32intType = 0U;
|
|
boolean bIsSpuriousInt = bIsSpuriousIntPrevious;
|
|
|
|
/* Get the interrupts that are enabled and ready */
|
|
for (u32intType = CAN_ENHANCED_RXFIFO_UNDERFLOW; u32intType >= CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE; u32intType--)
|
|
{
|
|
if ((uint8)0U != FlexCAN_GetEnhancedRxFIFOStatusFlag(base, u32intType))
|
|
{
|
|
if ((uint8)0U != FlexCAN_GetEnhancedRxFIFOIntStatusFlag(base, u32intType))
|
|
{
|
|
FlexCAN_IRQHandlerEnhancedRxFIFO(u8Instance, u32intType);
|
|
bIsSpuriousInt = (boolean)FALSE;
|
|
}
|
|
/* just process spurious interrupt when no real interrupt at all */
|
|
else if (((boolean)TRUE == bIsSpuriousInt) && ((boolean)FALSE == state->enhancedFifoOutput.isPolling))
|
|
{
|
|
/* Process spurious interrupt */
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, u32intType);
|
|
}
|
|
else
|
|
{
|
|
/* prevent misra */
|
|
}
|
|
}
|
|
}
|
|
|
|
return bIsSpuriousInt;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_IRQHandlerEnhancedRxFIFO
|
|
* Description : Process IRQHandler in case of Enhanced RxFIFO mode selection for CAN interface.
|
|
*
|
|
* Implements : FLEXCAN_IRQHandlerEnyhancedRxFIFO_Activity
|
|
*END**************************************************************************/
|
|
static void FlexCAN_IRQHandlerEnhancedRxFIFO(uint8 instance,
|
|
uint32 intType)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
Flexcan_Ip_MsgBuffType data;
|
|
|
|
switch (intType)
|
|
{
|
|
case CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE:
|
|
if (state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY)
|
|
{
|
|
/* If use pass NULL_PTR, they can get data in callback function by getting state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage */
|
|
if (NULL_PTR == state->enhancedFifoOutput.pMBmessage)
|
|
{
|
|
state->enhancedFifoOutput.pMBmessage = &data;
|
|
}
|
|
|
|
/* Get Enhanced RX FIFO field values */
|
|
FlexCAN_ReadEnhancedRxFifo(base, state->enhancedFifoOutput.pMBmessage);
|
|
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_WATERMARK);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_OVERFLOW);
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_COMPLETE, FLEXCAN_MB_ENHANCED_RXFIFO, state);
|
|
}
|
|
|
|
if (state->enhancedFifoOutput.state == FLEXCAN_MB_IDLE)
|
|
{
|
|
/* Complete receive data */
|
|
FlexCAN_CompleteRxMessageEnhancedFifoData(instance);
|
|
}
|
|
}
|
|
|
|
break;
|
|
case CAN_ENHANCED_RXFIFO_WATERMARK:
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_WATERMARK, FLEXCAN_MB_ENHANCED_RXFIFO, state);
|
|
}
|
|
|
|
break;
|
|
case CAN_ENHANCED_RXFIFO_OVERFLOW:
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_OVERFLOW, FLEXCAN_MB_ENHANCED_RXFIFO, state);
|
|
}
|
|
|
|
break;
|
|
case CAN_ENHANCED_RXFIFO_UNDERFLOW:
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, intType);
|
|
|
|
/* Invoke callback */
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_ENHANCED_RXFIFO_UNDERFLOW, FLEXCAN_MB_ENHANCED_RXFIFO, state);
|
|
}
|
|
|
|
break;
|
|
default:
|
|
/* Do Nothing */
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
static void DMA_Can_Callback(uint8 instance)
|
|
{
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
|
|
{
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
|
|
{
|
|
/* Need to add handler for Enhaced RxFifoDataDMA */
|
|
FlexCAN_CompleteRxMessageEnhancedFifoData(instance);
|
|
}
|
|
else
|
|
{
|
|
FlexCAN_CompleteRxMessageFifoData(instance);
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
FlexCAN_CompleteRxMessageFifoData(instance);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_SetUserAccessAllowed
|
|
* Description : Sets the UAA bit in REG_PROT to make the instance accessible
|
|
* in user mode.
|
|
*
|
|
* This is not a public API as it is called from other driver functions.
|
|
*END**************************************************************************/
|
|
static void FlexCAN_SetUserAccessAllowed(const FLEXCAN_Type * pBase)
|
|
{
|
|
SET_USER_ACCESS_ALLOWED((uint32)pBase, FLEXCAN_PROT_MEM_U32);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_ClrUserAccessAllowed
|
|
* Description : Clears the UAA bit in REG_PROT to make the instance accessible
|
|
* in user mode.
|
|
*
|
|
* This is not a public API as it is called from other driver functions.
|
|
*END**************************************************************************/
|
|
static void FlexCAN_ClrUserAccessAllowed(const FLEXCAN_Type * pBase)
|
|
{
|
|
CLR_USER_ACCESS_ALLOWED((uint32)pBase, FLEXCAN_PROT_MEM_U32);
|
|
}
|
|
#endif /* (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE) */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_AbortTxTransfer
|
|
* Description : Abort transfer for Tx buffer.
|
|
*
|
|
* This is not a public API as it is called from other driver functions.
|
|
*END**************************************************************************/
|
|
static Flexcan_Ip_StatusType FlexCAN_AbortTxTransfer(uint8 u8Instance, uint8 mb_idx)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
uint32 timeStart = 0U;
|
|
uint32 timeElapsed = 0U;
|
|
uint32 flexcan_mb_config = 0;
|
|
uint32 uS2Ticks = 0U;
|
|
volatile uint32 * flexcan_mb = NULL_PTR;
|
|
|
|
flexcan_mb = FlexCAN_GetMsgBuffRegion(pBase, mb_idx);
|
|
flexcan_mb_config = * flexcan_mb;
|
|
/* Reset the code */
|
|
flexcan_mb_config &= (~CAN_CS_CODE_MASK);
|
|
flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_TX_ABORT & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
|
|
*flexcan_mb = flexcan_mb_config;
|
|
|
|
/* Wait to finish abort operation */
|
|
uS2Ticks = OsIf_MicrosToTicks(CAN_TIMEOUT_DURATION, CAN_SERVICE_TIMEOUT_TYPE);
|
|
timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
|
|
while (FlexCAN_GetBuffStatusFlag(pBase, mb_idx) == 0U)
|
|
{
|
|
timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
|
|
if (timeElapsed >= uS2Ticks)
|
|
{
|
|
result = FLEXCAN_STATUS_TIMEOUT;
|
|
break;
|
|
}
|
|
}
|
|
if (result != FLEXCAN_STATUS_TIMEOUT)
|
|
{
|
|
flexcan_mb_config = *flexcan_mb;
|
|
/* Check if the MBs have been safely Inactivated */
|
|
if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_INACTIVE)
|
|
{
|
|
/* Transmission have occurred */
|
|
result = FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
|
|
}
|
|
|
|
if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_ABORT)
|
|
{
|
|
/* Transmission have been aborted */
|
|
result = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
}
|
|
/* Clear message buffer flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(pBase, mb_idx);
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_AbortRxTransfer
|
|
* Description : Abort transfer for Rx normal or legacy fifo if enabled.
|
|
*
|
|
* This is not a public API as it is called from other driver functions.
|
|
*END**************************************************************************/
|
|
static void FlexCAN_AbortRxTransfer(uint8 u8Instance,
|
|
uint8 mb_idx)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
uint32 val1 = 0U;
|
|
uint32 val2 = 0U;
|
|
uint32 flexcan_mb_config = 0;
|
|
volatile uint32 * flexcan_mb = NULL_PTR;
|
|
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
|
|
/* Check if fifo enabled */
|
|
if ((boolean)TRUE == state->bIsLegacyFifoEn)
|
|
{
|
|
/* Get the number of RX FIFO Filters*/
|
|
val1 = (((pBase->CTRL2) & FLEXCAN_CTRL2_RFFN_MASK) >> FLEXCAN_CTRL2_RFFN_SHIFT);
|
|
/* 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 = RxFifoOcuppiedLastMsgBuff(val1);
|
|
if (mb_idx > val2)
|
|
{
|
|
/* This operation is not allowed for MB that are part of RxFIFO */
|
|
flexcan_mb = FlexCAN_GetMsgBuffRegion(pBase, mb_idx);
|
|
flexcan_mb_config = * flexcan_mb;
|
|
/* Reset the code and unlock the MB */
|
|
flexcan_mb_config &= (uint32)(~CAN_CS_CODE_MASK);
|
|
flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_INACTIVE & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
|
|
*flexcan_mb = flexcan_mb_config;
|
|
/* Reconfigure The MB as left by RxMBconfig */
|
|
flexcan_mb_config &= (~CAN_CS_CODE_MASK);
|
|
flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_EMPTY & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
|
|
*flexcan_mb = flexcan_mb_config;
|
|
}
|
|
if (FLEXCAN_MB_HANDLE_RXFIFO == mb_idx)
|
|
{
|
|
FLEXCAN_ClearMsgBuffIntCmd(pBase, u8Instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, state->isIntActive);
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
(void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* This operation is not allowed for MB that are part of RxFIFO */
|
|
flexcan_mb = FlexCAN_GetMsgBuffRegion(pBase, mb_idx);
|
|
flexcan_mb_config = * flexcan_mb;
|
|
/* Reset the code and unlock the MB */
|
|
flexcan_mb_config &= (~CAN_CS_CODE_MASK);
|
|
flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_INACTIVE & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
|
|
*flexcan_mb = flexcan_mb_config;
|
|
/* Reconfigure The MB as left by RxMBconfig */
|
|
flexcan_mb_config &= (~CAN_CS_CODE_MASK);
|
|
flexcan_mb_config |= (uint32)(((uint32)FLEXCAN_RX_EMPTY & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK;
|
|
*flexcan_mb = flexcan_mb_config;
|
|
}
|
|
/* Clear message buffer flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(pBase, mb_idx);
|
|
}
|
|
/*==================================================================================================
|
|
* GLOBAL FUNCTIONS
|
|
==================================================================================================*/
|
|
/* implements FlexCAN_Ip_Init_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_Init_Privileged(uint8 Flexcan_Ip_u8Instance,
|
|
Flexcan_Ip_StateType * Flexcan_Ip_pState,
|
|
const Flexcan_Ip_ConfigType * Flexcan_Ip_pData)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[Flexcan_Ip_u8Instance];
|
|
uint32 i;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(Flexcan_Ip_u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(Flexcan_Ip_pData != NULL_PTR);
|
|
#endif
|
|
|
|
#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
|
|
/* Set the UAA bit in REG_PROT to make the instance accessible in user mode */
|
|
if (Flexcan_Ip_u8Instance < FLEXCAN_CTRL_REG_PROT_SUPPORT_U8)
|
|
{
|
|
OsIf_Trusted_Call1param(FlexCAN_SetUserAccessAllowed, pBase);
|
|
}
|
|
#endif
|
|
|
|
eResult = FlexCAN_InitController(pBase, Flexcan_Ip_pData);
|
|
if (FLEXCAN_STATUS_SUCCESS == eResult)
|
|
{
|
|
/* Enable the use of extended bit time definitions */
|
|
FlexCAN_EnableExtCbt(pBase, Flexcan_Ip_pData->fd_enable);
|
|
|
|
if(Flexcan_Ip_pData->enhCbtEnable)
|
|
{
|
|
/* Start critical section: implementation depends on integrator */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();
|
|
/* Enable Enhanced CBT time segments */
|
|
pBase->CTRL2 |= FLEXCAN_CTRL2_BTE_MASK;
|
|
FlexCAN_SetEnhancedNominalTimeSegments(pBase, &Flexcan_Ip_pData->bitrate);
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
if (Flexcan_Ip_pData->fd_enable)
|
|
{
|
|
FlexCAN_SetEnhancedDataTimeSegments(pBase, &Flexcan_Ip_pData->bitrate_cbt);
|
|
}
|
|
#endif
|
|
/* End critical section: implementation depends on integrator */
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
|
|
}
|
|
else
|
|
{
|
|
/* Start critical section: implementation depends on integrator */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_00();
|
|
/* Disable Enhanced CBT time segments */
|
|
pBase->CTRL2 &= ~FLEXCAN_CTRL2_BTE_MASK;
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
/* Set bit rate. */
|
|
if (Flexcan_Ip_pData->fd_enable)
|
|
{
|
|
/* Write Normal bit time configuration to CBT register */
|
|
FlexCAN_SetExtendedTimeSegments(pBase, &Flexcan_Ip_pData->bitrate);
|
|
/* Write Data bit time configuration to FDCBT register */
|
|
FlexCAN_SetFDTimeSegments(pBase, &Flexcan_Ip_pData->bitrate_cbt);
|
|
}
|
|
else
|
|
{
|
|
/* Write Normal bit time configuration to CTRL1 register */
|
|
FlexCAN_SetTimeSegments(pBase, &Flexcan_Ip_pData->bitrate);
|
|
}
|
|
#endif
|
|
/* End critical section: implementation depends on integrator */
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_00();
|
|
}
|
|
|
|
/* Select mode */
|
|
FlexCAN_SetOperationMode(pBase, Flexcan_Ip_pData->flexcanMode);
|
|
|
|
#if (STD_ON == FLEXCAN_ENABLE_USER_MODE_SUPPORT)
|
|
#if (STD_ON == FEATURE_CAN_HAS_SUPV)
|
|
pBase->MCR = (pBase->MCR & ~FLEXCAN_MCR_SUPV_MASK) | FLEXCAN_MCR_SUPV(0U);
|
|
#endif
|
|
#endif
|
|
|
|
/* Leave driver in FreezMode if successfully initialized */
|
|
eResult = FlexCAN_EnterFreezeMode(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS == eResult)
|
|
{
|
|
#if (FEATURE_CAN_HAS_HR_TIMER == STD_ON)
|
|
FlexCAN_ConfigTimestamp(pBase, (Flexcan_Ip_TimeStampConfigType *)&Flexcan_Ip_pData->time_stamp);
|
|
#endif /* (FEATURE_CAN_HAS_HR_TIMER == STD_ON) */
|
|
|
|
for (i = 0; i < (uint8)FEATURE_CAN_MAX_MB_NUM; i++)
|
|
{
|
|
/* Check if blocking need to be any more present in sync\async discussions */
|
|
/* Sync up isPolling status with hw (Imask), at the begining all Imask = 0 => isPolling = TRUE */
|
|
Flexcan_Ip_pState->mbs[i].isPolling = (boolean)TRUE;
|
|
Flexcan_Ip_pState->mbs[i].pMBmessage = NULL_PTR;
|
|
Flexcan_Ip_pState->mbs[i].state = FLEXCAN_MB_IDLE;
|
|
Flexcan_Ip_pState->mbs[i].time_stamp = 0U;
|
|
}
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
/* Sync up isPolling status with hw (Imask), at the begining all Imask = 0 => isPolling = TRUE */
|
|
Flexcan_Ip_pState->enhancedFifoOutput.isPolling = (boolean)TRUE;
|
|
Flexcan_Ip_pState->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
#endif
|
|
|
|
Flexcan_Ip_pState->transferType = Flexcan_Ip_pData->transfer_type;
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
Flexcan_Ip_pState->rxFifoDMAChannel = Flexcan_Ip_pData->rxFifoDMAChannel;
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
Flexcan_Ip_pState->u32NumOfMbTransferByDMA = Flexcan_Ip_pData->num_enhanced_watermark;
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
#endif
|
|
|
|
/* Clear Callbacks in case of autovariables garbage */
|
|
Flexcan_Ip_pState->callback = Flexcan_Ip_pData->Callback;
|
|
Flexcan_Ip_pState->callbackParam = NULL_PTR;
|
|
Flexcan_Ip_pState->error_callback = Flexcan_Ip_pData->ErrorCallback;
|
|
Flexcan_Ip_pState->errorCallbackParam = NULL_PTR;
|
|
Flexcan_Ip_pState->bIsLegacyFifoEn = Flexcan_Ip_pData->is_rx_fifo_needed;
|
|
Flexcan_Ip_pState->u32MaxMbNum = Flexcan_Ip_pData->max_num_mb;
|
|
Flexcan_Ip_pState->isIntActive = TRUE;
|
|
/* Save runtime structure pointers so irq handler can point to the correct state structure */
|
|
g_flexcan_Ip_StatePtr[Flexcan_Ip_u8Instance] = Flexcan_Ip_pState;
|
|
}
|
|
}
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_DRV_Send
|
|
* Description : This function sends a CAN frame using a configured message
|
|
* buffer. The function returns immediately. If a callback is installed, it will
|
|
* be invoked after the frame was sent.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_Send_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_Send(uint8 instance,
|
|
uint8 mb_idx,
|
|
const Flexcan_Ip_DataInfoType * tx_info,
|
|
uint32 msg_id,
|
|
const uint8 * mb_data)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
#else
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#endif
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(tx_info != NULL_PTR);
|
|
#endif
|
|
if(!FlexCAN_IsListenOnlyModeEnabled(base))
|
|
{
|
|
result = FlexCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data);
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
if ((FLEXCAN_STATUS_SUCCESS == result) && (FALSE == tx_info->is_polling))
|
|
{
|
|
/* Enable message buffer interrupt*/
|
|
result = FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, TRUE, state->isIntActive);
|
|
}
|
|
#endif
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ConfigMb
|
|
* Description : Configure a Rx message buffer.
|
|
* 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 set up the message buffer fields,
|
|
* configure the message buffer code for Rx message buffer as NOT_USED, enable
|
|
* the Message Buffer interrupt, configure the message buffer code for Rx
|
|
* message buffer as INACTIVE, copy user's buffer into the message buffer data
|
|
* area, and configure the message buffer code for Rx message buffer as EMPTY.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ConfigRxMb_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigRxMb(uint8 instance,
|
|
uint8 mb_idx,
|
|
const Flexcan_Ip_DataInfoType * rx_info,
|
|
uint32 msg_id)
|
|
{
|
|
Flexcan_Ip_StatusType eResult = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_MsbuffCodeStatusType cs;
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(rx_info != NULL_PTR);
|
|
|
|
if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(base, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
|
|
{
|
|
eResult = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
/* Clear the message buffer flag if previous remained triggered */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
cs.dataLen = rx_info->data_length;
|
|
cs.msgIdType = rx_info->msg_id_type;
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
cs.fd_enable = rx_info->fd_enable;
|
|
#endif
|
|
|
|
/* Initialize rx mb*/
|
|
cs.code = (uint32)FLEXCAN_RX_NOT_USED;
|
|
FlexCAN_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
|
|
|
|
/* Initialize receive MB*/
|
|
cs.code = (uint32)FLEXCAN_RX_INACTIVE;
|
|
FlexCAN_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
|
|
|
|
/* Set up FlexCAN message buffer fields for receiving data*/
|
|
cs.code = (uint32)FLEXCAN_RX_EMPTY;
|
|
FlexCAN_SetRxMsgBuff(base, mb_idx, &cs, msg_id);
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
}
|
|
#endif
|
|
return eResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_Receive
|
|
* Description : This function receives a CAN frame into a configured message
|
|
* buffer. The function returns immediately. If a callback is installed, it will
|
|
* be invoked after the frame was received and read into the specified buffer.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_Receive_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_Receive(uint8 instance,
|
|
uint8 mb_idx,
|
|
Flexcan_Ip_MsgBuffType * data,
|
|
boolean isPolling)
|
|
{
|
|
|
|
Flexcan_Ip_StatusType result;
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
#endif
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
result = FlexCAN_StartRxMessageBufferData(instance, mb_idx, data, isPolling);
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
if ((result == FLEXCAN_STATUS_SUCCESS) && (FALSE == isPolling))
|
|
{
|
|
/* Enable MB interrupt*/
|
|
result = FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, TRUE, state->isIntActive);
|
|
}
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ReceiveBlocking
|
|
* Description : This function receives a CAN frame into a configured message
|
|
* buffer. The function blocks until either a frame was received, or the
|
|
* specified timeout expired.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ReceiveBlocking_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ReceiveBlocking(uint8 instance,
|
|
uint8 mb_idx,
|
|
Flexcan_Ip_MsgBuffType * data,
|
|
boolean isPolling,
|
|
uint32 u32TimeoutMs)
|
|
{
|
|
Flexcan_Ip_StatusType result;
|
|
uint32 timeStart = 0U;
|
|
uint32 timeElapsed = 0U;
|
|
uint32 mS2Ticks = OsIf_MicrosToTicks((u32TimeoutMs * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#else
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#endif
|
|
result = FlexCAN_StartRxMessageBufferData(instance, mb_idx, data, isPolling);
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
if ((result == FLEXCAN_STATUS_SUCCESS) && (FALSE == isPolling))
|
|
{
|
|
/* Enable MB interrupt*/
|
|
result = FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, TRUE, state->isIntActive);
|
|
}
|
|
#endif
|
|
if (FLEXCAN_STATUS_SUCCESS == result)
|
|
{
|
|
timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
|
|
while (FLEXCAN_MB_RX_BUSY == state->mbs[mb_idx].state)
|
|
{
|
|
if (TRUE == isPolling)
|
|
{
|
|
if (FlexCAN_GetBuffStatusFlag(base, mb_idx) != 0U)
|
|
{
|
|
FlexCAN_IRQHandlerRxMB(instance, mb_idx);
|
|
}
|
|
}
|
|
timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
|
|
if (timeElapsed >= mS2Ticks)
|
|
{
|
|
result = FLEXCAN_STATUS_TIMEOUT;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((FLEXCAN_STATUS_TIMEOUT == result) && (FALSE == isPolling))
|
|
{
|
|
#if (CAN_MB_INTERRUPT_SUPPORT == STD_ON)
|
|
/* Disable Mb interrupt*/
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, mb_idx, (boolean)FALSE, state->isIntActive);
|
|
#endif
|
|
}
|
|
|
|
if ((FLEXCAN_STATUS_BUFF_OUT_OF_RANGE != result) && (FLEXCAN_STATUS_BUSY != result))
|
|
{
|
|
if ((FLEXCAN_MB_IDLE == state->mbs[mb_idx].state))
|
|
{
|
|
result = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
|
|
result = FLEXCAN_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
|
|
void DMA_Can_Callback0(void)
|
|
{ DMA_Can_Callback(0U); }
|
|
|
|
#if FLEXCAN_INSTANCE_COUNT > 1U
|
|
void DMA_Can_Callback1(void)
|
|
{ DMA_Can_Callback(1U); }
|
|
#endif
|
|
#if FLEXCAN_INSTANCE_COUNT > 2U
|
|
void DMA_Can_Callback2(void)
|
|
{ DMA_Can_Callback(2U); }
|
|
#endif
|
|
#if FLEXCAN_INSTANCE_COUNT > 3U
|
|
void DMA_Can_Callback3(void)
|
|
{ DMA_Can_Callback(3U); }
|
|
#endif
|
|
#if FLEXCAN_INSTANCE_COUNT > 4U
|
|
void DMA_Can_Callback4(void)
|
|
{ DMA_Can_Callback(4U); }
|
|
#endif
|
|
#if FLEXCAN_INSTANCE_COUNT > 5U
|
|
void DMA_Can_Callback5(void)
|
|
{ DMA_Can_Callback(5U); }
|
|
#endif
|
|
#if FLEXCAN_INSTANCE_COUNT > 6U
|
|
void DMA_Can_Callback6(void)
|
|
{ DMA_Can_Callback(6U); }
|
|
#endif
|
|
|
|
|
|
#endif /* FEATURE_CAN_HAS_DMA_ENABLE */
|
|
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_RxFifo
|
|
* Description : This function receives a CAN frame using the Rx FIFO or
|
|
* Enhanced Rx FIFO (if available and enabled). If use Enhanced Rx FIFO, the size of
|
|
* the data array will be considered the same as the configured FIFO watermark.
|
|
* The function returns immediately. If a callback is installed, it will be invoked
|
|
* after the frame was received and read into the specified buffer.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_RxFifo_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_RxFifo(uint8 instance,
|
|
Flexcan_Ip_MsgBuffType * data)
|
|
{
|
|
#ifdef MCAL_ENABLE_FAULT_INJECTION
|
|
/* Fault injection point to test dma error event */
|
|
MCAL_FAULT_INJECTION_POINT(CAN_FIP_0_DMA_ERROR_EVENT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
|
|
{
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
|
|
{
|
|
result = FlexCAN_StartRxMessageEnhancedFifoData(instance, data);
|
|
}
|
|
else
|
|
{
|
|
result = FlexCAN_StartRxMessageFifoData(instance, data);
|
|
}
|
|
}
|
|
else
|
|
#endif /*FEATURE_CAN_HAS_ENHANCED_RX_FIFO*/
|
|
{
|
|
result = FlexCAN_StartRxMessageFifoData(instance, data);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_RxFifoBlocking
|
|
* Description : This function receives a CAN frame using the Rx FIFO or
|
|
* Enhanced Rx FIFO (if available and enabled). If use Enhanced Rx FIFO, the size of
|
|
* the data array will be considered the same as the configured FIFO watermark.
|
|
* The function blocks until either a frame was received, or the specified timeout expired.
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
/* implements FlexCAN_Ip_RxFifoBlocking_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_RxFifoBlocking(uint8 instance, Flexcan_Ip_MsgBuffType *data, uint32 timeout)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
|
|
{
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
|
|
{
|
|
result = FlexCAN_StartRxMessageEnhancedFifoData(instance, data);
|
|
if (FLEXCAN_STATUS_SUCCESS == result)
|
|
{
|
|
result = FlexCAN_ProccessEnhancedRxFifo(instance, timeout);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = FlexCAN_StartRxMessageFifoData(instance, data);
|
|
if (FLEXCAN_STATUS_SUCCESS == result)
|
|
{
|
|
result = FlexCAN_ProccessLegacyRxFIFO(instance, timeout);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
#endif /*FEATURE_CAN_HAS_ENHANCED_RX_FIFO*/
|
|
{
|
|
result = FlexCAN_StartRxMessageFifoData(instance, data);
|
|
if (FLEXCAN_STATUS_SUCCESS == result)
|
|
{
|
|
result = FlexCAN_ProccessLegacyRxFIFO(instance, timeout);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ConfigRxFifo
|
|
* Description : Confgure RX FIFO ID filter table elements.
|
|
* This function will confgure RX FIFO ID filter table elements, and enable RX
|
|
* FIFO interrupts.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ConfigRxFifo_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigRxFifo_Privileged(uint8 instance,
|
|
Flexcan_Ip_RxFifoIdElementFormatType id_format,
|
|
const Flexcan_Ip_IdTableType * id_filter_table)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
/* Initialize rx fifo*/
|
|
FlexCAN_SetRxFifoFilter(pBase, id_format, id_filter_table);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ConfigEnhancedRxFifo
|
|
* Description : Confgure Enhanced RX FIFO ID filter table elements.
|
|
* This function will confgure Enhanced RX FIFO ID filter table elements, and enable Enhanced RX
|
|
* FIFO interrupts.
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ConfigEnhancedRxFifo_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigEnhancedRxFifo_Privileged(uint8 instance,
|
|
const Flexcan_Ip_EnhancedIdTableType * id_filter_table)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(FlexCAN_IsEnhancedRxFifoAvailable(pBase));
|
|
DevAssert(id_filter_table != NULL_PTR);
|
|
#endif
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
/* Initialize rx fifo*/
|
|
FlexCAN_SetEnhancedRxFifoFilter(pBase, id_filter_table);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ConfigRemoteResponseMb
|
|
* Description : Configures a transmit message buffer for remote frame
|
|
* response. 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
|
|
* the RX FIFO and ID filter table. Then this function will set up the message
|
|
* buffer fields, configure the message buffer code for Tx buffer as RX_RANSWER,
|
|
* and enable the Message Buffer interrupt if required by user.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ConfigRemoteResponseMb_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigRemoteResponseMb(uint8 instance,
|
|
uint8 mb_idx,
|
|
const Flexcan_Ip_DataInfoType *tx_info,
|
|
uint32 msg_id,
|
|
const uint8 *mb_data)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_MsbuffCodeStatusType cs;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * const state = g_flexcan_Ip_StatePtr[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(tx_info != NULL_PTR);
|
|
|
|
if ((boolean)TRUE == FlexCAN_IsMbOutOfRange(pBase, mb_idx, state->bIsLegacyFifoEn, state->u32MaxMbNum))
|
|
{
|
|
result = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
|
|
}
|
|
#endif
|
|
if (FLEXCAN_STATUS_SUCCESS == result)
|
|
{
|
|
/* Initialize transmit mb*/
|
|
cs.dataLen = tx_info->data_length;
|
|
cs.msgIdType = tx_info->msg_id_type;
|
|
cs.code = (uint32)FLEXCAN_RX_RANSWER;
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
cs.fd_enable = (boolean)FALSE;
|
|
#endif
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(pBase, mb_idx);
|
|
FlexCAN_SetTxMsgBuff(pBase, mb_idx, &cs, msg_id, mb_data, tx_info->is_remote);
|
|
if (tx_info->is_polling == FALSE)
|
|
{
|
|
/* Enable MB interrupt*/
|
|
result = FlexCAN_SetMsgBuffIntCmd(pBase, instance, mb_idx, TRUE, state->isIntActive);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetTransferStatus
|
|
* Description : This function returns whether the previous FLEXCAN receive is
|
|
* completed.
|
|
* When performing a non-blocking receive, the user can call this function to
|
|
* ascertain the state of the current receive progress: in progress (or busy)
|
|
* or complete (success). In case Enhanced Rx Fifo, mb_idx will be 255.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetTransferStatus_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_GetTransferStatus(uint8 instance,
|
|
uint8 mb_idx)
|
|
{
|
|
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_ERROR;
|
|
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert((mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM) || (mb_idx == 255u));
|
|
#endif
|
|
|
|
if (mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM)
|
|
{
|
|
if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
|
|
{
|
|
status = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
else if (state->mbs[mb_idx].state == FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
status = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
status = FLEXCAN_STATUS_BUSY;
|
|
}
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
else
|
|
{
|
|
if (state->enhancedFifoOutput.state == FLEXCAN_MB_IDLE)
|
|
{
|
|
status = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
else if (state->enhancedFifoOutput.state == FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
status = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
status = FLEXCAN_STATUS_BUSY;
|
|
}
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
|
|
return status;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_CompleteRxMessageFifoData
|
|
* Description : Finish up a receive by completing the process of receiving
|
|
* data and disabling the interrupt.
|
|
* This is not a public API as it is called from other driver functions.
|
|
*
|
|
*END**************************************************************************/
|
|
static void FlexCAN_CompleteRxMessageFifoData(uint8 instance)
|
|
{
|
|
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
if (state->transferType == FLEXCAN_RXFIFO_USING_INTERRUPTS)
|
|
{
|
|
/* Disable RX FIFO interrupts*/
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE, FALSE, state->isIntActive);
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_WARNING, FALSE, state->isIntActive);
|
|
(void)FlexCAN_SetMsgBuffIntCmd(base, instance, CAN_LEGACY_RXFIFO_OVERFLOW, FALSE, state->isIntActive);
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
else if (state->transferType == FLEXCAN_RXFIFO_USING_DMA)
|
|
{
|
|
Dma_Ip_LogicChannelStatusType dmaStatus;
|
|
Dma_Ip_GetLogicChannelStatus(state->rxFifoDMAChannel, &dmaStatus);
|
|
|
|
if (dmaStatus.ChStateValue == DMA_IP_CH_ERROR_STATE)
|
|
{
|
|
(void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_ERROR);
|
|
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_DMA_ERROR;
|
|
}
|
|
|
|
(void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
|
|
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state != FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
Flexcan_Ip_MsgBuffType * fifo_message = state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage;
|
|
uint32 * msgData_32 = (uint32 *)fifo_message->data;
|
|
|
|
/* Adjust the ID if it is not extended */
|
|
if (((fifo_message->cs) & CAN_CS_IDE_MASK) == 0U)
|
|
{
|
|
fifo_message->msgId = fifo_message->msgId >> CAN_ID_STD_SHIFT;
|
|
}
|
|
|
|
/* Extract the data length */
|
|
fifo_message->dataLen = (uint8)((fifo_message->cs & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
|
|
/* Extract the IDHIT */
|
|
fifo_message->id_hit = (uint8)((fifo_message->cs & CAN_CS_IDHIT_MASK) >> CAN_CS_IDHIT_SHIFT);
|
|
/* Extract the Time Stamp */
|
|
fifo_message->time_stamp = (uint32)((fifo_message->cs & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
|
|
/* Reverse the endianness */
|
|
FlexcanSwapBytesInWord(msgData_32[0], msgData_32[0]);
|
|
FlexcanSwapBytesInWord(msgData_32[1], msgData_32[1]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* do nothing when transferType is POLLING */
|
|
}
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
/* Clear fifo message*/
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].pMBmessage = NULL_PTR;
|
|
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state != FLEXCAN_MB_DMA_ERROR)
|
|
{
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
if ((state->callback != NULL_PTR) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_DMA_COMPLETE, FLEXCAN_MB_HANDLE_RXFIFO, state);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (state->callback != NULL_PTR)
|
|
{
|
|
state->callback(instance, FLEXCAN_EVENT_DMA_ERROR, FLEXCAN_MB_HANDLE_RXFIFO, state);
|
|
}
|
|
}
|
|
|
|
#else
|
|
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_IRQHandler
|
|
* Description : Interrupt handler for FLEXCAN.
|
|
* This handler read data from MB or FIFO, and then clear the interrupt flags.
|
|
* This is not a public API as it is called whenever an interrupt occurs.
|
|
* Spurious interrupt implementation:
|
|
* This handler will process only one Normal Buffers (tx or rx or legacy fifo)
|
|
* and Enhance FIFO(if supported). The processing of spurious interrupt will be
|
|
* done when there is no real interrupt(both IF and IE are set) at all.
|
|
* If a spurious interrupt found:
|
|
* - for Rx (Rx normal, Legacy FIFO, Enhanced FIFO): Just clear IF and exit,
|
|
* the Buffer is still ready to receive a new Frame.
|
|
* - for Tx: Clear IF and reset the Buffer to default state to ready to use in next time.
|
|
*END**************************************************************************/
|
|
/* implements CAN_X_MB_Y_ISR_Activity */
|
|
void FlexCAN_IRQHandler
|
|
(
|
|
uint8 instance,
|
|
uint32 startMbIdx,
|
|
uint32 endMbIdx
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
,boolean bEnhancedFifoExisted
|
|
#endif
|
|
)
|
|
{
|
|
uint32 u32MbHandle = 0U;
|
|
uint32 flag_reg = 0;
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
boolean bIsSpuriousInt = (boolean)TRUE;
|
|
/* Get the interrupts that are enabled and ready */
|
|
uint32 mb_idx = endMbIdx;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(endMbIdx < (uint8)FEATURE_CAN_MAX_MB_NUM);
|
|
#endif
|
|
/* Check if instance initialized */
|
|
if (NULL_PTR != state)
|
|
{
|
|
flag_reg = FlexCAN_GetMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
while ((0U == flag_reg) && (mb_idx > startMbIdx))
|
|
{
|
|
mb_idx--;
|
|
flag_reg = FlexCAN_GetMsgBuffIntStatusFlag(base, mb_idx);
|
|
}
|
|
|
|
/* Check Tx/Rx interrupt flag and clear the interrupt */
|
|
if (flag_reg != 0U)
|
|
{
|
|
/* At least one real interrupt -> no process spurious interurpt */
|
|
bIsSpuriousInt = (boolean)FALSE;
|
|
|
|
/* For legacy fifo, mb handler is FLEXCAN_MB_HANDLE_RXFIFO(0) */
|
|
u32MbHandle = mb_idx;
|
|
|
|
if (((boolean)TRUE == state->bIsLegacyFifoEn) && (mb_idx <= CAN_LEGACY_RXFIFO_OVERFLOW))
|
|
{
|
|
FlexCAN_IRQHandlerRxFIFO(instance, mb_idx);
|
|
u32MbHandle = (uint32)FLEXCAN_MB_HANDLE_RXFIFO;
|
|
}
|
|
else
|
|
{
|
|
/* Check mailbox completed reception */
|
|
if (state->mbs[u32MbHandle].state == FLEXCAN_MB_RX_BUSY)
|
|
{
|
|
FlexCAN_IRQHandlerRxMB(instance, mb_idx);
|
|
}
|
|
}
|
|
|
|
/* Check mailbox completed transmission */
|
|
if (state->mbs[u32MbHandle].state == FLEXCAN_MB_TX_BUSY)
|
|
{
|
|
FlexCAN_IRQHandlerTxMB(instance, mb_idx);
|
|
}
|
|
|
|
/* Check for spurious interrupt */
|
|
if (FlexCAN_GetMsgBuffIntStatusFlag(base, mb_idx) != 0U)
|
|
{
|
|
if (state->mbs[u32MbHandle].state == FLEXCAN_MB_IDLE)
|
|
{
|
|
/* In case of desynchronized status of the MB to avoid trapping in ISR
|
|
* clear the MB flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
if ((boolean)TRUE == bEnhancedFifoExisted)
|
|
{
|
|
if (((boolean)TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base)) && (FLEXCAN_RXFIFO_USING_INTERRUPTS == state->transferType))
|
|
{
|
|
bIsSpuriousInt = FlexCAN_ProcessIRQHandlerEnhancedRxFIFO(instance, bIsSpuriousInt);
|
|
}
|
|
}
|
|
#endif /* End of (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
|
|
|
|
/* continue processing spurious interrupt for normal Mb only if enhance fifo interrupt is not existed on ISR or no enhance fifo interrupts occurred */
|
|
/* Expectation is that ISR just process one Object (Tx, Rx normal, Rx legacy fifo, Rx enhance fifo) when ISR triggered */
|
|
if ((boolean)TRUE == bIsSpuriousInt)
|
|
{
|
|
FlexCAN_ProcessSpuriousInterruptMB(instance, startMbIdx, endMbIdx);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Clear all interrupt flags when driver is not initialized */
|
|
/* Process spurious interrupt */
|
|
for (mb_idx = startMbIdx; mb_idx <= endMbIdx; mb_idx++)
|
|
{
|
|
/* clear the MB flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
}
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
/* Check if Enhance fifo interrupt existed on the ISR! */
|
|
if ((boolean)TRUE == bEnhancedFifoExisted)
|
|
{
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_WATERMARK);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_OVERFLOW);
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(base, CAN_ENHANCED_RXFIFO_UNDERFLOW);
|
|
}
|
|
#endif /* End of (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ClearErrorStatus
|
|
* Description : Clears various error conditions detected in the reception and
|
|
* transmission of a CAN frame.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ClearErrorStatus_Activity */
|
|
void FlexCAN_Ip_ClearErrorStatus(uint8 instance, uint32 error)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
base->ESR1 = error;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetErrorStatus
|
|
* Description : Reports various error conditions detected in the reception and
|
|
* transmission of a CAN frame and some general status of the device.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetErrorStatus_Activity */
|
|
uint32 FlexCAN_Ip_GetErrorStatus(uint8 instance)
|
|
{
|
|
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
return (uint32)(base->ESR1);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetControllerTxErrorCounter
|
|
* Description : Reports Transmit error counter for all errors detected in
|
|
* transmitted messages.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetControllerTxErrorCounter_Activity */
|
|
uint8 FlexCAN_Ip_GetControllerTxErrorCounter(uint8 instance)
|
|
{
|
|
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
return (uint8)((base->ECR & FLEXCAN_ECR_TXERRCNT_MASK) >> FLEXCAN_ECR_TXERRCNT_SHIFT);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetControllerRxErrorCounter
|
|
* Description : Reports Receive error counter for all errors detected in
|
|
* received messages.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetControllerRxErrorCounter_Activity */
|
|
uint8 FlexCAN_Ip_GetControllerRxErrorCounter(uint8 instance)
|
|
{
|
|
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
return (uint8)((base->ECR & FLEXCAN_ECR_RXERRCNT_MASK) >> FLEXCAN_ECR_RXERRCNT_SHIFT);
|
|
}
|
|
|
|
|
|
#if (FEATURE_CAN_BUSOFF_ERROR_INTERRUPT_UNIFIED == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Busoff_Error_IRQHandler
|
|
* Description : BusOff and Error interrupt handler for FLEXCAN.
|
|
* This is not a public API as it is called whenever an interrupt occurs.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements CAN_X_BUSOFF_ERROR_ISR_Activity */
|
|
void FlexCAN_Busoff_Error_IRQHandler(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
uint32 u32ErrStatus = 0U;
|
|
boolean isSpuriousInt = (boolean)TRUE;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
/* Check if the instance initialized */
|
|
if (NULL_PTR != state)
|
|
{
|
|
/* Get error status to get value updated */
|
|
u32ErrStatus = pBase->ESR1;
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_ERRMSK_MASK))))
|
|
{
|
|
pBase->ESR1 = FLEXCAN_ESR1_ERRINT_MASK;
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_ERROR, u32ErrStatus, state);
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = pBase->ESR1;
|
|
}
|
|
isSpuriousInt = (boolean)FALSE;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
/* Check if this is spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_FAST_MASK))) && ((uint32)0U != (pBase->CTRL2 & ((uint32)FLEXCAN_CTRL2_ERRMSK_FAST_MASK))))
|
|
{
|
|
pBase->ESR1 = FLEXCAN_ESR1_ERRINT_FAST_MASK;
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_ERROR_FAST, u32ErrStatus, state);
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = pBase->ESR1;
|
|
}
|
|
isSpuriousInt = (boolean)FALSE;
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_FD */
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_TWRNINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_TWRNMSK_MASK))))
|
|
{
|
|
pBase->ESR1 = FLEXCAN_ESR1_TWRNINT_MASK;
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_TX_WARNING, u32ErrStatus, state);
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = pBase->ESR1;
|
|
}
|
|
isSpuriousInt = (boolean)FALSE;
|
|
}
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_RWRNINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_RWRNMSK_MASK))))
|
|
{
|
|
pBase->ESR1 = FLEXCAN_ESR1_RWRNINT_MASK;
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_RX_WARNING, u32ErrStatus, state);
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = pBase->ESR1;
|
|
}
|
|
isSpuriousInt = (boolean)FALSE;
|
|
}
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_BOFFINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_BOFFMSK_MASK))))
|
|
{
|
|
pBase->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK;
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_BUSOFF, u32ErrStatus, state);
|
|
}
|
|
isSpuriousInt = (boolean)FALSE;
|
|
}
|
|
}
|
|
|
|
if ((boolean)TRUE == isSpuriousInt)
|
|
{
|
|
pBase->ESR1 = FLEXCAN_ALL_INT;
|
|
}
|
|
}
|
|
#else /* (FEATURE_CAN_BUSOFF_ERROR_INTERRUPT_UNIFIED == STD_OFF) */
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FLEXCAN_Error_IRQHandler
|
|
* Description : Error interrupt handler for FLEXCAN.
|
|
* This is not a public API as it is called whenever an interrupt occurs.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements CAN_X_ERROR_ISR_Activity */
|
|
void FlexCAN_Error_IRQHandler(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
uint32 u32ErrStatus = 0U;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
/* Check if the instance initialized */
|
|
if (NULL_PTR != state)
|
|
{
|
|
/* Get error status to get value updated */
|
|
u32ErrStatus = pBase->ESR1;
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_MASK))) && ((uint32)0U != (pBase->CTRL1 & ((uint32)FLEXCAN_CTRL1_ERRMSK_MASK))))
|
|
{
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_ERROR, u32ErrStatus, state);
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = pBase->ESR1;
|
|
#endif /* FEATURE_CAN_HAS_FD */
|
|
}
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
/* Check if this is spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_ERRINT_FAST_MASK))) && ((uint32)0U != (pBase->CTRL2 & ((uint32)FLEXCAN_CTRL2_ERRMSK_FAST_MASK))))
|
|
{
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_ERROR_FAST, u32ErrStatus, state);
|
|
}
|
|
}
|
|
#endif /* FEATURE_CAN_HAS_FD */
|
|
}
|
|
/* Clear all other interrupts in ESR1 register (Error, Wakeup) */
|
|
FlexCAN_ClearErrIntStatusFlag(pBase);
|
|
}
|
|
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_BusOff_IRQHandler
|
|
* Description : BusOff and Tx/Rx Warning interrupt handler for FLEXCAN.
|
|
* This handler only provides a error status report and invokes the user callback,
|
|
* and then clears the interrupt flags.
|
|
* This is not a public API as it is called whenever an interrupt occurs.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements CAN_X_BUSOFF_ISR_Activity */
|
|
void FlexCAN_BusOff_IRQHandler(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
uint32 u32ErrStatus = 0U;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
/* Check If Driver initialized */
|
|
if (NULL_PTR != state)
|
|
{
|
|
/* Get error status to get value updated */
|
|
u32ErrStatus = base->ESR1;
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_TWRNINT_MASK))) && (0U != (base->CTRL1 & ((uint32)FLEXCAN_CTRL1_TWRNMSK_MASK))))
|
|
{
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_TX_WARNING, u32ErrStatus, state);
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = base->ESR1;
|
|
}
|
|
}
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_RWRNINT_MASK))) && (0U != (base->CTRL1 & ((uint32)FLEXCAN_CTRL1_RWRNMSK_MASK))))
|
|
{
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_RX_WARNING, u32ErrStatus, state);
|
|
/* Get error status to get value updated due to user may handle ESR1 register */
|
|
u32ErrStatus = base->ESR1;
|
|
}
|
|
}
|
|
|
|
/* Check spurious interrupt */
|
|
if (((uint32)0U != (u32ErrStatus & ((uint32)FLEXCAN_ESR1_BOFFINT_MASK))) && ((uint32)0U != (base->CTRL1 & ((uint32)FLEXCAN_CTRL1_BOFFMSK_MASK))))
|
|
{
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_BUSOFF, u32ErrStatus, state);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Clear all BusOff and Tx/Rx Warning interrupts in ESR1 register */
|
|
FlexCAN_ClearBusOffIntStatusFlag(base);
|
|
}
|
|
#endif /* (FEATURE_CAN_BUSOFF_ERROR_INTERRUPT_UNIFIED) */
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SendBlocking
|
|
* Description : This function sends a CAN frame using a configured message
|
|
* buffer. The function blocks until either the frame was sent, or the specified
|
|
* timeout expired.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SendBlocking_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SendBlocking(uint8 instance,
|
|
uint8 mb_idx,
|
|
const Flexcan_Ip_DataInfoType * tx_info,
|
|
uint32 msg_id,
|
|
const uint8 * mb_data,
|
|
uint32 timeout_ms)
|
|
{
|
|
Flexcan_Ip_StatusType result;
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
|
|
uint32 timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
|
|
uint32 timeElapsed = 0U;
|
|
uint32 mS2Ticks = OsIf_MicrosToTicks((timeout_ms * 1000U), CAN_SERVICE_TIMEOUT_TYPE);
|
|
uint32 uS2Ticks = 0U;
|
|
uint32 flexcan_mb_config = 0;
|
|
|
|
volatile uint32 * flexcan_mb = NULL_PTR;
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(tx_info != NULL_PTR);
|
|
#endif
|
|
|
|
result = FlexCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data);
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
while(FlexCAN_GetBuffStatusFlag(base, mb_idx) != 1U)
|
|
{
|
|
timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
|
|
if (timeElapsed >= mS2Ticks)
|
|
{
|
|
result = FLEXCAN_STATUS_TIMEOUT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((result == FLEXCAN_STATUS_TIMEOUT) && (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE))
|
|
{
|
|
/* Clear message buffer flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
flexcan_mb = FlexCAN_GetMsgBuffRegion(base, mb_idx);
|
|
flexcan_mb_config = * flexcan_mb;
|
|
/* Reset the code */
|
|
flexcan_mb_config &= (uint32)(~CAN_CS_CODE_MASK);
|
|
flexcan_mb_config |= ((uint32)(((uint32)FLEXCAN_TX_ABORT & (uint32)0x1F) << (uint8)CAN_CS_CODE_SHIFT) & (uint32)CAN_CS_CODE_MASK);
|
|
*flexcan_mb = flexcan_mb_config;
|
|
|
|
/* Wait to finish abort operation */
|
|
uS2Ticks = OsIf_MicrosToTicks(CAN_TIMEOUT_DURATION, CAN_SERVICE_TIMEOUT_TYPE);
|
|
timeStart = OsIf_GetCounter(CAN_SERVICE_TIMEOUT_TYPE);
|
|
timeElapsed = 0U;
|
|
while (FlexCAN_GetBuffStatusFlag(base, mb_idx) == 0U)
|
|
{
|
|
timeElapsed += OsIf_GetElapsed(&timeStart, CAN_SERVICE_TIMEOUT_TYPE);
|
|
if (timeElapsed >= uS2Ticks)
|
|
{
|
|
result = FLEXCAN_STATUS_TIMEOUT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
flexcan_mb_config = *flexcan_mb;
|
|
/* Check if the MBs have been safely Inactivated */
|
|
if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_INACTIVE)
|
|
{
|
|
/* Transmission have occurred */
|
|
result = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32)FLEXCAN_TX_ABORT)
|
|
{
|
|
/* Transmission have been aborted */
|
|
result = FLEXCAN_STATUS_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Clear message buffer flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetRxMbGlobalMask
|
|
* Description : Set Rx Message Buffer global mask as the mask value provided.
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
/* implements FlexCAN_Ip_SetRxMbGlobalMask_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMbGlobalMask_Privileged(uint8 instance,
|
|
uint32 mask)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FALSE;
|
|
#endif
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
if (result == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
FlexCAN_SetRxMsgBuffGlobalMask(pBase, mask);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_EnterFreezeMode
|
|
* Description : Enter Driver In freeze Mode.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_EnterFreezeMode_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_EnterFreezeMode_Privileged(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
return FlexCAN_EnterFreezeMode(base);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ExitFreezeMode
|
|
* Description : Exit Driver from freeze Mode.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ExitFreezeMode_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ExitFreezeMode_Privileged(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
return FlexCAN_ExitFreezeMode(base);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetRxIndividualMask
|
|
* Description : Set Rx individual mask as absolute value provided by mask parameter
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetRxIndividualMask_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxIndividualMask_Privileged(uint8 instance,
|
|
uint8 mb_idx,
|
|
uint32 mask)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FALSE;
|
|
#endif
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
if ((mb_idx > (((pBase->MCR) & FLEXCAN_MCR_MAXMB_MASK) >> FLEXCAN_MCR_MAXMB_SHIFT)) || (mb_idx >= FLEXCAN_RXIMR_COUNT))
|
|
{
|
|
result = FLEXCAN_STATUS_BUFF_OUT_OF_RANGE;
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
if (result == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
FlexCAN_SetRxIndividualMask(pBase, mb_idx, mask);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
}
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetRxFifoGlobalMask
|
|
* Description : Set RxFifo Global Mask.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetRxFifoGlobalMask_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxFifoGlobalMask_Privileged(uint8 instance,
|
|
uint32 mask)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
FlexCAN_SetRxFifoGlobalMask(pBase, mask);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_Deinit
|
|
* Description : Shutdown a FlexCAN module.
|
|
* This function will disable all FlexCAN interrupts, and disable the FlexCAN.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_Deinit_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_Deinit_Privileged(uint8 instance)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
/* Enter Freeze Mode Required before to enter Disabled Mode */
|
|
result = FlexCAN_EnterFreezeMode(base);
|
|
if (FLEXCAN_STATUS_SUCCESS == result)
|
|
{
|
|
/* Reset registers */
|
|
FlexCAN_SetRegDefaultVal(base);
|
|
/* wait for disable */
|
|
(void)FlexCAN_Disable(base);
|
|
/* Clear state pointer that is checked by FLEXCAN_DRV_Init */
|
|
g_flexcan_Ip_StatePtr[instance] = NULL_PTR;
|
|
|
|
#if (STD_ON == FLEXCAN_SET_USER_ACCESS_ALLOWED_AVAILABLE)
|
|
/* Clear the UAA bit in REG_PROT to reset the elevation requirement */
|
|
OsIf_Trusted_Call1param(FlexCAN_ClrUserAccessAllowed, base);
|
|
#endif
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_MainFunctionRead
|
|
* Description : Process received Rx MessageBuffer or RxFifo.
|
|
* This function read the messages received as pulling or if the Interrupts are disabled.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_MainFunctionRead_Activity */
|
|
void FlexCAN_Ip_MainFunctionRead(uint8 instance, uint8 mb_idx)
|
|
{
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
DevAssert((mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM) || (mb_idx == FLEXCAN_MB_ENHANCED_RXFIFO));
|
|
#else
|
|
DevAssert(mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM);
|
|
#endif
|
|
#endif
|
|
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
if ((uint8)FLEXCAN_MB_ENHANCED_RXFIFO == mb_idx)
|
|
{
|
|
if ((boolean)TRUE == FlexCAN_IsEnhancedRxFifoAvailable(base))
|
|
{
|
|
if((boolean)TRUE == FlexCAN_IsEnhancedRxFifoEnabled(base))
|
|
{
|
|
if (FlexCAN_GetEnhancedRxFIFOStatusFlag(base, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE) != 0U)
|
|
{
|
|
FlexCAN_IRQHandlerEnhancedRxFIFO(instance, CAN_ENHANCED_RXFIFO_FRAME_AVAILABLE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
|
|
if (((boolean)TRUE == state->bIsLegacyFifoEn) && (mb_idx <= CAN_LEGACY_RXFIFO_OVERFLOW))
|
|
{
|
|
/* just process available legacy fifo event only */
|
|
if ((uint8)FLEXCAN_MB_HANDLE_RXFIFO == mb_idx)
|
|
{
|
|
if (FlexCAN_GetBuffStatusFlag(base, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE) != 0U)
|
|
{
|
|
FlexCAN_IRQHandlerRxFIFO(instance, CAN_LEGACY_RXFIFO_FRAME_AVAILABLE);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (FlexCAN_GetBuffStatusFlag(base, mb_idx) != 0U)
|
|
{
|
|
/* Check mailbox completed reception */
|
|
if (FLEXCAN_MB_RX_BUSY == state->mbs[mb_idx].state)
|
|
{
|
|
FlexCAN_IRQHandlerRxMB(instance, mb_idx);
|
|
}
|
|
}
|
|
}
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
}
|
|
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) */
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_MainFunctionBusOff
|
|
* Description : Check if BusOff occurred
|
|
* This function check the bus off event.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_MainFunctionBusOff_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_MainFunctionBusOff_Privileged(uint8 instance)
|
|
{
|
|
Flexcan_Ip_StatusType eRetVal = FLEXCAN_STATUS_ERROR;
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
uint32 u32ErrStatus = 0U;
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
/* Get error status */
|
|
u32ErrStatus = base->ESR1;
|
|
|
|
if(0U != (u32ErrStatus & FLEXCAN_ESR1_BOFFINT_MASK))
|
|
{
|
|
/* Invoke callback */
|
|
if (state->error_callback != NULL_PTR)
|
|
{
|
|
state->error_callback(instance, FLEXCAN_EVENT_BUSOFF, u32ErrStatus, state);
|
|
}
|
|
/* Clear BusOff Status Flag */
|
|
base->ESR1 = FLEXCAN_ESR1_BOFFINT_MASK;
|
|
eRetVal = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
return eRetVal;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_MainFunctionWrite
|
|
* Description : Process transmitted Tx MessageBuffer
|
|
* This function check the message if have been sent.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_MainFunctionWrite_Activity */
|
|
void FlexCAN_Ip_MainFunctionWrite(uint8 instance, uint8 mb_idx)
|
|
{
|
|
FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
if (FlexCAN_GetBuffStatusFlag(base, mb_idx) != 0U)
|
|
{
|
|
state->mbs[mb_idx].time_stamp = FlexCAN_GetMsgBuffTimestamp(base, mb_idx);
|
|
FlexCAN_UnlockRxMsgBuff(base);
|
|
|
|
/* Clear message buffer flag */
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
|
|
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetStopMode
|
|
* Description : Check if the FlexCAN instance is STOPPED.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetStopMode_Activity */
|
|
boolean FlexCAN_Ip_GetStopMode_Privileged(uint8 instance)
|
|
{
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
return (((base->MCR & FLEXCAN_MCR_LPMACK_MASK) == FLEXCAN_MCR_LPMACK_MASK) ? TRUE : FALSE);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetStartMode
|
|
* Description : Check if the FlexCAN instance is STARTED.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetStartMode_Activity */
|
|
boolean FlexCAN_Ip_GetStartMode_Privileged(uint8 instance)
|
|
{
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
return (((base->MCR & (FLEXCAN_MCR_LPMACK_MASK | FLEXCAN_MCR_FRZACK_MASK)) == 0U) ? TRUE : FALSE);
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetStartMode
|
|
* Description : Set the FlexCAN instance in START mode.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetStartMode_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetStartMode_Privileged(uint8 instance)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
/* Enable Flexcan Module */
|
|
pBase->MCR &= ~FLEXCAN_MCR_MDIS_MASK;
|
|
return (FlexCAN_ExitFreezeMode(pBase));
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetStopMode
|
|
* Description : Set the FlexCAN instance in STOP mode.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetStopMode_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetStopMode_Privileged(uint8 instance)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
Flexcan_Ip_StatusType status;
|
|
status = FlexCAN_EnterFreezeMode(pBase);
|
|
if (status == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* TODO: deactivate all pending tx, this should be move to IPW */
|
|
|
|
/* TODO:Clear all flag */
|
|
|
|
/* TODO: reset MB status */
|
|
|
|
/* TODO: disable all interrupt */
|
|
|
|
status = FlexCAN_Disable(pBase);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetRxMaskType
|
|
* Description : Set RX masking type.
|
|
* This function will set RX masking type as RX global mask or RX individual
|
|
* mask.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetRxMaskType_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMaskType_Privileged(uint8 instance,
|
|
Flexcan_Ip_RxMaskType type)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
FlexCAN_SetRxMaskType(pBase, type);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetBitrate
|
|
* Description : Set FlexCAN baudrate.
|
|
* This function will set up all the time segment values for classical frames or the
|
|
* extended time segments. Those time segment values are passed in by the user and
|
|
* are based on the required baudrate.
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
/* implements FlexCAN_Ip_SetBitrate_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetBitrate_Privileged(uint8 instance, const Flexcan_Ip_TimeSegmentType * bitrate, boolean enhExt)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(bitrate != NULL_PTR);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
/* Start critical section: implementation depends on integrator */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_14();
|
|
/* Enable the use of extended bit time definitions */
|
|
FlexCAN_EnhCbtEnable(pBase, enhExt);
|
|
|
|
if (enhExt == TRUE)
|
|
{
|
|
/* Set extended time segments*/
|
|
FlexCAN_SetEnhancedNominalTimeSegments(pBase, bitrate);
|
|
}
|
|
else
|
|
{
|
|
if (FlexCAN_IsExCbtEnabled(pBase) == TRUE)
|
|
{
|
|
FlexCAN_SetExtendedTimeSegments(pBase, bitrate);
|
|
}
|
|
else
|
|
{
|
|
FlexCAN_SetTimeSegments(pBase, bitrate);
|
|
}
|
|
}
|
|
/* End critical section: implementation depends on integrator */
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_14();
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetBitrate
|
|
* Description : Get FlexCAN Baudrate.
|
|
* This function will be return the current bit rate settings for classical frames
|
|
* or the arbitration phase of FD frames.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetBitrate_Activity */
|
|
boolean FlexCAN_Ip_GetBitrate(uint8 instance,
|
|
Flexcan_Ip_TimeSegmentType * bitrate)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(bitrate != NULL_PTR);
|
|
#endif
|
|
const FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean enhCbt = FALSE;
|
|
enhCbt = FlexCAN_IsEnhCbtEnabled(pBase);
|
|
if (enhCbt == TRUE)
|
|
{
|
|
FlexCAN_GetEnhancedNominalTimeSegments(pBase, bitrate);
|
|
}
|
|
else
|
|
{
|
|
if (TRUE == FlexCAN_IsExCbtEnabled(pBase))
|
|
{
|
|
/* Get the Extended time segments*/
|
|
FlexCAN_GetExtendedTimeSegments(pBase, bitrate);
|
|
}
|
|
else
|
|
{
|
|
/* Get the time segments*/
|
|
FlexCAN_GetTimeSegments(pBase, bitrate);
|
|
}
|
|
}
|
|
return enhCbt;
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_FD == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ClearTDCFail
|
|
* Description : This function clear the TDC Fail flag.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ClearTDCFail_Activity */
|
|
void FlexCAN_Ip_ClearTDCFail_Privileged(uint8 u8Instance)
|
|
{
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
if (result == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* Check if enhaced CBT is Enabled */
|
|
if (FlexCAN_IsEnhCbtEnabled(pBase) == TRUE)
|
|
{
|
|
pBase->ETDC |= FLEXCAN_ETDC_ETDCFAIL_MASK;
|
|
}
|
|
else
|
|
{
|
|
pBase->FDCTRL |= FLEXCAN_FDCTRL_TDCFAIL_MASK;
|
|
}
|
|
}
|
|
if (disabled == TRUE)
|
|
{
|
|
(void)FlexCAN_Disable(pBase);
|
|
}
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetTDCFail
|
|
* Description : This function get the value of the TDC Fail flag.
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
/* implements FlexCAN_Ip_GetTDCFail_Activity */
|
|
boolean FlexCAN_Ip_GetTDCFail_Privileged(uint8 u8Instance)
|
|
{
|
|
boolean value=FALSE;
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
if (result == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* Check if enhaced CBT is Enabled */
|
|
if (FlexCAN_IsEnhCbtEnabled(pBase) == TRUE)
|
|
{
|
|
value = ((pBase->ETDC & FLEXCAN_ETDC_ETDCFAIL_MASK) == FLEXCAN_ETDC_ETDCFAIL_MASK) ? TRUE : FALSE;
|
|
}
|
|
else
|
|
{
|
|
value = ((pBase->FDCTRL & FLEXCAN_FDCTRL_TDCFAIL_MASK) == FLEXCAN_FDCTRL_TDCFAIL_MASK) ? TRUE : FALSE;
|
|
}
|
|
}
|
|
if (disabled == TRUE)
|
|
{
|
|
(void)FlexCAN_Disable(pBase);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetTDCValue
|
|
* Description : This function get the value of the Transceiver Delay Compensation.
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
/* implements FlexCAN_Ip_GetTDCValue_Activity */
|
|
uint8 FlexCAN_Ip_GetTDCValue_Privileged(uint8 u8Instance)
|
|
{
|
|
uint8 value = 0;
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
if (result == FLEXCAN_STATUS_SUCCESS)
|
|
{
|
|
/* Check if enhaced CBT is Enabled */
|
|
if (FlexCAN_IsEnhCbtEnabled(pBase) == TRUE)
|
|
{
|
|
value = (uint8)((pBase->ETDC& FLEXCAN_ETDC_ETDCVAL_MASK) >> FLEXCAN_ETDC_ETDCVAL_SHIFT);
|
|
}
|
|
else
|
|
{
|
|
value = (uint8)((pBase->FDCTRL & FLEXCAN_FDCTRL_TDCVAL_MASK) >> FLEXCAN_FDCTRL_TDCVAL_SHIFT);
|
|
}
|
|
}
|
|
if (disabled == TRUE)
|
|
{
|
|
(void)FlexCAN_Disable(pBase);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetBitrateCbt
|
|
* Description : Set FlexCAN bitrate.
|
|
* This function will set up all the time segment values for the data phase of
|
|
* FD frames. Those time segment values are passed in by the user and are based
|
|
* on the required baudrate.
|
|
*
|
|
*END**************************************************************************/
|
|
|
|
/* implements FlexCAN_Ip_SetBitrateCbt_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetBitrateCbt_Privileged(uint8 instance, const Flexcan_Ip_TimeSegmentType * bitrate,
|
|
boolean bitRateSwitch)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(bitrate != NULL_PTR);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
boolean fd_enable = FlexCAN_IsFDEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((fd_enable == FALSE) || ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS)))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
boolean enhCbt = FlexCAN_IsEnhCbtEnabled(pBase);
|
|
/* Start critical section: implementation depends on integrator */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_15();
|
|
FlexCAN_SetFDEnabled(pBase, fd_enable, bitRateSwitch);
|
|
|
|
if (enhCbt == TRUE)
|
|
{
|
|
FlexCAN_SetEnhancedDataTimeSegments(pBase, bitrate);
|
|
}
|
|
else
|
|
{
|
|
/* Set time segments*/
|
|
FlexCAN_SetFDTimeSegments(pBase, bitrate);
|
|
}
|
|
/* End critical section: implementation depends on integrator */
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_15();
|
|
}
|
|
|
|
if ((boolean)TRUE == disabled)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetBitrateFD
|
|
* Description : Get FlexCAN baudrate.
|
|
* This function will be return the current bit rate settings for the data phase
|
|
* of FD frames.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetBitrateFD_Activity */
|
|
boolean FlexCAN_Ip_GetBitrateFD(uint8 instance,
|
|
Flexcan_Ip_TimeSegmentType * bitrate)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert(bitrate != NULL_PTR);
|
|
#endif
|
|
const FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean enhCbt = FlexCAN_IsEnhCbtEnabled(pBase);
|
|
|
|
if (enhCbt == TRUE)
|
|
{
|
|
FlexCAN_GetEnhancedDataTimeSegments(pBase, bitrate);
|
|
}
|
|
else
|
|
{
|
|
/* Get the time segments*/
|
|
FlexCAN_GetFDTimeSegments(pBase, bitrate);
|
|
}
|
|
return enhCbt;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetTDCOffset
|
|
* Description : Enables/Disables the Transceiver Delay Compensation feature and sets
|
|
* the Transceiver Delay Compensation Offset.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetTDCOffset_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetTDCOffset_Privileged(uint8 instance,
|
|
boolean enable,
|
|
uint8 offset)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
/* Check if enhaced CBT is Enabled */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_16();
|
|
/* End critical section: implementation depends on integrator */
|
|
if ((pBase->CTRL2 & FLEXCAN_CTRL2_BTE_MASK) == FLEXCAN_CTRL2_BTE_MASK)
|
|
{
|
|
FlexCAN_SetEnhancedTDCOffset(pBase, enable, offset);
|
|
}
|
|
else
|
|
{
|
|
/* Enable/Disable TDC and set the TDC Offset */
|
|
FlexCAN_SetTDCOffset(pBase, enable, offset);
|
|
}
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_16();
|
|
/* Check if enhaced CBT is Enabled */
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetTxArbitrationStartDelay
|
|
* Description : Set FlexCAN Tx Arbitration Start Delay.
|
|
* This function will set how many CAN bits the Tx arbitration process start point can
|
|
* be delayed from the first bit of CRC field on CAN bus.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetTxArbitrationStartDelay_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetTxArbitrationStartDelay_Privileged(uint8 instance, uint8 value)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
/* Start critical section: implementation depends on integrator */
|
|
SchM_Enter_Can_CAN_EXCLUSIVE_AREA_17();
|
|
FlexCAN_SetTxArbitrationStartDelay(pBase, value);
|
|
/* End critical section: implementation depends on integrator */
|
|
SchM_Exit_Can_CAN_EXCLUSIVE_AREA_17();
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetBuffStatusFlag
|
|
* Description : Get FlexCAN Message Buffer Status Flag for an operation.
|
|
* In case of a complete operation this flag is set.
|
|
* In case msgBuff is 255 will return Enhanced Overflow Status Flag.
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetBuffStatusFlag_Activity */
|
|
boolean FlexCAN_Ip_GetBuffStatusFlag(uint8 instance, uint8 msgBuffIdx)
|
|
{
|
|
boolean returnResult = TRUE;
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
const FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
if (msgBuffIdx == FLEXCAN_MB_ENHANCED_RXFIFO)
|
|
{
|
|
returnResult = ((FlexCAN_GetEnhancedRxFIFOStatusFlag(pBase, CAN_ENHANCED_RXFIFO_OVERFLOW) == 1U) ? TRUE : FALSE);
|
|
}
|
|
else
|
|
{
|
|
returnResult = ((FlexCAN_GetBuffStatusFlag(pBase, msgBuffIdx) == 1U) ? TRUE : FALSE);
|
|
}
|
|
return returnResult;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ClearBuffStatusFlag
|
|
* Description : Clear FlexCAN Message Buffer Status Flag.
|
|
* In case msgBuff is 255 will clear Enhanced Overflow Status Flag.
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ClearBuffStatusFlag_Activity */
|
|
void FlexCAN_Ip_ClearBuffStatusFlag(uint8 instance, uint8 msgBuffIdx)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
if (msgBuffIdx == FLEXCAN_MB_ENHANCED_RXFIFO)
|
|
{
|
|
FlexCAN_ClearEnhancedRxFifoIntStatusFlag(pBase, CAN_ENHANCED_RXFIFO_OVERFLOW);
|
|
}
|
|
else
|
|
{
|
|
FlexCAN_ClearMsgBuffIntStatusFlag(pBase, msgBuffIdx);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_EnableInterrupts
|
|
* Description : Enable all mb interrupts configured.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_EnableInterrupts_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_EnableInterrupts_Privileged(uint8 u8Instance)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
if ((boolean)TRUE == FlexCAN_IsEnabled(pBase))
|
|
{
|
|
FlexCAN_EnableInterrupts(pBase, u8Instance);
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
if ((state->enhancedFifoOutput.isPolling == FALSE) && ( TRUE == FlexCAN_IsEnhancedRxFifoAvailable(pBase)))
|
|
{ /* Check if Enabled Enhanced Fifo */
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(pBase))
|
|
{
|
|
FlexCAN_SetEnhancedRxFifoIntAll(pBase, TRUE);
|
|
}
|
|
}
|
|
#endif
|
|
state->isIntActive = (boolean)TRUE;
|
|
result = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_DisableInterrupts
|
|
* Description : Enable all interrupts configured.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_DisableInterrupts_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_DisableInterrupts_Privileged(uint8 u8Instance)
|
|
{
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_ERROR;
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
|
|
if ((boolean)TRUE == FlexCAN_IsEnabled(pBase))
|
|
{
|
|
FlexCAN_DisableInterrupts(pBase);
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoAvailable(pBase))
|
|
{ /* Check if Enabled Enhanced Fifo */
|
|
if (TRUE == FlexCAN_IsEnhancedRxFifoEnabled(pBase))
|
|
{
|
|
FlexCAN_SetEnhancedRxFifoIntAll(pBase, FALSE);
|
|
}
|
|
}
|
|
state->isIntActive = (boolean)FALSE;
|
|
result = FLEXCAN_STATUS_SUCCESS;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetErrorInt
|
|
* Description : Enable\Disable Error or BusOff Interrupt
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetErrorInt_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetErrorInt_Privileged(uint8 u8Instance, Flexcan_Ip_ErrorIntType type, boolean enable)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
if(FLEXCAN_STATUS_SUCCESS == result )
|
|
{
|
|
switch(type)
|
|
{
|
|
case FLEXCAN_IP_INT_BUSOFF:
|
|
{
|
|
FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_BUSOFF, enable);
|
|
break;
|
|
}
|
|
case FLEXCAN_IP_INT_ERR:
|
|
{
|
|
FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_ERR, enable);
|
|
break;
|
|
}
|
|
case FLEXCAN_IP_INT_ERR_FAST :
|
|
{
|
|
FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_ERR_FAST, enable);
|
|
break;
|
|
}
|
|
case FLEXCAN_IP_INT_RX_WARNING :
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
if (TRUE != FlexCAN_IsFreezeMode(pBase))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}else
|
|
#endif
|
|
{
|
|
FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_RX_WARNING, enable);
|
|
}
|
|
break;
|
|
}
|
|
case FLEXCAN_IP_INT_TX_WARNING :
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
if (TRUE != FlexCAN_IsFreezeMode(pBase))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}else
|
|
#endif
|
|
{
|
|
FlexCAN_SetErrIntCmd(pBase, FLEXCAN_INT_TX_WARNING, enable);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert((boolean)FALSE);
|
|
/* Should not get here */
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_AbortTransfer
|
|
* Description : This function shuts down the FLEXCAN by disabling interrupts and
|
|
* the transmitter/receiver.
|
|
* This function disables the FLEXCAN interrupts, disables the transmitter and
|
|
* receiver.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_AbortTransfer_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_AbortTransfer(uint8 u8Instance,
|
|
uint8 mb_idx)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(u8Instance < FLEXCAN_INSTANCE_COUNT);
|
|
DevAssert((mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM) || (mb_idx == 255u));
|
|
#endif
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[u8Instance];
|
|
#if ((FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) && (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON))
|
|
Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
#else
|
|
const Flexcan_Ip_StateType * state = g_flexcan_Ip_StatePtr[u8Instance];
|
|
#endif /* (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON) && (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON) */
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
|
|
if (mb_idx < (uint8)FEATURE_CAN_MAX_MB_NUM)
|
|
{
|
|
|
|
if (FLEXCAN_MB_IDLE == state->mbs[mb_idx].state)
|
|
{
|
|
result = FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
|
|
}
|
|
else
|
|
{
|
|
FLEXCAN_ClearMsgBuffIntCmd(pBase, u8Instance, mb_idx, state->isIntActive);
|
|
if (FLEXCAN_MB_TX_BUSY == state->mbs[mb_idx].state)
|
|
{
|
|
result = FlexCAN_AbortTxTransfer(u8Instance, mb_idx);
|
|
}
|
|
|
|
if (FLEXCAN_MB_RX_BUSY == state->mbs[mb_idx].state)
|
|
{
|
|
FlexCAN_AbortRxTransfer(u8Instance, mb_idx);
|
|
}
|
|
}
|
|
|
|
}
|
|
#if (FEATURE_CAN_HAS_ENHANCED_RX_FIFO == STD_ON)
|
|
#if (FEATURE_CAN_HAS_DMA_ENABLE == STD_ON)
|
|
else
|
|
{
|
|
/* Check if transfer is done over DMA and stop transfer */
|
|
if ((state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
|
|
{
|
|
(void)Dma_Ip_SetLogicChannelCommand(state->rxFifoDMAChannel, DMA_IP_CH_CLEAR_HARDWARE_REQUEST);
|
|
if (state->enhancedFifoOutput.state == FLEXCAN_MB_RX_BUSY)
|
|
{
|
|
state->enhancedFifoOutput.state = FLEXCAN_MB_IDLE;
|
|
}
|
|
else
|
|
{
|
|
return FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FLEXCAN_STATUS_NO_TRANSFER_IN_PROGRESS;
|
|
}
|
|
}
|
|
#endif /* if FEATURE_CAN_HAS_DMA_ENABLE */
|
|
#endif /* if FEATURE_CAN_HAS_ENHANCED_RX_FIFO */
|
|
|
|
return result;
|
|
}
|
|
|
|
/* implements FlexCAN_Ip_SetRxMb14Mask_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMb14Mask_Privileged(uint8 instance, uint32 mask)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FALSE;
|
|
#endif
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
pBase->RX14MASK = mask;
|
|
}
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/* implements FlexCAN_Ip_SetRxMb15Mask_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetRxMb15Mask_Privileged(uint8 instance, uint32 mask)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FALSE;
|
|
#endif
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
pBase->RX15MASK = mask;
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_SetListenOnlyMode
|
|
* Description : Set FlexCAN Listen Only.
|
|
* This function will enable or disable Listen Only mode.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_SetListenOnlyMode_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_SetListenOnlyMode_Privileged(uint8 instance, const boolean enable)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
FlexCAN_SetListenOnlyMode(pBase, enable);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_GetListenOnlyMode
|
|
* Description : Check if Listen Only mode is ENABLE.
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_GetListenOnlyMode_Activity */
|
|
boolean FlexCAN_Ip_GetListenOnlyMode(uint8 instance)
|
|
{
|
|
const FLEXCAN_Type * base = g_Flexcan_Ip_aBase[instance];
|
|
return FlexCAN_IsListenOnlyModeEnabled(base);
|
|
}
|
|
|
|
#if (FEATURE_CAN_HAS_HR_TIMER == STD_ON)
|
|
/*FUNCTION**********************************************************************
|
|
*
|
|
* Function Name : FlexCAN_Ip_ConfigTimeStamp_Privileged
|
|
* Description : Timestamp configuration
|
|
*
|
|
*END**************************************************************************/
|
|
/* implements FlexCAN_Ip_ConfigTimeStamp_Activity */
|
|
Flexcan_Ip_StatusType FlexCAN_Ip_ConfigTimeStamp_Privileged(uint8 instance, Flexcan_Ip_TimeStampConfigType * time_stamp)
|
|
{
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
DevAssert(instance < FLEXCAN_INSTANCE_COUNT);
|
|
#endif
|
|
Flexcan_Ip_StatusType result = FLEXCAN_STATUS_SUCCESS;
|
|
Flexcan_Ip_StatusType status = FLEXCAN_STATUS_SUCCESS;
|
|
FLEXCAN_Type * pBase = g_Flexcan_Ip_aBase[instance];
|
|
boolean disabled = !FlexCAN_IsEnabled(pBase);
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
result = FlexCAN_Enable(pBase);
|
|
}
|
|
|
|
#if (FLEXCAN_DEV_ERROR_DETECT == STD_ON)
|
|
boolean freeze = FlexCAN_IsFreezeMode(pBase);
|
|
|
|
if ((freeze == FALSE) && (result == FLEXCAN_STATUS_SUCCESS))
|
|
{
|
|
result = FLEXCAN_STATUS_ERROR;
|
|
}
|
|
#endif
|
|
|
|
if (result == FLEXCAN_STATUS_SUCCESS )
|
|
{
|
|
FlexCAN_ConfigTimestamp(pBase, time_stamp);
|
|
FlexCAN_ConfigTimestampModule(time_stamp);
|
|
}
|
|
|
|
if (disabled == TRUE)
|
|
{
|
|
status = FlexCAN_Disable(pBase);
|
|
if (FLEXCAN_STATUS_SUCCESS != status)
|
|
{
|
|
result = status;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
#define CAN_STOP_SEC_CODE
|
|
#include "Can_MemMap.h"
|
|
|
|
/** @} */
|