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.

AM2432: Cant establish communication between two drives

Part Number: AM2432
Other Parts Discussed in Thread: TCA6424

Tool/software:

Hi

Im trying to make two drives to communicate with no success.

I used the loopback examples as refference and made one drive to try and send data and the othe drive to recive.

I tried to do so withe both with interrupts and polling way, it looks like i am able to send the data but in no way i got indication to reciving data.

Your guidance will be much appreciated.

  • Hi,

    What "drive" is this? Which AM2432 interface is the "drive" attached to? Which "loopback example" do you use? Please provide the path to the SDK.

  • Sorry, I forgot to mention I'm using the FSI interface.

    The drive is a product of ours, a motor drive.

    The SDK I'm using is as follows:

    https://www.ti.com/tool/download/MCU-PLUS-SDK-AM243X/09.00.00.35

    I'm using the fsi_loopback_interrupt and fsi_loopback_polling examples as references.

    I wrote two modules: one to be the "lead" device, which will start the communication, and a "node" device to receive the request.

  • Hi Sahar,

    Thanks for the details. I am routing your query to our MCU expert for comments.

  • Hi Sahar, few questions below

    1) Are OOB demos running (fsi_loopback_interrupt and fsi_loopback_polling examples) running OK to you in both boards (drives)?

    2) Are you testing on a custom board or in one of our boards? if one or ours which one? LP? EVM?

       2.1) How is your setup? Can you trace (scope) FSI TX from sender/lead? If so, is this signal received OK on the other drive/node?

       2.2) Do you have other known-working FSI drives to test your new drives?

    3) Which modifications did you do on top of MCS-SDK FSI examples? can you share an example code?

    thank you,

    Paula

  • Hi

    1. yes, the loopback examples are running fine on each board.

    2.im testing on 2 EVM's

    i can share a part of the modules where i try to make a handshake sequence.

    im not getting any response from the node and when measuring with scope i dont see any signal from TX0_CLK or TX0_D0

    attached the code for the lead module and the node module

    /*
     *  Copyright (C) 2021 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.
     */
    
    #include <string.h>
    #include <stdint.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/HwiP.h>
    #include <drivers/fsi.h>
    #include <drivers/pinmux.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    /*
     * This example performs FSI TX to FSI RX internal loopback in polled mode.
     * The application configures an instance of FSI TX and FSI RX module with below configuration
     *
     * - Single lane
     * - TX clock at 50 MHz
     * - 16 words per frame (transfer)
     *
     * With above configuration, the application transfers 100 frames of data from FSI TX,
     * waits for data to be received by FSI RX and then compares the data.
     *
     * Once the transfer it completes, it compares the source and destination buffers for any data mismatch.
     */
    
    /* FSI TXCLK - 50 MHz */
    #define FSI_APP_TXCLK_FREQ              (50 * 1000 * 1000)
    /* FSI module input clock - 500 MHz */
    #define FSI_APP_CLK_FREQ                (CONFIG_FSI_TX0_CLK)
    /* FSI TX prescaler value for TXCLKIN of 100 MHz. / 2 is provided as TXCLK = TXCLKIN/2 */
    #define FSI_APP_TX_PRESCALER_VAL        (FSI_APP_CLK_FREQ / FSI_APP_TXCLK_FREQ / 2U)
    
    #define FSI_APP_LOOP_COUNT              (100U)
    /* User data to be sent with Data frame */
    #define FSI_APP_TX_USER_DATA            (0x07U)
    /* Configuring Frame - can be between 1-16U */
    #define FSI_APP_FRAME_DATA_WORD_SIZE    (16U)
    /* 0x0U for 1 lane and 0x1U for two lane */
    #define FSI_APP_N_LANES                 (0x0U)
    #define FSI_APP_TX_DATA_FRAME_TAG       (0x1U)
    
    #define RX_TIME_OUT_CNTR    0x1000000
    
    /* Global variables */
    uint32_t rxBaseAddr = CONFIG_FSI_RX0_BASE_ADDR;
    uint32_t txBaseAddr = CONFIG_FSI_TX0_BASE_ADDR;
    uint32_t txTimeOutCntr = 0x100000, rxTimeOutCntr = 0x100000;
    uint32_t error = 0;
    uint16_t txEventSts = 0, rxEventSts = 0;
    
    HwiP_Object gFsiTxHwiObject, gFsiRxHwiObject;
    volatile uint32_t fsiTxInt1Received = 0, fsiRxInt1Received = 0;
    uint32_t dataFrameCntr = 0, dataFrameCntr_ui32 = 0;
    
    // Frame tag used with Data/Ping transfers
    FSI_FrameTag txDataFrameTag = FSI_FRAME_TAG10, txPingFrameTag = FSI_FRAME_TAG15;
    
    // User data to be sent with Data frame(for CPU control)
    uint16_t txUserData = 0x47;
    
    // Number of words per transfer may be from 1 -16
    uint16_t nWords = 8;
    
    /* Index of FSI TX/RX buffer, gBudIdx + FSI_APP_FRAME_DATA_WORD_SIZE should be <= 16 */
    uint32_t txBufAddr = 0;
    uint32_t rxBufAddr = 0;
    uint16_t gRxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    uint16_t gTxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr);
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr);
    void checkReceivedFrameTypeTag(FSI_FrameType type, FSI_FrameTag tag);
    void compare16(uint16_t val1, uint16_t val2);
    void compareBufData(uint16_t txBufIndex, uint16_t rxBufIndex, uint16_t nWords);
    static void Fsi_appIntrDeInit(uint32_t txBaseAddr, uint32_t rxBaseAddr);
    static int32_t Fsi_appIntrInit(uint32_t txBaseAddr, uint32_t rxBaseAddr);
    static void Fsi_appRxCallback(void *args);
    static void Fsi_appTxCallback(void *args);
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr);
    
    void *fsi_loopback_main(void *args)
    {
    
        int32_t     status = SystemP_SUCCESS;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        DebugP_log("[FSI] FSI Node application waiting ...\r\n");
    
        /* Wait for trigger from user */
        char dummy;
        uint32_t i32_uart_base_adr= UART_getBaseAddr(gUartHandle[0]);
        while ( !UART_getChar(i32_uart_base_adr, &dummy) );
    
        DebugP_log("[FSI] FSI Node application started ...\r\n");
    
        status += Fsi_appIntrInit(txBaseAddr, rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Disable loopback */
        status = FSI_disableRxInternalLoopback(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Enable RX frame done interrupt */
        status += FSI_enableRxInterrupt(rxBaseAddr, FSI_INT1, FSI_RX_EVT_PING_FRAME);
        DebugP_assert(status == SystemP_SUCCESS);
    
        FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        FSI_performRxInitialization(rxBaseAddr);
        status += FSI_getTxBufferAddress(txBaseAddr, &txBufAddr);
        status += FSI_getRxBufferAddress(rxBaseAddr, &rxBufAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        while(1)
        {
            while(fsiRxInt1Received != 1);
            compare16(rxEventSts, (FSI_RX_EVT_PING_FRAME | FSI_RX_EVT_FRAME_DONE));
            checkReceivedFrameTypeTag(FSI_FRAME_TYPE_PING, FSI_FRAME_TAG0);
            //
            // If received frame type and tag matches, exit this loop and proceed to
            // next step by sending flush sequence, otherwise clear error and
            // interrupt flag and continue looping.
            //
            if(error == 0)
            {
                fsiRxInt1Received = 0;
                break;
            }
    
            fsiRxInt1Received = 0;
            error = 0;
        }
    
        while(1)
        {
            //
            // Send the flush sequence
            //
            FSI_executeTxFlushSequence(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
    
            //
            // Send a ping frame with frame tag 0000b
            //
            FSI_setTxFrameTag(txBaseAddr, FSI_FRAME_TAG0);
            FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_PING);
            FSI_startTxTransmit(txBaseAddr);
    
            while(fsiRxInt1Received != 1U && rxTimeOutCntr != 0U)
            {
                ClockP_usleep(1);
                rxTimeOutCntr--;
            }
    
            if(rxTimeOutCntr == 0)
            {
                rxTimeOutCntr = RX_TIME_OUT_CNTR;
                continue;
            }
            else
            {
                compare16(rxEventSts, (FSI_RX_EVT_PING_FRAME | FSI_RX_EVT_FRAME_DONE));
                checkReceivedFrameTypeTag(FSI_FRAME_TYPE_PING, FSI_FRAME_TAG1);
                //
                // If received frame type and tag matches, exit this loop and proceed
                // to next step by sending flush sequence, otherwise clear error and
                // interrupt flag and continue looping.
                //
                if(error == 0)
                {
                    fsiRxInt1Received = 0;
                    break;
                }
    
                fsiRxInt1Received = 0;
                error = 0;
            }
        }
        // Send a ping frame with frame tag 0001b
        //
        FSI_setTxFrameTag(txBaseAddr, FSI_FRAME_TAG1);
        FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_PING);
        FSI_startTxTransmit(txBaseAddr);
        ClockP_usleep(10);
    
        DebugP_log("Handshake Success ...\r\n");
    
        Board_driversClose();
        Drivers_close();
    
        return NULL;
    }
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr)
    {
        int32_t     status;
    
        /* TX init and reset */
        status = FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        status += FSI_resetTxModule(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
        FSI_clearTxModuleReset(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setTxSoftwareFrameSize(txBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setTxDataWidth(txBaseAddr, FSI_APP_N_LANES);
    
        /* Setting frame config */
        status += FSI_setTxUserDefinedData(txBaseAddr, FSI_APP_TX_USER_DATA);
        status += FSI_setTxFrameTag(txBaseAddr, FSI_APP_TX_DATA_FRAME_TAG);
        status += FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_PING);
    
        return status;
    }
    
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr)
    {
        int32_t     status;
    
        /* RX init and reset */
        status  = FSI_performRxInitialization(rxBaseAddr);
        status += FSI_resetRxModule(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
        FSI_clearRxModuleReset(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setRxSoftwareFrameSize(rxBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setRxDataWidth(rxBaseAddr, FSI_APP_N_LANES);
        status += FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        return status;
    }
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr)
    {
        int32_t     status = SystemP_SUCCESS;
        uint32_t    i;
    
        for(i = 0; i < FSI_APP_FRAME_DATA_WORD_SIZE; i++)
        {
            if(*rxBufPtr++ != *txBufPtr++)
            {
                status = SystemP_FAILURE;
                break;
            }
        }
    
        return status;
    }
    
    //
    // compare16 - Compares two 16 bit values and increments global error flag by 1
    //             for mismatch
    //
    void compare16(uint16_t val1, uint16_t val2)
    {
        if(val1 != val2)
        {
            error++;
        }
    }
    
    //
    // checkReceivedFrameTypeTag - Checks received frame type/tag and updates global
    //                             error flag
    //
    void checkReceivedFrameTypeTag(FSI_FrameType type, FSI_FrameTag tag)
    {
        uint16_t frame_tag;
        FSI_getRxPingTag(rxBaseAddr, &frame_tag);
    
        compare16(frame_tag, (uint16_t)type);
    
        if(type == FSI_FRAME_TYPE_PING)
        {
            compare16(frame_tag, (uint16_t)tag);
        }
        else
        {
            compare16(frame_tag, (uint16_t)tag);
        }
    }
    static void Fsi_appTxCallback(void *args)
    {
    
        uint32_t txBaseAddr = (uint32_t) args;
    
        fsiTxInt1Received = 1U;
        FSI_getTxEventStatus(txBaseAddr, &txEventSts);
    
        // Set FSI TX buffer pointer to beginning
        FSI_setTxBufferPtr(txBaseAddr, 0U);
    
        FSI_clearTxEvents(txBaseAddr, FSI_TX_EVTMASK);
    
        /*
        ** Handle tx callback function here
        */
        return;
    }
    
    static void Fsi_appRxCallback(void *args)
    {
        uint32_t rxBaseAddr = (uint32_t) args;
        uint16_t u16_user_data, u16_farame_tag;
    
        FSI_getRxEventStatus(rxBaseAddr, &rxEventSts);
    
        if((rxEventSts & FSI_RX_EVT_DATA_FRAME) != 0)
       {
            dataFrameCntr++;
    
            if(dataFrameCntr >= 0xFFFFFFFF)
            {
                dataFrameCntr_ui32++;
                dataFrameCntr = 0;
            }
    
            //
            // Move received User Data, Frame Tag, and Data to TX buffer/registers
            //
            FSI_getRxUserDefinedData(rxBaseAddr, &u16_user_data);
            FSI_setTxUserDefinedData(txBaseAddr, u16_user_data);
            FSI_getRxFrameTag(rxBaseAddr, &u16_farame_tag);
            FSI_setTxFrameTag(txBaseAddr, u16_farame_tag);
    
            FSI_writeTxBuffer(txBaseAddr, (uint16_t *)rxBufAddr, nWords, 0U); // Put read data into TX buffer
            FSI_startTxTransmit(txBaseAddr);
       }
        fsiRxInt1Received = 1U;
    
        // Set FSI RX buffer pointer to beginning
        FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        //
        // Clear the interrupt flag and issue ACK
        //
        FSI_clearRxEvents(rxBaseAddr,rxEventSts);
    
        /*
        ** Handle rx callback function here
        */
        return;
    }
    
    static int32_t Fsi_appIntrInit(uint32_t txBaseAddr, uint32_t rxBaseAddr)
    {
        int32_t     status;
        uint32_t    txIntrNum, rxIntrNum;
        HwiP_Params txHwiPrms, rxHwiPrms;
    
        /*
         * TX interrupt config and registration
         */
        txIntrNum = CONFIG_FSI_TX0_INTR1;
        HwiP_Params_init(&txHwiPrms);
        txHwiPrms.intNum = txIntrNum;
        txHwiPrms.callback = Fsi_appTxCallback;
        txHwiPrms.args = (void *) txBaseAddr;
        status = HwiP_construct(&gFsiTxHwiObject, &txHwiPrms);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /*
         * RX interrupt config and registration
         */
        rxIntrNum = CONFIG_FSI_RX0_INTR1;
        HwiP_Params_init(&rxHwiPrms);
        rxHwiPrms.intNum = rxIntrNum;
        rxHwiPrms.callback = Fsi_appRxCallback;
        rxHwiPrms.args = (void *) rxBaseAddr;
        status =  HwiP_construct(&gFsiRxHwiObject, &rxHwiPrms);
        DebugP_assert(status == SystemP_SUCCESS);
    
        return status;
    }
    
    static void Fsi_appIntrDeInit(uint32_t txBaseAddr, uint32_t rxBaseAddr)
    {
        /* TX interrupt deinit */
        FSI_disableTxInterrupt(txBaseAddr, FSI_INT1, FSI_TX_EVTMASK);
        FSI_clearTxEvents(txBaseAddr, FSI_TX_EVTMASK);
        HwiP_destruct(&gFsiTxHwiObject);
    
        /* RX interrupt deinit */
        FSI_disableRxInterrupt(rxBaseAddr, FSI_INT1, FSI_TX_EVTMASK);
        FSI_clearRxEvents(rxBaseAddr, FSI_RX_EVTMASK);
        HwiP_destruct(&gFsiRxHwiObject);
        return;
    }
    
    /*
     *  Copyright (C) 2021 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.
     */
    
    #include <string.h>
    #include <stdint.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/HwiP.h>
    #include <drivers/fsi.h>
    #include <drivers/pinmux.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    /*
     * This example performs FSI TX to FSI RX internal loopback in polled mode.
     * The application configures an instance of FSI TX and FSI RX module with below configuration
     *
     * - Single lane
     * - TX clock at 50 MHz
     * - 16 words per frame (transfer)
     *
     * With above configuration, the application transfers 100 frames of data from FSI TX,
     * waits for data to be received by FSI RX and then compares the data.
     *
     * Once the transfer it completes, it compares the source and destination buffers for any data mismatch.
     */
    
    /* FSI TXCLK - 50 MHz */
    #define FSI_APP_TXCLK_FREQ              (50 * 1000 * 1000)
    /* FSI module input clock - 500 MHz */
    #define FSI_APP_CLK_FREQ                (CONFIG_FSI_TX0_CLK)
    /* FSI TX prescaler value for TXCLKIN of 100 MHz. / 2 is provided as TXCLK = TXCLKIN/2 */
    #define FSI_APP_TX_PRESCALER_VAL        (FSI_APP_CLK_FREQ / FSI_APP_TXCLK_FREQ / 2U)
    
    #define FSI_APP_LOOP_COUNT              (100U)
    /* User data to be sent with Data frame */
    #define FSI_APP_TX_USER_DATA            (0x07U)
    /* Configuring Frame - can be between 1-16U */
    #define FSI_APP_FRAME_DATA_WORD_SIZE    (16U)
    /* 0x0U for 1 lane and 0x1U for two lane */
    #define FSI_APP_N_LANES                 (0x0U)
    #define FSI_APP_TX_DATA_FRAME_TAG       (0x1U)
    
    /* Global variables */
    uint32_t rxBaseAddr = CONFIG_FSI_RX0_BASE_ADDR;
    uint32_t txBaseAddr = CONFIG_FSI_TX0_BASE_ADDR;
    uint32_t txTimeOutCntr = 0x100000, rxTimeOutCntr = 0x100000;
    uint32_t error = 0;
    uint16_t txEventSts = 0, rxEventSts = 0;
    
    HwiP_Object gFsiTxHwiObject, gFsiRxHwiObject;
    volatile uint32_t fsiTxInt1Received = 0, fsiRxInt1Received = 0;
    uint32_t dataFrameCntr = 0, dataFrameCntr_ui32 = 0;
    
    // Frame tag used with Data/Ping transfers
    FSI_FrameTag txDataFrameTag = FSI_FRAME_TAG10, txPingFrameTag = FSI_FRAME_TAG15;
    
    // User data to be sent with Data frame(for CPU control)
    uint16_t txUserData = 0x47;
    
    // Number of words per transfer may be from 1 -16
    uint16_t nWords = 8;
    
    /* Index of FSI TX/RX buffer, gBudIdx + FSI_APP_FRAME_DATA_WORD_SIZE should be <= 16 */
    uint32_t txBufAddr = 0;
    uint32_t rxBufAddr = 0;
    uint16_t gRxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    uint16_t gTxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    
    HwiP_Object gFsiTxHwiObject, gFsiRxHwiObject;
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr);
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr);
    void checkReceivedFrameTypeTag(FSI_FrameType type, FSI_FrameTag tag);
    void compare16(uint16_t val1, uint16_t val2);
    void compareBufData(uint16_t txBufIndex, uint16_t rxBufIndex, uint16_t nWords);
    static void Fsi_appIntrDeInit(uint32_t txBaseAddr, uint32_t rxBaseAddr);
    static int32_t Fsi_appIntrInit(uint32_t txBaseAddr, uint32_t rxBaseAddr);
    static void Fsi_appRxCallback(void *args);
    static void Fsi_appTxCallback(void *args);
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr);
    
    void *fsi_loopback_main(void *args)
    {
    
        int32_t     status = SystemP_SUCCESS;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        DebugP_log("[FSI] FSI Lead application waiting ...\r\n");
    
        /* Wait for trigger from user */
        char dummy;
        uint32_t i32_uart_base_adr= UART_getBaseAddr(gUartHandle[0]);
        while ( !UART_getChar(i32_uart_base_adr, &dummy) );
    
        DebugP_log("[FSI] FSI Lead application started ...\r\n");
    
        status += Fsi_appIntrInit(txBaseAddr, rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Disable loopback */
        status = FSI_disableRxInternalLoopback(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Enable RX frame done interrupt */
        status += FSI_enableRxInterrupt(rxBaseAddr, FSI_INT1, FSI_RX_EVT_PING_FRAME);
        DebugP_assert(status == SystemP_SUCCESS);
    
        FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        FSI_performRxInitialization(rxBaseAddr);
        status += FSI_getTxBufferAddress(txBaseAddr, &txBufAddr);
        status += FSI_getRxBufferAddress(rxBaseAddr, &rxBufAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        while(1)
        {
            /* Send Flush Sequence to sync, after every rx soft reset */
            status = FSI_executeTxFlushSequence(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
            DebugP_assert(status == SystemP_SUCCESS);
    
            //
            // Send a ping frame with frame tag 0000b
            //
            FSI_setTxFrameTag(txBaseAddr, FSI_FRAME_TAG0);
            FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_PING);
            FSI_startTxTransmit(txBaseAddr);
    
            while(fsiRxInt1Received != 1U && rxTimeOutCntr != 0U)
            {
                ClockP_usleep(1);
                rxTimeOutCntr--;
            }
    
            if(rxTimeOutCntr == 0)
            {
                rxTimeOutCntr = 0x100000;
                continue;
            }
            else
            {
                compare16(rxEventSts, (FSI_RX_EVT_PING_FRAME | FSI_RX_EVT_FRAME_DONE));
                checkReceivedFrameTypeTag(FSI_FRAME_TYPE_PING, FSI_FRAME_TAG0);
    
                //
                // If received frame type and tag matches, exit this loop and proceed
                // to next step by sending flush sequence, otherwise clear error and
                // interrupt flag and continue looping.
                //
                if(error == 0)
                {
                    fsiRxInt1Received = 0;
                    break;
                }
    
                fsiRxInt1Received = 0;
                error = 0;
            }
        }
        while(1)
        {
            //
            // Send a ping frame with frame tag 0001b
            //
            FSI_setTxFrameTag(txBaseAddr, FSI_FRAME_TAG1);
            FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_PING);
            FSI_startTxTransmit(txBaseAddr);
    
            while(fsiRxInt1Received != 1U && rxTimeOutCntr != 0U)
             {
                ClockP_usleep(1);
                rxTimeOutCntr--;
             }
    
             if(rxTimeOutCntr == 0)
             {
                 rxTimeOutCntr = 0x100000;
                 continue;
             }
             else
             {
                 compare16(rxEventSts, (FSI_RX_EVT_PING_FRAME | FSI_RX_EVT_FRAME_DONE));
                 checkReceivedFrameTypeTag(FSI_FRAME_TYPE_PING, FSI_FRAME_TAG1);
    
                 //
                 // If received frame type and tag matches, exit this loop and proceed
                 // to next step by sending flush sequence, otherwise clear error and
                 // interrupt flag and continue looping.
                 //
                 if(error == 0)
                 {
                     fsiRxInt1Received = 0;
                     break;
                 }
    
                 fsiRxInt1Received = 0;
                 error = 0;
             }
        }
        DebugP_log("Handshake Success ...\r\n");
    
        Board_driversClose();
        Drivers_close();
    
        return NULL;
    }
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr)
    {
        int32_t     status;
    
        /* TX init and reset */
        status = FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        status += FSI_resetTxModule(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
        FSI_clearTxModuleReset(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setTxSoftwareFrameSize(txBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setTxDataWidth(txBaseAddr, FSI_APP_N_LANES);
    
        /* Setting frame config */
        status += FSI_setTxUserDefinedData(txBaseAddr, FSI_APP_TX_USER_DATA);
        status += FSI_setTxFrameTag(txBaseAddr, FSI_APP_TX_DATA_FRAME_TAG);
        status += FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_PING);
    
        return status;
    }
    
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr)
    {
        int32_t     status;
    
        /* RX init and reset */
        status  = FSI_performRxInitialization(rxBaseAddr);
        status += FSI_resetRxModule(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
        FSI_clearRxModuleReset(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setRxSoftwareFrameSize(rxBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setRxDataWidth(rxBaseAddr, FSI_APP_N_LANES);
        status += FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        return status;
    }
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr)
    {
        int32_t     status = SystemP_SUCCESS;
        uint32_t    i;
    
        for(i = 0; i < FSI_APP_FRAME_DATA_WORD_SIZE; i++)
        {
            if(*rxBufPtr++ != *txBufPtr++)
            {
                status = SystemP_FAILURE;
                break;
            }
        }
    
        return status;
    }
    
    //
    // compare16 - Compares two 16 bit values and increments global error flag by 1
    //             for mismatch
    //
    void compare16(uint16_t val1, uint16_t val2)
    {
        if(val1 != val2)
        {
            error++;
        }
    }
    
    //
    // checkReceivedFrameTypeTag - Checks received frame type/tag and updates global
    //                             error flag
    //
    void checkReceivedFrameTypeTag(FSI_FrameType type, FSI_FrameTag tag)
    {
        uint16_t frame_tag;
        FSI_getRxPingTag(rxBaseAddr, &frame_tag);
    
        compare16(frame_tag, (uint16_t)type);
    
        if(type == FSI_FRAME_TYPE_PING)
        {
            compare16(frame_tag, (uint16_t)tag);
        }
        else
        {
            compare16(frame_tag, (uint16_t)tag);
        }
    }
    
    static void Fsi_appTxCallback(void *args)
    {
    
        uint32_t txBaseAddr = (uint32_t) args;
    
        fsiTxInt1Received = 1U;
    
        FSI_getTxEventStatus(txBaseAddr, &txEventSts);
    
        // Set FSI TX circular buffer pointer back to beginning
        FSI_setTxBufferPtr(txBaseAddr, 0U);
    
        FSI_clearTxEvents(txBaseAddr, FSI_TX_EVTMASK);
    
        /*
        ** Handle tx callback function here
        */
        return;
    }
    
    static void Fsi_appRxCallback(void *args)
    {
        uint32_t rxBaseAddr = (uint32_t) args;
        uint16_t u16_user_data;
    
        FSI_getRxEventStatus(rxBaseAddr, &rxEventSts);
    
        if((rxEventSts & FSI_RX_EVT_DATA_FRAME) != 0)
        {
            //
            // Verify TX data is same as RX data
            //
            checkReceivedFrameTypeTag(FSI_FRAME_TYPE_NWORD_DATA, txDataFrameTag);
            FSI_getRxUserDefinedData(rxBaseAddr, &u16_user_data);
            compare16(u16_user_data, txUserData);
            compareBufData(0, 0, nWords);
    
            dataFrameCntr++;
    
            if(dataFrameCntr >= 0xFFFFFFFF)
            {
                dataFrameCntr_ui32++;
                dataFrameCntr = 0;
            }
        }
        fsiRxInt1Received = 1U;
    
        // Set FSI RX circular buffer pointer back to beginning
        FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        FSI_clearRxEvents(rxBaseAddr, rxEventSts);
    
        /*
        ** Handle rx callback function here
        */
        return;
    }
    
    static int32_t Fsi_appIntrInit(uint32_t txBaseAddr, uint32_t rxBaseAddr)
    {
        int32_t     status;
        uint32_t    txIntrNum, rxIntrNum;
        HwiP_Params txHwiPrms, rxHwiPrms;
    
        /*
         * TX interrupt config and registration
         */
        txIntrNum = CONFIG_FSI_TX0_INTR1;
        HwiP_Params_init(&txHwiPrms);
        txHwiPrms.intNum = txIntrNum;
        txHwiPrms.callback = Fsi_appTxCallback;
        txHwiPrms.args = (void *) txBaseAddr;
        status = HwiP_construct(&gFsiTxHwiObject, &txHwiPrms);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /*
         * RX interrupt config and registration
         */
        rxIntrNum = CONFIG_FSI_RX0_INTR1;
        HwiP_Params_init(&rxHwiPrms);
        rxHwiPrms.intNum = rxIntrNum;
        rxHwiPrms.callback = Fsi_appRxCallback;
        rxHwiPrms.args = (void *) rxBaseAddr;
        status = HwiP_construct(&gFsiRxHwiObject, &rxHwiPrms);
        DebugP_assert(status == SystemP_SUCCESS);
    
        return status;
    }
    
    static void Fsi_appIntrDeInit(uint32_t txBaseAddr, uint32_t rxBaseAddr)
    {
        /* TX interrupt deinit */
        FSI_disableTxInterrupt(txBaseAddr, FSI_INT1, FSI_TX_EVTMASK);
        FSI_clearTxEvents(txBaseAddr, FSI_TX_EVTMASK);
        HwiP_destruct(&gFsiTxHwiObject);
    
        /* RX interrupt deinit */
        FSI_disableRxInterrupt(rxBaseAddr, FSI_INT1, FSI_TX_EVTMASK);
        FSI_clearRxEvents(rxBaseAddr, FSI_RX_EVTMASK);
        HwiP_destruct(&gFsiRxHwiObject);
        return;
    }
    
    //
    // compareBufData - Compares if received data is same as transmitted ones
    //                  It doesn't consider wrap-up cases, but, can be enhanced
    //
    void compareBufData(uint16_t txBufIndex, uint16_t rxBufIndex, uint16_t nWords)
    {
        uint16_t i;
        uint16_t rxDataArray[16];
    
        FSI_readRxBuffer(rxBaseAddr, rxDataArray, nWords, rxBufIndex);
    
        for(i = 0; i < nWords; i++)
        {
            if(rxDataArray[i] != ( (uint16_t *)txBufAddr )[txBufIndex])
            {
                error++;
                return;
            }
    
            txBufIndex++;
        }
    }
    

    Thank you

  • Thanks Sahar, let me check this and come back to you.

    Few more questions/comments in the meantime.

    Any other lead and/or node you can use to check? to help us to confirm if your lead or your node work ok

    Also, in the meantime, and in case you haven't seen it, some FSI documentation (done in C2000 team) but mostly applicable as we got the FSI IP from C2000 team.

    Academy: FSI Lab (ti.com)

    Using the Fast Serial Interface (FSI) With Multiple Devices in an Application (Rev. E) 

    thank you,

    Paula

  • Sahar, also if you can send me a picture of your setup (both drives connected) it would be helpful

    thank you,

    Paula

  • Hi

    I saw the FSI documentation already,thanks.

    heres a picture of my setup:

    /resized-image/__size/320x240/__key/communityserver-discussions-components-files/908/20240602_5F00_110129.jpg

    The FSI wire is connecting these signals:

    TX0_CLK -> RX0_CLK

    TX0_D0 -> RX_D0

    But even with one EVM, im running a program to send data in a loop. and when measuring with a scope, im not seeing any signal from the FSI connector pins.

  • Hi Sahar, let me try to understand. You already tried a loopback with one board and it is not working? If so,

    Friday, I tried that on a AM243x Launch Pad and it worked for me. What I did was:

    - I kept everything from the example the same and just commenting out the loopback enable line

        /* Enable loopback */

        //status = FSI_enableRxInternalLoopback(rxBaseAddr);

        //DebugP_assert(status == SystemP_SUCCESS);

    - Then connecting the pins in loopback externally. For my test, for quick availability, I used an AM243x LP, so those pins are in J16 header on the board

    TX0_CLK -> RX0_CLK

    TX0_D0 -> RX_D0

    TX0_D1 -> RX-D1 (Probably not needed)

    On AM243x EVM I see there is a MUX which can select those pins between HSE and board's J5 header. Please check you are using correct mux settings for your test

    AM64x / AM243x Evaluation Module User's Guide (Rev. A)

    Let me know if loopback test with one board works for you, if so, then we can try between two devices

    thank you,

    Paula

  • Thanks for checking.

    Yes, the internal loopback test works for me, but not the external test.

    Regarding the MUX, that looks like a good lead. Can you tell me how to alternate the MUX state?

    And where can I see which pins in the HSE are connected to the MUX?

    Thank you.

  • Hi Sahar, for configuring I2C to change IO expansion pin, please search for examples in which we use TCA6424 to have an idea. Below, is an snapshot example I am using for somthing else, just for your reference. 

    There is a good FAQ: (+) [FAQ] PROCESSOR-SDK-AM64X: How to program TCA6424A using SoC_I2C1 - Processors forum - Processors - TI E2E support forums

    One small tip is to select the correct ioindex number. In my case I need to change Pin23 (20), so it really is ioindex =19

    thank you,

    Paula

  • Thank you

    Now im realy starting to see signals from the FSI connector. but for some reason im only seeing the RX related signals (pins 2 and 6).

    Can you please provide me a Schema of the EVM to make sure i configured the right pin?

  • Hi Sahar, you can download schematics from EVM page

    TMDS243EVM Evaluation board | TI.com

    File: PROC101C(005)_SCH.pdf

    Current package is for RevC

    Thank you,

    Paula

  • Hi Sahar, I believe you are using FSI connector (J7). If so, the pins you need to loopback (assuming you have a REV C - PROC101C(005) board: are:

    1 (FSI_RX0_CLk) -> 2 (FSI_TX0_CLK)

    5 (FSI_RX0_D0) -> 6 (FSI_TX0_D0)

    Please let me know if FSI loopback, with external pins, for one board, is currently working for you.

    thank you,

    Paula

  • Hi Sahar, with below code I was able to run external FSI loopback on an AM243x EVM using FSI (J6) header

    /*
     *  Copyright (C) 2021 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.
     */
    
    #include <string.h>
    #include <stdint.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/HwiP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/fsi.h>
    #include <drivers/pinmux.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <board/ioexp/ioexp_tca6424.h> //PC-- added
    
    /*
     * This example performs FSI TX to FSI RX internal loopback in polled mode.
     * The application configures an instance of FSI TX and FSI RX module with below configuration
     *
     * - Single lane
     * - TX clock at 50 MHz
     * - 16 words per frame (transfer)
     *
     * With above configuration, the application transfers 100 frames of data from FSI TX,
     * waits for data to be received by FSI RX and then compares the data.
     *
     * Once the transfer it completes, it compares the source and destination buffers for any data mismatch.
     */
    
    /* FSI TXCLK - 50 MHz */
    #define FSI_APP_TXCLK_FREQ              (50 * 1000 * 1000)
    /* FSI module input clock - 500 MHz */
    #define FSI_APP_CLK_FREQ                (CONFIG_FSI_TX0_CLK)
    /* FSI TX prescaler value for TXCLKIN of 100 MHz. / 2 is provided as TXCLK = TXCLKIN/2 */
    #define FSI_APP_TX_PRESCALER_VAL        (FSI_APP_CLK_FREQ / FSI_APP_TXCLK_FREQ / 2U)
    
    #define FSI_APP_LOOP_COUNT              (100U)
    /* User data to be sent with Data frame */
    #define FSI_APP_TX_USER_DATA            (0x07U)
    /* Configuring Frame - can be between 1-16U */
    #define FSI_APP_FRAME_DATA_WORD_SIZE    (16U)
    /* 0x0U for 1 lane and 0x1U for two lane */
    #define FSI_APP_N_LANES                 (0x0U)
    #define FSI_APP_TX_DATA_FRAME_TAG       (0x1U)
    
    /* Index of FSI TX/RX buffer, gBudIdx + FSI_APP_FRAME_DATA_WORD_SIZE should be <= 16 */
    uint16_t gRxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    uint16_t gTxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr);
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr);
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr);
    
    static TCA6424_Config  gTCA6424_Config;
    
    //PC-- added
    void i2c_io_expander(void *args)
    {
        int32_t             status = SystemP_SUCCESS;
        TCA6424_Params      tca6424Params;
        TCA6424_Params_init(&tca6424Params);
        status = TCA6424_open(&gTCA6424_Config, &tca6424Params);
        uint32_t            ioIndex;
    
        if(status == SystemP_SUCCESS)
        {
            //PC-- IO expander I2C 0x22 - Pin8 (P07)--> FSI_FET_SEL. LOW -> HSE connector, HIGH EVM J7 header (C2000 connection)
            ioIndex = 7;
            status = TCA6424_setOutput(
                         &gTCA6424_Config,
                         ioIndex,
                         TCA6424_OUT_STATE_HIGH);
    
            /* Configure as output  */
            status += TCA6424_config(
                          &gTCA6424_Config,
                          ioIndex,
                          TCA6424_MODE_OUTPUT);
        }
        TCA6424_close(&gTCA6424_Config);
    }
    
    void *fsi_loopback_main(void *args)
    {
        int32_t     status;
        uint32_t    rxBaseAddr, txBaseAddr;
        uint16_t    dataSize;
        uint32_t    loopCnt;
        uint16_t    bufIdx;
        uint16_t    txEvtSts, rxEvtSts;
    
        /* Test parameters */
        rxBaseAddr = CONFIG_FSI_RX0_BASE_ADDR;
        txBaseAddr = CONFIG_FSI_TX0_BASE_ADDR;
        dataSize   = FSI_APP_FRAME_DATA_WORD_SIZE;
        loopCnt    = FSI_APP_LOOP_COUNT;
        bufIdx     = 0U;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        /* Configure the IO Expander to connect FSI to J7 EVM header */
        i2c_io_expander(NULL);
    
        DebugP_log("[FSI] Loopback Polling application started ...\r\n");
    
        /* FSI configuration */
        status  = Fsi_appTxConfig(txBaseAddr);
        status += Fsi_appRxConfig(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
    //PC-- commented so we can run loopback with external pins
    //    /* Enable loopback */
    //    status = FSI_enableRxInternalLoopback(rxBaseAddr);
    //    DebugP_assert(status == SystemP_SUCCESS);
    
        /* Send Flush Sequence to sync, after every rx soft reset */
        status = FSI_executeTxFlushSequence(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Start transfer */
        while(loopCnt--)
        {
            /* Memset TX buffer with new data for every loop */
            for(uint32_t i = 0; i < dataSize; i++)
            {
                gTxBufData[i] = loopCnt + i;
                gRxBufData[i] = 0U;
            }
    
            /* Transmit data */
            status = FSI_setTxBufferPtr(txBaseAddr, bufIdx);
            status += FSI_writeTxBuffer(txBaseAddr, gTxBufData, dataSize, bufIdx);
            status += FSI_startTxTransmit(txBaseAddr);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Wait for TX completion */
            while(1)
            {
                FSI_getTxEventStatus(txBaseAddr, &txEvtSts);
                if(txEvtSts & FSI_TX_EVT_FRAME_DONE)
                {
                    FSI_clearTxEvents(txBaseAddr, FSI_TX_EVT_FRAME_DONE);
                    break;
                }
            }
            /* Wait for RX completion */
            while(1)
            {
                FSI_getRxEventStatus(rxBaseAddr, &rxEvtSts);
                if(rxEvtSts & FSI_RX_EVT_FRAME_DONE)
                {
                    FSI_clearRxEvents(rxBaseAddr, FSI_RX_EVT_FRAME_DONE);
                    break;
                }
            }
    
            /* Read data */
            status = FSI_readRxBuffer(rxBaseAddr, gRxBufData, dataSize, bufIdx);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Compare data */
            status = Fsi_appCompareData(gTxBufData, gRxBufData);
            DebugP_assert(status == SystemP_SUCCESS);
        }
    
        if(SystemP_SUCCESS == status)
        {
            DebugP_log("[FSI] %d frames successfully received!!!\r\n", FSI_APP_LOOP_COUNT);
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            DebugP_log("Some tests have failed!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    
        return NULL;
    }
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr)
    {
        int32_t     status;
    
        /* TX init and reset */
        status = FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        status += FSI_resetTxModule(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
        FSI_clearTxModuleReset(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setTxSoftwareFrameSize(txBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setTxDataWidth(txBaseAddr, FSI_APP_N_LANES);
    
        /* Setting frame config */
        status += FSI_setTxUserDefinedData(txBaseAddr, FSI_APP_TX_USER_DATA);
        status += FSI_setTxFrameTag(txBaseAddr, FSI_APP_TX_DATA_FRAME_TAG);
        status += FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_NWORD_DATA);
    
        return status;
    }
    
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr)
    {
        int32_t     status;
    
        /* RX init and reset */
        status  = FSI_performRxInitialization(rxBaseAddr);
        status += FSI_resetRxModule(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
        FSI_clearRxModuleReset(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setRxSoftwareFrameSize(rxBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setRxDataWidth(rxBaseAddr, FSI_APP_N_LANES);
        status += FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        return status;
    }
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr)
    {
        int32_t     status = SystemP_SUCCESS;
        uint32_t    i;
    
        for(i = 0; i < FSI_APP_FRAME_DATA_WORD_SIZE; i++)
        {
            if(*rxBufPtr++ != *txBufPtr++)
            {
                status = SystemP_FAILURE;
                break;
            }
        }
    
        return status;
    }
    

    Please let me know if it works for you or if you face any issues. 

    Thank you,

    Paula

  • Forgot to mention, please also add I2C module in your project's example.syscfg

    thank you

    Paula

  • Thank you Paula.

    it is indeed working for me.

    waiting to hear about the two EVMs communication

    Sahar

  • Sahar, great!. if you have a chance please check 2 boards connection with your setup. Probably won't, but, maybe it works.

    thank you,

    Paula

  • Already tried. it didnt work but i keep on trying.

    Will let you know if i will have any progress

    Sahar

  • Hi Paula,

    I made some progress today and managed to pass the test of 100 loops between two EVMs, but with a few changes.

    The most significant change is that I was able to do it only at a TXCLK rate of 1 MHz (maybe that value can be optimized, but I didn't check).

    At a rate of 10 MHz, I was able to pass some packets, but not all of them.

    I am trying to build a mechanism to request to resend data when a packet arrives with an error, and maybe then I would be able to work at higher frequencies.

    Attached is the code with the changes.

    /*
     *  Copyright (C) 2021 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.
     */
    
    #include <string.h>
    #include <stdint.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/HwiP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/fsi.h>
    #include <drivers/pinmux.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <board/ioexp/ioexp_tca6424.h> //PC-- added
    
    /*
     * This example performs FSI TX to FSI RX internal loopback in polled mode.
     * The application configures an instance of FSI TX and FSI RX module with below configuration
     *
     * - Single lane
     * - TX clock at 1 MHz
     * - 16 words per frame (transfer)
     *
     * With above configuration, the application transfers 100 frames of data from FSI TX,
     * waits for data to be received by FSI RX and then compares the data.
     *
     * Once the transfer it completes, it compares the source and destination buffers for any data mismatch.
     */
    
    /* FSI TXCLK - 1 MHz */
    #define FSI_APP_TXCLK_FREQ              (1 * 1000 * 1000)
    /* FSI module input clock - 500 MHz */
    #define FSI_APP_CLK_FREQ                (CONFIG_FSI_TX0_CLK)
    /* FSI TX prescaler value for TXCLKIN of 100 MHz. / 2 is provided as TXCLK = TXCLKIN/2 */
    #define FSI_APP_TX_PRESCALER_VAL        (FSI_APP_CLK_FREQ / FSI_APP_TXCLK_FREQ / 2U)
    
    #define FSI_APP_LOOP_COUNT              (100U)
    /* User data to be sent with Data frame */
    #define FSI_APP_TX_USER_DATA            (0x07U)
    /* Configuring Frame - can be between 1-16U */
    #define FSI_APP_FRAME_DATA_WORD_SIZE    (16U)
    /* 0x0U for 1 lane and 0x1U for two lane */
    #define FSI_APP_N_LANES                 (0x0U)
    #define FSI_APP_TX_DATA_FRAME_TAG       (0x1U)
    
    /* Index of FSI TX/RX buffer, gBudIdx + FSI_APP_FRAME_DATA_WORD_SIZE should be <= 16 */
    uint16_t gRxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    uint16_t gTxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr);
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr);
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr);
    
    static TCA6424_Config  gTCA6424_Config;
    
    //PC-- added
    void i2c_io_expander(void *args)
    {
        int32_t             status = SystemP_SUCCESS;
        TCA6424_Params      tca6424Params;
        TCA6424_Params_init(&tca6424Params);
        status = TCA6424_open(&gTCA6424_Config, &tca6424Params);
        uint32_t            ioIndex;
    
        if(status == SystemP_SUCCESS)
        {
            //PC-- IO expander I2C 0x22 - Pin8 (P07)--> FSI_FET_SEL. LOW -> HSE connector, HIGH EVM J7 header (C2000 connection)
            ioIndex = 7;
            status = TCA6424_setOutput(
                         &gTCA6424_Config,
                         ioIndex,
                         TCA6424_OUT_STATE_HIGH);
    
            /* Configure as output  */
            status += TCA6424_config(
                          &gTCA6424_Config,
                          ioIndex,
                          TCA6424_MODE_OUTPUT);
        }
        TCA6424_close(&gTCA6424_Config);
    }
    
    void *fsi_loopback_main(void *args)
    {
        int32_t     status;
        uint32_t    rxBaseAddr, txBaseAddr;
        uint16_t    dataSize;
        uint32_t    loopCnt;
        uint16_t    bufIdx;
        uint16_t    txEvtSts, rxEvtSts;
    
        /* Test parameters */
        rxBaseAddr = CONFIG_FSI_RX0_BASE_ADDR;
        txBaseAddr = CONFIG_FSI_TX0_BASE_ADDR;
        dataSize   = FSI_APP_FRAME_DATA_WORD_SIZE;
        loopCnt    = FSI_APP_LOOP_COUNT;
        bufIdx     = 0U;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        /* Configure the IO Expander to connect FSI to J7 EVM header */
        i2c_io_expander(NULL);
    
        DebugP_log("FSI Lead application waiting ...\r\n");
    
        /* Wait for trigger from user */
        char dummy;
        uint32_t i32_uart_base_adr= UART_getBaseAddr(gUartHandle[0]);
        while ( !UART_getChar(i32_uart_base_adr, &dummy) );
    
        DebugP_log("FSI Lead Polling application started ...\r\n");
    
        /* FSI configuration */
        status  = Fsi_appTxConfig(txBaseAddr);
        status += Fsi_appRxConfig(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Disable loopback */
        status = FSI_disableRxInternalLoopback(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Start transfer */
        while(loopCnt--)
        {
            DebugP_log("Lead sending loop: %d\r\n", loopCnt);
    
            /* Memset TX buffer with new data for every loop */
            for(uint32_t i = 0; i < dataSize; i++)
            {
                gTxBufData[i] = loopCnt + i;
                gRxBufData[i] = 0U;
            }
    
            /* Send Flush Sequence to sync, after every rx soft reset */
            status = FSI_executeTxFlushSequence(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Transmit data */
            status = FSI_setTxBufferPtr(txBaseAddr, bufIdx);
            status += FSI_writeTxBuffer(txBaseAddr, gTxBufData, dataSize, bufIdx);
            status += FSI_startTxTransmit(txBaseAddr);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Wait for TX completion */
            while(1)
            {
                FSI_getTxEventStatus(txBaseAddr, &txEvtSts);
                if(txEvtSts & FSI_TX_EVT_FRAME_DONE)
                {
                    FSI_clearTxEvents(txBaseAddr, FSI_TX_EVT_FRAME_DONE);
                    break;
                }
            }
    
            DebugP_log("Lead receiving loop: %d\r\n", loopCnt);
    
            /* Wait for RX completion */
            while(1)
            {
                FSI_getRxEventStatus(rxBaseAddr, &rxEvtSts);
                if(rxEvtSts & ( FSI_RX_EVT_FRAME_DONE | FSI_RX_EVT_DATA_FRAME ) )
                {
                    FSI_clearRxEvents(rxBaseAddr, rxEvtSts );
                    break;
                }
            }
    
            /* Read data */
            status = FSI_readRxBuffer(rxBaseAddr, gRxBufData, dataSize, bufIdx);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Compare data */
            status = Fsi_appCompareData(gTxBufData, gRxBufData);
            DebugP_assert(status == SystemP_SUCCESS);
        }
    
        if(SystemP_SUCCESS == status)
        {
            DebugP_log("[FSI] %d frames successfully received!!!\r\n", FSI_APP_LOOP_COUNT);
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            DebugP_log("Some tests have failed!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    
        return NULL;
    }
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr)
    {
        int32_t     status;
    
        /* TX init and reset */
        status = FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        status += FSI_resetTxModule(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
        FSI_clearTxModuleReset(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setTxSoftwareFrameSize(txBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setTxDataWidth(txBaseAddr, FSI_APP_N_LANES);
    
        /* Setting frame config */
        status += FSI_setTxUserDefinedData(txBaseAddr, FSI_APP_TX_USER_DATA);
        status += FSI_setTxFrameTag(txBaseAddr, FSI_APP_TX_DATA_FRAME_TAG);
        status += FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_NWORD_DATA);
    
        return status;
    }
    
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr)
    {
        int32_t     status;
    
        /* RX init and reset */
        status  = FSI_performRxInitialization(rxBaseAddr);
        status += FSI_resetRxModule(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
        FSI_clearRxModuleReset(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setRxSoftwareFrameSize(rxBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setRxDataWidth(rxBaseAddr, FSI_APP_N_LANES);
        status += FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        return status;
    }
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr)
    {
        int32_t     status = SystemP_SUCCESS;
        uint32_t    i;
    
        for(i = 0; i < FSI_APP_FRAME_DATA_WORD_SIZE; i++)
        {
            if(*rxBufPtr++ != *txBufPtr++)
            {
                status = SystemP_FAILURE;
                break;
            }
        }
    
        return status;
    }

    /*
     *  Copyright (C) 2021 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.
     */
    
    #include <string.h>
    #include <stdint.h>
    #include <kernel/dpl/DebugP.h>
    #include <kernel/dpl/HwiP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <drivers/fsi.h>
    #include <drivers/pinmux.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <board/ioexp/ioexp_tca6424.h> //PC-- added
    
    /*
     * This example performs FSI TX to FSI RX internal loopback in polled mode.
     * The application configures an instance of FSI TX and FSI RX module with below configuration
     *
     * - Single lane
     * - TX clock at 1 MHz
     * - 16 words per frame (transfer)
     *
     * With above configuration, the application transfers 100 frames of data from FSI TX,
     * waits for data to be received by FSI RX and then compares the data.
     *
     * Once the transfer it completes, it compares the source and destination buffers for any data mismatch.
     */
    
    /* FSI TXCLK - 1 MHz */
    #define FSI_APP_TXCLK_FREQ              (1 * 1000 * 1000)
    /* FSI module input clock - 500 MHz */
    #define FSI_APP_CLK_FREQ                (CONFIG_FSI_TX0_CLK)
    /* FSI TX prescaler value for TXCLKIN of 100 MHz. / 2 is provided as TXCLK = TXCLKIN/2 */
    #define FSI_APP_TX_PRESCALER_VAL        (FSI_APP_CLK_FREQ / FSI_APP_TXCLK_FREQ / 2U)
    
    #define FSI_APP_LOOP_COUNT              (100U)
    /* User data to be sent with Data frame */
    #define FSI_APP_TX_USER_DATA            (0x07U)
    /* Configuring Frame - can be between 1-16U */
    #define FSI_APP_FRAME_DATA_WORD_SIZE    (16U)
    /* 0x0U for 1 lane and 0x1U for two lane */
    #define FSI_APP_N_LANES                 (0x0U)
    #define FSI_APP_TX_DATA_FRAME_TAG       (0x1U)
    
    /* Index of FSI TX/RX buffer, gBudIdx + FSI_APP_FRAME_DATA_WORD_SIZE should be <= 16 */
    uint16_t gRxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    uint16_t gTxBufData[FSI_MAX_VALUE_BUF_PTR_OFF + 1U];
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr);
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr);
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr);
    
    static TCA6424_Config  gTCA6424_Config;
    
    //PC-- added
    void i2c_io_expander(void *args)
    {
        int32_t             status = SystemP_SUCCESS;
        TCA6424_Params      tca6424Params;
        TCA6424_Params_init(&tca6424Params);
        status = TCA6424_open(&gTCA6424_Config, &tca6424Params);
        uint32_t            ioIndex;
    
        if(status == SystemP_SUCCESS)
        {
            //PC-- IO expander I2C 0x22 - Pin8 (P07)--> FSI_FET_SEL. LOW -> HSE connector, HIGH EVM J7 header (C2000 connection)
            ioIndex = 7;
            status = TCA6424_setOutput(
                         &gTCA6424_Config,
                         ioIndex,
                         TCA6424_OUT_STATE_HIGH);
    
            /* Configure as output  */
            status += TCA6424_config(
                          &gTCA6424_Config,
                          ioIndex,
                          TCA6424_MODE_OUTPUT);
        }
        TCA6424_close(&gTCA6424_Config);
    }
    
    void *fsi_loopback_main(void *args)
    {
        int32_t     status;
        uint32_t    rxBaseAddr, txBaseAddr;
        uint16_t    dataSize;
        uint32_t    loopCnt;
        uint16_t    bufIdx;
        uint16_t    txEvtSts, rxEvtSts;
    
        /* Test parameters */
        rxBaseAddr = CONFIG_FSI_RX0_BASE_ADDR;
        txBaseAddr = CONFIG_FSI_TX0_BASE_ADDR;
        dataSize   = FSI_APP_FRAME_DATA_WORD_SIZE;
        loopCnt    = FSI_APP_LOOP_COUNT;
        bufIdx     = 0U;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        /* Configure the IO Expander to connect FSI to J7 EVM header */
        i2c_io_expander(NULL);
    
        DebugP_log("FSI Node application waiting ...\r\n");
    
        /* Wait for trigger from user */
        char dummy;
        uint32_t i32_uart_base_adr= UART_getBaseAddr(gUartHandle[0]);
        while ( !UART_getChar(i32_uart_base_adr, &dummy) );
    
        DebugP_log("FSI Node Polling application started ...\r\n");
    
        /* FSI configuration */
        status  = Fsi_appTxConfig(txBaseAddr);
        status += Fsi_appRxConfig(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* disable loopback */
        status = FSI_disableRxInternalLoopback(rxBaseAddr);
        DebugP_assert(status == SystemP_SUCCESS);
    
        /* Start transfer */
        while(loopCnt--)
        {
            /* Memset RX buffer with new data for every loop */
            for(uint32_t i = 0; i < dataSize; i++)
            {
                gRxBufData[i] = 0U;
            }
    
            DebugP_log("Node receiving loop: %d\r\n", loopCnt);
    
            /* Wait for RX completion */
            while(1)
            {
                FSI_getRxEventStatus(rxBaseAddr, &rxEvtSts);
                if(rxEvtSts & ( FSI_RX_EVT_FRAME_DONE | FSI_RX_EVT_DATA_FRAME ) )
                {
                    FSI_clearRxEvents(rxBaseAddr, rxEvtSts);
                    break;
                }
            }
    
            /* Read data */
            status = FSI_readRxBuffer(rxBaseAddr, gRxBufData, dataSize, bufIdx);
            DebugP_assert(status == SystemP_SUCCESS);
    
            DebugP_log("Node sending loop: %d\r\n", loopCnt);
    
            /* Send Flush Sequence to sync, after every rx soft reset */
            status = FSI_executeTxFlushSequence(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Transmit data */
            status = FSI_setTxBufferPtr(txBaseAddr, bufIdx);
            status += FSI_writeTxBuffer(txBaseAddr, gRxBufData, dataSize, bufIdx);
            status += FSI_startTxTransmit(txBaseAddr);
            DebugP_assert(status == SystemP_SUCCESS);
    
            /* Wait for TX completion */
            while(1)
            {
                FSI_getTxEventStatus(txBaseAddr, &txEvtSts);
                if(txEvtSts & FSI_TX_EVT_FRAME_DONE)
                {
                    FSI_clearTxEvents(txBaseAddr, FSI_TX_EVT_FRAME_DONE);
                    break;
                }
            }
        }
    
        if(SystemP_SUCCESS == status)
        {
            DebugP_log("[FSI] %d frames successfully received!!!\r\n", FSI_APP_LOOP_COUNT);
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            DebugP_log("Some tests have failed!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    
        return NULL;
    }
    
    static int32_t Fsi_appTxConfig(uint32_t txBaseAddr)
    {
        int32_t     status;
    
        /* TX init and reset */
        status = FSI_performTxInitialization(txBaseAddr, FSI_APP_TX_PRESCALER_VAL);
        status += FSI_resetTxModule(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
        FSI_clearTxModuleReset(txBaseAddr, FSI_TX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setTxSoftwareFrameSize(txBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setTxDataWidth(txBaseAddr, FSI_APP_N_LANES);
    
        /* Setting frame config */
        status += FSI_setTxUserDefinedData(txBaseAddr, FSI_APP_TX_USER_DATA);
        status += FSI_setTxFrameTag(txBaseAddr, FSI_APP_TX_DATA_FRAME_TAG);
        status += FSI_setTxFrameType(txBaseAddr, FSI_FRAME_TYPE_NWORD_DATA);
    
        return status;
    }
    
    static int32_t Fsi_appRxConfig(uint32_t rxBaseAddr)
    {
        int32_t     status;
    
        /* RX init and reset */
        status  = FSI_performRxInitialization(rxBaseAddr);
        status += FSI_resetRxModule(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
        FSI_clearRxModuleReset(rxBaseAddr, FSI_RX_MAIN_CORE_RESET);
    
        /* Setting for requested transfer params */
        status += FSI_setRxSoftwareFrameSize(rxBaseAddr, FSI_APP_FRAME_DATA_WORD_SIZE);
        status += FSI_setRxDataWidth(rxBaseAddr, FSI_APP_N_LANES);
        status += FSI_setRxBufferPtr(rxBaseAddr, 0U);
    
        return status;
    }
    
    static int32_t Fsi_appCompareData(uint16_t *txBufPtr, uint16_t *rxBufPtr)
    {
        int32_t     status = SystemP_SUCCESS;
        uint32_t    i;
    
        for(i = 0; i < FSI_APP_FRAME_DATA_WORD_SIZE; i++)
        {
            if(*rxBufPtr++ != *txBufPtr++)
            {
                status = SystemP_FAILURE;
                break;
            }
        }
    
        return status;
    }

    Thank you

    Sahar

  • Hi Sahar, thanks a lot. let me check your new code and try it in my setup as well.

    Paula

  • Hi Sahar, I reproduced your results and working to see where it can be improved.

    thanks,

    Paula

  • Hi Sahar, I think I found the mistake in my setup. Please also check yours. I was missing connecting GND between both boards (J7.3 and J7.4 on AM243x EVM). After that, FSI loopback demo with 2 devices at 50MHz works OK.

    I also tried 2 FSI devices + FSI daughter cards TMDSFSIADAPEVM Daughter card | TI.com, which is the recommendation, and loopback demo also works great.

    FSI Adapter Board User’s Guide (ti.com)

    In case you want to tried connection between AM243x EVM and daughter card's FSI connector (J1), correspondence between pin numbers are one to one:

    AM64x EVM

    Header:Pin

    Pin Function

    FSI Adapter Board

    Header:Pin

    Pin Function

    Notes

    J7:P10

    VCC_3V3_SYS

    J1:P10

    3V3

    female-to-female jumper wire

    J7:P3

    DGND

    J1:P3

    GND

    female-to-female jumper wire

    J7:P1

    FSI_RX0_CLK

    J1:P1

    RX_CLK

    female-to-female jumper wire

    J7:P5

    FSI_RX0_D0

    J1:P5

    RX_D0

    female-to-female jumper wire

    J7:P2

    FSI_TX0_CLK

    J1:P2

    TX_CLK

    female-to-female jumper wire

    J7:P6

    FSI_TX0_D0

    J1:P6

    TX_D0

    female-to-female jumper wire

     

    Connecting this FSI daughter's card to an AM243x LP is even easier as you can just plug in on top of a LP. But you can also use jumper cables

    AM243xLP 

    Header:Pin

    Pin Function

    FSI Adapter Board

    Header:Pin

    Pin Function

    Notes

    J16:P10

    VCC_3V3_SYS

    J1:P10

    3V3

    female-to-female jumper wire

    J16:P3

    DGND

    J1:P3

    GND

    female-to-female jumper wire

    J16:P1

    FSI_RX0_CLK

    J1:P1

    TX_CLK

    female-to-female jumper wire

    J16:P5

    FSI_RX0_D0

    J1:P5

    TX_D0

    female-to-female jumper wire

    J16:P2

    FSI_TX0_CLK

    J1:P2

    RX_CLK

    female-to-female jumper wire

    J16:P6

    FSI_TX0_D0

    J1:P6

    RX_D0

    female-to-female jumper wire

    A quick note, between daughter's cards there is LVDS TX (RJ45) from one board goes to LVDS RX to the other board (RJ45)

    Please let me know if this resolves the issue.

    thank you,

    Paula

  • Hi Paula

    Thank you. that's realy works now

    Sahar