Strange behavior with SPI on S12NE, Codewarrior 5.9

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

Strange behavior with SPI on S12NE, Codewarrior 5.9

Jump to solution
2,199 Views
PatT_
Contributor I

This should be a VERY simple task but for some reason when I send data to SPI, unexpected data shows up on the bus in certain situations.

 

Init routine:

void spiInit(void)  {//TODO: Currently set up as slave, will have to//      change over to master once we're ready  SPICR1=0b01011110;  // No interrupts (yet), enable SPI,                      //   master mode, clock idles high                      //   sample on even (rising) edges                      //   slave select active,                      //   MSB first  SPICR2=0x10; // unidirectional, run in wait mode, use SS  SPIBR=0x24; //260khz for now}

 

SPI writing routine:

void spiWrite(unsigned char x)  {  char junk;    while(!(SPISR_SPTEF));  SPIDR=x;  while(!(SPISR_SPIF));  junk=SPIDR;   // discard the junk byte to clear SPIF  return;}

 

 ...and finally a wrapper to call the above three times with one convenient function:

void spiWriteReg(unsigned char chan, unsigned char addr, unsigned char data)  {  char tempchan;    tempchan=chan&0b00011111;  spiWrite(0b00100000+tempchan);  // byte 1 is binary 001 + last 5 bits of "chan"  spiWrite(addr);  spiWrite(data);  return;}

When I call spiWriteReg(0,5,0) for example, I expect the output to SPI to be hex 20 05 00.

 

Instead, I sometimes get 20 05 1F... or 3F 05 00... I've even seen a 7F xx xx from another function that sends binary 010+chan.  In other words, it seems like the bus goes high and stays there for the remainder of the byte.  This behavior "seems" to change based on stepping through vs going at full speed, but I can't nail down a specific pattern.  It also "seems" to be more likely to happen if the prior byte was odd (ended in a 1).

 

Initially I thought maybe I was running into problems with interference from my SCI ISR, but the problem persisted even with the SCI calls commented out and interrupts disabled.

 

If anyone has any insight PLEASE let me know, I've been banging my head against this on and off for a couple weeks... it seems like the kind of thing where I'm overlooking something really obvious.

 

Thanks!!!

Labels (1)
0 Kudos
Reply
1 Solution
1,944 Views
kef
Specialist I

Just scroll you data window so that SPI addresses are not visible to you.

Are you using SPI from different tasks? From interrupt and non interrupt code?

Even though you have analyser, what if external HW is pulling SPI data high?

View solution in original post

0 Kudos
Reply
7 Replies
1,944 Views
kef
Specialist I

How are you reading what bytes are sent? Unless it is oscilloscope or good analyser, I would suspect external hardware.

 

Didn't you forget to include spiWriteReg() prototype in all files, that have spiWriteReg() calls? Though this can't explain how 7F xx xx could be transferred.

0 Kudos
Reply
1,944 Views
PatT_
Contributor I

If it helps, the relevant disassembly of spiWrite() is:

C1FD PSHBC1FE BRCLR 0xDB,#32,*+0    ;0xDB is SPISRC202 LDAB  0,SPC204 STAB  0xDD                 ;0xDD is SPIDRC206 BRCLR 0xDB,#128,*+0C20A LDAB  0xDDC20C PULAC20D RTS

 

When I break at the top of the function ("while(!(SPISR_SPTEF));") and assembly-step through on the offending byte, I do in fact get the expected 0 out of SPI... but then the program seems to hang at C206 regardless of whether I step forward or attempt to "run."  The value of 0xDB is 0x20.  S, X, I, and Z are set.  This seems to support my notion that something is happening behind the scenes and I'm not clearing or setting something, but at face value it seems like the right things are happening in the code.

0 Kudos
Reply
1,944 Views
kef
Specialist I

Regarding a hang waiting for SPIF. Since reading SPISR, and then reading SPIDR clears SPIF, you should make sure debuggers data windows are not pointed to SPI registers. Else, debugger may update data window and clear SPIF, and as a result your code won't be able to finish your SPI routine.

 

I have no clue what causes bad data transferred, but S12NE is mature part, yet there's no relevant errata published on freescale.com. So I doubt it is some S12NE bug.

0 Kudos
Reply
1,944 Views
PatT_
Contributor I

Ah, that makes sense... is there a simple way to do that in the standard codewarrior debugger?  I closed the memory update window to try to work around it. :smileyhappy:  But why would it work at the C step level if that were the case??

I too looked for errata also and didn't find anything.  It seems like the outputting of a byte on SPI should be handled in hardware, thus not interruptable or disruptable unless you shut off the module mid-byte or something weird.  I just don't know.  The fact that stepping through at the assembler level causes different (correct) output than stepping through at the C level just reinforces my suspicion that something is buggy though.

If it comes down to it, maybe I can look into what's going on from a bus transaction perspective but I'd REALLY REALLY rather not do that unless I had to.  In fact I don't even know if the 80-pin version of the NE has the necessary pins bonded out.  Why can't things just work the simple way. :smileyhappy:

 

0 Kudos
Reply
1,945 Views
kef
Specialist I

Just scroll you data window so that SPI addresses are not visible to you.

Are you using SPI from different tasks? From interrupt and non interrupt code?

Even though you have analyser, what if external HW is pulling SPI data high?

0 Kudos
Reply
1,944 Views
PatT_
Contributor I

You have successfully moved my confusion elsewhere!  Nothing else is attached to MOSI except the other chip.  But when disconnected from the line and just monitoring the uC, indeed the issue seems to go away.  I don't see a pull-up on the schematic, and no configuration can make that pin bidirectional on the slave's side.  But I guess it rules out it being a code and uC issue so I'm "happy" in that sense.

 

I guess the moral of the story is "never take the simple things for granted, no matter how contrary to datasheets, when isolating a fault" !!  (and of course "always make prototype boards modular" which thankfully I did do :smileywink: )

 

Mea culpa. :smileyhappy:  Thanks for the help.

 

0 Kudos
Reply
1,944 Views
PatT_
Contributor I

I am using a logic analyzer to read it off, and have used a scope to be sure it's not a threshold/analog issue fooling the LA.

 

Mostly what I'm looking for is some understanding of the internal goings-on that could cause things to glitch or stick high in the middle of a byte... something I need to read or clear or something like that.  I'm going back through the disassembly to verify exactly what's happening, but the debugger THINKS that the variables are being passed correctly, when I break before returning.

 

The prototype should be getting included everywhere, the SPI functions are in spi.c, which has corresponding spi.h, which does the usual "if it's not defined yet, then here's the file and set a #define" thing.  I don't get any errors or warnings related to that, and I'm not deliberately supressing any.

 

For the sake of full disclosure, the board is my own design, but I copied the layout from one of the app notes, and I've not seen any other indication of hardware-related issues.  I'm using a P&E USB Multilink with the standard debugger.  

 

0 Kudos
Reply