I had a working circuit with Wiznet W5100, but to get better performance I switched over to Wiznet W5200 (in Wiz820io module:http://www.kynix.com/Parts/39165/WIZ820IO.html). This involved rewiring the pins, changing the register address and also the Read/Write code for the ethernet module as this chip supports Burst Write.
However (this has me totally stumped), when I power on the circuit and read the registers that I have just written to (GATEWAY, IP etc), all I get is 0x00.
This is what I got using logic analyzer
The MISO line is just flat. No data being sent back to the master.
These are my read/write routines for the Ethernet module :
//OP CODES (TO BE OR'ED WITH UPPER 7 BITS OF ADDRESS)
#define W5200_WRITE 0x80
#define W5200_READ 0x00
//BURST WRITING FOR W5200. FOR DATA LENGTH = 1, DEFAULTS TO BYTE WRITE
void ETHERNET_WRITE(uint16_t address, uint8_t *data, uint16_t len)
{
W5200_SS_LOW; //SET W5200 SS LOW
SPI_TXRX((address & 0xFF00)>>8); //WRITE HIGH BYTE OF 2 BYTE ADDRESS
while(SPI_DATA_RECEIVED==0);
SPI_TXRX((address & 0x00FF)); //WRITE LOW BYTE OF 2 BYTE ADDRESS
while(SPI_DATA_RECEIVED==0);
SPI_TXRX(W5200_WRITE | ((len & 0x7F00)>>8)); //WRITE OPCODE | DATA LENGTH (UPPER 7 BITS)
while(SPI_DATA_RECEIVED==0);
SPI_TXRX(len & 0x00FF); //DATA LENGTH (LOWER 8 BITS)
while(SPI_DATA_RECEIVED==0);
for(uint16_t i=0; i<len; i++)
{
SPI_TXRX(data[i]); //WRITE DATA
while(SPI_DATA_RECEIVED==0);
}
W5200_SS_HIGH; //TURN BACK SS HIGH
}
//BURST READING FOR W5200. FOR DATA LENGTH = 1, DEFAULTS TO BYTE READ
void ETHERNET_READ(uint16_t address, uint8_t len, uint8_t* retval)
{
W5200_SS_LOW; //SET W5200 SS LOW
SPI_TXRX((address & 0xFF00)>>8); //WRITE HIGH BYTE OF 2 BYTE ADDRESS
while(SPI_DATA_RECEIVED==0);
SPI_TXRX(address & 0x00FF); //WRITE LOW BYTE OF 2 BYTE ADDRESS
while(SPI_DATA_RECEIVED==0);
SPI_TXRX(W5200_READ | ((len & 0x7F00)>>8)); //READ OPCODE | DATA LENGTH (UPPER 7 BITS)
while(SPI_DATA_RECEIVED==0);
SPI_TXRX(len & 0x00FF); //DATA LENGTH (LOWER 8 BITS)
while(SPI_DATA_RECEIVED==0);
for(uint8_t i=0; i<len; i++)
{
SPI_TXRX(0x00); //WRITE DUMMY DATA TO READ DATA
while(SPI_DATA_RECEIVED==0);
retval[i] = SPI_RX_DATA;
}
W5200_SS_HIGH; //SET SS HIGH
}
Initially I was powering this module using LM2950 33, but since it’s max current output is 100mA, I moved over to LM317 adjustable LDO that is now powering the module with 3.14V
This is my ethernet intialization code
void ETHERNET_INIT(uint16_t ip_address, uint16_t subnet_address, uint16_t gateway_address, uint16_t mac)
{
uint8_t val[6];
uint8_t retval[6];
uint8_t i;
W5200_RESET_LOW;
_delay_us(50);
W5200_RESET_HIGH;
for(i=0;i<20; i++)
{
_delay_ms(20);
}
val[0] = MR_RST;
ETHERNET_WRITE(MR, val,1);
ETHERNET_READ(MR, 1, retval);
while(retval[0] !=0) {ETHERNET_READ(MR, 1, retval);}
printf("*** Ethernet ****\r");
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(MR, 1, retval);
printf("Reading MR : %u\r", retval[0]);
//}
//set IP Address
EEPROM_READ(ip_address, 4, retval);
ETHERNET_WRITE(SIPR, retval, 4);
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(SIPR, 4, retval);
printf("IP Address : %u.%u.%u.%u\r",retval[0],retval[1],retval[2],retval[3]);
//}
//set subnet mask
EEPROM_READ(subnet_address, 4, retval);
ETHERNET_WRITE(SUBR, retval, 4);
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(SUBR, 4, retval);
printf("Subnet Mask : %u.%u.%u.%u\r",retval[0],retval[1],retval[2],retval[3]);
//}
//set gateway address
EEPROM_READ(gateway_address, 4, retval);
ETHERNET_WRITE(GWR, retval, 4);
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(GWR, 4, retval);
printf("Gateway ip Address : %u.%u.%u.%u\r",retval[0],retval[1],retval[2],retval[3]);
//}
//set mac address
EEPROM_READ(mac, 6, retval);
ETHERNET_WRITE(SHAR, retval, 6);
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(SHAR, 6, retval);
printf("mac Address : %02X.%02X.%02X.%02X.%02X.%02X\r",retval[0],retval[1],retval[2],retval[3],retval[4],retval[5]);
//}
//set interrupt high time
val[0] = 1;
ETHERNET_WRITE(INTLEVEL, val, 1);
//set TX and RX memory to 2KB per socket
//val[0] = 0x55;
//ETHERNET_WRITE(RMSR, val, 1);
//ETHERNET_WRITE(TMSR, val, 1);
//set TX = 8Kb RX = 8Kb for Sock 0 & Sock 1
val[0] = 0x08;
ETHERNET_WRITE(SOCKET_0_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_0_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_1_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_1_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
val[0] = 0x00;
ETHERNET_WRITE(SOCKET_2_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_2_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_3_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_3_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_4_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_4_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_5_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_5_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_6_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_6_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_7_REGISTER_BASE + SN_RX_MEMSIZE, val, 1);
ETHERNET_WRITE(SOCKET_7_REGISTER_BASE + SN_TX_MEMSIZE, val, 1);
//set RTR - retry time value register for timeout @ 2000us
val[0] = 0x07;
val[1] = 0xD0;
ETHERNET_WRITE(RTR, val, 2);
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(RTR, 2, retval);
printf("rtr : %x:%x\r", retval[0], retval[1]);
//}
//set RCR - max retry count to 8
val[0] = 0x08;
ETHERNET_WRITE(RCR, val, 1);
//if(ETHERNET_DEBUG)
//{
ETHERNET_READ(RCR, 1, retval);
printf("rcr : %u\r", retval[0]);
//}
//enable mask for socket 1 interrupt
val[0] = IMR_S1_INT;
ETHERNET_WRITE(IMR, val, 1);
if(ETHERNET_DEBUG)
{
ETHERNET_READ(IMR, 1, retval);
printf("IMR : 0x%x\r",retval[0]);
}
}
Any ideas?