This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I am using the F28335 SPI to emulate an EEPROM. It works as an slave with words of 8 bits. I have enabled the FIFOs.
My application starts with the RXINT enabled and TXINT disabled, the level of the FIFO for the RXINT is 1 and for the TXINT is zero.
In the picture below the following lines are
D0: #SPISTE
D3: SPICLK (there is a discontinuity every 8 cycles of the SPICLK)
D4: MOSI
D5: SOMI
D14: goes high when SpiRxInt Isr enters and down before leaving the Isr.
D15: toggles every time a byte is copies to the SPITXBUF
1.- The first byte I receive triggers RXINT (fist pulse in D14 from picture below); in the context of the interrupt I parse the command
2.- The second byte I receive triggers the second RXINT (second pulse in D14); in the context of this interrupt:
- I parse the addres
- Copy some bytes into the SPITXBUF (this happens when line D15 toggles)
- disable in RXINT
- enable the TXINT
In my application I know the number of bytes that are going to be read from each address, so I will be waiting from the TXFIFO to be empty in order to copy more bytes into the FIFO
3.- When the TXFIFO gets empty if I have more data to transmit I copy more data into SPITXBUF.
4.- When the TXFIFO gets empty and I have no more data to transmit
- I clear the FIFOs
- Disable the TX INT
- Enable the RX INT.
This is the code that disables the TXINT enables RXINT and clears the flags. I know I am overdoing it, but still I get an extra RXINT when SPISTE - D0 goes high
SpiaRegs.SPICCR.bit.SPISWRESET = 0;
SpiaRegs.SPIFFTX.bit.SPIRST = 0; // Reset the TX & RX Buffers
SpiaRegs.SPIFFTX.bit.SPIRST = 1;
// clear receive FIFO
SpiaRegs.SPIFFRX.bit.RXFIFORESET = 0;
SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;
// Clear the over-run flag.
SpiaRegs.SPISTS.bit.OVERRUN_FLAG = 1;
SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 1; // Clear Overflow flag
SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1; // Clear Interrupt flag
SpiaRegs.SPIFFRX.bit.RXFFIENA = 1; // Enable Rx Interrupt
SpiaRegs.SPIFFTX.bit.TXFIFO = 1; // Enable the FIFO
SpiaRegs.SPICCR.bit.SPISWRESET = 1;
My question is if this is the expected behaviour of RXINT, and I should check that the SPISTE line is not high within the SpiRxIsr.
Can you check which flags are set in the RX ISR when it is generated the last time around? I do not see this last time represented by an IO toggle on your waveform either. From the looks of it, if D14 is in fact toggling every time a byte is being written to SPITXBUF, then it appears that you are writing another byte during your last transmission? Or am I misinterpreting the waveform?
The description of the signals was wrong in the header, note that D14 is the RXINT (I have edited the original post)
...
D14: goes high when SpiRxInt Isr enters and down before leaving the Isr.
D15: toggles every time a byte is copies to the SPITXBUF
.....
I have noticed that when I enter the interrupt for the last time there is data in the SPIRXBUF, only when I read the data the interrupt flag gets removed.
Why Is it not sufficient reseting the SPI?
My current work around is to check the state of SPISTE signal in the SpiRxIsr, read the SPIRXBUF and ignore the content is SPISTE is high, but I feel like I have an unnecessary context switch in my program.
Manuel,
I think what is happening is you are clearing the FIFO flags and resetting the FIFO, but note that the FIFO is not a requirement for SPI operation. The SPI itself does not have a true reset without resetting the chip. SPIRXBUF is a register that is used in SPI with FIFO and without FIFO. I suspect reading this register will clear the interrupt flags from both modes. In fact, the interrupt may only be triggered because you are doing a FIFO reset while the flag is set (hence possibly - not sure about this - momentarily disabling the FIFO). I'd be interested to know what you find out if you experiment with this some. Just for clarity, I am referring to the interrupt flags in SPISTS (looks like it is SPIST in the doc.. missing the final S).
We should be able to get it working properly without checking the SPISTE signal. Let's not waste the MIPS :)
**EDIT - I lied. The SPI does have a SW reset using SPICCR.7. The SPI INT flag in SPISTS does not have a clear bit- it can ONLY be cleared by reading the SPIRXBUF, using this SPI reset, or resetting the device.
Kris,
Thanks for your answer.
I think I have a reasonable theory about what is happening; the graphic in the picture above may help understanding what is going on. I think is it unavoidable to have a SPIRXINT at the end of my Transmit cycle with my current implementation.
What I think that happens is the following; let's start from the point when I start writing data into the SPITXBUF (first set of pulses in D15); at this point I am writing 16 bytes into the FIFO (and I have disabled SPIRXINT),
If we look at the clock line (D3) you can see that there are 15 bytes transmitted before I get the next SPITXINT interrupt, which will force the loading of the next set of bytes into SPITXBUF. [[[ The key is that the interrupt triggers in byte 15 and not in byte 16 ]]] So in the context of the SpiTxIsr I load my next 4 bytes. And 4 bytes later my SPITXINT will trigger again [[[ Note that in total I have transmitted 19 of my 20 bytes ]]].
In the context of the SpiTxIsr I know that I have nothing else to send, so I disable the SPITXINT, clear the FIFOs, clean all the interrupt flags and enable the SPIRXINT, but there is still one byte pending to be transmitted (not in the FIFO, the byte must have already been loaded into SPIDAT), the SPI will transmit this byte with the last SPI clock group and eventually there will be a new dummy word received in the SPIRXBUF, which the reason why I have another interrupt.
I can not think of a better way of discarding this interrupt but to rad the word to clean the interrupt and clean the RXBUF and check that if SPISTE is high I should discard my buffer. Maybe you can propose a different solution.
Manuel,
I think you lost a figure in your last post.
You are correct, that slipped my mind. When you receive your TX interrupt in FIFO mode, this indicates the TX FIFO buffer is empty, not that transmission is complete just as you said. So if your RX interrupt is still enabled here, you will automatically shift in garbage data during that last transmission cycle and therefore receive the interrupt.
I would use a software variable before I would rely on the STE signal to detect this garbage data. I'm actually surprised it is high already when you receive your last interrupt (it looks like it is very close on the waveform). Depending on your baud rate and interrupt latency, I would not be at all surprised if you received this last interrupt before it goes high, as there is some delay between the time you stop sending data and it is set, but this is device dependent.
Kris