Hello,
I am using FSI in an application with F280041C DSP (with the LaunchPad) to do two things at the same time:
- Synchronizing the EPWMs of two F280041C microcontrollers
- Sending data between the microcontrollers
The way I am doing this (after handshake procedure) is the following:
- In 'master' device, I set one EPWM as external trigger source to trigger the PING frame transmission with a certain frequency. This ping will be used by the 'slave' DSP to synchronize the PWM. When the application wants to send data to the 'slave', the external ping transmission is disabled, and then software transmission is enabled. Buffer and USER_DATA is filled with custom data, and then transmission is started. When the transmission is finished, then external ping transmission is enabled back again.
- in 'slave' device, I set the CLB module to automatically send back the ping frame upon reception (as explained in the TI Examples for PWM synchronization). Similarly to what I do in the 'master' device, if the application wants to send data, then the external ping transmission is disabled and then software transmission is enabled. When the software transmission is finished, the external transmission is enabled back again.
To interpret the custom received data frame (in either master or slave device), what I do is to check the USER_DATA value, and then call a different function based on this value.
Now I explain the problem that I am facing. Normally, handshake procedure goes smoothly, and the two boards are able to synchronize their PWMs. I am also able to successfully send data between them, but from time to time, the USER_DATA content and BUFFER content do not match what I am expecting. Let me give you an example:
When USER_DATA is 0, I expect the BUFFER content to be all 0x0000, and when USER_DATA is 1, I expect my buffer content to be all 0xAAAA. However, sometimes, I may receive USER_DATA with value 1, and the buffer content is all zeros, and the other way around. Basically, it seems like if the RX submodule is reading old information of either the USER_DATA or the BUFFER register. But I know that it is impossible (from my application code) to have given the wrong values to these registers. So I think it has to do with the arbitration of the TX/RX modules of FSI.
Here Is a code snippet of what I do in the 'write' function:
static int fsi__write(struct fsi_f *f)
{
/* Set software trigger mode */
FSI_setTxStartMode(FSITXA_BASE, FSI_TX_START_FRAME_CTRL);
FSI_disableRxPingWatchdog(FSIRXA_BASE);
FSI_disableTxExtPingTrigger(FSITXA_BASE);
FSI_setTxFrameType(FSITXA_BASE, FSI_FRAME_TYPE_NWORD_DATA);
/* Fill USER_DATA and BUFFER */
FSI_setTxUserDefinedData(FSITXA_BASE,f->id);
FSI_writeTxBuffer(FSITXA_BASE,f->data,16U,0U);
/* Start transmission */
FSI_clearTxEvents(FSITXA_BASE, FSI_TX_EVT_FRAME_DONE); // Clear previous FRAME_DONE flags
FSI_startTxTransmit(FSITXA_BASE);
/* Wait until the data frame is sent */
fsi__wait(FSI_TX_EVT_FRAME_DONE);
/* Enable Ping Watchdog with 1.5 seconds of timeout, assuming 100 MHz SYSCLK*/
FSI_setRxPingTimeoutMode(FSIRXA_BASE,FSI_PINGTIMEOUT_ON_HWINIT_PING_FRAME);
FSI_enableRxPingWatchdog(FSIRXA_BASE,TIMEOUT_WATCHDOG);
/* Enable external ping trigger*/
FSI_setTxPingTag(FSITXA_BASE, FSI_FRAME_TAG1);
FSI_setTxFrameType(FSITXA_BASE, FSI_FRAME_TYPE_PING);
FSI_enableTxExtPingTrigger(FSITXA_BASE, priv->trg_src);
FSI_setTxStartMode(FSITXA_BASE, FSI_TX_START_EXT_TRIG);
return 1;
}
And here is a code snippet of what I do in the 'read' function
static int fsi__read(struct fsi_f *f)
{
uint16_t rxFlags;
uint16_t receivedWords;
/* Read RX Event flags */
rxFlags = FSI_getRxEventStatus(FSIRXA_BASE);
/* Return in case of CRC error */
if(rxFlags & (FSI_RX_EVT_CRC_ERR)){
FSI_clearRxEvents(FSITXA_BASE, FSI_RX_EVT_CRC_ERR);
return 0;
}
/* If received data frame, and there are 16 words, read its content */
if(rxFlags & (FSI_RX_EVT_DATA_FRAME | FSI_RX_EVT_FRAME_DONE) ){
receivedWords = FSI_getRxWordCount(FSIRXA_BASE);
if(receivedWords == 16){
FSI_clearRxEvents(FSITXA_BASE, (FSI_RX_EVT_DATA_FRAME | FSI_RX_EVT_FRAME_DONE));
f->id = FSI_getRxUserDefinedData(FSIRXA_BASE);
FSI_readRxBuffer(FSIRXA_BASE,f->data,16U,0U);
return 1;
}
}
return 0;
}
Is there anything that I might be doing wrong? I am thinking that maybe there is some race condition somewhere because I am switching between external trigger and software trigger or something like that...
For your information, none of this code is run inside any interrupt.
Any help is appreciated and let me know if you need a better explanation of my problem.
Best regards.