/***********************************************************************************
成都浩然电子有限公司
电话:028-86127089,400-998-5300
传真:028-86127039
网址:http://www.hschip.com
编写时间:2014-2-26
***********************************************************************************/
#include <iom64v.h> /* Mega64 库定义 */
#include<macros.h>
#include"W5500.h"
typedef unsigned char SOCKET;
#define true 0xff
#define false 0x00
#define S_RX_SIZE 2048
#define S_TX_SIZE 2048
#define W5500_SCS_H PORTB|=BIT(PB0);
#define W5500_SCS_L PORTB&=~BIT(PB0);
extern void Delay(unsigned int d); /* Delay d*1ms */
/******************************* W5500 Write Operation *******************************/
/* Write W5500 Common Register a byte */
void Write_1_Byte(unsigned int reg, unsigned char dat)
{
/* Set W5500 SCS Low */
W5500_SCS_L
/* Write Address */
SPDR=reg/256; /* Send Register Address */
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM1|RWB_WRITE|COMMON_R);
while((SPSR&0x80)!=0x80);
/* Write 1 byte */
SPDR=dat;
while((SPSR&0x80)!=0x80);
/* Set W5500 SCS High */
W5500_SCS_H
}
/* Write W5500 Common Register 2 bytes */
void Write_2_Byte(unsigned int reg, unsigned char *dat_ptr)
{
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM2|RWB_WRITE|COMMON_R);
while((SPSR&0x80)!=0x80);
/* Write 2 bytes */
SPDR=*dat_ptr++;
while((SPSR&0x80)!=0x80);
SPDR=*dat_ptr;
while((SPSR&0x80)!=0x80);
/* Set W5500 SCS High */
W5500_SCS_H;;
}
/* Write W5500 Common Register n bytes */
void Write_Bytes(unsigned int reg, unsigned char *dat_ptr, unsigned int size)
{
unsigned int i;
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(VDM|RWB_WRITE|COMMON_R);
while((SPSR&0x80)!=0x80);
/* Write n bytes */
for(i=0;i<size;i++)
{
SPDR=*dat_ptr++;
while((SPSR&0x80)!=0x80);
}
/* Set W5500 SCS High */
W5500_SCS_H;
}
/* Write W5500 Socket Register 1 byte */
void Write_SOCK_1_Byte(SOCKET s, unsigned int reg, unsigned char dat)
{
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM1|RWB_WRITE|(s*0x20+0x08));
while((SPSR&0x80)!=0x80);
/* Write 1 byte */
SPDR=dat;
while((SPSR&0x80)!=0x80);
/* Set W5500 SCS High */
W5500_SCS_H;
}
/* Write W5500 Socket Register 2 byte */
void Write_SOCK_2_Byte(SOCKET s, unsigned int reg, unsigned int dat)
{
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM2|RWB_WRITE|(s*0x20+0x08));
while((SPSR&0x80)!=0x80);
/* Write 2 bytes */
SPDR=dat/256;
while((SPSR&0x80)!=0x80);
SPDR=dat;
while((SPSR&0x80)!=0x80);
/* Set W5500 SCS High */
W5500_SCS_H;
}
/* Write W5500 Socket Register 2 byte */
void Write_SOCK_4_Byte(SOCKET s, unsigned int reg, unsigned char *dat_ptr)
{
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM4|RWB_WRITE|(s*0x20+0x08));
while((SPSR&0x80)!=0x80);
/* Write 4 bytes */
SPDR=*dat_ptr++;
while((SPSR&0x80)!=0x80);
SPDR=*dat_ptr++;
while((SPSR&0x80)!=0x80);
SPDR=*dat_ptr++;
while((SPSR&0x80)!=0x80);
SPDR=*dat_ptr;
while((SPSR&0x80)!=0x80);
/* Set W5500 SCS High */
W5500_SCS_H;
}
/******************************* W5500 Read Operation *******************************/
/* Read W5500 Common register 1 Byte */
unsigned char Read_1_Byte(unsigned int reg)
{
unsigned char i;
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM1|RWB_READ|COMMON_R);
while((SPSR&0x80)!=0x80);
/* Write a dummy byte */
SPDR=0x00;
while((SPSR&0x80)!=0x80);
/* Read 1 byte */
i=SPDR;
/* Set W5500 SCS High*/
W5500_SCS_H;
return i;
}
/* Read W5500 Socket register 1 Byte */
unsigned char Read_SOCK_1_Byte(SOCKET s, unsigned int reg)
{
unsigned char i;
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM1|RWB_READ|(s*0x20+0x08));
while((SPSR&0x80)!=0x80);
/* Write a dummy byte */
SPDR=0x00;
while((SPSR&0x80)!=0x80);
/* Read 1 byte */
i=SPDR;
/* Set W5500 SCS High*/
W5500_SCS_H;
return i;
}
/* Read W5500 Socket register 2 Bytes (short) */
unsigned int Read_SOCK_2_Byte(SOCKET s, unsigned int reg)
{
unsigned int i;
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=reg/256;
while((SPSR&0x80)!=0x80);
SPDR=reg;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(FDM2|RWB_READ|(s*0x20+0x08));
while((SPSR&0x80)!=0x80);
/* Write a dummy byte */
SPDR=0x00;
while((SPSR&0x80)!=0x80);
i=SPDR;
i*=256;
SPDR=0x00;
while((SPSR&0x80)!=0x80);
i+=SPDR;
/* Set W5500 SCS High*/
W5500_SCS_H;
return i;
}
/******************** Read data from W5500 Socket data RX Buffer *******************/
unsigned int Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr)
{
unsigned int rx_size;
unsigned int offset, offset1;
unsigned int i;
rx_size=Read_SOCK_2_Byte(s,Sn_RX_RSR);
if(rx_size==0) /* if no data received, return */
return 0;
if(rx_size>1460)
rx_size=1460;
offset=Read_SOCK_2_Byte(s,Sn_RX_RD);
offset1=offset;
offset&=(S_RX_SIZE-1); /* Calculate the real physical address */
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=offset/256;
while((SPSR&0x80)!=0x80);
SPDR=offset;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(VDM|RWB_READ|(s*0x20+0x18)); /* Read variable size */
while((SPSR&0x80)!=0x80);
if((offset+rx_size)<S_RX_SIZE)
{
/* Read Data */
for(i=0;i<rx_size;i++)
{
SPDR=0x00; /* Send a dummy byte */
while((SPSR&0x80)!=0x80);
*dat_ptr++=SPDR;
}
}
else
{
offset=S_RX_SIZE-offset;
for(i=0;i<offset;i++)
{
SPDR=0x00; /* Send a dummy byte */
while((SPSR&0x80)!=0x80);
*dat_ptr++=SPDR;
}
/* Set W5500 SCS High*/
W5500_SCS_H;
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=0x00;
while((SPSR&0x80)!=0x80);
SPDR=0x00;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(VDM|RWB_READ|(s*0x20+0x18)); /* Read variable size */
while((SPSR&0x80)!=0x80);
/* Read Data */
for(;i<rx_size;i++)
{
SPDR=0x00; /* Send a dummy byte */
while((SPSR&0x80)!=0x80);
*dat_ptr++=SPDR;
}
}
/* Set W5500 SCS High*/
W5500_SCS_H;
/* Update offset*/
offset1+=rx_size;
Write_SOCK_2_Byte(s, Sn_RX_RD, offset1);
Write_SOCK_1_Byte(s, Sn_CR, RECV); /* Write RECV Command */
return rx_size;
}
/******************** Write data to W5500 Socket data TX Buffer *******************/
void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned int size)
{
unsigned int offset,offset1;
unsigned int i;
offset=Read_SOCK_2_Byte(s,Sn_TX_WR);
offset1=offset;
offset&=(S_TX_SIZE-1); /* Calculate the real physical address */
/* Set W5500 SCS Low */
W5500_SCS_L;
/* Write Address */
SPDR=offset/256;
while((SPSR&0x80)!=0x80);
SPDR=offset;
while((SPSR&0x80)!=0x80);
/* Write Control Byte */
SPDR=(VDM|RWB_WRITE|(s*0x20+0x10)); /*