S908GT32A: No SPRF flag on 1st SPI Tx Byte

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S908GT32A: No SPRF flag on 1st SPI Tx Byte

5,113 Views
Wings
Contributor I
On power up I init the SPI (SPE and MSTR set). I store a byte in SPID to send it, and wait until SPRF becomes set. It never does.

When using the Cyclone debugger I can run this same code after a reset and it works fine.

Then I changed the code so that after init I store a byte to the SPID register, then after a short delay (while I do other things) I come back and read the status reg (SPIS) and then the data register (SPID), for the purpose of clearing any SPRF that MAY have become set. After this, SPRF works just fine.

Any clues?
Labels (1)
0 Kudos
7 Replies

576 Views
peg
Senior Contributor IV
Hi Wings,
 
This works for me on a GT16:
 
Code:
********** Setup SPI ********************************************************  MOV #(mSPE|mMSTR|mCPOL),SPIC1 ;set up SPI, now with CPOL=1 for HC165 (5.01)  MOV #(mSPPR2|mSPR0),SPIBR ;set frequency to ~1MHz (999,771kHz)*further down  JSR RDIPSW  ;READ DIP SWITCH SETTING*somewhere elseRDIPSW  BSET DIPSWLD,INTPORT  ;SET HC165 TO SERIAL SHIFT  BRCLR SPTEF,SPIS,*  ;wait for transmit buffer MT  STA SPID   ;PUT DUMMY VALUE IN SPDR TO START XFER  BRCLR SPRF,SPIS,*  ;WAIT TILL DONE  LDA SPID   ;GET CLOCKED IN VALUE

 
If it didn't work I would hang during initialisation.
 
 
 
0 Kudos

576 Views
Wings
Contributor I
;Init SPI port. CPOL=CPHA=0, Master, No interrupts.
           MOV #%01010000,SPIC1
           MOV #%00000000,SPIC2 ;NO SPECIAL FEATURES, SS IS G.P. I/O.
           MOV #(6
           LDA SPIS  ;PRIME THE PUMP (FIXES NO SPRF ON 1ST BYTE).

And later my SPI output routine is called:

SPIOUT     EQU *
           BCLR CS867,PTA ;CMX867 CHIP SELECT LOW.
           BSR SPIDEL ;EXTRA DELAY FOR SETUP TIME.
           STA SPID ;SEND THE DATA.
           BRCLR SPRF,SPIS,* ;WAIT FOR SPRF SET.
           LDA SPID ;RETURN WITH ANY RX DATA.
SPIDEL     RTS

If I remove the "LDA SPIS" line this always hangs waiting for SPRF being set. So it seems the status register must be read before storing to the data register, or the SPI just will not set the SPRF when the data is sent. That "LDA SPIS" line just after init shows that the SPTEF bit is set (in another test I saved it in RAM and examined it later), so I would think that the SPI is ready for a transmit even if the SPIS isn't read first. Guess not.

Best solution (IMHO) is to read the SPIS and wait for SPTEF before sending, as in Peg's code, even though it will always be set.
0 Kudos

576 Views
peg
Senior Contributor IV
Hi,
 
It looks like this strange phenomenon may be perculiar to the GT/GB or newer devices.
I noticed the extra read in my code is commented in lower case whereas all the rest is in uppercase.
This tells me it is very old code and this is added later.
The original code is for HC05C8 then converted to HC08GP32 and then to 9S08GT16.
I went back through the versions and the extra line comes in in the GT conversion.
I must have discovered this like you but have forgotten about it. (The 08GP to S08GT was suprisingly painless)
 
0 Kudos

576 Views
peg
Senior Contributor IV
Hello,
 
This change in the way the SPI operates does not go undocumented!
 
See here:

12.3 Functional Description

An SPI transfer is initiated by checking for the SPI transmit buffer empty flag (SPTEF = 1) and then writing a byte of data to the SPI data register (SPI1D) in the master SPI device. When the SPI shift register is available, this byte of data is moved from the transmit data buffer to the shifter, SPTEF is set to indicate there is room in the buffer to queue another transmit character if desired, and the SPI serial transfer starts.

and here:

SPTEF — SPI Transmit Buffer Empty Flag

This bit is set when there is room in the transmit data buffer. It is cleared by reading SPI1S with SPTEF set, followed by writing a data value to the transmit buffer at SPI1D. SPI1S must be read with SPTEF = 1 before writing data to SPI1D or the SPI1D write will be ignored.

It is also like this in the QG and possibly other newer devices.

 

0 Kudos

576 Views
Wings
Contributor I
Well Peg, now THAT is something I'd call a clue. I missed that even when looking for it. Thanks for pointing it out to me.

(Except in my manual, Functional Description is in section 12.4. Was that a typo?)
0 Kudos

576 Views
bigmac
Specialist III
Hello Wings and Peg,
 
It appears that the additional requirement to explicitly read SPIS register before sending each data byte may have been first introduced for the HCS12, and subsequently found its way to the HCS08 devices.  After examining a number of data sheets, I have not been able to find any HCS08 devices that do not have this requirement.
 
On the other hand, all the HC08 devices seem to allow an immediate write to the data register without testing for the status of the flag.  Of course, if the flag is actually clear, the write would be problematic.
 
Curiously, AN2717 "M68HC08 to HCS08 Transition" does not mention this difference, contrary to a reasonable expectation.  However, this application note also has other problems in its SPI section.  It claims that the receive process is "double buffered" for the HCS08, but is not double buffered for the MC68HC08, for a very similar hardware configuration in both cases.
 
For all writes, other than the first write, the SPIS register has already been read, by virtue of testing the SPIF flag, and the SPTE flag must always be set at this point, provided only a single byte was previously written.  So the additional requirement only becomes an issue after SPI initialisation, as Wings has found.  The "belt and braces" approach is to specifically test the SPTE flag prior to every send, as Peg does.
 
Regards,
Mac
 
0 Kudos

576 Views
bigmac
Specialist III
Hello,
 
This seems a strange one!
 
I can't really offer any explanation.  However, as a matter of curiosity, do you currently set both SPE and MSTR bits of SPI1C1 simultaneously, or as separate operations?  If separate operations, perhaps you could try setting SPE last, just in case this is an artifact of slave mode being enabled prior to master mode being selected.
 
This is just a wild guess.
 
Regards,
Mac
 
0 Kudos