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){}
}