This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

IWRL6432BOOST: SBL Via CAN

Part Number: IWRL6432BOOST
Other Parts Discussed in Thread: IWRL6432

Hello,

     I'm trying to Integrate CAN for SBL available at C:\ti\MMWAVE_L_SDK_05_03_00_02\examples\drivers\boot\sbl for IWRL6432Boost. I was able to successfully integrate Mcan and initialize. However i want to download the app_image via CAN now. I did not find any helpfull document for developing this. I referred CAN_SBL_18xx example code. However api looks quite different for 18xx and 64xx. They have implemented a callback for data gathering from CAN interface. But in iwrl6432 i'm not sure how to implement something similar. Do i have any inputs or suggestions to go forward. Thanks 

  • Hey Madhusudhan,

    I would recommend looking at the SBL_CAN_RECV case in the SBL_transportDownloadFile function in transport.c in the CAN SBL example and implementing a similar case in the same function in the SDK 5 SBL example. This case downloads an application image over CAN to FLASH using QSPI. Do note that you may have to adjust the syntax of some functions to fit SDK 5 functions, and you might want to add your CAN initializations in the transport.c file as well unless you need to utilize CAN earlier.

    Hopefully this gives you a good starting point, but let me know if you have any other questions.

    Regards,

    Kristien

  • Hello Kristien,

       Thanks for your information. I was trying the similar idea you have mentioned. However, on SBL_CAN_RECV we are gathering data via static void sblDataCallback. I believe as api is quite different in 64xx. idk how to perform the callback operations. This is where i'm currently trying to download the file via CAN. Untill the point you have explained to check the SBL_CAN_Recv method i was able to understand. From here now idk how to start the callback function in the sdk_5 for iwrl6432. Can you give some information related to call back function i,e. while (gPktsWrt == gRxPkts) during this while loop running there's data incoming and via CAN interface and sbl_callback method is working in 18xx. similar i'm unclear about how to initiate the same for 64xx. As we have quite different methods in mcan api. 

  • Hello Kristien,

           I'm referring to Mcan_external_read_write demo example for CAN tx and rx. Here when ever the CAN message is received. this App_mcanIntrISR method is being invoked. However only if i transmit data with "192" message ID i'm able to receive and print the message information. However when i try to send message with other ID's i'm able to transmit from Pcan View virtual env and no error while transmitting however i don't receive due to if (MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG == (intrStatus & MCAN_INTR_SRC_DEDICATED_RX_BUFF_MSG)) this conditon. As APP_MCAN_STD_ID  is defined as identifies 120. if i want to send with different ID and receive that message and able to print it how can i do it. I'm bit confused about this. Can you please explain me how it works. Thanks 

  • Hey Madhusudhan,

    For the callback, one way to implement a similar functionality as the 18xx CAN SBL is to take the App_mcanIntrISR and create sub-ISRs for Rx and Tx that replicate the error checks done. In the case of the Rx ISR, you would also receive the message into a buffer - or FIFO if you choose - and use that in the SBL_CAN_RECV statement. I wrote up a rough outline of how I would implement something like this in the attachment below, but please note that I have not tested this, and you should review this to understand the general process - see the comments labeled "NOTE" in the file for potential unresolved areas. 

    As for the ID, I'm a bit confused about what is received and what is filtered. It sounds like you are able to receive a message with ID 192 (0xC0) and cannot receive ID 120 (0x78) on the IWRL6432 which is expected for the MCAN external R/W demo since the APP_MCAN_STD_ID = 0xC0. If this is a general filtering issue, I would recommend reviewing this previous E2E I answered which discusses some considerations for filtering and some resources.

    Let me know if you have any other questions.

    Regards,

    Kristien

    low_power_SBL_outline.txt
    MCAN_RxBufElement       rxMsg;
    volatile uint32_t gRxPkts = 0;
    
    static void App_mcanIntrISR(void *arg)
    {
        uint32_t intrStatus;
    
        intrStatus = MCAN_getIntrStatus(gMcanBaseAddr);
        MCAN_clearIntrStatus(gMcanBaseAddr, intrStatus);
    
        /* Could remove Tx sub-ISR function */
        if (MCAN_INTR_SRC_TRANS_COMPLETE ==
            (intrStatus & MCAN_INTR_SRC_TRANS_COMPLETE))
        {
            App_mcanIntrISRTx();
            /* Could be posted at end of sub-ISR callback */
            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))
        {
            App_mcanIntrISRRx();
            /* Could be posted at end of sub-ISR callback */
            SemaphoreP_post(&gMcanRxDoneSem);
        }
    
        return;
    }
    
    static void App_mcanIntrISRTx(void)
    {
        MCAN_ProtocolStatus     protStatus;
    
        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);
        }
    
        return;
    }
    
    static void App_mcanIntrISRRx(void)
    {
        MCAN_ErrCntStatus       errCounter;
        MCAN_RxNewDataStatus    newDataStatus;
        uint32_t                bufNum, fifoNum;
    
        /* 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 example */
        bufNum = 0U;
        fifoNum = MCAN_RX_FIFO_NUM_0;
    
        /* NOTE: Determine buffer offset if needed using received packets and number of packets in buffer */
        bitPos = (1U << bufNum);
        if (bitPos == (newDataStatus.statusLow & bitPos))
        {
            /* NOTE: Offset read address if needed */
            MCAN_readMsgRam(gMcanBaseAddr, MCAN_MEM_TYPE_BUF, bufNum, fifoNum, &rxMsg);
        }
        else
        {
            DebugP_assert(FALSE);
        }
        /* Message ID for terminate message? */
        if (id == SBL_CANFD_TERMINATE_MSG_ID)
        {
            gLastMsgFlag = 1;
        }
    
        return;
    }
    
    case SBL_CAN_RECV:
    {
        uint32_t buffOffset = 0;
        uint32_t totDataLen = 0;
        while (1)
        {
            /* Wait till a new data packet is received. */
            /* NOTE: The gRxPkts can be replaced with this semaphore pend instead - though the original conditional would work too */
            SemaphoreP_pend(&gMcanRxDoneSem);
            /* Check if the terminate Message Id is received? */
            if (gLastMsgFlag != 0)
            {
                break;
            }
            buffOffset = (gPktsWrt % NUM_PKT_IN_BUFF);
            /* NOTE: Adjust flash write function to write proper size */
            Flash_write(qspiFlashHandle, flashAddr, (uint8_t *)&rxMsg.data[buffOffset * 64], 64);
            /* Increment the Flash pointer. */
            flashAddr += 64;
            /* Increment the number of packets written. */
            /* NOTE: This does not needed to be used but I left it here in case you want to use it for something else*/
            gPktsWrt++;
            totDataLen += 64;
        }
        dataLength = totDataLen;
        goto exitGetFile;
    }

  • Hello, 

     Thanks for the information.  When I was reading the mcan document from sdk_5_03_00_02. I came across filtering acceptance topic. Where they have mentioned user can accept any can id's instead by making modifications in filter configurations. Currently according to the default settings for mcan_external_read_write demo. Filters are configured to receive only CAN ID I.E. 192. if I want to modify to accept any can Id. Do you have any information regarding to it. To modify the filter configuration to accept any incoming can id's. Thanks 

  • Hey Madhusudhan,

    As shown in the figure below, the GFC.ANFS bitfield needs to be set to 0 to accept non-matching frames which can be done by changing configParams->filterConfig.anfs to zero after its been configured by MCAN_initGlobalFilterConfigParams. If using extended message ID filtering, then configParams->filterConfig.anfe will need to be set to zero as well. Note: The MCAN_initGlobalFilterConfigParams function only sets up the MCAN_ConfigParams struct and does not write into the GFC register of the device. The MCAN_config function takes a MCAN_ConfigParams struct and writes those values into the GFC register.

    Regards,

    Kristien