Check if SPI transmission is complete in PIC18.

Thread Starter

roxi60

Joined Sep 2, 2018
73
Hello.
As far as I know, the check if SPI transmission is complete can be made looking at SSPSTAT,BF flag:

Code:
movwf SSPBUF
LOOP
btfss SSPSTAT, BF ;CHECK IF TRANSMISSION IS COMPLETE
goto LOOP
bcf SSPSTAT,BF

or looking at PIR1,SSPIF interrupt flag:
Code:
movwf SSPBUF
LOOP
btfss PIR1, SSPIF ;CHECK IF TRANSMISSION IS COMPLETE
goto LOOP
bcf PIR1,SSPIF

I don’t understand when to use one and when to use the other.
What’s the difference, if any?
I found cases where checking SSPIF, the code works, while checking BF, it doesn’t.

Thanks in advance for any kind explanation.
Regards
 

Thread Starter

roxi60

Joined Sep 2, 2018
73
Thank you Eric.
I already saw a lot of tutorial, but no one explain to me what is the difference, if any ,in using one of the two flags in place of the other.

Thank you again for yor kind answer.
 

ericgibbs

Joined Jan 29, 2010
18,766
hi,
For SPI reception you could keep Polling the BF in a Loop, but I prefer using the IF with a ISR, it is a more efficient way.

Have you tried using an ISR for the SPI reception.?

E
 

jpanhalt

Joined Jan 18, 2008
11,087
It took me awhile to find it, as I am pretty stuck on the 16F series. The first bit of code posted will not work, as SSPSTAT,BF is a read-only bit. It can only be cleared by reading the buffer.

Buffer Full bit, BF (SSPSTAT<0>), indicates when SSPBUF has been loaded with the received data (transmission is complete). When the SSPBUF is read, the BF bit is cleared.
Since you will be reading SSPBUF anyway presumably, that is taken care of. The second bit of code doesn't clear the BF bit. I am not sure whether PIR1,SSPIF needs to be cleared in software or clears automatically. (I didn't check.) It is read/write, so presumably needs to be cleared if you are using interrupts.
 

JohnInTX

Joined Jun 26, 2012
4,787
Also, check the errata for your particular 18F. Many have a bug that can foul polling BF:
40. Module: MSSP
When the MSSP is configured for SPI mode, the
Buffer Full bit, BF (SSPSTAT<0>), should not be
polled in software to determine when the transfer
is complete.
Work around
Copy the SSPSTAT register into a variable and
perform the bit test on the variable. In Example 5,
SSPSTAT is copied into the working register
where the bit test is performed.
EXAMPLE 5:
A second option is to poll the Master Synchronous
Serial Port Interrupt Flag bit, SSPIF (PIR1<3>).
This bit can be polled and will set when the transfer
is complete.
Date Codes that pertain to this issue:
All engineering and production devices.
I can't find the particular citation but it has to do with the PIC not being able to bit test certain addresses ending in C9h or use certain instructions ending in C9h or some such thing. Unfortunately, polling BF was one of the affected areas. Besides the workarounds here, you can also point one of the FSRs to SSPSTAT and to the bit test on INDFx.
Keep in mind that it sometimes takes some time for a bug to be reported in the errata so just because the bug isn't listed in your chip's errata doesn't mean it's not there.

FWIW, if you are the SPI master with a fast clock rate and short messages, you may find that just writing and polling for BF is less load on the system than using the interrupt. The reason is that the byte can transmit in a much shorter time than it takes to save and restore the system context in a typical interrupt routine.
Good luck!
 
Last edited:

Thread Starter

roxi60

Joined Sep 2, 2018
73
Thank you very much, Eric, jpanhalt and JohnInTX!
I think the problem was what jpanhalt said, that I can't clear BF flag.
I replaced that with writing the SSPBUF to a dummy byte (and that clears BF) and it works properly.
Anyway I agree with you that it's better to use SSPIF check.

Thanks again.

Regards
 

jpanhalt

Joined Jan 18, 2008
11,087
Just an FYI in case you ever use a 16F chip. PIR1,SSPIF is likely in Bank0; whereas, SSPSTAT,BF is in Bank4 along with other SPI registers. Thus, checking BF avoids the need for bank changes.
 
Top