你(们)好
它正在与 PCANview 连接并检查通信操作。
从 PCANview 的角度来看、如果定期执行发送操作、则电路板上的 CANFD 接收中断第一次只会发生一次、之后不会发生中断。
如果 CANFD_Rx_Control()函数在100us 周期内从 CPUTimer 中断调用,而不是在 CANFD 接收中断内部调用,则确认接收工作正常。
当使用 CANFD 接收中断时、我想知道为什么中断第一次只发生一次、之后中断不起作用。
是否有任何与 Rx 相关的寄存器未被清除? 请帮助。
#define NUM_OF_MSG (1U)
#define MCAN_STD_ID_FILT_START_ADDR (0U)
#define MCAN_STD_ID_FILTER_NUM (1U)
#define MCAN_EXT_ID_FILT_START_ADDR (48U)
#define MCAN_EXT_ID_FILTER_NUM (1U)
#define MCAN_TX_EVENT_START_ADDR (100U)
#define MCAN_TX_EVENT_SIZE (NUM_OF_MSG)
#define MCAN_TX_EVENT_WATERMARK (NUM_OF_MSG/2)
#define MCAN_TX_BUFF_START_ADDR (148U)
#define MCAN_TX_BUFF_SIZE (NUM_OF_MSG)
#define MCAN_TX_FIFO_SIZE (NUM_OF_MSG)
#define MCAN_FIFO_0_START_ADDR (548U)
#define MCAN_FIFO_0_NUM (NUM_OF_MSG)
#define MCAN_FIFO_0_WATERMARK (NUM_OF_MSG)
#define MCAN_FIFO_1_START_ADDR (748U)
#define MCAN_FIFO_1_NUM (NUM_OF_MSG)
#define MCAN_FIFO_1_WATERMARK (NUM_OF_MSG)
#define MCAN_RX_BUFF_START_ADDR (948U)
#define MCAN_EXT_ID_AND_MASK (0x1FFFFFFFU)
#define MCAN_TS_PRESCALAR (0xB0)
#define MCAN_TX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64Bytes)
#define MCAN_RX_BUFF_ELEM_SIZE (MCAN_ELEM_SIZE_64Bytes)
#define MCAN_RX_FIFO0_ELEM_SIZE (MCAN_ELEM_SIZE_64Bytes)
#define MCAN_RX_FIFO1_ELEM_SIZE (MCAN_ELEM_SIZE_64Bytes)
void CANFD_Init(void);
static void MCANConfig(void);
void MCANIntrConfig(void);
__interrupt void MCANIntr1ISR(void);
MCAN_RxBufElement CANFD_rxMsg;
MCAN_RxFIFOStatus RxFS;
void CANFD_Rx_DATA()
{
if(CANFD_rxMsg.id==0x100)
{
CANFD_DATA.Rx_Test[0] = CANFD_rxMsg.data[0];
CANFD_DATA.Rx_Test[1] = CANFD_rxMsg.data[1];
CANFD_DATA.Rx_Test[2] = CANFD_rxMsg.data[2];
CANFD_DATA.Rx_Test[3] = CANFD_rxMsg.data[3];
CANFD_DATA.Rx_Test[4] = CANFD_rxMsg.data[4];
CANFD_DATA.Rx_Test[5] = CANFD_rxMsg.data[5];
CANFD_DATA.Rx_Test[6] = CANFD_rxMsg.data[6];
CANFD_DATA.Rx_Test[7] = CANFD_rxMsg.data[7];
}
}
void CANFD_Rx_Control(void)
{
// Read Message RAM.
MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_FIFO, 0U, MCAN_RX_FIFO_NUM_1, &CANFD_rxMsg);
RxFS.num = MCAN_RX_FIFO_NUM_1;
MCAN_getRxFIFOStatus(MCAN0_BASE, &RxFS);
MCAN_writeRxFIFOAck(MCAN0_BASE, MCAN_RX_FIFO_NUM_1, RxFS.getIdx);
CANFD_Rx_DATA();
}
int canfd_rx_isr_fail1=0, isrIntr1Flag=0, canfdRxIsrCnt0=0, canfdRxIsrCnt1=0;
uint32_t intrStatus1;
__interrupt void MCANIntr1ISR(void)
{
//uint32_t intrStatus;
canfdRxIsrCnt1++;
intrStatus1 = MCAN_getIntrStatus(MCAN0_BASE);
if( MCAN_INTR_SRC_RX_FIFO1_NEW_MSG == (intrStatus1 & MCAN_INTR_SRC_RX_FIFO1_NEW_MSG) )
{
//
// Decrement the flag after each message is received.
//
isrIntr1Flag++;
CANFD_Rx_Control();
}
else
{
canfd_rx_isr_fail1++;
}
MCAN_clearIntrStatus(MCAN0_BASE, intrStatus1);
// Acknowledge this interrupt located in group 9
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
void CANFD_Init(void)
{
int i = 0;
//
// Allocated MCAN shared peripheral to C28x
//
SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_MCAN_A,0x0U);
//
// Setting the MCAN Clock.
//
SysCtl_setMCANClk(SYSCTL_MCANCLK_DIV_10);
//
// Configuring the GPIOs for MCAN.
//
GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANRXA);
GPIO_setPinConfig(DEVICE_GPIO_CFG_MCANTXA);
// Initialize message to transmit.
CANFD_txMsg.id = ((uint32_t)(0x11)); // Identifier Value.
CANFD_txMsg.rtr = 0U; // Transmit data frame.
CANFD_txMsg.xtd = 1U; // extended identifier
CANFD_txMsg.esi = 0U; // ESI bit in CAN FD format depends only on error
// passive flag.
CANFD_txMsg.dlc = 15U; // CAN FD: transmit frame has 12/16/20/24/32/48/64 data bytes
CANFD_txMsg.brs = 1U; // CAN FD frames transmitted with bit rate
// switching.
CANFD_txMsg.fdf = 1U; // Frame transmitted in CAN FD format.
CANFD_txMsg.efc = 1U; // Store Tx events.
CANFD_txMsg.mm = 0xAAU; // Message Marker.
// Data bytes.
for(i=0;i<64;i++)
{
CANFD_txMsg.data[i] = i;
}
// CrossBar and ISR Configuration.
MCANIntrConfig();
// Configure MCAN.
MCANConfig();
// Enable Interrupts.
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_MASK_ALL,1);
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_SRC_RES_ADDR_ACCESS|
MCAN_INTR_SRC_TIMESTAMP_WRAPAROUND,0);
MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_SRC_RX_FIFO1_NEW_MSG,
MCAN_INTR_LINE_NUM_1);
MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_1, 1U);
}
void MCANIntrConfig(void)
{
Interrupt_register(INT_MCANSS1,&MCANIntr1ISR);
Interrupt_enable(INT_MCANSS1);
Interrupt_enableMaster();
}
// This function will configure MCAN module.
//
static void MCANConfig(void)
{
MCAN_RevisionId revId;
MCAN_InitParams initParams;
MCAN_ConfigParams configParams;
MCAN_MsgRAMConfigParams msgRAMConfigParams;
MCAN_StdMsgIDFilterElement stdFiltelem;
MCAN_ExtMsgIDFilterElement extFiltelem;
MCAN_BitTimingParams bitTimes;
//
// Initialize MCAN Init parameters.
//
initParams.fdMode = 0x1U; // FD operation disabled.
initParams.brsEnable = 0x1U; // Bit rate switching for
// transmissions enabled.
initParams.txpEnable = 0x1U; // Transmit pause enabled.
initParams.efbi = 0x0U; // Edge filtering disabled.
initParams.pxhddisable = 0x0U; // Protocol exception handling enabled.
initParams.darEnable = 0x1U; // Automatic retransmission of messages
// not transmitted successfully enabled.
initParams.wkupReqEnable = 0x1U; // Wakeup request is enabled.
initParams.autoWkupEnable = 0x1U; // Auto-Wakeup is enabled.
initParams.emulationEnable = 0x1U; // Emulation/Debug Suspend is enabled.
initParams.tdcEnable = 0x1U; // Transmitter Delay Compensation is
// enabled.
initParams.wdcPreload = 0xFFU; // Start value of the Message RAM
// Watchdog Counter preload.
//
// Transmitter Delay Compensation parameters.
//
initParams.tdcConfig.tdcf = 0xAU;
initParams.tdcConfig.tdco = 0x6U;
//
// Initialize MCAN Config parameters.
//
configParams.monEnable = 0x0U; // Bus Monitoring Mode is disabled.
configParams.asmEnable = 0x0U; // Normal CAN operation.
configParams.tsPrescalar = 0x2U; // Prescaler Value.
configParams.tsSelect = 0x2U; // Timestamp counter value.
configParams.timeoutSelect = MCAN_TIMEOUT_SELECT_CONT;
// Time-out counter source select.
configParams.timeoutPreload = 0xFFFFU;// Start value of the Timeout
// Counter.
configParams.timeoutCntEnable = 0x0U; // Time-out Counter is disabled.
configParams.filterConfig.rrfs = 0x1U; // Reject all remote frames with
// 29-bit extended IDs.
configParams.filterConfig.rrfe = 0x1U; // Reject all remote frames with
// 11-bit standard IDs.
configParams.filterConfig.anfe = 0x1U; // Accept in Rx FIFO 1.
configParams.filterConfig.anfs = 0x1U; // Accept in Rx FIFO 1.
//
// Initialize Message RAM Sections Configuration Parameters
//
msgRAMConfigParams.flssa = MCAN_STD_ID_FILT_START_ADDR;
// Standard ID Filter List Start Address.
msgRAMConfigParams.lss = MCAN_STD_ID_FILTER_NUM;
// List Size: Standard ID.
msgRAMConfigParams.flesa = MCAN_EXT_ID_FILT_START_ADDR;
// Extended ID Filter List Start Address.
msgRAMConfigParams.lse = MCAN_EXT_ID_FILTER_NUM;
// List Size: Extended ID.
msgRAMConfigParams.txStartAddr = MCAN_TX_BUFF_START_ADDR;
// Tx Buffers Start Address.
msgRAMConfigParams.txBufNum = MCAN_TX_BUFF_SIZE;
// Number of Dedicated Transmit Buffers.
msgRAMConfigParams.txFIFOSize = MCAN_TX_FIFO_SIZE;
// Tx FIFO/Queue.
msgRAMConfigParams.txBufMode = 0U;
msgRAMConfigParams.txBufElemSize = MCAN_ELEM_SIZE_64BYTES;
// Tx Buffer Element Size.
msgRAMConfigParams.txEventFIFOStartAddr = MCAN_TX_EVENT_START_ADDR;
// Tx Event FIFO Start Address.
msgRAMConfigParams.txEventFIFOSize = MCAN_TX_BUFF_SIZE;
// Event FIFO Size.
msgRAMConfigParams.txEventFIFOWaterMark = MCAN_TX_EVENT_WATERMARK;
// Level for Tx Event FIFO watermark interrupt.
msgRAMConfigParams.rxFIFO0startAddr = MCAN_FIFO_0_START_ADDR;
// Rx FIFO0 Start Address.
msgRAMConfigParams.rxFIFO0size = MCAN_FIFO_0_NUM;
// Number of Rx FIFO elements.
msgRAMConfigParams.rxFIFO0waterMark = MCAN_FIFO_0_WATERMARK;
msgRAMConfigParams.rxFIFO0OpMode = 0U;
msgRAMConfigParams.rxFIFO1startAddr = MCAN_FIFO_1_START_ADDR;
// Rx FIFO1 Start Address.
msgRAMConfigParams.rxFIFO1size = MCAN_FIFO_1_NUM;
// Number of Rx FIFO elements.
msgRAMConfigParams.rxFIFO1waterMark = MCAN_FIFO_1_WATERMARK;
// Level for Rx FIFO 1 watermark interrupt.
msgRAMConfigParams.rxFIFO1OpMode = 0U; // FIFO blocking mode.
msgRAMConfigParams.rxBufStartAddr = MCAN_RX_BUFF_START_ADDR;
// Rx Buffer Start Address.
msgRAMConfigParams.rxBufElemSize = MCAN_ELEM_SIZE_64BYTES;
// Rx Buffer Element Size.
msgRAMConfigParams.rxFIFO0ElemSize = MCAN_ELEM_SIZE_64BYTES;
// Rx FIFO0 Element Size.
msgRAMConfigParams.rxFIFO1ElemSize = MCAN_ELEM_SIZE_64BYTES;
// Rx FIFO1 Element Size.
//
// Initialize Tx Buffer Configuration parameters.
//
stdFiltelem.sfid2 = 0x0U; // Standard Filter ID 2.
stdFiltelem.sfid1 = 0x4U; // Standard Filter ID 1.
stdFiltelem.sfec = 0x7U; // Store into Rx Buffer or as
// debug message, configuration of SFT[1:0] ignored.
stdFiltelem.sft = 0x0U; // Range filter from SFID1 to SFID2.
//
// Initialize Tx Buffer Configuration parameters.
//
extFiltelem.efid2 = ((Uint32)0x9U << 16U);
extFiltelem.efid2 |= 0xFFU;
extFiltelem.efid1 = ((Uint32)0x0U << 16U);
extFiltelem.efid1 |= 0xFFU;
extFiltelem.efec = 0x6U;
extFiltelem.eft = 0x0U;
//
// Initialize bit timings.
//
// Nominal = 1M / Data = 2M
bitTimes.nomRatePrescalar = 0x4U; // Nominal Baud Rate Pre-scaler.
bitTimes.nomTimeSeg1 = 0x1U; // Nominal Time segment before sample point.
bitTimes.nomTimeSeg2 = 0x0U; // Nominal Time segment after sample point.
bitTimes.nomSynchJumpWidth = 0x0U; // Nominal (Re)Synchronization Jump Width Range.
bitTimes.dataRatePrescalar = 0x1U; // Data Baud Rate Pre-scaler.
bitTimes.dataTimeSeg1 = 0x2U; // Data Time segment before sample point.
bitTimes.dataTimeSeg2 = 0x0U; // Data Time segment after sample point.
bitTimes.dataSynchJumpWidth = 0x0U; // Data (Re)Synchronization Jump Width.
//
// Get MCANSS Revision ID
//
MCAN_getRevisionId(MCAN0_BASE, &revId);
//
// Wait for memory initialization to happen.
//
while(FALSE == MCAN_isMemInitDone(MCAN0_BASE))
{
}
//
// Put MCAN in SW initialization mode.
//
MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_SW_INIT);
//
// Wait till MCAN is not initialized.
//
while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(MCAN0_BASE))
{}
//
// Initialize MCAN module.
//
MCAN_init(MCAN0_BASE, &initParams);
//
// Configure MCAN module.
//
MCAN_config(MCAN0_BASE, &configParams);
//
// Disable external timeStamp overflow interrupt.
//
MCAN_extTSEnableIntr(MCAN0_BASE,1);
//
// Configure TimeStamp Counter.
//
MCAN_extTSCounterConfig(MCAN0_BASE, MCAN_TS_PRESCALAR);
//
// Configure Bit timings.
//
MCAN_setBitTime(MCAN0_BASE, &bitTimes);
//
// Set Extended ID Mask.
//
MCAN_setExtIDAndMask(MCAN0_BASE, MCAN_EXT_ID_AND_MASK);
//
// Configure Message RAM Sections
//
MCAN_msgRAMConfig(MCAN0_BASE, &msgRAMConfigParams);
//
// Configure Standard ID filter element
//
MCAN_addStdMsgIDFilter(MCAN0_BASE, 0U, &stdFiltelem);
//
// Configure Extended ID filter element
//
MCAN_addExtMsgIDFilter(MCAN0_BASE, 0U, &extFiltelem);
//
// Enable external counter.
//
//MCAN_extTSCounterEnable(MCAN0_BASE, 1U);
//
// Take MCAN out of the SW initialization mode
//
MCAN_setOpMode(MCAN0_BASE, MCAN_OPERATION_MODE_NORMAL);
while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(MCAN0_BASE))
{
}
}