SPI issue - 18LF4550, first bit being ignored.

Status
Not open for further replies.

toodles

New Member
I have a 4550 setup for SPI slave mode. The system it's connected to (Playstation) has a Slave Select type line, but the slave mode I selected ignores the SS line; I've been watching it manually.

The clock line is at rest high, and drops low eight times per byte, like so:
----__--__--__--__-- __--__--__--__----------
There is 20us from the time the Slave Select style line goes low until the first drop of the clock, and the clock does not move if the Slave Select line is high.
The first byte sent from the console is 10000000; first bit high, rest are low. The transmission looks like this:
----__--__--__--__-- __--__--__--__----------
--------__________________________________
The slave select line goes down for the duration of the transmission. With the oscope set to trigger on the falling edge of the slave select line, the transmission looks like this:
-_____________________________________------------
----__--__--__--__-- __--__--__--__------------------
--------_______________________________------------
From seeing the number of clock drops (8) and when the console changes the output (falling edge of clock), I know the SPI should be reading the bit on the rising edge, and changing the output on falling edge.
This matches figure 19-5 in the datasheet, using SMP=0, CKE=0, and CKP=1, and SPI mode 0101 (slave mode, ignore slave select pin). The setup of the SPI module is done in C18 with SSPSTAT=0x00; SSPCON1=0x35;

I have the PIC waiting for the slave select line to drop, then opening the SPI module, writing the byte to be transmitted to SSPBUF (sending out the last byte read in, unless it is 0, then sending out 0x99 instead), waiting for the BF flag, saving the byte read, and closing the SPI module. That's it.

Since the last byte read is always for some reason 0x00, I am always sending out 0x99, which helps me see when the shift register is doing stuff. Frankly, the outgoing byte is PERFECT. But for some reason, the byte being read is always read as 0x00, as if the first bit is being ignored, or an additional bit is being read in shifting out the first.

The code is posted below, and is very simple. If anyone can help me spot where I'm making the mistake, I would serious love to hear it.

The pattern I see on my oscope including the outgoing 0x99, is below. Sorry for the ASCII art, but digital images of my oscope done seem to work too well.
Code:
-_____________________________________------------  Slave Select line
----__--__--__--__-- __--__--__--__------------------  clock
--------_______________________________------------ data in to PIC
--------________---------________-------------------- data out from PIC
PSX header file
Code:
  #ifndef PSX_H
#define PSX_H

#define PSX_ATT PORTAbits.RA5
#define PSX_CLOCK PORTBbits.RB1

	//OpenSPI(SLV_SSON, MODE_10, SMPMID);
	/* Okay, so using the OpenSPI function just aint cutting it. Tryng to manually start the SPI module 
	 SSPSTAT =0x00;
	 	7 - Sample bit - off. 'must be cleared when SPI is used in Slave mode'
	 	6 - CKE - off. Datasheet figure 19-5, CKP=1, CKE=0 matches what we want.
	 	5-0 - read only
	  SSPCON1 = 0x35;
	  	7 - WCOL - Clear to be safe
	  	6 - Receive overflow - clear to be safe
	  	5 - SSPEN - on, main enable bit
	  	4 - CKP - on (we want CKP=1, CKE=0)
	  	3-0 - Port mode select bits
	  		0100 and 0101 are the only slave modes. 0100 has the SPI
	  		module control the SlaveSelect line. *WE* want to control 
	  		that, so use mode 0101.
	*/
#define PSX_OPENSPI { SSPSTAT =0x00; SSPCON1 = 0x35; }
#define PSX_CLOSESPI { SSPCON1 &= 0b11011111; }

// Prototypes
void PSX_Init_Pins(void);
void PSX_DIG_main (void);

#endif //PSX_H

PSX C file
Code:
   #include <p18cxxx.h>
#include "psx.h"
#include "upcb.h"
#include <spi.h>
#include <delays.h>

void PSX_DIG_main (void)
{
	unsigned char holder;
	PSX_Init_Pins();
	SSPBUF=0xFF;
	PSX_OPENSPI;
	mLED_1_Off();
	mLED_2_Off();
	while(1)
	{	
		PSX_CLOSESPI; //shutdown the SPI module
		while(PSX_ATT); //sit and sping until the slave select line is low
		PSX_OPENSPI; //start up the SPI module
		if (holder == 0)  //send out the last byte read unless is was 0
		{	SSPBUF= 0x99; } //if it was zero, send 0x99 instead.
		else
			{SSPBUF = holder;}
		
		while ((!SSPSTATbits.BF) && (!PSX_ATT)); 	// wait for a read cycle to complete
                //was afraid there was a delay from the tiem the BF flag went high, and the SSPBUFF was updated from
                //the SSPSR, so added a delay of four instructions before reading the SSPBUF.
		_asm
			nop
			nop
			nop
			nop
		_endasm
		holder=SSPBUF;  //stash the byte read, and repeat.
	}	
}//PSX_main()

void PSX_Init_Pins(void)
{
	TRISAbits.TRISA5=1; //SS line - input
	TRISCbits.TRISC7=0; //SDO - output
	TRISBbits.TRISB1=1; //Clock - input
   	TRISBbits.TRISB0=1; //SDI - input
   	TRISCbits.TRISC6=0; //Line we're using for Ack
}
 
Last edited:
whether one more clock cycle is needed to be there, if I remember, as once detailed on this very site, by some expert member?
 
Are you saying I need to change:
_asm
nop
nop
nop
nop
_endasm
to
_asm
nop
nop
nop
nop
nop
_endasm
?
 
Are you saying I need to change:
_asm
nop
nop
nop
nop
_endasm
to
_asm
nop
nop
nop
nop
nop
_endasm
?
I am in fact searching for the link, to to be able to link to you. it was discussed on this forum, around 4 months back.
 
I had a simple doubt again. In the PSX C code you named some other chip --
#include <p18cxxx.h>
 
from p18cxxx.h:

#elif defined(__18F4550)
#include <p18f4550.h>

it includes the proper header based on the defined PIC.
 
Looking at the clock on the oscope, the clock is high when at rest, the outputs change on the falling edge of the clock, and they are read on the rising edge of the clock. Based on the waveform on pg 200 (pg 202 in the pdf) of the 4550 datasheet, that matches CKP=1, CKE=0. The description of the CKP bit from the datasheet:

Am I misinterpreting something somewhere? I'll give it a try in a bit, but I don't see any other combination that has it at rest high, with the set and reads at the needed transitions.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…