SPIM Register_TxStatus

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
jra_4963611
Level 1
Level 1
5 sign-ins First solution authored First reply posted

What is the difference between these SPIM Register_TxStatus:  SPI Done and SPI Idle.

What needs to happened to set SPI Idle once that SPI Done is already set?

 

Thanks.

0 Likes
1 Solution

Thank you Len.

I asked because if use this lines of code to read 3 bytes from a Slave:

SPIM_ClearRxBuffer();
SPIM_ClearFIFO();
PinLoRa_CS_DR &= ~PinLoRa_CS_MASK;  // SS to LOW
SPIM_WriteTxData(REG_FIFO & 0x7F); // Sending to Slave Read bit and address

// Start reading from Slave
for(int i =0; i < data_l; i++){
SPIM_WriteTxData(0x00);
}

while(!(SPIM_ReadTxStatus() & SPIM_STS_SPI_DONE));
PinLoRa_CS_DR |= PinLoRa_CS_MASK;   //  SS to HIGH

The Master sends two bytes all in a row, then waits 2uSec (SPI bit rate 1 Mbps) and sends the third byte. Then waits almost 10 uSec and sends the fourth byte. But at the middle of the 4th byte, the SS goes HIGH. I guess the delay after the second byte is to move from the FIFO to the RAM buffer, but somehow, the SPI_DONE flag is set in the middle of the 4th byte transfer.

However, with the same code, but using the SPIM_STS_SPI_IDLE, like this next one, it works fine.

SPIM_ClearRxBuffer();
SPIM_ClearFIFO();
PinLoRa_CS_DR &= ~PinLoRa_CS_MASK;
SPIM_WriteTxData(REG_FIFO & 0x7F); // Sending to Slave Read code and address

// Start reading from Slave
for(int i =0; i < data_l; i++){
SPIM_WriteTxData(0x00);
}

while(!(SPIM_ReadTxStatus() & SPIM_STS_SPI_IDLE));
PinLoRa_CS_DR |= PinLoRa_CS_MASK;

 

 

View solution in original post

0 Likes
4 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

jra,

SPI_DONE is set when all the bits have left the SPI_DATA.  It is only active for ONE cycle.  SPI_DONE becomes inactive, the SPI_IDLE bit is set and remains set until new data is placed in the Tx FIFO.

Here's a Functional timing diagram.

Len_CONSULTRON_0-1631843875416.png

 

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Thank you Len.

I asked because if use this lines of code to read 3 bytes from a Slave:

SPIM_ClearRxBuffer();
SPIM_ClearFIFO();
PinLoRa_CS_DR &= ~PinLoRa_CS_MASK;  // SS to LOW
SPIM_WriteTxData(REG_FIFO & 0x7F); // Sending to Slave Read bit and address

// Start reading from Slave
for(int i =0; i < data_l; i++){
SPIM_WriteTxData(0x00);
}

while(!(SPIM_ReadTxStatus() & SPIM_STS_SPI_DONE));
PinLoRa_CS_DR |= PinLoRa_CS_MASK;   //  SS to HIGH

The Master sends two bytes all in a row, then waits 2uSec (SPI bit rate 1 Mbps) and sends the third byte. Then waits almost 10 uSec and sends the fourth byte. But at the middle of the 4th byte, the SS goes HIGH. I guess the delay after the second byte is to move from the FIFO to the RAM buffer, but somehow, the SPI_DONE flag is set in the middle of the 4th byte transfer.

However, with the same code, but using the SPIM_STS_SPI_IDLE, like this next one, it works fine.

SPIM_ClearRxBuffer();
SPIM_ClearFIFO();
PinLoRa_CS_DR &= ~PinLoRa_CS_MASK;
SPIM_WriteTxData(REG_FIFO & 0x7F); // Sending to Slave Read code and address

// Start reading from Slave
for(int i =0; i < data_l; i++){
SPIM_WriteTxData(0x00);
}

while(!(SPIM_ReadTxStatus() & SPIM_STS_SPI_IDLE));
PinLoRa_CS_DR |= PinLoRa_CS_MASK;

 

 

0 Likes

jra,

It is not clear in the datasheet whether SPI_Done is latched until read.  If not, then since it only appears for one clock cycle, a CPU poll might miss it.

SPI_Done would be best uses to generate an interrupt.

The SPI_IDLE is very good.  It is just delayed by one clock cycle from SPI_Done.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I understand.  Len, thank you very much.

0 Likes