2011-12-09 11:57 AM
I have a Max3107 UART hooked up via the SPI1 bus on a STM32F103ZG. Currently, I can configure the UART, write data out and receive it. I'm trying to implement trigger interrupts because the UART has a 128 word FIFO and I need to make sure I don't overfill the FIFO when dumping a bunch of data in, but I seem to have run into a problem.
In my configuration I enable the interrupt to be thrown once it reaches ~112 words. The RTOS handles the interrupt but when I go to read the UART to see why the interrupt was thrown, I end up reading an empty SPI data register. I have a logic analyzer hooked up to the SPI bus and I can see the read coming from the STM The kicker is I can also see the UART sending the response in the same transaction as expected, but when I'm reading the SPI data register it says there is nothing there, even though I wait on the SPI status register's RX flag before a read. It almost seems that the RX flag is set before the data is in the register(is this possible). I would think the problem lies somewhere in my ISR code, but before the UART trigger IRQ, I properly handle an interrupt from the UART signaling the crystal has settled. When I read the data register for that interrupt, the data I see on the SPI bus with the logic analyzer is the same data I read out of the data register. This snippet is how I read the SPI register.volatile
CPU_INT16U read_data = 0;
/* Drop slave select low, send data and wait until its sent */
spi_ss_low();
SPI_I2S_SendData(spi_port, write_byte);
while
(SPI_I2S_GetFlagStatus(spi_port, SPI_I2S_FLAG_TXE) == RESET) { }
/* Wait for data to read, read it, then raise the slave select */
while
(SPI_I2S_GetFlagStatus(spi_port, SPI_I2S_FLAG_RXNE) == RESET) { }
read_data = SPI_I2S_ReceiveData(spi_port);
spi_ss_high();
return
read_data;
I'm curious if anyone else has seen this? Any suggestions or pointers are greatly appreciated. Thanks!
2011-12-09 01:32 PM
when I'm reading the SPI data register it says there is nothing there, even though I wait on the SPI status register's RX flag before a read. It almost seems that the RX flag is set before the data is in the register(is this possible).
Well one problem would be that you need to read the data register to clear the RXNE flag, so you need to make sure it is cleared prior to sending out data, otherwise the RXNE will stick high from a previous transfer.2011-12-09 02:02 PM
Do I need clear the flag if I use the write byte read byte every time I communicate with the UART? I thought I had covered that situation by reading right after I write to prevent that from happening but it's very possible I misunderstood that.
I should add that I've found that if I step through the SPI read with a debugger it reads the correct values from the trigger interrupt. That would almost point to a timing issue, but I'm not sure where that issue could be. I can see on the logic analyzer the UART responds perfectly in sync with the SPI clock. I also verified that the signals were clean and transitioned quickly on an analog scope and saw nothing wrong.2011-12-09 02:26 PM
I should add that I've found that if I step through the SPI read with a debugger it reads the correct values from the trigger interrupt. That would almost point to a timing issue, but I'm not sure where that issue could be.
In the fraction of a second it takes for the transfer to complete the data will have been rolled through the data register before you can read the status register, regardless of the state of the RXNE bit previously. Adding aSPI_I2S_ReceiveData(spi_port);
should be innocuous enough, it just reads an STM32 register and nothing will happen on the SPI bus. I should also be easy enough to see the state of RXNE prior to the SendData
2011-12-12 10:27 AM
It looks like the flag still being set was indeed the problem. I didn't realize this at first because I'm still having problems with the RTOS crashing when it switches out of the ISR, but I have at least been able to verify that I'm getting the correct values from the UART over the SPI. Thanks!
2011-12-12 12:57 PM
Just another small update on this issue; it was indeed the RX flag being set. The reason being was after writing a command to enable interrupts on the UART chip, an interrupt was triggered(TX FIFO empty) as one would expect since the chip just started up. The problem was that the interrupt interruped the RTOS before it had a chance to perform the read after the write as shown in the above code.
Thanks for all your help.