NorthStar-Endurance-TestBench/NorthStar-Emotas-Stack/codrv_sl/stm32_mcan/codrv_mcan.c

1600 lines
38 KiB
C

/*
* codrv_mcan - driver for mcan
*
* Copyright (c) 2017-2020 emotas embedded communication GmbH
*-------------------------------------------------------------------
* SVN $Id: codrv_mcan.c 51556 2023-12-18 09:35:01Z ro $
*
*
*-------------------------------------------------------------------
*
*
*/
/*
Functionality Singleline:
- extended and standard id
- rtr
- software auto bus on
- CAN-FD ISO
- id filter
- id group filter
*/
/***************************************************************************/
/**
* \file
* \brief mCAN CAN driver (e.g. STM32, LPC, Atmel)
*
*
*
* Note: This settings should be part of gen_define.h!
*
*/
/* #define CO_DRV_FILTER 1 */
/* #define CO_DRV_GROUP_FILTER 1 */
/* header of standard C - libraries
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stddef.h>
#include <string.h>
/* header of project specific types
---------------------------------------------------------------------------*/
#include <gen_define.h>
#include <co_datatype.h>
#include <co_drv.h>
#include <codrv_error.h>
#include <co_commtask.h>
#include "codrv_mcan.h"
/* constant definitions
---------------------------------------------------------------------------*/
/*
* Below is the message RAM setting, it will be stored in the system RAM.
* Please adjust the message size according to your application.
*/
#if defined(CODRV_MCAN_STM32_L5) || defined(CODRV_MCAN_STM32_G0) || defined(CODRV_MCAN_STM32_G4) || defined(CODRV_MCAN_STM32_U5) || defined(CODRV_MCAN_STM32_H5)
# define CODRV_MCAN_FIXED_MSG_RAM 1u
# define CODRV_MCAN_FILTER_STD_SIZE 28u
# define CODRV_MCAN_FILTER_EXT_SIZE 8u
# define CODRV_MCAN_RXFIFO_SIZE 3u
# define CODRV_MCAN_ELEMENT_DATA_SIZE 64u
# define CODRV_MCAN_TXBUFFER_SIZE 3u
# define CODRV_RX0L_IR_POS 2u
#endif /* defined(CODRV_MCAN_STM32_L5) || defined(CODRV_MCAN_STM32_G0) || defined(CODRV_MCAN_STM32_G4) || defined(CODRV_MCAN_STM32_U5) || defined(CODRV_MCAN_STM32_H5) */
/* The value should be 8/12/16/20/24/32/48/64. */
# ifndef CODRV_MCAN_ELEMENT_DATA_SIZE
# define CODRV_MCAN_ELEMENT_DATA_SIZE 8u
# define CODRV_MCAN_ELEMENT_SIZE_CODE 0u
# endif /*CODRV_MCAN_ELEMENT_DATA_SIZE*/
/**
* \define CODRV_MCAN_RXFIFO_SIZE
* Number of rx fifo elements
*/
#ifndef CODRV_MCAN_RXFIFO_SIZE
# define CODRV_MCAN_RXFIFO_SIZE (10u)
#endif /* CODRV_MCAN_RXFIFO_SIZE */
/**
* \define CODRV_RX0L_IR_POS
* RX-fifo message lost flag position
*/
#ifndef CODRV_RX0L_IR_POS
# define CODRV_RX0L_IR_POS 3u
#endif /* CODRV_RX0L_IR_POS */
/**
* \define CODRV_MCAN_TXBUFFER_SIZE
* Number of tx buffer elements
*/
#ifndef CODRV_MCAN_TXBUFFER_SIZE
# define CODRV_MCAN_TXBUFFER_SIZE 1u
#endif /* CODRV_MCAN_TXBUFFER_SIZE */
/**
* \define CODRV_MCAN_FILTER_STD_SIZE
* Number of std id filter elements
*/
#ifndef CODRV_MCAN_FILTER_STD_SIZE
# ifdef CO_DRV_FILTER
# define CODRV_MCAN_FILTER_STD_SIZE (28u)
# else /* CO_DRV_FILTER */
# define CODRV_MCAN_FILTER_STD_SIZE 0u
# endif /* CO_DRV_FILTER */
#endif /* CODRV_MCAN_FILTER_STD_SIZE */
/**
* \define CODRV_MCAN_FILTER_EXT_SIZE
* Number of ext id filter elements
*/
#ifndef CODRV_MCAN_FILTER_EXT_SIZE
# ifdef CO_DRV_FILTER
# define CODRV_MCAN_FILTER_EXT_SIZE (28u)
# else /* CO_DRV_FILTER */
# define CODRV_MCAN_FILTER_EXT_SIZE 0u
# endif /* CO_DRV_FILTER */
#endif /* CODRV_MCAN_FILTER_EXT_SIZE */
#define MCAN_SIDF_SIZE 4u /* standard id filter */
#define MCAN_XIDF_SIZE 8u /* extended id filter */
#define MCAN_RXF0_SIZE (MCAN_XIDF_SIZE + CODRV_MCAN_ELEMENT_DATA_SIZE) /* rx fifo 0 */
#define MCAN_RXB_SIZE (MCAN_XIDF_SIZE + CODRV_MCAN_ELEMENT_DATA_SIZE) /* rx buffer */
#define MCAN_TXE_SIZE 8u /* tx event */
#define MCAN_TXB_SIZE (MCAN_XIDF_SIZE + CODRV_MCAN_ELEMENT_DATA_SIZE) /* tx buffer */
/**
* \define CODRV_DEBUG
* UART Debug output
*/
/* #define CODRV_DEBUG 1 */
/**
* \define POLLING
* work without interrupts
* !! Seldom tested - support is not guaranteed !!
*/
/* #define POLLING 1 */
/* OS related macros - default definition */
#ifdef CO_OS_SIGNAL_CAN_TRANSMIT
#else
# define CO_OS_SIGNAL_CAN_TRANSMIT
#endif
#ifdef CO_OS_SIGNAL_CAN_RECEIVE
#else
# define CO_OS_SIGNAL_CAN_RECEIVE
#endif
/* local defined data types
---------------------------------------------------------------------------*/
typedef struct {
UNSIGNED32 id;
UNSIGNED32 ctrl;
UNSIGNED8 data[CODRV_MCAN_ELEMENT_DATA_SIZE];
}MCAN_FIFO_ELEMENT_T;
typedef struct {
UNSIGNED32 F0;
UNSIGNED32 F1;
}MCAN_EXT_FILTER_ELEMENT_T;
typedef struct {
#if defined(CO_DRV_FILTER) || defined(CODRV_MCAN_FIXED_MSG_RAM)
UNSIGNED32 stdIdFilter[CODRV_MCAN_FILTER_STD_SIZE];
MCAN_EXT_FILTER_ELEMENT_T extIdFilter[CODRV_MCAN_FILTER_EXT_SIZE];
#endif /* CO_DRV_FILTER || CODRV_MCAN_FIXED_MSG_RAM */
MCAN_FIFO_ELEMENT_T rxFifo[CODRV_MCAN_RXFIFO_SIZE];
#ifdef CODRV_MCAN_FIXED_MSG_RAM
MCAN_FIFO_ELEMENT_T rxFifo2[CODRV_MCAN_RXFIFO_SIZE];
UNSIGNED8 eventfifo[8 * 3];
#endif /* CODRV_MCAN_FIXED_MSG_RAM */
MCAN_FIFO_ELEMENT_T txBuf[CODRV_MCAN_TXBUFFER_SIZE];
} MCAN_MSGRAM_T;
/* list of external used functions, if not in headers
---------------------------------------------------------------------------*/
/* list of global defined functions
---------------------------------------------------------------------------*/
#ifdef CODRV_DEBUG
# ifdef CO_DRV_FILTER
void printFilter(void);
# endif /* CO_DRV_FILTER */
#endif /* CODRV_DEBUG */
/* list of local defined functions
---------------------------------------------------------------------------*/
static RET_T codrvCanInitController(UNSIGNED16 nomBitrate, UNSIGNED16 datBitrate);
static RET_T codrvCanTransmit(CO_CONST CO_CAN_TR_MSG_T * pBuf);
static CO_CONST CODRV_BTR_T * codrvCanGetBtrSettings(UNSIGNED16 bitRate);
static void codrvCanResetRam(void);
#ifdef CO_DRV_FILTER
# ifdef CO_DRV_GROUP_FILTER
static BOOL_T codrvCanCheckGroupFilter(CO_CONST CO_CAN_COB_T * CO_CONST pCob);
# endif /* CO_DRV_GROUP_FILTER */
static RET_T codrvCanEnableExtIdFilter(CO_CAN_COB_T * CO_CONST pCob);
static RET_T codrvCanEnableStdIdFilter(CO_CAN_COB_T * CO_CONST pCob);
static RET_T codrvCanDisableExtIdFilter(CO_CAN_COB_T * CO_CONST pCob);
static RET_T codrvCanDisableStdIdFilter(CO_CAN_COB_T * CO_CONST pCob);
#endif
#ifdef CODRV_AUTOBAUD
RET_T codrvAutoBaudNextBitrate(void);
UNSIGNED16 codrvAutoBaudGetActualBitrate(void);
#endif /* CODRV_AUTOBAUD */
/* external variables
---------------------------------------------------------------------------*/
/* global variables
---------------------------------------------------------------------------*/
/* local defined variables
---------------------------------------------------------------------------*/
static BOOL_T canEnabled = { CO_FALSE };
static volatile BOOL_T transmissionIsActive = { CO_FALSE };
static UNSIGNED32 oldEsrValue;
/** currently TX message buffer */
static CO_CAN_TR_MSG_T *pTxBuf = { NULL };
/** CAN Controller address */
#ifdef CODRV_MCAN_STM32_H7
# define CODRV_MCAN0_ADDR ((CODRV_MCANFD_T*)0x4000A000ul)
# define CODRV_MCAN1_ADDR ((CODRV_MCANFD_T*)0x4000A400ul)
#endif /* CODRV_MCAN_STM32_H7 */
#ifdef CODRV_MCAN_STM32_MP1
# define CODRV_MCAN0_ADDR ((CODRV_MCANFD_T*)0x4400E000ul)
# define CODRV_MCAN1_ADDR ((CODRV_MCANFD_T*)0x4400F000ul)
#endif /* CODRV_MCAN_STM32_MP1 */
#if defined(CODRV_MCAN_STM32_G0) || defined(CODRV_MCAN_STM32_G4)
# define CODRV_MCAN0_ADDR ((CODRV_MCANFD_T*)0x40006400ul)
# define CODRV_MCAN1_ADDR ((CODRV_MCANFD_T*)0x40006800ul)
# if defined(CODRV_MCAN_STM32_G4)
# define CODRV_MCAN2_ADDR ((CODRV_MCANFD_T*)0x40006C00ul)
# endif /* defined(CODRV_MCAN_STM32_G4) */
#endif /* defined(CODRV_MCAN_STM32_G0) || defined(CODRV_MCAN_STM32_G4) */
/* STM32L5 - only CPUs with 1 FDCAN out at the moment! */
#if defined(CODRV_MCAN_STM32_L5)
# define CODRV_MCAN0_ADDR ((CODRV_MCANFD_T*)0x4000A400ul)
#endif /* defined(CODRV_MCAN_STM32_L5) */
/* STM32U5 - only CPUs with 1 FDCAN out at the moment! */
#if defined(CODRV_MCAN_STM32_U5)
# define CODRV_MCAN0_ADDR ((CODRV_MCANFD_T*)0x4000A400ul)
#endif /* defined(CODRV_MCAN_STM32_U5) */
#ifdef CODRV_MCAN_STM32_H5
# define CODRV_MCAN0_ADDR ((CODRV_MCANFD_T*)0x4000A400ul)
# define CODRV_MCAN1_ADDR ((CODRV_MCANFD_T*)0x4000A800ul)
#endif /* CODRV_MCAN_STM32_MP1 */
#ifndef CODRV_MCAN0_ADDR
# error select MCAN configuration first!
#endif /* CODRV_MCAN0_ADDR */
/** \var pCan - used CAN controller address */
# ifdef CONFIG_MCAN0
static volatile CODRV_MCANFD_T * const pCan = CODRV_MCAN0_ADDR; /*lint !e923 CAN controller address */
# endif /* CONFIG_MCAN0 */
# ifdef CONFIG_MCAN1
static volatile CODRV_MCANFD_T * const pCan = CODRV_MCAN1_ADDR; /*lint !e923 CAN controller address */
# endif /* CONFIG_MCAN1 */
# ifdef CONFIG_MCAN2
static volatile CODRV_MCANFD_T * const pCan = CODRV_MCAN2_ADDR; /*lint !e923 CAN controller address */
# endif /* CONFIG_MCAN2 */
/** CAN message RAM address */
#define CODRV_MCAN_STATIC_MSG_RAM
# ifdef CONFIG_MCAN0
static const UNSIGNED8 mcanMsgRamOffs = 0u;
# endif /* CONFIG_MCAN0 */
# ifdef CONFIG_MCAN1
static const UNSIGNED8 mcanMsgRamOffs = 1u;
# endif /* CONFIG_MCAN1 */
# ifdef CONFIG_MCAN2
static const UNSIGNED8 mcanMsgRamOffs = 2u;
# endif /* CONFIG_MCAN2 */
#ifdef CODRV_MCAN_STATIC_MSG_RAM
# ifdef CODRV_MCAN_STM32_H7
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x4000AC00u);
# endif /* CODRV_MCAN_STM32_H7 */
# ifdef CODRV_MCAN_STM32_MP1
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x44011000u);
# endif /* CODRV_MCAN_STM32_MP1 */
# ifdef CODRV_MCAN_STM32_G0
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x4000B400u);
# endif /* CODRV_MCAN_STM32_G0 */
# ifdef CODRV_MCAN_STM32_G4
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x4000A400u);
# endif /* CODRV_MCAN_STM32_G4 */
# ifdef CODRV_MCAN_STM32_L5
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x4000AC00u);
# endif /* CODRV_MCAN_STM32_L5 */
# ifdef CODRV_MCAN_STM32_U5
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x4000AC00u);
# endif /* CODRV_MCAN_STM32_U5 */
# ifdef CODRV_MCAN_STM32_H5
static volatile MCAN_MSGRAM_T * const pMcanMsgRam = (MCAN_MSGRAM_T*)(0x4000AC00u);
# endif /* CODRV_MCAN_STM32_U5 */
# else /* CODRV_MCAN_STATIC_MSG_RAM */
static volatile MCAN_MSGRAM_T mcanMsgRam __attribute__((section(".MCAN_SECTION")));
static volatile MCAN_MSGRAM_T * volatile pMcanMsgRam = &mcanMsgRam;
# ifdef CONFIG_MCAN0
static volatile UNSIGNED32* pMcanMRBA = (UNSIGNED32 *)0x4009D200ul;
# endif /* CONFIG_MCAN0 */
# ifdef CONFIG_MCAN1
static volatile UNSIGNED32* pMcanMRBA = (UNSIGNED32 *)0x4009e200ul;
# endif /* CONFIG_MCAN1 */
#endif /* CODRV_MCAN_STATIC_MSG_RAM */
#ifdef CODRV_BIT_TABLE_EXTERN
extern CO_CONST CODRV_BTR_T codrvCanBittimingTable[];
#else /* CODRV_BIT_TABLE_EXTERN */
/** CAN bittiming table */
static CO_CONST CODRV_BTR_T codrvCanBittimingTable[] = {
# ifdef CODRV_CANCLOCK_PRE_10BIT
/* 80MHz table */
{ 10u, 500u, 0u, 13u, 2u }, /* 87.5% */
{ 20u, 250u, 0u, 13u, 2u }, /* 87.5% */
{ 50u, 100u, 0u, 13u, 2u }, /* 87.5% */
# endif /* CODRV_CANCLOCK_PRE_10BIT */
{ 100u, 50u, 0u, 13u, 2u }, /* 87.5% */
{ 125u, 40u, 0u, 13u, 2u }, /* 87.5% */
{ 250u, 20u, 0u, 13u, 2u }, /* 87.5% */
{ 500u, 10u, 0u, 13u, 2u }, /* 87.5% */
{ 800u, 10u, 0u, 8u, 1u }, /* 90.0% */
{ 1000u, 5u, 0u, 13u, 2u }, /* 87.5% */
{ 0u, 0u, 0u, 0u, 0u } /* last */
};
#endif /* CODRV_BIT_TABLE_EXTERN */
#ifdef CODRV_AUTOBAUD
static UNSIGNED16 autoBaudBitRateIdx = { 0u };
static UNSIGNED8 autoBaudActive = { 0u };
#endif /* CODRV_AUTOBAUD */
/*---------------------------------------------------------------------------*/
/* #define DEBUG_SEND_TESTMESSAGE */
#ifdef DEBUG_SEND_TESTMESSAGE
static void codrvSendTestMessage(
void /* no parameter */
)
{
MCAN_MSGRAM_T * pRam;
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
pRam->txBuf[0].id = (0x555 << 18u);
pRam->txBuf[0].ctrl = (9u << 16u);/* | (3u << 20u)*/;
pRam->txBuf[0].data[0] = 0x01;
pRam->txBuf[0].data[7] = 0x08;
pCan->TXBTIE = 0x01;
pCan->TXBAR = 0x01;
}
#endif /* DEBUG_SEND_TESTMESSAGE */
/*---------------------------------------------------------------------------*/
/***************************************************************************/
/**
* \brief codrvCanInit - init CAN controller
*
* This Function inits the CAN controller and setup the bitrate
* After that, the CAN controller is disabled.
*
* \param
* bitrate - CANopen bitrate
* \results
* RET_T
*/
RET_T codrvCanInit(
UNSIGNED16 bitRate /**< Bitrate */
)
{
RET_T retVal;
/* clear the FD RAM */
codrvCanResetRam();
#ifdef CO_DRV_FILTER
/* start of ID filter */
#endif /* CO_DRV_FILTER */
retVal = codrvCanInitController(bitRate, 0u);
return(retVal);
}
/***************************************************************************/
/**
* \brief codrvCanReInit - reinit CAN controller
*
* This Function reinits the CAN controller after deactivation.
*
* In Filter mode: After this function call all Filter are reset and must
* be reconfigured!
*
* At the end of the function, the CAN controller should be in state disabled.
*
* \param
* bitrate - CANopen bitrate
* \results
* RET_T
*/
RET_T codrvCanReInit(
UNSIGNED16 bitRate /**< Bitrate */
)
{
RET_T retVal;
retVal = codrvCanInitController(bitRate,0u);
return(retVal);
}
/***************************************************************************/
/**
* \brief codrvCanInitController - init CAN controller
*
* \internal
*
* This Function inits the CAN controller and setup the bitrate
* After that, the CAN controller is disabled.
*
* \param
* bitrate - CANopen bitrate
* \results
* RET_T
*/
static RET_T codrvCanInitController(
UNSIGNED16 nomBitrate,
UNSIGNED16 datBitrate
)
{
RET_T retVal = RET_OK;
#ifdef CODRV_MCAN_FIXED_MSG_RAM
#else /* CODRV_MCAN_FIXED_MSG_RAM */
UNSIGNED32 ramOffset = (sizeof(MCAN_MSGRAM_T) * mcanMsgRamOffs);
#endif /* CODRV_MCAN_FIXED_MSG_RAM */
/* exit from sleep mode */
pCan->CCCR &= ~MCAN_CCCR_BIT_CSR;
/* wait for sleep mode acknowledge */
while((pCan->CCCR & MCAN_CCCR_BIT_CSA) == MCAN_CCCR_BIT_CSA) {
;
}
/* Request initialization */
pCan->CCCR |= MCAN_CCCR_BIT_INIT;
while((pCan->CCCR & MCAN_CCCR_BIT_INIT) != MCAN_CCCR_BIT_INIT) {
;
}
/* Enable configuration change */
pCan->CCCR |= MCAN_CCCR_BIT_CCE;
while((pCan->CCCR & MCAN_CCCR_BIT_CCE) != MCAN_CCCR_BIT_CCE) {
;
}
/* set the ram address for message ram */
#ifdef CODRV_MCAN_STATIC_MSG_RAM
#else /* CODRV_MCAN_STATIC_MSG_RAM */
*pMcanMRBA = (UNSIGNED32)pMcanMsgRam;
#endif /* CODRV_MCAN_STATIC_MSG_RAM */
/* setup filter */
#ifdef CODRV_MCAN_FIXED_MSG_RAM
#else /* CODRV_MCAN_FIXED_MSG_RAM */
pCan->SIDFC = ((UNSIGNED32)CODRV_MCAN_FILTER_STD_SIZE << 16u) | ramOffset;
ramOffset += MCAN_SIDF_SIZE * CODRV_MCAN_FILTER_STD_SIZE;
pCan->XIDFC = ((UNSIGNED32)CODRV_MCAN_FILTER_EXT_SIZE << 16u) | ramOffset;
ramOffset += MCAN_XIDF_SIZE * CODRV_MCAN_FILTER_EXT_SIZE;
/* RX Buffer/FIFO Element Size 64 bytes data field */
pCan->RXESC |= (UNSIGNED32)CODRV_MCAN_ELEMENT_SIZE_CODE;
/* RX Buffer/FIFO configuration */
pCan->RXF0C = ((UNSIGNED32)CODRV_MCAN_RXFIFO_SIZE << 16u) | ramOffset;
ramOffset += CODRV_MCAN_RXFIFO_SIZE * MCAN_RXF0_SIZE;
#endif /* CODRV_MCAN_FIXED_MSG_RAM */
#ifdef CO_DRV_FILTER
/* the GFC register differs if the message ram is fixed or not.
This has to be checked if new STM32 derivatives are released,
that this is still the case! */
# ifdef CODRV_MCAN_FIXED_MSG_RAM
pCan->GFC = (UNSIGNED32)(0x3c | (CODRV_MCAN_FILTER_EXT_SIZE << 24) | (CODRV_MCAN_FILTER_STD_SIZE << 16)) ;
# else /* CODRV_MCAN_FIXED_MSG_RAM */
pCan->GFC = (UNSIGNED32)0x3c;
# endif /* CODRV_MCAN_FIXED_MSG_RAM */
#else /* CO_DRV_FILTER */
/* Accept Non-matching Frames Into FIFO 0 */
pCan->GFC = (UNSIGNED32)0x0;
#endif /* CO_DRV_FILTER */
#ifdef CODRV_MCAN_FIXED_MSG_RAM
#else /* CODRV_MCAN_FIXED_MSG_RAM */
/* only support one Tx Buffer currently */
pCan->TXBC = ((UNSIGNED32)1u << 16u) | ramOffset;
/* support up to 64 bytes payload */
pCan->TXESC = ((UNSIGNED32)CODRV_MCAN_ELEMENT_SIZE_CODE);
#endif /* CODRV_MCAN_FIXED_MSG_RAM */
/* Set the automatic retransmission */
pCan->CCCR &= ~MCAN_CCCR_BIT_DAR;
/* init req. variables */
canEnabled = CO_FALSE;
transmissionIsActive = CO_FALSE;
/* error states */
codrvCanErrorInit();
/* set bitrate */
retVal = codrvCanSetBitRate(nomBitrate); /*lint !e838 initialization for long function */
(void)datBitrate;
#ifdef DEBUG_SEND_TESTMESSAGE
if (retVal == RET_OK) {
codrvCanEnable();
codrvSendTestMessage();
}
#endif /* DEBUG_SEND_TESTMESSAGE */
return(retVal);
}
#ifdef CODRV_AUTOBAUD
/***************************************************************************/
/**
*
* codrvAutoBaudNextBitrate - set next bitrate for autobaud
*
* \internal
*
* \returns
* RET_T
*/
RET_T codrvAutoBaudNextBitrate(
void /* no parameter */
)
{
RET_T retVal;
autoBaudBitRateIdx++;
if (codrvCanBittimingTable[autoBaudBitRateIdx].bitRate == 0u) {
autoBaudBitRateIdx = 0u;
}
retVal = codrvCanSetBitRate(codrvCanBittimingTable[autoBaudBitRateIdx].bitRate); /*lint !e838 initialization for long function */
return(retVal);
}
/***********************************************************************/
/**
* codrvAutoBaudGetActualBitrate - get actual used bitrate
*
* This function returns the actual used bitrate.
* They haven't be valid.
*
*
* \returns
* bitrate
*/
UNSIGNED16 codrvAutoBaudGetActualBitrate(
void /* no parameter */
)
{
return(codrvCanBittimingTable[autoBaudBitRateIdx].bitRate);
}
#endif /* CODRV_AUTOBAUD */
/***************************************************************************/
/**
* codrvCanGetBtrSettings - get pointer to the btr value structure
*
* \internal
*
* \returns
* pointer to an btr table entry
*/
static CO_CONST CODRV_BTR_T * codrvCanGetBtrSettings(
UNSIGNED16 bitRate /**< required bitrate */
)
{
CO_CONST CODRV_BTR_T * pBtrEntry = NULL;
UNSIGNED8 i = 0u;
while (codrvCanBittimingTable[i].bitRate != 0u) {
if (codrvCanBittimingTable[i].bitRate == bitRate) {
pBtrEntry = &codrvCanBittimingTable[i];
break;
}
i++;
}
return(pBtrEntry);
}
/***************************************************************************/
/**
* codrvCanSetBitRate - sets the CAN bit rate
*
* \internal
*
* Changing the Bitrate only if the CAN controller is in Reset
*
* \param
* bitRate in kbit/s
* \results
* RET_T
*
*/
RET_T codrvCanSetBitRate(
UNSIGNED16 bitRate /**< bit rate in kbit/s */
)
{
CO_CONST CODRV_BTR_T * pBtrEntry;
UNSIGNED32 pre;
UNSIGNED32 seg1;
UNSIGNED32 seg2;
/* stop CAN controller */
(void)codrvCanDisable();
pBtrEntry = codrvCanGetBtrSettings(bitRate);
if (pBtrEntry == NULL) {
/* if bitrate not supported */
return(RET_DRV_WRONG_BITRATE);
}
/* Enable configuration change */
pCan->CCCR |= MCAN_CCCR_BIT_CCE;
while((pCan->CCCR & MCAN_CCCR_BIT_CCE) != MCAN_CCCR_BIT_CCE) {
;
}
pre = (UNSIGNED32)pBtrEntry->pre;
seg1 = (UNSIGNED32)pBtrEntry->seg1 + (UNSIGNED32)pBtrEntry->prop;
seg2 = (UNSIGNED32)pBtrEntry->seg2;
#ifdef CODRV_AUTOBAUD
# warning "autobaud not supported yet"
#endif
pCan->NBTP = ((UNSIGNED32)(seg2 - 1u) << 25) | /*use same size for sjw as seg2*/\
((UNSIGNED32)(pre - 1u) << 16) | \
((UNSIGNED32)(seg1 - 1u) << 8) | \
((UNSIGNED32)(seg2 - 1u));
return(RET_OK);
}
/***************************************************************************/
/**
* codrvCanEnable - enable CAN controller
*
* \internal
*
* \param
* none
* \results
* RET_T
*/
RET_T codrvCanEnable(
void /* no parameter */
)
{
pCan->CCCR &= ~MCAN_CCCR_BIT_INIT;
/* Error active is later checked */
/* enable interrupts */
codrvCanEnableInterrupt();
/* enable interrupt line 0 */
pCan->ILE = 1u;
pCan->IE = MCAN_IE_BIT_RF0NE | MCAN_IE_BIT_TCE | MCAN_IE_BIT_BO | MCAN_IE_BIT_EP;
#ifdef CO_DRV_FILTER
# ifdef CODRV_DEBUG
printFilter();
# endif /* CODRV_DEBUG */
#endif /* CO_DRV_FILTER */
canEnabled = CO_TRUE;
oldEsrValue = 0xFFffFFffu;
return(RET_OK);
}
/***************************************************************************/
/**
* codrvCanDisable - disable CAN controller
*
* This function disables the CAN controller. The function waits
* for the CAN controller being disabled. Code calling this function
* typically expects that after returning the CAN controller is in Init mode.
*
* But note, the time the CAN controller needs to enter the Init mode
* can be as long as the duration of one CAN frame.
*
* \internal
*
* \param
* none
* \results
* RET_OK CAN controller is set to be disabled
*/
RET_T codrvCanDisable(
void /* no parameter */
)
{
/* disable CAN controller */
pCan->CCCR |= MCAN_CCCR_BIT_INIT;
while ((pCan->CCCR & MCAN_CCCR_BIT_INIT) == 0u) {
/* 500us on 250kbit/s */
}
pCan->ILE = 0u;
pCan->IE &= ~MCAN_IE_BIT_RF0NE;
pCan->IE &= ~MCAN_IE_BIT_TCE;
pCan->IE &= ~MCAN_IE_BIT_BO;
pCan->IE &= ~MCAN_IE_BIT_EP;
canEnabled = CO_FALSE;
return(RET_OK);
}
#ifdef CO_DRV_FILTER
# ifdef CO_DRV_GROUP_FILTER
/***********************************************************************/
/**
* \brief codrvCheckGroupFilter - check, if the canId part of the group filter
*
* Depend of some settings the group filter are for the IDs
* 0x700..0x77F - Heartbeat
* 0x80..0xFF - Emergency (and default Sync)
*
* \return BOOL_T
* \retval CO_TRUE
* The ID is part of the group filter.
* \retval CO_FALSE
* The ID is not part of the group filter.
*
*
*
*/
static BOOL_T codrvCanCheckGroupFilter(
CO_CONST CO_CAN_COB_T * CO_CONST pCob
)
{
BOOL_T retval;
UNSIGNED32 canId = pCob->canId;
retval = CO_FALSE;
if ((pCob->flags & CO_COBFLAG_RTR) != CO_COBFLAG_RTR)
{
# ifdef CO_HB_CONSUMER_CNT
if ((canId & 0x0780u) == 0x700u) {
/* part of the group filter */
retval = CO_TRUE;
}
# endif /* CO_HB_CONSUMER_CNT */
# ifdef CO_EMCY_CONSUMER_CNT
if ((canId & 0x0780u) == 0x80u) {
/* part of the group filter */
retval = CO_TRUE;
}
# endif /* CO_EMCY_CONSUMER_CNT */
}
return(retval);
}
# endif /* CO_DRV_GROUP_FILTER */
/***************************************************************************/
/* codrvCanDisableExtIdFilter -disables an extended filter element
*
* This function disables an extended filter element from a given cob. The
* element number is coded in the upper 8bits of the canChan member.
*
* \internal
*
* \results
* RET_T
*/
static RET_T codrvCanDisableExtIdFilter(
CO_CAN_COB_T * CO_CONST pCob
)
{
UNSIGNED16 chan;
MCAN_MSGRAM_T * pRam;
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
if ((pCob->canChan & 0xff00) == 0xff00) {
/* already disabled */
return(RET_OK); /*lint !e904 function entry check */
}
chan = pCob->canChan >> 8u;
pRam->extIdFilter[chan].F0 = 0u;
pRam->extIdFilter[chan].F1= 0u;
pCob->canChan |= 0xff00;
return(RET_OK);
}
/***************************************************************************/
/* codrvCanDisableStdIdFilter -disables an standard filter element
*
* This function disables an standard filter element from a given cob. The
* element number is coded in the lower 8bits of the canChan member.
*
* \internal
*
* \results
* RET_T
*/
static RET_T codrvCanDisableStdIdFilter(
CO_CAN_COB_T * CO_CONST pCob
)
{
UNSIGNED16 chan;
MCAN_MSGRAM_T * pRam;
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
if ((pCob->canChan & 0x00ff) == 0x00ff) {
/* already disabled */
return(RET_OK); /*lint !e904 function entry check */
}
chan = pCob->canChan & 0x00ff;
pRam->stdIdFilter[chan] = 0x00000000u;
pCob->canChan |= 0x00ff;
return(RET_OK);
}
static RET_T codrvCanEnableExtIdFilter(
CO_CAN_COB_T * CO_CONST pCob
)
{
UNSIGNED16 chan;
UNSIGNED32 mask;
MCAN_MSGRAM_T * pRam;
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
chan = pCob->canChan >> 8u;
if (chan == 0xff) {
/* search next free entry */
for (chan = 0u; chan < CODRV_MCAN_FILTER_EXT_SIZE; chan++) {
if (pRam->extIdFilter[chan].F0 == 0u) {
break;
}
}
if (chan == CODRV_MCAN_FILTER_EXT_SIZE) {
return(RET_DRV_ERROR);
}
}
pRam->extIdFilter[chan].F0 = pCob->canId & 0x1fffffff;
mask = ~(pCob->ignore);
mask &= 0x1fffffff;
pRam->extIdFilter[chan].F1 = 0x2u << 30u;
pRam->extIdFilter[chan].F1 |= mask;
/* enable filter */
pRam->extIdFilter[chan].F0 |= 0x20000000;
pCob->canChan &= 0x00ff;
pCob->canChan |= (chan << 8u);
return(RET_OK);
}
static RET_T codrvCanEnableStdIdFilter(
CO_CAN_COB_T * CO_CONST pCob
)
{
UNSIGNED16 chan;
UNSIGNED32 mask;
MCAN_MSGRAM_T * pRam;
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
chan = pCob->canChan & 0xff;
if (chan == 0xff) {
/* search next free entry */
for (chan = 0u; chan < CODRV_MCAN_FILTER_STD_SIZE; chan++) {
if (pRam->stdIdFilter[chan] == 0x00000000u) {
break;
}
}
if (chan == CODRV_MCAN_FILTER_STD_SIZE) {
return(RET_DRV_ERROR);
}
}
pRam->stdIdFilter[chan] = pCob->canId & 0x7ff;
pRam->stdIdFilter[chan] <<= 16u;
mask = ~(pCob->ignore);
mask &= 0x7ff;
pRam->stdIdFilter[chan] |= mask;
/* enable filter */
pRam->stdIdFilter[chan] |= (1u<<27);
pRam->stdIdFilter[chan] |= (2u<<30);
pCob->canChan &= 0xff00;
pCob->canChan |= chan;
return(RET_OK);
}
/***********************************************************************/
/**
* codrvCanSetFilter - activate and configure the receive filter
*
* Depend of the COB entry's the driver specific filter will
* be configured.
*
* For the bxCan only Base Identifiere are allowed.
*
*
* \retval RET_OK
* OK
* \retval RET_INVALID_PARAMETER
* invalid COB reference
* \retval RET_DRV_ERROR
* filter cannot be set, e.g. no free entry
*
*/
RET_T codrvCanSetFilter(
CO_CAN_COB_T * pCanCob /**< COB reference */
)
{
# ifdef CODRV_DEBUG
printf("codrvCanSetFilter: 0x%04x rtr: %d enabled: %d\n", pCanCob->canId, (pCanCob->flags & CO_COBFLAG_RTR), (pCanCob->flags & CO_COBFLAG_ENABLED));
# endif
/* get a filter entry in case of:
* - COB has a filter entry from older setting or
* - COB is enabled and
* - COB is a Receive Data Frame or
* - COB is a Transmit Data Frame, but can be query by RTR
*/
(void)codrvCanDisableExtIdFilter(pCanCob);
(void)codrvCanDisableStdIdFilter(pCanCob);
if ((pCanCob->flags & CO_COBFLAG_ENABLED) == CO_COBFLAG_ENABLED) {
if ((pCanCob->flags & CO_COBFLAG_EXTENDED) == CO_COBFLAG_EXTENDED) {
return(codrvCanEnableExtIdFilter(pCanCob));
} else {
return(codrvCanEnableStdIdFilter(pCanCob));
}
}
# ifdef CODRV_DEBUG
printFilter();
# endif
return(RET_OK);
}
#endif /* CO_DRV_FILTER */
/***********************************************************************/
/**
* codrvCanStartTransmission - start can transmission if not active
*
* Transmission of CAN messages should be interrupt driven.
* If a message was sent, the Transmit Interrupt is called
* and the next message can be transmitted.
* To start the transmission of the first message,
* this function is called from the stack.
*
* The easiest way to implement this function is
* to trigger the transmit interrupt,
* but only if the transmission is not already active.
*
* \internal
*
* \return RET_T
*
*/
RET_T codrvCanStartTransmission(
void /* no parameter */
)
{
RET_T retVal = RET_DRV_BUSY;
/* if can is not enabled, return with error */
if (canEnabled != CO_TRUE) {
return(RET_DRV_ERROR); /*lint !e904 function entry check */
}
if (transmissionIsActive == CO_FALSE) {
/* trigger transmit interrupt */
#ifdef POLLING
retVal = codrvCanTransmitInterrupt();
#else /* POLLING */
/* enable global interrupt pending bit to call interrupt */
codrvCanSetTxInterrupt();
#endif /* POLLING */
} else {
codrvCanDriverHandler();
}
return(retVal);
}
/***************************************************************************/
/* codrvCanTransmit - transmit can message
*
* This function writes a new message to the CAN controller and transmits it.
* Normally called from transmit Interrupt
*
* \internal
*
* \results
* RET_T
*/
static RET_T codrvCanTransmit(
CO_CONST CO_CAN_TR_MSG_T * pBuf /**< pointer to data */
)
{
RET_T retVal = RET_OK;
/* currently, general MB 0 */
UNSIGNED32 ctrl;
UNSIGNED8 i;
MCAN_MSGRAM_T * pRam;
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
/* return if device is not initialized or enabled */
if (canEnabled == CO_FALSE) {
return(RET_DRV_ERROR);
}
/* busy check */
if (pCan->TXBRP != 0ul) {
return(RET_DRV_BUSY); /*lint !e904 function entry check */
}
ctrl = pBuf->len;
if (ctrl > 8u) {
ctrl = 8u;
}
pRam->txBuf[0u].ctrl = (ctrl << 16u);
/* extended CAN ID */
if ((pBuf->flags & CO_COBFLAG_EXTENDED) == CO_COBFLAG_EXTENDED) {
/* message with 29 bit identifier */
pRam->txBuf[0u].id = pBuf->canId;
pRam->txBuf[0u].id |= MCAN_CANID_BIT_XTD;
} else {
/* message with 11 bit identifier */
pRam->txBuf[0u].id = (pBuf->canId << 18u);
}
/* remote transmission request */
if ((pBuf->flags & CO_COBFLAG_RTR) == CO_COBFLAG_RTR) {
/* message is remote frame */
pRam->txBuf[0u].id |= MCAN_CANID_BIT_RTR;
}
/* copy message data */
if ((pBuf->flags & CO_COBFLAG_RTR) != CO_COBFLAG_RTR) {
for (i = 0u; i < CODRV_MCAN_ELEMENT_DATA_SIZE; i = i + 4u) {
*((UNSIGNED32*)&(pRam->txBuf[0u].data[i])) =
(UNSIGNED32)pBuf->data[i] | \
((UNSIGNED32)pBuf->data[i + 1] << 8u) | \
((UNSIGNED32)pBuf->data[i + 2] << 16u) | \
((UNSIGNED32)pBuf->data[i + 3] << 24u);
}
}
/* transmit it */
/* currently, general MB 0 */
pCan->TXBAR = 1ul;
pCan->TXBTIE = 0x01;
transmissionIsActive = CO_TRUE;
return(retVal);
}
/***************************************************************************/
/* codrvCanDriverTransmitInterrupt - can driver transmit interrupt
*
* \internal
*
* This function is called, after message was transmitted.
* As first, inform stack about message transmission.
* Get the next message from the transmit buffer, write it to the CAN controller
* and transmit it.
*
* \param
* none
* \results
* none
*/
RET_T codrvCanTransmitInterrupt(
void /* no parameter */
)
{
RET_T retVal = RET_OK;
/* reset interrupt request
* => currently reset all possible TX IRQ requests
*
* -> very simple implementation
*/
if (pCan->TXBRP == 0ul) {
transmissionIsActive = CO_FALSE;
/* inform stack about transmitted message */
if (pTxBuf != NULL) {
coQueueMsgTransmitted(pTxBuf);
pTxBuf = NULL;
/* signal transmitted message */
CO_OS_SIGNAL_CAN_TRANSMIT
}
/* get next message from transmit queue */
pTxBuf = coQueueGetNextTransmitMessage();
if (pTxBuf != NULL) {
/* and transmit it - CAN message buffer is free */
retVal = codrvCanTransmit(pTxBuf);
}
/* clear interrupt flag */
pCan->IR = MCAN_IE_BIT_TCE;
} else {
retVal = RET_DRV_BUSY;
}
return(retVal);
}
/***********************************************************************
* codrvCanReceiveInterrupt - can driver receive interrupt
*
* \internal
*
* This function is called, if a new message was received
* As first get the pointer to the receive buffer
* and save the message there.
* Then set the buffer as filled and inform the library about new data.
*
*
* \param
* none
* \results
* none
*/
void codrvCanReceiveInterrupt(
void /* no parameter */
)
{
UNSIGNED8 *pRecBuf;
UNSIGNED8 coFlags;
UNSIGNED8 len;
UNSIGNED8 mbNr = 0u;
UNSIGNED32 id;
CAN_ERROR_FLAGS_T * pError;
UNSIGNED8 i;
MCAN_MSGRAM_T * pRam;
#ifdef CO_CAN_TIMESTAMP_SUPPORTED
CO_CAN_TIMESTAMP_T timestamp;
#endif /* CO_CAN_TIMESTAMP_SUPPORTED */
pRam = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
pCan->IR = MCAN_IE_BIT_RF0NE;
if ((pCan->RXF0S & 0x7f) == 0u) {
return;
}
do {
/* delete pending interrupt */
pCan->IR = MCAN_IE_BIT_RF0NE;
/* initialize COB flag */
coFlags = CO_COBFLAG_NONE;
/* currently only Fifo 0 */
mbNr = ((pCan->RXF0S >> 8u) & 0x3f);
/* get Identifier */
id = pRam->rxFifo[mbNr].id;
/* extended CAN-ID */
if ((id & MCAN_CANID_BIT_XTD) == MCAN_CANID_BIT_XTD) {
coFlags |= CO_COBFLAG_EXTENDED;
}
/* remote transmission request */
if ((id & MCAN_CANID_BIT_RTR) == MCAN_CANID_BIT_RTR) {
coFlags |= CO_COBFLAG_RTR;
}
len = (pRam->rxFifo[mbNr].ctrl >> 16) & 0x0f;
/* FD frame */
if (((pRam->rxFifo[mbNr].ctrl >> 21) & 0x01) == 1u) {
continue;
} else {
if (len > 8u) {
len = 8u;
}
}
/* save 11/29 bit CAN-ID */
if ((id & MCAN_CANID_BIT_XTD) != MCAN_CANID_BIT_XTD) {
/* save 11 bit CAN-ID */
id = (id >> 18u) & 0x7FFul;
} else {
/* save 29 bit CAN-ID */
id = id & 0x1FFFFFFFul;
}
#ifdef CO_CAN_TIMESTAMP_SUPPORTED
/* get RX timestamp */
timestamp = (UNSIGNED32)(pRam->rxFifo[mbNr].ctrl & 0xffFF);
#endif /* CO_CAN_TIMESTAMP_SUPPORTED */
/* get receiveBuffer */
pRecBuf = coQueueGetReceiveBuffer(id, len, coFlags
#ifdef CO_CAN_TIMESTAMP_SUPPORTED
, timestamp
#endif /* CO_CAN_TIMESTAMP_SUPPORTED */
);
if (pRecBuf == NULL) {
/* error, no buffer available */
/* release mailbox */
pCan->RXF0A = mbNr;
/* signal received message - but there was generated
* signals for all older received messages
* that are in the buffer
*/
/* CO_OS_SIGNAL_CAN_RECEIVE */
return; /*lint !e904 no buffer possible */
}
/* save message at buffer */
if ((id & MCAN_CANID_BIT_RTR) != MCAN_CANID_BIT_RTR) {
for (i = 0u; i < len; i++) {
pRecBuf[i] = pRam->rxFifo[mbNr].data[i];
}
}
if ((pCan->RXF0S & (1u << 25u)) == (1u << 25u)) {
pError = codrvCanErrorGetFlags();
pError->canErrorRxOverrun = CO_TRUE;
/* reset message lost error */
pCan->IR |= (1u << CODRV_RX0L_IR_POS);
}
/* release mailbox */
pCan->RXF0A = mbNr;
/* set buffer filled */
coQueueReceiveBufferIsFilled();
} while (pCan->RXF0S & 0x7f);
/* signal received message */
CO_OS_SIGNAL_CAN_RECEIVE
}
/***********************************************************************
* codrvCanErrorInterrupt - can driver error interrupt
*
* \internal
*
* This function is called, if a error passive or Busoff event
* occurs.
*
* \param
* none
* \results
* none
*/
void codrvCanErrorInterrupt(
void /* no parameter */
)
{
if ((pCan->IR & (MCAN_IE_BIT_BO | MCAN_IE_BIT_EP)) != 0u) {
CAN_ERROR_FLAGS_T * pError;
/* set flag to signal the state change */
pError = codrvCanErrorGetFlags();
if ((pCan->IR & MCAN_IE_BIT_BO) != 0) {
pError->canErrorBusoff = CO_TRUE;
/* clear init bit to get buss on again */
pCan->CCCR &= ~MCAN_CCCR_BIT_INIT;
} else
if ((pCan->IR & MCAN_IE_BIT_EP) != 0) {
pError->canErrorPassive = CO_TRUE;
} else {
/* never occur, because the error interrupt is not
* calling for this state change */
pError->canErrorActive = CO_TRUE;
}
/* clear interrupt bit */
pCan->IR = (MCAN_IE_BIT_BO | MCAN_IE_BIT_EP);
}
}
/***************************************************************************/
/**
* codrvCanErrorHandler - Error handler
*
* This function polls the current state of the CAN controller
* and checks explicitly all situation that are not signaled
* within the interrupts.
*
* Call outside of interrupts!
* Typical call in codrvCanDriverHandler().
*/
static void codrvCanErrorHandler(
void /* no parameter */
)
{
UNSIGNED32 err;
UNSIGNED32 change;
CAN_ERROR_FLAGS_T * pError;
BOOL_T fStartTransmission = CO_FALSE;
pError = codrvCanErrorGetFlags();
/*
* Error active/passive/busoff check
*/
err = pCan->PSR;
/* check only changes of passive and busoff */
change = err ^ oldEsrValue;
change &= ((MCAN_PSR_BIT_BO) | (MCAN_PSR_BIT_EP));
if (change != 0ul) {
if ((err & MCAN_PSR_BIT_BO) != 0ul) {
/* busoff */
/* canErrorBusoff = CO_TRUE;*/
pError->canNewState = Error_Busoff; /* current state */
} else
if ((err & MCAN_PSR_BIT_EP) != 0ul) {
/* error passive */
/* canErrorPassive = CO_TRUE; */
pError->canNewState = Error_Passive; /* current state */
} else {
/* error active */
/* canErrorActive = CO_TRUE; */
pError->canNewState = Error_Active; /* current state */
}
}
oldEsrValue = err;
/* busoff recovery */
if ((err & MCAN_PSR_BIT_BO) != 0ul) {
/* busoff */
pCan->CCCR &= ~MCAN_CCCR_BIT_INIT;
}
/* more for polling - software interrupt, but TX object was sended */
if (pCan->TXBRP == 0ul) {
/* correct possible Errors -> CAN has deactivated the transmission */
transmissionIsActive = CO_FALSE;
}
if (canEnabled == CO_TRUE) {
/* check for stopped transmissions */
if ((transmissionIsActive == CO_FALSE) && (pTxBuf != NULL)) {
/* transmission aborted, e.g. busoff,
* discard message -> is done within the tx interrupt
*/
fStartTransmission = CO_TRUE;
}
}
if (fStartTransmission == CO_TRUE) {
(void)codrvCanStartTransmission(); /* -> call Interrupt at this point */
}
}
/***************************************************************************/
/** codrvCanDriverHandler - can driver handler
*
* \internal
*
* is cyclically called from stack to get actual CAN state
* (BUS_OFF, PASSIVE, ACTIVE)
* and return to bus on again after bus off was occurred.
*
* \param
* none
* \results
* none
*/
void codrvCanDriverHandler(
void /* no parameter */
)
{
/* check current state */
codrvCanErrorHandler();
/*
* inform the CANopen Stack about state changes
*/
(void)codrvCanErrorInformStack();
#ifdef POLLING
codrvCanReceiveInterrupt();
codrvCanTransmitInterrupt();
#endif /* POLLING */
return;
}
#ifdef CODRV_DEBUG
#include <stdio.h>
void printFilter(void)
{
# ifdef CODRV_DEBUG_MAX
int i,j;
volatile UNSIGNED32 *pCanFilter = pCanFilterAddr;
printf("\nFiltersettings:\n");
printf("FINIT %d\n", pCanFilter[BXCAN_CANFMR] & BXCAN_CANFMR_FINIT );
printf("Filter active (0 off 1 on) 0x%08lx\n", pCanFilter[BXCAN_CANFA1R]);
printf("Filtermode (0 mask 1 list) 0x%08lx\n", pCanFilter[BXCAN_CANFM1R]);
printf("Filterscale (0 16-bit 1 32-bit) 0x%08lx\n", pCanFilter[BXCAN_CANFS1R]);
printf("Filter assignm (0 fifo0 1 fifo1) 0x%08lx\n", pCanFilter[BXCAN_CANFFA1R]);
printf("\n");
//for(i = 0; i < 14; i++)
for(i = 0; i <= 0; i++)
{
for (j = 1; j <= 2; j++) {
printf("\n");
printf("Filterbank %d Register %d\n", i,j );
printf("Adr: 0x%08lx\n", &pCanFilter[BXCAN_CANFIRX(i,j)]);
printf(" ID 0x%04x\n", (pCanFilter[BXCAN_CANFIRX(i,j)] & 0xFFFFul) >> 5 );
if( (pCanFilter[BXCAN_CANFM1R] & (1ul << i)) != 0) {
printf(" ID 0x%04x\n", (pCanFilter[BXCAN_CANFIRX(i,j)] >> (16 + 5) )& 0xFFFFul);
} else {
printf("Mask 0x%04x\n", (pCanFilter[BXCAN_CANFIRX(i,j)] >> (16 + 5) )& 0xFFFFul);
}
}
}
for(i = 1; i < 14; i++)
{
if( (pCanFilter[BXCAN_CANFA1R] & (1ul << i)) != 0) {
for (j = 1; j <= 2; j++) {
printf("\n");
printf("Filterbank %d Register %d Val 0x%08lx\n", i,j, pCanFilter[BXCAN_CANFIRX(i,j)] );
printf(" ID 0x%04x\n", (pCanFilter[BXCAN_CANFIRX(i,j)] & 0xFFFFul) >> 5);
printf(" ID 0x%04x\n", ((pCanFilter[BXCAN_CANFIRX(i,j)] >> 16 )& 0xFFFFul) >> 5);
}
}
}
# endif
}
#endif
static void codrvCanResetRam(
void /* no parameter */
)
{
volatile MCAN_MSGRAM_T *pOffset;
pOffset = (MCAN_MSGRAM_T *)(pMcanMsgRam + mcanMsgRamOffs);
memset((void*)pOffset, 0x00u, sizeof(MCAN_MSGRAM_T));
}