Other Parts Discussed in Thread: TMS570LS3137, TMS570LS0332
Context:
We have an application using the following microcontrollers:
TMS320F280049CPZS - DSP
TMS570LS3137 – Main
TMS570LS0332 - Secondary
All processors communicate with each other through the SPI interface. The SPI and DMA modules are configured in the DSP as follows:
Communication between Main and DSP
SPI bus: SPIA
SPI bitrate: 8MHz
SPI msg: 64 words every 1 msec.
Main is Master. DSP is slave.
DMA channels: CH5 (DSP to Main) and CH6 (Main to DSP).
DMA CH6: Continuous Mode ON
DMA CH5: Continuous Mode OFF
DMA interrupt: INT_AT_END
Communication between Secondary and DSP
SPI bus: SPIB
SPI speed: 8MHz
SPI msg: 64 words every 1 msec.
Secondary is Master. DSP is slave.
DMA channels: CH3 (DSP to Secondary) and CH4 (Main to Secondary).
DMA CH4: Continuous Mode ON
DMA CH3: Continuous Mode OFF
DMA interrupt: INT_AT_END
Problem
SPI data is not “understood” correctly if one of the microcontrollers is forced to reset while the others continue running. This problem is intermittent (it does not occur for every reset).
Inspecting the DMA memory, it has been observed the data is shifted a given number of words.
Hypothesis
SPI slave loses synchronization with the master when reset is forced. When the reset occurs while data was being transmitted, part of the message is lost. The DMA memory stores an incomplete message stream.
Suggested solution
Reset the SPI and DMA modules to its default state if we ever detect an incorrect data stream. We were using the CS line and a GPIO interrupt to bring the SPI/DMA to a known state. However, we would like to confirm what the appropriate set of steps should be to bring both the SPI and DMA modules to its initial state (working state).
We would need to communication between main and DSP while keeping the communication between the Secondary and DSP active or vice versa.
Would the following code make it for the communication between main and DSP?
//Disable SPI
SPI_disableModule(SPIA_BASE);
//Stop channel and clear trigger Flag
DMA_stopChannel(DMA_CH6_BASE);
DMA_clearTriggerFlag(DMA_CH6_BASE);
//Soft Reset the DMA Channel 6
DMA_triggerSoftReset(DMA_CH6_BASE);
// Soft Reset Channel 5 and Flush SPI Tx Buffer
DMA_triggerSoftReset(DMA_CH5_BASE);
SPI_resetTxFIFO(SPIA_BASE);
DMA_enableTrigger(DMA_CH5_BASE);
//Enable SPI
SPI_enableModule(SPIA_BASE);
//Start Channel
DMA_startChannel(DMA_CH6_BASE);
We suspect some code may not be necessary or additional code may be required.