Initial SPI communication problem

Hi,
I am having problem in SPI communication with W5500 chip in Wiz550io Ethernet module.
First of all i am just checking SPI communication between PIC18F4550 and W5500. First I reset it by accessing RSTn pin by microcontoller (Hardware reset). Then i try to read default ip address ie. 192.168.1.2 at position 0x000F-0x0012 using SPI. following is the sequence of bytes i send using SPI

chip select = low

0x0F address high byte
0x00 address low byte
0x00 control phase
0x00 dummy byte
read SSPBUF
0x00 dummy byte
read SSPBUF
0x00 dummy byte
read SSPBUF
0x00 dummy byte
read SSPBUF

chip select = high

while sending each byte i am reading the value of SSPBUF as well as i am waiting for that byte to transmit completely.

Master is configured so that its SPI clock ideal state is HIGH. It puts data on MOSI pin at falling edge. Also master samples the data in the middle of data output time (ie. at rising edge) .
W5500 operates in SPI mode 0 or 3. It puts data on MISO at falling edge and samples data at rising edge.I am getting some data.I got correct data only one time.

sometimes the data is shifted. MSB of the next byte goes into the LSB of the previous byte as clear from the following data

ip address = 192.168.01.2= C0.A8.01.02
data A: 03.C0.A8.01.02 ----- one attempt
data B: 07.81.50.02.04 ----- next attempt

we can see B>>1 = 03.C0.A8.01.02

I tried SPI in every mode. Also data got in every attempt is different ( ie. if we try to read the same registers again the received values will be different.)
these values are sometimes shifted.

i dont know the reason why this is happening. i suppose that this is related to the timing of SPI. i have checked and put SPI in the appropriate mode as mentioned above. but no effect.

code:


#include <p18f4550.h>
#include <usart.h>
#include <spi.h>
#include <delays.h>

// Delay function 
void delay_ms (unsigned int time)
{
        unsigned int i, j;
        for (i = 0; i < time; i++)
                for (j = 0; j < 710; j++);
}

void main(void);

	char a1,a2,a3,a4,a5,a6,a7;
	char control_phase_byte;
	char addr;

	ADCON0 = 0x3C; // Disabling the ADC module which is multiplexed with SPI pins
	ADCON1 = 0x0F; // Disabling the ADC module which is multiplexed with SPI pins
	CMCON = 0x00; // Disabling the COMPARATOR module which is multiplexed with SPI pins
	SPPCON = 0x00; // Disabling the SERIAL PERIPHERAL CONTROL module which is multiplexed with SPI pins
 
	TRISCbits.RC2 = 0;	// used as SS pin 
	TRISCbits.RC7 = 0;	//SDO MOSI
	TRISBbits.RB1 = 0;	//SCK	
	TRISBbits.RB0 = 1;	//SDI  MISO is configured as input 

	TRISBbits.RB2 = 0;
	TRISBbits.RB3 = 0;
	TRISBbits.RB5 = 0;

	PORTBbits.RB2=0; 
	PORTBbits.RB3=0;
	SPI_CS = 1;			// this is SS (chip select pin) 

	PORTBbits.RB5=1;    // RB5 is connected to RSTn of Wiz550io
	delay_ms(300);
	PORTBbits.RB5=0;
	delay_ms(5);
	PORTBbits.RB5=1;
	delay_ms(1500);
	

	OpenSPI(SPI_FOSC_64, MODE_11, SMPMID); // (master mode,clock=FOSC/64), Idle state for clock is a high level,
//	Transmit occurs on transition from Idle to active clock state,Input data sampled at middle of data output time

	
	control_phase_byte=0x00;
	addr=0x000F;		// address of SIPR (Source IP Address Register) [R/W] [0x000F – 0x0012] [0x00]
						// this is VDM mode
	SPI_CS = 0;
	WriteSPI((addr>>8) & 0x00FF);
	a1=SSPBUF;
	WriteSPI(addr & 0x00FF);
	a2=SSPBUF;
	WriteSPI(control_phase_byte);
	a3=SSPBUF;
	WriteSPI(0x00);			// dummy byte
	a4=SSPBUF;
	WriteSPI(0x00);			// dummy byte
	a5=SSPBUF;
	WriteSPI(0x00);			// dummy byte
	a6=SSPBUF;
	WriteSPI(0x00);			// dummy byte
	a7=SSPBUF;

	SPI_CS = 1;

// this "program_single_byte()" is just for observing value of SSPBUF
// This function writes 8 bit data specified by variable modified_byte_value at a specified memory location.

	modified_byte_value = a1;
	program_single_byte(0x05, 0x00, 0x05, 0x05, 0x00, 0x40, 0x00);
	modified_byte_value = a2;
	program_single_byte(0x05, 0x00, 0x05, 0x06, 0x00, 0x40, 0x00);
	modified_byte_value = a3;
	program_single_byte(0x05, 0x00, 0x05, 0x07, 0x00, 0x40, 0x00);
	modified_byte_value = a4;
	program_single_byte(0x05, 0x00, 0x05, 0x08, 0x00, 0x40, 0x00);
	modified_byte_value = a5;
	program_single_byte(0x05, 0x00, 0x05, 0x09, 0x00, 0x40, 0x00);
	modified_byte_value = a6;
	program_single_byte(0x05, 0x00, 0x05, 0x0A, 0x00, 0x40, 0x00);
	modified_byte_value = a7;
	program_single_byte(0x05, 0x00, 0x05, 0x0B, 0x00, 0x40, 0x00);

	PORTBbits.RB2 = ~PORTBbits.RB2 ;
	while (1){}
}	

Hello ashrpat,

[quote=“ashrpat”]
Master is configured so that its SPI clock ideal state is HIGH. It puts data on MOSI pin at falling edge. Also master samples the data in the middle of data output time (ie. at rising edge) .
W5500 operates in SPI mode 0 or 3. It puts data on MISO at falling edge and samples data at rising edge.I am getting some data.I got correct data only one time. [/quote]

I initially had my same problem and the only possible configuration to achieve a speed of OscDiv4 (40MHz xtal) is as follows:

Clock: spiIdleLow, spiRisingEdge
Sample: spiSampleEnd

While the initialization sequence that I have used is the following:

    Output(SCS_PIN)     
    Output(RST_PIN)
    Low(RST_PIN) 
    High(SCS_PIN)
    High(RST_PIN) 
    SPI.SetAsMaster(spiOscDiv4)        
    SPI.SetClock(spiIdleLow, spiRisingEdge)
    SPI.SetSample(spiSampleEnd)
    SPI.EnableSPI() 
    DelayUS(500)
    High(RST_PIN)          
    DelayMS(1000)

Unfortunately not development directly in assembler, I develop with Swordfish and Firewing compilers and assembler generated is quite cryptic but in both cases with their standard SPI libraries this approach works.
If you are able to read the source library BASIC you find it here:
[url]http://www.firewing.info/pmwiki.php?n=FirewingUser.W5500[/url]
Source file driver for the SPI is in “W5500-Regs.bas”

… I hope you can take advantage of it.

Thanks for the reply. i am trying use Wiz550io without using any library. can you please clarify the following?
should SPI be configured in different mode for write and read? I am not getting proper data in writing and reading using same SPI mode. Wiznet has frequency of 25MHz. At what oscillator frequency should master operate?

With any PIC SPI interface (both PIC18, PIC24) the most important thing is setting the SPI :

Clock: spiIdleLow, spiRisingEdge
Sample: spiSampleEnd

and the source that you posted does not seem that you have done so.
ONLY IN THIS WAY I could synchronize myself properly with the data read from this module.

The PIC24 version works clocked at 80MHz
The PIC18 version works clocked at 10MHz with PLL enabled (40MHz)

In both cases the SPI works with a frequency divided by 4.

The device that I used as the PIC18 is the PIC18F2682.

However to write BASIC libraries for this device I left from the examples in C ++ that you can find in the WIZNET site where you downloaded the datasheet. In the examples of DHCP and DNS, even if they uses only UDP, there are all the necessary functions to initialize and read through SPI including the protocol (SW/HW) for reading and writing in the W5500 registers.

Hi,

I think you are wrong at address phase.
If you want to read data at 0x000F, write 00 first and then 0f.
First 8bit is MSB and last 8bit is LSB.

Try to change your code.