SPI, Unable to Clear SPRF in Simulator

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

SPI, Unable to Clear SPRF in Simulator

2,520 Views
krump
Contributor I
Using the 68HC908JW32 with CodeWarrior full chip simulation debugger, after successfully sending data out with the SPI module, I am unable to clear the bit for the receiver full SPRF in the SPSCR register.  I read the Status and Control Register and the Data Register as directed by the data sheet, but the bit won't go away.
 
Code:
  while (SPSCR_SPTE==0);  //Wait for SPI transmit data register to empty  SPDR = DataOut;         //Send data to be written  while (SPSCR_SPRF==0);  //Wait for SPI receive data  SPSCR;                  //Clear SPRF per data sheet  SPDR;                   // by reading SPSCR and SPDR

 
I have also tried multiple reads of the SPSCR and SPDR and looping while waiting for the bit to clear.
Please pardon my C; I was raised on assembly language.
 
Any assistance would be greatly appreciated!
Labels (1)
0 Kudos
10 Replies

614 Views
krump
Contributor I
Eureka!
Copied my code to a new project using the 68HC908GR16.
The SPRF clears properly in the simulator.
For some reason it doesn't clear with the 68HC908JW32.
 
Thanks again for your feedback!
 
-krump
 
0 Kudos

614 Views
peg
Senior Contributor IV
Hi,
 
I confirm that the JW simulator IS broken in CW5.0 and 5.1 in regard to reading SPI data register does not clear SPRF.
I do not see what bigmac has mentioned!
Doing EXACTLY the same test with GP32 and S08GB, the simulator works as expected.
 
0 Kudos

614 Views
krump
Contributor I
Thanks for the responses from all!
I've tried the suggestions and the bit still won't clear.
From the disassembly, it appears as though the SPSCR and SPDR are being read:
Code:
   55:   unsigned char DataOut;   56:      57:   while (SPSCR_SPTE==0);  //Wait for SPI transmit data register to empty  000b 0700fd   [5]             BRCLR 3,_SPSCR,LB ;abs = 000b   58:   SPDR = DataOut;   //Send data to be written  000e 95       [2]             TSX     000f e602     [3]             LDA   2,X  0011 b700     [3]             STA   _SPDR  0013          [5]     L13:       59:    while (SPSCR_SPRF==0);  //Wait for SPI receive data  0013 0f00fd   [5]             BRCLR 7,_SPSCR,L13 ;abs = 0013   60:   SPSCR;  0016 b600     [3]             LDA   _SPSCR   61:   SPDR;  0018 b600     [3]             LDA   _SPDR

 
I'll keep plugging at this one.
Thanks again!
0 Kudos

614 Views
bigmac
Specialist III
Hello,
 
At the present time, the most that can be said is that a problem exists during simulation of the SPI.  I would think that, when the code is tested using the real hardware, there would not be a flag clearing problem.
 
Regards,
Mac
 
0 Kudos

614 Views
bigmac
Specialist III
Hello and welcome to the forum.
 
To read SPDR, I would suggest you do either of the following -
Assign the value of SPDR to a byte variable
temp = SPDR;
 
or return the value of SPDR on exit from a function
return SPDR;
 
Note that SPSCR is read within the following line, so nothing further is necessary -
while (SPSCR_SPRF==0);
 
A SPI function might be as follows -
 
byte SPI_trans(byte DataOut)
{
  while (SPSCR_SPTE==0);  // Wait for transmit data register empty
  SPDR = DataOut;         // Send byte value
  while (SPSCR_SPRF==0);  // Wait for SPI receive flag
  return SPDR;            // Return received value
}
 
Regards,
Mac
 
0 Kudos

614 Views
rocco
Senior Contributor II
Hi Krump,

Just to expand on Mac's suggestion, I believe your code:

SPSCR;
SPDR;

is valid C code, and should read the designated registers. However, the optimizations in the CodeWarrior compiler are probably removing the resulting code, as the results are not used. Mac's code forces the compiler to treat the register reads as necessary, and prevents them from being optimized out.

It might be interesting to look at the final code in the debugger.
0 Kudos

614 Views
CompilerGuru
NXP Employee
NXP Employee
The compiler is not throwing away accesses to volatile registers. So if the registers are correctly declared as volatile as in the delivered header file MC68HC908JW32.h, then the compiler does translate them even if the values are not used.

Daniel



Code:
    4:  unsigned char DataOut;    5:  void code() {Function: code  0000          [5]     L0:         6:      7:    while (SPSCR_SPTE==0);  //Wait for SPI transmit data register to empty  0000 0700fd   [5]             BRCLR 3,_SPSCR,L0 ;abs = 0000    8:    SPDR = DataOut;         //Send data to be written  0003 c60000   [4]             LDA   DataOut  0006 b700     [3]             STA   _SPDR  0008          [5]     L8:         9:    while (SPSCR_SPRF==0);  //Wait for SPI receive data  0008 0f00fd   [5]             BRCLR 7,_SPSCR,L8 ;abs = 0008   10:    SPSCR;                  //Clear SPRF per data sheet  000b b600     [3]             LDA   _SPSCR   11:    SPDR;                   // by reading SPSCR and SPDR  000d b600     [3]             LDA   _SPDR   12:       13:  }  000f 81       [4]             RTS  

 
0 Kudos

614 Views
rocco
Senior Contributor II
Oops. Your right.

Thanks for the correction, Daniel, and for the assembly code.

Krump, Daniel's compiled code looks like it should be clearing the receiver-full bit. Can you generate the assembler code from your project and see if it looks the same?
0 Kudos

614 Views
peg
Senior Contributor IV
Hi,
 
Knowing, and having been reminded of, the above, it seems that the best way to code this is like the OP krump has done. This immediately lets the reader know that this is just being done "because it has to be" rather than because the returned value is required or it is being transferred into another variable for use elsewhere.
 
Having said that it would appear the only explanation for it not working is that the read has been optimised away, perhaps because it has not been declared as volatile. Further optimisations perhaps? (not a compiler expert here).
 
0 Kudos

614 Views
bigmac
Specialist III
Hello,
 
I tried the above code, using CW08 V5.0, under full chip simulation for the JW32.  In my case, the SPRF flag never became set whilst within the wait loop (COP timeout eventually occurred within the loop).  This is the opposite problem to that described above.
 
It is possible that the debugger itself is clearing the flag, by monitoring the state of SPSCR and SPDAT.  On the other hand, it may be a limitation or bug within the full chip simulator.
 
I wonder if this issue might be dependent on the version of CW?
 
Regards,
Mac
 
0 Kudos