2013-09-20 09:13 AM
I am puzzled over a missing SPI TX buffer empty interrupt at the end of a transmission.
In slave mode I transmit x bytes and disable the tx interrupt when a new tx empty interrupt is generated after the last byte was send. Every now and then (1:2000 maybe) I never reach the disabling code. I.e. after sending the x bytes the TX empty interrupt is never generated or the interrupt handler never called. As far as I can tell from the physical signals the transfer completes. I use CAN in parallel with same interrupt prio. Data is copied from CAN into a ring buffer, processed and written into a buffer ruled by main(). main() waits on dataBusyFlag == 0 and will write into the spiDataBuffer. Now I am wondering for possible reasons and where timing could play a role. Is it better to disable txe int right after the SendData-command? I could while-loop over the SPI BSY flag and disable then rather than to rely on a new TX empty interrupt being generated?void spi_handleSPI1Interrupt(void){
uint8_t c; if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == SET) { c = SPI_I2S_ReceiveData(SPI1); if(c == READ_FLAG) { spiTxCounter = 0;SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE); // enable txe
} ... } else if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == SET) { if((spiTxCounter < txBufLen) && (spiTxCounter < TX_BUFFER_SIZE)){ SPI_I2S_SendData(SPI1, spiDataBuffer[spiTxCounter]); spiTxCounter++; } else { SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, DISABLE); // disable txe GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET); // reset data available line dataBusyFlag = 0; // open tx buffer for new data } } } Kind Regards, Bernd2013-09-20 09:51 AM
Your assumption with the IF/THEN/ELSE that the TXE and RXNE are mutually exclusive is problematic. What happens when both are asserted, and how does that interfere with your logic/sequencing?
2013-09-21 09:38 PM
From the logic I could remove the else. And I agree that a set RXNE-flag would be an issue as it would disable the interrupt without also performing the required other logic.
But it raises two new question: 1) there is nothing that should set the RXNE-flag as the transfer stopped after X bytes and the receive buffer should be empty. Why would the flag be set? 2) Aren't always both RX and TX interrupts fired (if enabled) so that the interrupt handler is called twice if data is received and the tx buffer is empty? I want to make sure that the received byte is read from SPIx->DR before overwriting it with the new tx byte. Regards, Bernd