Other Parts Discussed in Thread: SYSCONFIG
Tool/software:
Hello,
I have a CANalyzer connected to my AM263 Control card CAN port. I have modified the external_mcan_read_write example to:
1) Send a message on a button press
2) poll MCAN for messages if button is not pressed.
The problem is that when I run the debugger, hit a breakpoint in line 237, and send more CAN messages, then resume the code, the MCAN peripheral discards the other messages I transmitted from my CANalyzer.
How do I use the buffer to make sure my other CAN messages are not discarded?
/* * Copyright (C) 2023 Texas Instruments Incorporated * * 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. */ /* This example demonstrates the CAN message communication to external CAN * controller in with the following configuration. * CAN FD Message Format. * Message ID Type is Standard, Msg Id 0xC0. * MCAN is configured in Interrupt Mode. * MCAN Interrupt Line Number 0. * Arbitration Bit Rate 1Mbps. * Data Bit Rate 5Mbps. * Buffer mode is used for Tx and RX to store message in message RAM. * Instance MCAN1 is set as a Commander in Transmit Mode. Message is transmitted and received * back from external CAN controller. Once message is transmitted the example will wait for * recieving the messages from external PC. Have to manually transmit ten messages from external * PC for test to finish. When the received message id and the data matches with the transmitted * one, then the example is completed. */ #include <stdio.h> #include <kernel/dpl/DebugP.h> #include <kernel/dpl/AddrTranslateP.h> #include <kernel/dpl/SemaphoreP.h> #include <drivers/mcan.h> #include "ti_drivers_config.h" #include "ti_drivers_open_close.h" #include "ti_board_open_close.h" #define APP_MCAN_BASE_ADDR (CONFIG_MCAN0_BASE_ADDR) #define APP_MCAN_INTR_NUM (CONFIG_MCAN0_INTR) #define APP_MCAN_MSG_LOOP_COUNT (10U) #define APP_MCAN_LOOPBACK_MODE_DISABLE (FALSE) /* Allocate Message RAM memory section to filter elements, buffers, FIFO */ /* Maximum STD Filter Element can be configured is 128 */ #define APP_MCAN_STD_ID_FILTER_CNT (1U) /* Maximum EXT Filter Element can be configured is 64 */ #define APP_MCAN_EXT_ID_FILTER_CNT (0U) /* Maximum TX Buffer + TX FIFO, combined can be configured is 32 */ #define APP_MCAN_TX_BUFF_CNT (1U) #define APP_MCAN_TX_FIFO_CNT (4U) /* Maximum TX Event FIFO can be configured is 32 */ #define APP_MCAN_TX_EVENT_FIFO_CNT (0U) /* Maximum RX FIFO 0 can be configured is 64 */ #define APP_MCAN_FIFO_0_CNT (60U) /* Maximum RX FIFO 1 can be configured is 64 and * rest of the memory is allocated to RX buffer which is again of max size 64 */ #define APP_MCAN_FIFO_1_CNT (0U) /* Standard Id configured in this app */ #define APP_MCAN_STD_ID (0xC0U) #define APP_MCAN_STD_ID_MASK (0x7FFU) #define APP_MCAN_STD_ID_SHIFT (18U) #define APP_MCAN_EXT_ID_MASK (0x1FFFFFFFU) /* In the CAN FD format, the Data length coding differs from the standard CAN. * In case of standard CAN it is 8 bytes */ static const uint8_t gMcanDataSize[16U] = {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U}; /* Semaphore to indicate transfer completion */ static SemaphoreP_Object gMcanTxDoneSem, gMcanRxDoneSem; static HwiP_Object gMcanHwiObject; static uint32_t gMcanBaseAddr; /* Static Function Declarations */ static void App_mcanIntrISR(void *arg); static void App_mcanConfig(Bool enableInternalLpbk); static void App_mcanInitMsgRamConfigParams( MCAN_MsgRAMConfigParams *msgRAMConfigParams); static void App_mcanEnableIntr(void); static void App_mcanConfigTxMsg(MCAN_TxBufElement *txMsg); static void App_mcanInitStdFilterElemParams( MCAN_StdMsgIDFilterElement *stdFiltElem, uint32_t bufNum); void mcanEnableTransceiver(void); static void GPIO_bankIsrFxn(void *args); uint32_t gGpioBaseAddr = GPIO_PUSH_BUTTON_BASE_ADDR; HwiP_Object gGpioHwiObject; volatile bool gGpioIntrDone = false; void mcan_external_read_write_main(void *args) { int32_t status = SystemP_SUCCESS; HwiP_Params hwiPrms; MCAN_TxBufElement txMsg; MCAN_ProtocolStatus protStatus; MCAN_RxBufElement rxMsg; MCAN_RxNewDataStatus newDataStatus; MCAN_ErrCntStatus errCounter; uint32_t i, bufNum, fifoNum, bitPos = 0U; int32_t retVal; uint32_t pinNum, intrNum, buttonNum; // GPIO STUFF uint32_t waitCount = 5; /* INITIALIZE MCAN */ mcanEnableTransceiver(); DebugP_log("[MCAN] Application started... Please read or write ...\r\n"); /* Construct Tx/Rx Semaphore objects */ status = SemaphoreP_constructBinary(&gMcanTxDoneSem, 0); DebugP_assert(SystemP_SUCCESS == status); status = SemaphoreP_constructBinary(&gMcanRxDoneSem, 0); DebugP_assert(SystemP_SUCCESS == status); /* Register interrupt */ HwiP_Params_init(&hwiPrms); hwiPrms.intNum = APP_MCAN_INTR_NUM; hwiPrms.callback = &App_mcanIntrISR; status = HwiP_construct(&gMcanHwiObject, &hwiPrms); DebugP_assert(status == SystemP_SUCCESS); /* Assign MCAN instance address */ gMcanBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(APP_MCAN_BASE_ADDR); /* Configure MCAN module, Enable External LoopBack Mode */ App_mcanConfig(APP_MCAN_LOOPBACK_MODE_DISABLE); /* Enable Interrupts */ App_mcanEnableIntr(); /* MCAN INITIALIZED */ /* INITIALIZE GPIO */ pinNum = GPIO_PUSH_BUTTON_PIN; intrNum = CSLR_R5FSS0_CORE0_INTR_GPIO_INTRXBAR_OUT_14; buttonNum = 1; /* Address translate */ gGpioBaseAddr = (uint32_t) AddrTranslateP_getLocalAddr(gGpioBaseAddr); /* Register pin interrupt */ HwiP_Params_init(&hwiPrms); hwiPrms.intNum = intrNum; hwiPrms.callback = &GPIO_bankIsrFxn; hwiPrms.args = (void *) pinNum; /* GPIO interrupt is a pulse type interrupt */ hwiPrms.isPulse = TRUE; retVal = HwiP_construct(&gGpioHwiObject, &hwiPrms); DebugP_assert(retVal == SystemP_SUCCESS ); /* GPIO INITIALIZED */ DebugP_log("Starting Test...\n"); DebugP_log("Press SW1 to transmit message. Otherwise, wait for message."); while(1) { if(gGpioIntrDone) { /* Configure Tx Msg to transmit */ App_mcanConfigTxMsg(&txMsg); /* Select buffer number, 32 buffers available */ bufNum = 0U; /* Enable Transmission interrupt for the selected buf num, * If FIFO is used, then need to send FIFO start index until FIFO count */ status = MCAN_txBufTransIntrEnable(gMcanBaseAddr, bufNum, (uint32_t)TRUE); DebugP_assert(status == CSL_PASS); /* Write message to Msg RAM */ MCAN_writeMsgRam(gMcanBaseAddr, MCAN_MEM_TYPE_BUF, bufNum, &txMsg); /* Add request for transmission, This function will trigger transmission */ status = MCAN_txBufAddReq(gMcanBaseAddr, bufNum); DebugP_assert(status == CSL_PASS); /* Wait for Tx completion */ SemaphoreP_pend(&gMcanTxDoneSem, SystemP_WAIT_FOREVER); MCAN_getProtocolStatus(gMcanBaseAddr, &protStatus); /* Checking for Tx Errors */ if (((MCAN_ERR_CODE_NO_ERROR != protStatus.lastErrCode) || (MCAN_ERR_CODE_NO_CHANGE != protStatus.lastErrCode)) && ((MCAN_ERR_CODE_NO_ERROR != protStatus.dlec) || (MCAN_ERR_CODE_NO_CHANGE != protStatus.dlec)) && (0U != protStatus.pxe)) { DebugP_assert(FALSE); } gGpioIntrDone = false; } else { /* Wait for Rx completion */ // SemaphoreP_pend(&gMcanRxDoneSem, 10); /* Checking for Rx Errors */ // MCAN_getErrCounters(gMcanBaseAddr, &errCounter); /*DebugP_assert((0U == errCounter.recErrCnt) && (0U == errCounter.canErrLogCnt));*/ /* Get the new data staus, indicates buffer num which received message */ MCAN_getNewDataStatus(gMcanBaseAddr, &newDataStatus); MCAN_clearNewDataStatus(gMcanBaseAddr, &newDataStatus); /* Select buffer and fifo number, Buffer is used in this app */ bufNum = 0; fifoNum = MCAN_RX_FIFO_NUM_0; bitPos = (1U << bufNum); if (bitPos == (newDataStatus.statusLow & bitPos)) { MCAN_readMsgRam(gMcanBaseAddr, MCAN_MEM_TYPE_BUF, bufNum, fifoNum, &rxMsg); } } //ClockP_usleep(2000); } /* De-Construct Tx/Rx Semaphore objects */ HwiP_destruct(&gMcanHwiObject); SemaphoreP_destruct(&gMcanTxDoneSem); SemaphoreP_destruct(&gMcanRxDoneSem); MCAN_reset(gMcanBaseAddr); DebugP_log("Test Finished"); Board_driversClose(); Drivers_close(); return; } static void GPIO_bankIsrFxn(void *args) { uint32_t pinNum = (uint32_t) args; uint32_t bankNum = GPIO_GET_BANK_INDEX(pinNum); uint32_t intrStatus, pinMask = GPIO_GET_BANK_BIT_MASK(pinNum); /* Get and clear bank interrupt status */ intrStatus = GPIO_getBankIntrStatus(gGpioBaseAddr, bankNum); GPIO_clearBankIntrStatus(gGpioBaseAddr, bankNum, intrStatus); /* Per pin interrupt handling */ if(intrStatus & pinMask) { gGpioIntrDone = true; } } static void App_mcanConfig(Bool enableInternalLpbk) { MCAN_StdMsgIDFilterElement stdFiltElem[APP_MCAN_STD_ID_FILTER_CNT] = {0U}; MCAN_InitParams initParams = {0U}; MCAN_ConfigParams configParams = {0U}; MCAN_MsgRAMConfigParams msgRAMConfigParams = {0U}; MCAN_BitTimingParams bitTimes = {0U}; uint32_t i; /* Initialize MCAN module initParams */ MCAN_initOperModeParams(&initParams); /* CAN FD Mode and Bit Rate Switch Enabled */ initParams.fdMode = TRUE; initParams.brsEnable = TRUE; /* Initialize MCAN module Global Filter Params */ MCAN_initGlobalFilterConfigParams(&configParams); /* Initialize MCAN module Bit Time Params */ /* Configuring default 1Mbps and 5Mbps as nominal and data bit-rate resp */ MCAN_initSetBitTimeParams(&bitTimes); /* Initialize MCAN module Message Ram Params */ App_mcanInitMsgRamConfigParams(&msgRAMConfigParams); /* Initialize Filter element to receive msg, should be same as tx msg id */ for (i = 0U; i < APP_MCAN_STD_ID_FILTER_CNT; i++) { App_mcanInitStdFilterElemParams(&stdFiltElem[i], i); } /* wait for memory initialization to happen */ while (FALSE == MCAN_isMemInitDone(gMcanBaseAddr)) {} /* Put MCAN in SW initialization mode */ MCAN_setOpMode(gMcanBaseAddr, MCAN_OPERATION_MODE_SW_INIT); while (MCAN_OPERATION_MODE_SW_INIT != MCAN_getOpMode(gMcanBaseAddr)) {} /* Initialize MCAN module */ MCAN_init(gMcanBaseAddr, &initParams); /* Configure MCAN module Gloabal Filter */ MCAN_config(gMcanBaseAddr, &configParams); /* Configure Bit timings */ MCAN_setBitTime(gMcanBaseAddr, &bitTimes); /* Configure Message RAM Sections */ MCAN_msgRAMConfig(gMcanBaseAddr, &msgRAMConfigParams); /* Set Extended ID Mask */ MCAN_setExtIDAndMask(gMcanBaseAddr, APP_MCAN_EXT_ID_MASK); /* Configure Standard ID filter element */ for (i = 0U; i < APP_MCAN_STD_ID_FILTER_CNT; i++) { MCAN_addStdMsgIDFilter(gMcanBaseAddr, i, &stdFiltElem[i]); } if (TRUE == enableInternalLpbk) { MCAN_lpbkModeEnable(gMcanBaseAddr, MCAN_LPBK_MODE_INTERNAL, TRUE); } /* Take MCAN out of the SW initialization mode */ MCAN_setOpMode(gMcanBaseAddr, MCAN_OPERATION_MODE_NORMAL); while (MCAN_OPERATION_MODE_NORMAL != MCAN_getOpMode(gMcanBaseAddr)) {} return; } static void App_mcanConfigTxMsg(MCAN_TxBufElement *txMsg) { uint32_t i; /* Initialize message to transmit */ MCAN_initTxBufElement(txMsg); /* Standard message identifier 11 bit, stored into ID[28-18] */ txMsg->id = ((APP_MCAN_STD_ID & MCAN_STD_ID_MASK) << MCAN_STD_ID_SHIFT); txMsg->dlc = MCAN_DATA_SIZE_2BYTES; /* Payload size is 64 bytes */ txMsg->fdf = TRUE; /* CAN FD Frame Format */ txMsg->xtd = FALSE; /* Extended id not configured */ txMsg->data[0] = 0b11001100; txMsg->data[1] = 0b00000111; return; } static void App_mcanInitStdFilterElemParams(MCAN_StdMsgIDFilterElement *stdFiltElem, uint32_t bufNum) { /* sfid1 defines the ID of the standard message to be stored. */ stdFiltElem->sfid1 = APP_MCAN_STD_ID; /* As buffer mode is selected, sfid2 should be bufNum[0 - 63] */ stdFiltElem->sfid2 = bufNum; /* Store message in buffer */ stdFiltElem->sfec = MCAN_STD_FILT_ELEM_BUFFER; /* Below configuration is ignored if message is stored in buffer */ stdFiltElem->sft = MCAN_STD_FILT_TYPE_RANGE; return; } static void App_mcanInitMsgRamConfigParams(MCAN_MsgRAMConfigParams *msgRAMConfigParams) { int32_t status; MCAN_initMsgRamConfigParams(msgRAMConfigParams); /* Configure the user required msg ram params */ msgRAMConfigParams->lss = APP_MCAN_STD_ID_FILTER_CNT; msgRAMConfigParams->lse = APP_MCAN_EXT_ID_FILTER_CNT; msgRAMConfigParams->txBufCnt = APP_MCAN_TX_BUFF_CNT; msgRAMConfigParams->txFIFOCnt = APP_MCAN_TX_FIFO_CNT; /* Buffer/FIFO mode is selected */ msgRAMConfigParams->txBufMode = MCAN_TX_MEM_TYPE_BUF; msgRAMConfigParams->txEventFIFOCnt = APP_MCAN_TX_EVENT_FIFO_CNT; msgRAMConfigParams->rxFIFO0Cnt = APP_MCAN_FIFO_0_CNT; msgRAMConfigParams->rxFIFO1Cnt = APP_MCAN_FIFO_1_CNT; /* FIFO blocking mode is selected */ msgRAMConfigParams->rxFIFO0OpMode = MCAN_RX_FIFO_OPERATION_MODE_BLOCKING; msgRAMConfigParams->rxFIFO1OpMode = MCAN_RX_FIFO_OPERATION_MODE_BLOCKING; status = MCAN_calcMsgRamParamsStartAddr(msgRAMConfigParams); DebugP_assert(status == CSL_PASS); return; } static void App_mcanEnableIntr(void) { MCAN_enableIntr(gMcanBaseAddr, MCAN_INTR_MASK_ALL, (uint32_t)TRUE); MCAN_enableIntr(gMcanBaseAddr, MCAN_INTR_SRC_RES_ADDR_ACCESS, (uint32_t)FALSE); /* Select Interrupt Line 0 */ MCAN_selectIntrLine(gMcanBaseAddr, MCAN_INTR_MASK_ALL, MCAN_INTR_LINE_NUM_0); /* Enable Interrupt Line */ MCAN_enableIntrLine(gMcanBaseAddr, MCAN_INTR_LINE_NUM_0, (uint32_t)TRUE); return; } static void App_mcanIntrISR(void *arg) { uint32_t intrStatus; intrStatus = MCAN_getIntrStatus(gMcanBaseAddr); MCAN_clearIntrStatus(gMcanBaseAddr, intrStatus); if (MCAN_INTR_SRC_TRANS_COMPLETE == (intrStatus & MCAN_INTR_SRC_TRANS_COMPLETE)) { SemaphoreP_post(&gMcanTxDoneSem); } /* If FIFO0/FIFO1 is used, then MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG macro * needs to be replaced by MCAN_INTR_SRC_RX_FIFO0_NEW_MSG/ * MCAN_INTR_SRC_RX_FIFO1_NEW_MSG respectively */ if (MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG == (intrStatus & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG)) { SemaphoreP_post(&gMcanRxDoneSem); } return; }
Thanks,
David Martinez