2015-06-04 02:53 AM
Hi,
I am using the STM32F407 SPI TXE and RXNE interrupts. The ISR checks if there is data to transmit or if any data is received. The data to be transmitted is filled outside the ISR and the TXE interrupt and CS is enabled here. If there is no data to be transmitted, the TXE interrupt is disabled and CS is held low. But, after the last data is transmitted, the TXE flag still remains HIGH and the execution keeps reentering the ISR over and over. Furthermore, the RXNE flag is never SET. So no data is received. I watched the DR register and data seems to be clocked out.2015-06-04 04:39 AM
> But, after the last data is transmitted, the TXE flag still remains HIGH and the execution keeps reentering the ISR over and over.
That's how it's supposed to work - it is an indicator of tx (holding) register empty. Disable the interrupt after last byte. > Furthermore, the RXNE flag is never SET. So no data is received. Don't look at it in the debugger. JW2015-06-04 04:55 AM
Hi Jan,
Thank you for replying. I didn't understand the second part > Don't look at it in the debugger. Here's my interrupt routine:- void SPI2_IRQHandler(void) { if(SPI_I2S_GetITStatus(My_SPI, SPI_I2S_IT_TXE) == SET) { if(TxDiffPtr > 0) { SPI_I2S_SendData(My_SPI, gu8a_Tx[TxRdPtr]); TxRdPtr++; TxDiffPtr--; if(TxRdPtr >= TX_RX_SIZE) { TxRdPtr = 0; } } else { SPI_I2S_ITConfig(My_SPI, SPI_I2S_IT_TXE, DISABLE); } } if(SPI_I2S_GetITStatus(My_SPI, SPI_I2S_IT_RXNE) == SET) { gu8a_Rx[RxWrPtr] = SPI_I2S_ReceiveData(My_SPI); RxWrPtr++; RxDiffPtr++; if(RxWrPtr >= TX_RX_SIZE) { RxWrPtr = 0; } SPI_I2S_ITConfig(My_SPI, SPI_I2S_IT_RXNE, DISABLE); } }2015-06-05 04:26 AM
and the routines to send data to the slave and read data from it...
For sending data:- CS_LOW(); //Slave enabled for (int i = 0; i < length; i++) { gu8a_Tx[TxWrPtr] = data[i]; TxWrPtr++; TxDiffPtr++; if(TxWrPtr >= TX_RX_SIZE) { TxWrPtr = 0; } } For receiving data:- CS_LOW(); for (int j = 0; j < length; j++) { if(RxDiffPtr > 0) { data[j] = gu8a_Rx[RxRdPtr]; RxRdPtr++; RxDiffPtr--; if(RxRdPtr >= TX_RX_SIZE) { RxRdPtr = 0; } } } I get the interrupts, but no communication though. Regards, Abhishek.2015-06-05 09:07 AM
I didn't understand the second part > Don't look at it in the debugger.
The debugger will change the behaviour of the peripheral if you park a register view over it. So DON'T do that, because it's invasive.Check also that you are using volatile keyword for variables changed under interrupt, and the wisdom of using non-atomic operations to manage content.
2015-06-05 09:53 PM
Hi Clive,
Thank you very much for replying. I declared the variables used in interrupt as volatile. I probed the SPI clock when SPI_I2S_SendData(My_SPI, gu8a_Tx[TxRdPtr]); is called from interrupt, and clock is generated. In order to keep record of read, write and difference pointers, i am using for loop(atomic operation of copying byte one-by-one into buffer) rather than non-atomic operation(memcpy), if that is what you meant. To summarize upto now, i get the TXE interrupts, and spi clock is generated when data is transmitted to the slave. But still unable to receive any data. So i suppose that actually the slave is not receiving any data at all. Regards, Abhishek.