Other Parts Discussed in Thread: CC2640,
Tool/software: Code Composer Studio
Hi Forum;
I'm using CC2640R2F running TI-RTOS (with Simplelink CC2640R2F SDK 1.50) as an SPI slave connected to an MSP432P4011 (with TI-RTOS with Simplelink SDK 3.30) as the master. I have omitted the chip select line and am using a GPIO instead to signal slave data ready. Whenever the CC2640 wants to initiate data transfer, it pulls the line high which triggers a rising edge interrupt on the MSP432, which then initiates an SPI transaction. The MSP432 is the source of data and CC2640 acts as a communication interface, hence configured them as master and slave respectively. However, in 2 cases, the CC2640 needs to initiate the SPI, so I'm using the GPIO as a signalling line.
My SPI parameters on the CC2640 are as follows -
SPI_Params_init(&spiParams_slave); spiParams_slave.bitRate = 50000; //50 kHz SPI CLK spiParams_slave.frameFormat = SPI_POL0_PHA1; spiParams_slave.mode = SPI_SLAVE; spiParams_slave.dataSize = 8; spiParams_slave.transferCallbackFxn = SPITransferCompleteFxn; spiParams_slave.transferMode = SPI_MODE_CALLBACK; spiHandle_slave = SPI_open(Board_SPI1, &spiParams_slave);
The clock is low because transfer speed is not a concern, but I was worried about data integrity without CS line, so I brought down the speed from 1 MHz to 50 kHz.
On the CC2640 slave, the SPI is set up as a callback mode, which enqueues an RTOS event whenever a transaction is complete. The event then copies over the slaveRxbuffer and parses the data and treats it accordingly.
On the master (MSP432) the SPI is configured in Blocking mode as follows -
SPI_Params_init(&spiParams_Kernel); spiParams_Kernel.bitRate = 50000; //50 kHz clock spiParams_Kernel.frameFormat = SPI_POL0_PHA1; spiParams_Kernel.mode = SPI_MASTER; spiParams_Kernel.transferMode = SPI_MODE_BLOCKING; spiParams_Kernel.dataSize = 8; spiParams_Kernel.transferTimeout = 500; spi_Kernel = SPI_open(KERNEL_SPI, &spiParams_Kernel);
Now, this interface works very well for the most part - I'm able to transfer complete frames and transactions up to 30-35 bytes in length.
However, if I reset the MSP432 MCU, everything goes haywire. When the MSP432 is reset, the all the GPIOs get toggled and I scoped the MOSI and CLK lines, and they also get toggled as shown in the attached image -
After this happens, all my subsequent SPI transactions are bit or byte shifted and everything gets messed up. Interestingly, this does NOT happen if I reset the CC2640. Infact, resetting CC2640 after MSP has been reset solves this issue.
My hunch is that since the CC2640 SPI slave is configured without a transfertimeout, it keeps waiting for data from the master and the synchronization gets disturbed. The one clock pulse and MOSI toggle shifts the internal register by 1 bit and loses synchronization. Is this analysis correct?
I was wondering if adding a transferTimeout to the slave SPI configuration will overcome this issue but I had questions regarding this parameter, which I could not get answered from the documentation. How does this work in callback mode? For instance, if I add a timeout of 1 sec in callback mode, does the SPI transaction have to be completed within 1 sec of calling SPI_transfer() function?
Noticed the following line in the SPI.h driver -
* From calling %SPI_transfer() until transfer completion, the SPI_Transaction * structure must stay persistent and must not be altered by application code. * It is also forbidden to modify the content of the SPI_Transaction.txBuffer * during a transaction, even though the physical transfer might not have * started yet. Doing this can result in data corruption. This is especially * important for slave operations where %SPI_transfer() might be called a long * time before the actual data transfer begins.
So my question is - If I implement a transfertimeout = 1 sec, will it time out if the SPI transaction has been initiated by the master but did not complete within 1 sec? If this is the case, all spurious GPIO toggles like the one I captured above will get ignored and the bit shifts, possibly avoided.
OR, will it timeout after 1 sec elapses after SPI_transfer() gets called in the CC2640's execution and no SPI transfer has taken place? In that case, how can one use this effectively when using callback mode when the SPI transaction may be initiated by the master at an unknown time? If this is the case, how can one prevent spurious transactions with GPIO toggles one reset like the one above?
Will appreciate some more insights on this!
-Shreyas Kulkarni