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.

TMS320F28388D: FSI error recovery and soft reset

Part Number: TMS320F28388D

Hello there,

I'm running tests with the fsi_ex-daisy_handshake example. Whenever a communication error happens in this example, the application simply stops. But what if I want to recover from an error, for example disconnecting and reconnecting one of the cables?

Section 32.4.3.10 of the TRM describes the conditions in which the receiver must undergo a soft reset. I suppose I would need to check for these errors in the main() while loop and perform a soft reset in case of an error. But I'm not sure about the meaning of 'soft reset'. Does it mean to start again from the handshake? Or is there simply an API function to call?

Thanks and kind regards,
Arjan

  • Absolutely, when the communication is lost and this is detected (watchdog and ping frames are great features for this), the handshake must take place again and you need to take care of that in main.

    Nima

  • Hi Nima,

    I added some code in fsi_ex16_daisy_handshake_lead.c that checks for an Rx timeout and then restarts the handshake. So when I run it and shortly disconnect or reset the other node I see the timeout works OK and it enters the handshake_lead() function. However there it remains in the first loop, so waiting for ping frame tag 0.

    Even when I use Run-Restart in the debugger (so restarting from main()) it does the same. Only when I use Run-Reset-CPU Reset, and then start from main(), then the handshake succeeds.

    Obviously I need to reset some stuff before I run the handshake again. But what exactly? I tried calling these functions in various combinations, but that didn't work:

                                disableAllFSIInterrupts();
                                DMA_stopChannel(DMA_CH4_BASE);
                                DMA_stopChannel(DMA_CH3_BASE);
                                DMA_stopChannel(DMA_CH2_BASE);
                                DMA_stopChannel(DMA_CH1_BASE);
                                FSI_disableRxDMAEvent(FSIRXA_BASE);
                                DMA_disableInterrupt(DMA_CH2_BASE);
                                DMA_disableInterrupt(DMA_CH4_BASE);
                                FSI_resetRxModule(FSIRXA_BASE, FSI_RX_MASTER_CORE_RESET);
                                FSI_resetTxModule(FSITXA_BASE, FSI_TX_MASTER_CORE_RESET);
    

    Thanks and kind regards,
    Arjan

  • Well both devices should detect the line break and the device initiating the handshake should be continuously send PING0. I'm assuming only one device is doing this.

    Nima

  • Hi Nima,

    No, for this test I simply reboot the other node, so it restarts and waits in its own handshake_node() function for the first ping from the lead node.

    The lead node (which I'm debugging) notices the line break caused by the reboot of the other node, and re-enters its handshake_lead() function. But there it fails to receive the ping message from the other node.

    Then I tried to restart from main() in the debugger (without touching the other node), then still it fails even though the application starts from scratch.

    Then I reset the CPU from the debugger and restart from main() again (still not touching the other node), and then the handshake works and communication is restored.

    So it appears I need to reset something in the FSI or interrupts or DMA (or something else) to be able to repeat the handshake after the 'normal' communication has been active.

    Any ideas? Are there any other examples that detect a line break and restore FSI communication?

    Kind regards,
    Arjan

  • Yes, I recommend you reset EVERYTHING in your FSI, DMA settings, in your CCS debugger window , grab the register content for FSI and DMA. Then in the failing condition grab the register content for the FSI and DMA. Compare then find the differences.

    For FSI, during the handshake there should be no need for DMA. So remove the DMA section of handling the FSI during the handshake so we eliminate another variable. Then for FSI, If you look at the examples we have in:

    They continuously check for failure between PINGs and recovers from failures. Remember PING0 MUST BE used since it flushes the state machine inside FSI.

  • Hi Nima,

    I was already using the FSI and DMA API functions to try and reset the relevant registers, but apparently it wasn't enough. I followed your suggestion to look at the registers in the CCS debugger in different situations, and I found that the TX_OPER_CTRL_LO and TX_CLK_CTRL were not reset after restarting the program.

    So now I always call these functions before the handshake:

                    // Reset FSI before handshake (in case we're here after comm failure)
                    disableAllFSIInterrupts();
                    resetFSIRegisters(FSITXA_BASE, FSIRXA_BASE);
                    FSI_performTxInitialization(FSITXA_BASE, PRESCALER_VAL);
                    FSI_performRxInitialization(FSIRXA_BASE);
    
                    // Reset DMA before handshake (in case we're here after comm failure)
                    DMA_initController();
    
    

    resetFSIRegisters() is a function I made, with similar setup as the FSI API:

    //
    // resetFSIRegisters - Reset registers in both FSI Tx/Rx, needed before
    //                     reconnecting with handshake
    //
    static inline void resetFSIRegisters(uint32_t txBase, uint32_t rxBase)
    {
        //
        // Check the arguments.
        //
        ASSERT(FSI_isTxBaseValid(txBase));
        ASSERT(FSI_isRxBaseValid(rxBase));
    
        EALLOW;
        HWREGH(txBase + FSI_O_TX_CLK_CTRL)     = 0;
        HWREGH(txBase + FSI_O_TX_OPER_CTRL_LO) = 0;
        HWREGH(txBase + FSI_O_TX_FRAME_CTRL)   = 0;
    
        HWREGH(rxBase + FSI_O_RX_OPER_CTRL)    = 0;
        EDIS;
    }
    

    And now it's working OK! When I reset the other node, or disconnect and reconnect a cable, the handshake is successful and the connection is restored.

    Thanks and kind regards,
    Arjan



  • Fantastic debugging Arjan!