2021-10-10 08:13 AM
I am trying to change from using a Timer PWM controlled outgoing bit stream to an SPI controlled outgoing bit stream. It would be very nice to output a 32-bit word in one shot using the 4-byte FIFO at each TXE interrupt, but the RM seems to indicate TXE gets set when the FIFO is HALF empty and not when the FIFO is actually EMPTY (if so, who's stupid idea was that?!!)
If TXE is set when it is empty, I can stuff the fifo with 4-bytes at every interrupt. If TXE is set when the fifo is half-empty, now I have to interrupt twice to stuff the open end of the fifo with 2-bytes AND I have to keep track of which 2-bytes of each 4 I have already put into the fifo making coding that much more complicated.
So before starting to code, I need to know exactly which way TXE is being handled.
Thanks
2021-10-10 12:08 PM
Per the RM, TXE is triggered when the 32-bit TXFIFO is half-full or less.
> if so, who's stupid idea was that?!!)
Triggering before it's empty gives the mcu some time to populate the FIFO before it runs out. At higher clock rates, this can increase throughput.
If you're concerned about efficiency, DMA is a much better option.
2021-10-10 12:13 PM
Actually, looking more into it, the RM says three different things about this. I suspect what I wrote originally is correct, but I didn't check.
The excerpt in the original reply says TXE is triggered when the TXFIFO is less than half full.
This excerpt says TXE is triggered when half-full or less:
This one says it's only cleared when TXFIFO is full:
2021-10-10 12:18 PM
So it has some hysteresis.
Master Tx is synchronous, so the problem can be circumvented simply by ignoring TXE and using a timer.
JW
2021-10-11 04:39 AM
I have already started on the DMA option on the assumption that TXE was set at 1/2.
But for the interrupt option, this turns a 4-byte fifo into a 2-byte fifo. In order to use the full 4-byte fifo in the interrupt routine, I would have to sit, IN AN INTERRUPT ROUTINE, polling to see when the fifo is empty so I could then stuff 4-bytes into the fifo. At 4MHz, that means sitting there doing nothing for 2uS or half of my data transmit time, or in other words loosing half of my processor time that could have been utilized setting up my next buffer of data. And at 216MHz a decent programmer can't get data that should be available already from a variable, array, buffer into the fifo before the shift register finishes transmitting its data?!! (SPI2->DR = spidataupperhalfword; SPI2->DR = spidatalowerhalfword; // not difficult)
As I said before stupid.
This basically turns interrupt driven into polling driven and if I wanted to do that I would do that. Or it makes coding more difficult because I have to keep track of what half of the data is to be stuffed into the fifo. Or processing the data as 16-bit values not 32-bit, half as efficient and more complicated. And I already have to process 2 interrupts instead of 1 to transmit the same amount of data.
I'm doing the DMA option with the added complexity of setting up DMAs and letting the hardware handle this.
2021-10-11 05:44 AM
Eh, it's only polling driven if you sit there and wait for it, which you are choosing to do. It's still a 4-byte FIFO, just takes data 16-bits at a time.
2021-10-11 06:37 AM
Actually, no it isn't if the interrupt happens where 2-bytes still have data in them and only 2-bytes are available for me to put data in. I either wait for it to be fully empty or I treat it as a 2-byte fifo.
2021-10-11 06:56 AM
This would be a kludgy workaround for a bad design. Doing this means having to chain the "TXHE" signal event to start a timer set up to interrupt when it THINKS the SPI fifo is empty. Bad design.
If the designers wanted a TXHE signal then they should have called it that and also put in a true TXE signal.