#ifndef?_W5500_QUEUE_H_
#define?_W5500_QUEUE_H_
#include?"type.h"
#define?W5500_FRAME_SIZE??????????2048
#define?W5500_RECV_QUEUE_SIZE?????20
typedef?enum
{
??W5500_FAILURE?=?0,
??W5500_OK?=?1,
}?w5500_queue_status_t;
typedef?__packed?struct
{
??uint8_t?data[W5500_FRAME_SIZE];
??uint16_t?length;
}?w5500_frame_t;
typedef?struct
{
??uint16_t?in;
??uint16_t?out;
??uint16_t?count;
??uint16_t?item_size[W5500_RECV_QUEUE_SIZE];
??uint8_t?data[W5500_RECV_QUEUE_SIZE][W5500_FRAME_SIZE];
}?w5500_queue_t;
extern?w5500_queue_t?w5500_queue_recv;
void?W5500QueueInit(w5500_queue_t?*q);
uint8_t?W5500QueueWrite(w5500_queue_t?*q,?w5500_frame_t?*data);
uint8_t?W5500QueueRead(w5500_queue_t?*q,?w5500_frame_t?*data);
#endif?/*?_W5500_QUEUE_H_?*/
#include?"w5500_queue.h"
#include#include#include?"debug.h"
w5500_queue_t?w5500_queue_recv;
void?W5500QueueInit(w5500_queue_t?*q)
{
??int?i;
??for(i?=?0;?i?<?W5500_RECV_QUEUE_SIZE;?++i)
??{
????memset(q->data[i],?0,?W5500_FRAME_SIZE);
??}
??memset(q->item_size,?0,?sizeof(q->item_size));
??q->in???=?0;
??q->out??=?0;
??q->count?=?0;
}
uint8_t?W5500QueueWrite(w5500_queue_t?*q,?w5500_frame_t?*frame)
{
??if((q->out?%?W5500_RECV_QUEUE_SIZE?==?q->in)?&&?(q->count?==?W5500_RECV_QUEUE_SIZE))
??{
????return?W5500_FAILURE;
??}
??q->item_size[q->in]?=?frame->length;
??memcpy(q->data[q->in],?frame->data,?frame->length);
??q->in?=?(q->in?+?1)?%?W5500_RECV_QUEUE_SIZE;
??q->count++;
??return?W5500_OK;
}
uint8_t?W5500QueueRead(w5500_queue_t?*q,?w5500_frame_t?*frame)
{
??if((q->in?==?q->out)?&&?(q->count?==?0))
??{
????return?W5500_FAILURE;
??}
??frame->length?=?q->item_size[q->out];
??memcpy(frame->data,?q->data[q->out],?q->item_size[q->out]);
??q->out?=?(q->out?+?1)?%?W5500_RECV_QUEUE_SIZE;
??q->count--;
??return?W5500_OK;
}
#ifndef?_W5500_H_
#define?_W5500_H_
#include?"type.h"
#include?"debug.h"
/*****************?Common?Register?*****************/
#define?MR????0x0000
#define?RST???0x80
#define?WOL???0x20
#define?PB????0x10
#define?PPP???0x08
#define?FARP??0x02
#define?GAR???0x0001
#define?SUBR??0x0005
#define?SHAR??0x0009
#define?SIPR??0x000f
#define?INTLEVEL??0x0013
#define?IR????????0x0015
#define?CONFLICT??0x80
#define?UNREACH???0x40
#define?PPPOE?????0x20
#define?MP????????0x10
#define?IMR???????0x0016
#define?IM_IR7????0x80
#define?IM_IR6????0x40
#define?IM_IR5????0x20
#define?IM_IR4????0x10
#define?SIR???????0x0017
#define?S7_INT????0x80
#define?S6_INT????0x40
#define?S5_INT????0x20
#define?S4_INT????0x10
#define?S3_INT????0x08
#define?S2_INT????0x04
#define?S1_INT????0x02
#define?S0_INT????0x01
#define?SIMR??????0x0018
#define?S7_IMR????0x80
#define?S6_IMR????0x40
#define?S5_IMR????0x20
#define?S4_IMR????0x10
#define?S3_IMR????0x08
#define?S2_IMR????0x04
#define?S1_IMR????0x02
#define?S0_IMR????0x01
#define?RTR_w5500?0x0019
#define?RCR_w5500?0x001b
#define?PTIMER??0x001c
#define?PMAGIC??0x001d
#define?PHA?????0x001e
#define?PSID????0x0024
#define?PMRU????0x0026
#define?UIPR????0x0028
#define?UPORT???0x002c
#define?PHYCFGR?0x002e
#define?RST_PHY?0x80
#define?OPMODE??0x40
#define?DPX?????0x04
#define?SPD?????0x02
#define?LINK????0x01
#define?VERR????0x0039
/*********************?Socket?Register?*******************/
#define?Sn_MR?????????0x0000
#define?MULTI_MFEN????0x80
#define?BCASTB????????0x40
#define?ND_MC_MMB?????0x20
#define?UCASTB_MIP6B??0x10
#define?MR_CLOSE??????0x00
#define?MR_TCP????????0x01
#define?MR_UDP????????0x02
#define?MR_MACRAW?????0x04
#define?Sn_CR?????????0x0001
#define?OPEN??????????0x01
#define?LISTEN????????0x02
#define?CONNECT???????0x04
#define?DISCON????????0x08
#define?CLOSE?????????0x10
#define?SEND??????????0x20
#define?SEND_MAC??????0x21
#define?SEND_KEEP?????0x22
#define?RECV??????????0x40
#define?Sn_IR?????????0x0002
#define?IR_SEND_OK????0x10
#define?IR_TIMEOUT????0x08
#define?IR_RECV???????0x04
#define?IR_DISCON?????0x02
#define?IR_CON????????0x01
#define?Sn_SR?????????0x0003
#define?SOCK_CLOSED???0x00
#define?SOCK_INIT?????0x13
#define?SOCK_LISTEN???0x14
#define?SOCK_ESTABLISHED??0x17
#define?SOCK_CLOSE_WAIT???0x1c
#define?SOCK_UDP??????0x22
#define?SOCK_MACRAW???0x02
#define?SOCK_SYNSEND??0x15
#define?SOCK_SYNRECV??0x16
#define?SOCK_FIN_WAI??0x18
#define?SOCK_CLOSING??0x1a
#define?SOCK_TIME_WAIT??0x1b
#define?SOCK_LAST_ACK?0x1d
#define?Sn_PORT???0x0004
#define?Sn_DHAR???0x0006
#define?Sn_DIPR???0x000c
#define?Sn_DPORTR?0x0010
#define?Sn_MSSR???0x0012
#define?Sn_TOS????0x0015
#define?Sn_TTL????0x0016
#define?Sn_RXBUF_SIZE?0x001e
#define?Sn_TXBUF_SIZE?0x001f
#define?Sn_TX_FSR?0x0020
#define?Sn_TX_RD??0x0022
#define?Sn_TX_WR??0x0024
#define?Sn_RX_RSR?0x0026
#define?Sn_RX_RD??0x0028
#define?Sn_RX_WR??0x002a
#define?Sn_IMR??????0x002c
#define?IMR_SENDOK??0x10
#define?IMR_TIMEOUT?0x08
#define?IMR_RECV????0x04
#define?IMR_DISCON??0x02
#define?IMR_CON?????0x01
#define?Sn_FRAG?????0x002d
#define?Sn_KPALVTR??0x002f
/*******************************************************************/
/************************?SPI?Control?Byte?*************************/
/*******************************************************************/
/*?Operation?mode?bits?*/
#define?VDM???0x00
#define?FDM1??0x01
#define?FDM2??0x02
#define?FDM4??0x03
/*?Read_Write?control?bit?*/
#define?RWB_READ??0x00
#define?RWB_WRITE?0x04
/*?Block?select?bits?*/
#define?COMMON_R??0x00
/*?Socket?0?*/
#define?S0_REG????0x08
#define?S0_TX_BUF?0x10
#define?S0_RX_BUF?0x18
/*?Socket?1?*/
#define?S1_REG????0x28
#define?S1_TX_BUF?0x30
#define?S1_RX_BUF?0x38
/*?Socket?2?*/
#define?S2_REG????0x48
#define?S2_TX_BUF?0x50
#define?S2_RX_BUF?0x58
/*?Socket?3?*/
#define?S3_REG????0x68
#define?S3_TX_BUF?0x70
#define?S3_RX_BUF?0x78
/*?Socket?4?*/
#define?S4_REG????0x88
#define?S4_TX_BUF?0x90
#define?S4_RX_BUF?0x98
/*?Socket?5?*/
#define?S5_REG????0xa8
#define?S5_TX_BUF?0xb0
#define?S5_RX_BUF?0xb8
/*?Socket?6?*/
#define?S6_REG????0xc8
#define?S6_TX_BUF?0xd0
#define?S6_RX_BUF?0xd8
/*?Socket?7?*/
#define?S7_REG????0xe8
#define?S7_TX_BUF?0xf0
#define?S7_RX_BUF?0xf8
#define?SOCKET_OK??0xff
#define?SOCKET_FAILURE?0x00
#define?S_RX_SIZE?2048??/*定義Socket接收緩沖區(qū)的大小,可以根據(jù)W5500_RMSR的設(shè)置修改?*/
#define?S_TX_SIZE?2048????/*定義Socket發(fā)送緩沖區(qū)的大小,可以根據(jù)W5500_TMSR的設(shè)置修改?*/
/***************-----?端口數(shù)據(jù)緩沖區(qū)?-----***************/
extern?uint8_t?socket_rx_buffer[2048];?//端口接收數(shù)據(jù)緩沖區(qū)
extern?uint8_t?socket_tx_buffer[2048];?//端口發(fā)送數(shù)據(jù)緩沖區(qū)
typedef?unsigned?char?SOCKET;?????//自定義端口號數(shù)據(jù)類型
void?W5500Init(void);
void?W5500SocketScan(void);
uint16_t?W5500SocketRecv(uint8_t?*buffer);
void?W5500SocketSend(uint8_t?*buffer,?uint16_t?length);
void?W5500Process(void);
extern?void?w5500_test(void);
#endif
#include#include?"stm32f10x.h"
#include?"stm32f10x_spi.h"
#include?"target.h"
#include?"delay.h"
#include?"w5500.h"
#include?"w5500_queue.h"
#include?"debug.h"
static?uint8_t?gateway_addr[4];
static?uint8_t?sub_mask[4];
static?uint8_t?mac_addr[6];
static?uint8_t?ip_addr[4];
static?uint8_t?s0_port[2];???//端口0的端口號(5000)
static?uint8_t?s0_dip[4];????//端口0目的IP地址
static?uint8_t?s0_dport[2];??//端口0目的端口號(6000)
static?uint8_t?udp_daddr[4];?//UDP(廣播)模式,目的主機IP地址
static?uint8_t?udp_dport[2];?//UDP(廣播)模式,目的主機端口號
/***************-----?端口的運行模式?-----***************/
static?uint8_t?s0_mode?=?3;?//端口0的運行模式,0:TCP服務(wù)器模式,1:TCP客戶端模式,2:UDP(廣播)模式
#define?TCP_SERVER??0x00??//TCP服務(wù)器模式
#define?TCP_CLIENT??0x01??//TCP客戶端模式?
#define?UDP_MODE????0x02??//UDP(廣播)模式?
/***************-----?端口的運行狀態(tài)?-----***************/
static?uint8_t?s0_state?=?0;?//端口0狀態(tài)記錄,1:端口完成初始化,2端口完成連接(可以正常傳輸數(shù)據(jù))
#define?S_INIT????0x01??//端口完成初始化?
#define?S_CONN????0x02??//端口完成連接,可以正常傳輸數(shù)據(jù)?
/***************-----?端口收發(fā)數(shù)據(jù)的狀態(tài)?-----***************/
static?uint8_t?s0_data;????//端口0接收和發(fā)送數(shù)據(jù)的狀態(tài),1:端口接收到數(shù)據(jù),2:端口發(fā)送數(shù)據(jù)完成
#define?S_RECEIVE????0x01?//端口接收到一個數(shù)據(jù)包?
#define?S_TRANSMITOK?0x02?//端口發(fā)送一個數(shù)據(jù)包完成?
/***************-----?端口數(shù)據(jù)緩沖區(qū)?-----***************/
uint8_t?socket_rx_buffer[2048];??//端口接收數(shù)據(jù)緩沖區(qū)
uint8_t?socket_tx_buffer[2048];??//端口發(fā)送數(shù)據(jù)緩沖區(qū)
static?void?w5500_gpio_init(void)
{
??RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,?ENABLE);
??W5500_RST_CONFIG();
??W5500_RST_LOW();
??W5500_INT_CONFIG();
??W5500_CS_CONFIG();
??W5500_SPI_CONFIG();?//?clk??miso??mosi
}
static?void?w5500_spi_init(void)
{
??SPI_InitTypeDef?SPI_InitStructure;
??RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,?ENABLE);
??SPI_InitStructure.SPI_Direction?=?SPI_Direction_2Lines_FullDuplex;
??SPI_InitStructure.SPI_Mode?=?SPI_Mode_Master;
??SPI_InitStructure.SPI_DataSize?=?SPI_DataSize_8b;
??SPI_InitStructure.SPI_CPOL?=?SPI_CPOL_Low;
??SPI_InitStructure.SPI_CPHA?=?SPI_CPHA_1Edge;
??SPI_InitStructure.SPI_NSS?=?SPI_NSS_Soft;
??SPI_InitStructure.SPI_BaudRatePrescaler?=?SPI_BaudRatePrescaler_2;
??SPI_InitStructure.SPI_FirstBit?=?SPI_FirstBit_MSB;
??SPI_InitStructure.SPI_CRCPolynomial?=?7;
??SPI_Init(W5500_SPI,?&SPI_InitStructure);
??SPI_Cmd(W5500_SPI,?ENABLE);
}
static?void?w5500_send_byte(uint8_t?data)
{
??SPI_I2S_SendData(W5500_SPI,?data);//寫1個字節(jié)數(shù)據(jù)
??while(SPI_I2S_GetFlagStatus(W5500_SPI,?SPI_I2S_FLAG_TXE)?==?RESET);//等待數(shù)據(jù)寄存器空
}
static?void?w5500_send_short(uint16_t?data)
{
??w5500_send_byte(data?/?256);
??w5500_send_byte(data);
}
static?void?w5500_write_byte(uint16_t?reg,?uint8_t?data)
{
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM1?|?RWB_WRITE?|?COMMON_R);?//?寫控制字節(jié),1個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇通用寄存器
??w5500_send_byte(data);
??W5500_CS_HIGH();
}
static?void?w5500_write_short(uint16_t?reg,?uint16_t?data)
{
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM2?|?RWB_WRITE?|?COMMON_R);?//?寫控制字節(jié),2個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇通用寄存器
??w5500_send_short(data);
??W5500_CS_HIGH();
}
static?void?w5500_write(uint16_t?reg,?uint8_t?*buffer,?uint16_t?length)
{
??uint16_t?i;
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(VDM?|?RWB_WRITE?|?COMMON_R);
??for(i?=?0;?i?<?length;?++i)
??{
????w5500_send_byte(*buffer++);
??}
??W5500_CS_HIGH();
}
static?void?w5500_sock_write_byte(SOCKET?s,?uint16_t?reg,?uint8_t?data)
{
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM1?|?RWB_WRITE?|?(s?*?0x20?+?0x08));?//?寫控制字節(jié),1個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇端口s的寄存器
??w5500_send_byte(data);
??W5500_CS_HIGH();
}
static?void?w5500_sock_write_short(SOCKET?s,?uint16_t?reg,?uint16_t?data)
{
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM2?|?RWB_WRITE?|?(s?*?0x20?+?0x08));?//?寫控制字節(jié),2個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇端口s的寄存器
??w5500_send_short(data);
??W5500_CS_HIGH();
}
static?void?w5500_sock_write_4bytes(SOCKET?s,?uint16_t?reg,?uint8_t?*buffer)
{
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM4?|?RWB_WRITE?|?(s?*?0x20?+?0x08));?//?寫控制字節(jié),4個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇端口s的寄存器
??w5500_send_byte(*buffer++);
??w5500_send_byte(*buffer++);
??w5500_send_byte(*buffer++);
??w5500_send_byte(*buffer++);
??W5500_CS_HIGH();
}
static?uint8_t?w5500_read_byte(uint16_t?reg)
{
??uint8_t?value;
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM1?|?RWB_READ?|?COMMON_R);?//?寫控制字節(jié),1個字節(jié)數(shù)據(jù)長度,讀數(shù)據(jù),選擇通用寄存器
??value?=?SPI_I2S_ReceiveData(W5500_SPI);
??w5500_send_byte(0x00);
??value?=?SPI_I2S_ReceiveData(W5500_SPI);
??W5500_CS_HIGH();
??return?value;
}
static?uint8_t?w5500_sock_read_byte(SOCKET?s,?uint16_t?reg)
{
??uint8_t?value;
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM1?|?RWB_READ?|?(s?*?0x20?+?0x08));?//?寫控制字節(jié),1個字節(jié)數(shù)據(jù)長度,讀數(shù)據(jù),選擇端口s的寄存器
??value?=?SPI_I2S_ReceiveData(W5500_SPI);
??w5500_send_byte(0x00);
??value?=?SPI_I2S_ReceiveData(W5500_SPI);
??W5500_CS_HIGH();
??return?value;
}
static?uint16_t?w5500_sock_read_2bytes(SOCKET?s,?uint16_t?reg)
{
??uint16_t?value;
??W5500_CS_LOW();
??w5500_send_short(reg);
??w5500_send_byte(FDM2?|?RWB_READ?|?(s?*?0x20?+?0x08));?//?寫控制字節(jié),2個字節(jié)數(shù)據(jù)長度,讀數(shù)據(jù),選擇端口s的寄存器
??value?=?SPI_I2S_ReceiveData(W5500_SPI);
??w5500_send_byte(0x00);
??value?=?SPI_I2S_ReceiveData(W5500_SPI);
??w5500_send_byte(0x00);
??value?*=?256;
??value?+=?SPI_I2S_ReceiveData(W5500_SPI);
??W5500_CS_HIGH();
??return?value;
}
static?uint16_t?w5500_socket_read(SOCKET?s,?uint8_t?*buffer)
{
??uint16_t?rx_size,?offset,?offset1,?i;
??uint8_t?j;
??rx_size?=?w5500_sock_read_2bytes(s,?Sn_RX_RSR);
??if(rx_size?==?0)
??{
????return?0;??//沒接收到數(shù)據(jù)則返回
??}
??if(rx_size?>?1460)
??{
????rx_size?=?1460;
??}
??offset?=?w5500_sock_read_2bytes(s,?Sn_RX_RD);
??offset1?=?offset;
??offset?&=?(S_RX_SIZE?-?1);?//計算實際的物理地址
??W5500_CS_LOW();
??w5500_send_short(offset);//寫16位地址
??w5500_send_byte(VDM?|?RWB_READ?|?(s?*?0x20?+?0x18));?//寫控制字節(jié),N個字節(jié)數(shù)據(jù)長度,讀數(shù)據(jù),選擇端口s的寄存器
??j?=?SPI_I2S_ReceiveData(SPI2);
??if((offset?+?rx_size)?<?S_RX_SIZE)?//如果最大地址未超過W5500接收緩沖區(qū)寄存器的最大地址
??{
????for(i?=?0;?i?<?rx_size;?i++)?//循環(huán)讀取rx_size個字節(jié)數(shù)據(jù)
????{
??????w5500_send_byte(0x00);//發(fā)送一個啞數(shù)據(jù)
??????j?=?SPI_I2S_ReceiveData(SPI2);?//讀取1個字節(jié)數(shù)據(jù)
??????*buffer?=?j;?//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū)
??????buffer++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1
????}
??}
??else//如果最大地址超過W5500接收緩沖區(qū)寄存器的最大地址
??{
????offset?=?S_RX_SIZE?-?offset;
????for(i?=?0;?i?<?offset;?i++)?//循環(huán)讀取出前offset個字節(jié)數(shù)據(jù)
????{
??????w5500_send_byte(0x00);//發(fā)送一個啞數(shù)據(jù)
??????j?=?SPI_I2S_ReceiveData(SPI2);?//讀取1個字節(jié)數(shù)據(jù)
??????*buffer?=?j;?//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū)
??????buffer++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1
????}
????W5500_CS_HIGH();
????W5500_CS_LOW();
????w5500_send_short(0x00);//寫16位地址
????w5500_send_byte(VDM?|?RWB_READ?|?(s?*?0x20?+?0x18));?//寫控制字節(jié),N個字節(jié)數(shù)據(jù)長度,讀數(shù)據(jù),選擇端口s的寄存器
????j?=?SPI_I2S_ReceiveData(SPI2);
????for(;?i?<?rx_size;?i++)?//循環(huán)讀取后rx_size-offset個字節(jié)數(shù)據(jù)
????{
??????w5500_send_byte(0x00);//發(fā)送一個啞數(shù)據(jù)
??????j?=?SPI_I2S_ReceiveData(SPI2);?//讀取1個字節(jié)數(shù)據(jù)
??????*buffer?=?j;?//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū)
??????buffer++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1
????}
??}
??W5500_CS_HIGH();
??offset1?+=?rx_size;?//更新實際物理地址,即下次讀取接收到的數(shù)據(jù)的起始地址
??w5500_sock_write_short(s,?Sn_RX_RD,?offset1);
??w5500_sock_write_byte(s,?Sn_CR,?RECV);//發(fā)送啟動接收命令
??return?rx_size;//返回接收到數(shù)據(jù)的長度
}
static?void?w5500_socket_write(SOCKET?s,?uint8_t?*buffer,?uint16_t?length)
{
??uint16_t?offset,?offset1,?i;
??//如果是UDP模式,可以在此設(shè)置目的主機的IP和端口號
??if((w5500_sock_read_byte(s,?Sn_MR)?&?0x0f)?!=?SOCK_UDP)?//如果Socket打開失敗
??{
????w5500_sock_write_4bytes(s,?Sn_DIPR,?udp_daddr);//設(shè)置目的主機IP
????w5500_sock_write_short(s,?Sn_DPORTR,?udp_dport[0]?*?256?+?udp_dport[1]);?//設(shè)置目的主機端口號
??}
??offset?=?w5500_sock_read_2bytes(s,?Sn_TX_WR);
??offset1?=?offset;
??offset?&=?(S_TX_SIZE?-?1);?//計算實際的物理地址
??W5500_CS_LOW();
??w5500_send_short(offset);//寫16位地址
??w5500_send_byte(VDM?|?RWB_WRITE?|?(s?*?0x20?+?0x10));?//寫控制字節(jié),N個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇端口s的寄存器
??if((offset?+?length)?<?S_TX_SIZE)?//如果最大地址未超過W5500發(fā)送緩沖區(qū)寄存器的最大地址
??{
????for(i?=?0;?i?<?length;?++i)?//循環(huán)寫入size個字節(jié)數(shù)據(jù)
????{
??????w5500_send_byte(*buffer++);//寫入一個字節(jié)的數(shù)據(jù)
????}
??}
??else//如果最大地址超過W5500發(fā)送緩沖區(qū)寄存器的最大地址
??{
????offset?=?S_TX_SIZE?-?offset;
????for(i?=?0;?i?<?offset;?++i)?//循環(huán)寫入前offset個字節(jié)數(shù)據(jù)
????{
??????w5500_send_byte(*buffer++);//寫入一個字節(jié)的數(shù)據(jù)
????}
????W5500_CS_HIGH();
????W5500_CS_LOW();
????w5500_send_short(0x00);//寫16位地址
????w5500_send_byte(VDM?|?RWB_WRITE?|?(s?*?0x20?+?0x10));?//寫控制字節(jié),N個字節(jié)數(shù)據(jù)長度,寫數(shù)據(jù),選擇端口s的寄存器
????for(;?i?<?length;?i++)?//循環(huán)寫入size-offset個字節(jié)數(shù)據(jù)
????{
??????w5500_send_byte(*buffer++);//寫入一個字節(jié)的數(shù)據(jù)
????}
??}
??W5500_CS_HIGH();
??offset1?+=?length;?//更新實際物理地址,即下次寫待發(fā)送數(shù)據(jù)到發(fā)送數(shù)據(jù)緩沖區(qū)的起始地址
??w5500_sock_write_short(s,?Sn_TX_WR,?offset1);
??w5500_sock_write_byte(s,?Sn_CR,?SEND);//發(fā)送啟動發(fā)送命令
}
static?void?w5500_hardware_reset(void)
{
??W5500_RST_LOW();
??delay_ms(5);
??W5500_RST_HIGH();
??delay_ms(20);
??while((w5500_read_byte(PHYCFGR)?&?LINK)?==?0);//等待以太網(wǎng)連接完成
}
static?void?w5500_reg_init(void)
{
??uint8_t?i?=?0;
??w5500_write_byte(MR,?RST);//軟件復(fù)位W5500,置1有效,復(fù)位后自動清0
??delay_ms(10);
??//設(shè)置網(wǎng)關(guān)(Gateway)的IP地址,Gateway_IP為4字節(jié)unsigned?char數(shù)組,自己定義
??//使用網(wǎng)關(guān)可以使通信突破子網(wǎng)的局限,通過網(wǎng)關(guān)可以訪問到其它子網(wǎng)或進入Internet
??w5500_write(GAR,?gateway_addr,?4);
??//設(shè)置子網(wǎng)掩碼(MASK)值,SUB_MASK為4字節(jié)unsigned?char數(shù)組,自己定義
??//子網(wǎng)掩碼用于子網(wǎng)運算
??w5500_write(SUBR,?sub_mask,?4);
??//設(shè)置物理地址,PHY_ADDR為6字節(jié)unsigned?char數(shù)組,自己定義,用于唯一標識網(wǎng)絡(luò)設(shè)備的物理地址值
??//該地址值需要到IEEE申請,按照OUI的規(guī)定,前3個字節(jié)為廠商代碼,后三個字節(jié)為產(chǎn)品序號
??//如果自己定義物理地址,注意第一個字節(jié)必須為偶數(shù)
??w5500_write(SHAR,?mac_addr,?6);
??//設(shè)置本機的IP地址,IP_ADDR為4字節(jié)unsigned?char數(shù)組,自己定義
??//注意,網(wǎng)關(guān)IP必須與本機IP屬于同一個子網(wǎng),否則本機將無法找到網(wǎng)關(guān)
??w5500_write(SIPR,?ip_addr,?4);
??//設(shè)置發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小,參考W5500數(shù)據(jù)手冊
??for(i?=?0;?i?<?8;?i++)
??{
????w5500_sock_write_byte(i,?Sn_RXBUF_SIZE,?0x02);?//Socket?Rx?memory?size=2k
????w5500_sock_write_byte(i,?Sn_TXBUF_SIZE,?0x02);?//Socket?Tx?mempry?size=2k
??}
??//設(shè)置重試時間,默認為2000(200ms)
??//每一單位數(shù)值為100微秒,初始化時值設(shè)為2000(0x07D0),等于200毫秒
??w5500_write_short(RTR_w5500,?0x07d0);
??//設(shè)置重試次數(shù),默認為8次
??//如果重發(fā)的次數(shù)超過設(shè)定值,則產(chǎn)生超時中斷(相關(guān)的端口中斷寄存器中的Sn_IR?超時位(TIMEOUT)置“1”)
??w5500_write_byte(RCR_w5500,?8);
??//啟動中斷,參考W5500數(shù)據(jù)手冊確定自己需要的中斷類型
??//IMR_CONFLICT是IP地址沖突異常中斷,IMR_UNREACH是UDP通信時,地址無法到達的異常中斷
??//其它是Socket事件中斷,根據(jù)需要添加
??w5500_write_byte(IMR,?IM_IR7?|?IM_IR6);
??w5500_write_byte(SIMR,?S0_IMR);
??w5500_sock_write_byte(0,?Sn_IMR,?IMR_SENDOK?|?IMR_TIMEOUT?|?IMR_RECV?|?IMR_DISCON?|?IMR_CON);
}
static?uint8_t?w5500_gateway_check(void)
{
??uint8_t?ip_adde[4];
??ip_adde[0]?=?ip_addr[0]?+?1;
??ip_adde[1]?=?ip_addr[1]?+?1;
??ip_adde[2]?=?ip_addr[2]?+?1;
??ip_adde[3]?=?ip_addr[3]?+?1;
??//檢查網(wǎng)關(guān)及獲取網(wǎng)關(guān)的物理地址
??w5500_sock_write_4bytes(0,?Sn_DIPR,?ip_adde);?//向目的地址寄存器寫入與本機IP不同的IP值
??w5500_sock_write_byte(0,?Sn_MR,?MR_TCP);?//設(shè)置socket為TCP模式
??w5500_sock_write_byte(0,?Sn_CR,?OPEN);?//打開Socket
??delay_ms(5);//延時5ms
??if(w5500_sock_read_byte(0,?Sn_SR)?!=?SOCK_INIT)?//如果socket打開失敗
??{
????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//打開不成功,關(guān)閉Socket
????return?SOCKET_FAILURE;//返回FALSE(0x00)
??}
??w5500_sock_write_byte(0,?Sn_CR,?CONNECT);?//設(shè)置Socket為Connect模式
??do
??{
????uint8_t?j?=?0;
????j?=?w5500_sock_read_byte(0,?Sn_IR);?//讀取Socket0中斷標志寄存器
????if(j?!=?0)
????{
??????w5500_sock_write_byte(0,?Sn_IR,?j);
????}
????delay_ms(5);//延時5ms
????if((j?&?IR_TIMEOUT)?==?IR_TIMEOUT)
????{
??????return?SOCKET_FAILURE;
????}
????else?if(w5500_sock_read_byte(0,?Sn_DHAR)?!=?0xff)
????{
??????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//關(guān)閉Socket
??????return?SOCKET_OK;
????}
??}
??while(1);
}
static?void?w5500_socket_init(SOCKET?s)
{
??//設(shè)置分片長度,參考W5500數(shù)據(jù)手冊,該值可以不修改
??w5500_sock_write_short(0,?Sn_MSSR,?1460);//最大分片字節(jié)數(shù)=1460(0x5b4)
??//設(shè)置指定端口
??switch(s)
??{
??case?0:
??{
????if(UDP_MODE?==?s0_mode)
????{
??????//設(shè)置端口0的端口號
??????w5500_sock_write_short(0,?Sn_PORT,?s0_port[0]?*?256?+?s0_port[1]);
????}
????else?if(TCP_CLIENT?==?s0_mode)
????{
??????//設(shè)置端口0的端口號
??????w5500_sock_write_short(0,?Sn_PORT,?s0_port[0]?*?256?+?s0_port[1]);
??????//設(shè)置端口0目的(遠程)端口號
??????w5500_sock_write_short(0,?Sn_DPORTR,?s0_dport[0]?*?256?+?s0_dport[1]);
??????//設(shè)置端口0目的(遠程)IP地址
??????w5500_sock_write_4bytes(0,?Sn_DIPR,?s0_dip);
????}
????else?if(TCP_SERVER?==?s0_mode)
????{
??????//設(shè)置端口0的端口號
??????w5500_sock_write_short(0,?Sn_PORT,?s0_port[0]?*?256?+?s0_port[1]);
????}
??}
??break;
??case?1:
????break;
??case?2:
????break;
??case?3:
????break;
??case?4:
????break;
??case?5:
????break;
??case?6:
????break;
??case?7:
????break;
??default:
????break;
??}
}
static?uint8_t?w5500_socket_connect(SOCKET?s)
{
??w5500_sock_write_byte(s,?Sn_MR,?MR_TCP);?
??w5500_sock_write_byte(s,?Sn_CR,?OPEN);?
??delay_ms(5);
??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_INIT)?
??{
????w5500_sock_write_byte(s,?Sn_CR,?CLOSE);?
????return?SOCKET_FAILURE;
??}
??w5500_sock_write_byte(s,?Sn_CR,?CONNECT);?
??return?SOCKET_OK;
}
static?uint8_t?w5500_socket_listen(SOCKET?s)
{
??w5500_sock_write_byte(s,?Sn_MR,?MR_TCP);?
??w5500_sock_write_byte(s,?Sn_CR,?OPEN);
??delay_ms(5);
??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_INIT)?
??{
????w5500_sock_write_byte(s,?Sn_CR,?CLOSE);?
????return?SOCKET_FAILURE;
??}
??w5500_sock_write_byte(s,?Sn_CR,?LISTEN);?
??delay_ms(5);
??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_LISTEN)
??{
????w5500_sock_write_byte(s,?Sn_CR,?CLOSE);
????return?SOCKET_FAILURE;
??}
??return?SOCKET_OK;
}
static?uint8_t?w5500_socket_udp(SOCKET?s)
{
??w5500_sock_write_byte(s,?Sn_MR,?MR_UDP);
??w5500_sock_write_byte(s,?Sn_CR,?OPEN);
??delay_ms(5);
??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_UDP)
??{
????w5500_sock_write_byte(s,?Sn_CR,?CLOSE);
????return?SOCKET_FAILURE;
??}
??else
??{
????return?SOCKET_OK;
??}
}
static?void?w5500_load_para(void)
{
??gateway_addr[0]?=?192;
??gateway_addr[1]?=?168;
??gateway_addr[2]?=?1;
??gateway_addr[3]?=?1;
??sub_mask[0]?=?255;
??sub_mask[1]?=?255;
??sub_mask[2]?=?255;
??sub_mask[3]?=?0;
??mac_addr[0]?=?0x0c;
??mac_addr[1]?=?0x29;
??mac_addr[2]?=?0xab;
??mac_addr[3]?=?0x7c;
??mac_addr[4]?=?0x00;
??mac_addr[5]?=?0x02;
??ip_addr[0]?=?192;
??ip_addr[1]?=?168;
??ip_addr[2]?=?1;
??ip_addr[3]?=?199;
??s0_port[0]?=?0x18;
??s0_port[1]?=?0x56;
??udp_daddr[0]?=?192;
??udp_daddr[1]?=?168;
??udp_daddr[2]?=?1;
??udp_daddr[3]?=?190;
#if?0
??s0_dip[0]?=?192;
??s0_dip[1]?=?168;
??s0_dip[2]?=?1;
??s0_dip[3]?=?99;
??s0_dport[0]?=?0x18;?
??s0_dport[1]?=?0x56;?
#endif
??udp_dport[0]?=?0x17;
??udp_dport[1]?=?0x70;
??s0_mode?=?UDP_MODE;
}
void?W5500Init(void)
{
??w5500_gpio_init();
??w5500_spi_init();
??w5500_load_para();?//?load?net?para?[ip,?port,?mask...]
??w5500_hardware_reset();
??w5500_reg_init();
??w5500_gateway_check();
??w5500_socket_init(0);
}
void?W5500SocketScan(void)
{
??if(s0_state?==?0)
??{
????if(s0_mode?==?TCP_SERVER)
????{
??????if(w5500_socket_listen(0)?==?SOCKET_OK)
??????{
????????s0_state?=?S_INIT;
??????}
??????else
??????{
????????s0_state?=?0;
??????}
????}
????else?if(s0_mode?==?TCP_CLIENT)
????{
??????if(w5500_socket_connect(0)?==?SOCKET_OK)
??????{
????????s0_state?=?S_INIT;
??????}
??????else
??????{
????????s0_state?=?0;
??????}
????}
????else
????{
??????if(w5500_socket_udp(0)?==?SOCKET_OK)
??????{
????????debug("1234rn");
????????s0_state?=?S_INIT?|?S_CONN;
??????}
??????else
??????{
????????s0_state?=?0;
??????}
????}
??}
}
uint16_t?W5500SocketRecv(uint8_t?*buffer)
{
??uint16_t?length;
??if((s0_data?&?S_RECEIVE)?==?S_RECEIVE)
??{
????s0_data?&=?~S_RECEIVE;
????length?=?w5500_socket_read(0,?buffer);
??}
??return?length;
}
void?W5500SocketSend(uint8_t?*buffer,?uint16_t?length)
{
??if(s0_state?==?(S_INIT?|?S_CONN))
??{
????s0_data?&=?~S_TRANSMITOK;
????w5500_socket_write(0,?buffer,?length);
??}
}
void?W5500InterruptProcess(void)
{
??uint8_t?i,?j;
IntDispose:
??i?=?w5500_read_byte(IR);//讀取中斷標志寄存器
??w5500_write_byte(IR,?(i?&?0xf0));//回寫清除中斷標志
??if((i?&?CONFLICT)?==?CONFLICT)//IP地址沖突異常處理
??{
????//自己添加代碼
??}
??if((i?&?UNREACH)?==?UNREACH)//UDP模式下地址無法到達異常處理
??{
????debug("-------n");
????//自己添加代碼
??}
??i?=?w5500_read_byte(SIR);?//讀取端口中斷標志寄存器
??if((i?&?S0_INT)?==?S0_INT)//Socket0事件處理
??{
????j?=?w5500_sock_read_byte(0,?Sn_IR);?//讀取Socket0中斷標志寄存器
????w5500_sock_write_byte(0,?Sn_IR,?j);
????if(j?&?IR_CON)?//在TCP模式下,Socket0成功連接
????{
??????s0_state?|=?S_CONN;?//網(wǎng)絡(luò)連接狀態(tài)0x02,端口完成連接,可以正常傳輸數(shù)據(jù)
????}
????if(j?&?IR_DISCON)?//在TCP模式下Socket斷開連接處理
????{
??????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//關(guān)閉端口,等待重新打開連接
??????w5500_socket_init(0);???//指定Socket(0~7)初始化,初始化端口0
??????s0_state?=?0;?//網(wǎng)絡(luò)連接狀態(tài)0x00,端口連接失敗
????}
????if(j?&?IR_SEND_OK)?//Socket0數(shù)據(jù)發(fā)送完成,可以再次啟動S_tx_process()函數(shù)發(fā)送數(shù)據(jù)
????{
??????s0_data?|=?S_TRANSMITOK;?//端口發(fā)送一個數(shù)據(jù)包完成
????}
????if(j?&?IR_RECV)?//Socket接收到數(shù)據(jù),可以啟動S_rx_process()函數(shù)
????{
??????s0_data?|=?S_RECEIVE;?//端口接收到一個數(shù)據(jù)包
????}
????if(j?&?IR_TIMEOUT)?//Socket連接或數(shù)據(jù)傳輸超時處理
????{
??????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//?關(guān)閉端口,等待重新打開連接
??????s0_state?=?0;?//網(wǎng)絡(luò)連接狀態(tài)0x00,端口連接失敗
????}
??}
??if(w5500_read_byte(SIR)?!=?0)
??{
????goto?IntDispose;
??}
}
//?test?use
static?void?socket_data_process(SOCKET?s)
{
??w5500_frame_t?frame;
??frame.length?=?w5500_socket_read(s,?frame.data);
//?debug("socket_data_process...rn");
??W5500QueueWrite(&w5500_queue_recv,?&frame);
??if(UDP_MODE?==?s0_mode)
??{
????udp_daddr[0]?=?frame.data[0];
????udp_daddr[1]?=?frame.data[1];
????udp_daddr[2]?=?frame.data[2];
????udp_daddr[3]?=?frame.data[3];
????udp_dport[0]?=?frame.data[4];
????udp_dport[1]?=?frame.data[5];
??}
}
void?W5500Process(void)
{
??W5500SocketScan();
??debug("22222rn");
??W5500InterruptProcess();
??debug("3333rn");
??if((s0_data?&?S_RECEIVE)?==?S_RECEIVE)//如果Socket0接收到數(shù)據(jù)
??{
????s0_data?&=?~S_RECEIVE;
????socket_data_process(0);//W5500接收并發(fā)送接收到的數(shù)據(jù)
??}
??debug("1111rn");
}
void?w5500_test(void)
{
??static?uint16_t?W5500_Send_Delay_Counter?=?0;
??W5500_Send_Delay_Counter++;
??W5500SocketScan();
??W5500InterruptProcess();
??if((s0_data?&?S_RECEIVE)?==?S_RECEIVE)//如果Socket0接收到數(shù)據(jù)
??{
????s0_data?&=?~S_RECEIVE;
????socket_data_process(0);//W5500接收并發(fā)送接收到的數(shù)據(jù)
??}
??else?if(W5500_Send_Delay_Counter?>=?500)//定時發(fā)送字符串
??{
????if(s0_state?==?(S_INIT?|?S_CONN))
????{
??????s0_data?&=?~S_TRANSMITOK;
??????memcpy(socket_tx_buffer,?"rn123456rn",?10);
??????w5500_socket_write(0,?socket_tx_buffer,?10);//指定Socket(0~7)發(fā)送數(shù)據(jù)處理,端口0發(fā)送23字節(jié)數(shù)據(jù)
??????W5500_Send_Delay_Counter?=?0;
????}
??}
}