Part Number: TMDSCNCD28388D
Hi
I have a question from the CAN-FD example.
I am looking at mcan_ex1_loopback.c example, in this example, Tx Interrupt occurs only once at the beginning, and the Rx value is being read!
By applying this, I want to do Tx at a desired time or periodically.
I thought that it would be possible to perform Tx periodically by using the MCAN_writeMsgRam, MCAN_txBufTransIntrEnable, and MCAN_txBufAddReq functions, but the Tx interrupt occurs only once initially and does not occur after that.
Is this a problem because the related setting values are not cleared after the initial Tx..?
Please take a look at the code below to see if there is anything wrong.
"txtest" is a test variable. Used to transmit and receive data at the desired time.
Whenever the'if statement' in line 263 is executed, I thought that data would be transmitted, but it doesn't work. What's wrong with it?
Please help. Thank you
//#############################################################################
//
// FILE: mcan_ex1_loopback.c
//
// TITLE: MCAN Loopback with Interrupts Example
//
//! \addtogroup driver_example_cm_list
//! <h1> MCAN Internal Loopback with Interrupt </h1>
//!
//! This example shows the MCAN Loopback functionality. The internal loopback
//! mode is entered. The sent message should be received by the node. This
//! should not disturb bus thus a manual check is required. Use the last
//! address of memory for Rx buffer. Choose different clock sources and
//! confirm functionality.
//!
//! \b External \b Connections \n
//! - None.
//!
//! \b Watch \b Variables \n
//! - error - Checks if there is an error that occurred when the data was
//! sent using internal loopback.
//!
//
//#############################################################################
// $TI Release: F2838x Support Library v3.04.00.00 $
// $Release Date: Fri Feb 12 19:08:49 IST 2021 $
// $Copyright:
// Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
//
// Include Files
//
#include "driverlib.h"
#include "device.h"
#include "inc/stw_dataTypes.h"
#include "inc/stw_types.h"
//
// Defines
//
#define MCAN_STD_ID_FILT_START_ADDR (0x0U)
#define MCAN_STD_ID_FILTER_NUM (1U)
#define MCAN_EXT_ID_FILT_START_ADDR (0x14U)
#define MCAN_EXT_ID_FILTER_NUM (1U)
#define MCAN_TX_BUFF_START_ADDR (0x80U)
#define MCAN_TX_BUFF_SIZE (10U)
#define MCAN_FIFO_1_START_ADDR (0xc0U)
#define MCAN_FIFO_1_NUM (10U)
#define MCAN_TX_EVENT_START_ADDR (0x100U)
#define MCAN_TX_EVENT_SIZE (10U)
#define MCAN_EXT_ID_AND_MASK (0x1FFFFFFFU)
#define MCAN_RX_BUFF_START_ADDR (948U)
#define MCAN_FIFO_0_START_ADDR (548U)
#define MCAN_FIFO_0_NUM (5U)
#define MCAN_MSG_INT (0x81200)
//
// Global Variables.
//
volatile uint32_t isrIntr0Flag = 1U;
volatile uint32_t isrIntr1Flag = 1U;
volatile uint16_t monEn = 0x0;
volatile unsigned long msgCount = 0;
volatile unsigned long error = 0;
//
// Function Prototype.
//
static void MCANConfig(void);
static void MCANIntrConfig(void);
__interrupt void MCANIntr0ISR(void);
__interrupt void MCANIntr1ISR(void);
//
// Main
//
int forcnt=0, testcnt=0, txtest=0;
MCAN_TxBufElement txMsg;
MCAN_RxBufElement rxMsg;
MCAN_RxNewDataStatus newData;
void main(void)
{
volatile uint32_t mode = 0U;
//
// Initialize device clock and peripherals
//
Device_init();
//
// Initialize GPIO and configure GPIO pins for CANTX/CANRX
//
Device_initGPIO();
//
// Allocated MCAN shared peripheral to C28x
//
SysCtl_allocateSharedPeripheral(SYSCTL_PALLOCATE_MCAN_A,0x0U);
//
// CrossBar and ISR Configuration.
//
MCANIntrConfig();
//
// Initialize message to transmit.
//
txMsg.id = ((uint32_t)(0x4)) << 18U; // Identifier Value.
txMsg.rtr = 0U; // Transmit data frame.
txMsg.xtd = 0U; // 11-bit standard identifier.
txMsg.esi = 0U; // ESI bit in CAN FD format depends only on error
// passive flag.
txMsg.dlc = 4U; // CAN + CAN FD: transmit frame has 0-8 data bytes.
txMsg.brs = 1U; // CAN FD frames transmitted with bit rate
// switching.
txMsg.fdf = 1U; // Frame transmitted in CAN FD format.
txMsg.efc = 1U; // Store Tx events.
txMsg.mm = 0xAAU; // Message Marker.
//
// Data bytes.
//
txMsg.data[0] = 0x12;
txMsg.data[1] = 0x34;
txMsg.data[2] = 0x56;
txMsg.data[3] = 0x78;
//
// Configure MCAN.
//
MCANConfig();
//
// Enable Interrupts.
//
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_MASK_ALL, 1U);
//
// Select Interrupt Line.
//
MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_1);
//
// Enable Interrupt Line.
//
MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_1, 1U);
//
// Write Tx Message to the Message RAM.
//
MCAN_writeMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_BUF, 1U, &txMsg);
//
// Enable Transmission interrupt.
//
MCAN_txBufTransIntrEnable(MCAN0_BASE, 1U,1U);
//
// Add request for transmission.
//
MCAN_txBufAddReq(MCAN0_BASE, 1U);
//
// Wait for the isrIntr1Flag to be reset.
//
while(isrIntr1Flag)
{
}
//
// Read Message RAM.
//
MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_BUF, 0U, MCAN_RX_FIFO_NUM_1,
&rxMsg);
//
// Get the New Data Status.
//
MCAN_getNewDataStatus(MCAN0_BASE, &newData);
/*
//
// Check that received data matches sent data.
// Device will halt here during debug if data doesn't match.
//
if((txMsg.data[0] != rxMsg.data[0]) ||
(txMsg.data[1] != rxMsg.data[1]) ||
(txMsg.data[2] != rxMsg.data[2]) ||
(txMsg.data[3] != rxMsg.data[3]))
{
//
// Device will halt here if transmitted and received data are
// not same.
//
//asm(" ESTOP0");
testcnt++;
}
else
{
//
// Increment message count if message is received.
//
msgCount++;
}
//
// Stop Application.
//
// asm(" ESTOP0");*/
for(;;)
{
//forcnt++;
if(txtest==1)
{
MCANConfig();
//
// Enable Interrupts.
//
MCAN_enableIntr(MCAN0_BASE, MCAN_INTR_SRC_TRANS_COMPLETE, 1U);
//
// Select Interrupt Line.
//
MCAN_selectIntrLine(MCAN0_BASE, MCAN_INTR_SRC_TRANS_COMPLETE, MCAN_INTR_LINE_NUM_1);
//
// Enable Interrupt Line.
//
MCAN_enableIntrLine(MCAN0_BASE, MCAN_INTR_LINE_NUM_1, 1U);
txtest=0;
}
if(txtest==2)
{
MCANConfig();
//
// Write Tx Message to the Message RAM.
//
MCAN_writeMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_BUF, 1U, &txMsg);
//
// Enable Transmission interrupt.
//
MCAN_txBufTransIntrEnable(MCAN0_BASE, 1U,1U);
//
// Add request for transmission.
//
MCAN_txBufAddReq(MCAN0_BASE, 1U);
txtest=0;
}
if(txtest==3)
{
//
// Read Message RAM.
//
MCAN_readMsgRam(MCAN0_BASE, MCAN_MEM_TYPE_BUF, 0U, MCAN_RX_FIFO_NUM_1,
&rxMsg);
//
// Get the New Data Status.
//
MCAN_getNewDataStatus(MCAN0_BASE, &newData);
txtest=0;
}
}
}
//
// 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_BitTimingParams bitTimes;
//
// Initialize MCAN Init parameters.
//
initParams.fdMode = 0x1U; // FD operation enabled.
initParams.brsEnable = 0x1U; // Bit rate switching for
// transmissions enabled.
initParams.txpEnable = 0x0U; // Transmit pause disabled.
initParams.efbi = 0x0U; // Edge filtering disabled.
initParams.pxhddisable = 0x0U; // Protocol exception handling enabled.
initParams.darEnable = 0x0U; // 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 = monEn; // Bus Monitoring Mode is disabled.
configParams.asmEnable = 0x0U; // Normal CAN operation.
configParams.tsPrescalar = 0xFU; // Prescaler Value.
configParams.tsSelect = 0x0U; // 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 = 0U; // No Tx FIFO/Queue.
msgRAMConfigParams.txBufMode = 0U; //Tx FIFO operation
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 = 3U;
// 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 = 3U; // Rx FIFO0 Watermark.
msgRAMConfigParams.rxFIFO0OpMode = 0U; // FIFO blocking mode.
msgRAMConfigParams.rxFIFO1startAddr = MCAN_FIFO_1_START_ADDR;
// Rx FIFO1 Start Address.
msgRAMConfigParams.rxFIFO1size = MCAN_FIFO_1_NUM;
// Number of Rx FIFO elements.
msgRAMConfigParams.rxFIFO1waterMark = 3U; // 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 bit timings.
//
bitTimes.nomRatePrescalar = 0x1FU; // Nominal Baud Rate Pre-scaler.
bitTimes.nomTimeSeg1 = 0x1U; // Nominal Time segment before sample point.
bitTimes.nomTimeSeg2 = 0x1U; // Nominal Time segment after sample point.
bitTimes.nomSynchJumpWidth = 0x0U; // Nominal (Re)Synchronization Jump Width Range.
bitTimes.dataRatePrescalar = 0x3U; // Data Baud Rate Pre-scaler.
bitTimes.dataTimeSeg1 = 0x1U; // Data Time segment before sample point.
bitTimes.dataTimeSeg2 = 0x1U; // 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 be completed.
//
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);
//
// 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);
//
// Enable internal loopback mode
//
MCAN_lpbkModeEnable(MCAN0_BASE, MCAN_LPBK_MODE_EXTERNAL, TRUE);
//
// 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));
}
//
// This function will configure X-BAR for MCAN interrupts.
//
static void MCANIntrConfig(void)
{
Interrupt_initModule();
Interrupt_initVectorTable();
Interrupt_register(INT_MCANSS0,&MCANIntr0ISR);
Interrupt_enable(INT_MCANSS0);
Interrupt_register(INT_MCANSS1,&MCANIntr1ISR);
Interrupt_enable(INT_MCANSS1);
Interrupt_enableMaster();
}
//
// This is Interrupt Service Routine for MCAN interrupt 0.
//
int cnt0isr=0, cnt1isr=0;
__interrupt void MCANIntr0ISR(void)
{
uint32_t intrStatus;
intrStatus = MCAN_getIntrStatus(MCAN0_BASE);
cnt0isr++;
if (MCAN_MSG_INT != intrStatus)
{
error++;
}
//
// Clear the interrupt Status.
//
MCAN_clearIntrStatus(MCAN0_BASE, intrStatus);
//
// Update the flag value.
//
isrIntr0Flag = 0U;
//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}
//
// This is Interrupt Service Routine for MCAN interrupt 1.
//
__interrupt void MCANIntr1ISR(void)
{
uint32_t intrStatus;
intrStatus = MCAN_getIntrStatus(MCAN0_BASE);
cnt1isr++;
if (MCAN_MSG_INT != intrStatus)
{
error++;
}
//
// Clear the interrupt Status.
//
MCAN_clearIntrStatus(MCAN0_BASE, intrStatus);
//
// Update the flag value.
//
isrIntr1Flag = 0U;
//
// Acknowledge this interrupt located in group 9
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}