STM32+W5500网络通信-------嵌入式系统基础学习
STM32+W5500网络通信-------嵌入式系统基础学习
一.W5500以太网模块介绍
Niren_W5500模块是一款基于WIZnet W5500芯片的以太网模块,是泥人电子继 Niren_W5100模块后设计的一块性能更好、性价比更高的以太网模块。模块集成硬件化TCP/IP协议:内部32K字节存储器作TX/RX
缓存:支持10/100Mbps的传输速率;支持8个独立端口同时运行;同时模块还支持3.3V或5V电源供电,5V供电时还可以输出3.3V电源,方便用户在不同的单片机系统中使用;模块与单片机系统的通讯方式是简单、方便的SPI通信。
二.模块排针功能表
三.调试方法
资源分享:
链接:https://pan.baidu.com/s/1fiWWfmWQT9CNh4EimU-Igw
提取码:1234
调试工具使用该压缩包里面的TCPUDPDebug102_Setup,自行安装.
STM32与W5500接线方法
PA15->W5500_RST(源程序使用的是PC5,这里没有该引脚修改为PA15)
PC4->W5500_INT(使用寄存器查询方式的例程时,此引脚可以不接,其他例程可能涉及修改引脚)
PA4->W5500_SCS
PA5->W5500_SCK
PA6->W5500_MISO
PA7->W5500_MOSI
具体例程的调试过程请参考压缩包中NiRen_W5500模块用户手册(用Adobe Reader打开).pdf文件。
这里我调试了查询寄存器方式中的UDP模式,服务端模式和客户端模式例程,调试结果如下:
四、代码实现TCP数据通信、DHCP自动获取IP
在官网下载W5500的例程https://www.w5500.com/code/W5500EVB/DHCP.html
主要代码如下
int main()
{
RCC_Configuration(); /* 配置单片机系统时钟*/
NVIC_Configuration();/* 配置嵌套中断向量*/
Systick_Init(72);/* 初始化Systick工作时钟*/
GPIO_Configuration();/* 配置GPIO*/
Timer_Configuration();/*定时器初始化*/
USART1_Init(); /*初始化串口通信:115200@8-n-1*/
at24c16_init();/*初始化eeprom*/
printf("W5500 EVB initialization over.\r\n");
Reset_W5500();/*硬重启W5500*/
WIZ_SPI_Init();/*初始化SPI接口*/
printf("W5500 initialized!\r\n");
set_default();
init_dhcp_client();
while(1)
{
DHCP_run();
}
}
设备配置代码
#include "config.h"
#include "socket.h"
#include "util.h"
#include "w5500.h"
#include "device.h"
#include "at24c16.h"
#include <stdio.h>
#include <string.h>
CONFIG_MSG ConfigMsg, RecvMsg;
uint8 txsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};
uint8 rxsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};
//public buffer for DHCP, DNS, HTTP
uint8 pub_buf[1460];
void Reset_W5500(void)
{
GPIO_ResetBits(GPIOB, WIZ_RESET);
Delay_us(50);
GPIO_SetBits(GPIOB, WIZ_RESET);
Delay_us(50);
}
//reboot
void reboot(void)
{
pFunction Jump_To_Application;
uint32 JumpAddress;
JumpAddress = *(vu32*) (0x00000004);
Jump_To_Application = (pFunction) JumpAddress;
Jump_To_Application();
}
void USART1_Init(void)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //Enable rx enable,
/* Configure the USARTx */
USART_Init(USART1, &USART_InitStructure);
/* Enable the USARTx */
USART_Cmd(USART1, ENABLE);
}
void set_network(void)
{
uint8 ip[4];
setSHAR(ConfigMsg.mac);/*配置Mac地址*/
setSUBR(ConfigMsg.sub);/*配置子网掩码*/
setGAR(ConfigMsg.gw);/*配置默认网关*/
setSIPR(ConfigMsg.lip);/*配置Ip地址*/
//Init. TX & RX Memory size of w5500
sysinit(txsize, rxsize); /*初始化8个socket*/
setRTR(2000);/*设置溢出时间值*/
setRCR(3);/*设置最大重新发送次数*/
getSIPR (ip);
printf("IP : %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]);
getSUBR(ip);
printf("SN : %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]);
getGAR(ip);
printf("GW : %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]);
}
void write_config_to_eeprom(void)
{
uint8 data;
uint16 i,j;
uint16 dAddr=0;
for (i = 0, j = 0; i < (uint8)(sizeof(ConfigMsg)-4);i++)
{
data = *(uint8 *)(ConfigMsg.mac+j);
at24c16_write(dAddr, data);
dAddr += 1;
j +=1;
}
}
void set_default(void)
{
uint8 mac[6]={0x00,0x08,0xdc,0x11,0x11,0x15};
uint8 lip[4]={192,168,1,88};
uint8 sub[4]={255,255,255,0};
uint8 gw[4]={192,168,1,1};
uint8 dns[4]={8,8,8,8};
memcpy(ConfigMsg.lip, lip, 4);
memcpy(ConfigMsg.sub, sub, 4);
memcpy(ConfigMsg.gw, gw, 4);
memcpy(ConfigMsg.mac, mac,6);
memcpy(ConfigMsg.dns,dns,4);
/*
uint8 dhcp;
uint8 debug;
uint16 fw_len;
uint8 state;
*/
ConfigMsg.dhcp=0;
ConfigMsg.debug=1;
ConfigMsg.fw_len=0;
ConfigMsg.state=NORMAL_STATE;
ConfigMsg.sw_ver[0]=FW_VER_HIGH;
ConfigMsg.sw_ver[1]=FW_VER_LOW;
}
void get_config(void)
{
uint8 tmp=0;
uint16 i=0;
for (i=0; i < CONFIG_MSG_LEN; i++)
{
tmp=at24c16_read(i);
*(ConfigMsg.mac+i) = tmp;
}
if((ConfigMsg.mac[0]==0xff)&&(ConfigMsg.mac[1]==0xff)&&(ConfigMsg.mac[2]==0xff)&&(ConfigMsg.mac[3]==0xff)&&(ConfigMsg.mac[4]==0xff)&&(ConfigMsg.mac[5]==0xff))
{
set_default();
}
}
具体DHCP配置代码
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "device.h"
#include "socket.h"
#include "w5500.h"
#include "dhcp.h"
#include "sockutil.h"
#include "util.h"//delay
//#define _DHCP_DEBUG_
uint8* DHCP_CHADDR = EXTERN_DHCP_MAC; // DHCP Client MAC address. 20180625
uint8* GET_SN_MASK = EXTERN_DHCP_SN; // Subnet mask received from the DHCP server
uint8* GET_GW_IP = EXTERN_DHCP_GW; // Gateway ip address received from the DHCP server
uint8* GET_DNS_IP = EXTERN_DHCP_DNS; // DNS server ip address received from the DHCP server
uint8* GET_SIP = EXTERN_DHCP_SIP; // Local ip address received from the DHCP server
uint8 DHCP_SIP[4] = {0,}; // DNS server ip address is discovered
uint8 DHCP_REAL_SIP[4] = {0,}; // For extract my DHCP server in a few DHCP servers
uint8 OLD_SIP[4]; // Previous local ip address received from DHCP server
uint32_t dhcp_tick_next = DHCP_WAIT_TIME ;//20180625
// Network information from DHCP Server 20180625
uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address
uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP
uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP
uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP
uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP
uint8_t HOST_NAME[] = DEVICE_TYPE;
uint8 dhcp_state = STATE_DHCP_READY; // DHCP client status
uint8 dhcp_retry_count = 0; // retry count
uint8 DHCP_timeout = 0; // DHCP Timeout flag
uint32 dhcp_lease_time; // Leased time
uint32 dhcp_time = 0;
uint32 next_dhcp_time = 0; // DHCP Time 1s
uint32 dhcp_tick_cnt = 0; // 1ms
uint8 DHCP_timer;
uint32 DHCP_XID = DEFAULT_XID;
uint8 EXTERN_DHCPBUF[1024];
RIP_MSG* pDHCPMSG = (RIP_MSG*)EXTERN_DHCPBUF; // Pointer for the DHCP message
/*
*********************************************************************************************************
* default_ip_assign
*
* Description: The default handler of ip assign first
* Arguments : None
* Returns : None
* Note :
*********************************************************************************************************
*/
void default_ip_assign(void)
{
setSIPR(DHCP_allocated_ip);
setSUBR(DHCP_allocated_sn);
setGAR (DHCP_allocated_gw);
}
/*
*********************************************************************************************************
* default_ip_update
*
* Description: The default handler of ip chaged
* Arguments : None
* Returns : None
* Note :
*********************************************************************************************************
*/
void default_ip_update(void)
{
/* WIZchip Software Reset */
setMR(MR_RST);
getMR(); // for delay
default_ip_assign();
setSHAR(DHCP_CHADDR);
}
/*
*********************************************************************************************************
* default_ip_conflict
*
* Description: The default handler of ip chaged
* Arguments : None
* Returns : None
* Note :
*********************************************************************************************************
*/
void default_ip_conflict(void)
{
// WIZchip Software Reset
setMR(MR_RST);
getMR(); // for delay
setSHAR(DHCP_CHADDR);
}
void (*dhcp_ip_assign)(void) = default_ip_assign; /* handler to be called when the IP address from DHCP server is first assigned */
void (*dhcp_ip_update)(void) = default_ip_update; /* handler to be called when the IP address from DHCP server is updated */
void (*dhcp_ip_conflict)(void) = default_ip_conflict; /* handler to be called when the IP address from DHCP server is conflict */
/*
*********************************************************************************************************
* reset_DHCP_timeout
*
* Description: reset timeout value and retry count
* Arguments :
* Returns :
* Note :
*********************************************************************************************************
*/
void reset_DHCP_timeout(void)//20180625
{
dhcp_time = 0;
dhcp_tick_next = DHCP_WAIT_TIME;
dhcp_retry_count = 0;
}
/*
*********************************************************************************************************
* check_DHCP_timeout
*
* Description: Check DHCP for timeout
* Arguments : None
* Returns : DHCP State
* Note :
*********************************************************************************************************
*/
uint8_t check_DHCP_timeout(void)//20180625
{
uint8_t ret = DHCP_RUNNING;
if (dhcp_retry_count < MAX_DHCP_RETRY) {
if (dhcp_tick_next < dhcp_time) {
switch ( dhcp_state ) {
case STATE_DHCP_DISCOVER :
#ifdef _DHCP_DEBUG_
printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
#endif
send_DHCP_DISCOVER();
break;
case STATE_DHCP_REQUEST :
#ifdef _DHCP_DEBUG_
printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");
#endif
send_DHCP_REQUEST();
break;
case STATE_DHCP_REREQUEST :
#ifdef _DHCP_DEBUG_
printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
#endif
send_DHCP_REQUEST();
break;
default :
break;
}
dhcp_time = 0;
dhcp_tick_next = dhcp_time + DHCP_WAIT_TIME;
dhcp_retry_count++;
}
} else { // timeout occurred
switch(dhcp_state) {
case STATE_DHCP_DISCOVER:
dhcp_state = STATE_DHCP_READY;
ret = DHCP_FAILED;
break;
case STATE_DHCP_REQUEST:
case STATE_DHCP_REREQUEST:
send_DHCP_DISCOVER();
dhcp_time = 0;
dhcp_state = STATE_DHCP_DISCOVER;
break;
default :
break;
}
reset_DHCP_timeout();
}
return ret;
}
/*
*********************************************************************************************************
* makeDHCPMSG
*
* Description: make the common DHCP message
* Arguments : None
* Returns : None
* Note :
*********************************************************************************************************
*/
void makeDHCPMSG(void)
{
uint8_t bk_mac[6];
uint8_t* ptmp;
uint8_t i;
getSHAR(bk_mac);
pDHCPMSG->op = DHCP_BOOTREQUEST;
pDHCPMSG->htype = DHCP_HTYPE10MB;
pDHCPMSG->hlen = DHCP_HLENETHERNET;
pDHCPMSG->hops = DHCP_HOPS;
ptmp = (uint8_t*)(&pDHCPMSG->xid);
*(ptmp+0) = (uint8_t)((DHCP_XID & 0xFF000000) >> 24);
*(ptmp+1) = (uint8_t)((DHCP_XID & 0x00FF0000) >> 16);
*(ptmp+2) = (uint8_t)((DHCP_XID & 0x0000FF00) >> 8);
*(ptmp+3) = (uint8_t)((DHCP_XID & 0x000000FF) >> 0);
pDHCPMSG->secs = DHCP_SECS;
ptmp = (uint8_t*)(&pDHCPMSG->flags);
*(ptmp+0) = (uint8_t)((DHCP_FLAGSBROADCAST & 0xFF00) >> 8);
*(ptmp+1) = (uint8_t)((DHCP_FLAGSBROADCAST & 0x00FF) >> 0);
pDHCPMSG->ciaddr[0] = 0;
pDHCPMSG->ciaddr[1] = 0;
pDHCPMSG->ciaddr[2] = 0;
pDHCPMSG->ciaddr[3] = 0;
pDHCPMSG->yiaddr[0] = 0;
pDHCPMSG->yiaddr[1] = 0;
pDHCPMSG->yiaddr[2] = 0;
pDHCPMSG->yiaddr[3] = 0;
pDHCPMSG->siaddr[0] = 0;
pDHCPMSG->siaddr[1] = 0;
pDHCPMSG->siaddr[2] = 0;
pDHCPMSG->siaddr[3] = 0;
pDHCPMSG->giaddr[0] = 0;
pDHCPMSG->giaddr[1] = 0;
pDHCPMSG->giaddr[2] = 0;
pDHCPMSG->giaddr[3] = 0;
pDHCPMSG->chaddr[0] = DHCP_CHADDR[0];
pDHCPMSG->chaddr[1] = DHCP_CHADDR[1];
pDHCPMSG->chaddr[2] = DHCP_CHADDR[2];
pDHCPMSG->chaddr[3] = DHCP_CHADDR[3];
pDHCPMSG->chaddr[4] = DHCP_CHADDR[4];
pDHCPMSG->chaddr[5] = DHCP_CHADDR[5];
for (i = 6; i < 16; i++) pDHCPMSG->chaddr[i] = 0;
for (i = 0; i < 64; i++) pDHCPMSG->sname[i] = 0;
for (i = 0; i < 128; i++) pDHCPMSG->file[i] = 0;
// MAGIC_COOKIE
pDHCPMSG->OPT[0] = (uint8_t)((MAGIC_COOKIE & 0xFF000000) >> 24);
pDHCPMSG->OPT[1] = (uint8_t)((MAGIC_COOKIE & 0x00FF0000) >> 16);
pDHCPMSG->OPT[2] = (uint8_t)((MAGIC_COOKIE & 0x0000FF00) >> 8);
pDHCPMSG->OPT[3] = (uint8_t) (MAGIC_COOKIE & 0x000000FF) >> 0;
}
/*
*********************************************************************************************************
* SEND DHCP DISCOVER
*
* Description: This function sends DHCP DISCOVER message to DHCP server.
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
void send_DHCP_DISCOVER(void)
{
uint8_t ip[4];
uint16_t k = 0;
uint8_t host_name[18];
makeDHCPMSG();
k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG()
// Option Request Param
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_DISCOVER;
// Client identifier
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
// host name
pDHCPMSG->OPT[k++] = hostName;
sprintf((char*)host_name,"%.11s-%02X%02X%02X",DEVICE_TYPE,DHCP_CHADDR[3],DHCP_CHADDR[4],DHCP_CHADDR[5]);
pDHCPMSG->OPT[k++] = strlen((char*)host_name);
strcpy((char*)(&(pDHCPMSG->OPT[k])),(char*)host_name);
k+=strlen((char*)host_name);
pDHCPMSG->OPT[k++] = dhcpParamRequest;
pDHCPMSG->OPT[k++] = 0x06; // length of request
pDHCPMSG->OPT[k++] = subnetMask;
pDHCPMSG->OPT[k++] = routersOnSubnet;
pDHCPMSG->OPT[k++] = dns;
pDHCPMSG->OPT[k++] = domainName;
pDHCPMSG->OPT[k++] = dhcpT1value;
pDHCPMSG->OPT[k++] = dhcpT2value;
pDHCPMSG->OPT[k++] = endOption;
// send broadcasting packet
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
#ifdef _DHCP_DEBUG_
printf("> Send DHCP_DISCOVER\r\n");
#endif
sendto(SOCK_DHCP, (uint8_t *)pDHCPMSG, sizeof(RIP_MSG), ip, DHCP_SERVER_PORT);
}
/*
*********************************************************************************************************
* SEND DHCP REQUEST
*
* Description: This function sends DHCP REQUEST message to DHCP server.
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
void send_DHCP_REQUEST(void)
{
// int i;
uint8_t ip[4];
uint16_t k = 0;
uint8_t host_name[18];
makeDHCPMSG();
if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST)
{
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0];
pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1];
pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2];
pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3];
ip[0] = DHCP_SIP[0];
ip[1] = DHCP_SIP[1];
ip[2] = DHCP_SIP[2];
ip[3] = DHCP_SIP[3];
}
else
{
ip[0] = 255;
ip[1] = 255;
ip[2] = 255;
ip[3] = 255;
}
k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG()
// Option Request Param.
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_REQUEST;
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE)
{
pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_SIP[0];
pDHCPMSG->OPT[k++] = DHCP_SIP[1];
pDHCPMSG->OPT[k++] = DHCP_SIP[2];
pDHCPMSG->OPT[k++] = DHCP_SIP[3];
}
// host name
pDHCPMSG->OPT[k++] = hostName;
sprintf((char*)host_name,"%.11s-%02X%02X%02X",DEVICE_TYPE,DHCP_CHADDR[3],DHCP_CHADDR[4],DHCP_CHADDR[5]);
pDHCPMSG->OPT[k++] = (uint8)strlen((char*)host_name);
strcpy((char*)(&(pDHCPMSG->OPT[k])),(char*)host_name);
k+=(uint8)strlen((char*)host_name);
pDHCPMSG->OPT[k++] = dhcpParamRequest;
pDHCPMSG->OPT[k++] = 0x08;
pDHCPMSG->OPT[k++] = subnetMask;
pDHCPMSG->OPT[k++] = routersOnSubnet;
pDHCPMSG->OPT[k++] = dns;
pDHCPMSG->OPT[k++] = domainName;
pDHCPMSG->OPT[k++] = dhcpT1value;
pDHCPMSG->OPT[k++] = dhcpT2value;
pDHCPMSG->OPT[k++] = performRouterDiscovery;
pDHCPMSG->OPT[k++] = staticRoute;
pDHCPMSG->OPT[k++] = endOption;
#ifdef _DHCP_DEBUG_
printf("> Send DHCP_REQUEST\r\n");
#endif
sendto(SOCK_DHCP, (uint8_t *)pDHCPMSG, sizeof(RIP_MSG), ip, DHCP_SERVER_PORT);
}
/*
*********************************************************************************************************
* SEND DHCP RELEASE
*
* Description: This function sends DHCP RELEASE message to DHCP server.
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
void send_DHCP_DECLINE(void)
{
// int i;
uint8_t ip[4];
uint16_t k = 0;
makeDHCPMSG();
k = 4; // beacaue MAGIC_COOKIE already made by makeDHCPMSG()
*((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8);
*((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF);
// Option Request Param.
pDHCPMSG->OPT[k++] = dhcpMessageType;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_DECLINE;
pDHCPMSG->OPT[k++] = dhcpClientIdentifier;
pDHCPMSG->OPT[k++] = 0x07;
pDHCPMSG->OPT[k++] = 0x01;
pDHCPMSG->OPT[k++] = DHCP_CHADDR[0];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[1];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[2];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[3];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[4];
pDHCPMSG->OPT[k++] = DHCP_CHADDR[5];
pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2];
pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3];
pDHCPMSG->OPT[k++] = dhcpServerIdentifier;
pDHCPMSG->OPT[k++] = 0x04;
pDHCPMSG->OPT[k++] = DHCP_SIP[0];
pDHCPMSG->OPT[k++] = DHCP_SIP[1];
pDHCPMSG->OPT[k++] = DHCP_SIP[2];
pDHCPMSG->OPT[k++] = DHCP_SIP[3];
pDHCPMSG->OPT[k++] = endOption;
//send broadcasting packet
ip[0] = 0xFF;
ip[1] = 0xFF;
ip[2] = 0xFF;
ip[3] = 0xFF;
#ifdef _DHCP_DEBUG_
printf("\r\n> Send DHCP_DECLINE\r\n");
#endif
sendto(SOCK_DHCP, (uint8_t *)pDHCPMSG, sizeof(RIP_MSG), ip, DHCP_SERVER_PORT);
}
/*
*********************************************************************************************************
* PARSE REPLY MSG
*
* Description: This function parses the reply message from DHCP server.
* Arguments : None
* Returns : success - return type, fail - 0
* Note :
*********************************************************************************************************
*/
int8_t parseDHCPMSG(void)//20180625
{
uint8_t svr_addr[6];
uint16_t svr_port;
uint16_t len;
uint8_t * p;
uint8_t * e;
uint8_t type;
uint8_t opt_len;
if((len = getSn_RX_RSR(SOCK_DHCP)) > 0)
{
len = recvfrom(SOCK_DHCP, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port);
#ifdef _DHCP_DEBUG_
printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port,len);
#endif
}
else return 0;
if (svr_port == DHCP_SERVER_PORT) {
// compare mac address
if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) ||
(pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) ||
(pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) )
return 0;
type = 0;
p = (uint8_t *)(&pDHCPMSG->op);//2
p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt)
e = p + (len - 240);
while ( p < e ) {
switch ( *p ) {
case endOption :
p = e; // for break while(p < e)
break;
case padOption :
p++;
break;
case dhcpMessageType :
p++;
p++;
type = *p++;
break;
case subnetMask :
p++;
p++;
DHCP_allocated_sn[0] = *p++;
DHCP_allocated_sn[1] = *p++;
DHCP_allocated_sn[2] = *p++;
DHCP_allocated_sn[3] = *p++;
break;
case routersOnSubnet :
p++;
opt_len = *p++;
DHCP_allocated_gw[0] = *p++;
DHCP_allocated_gw[1] = *p++;
DHCP_allocated_gw[2] = *p++;
DHCP_allocated_gw[3] = *p++;
p = p + (opt_len - 4);
break;
case dns :
p++;
opt_len = *p++;
DHCP_allocated_dns[0] = *p++;
DHCP_allocated_dns[1] = *p++;
DHCP_allocated_dns[2] = *p++;
DHCP_allocated_dns[3] = *p++;
p = p + (opt_len - 4);
break;
case dhcpIPaddrLeaseTime :
p++;
opt_len = *p++;
dhcp_lease_time = *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
dhcp_lease_time = (dhcp_lease_time << 8) + *p++;
#ifdef _DHCP_DEBUG_
// dhcp_lease_time = 10;
// printf("dhcp_lease_time:%d\r\n",(int)dhcp_lease_time);
#endif
break;
case dhcpServerIdentifier :
p++;
opt_len = *p++;
DHCP_SIP[0] = *p++;
DHCP_SIP[1] = *p++;
DHCP_SIP[2] = *p++;
DHCP_SIP[3] = *p++;
break;
default :
p++;
opt_len = *p++;
p += opt_len;
break;
} // switch
} // while
} // if
return type;
}
/*
*********************************************************************************************************
* CHECK TIMEOUT
*
* Description: This function checks the timeout of DHCP in each state.
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
void check_DHCP_Timeout(void)
{
if (dhcp_retry_count < MAX_DHCP_RETRY)
{
if (dhcp_time > next_dhcp_time)
{
dhcp_time = 0;
next_dhcp_time = dhcp_time + DHCP_WAIT_TIME;
dhcp_retry_count++;
switch ( dhcp_state )
{
case STATE_DHCP_DISCOVER :
#ifdef _DHCP_DEBUG_
printf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
#endif
send_DHCP_DISCOVER();
break;
case STATE_DHCP_REQUEST :
#ifdef _DHCP_DEBUG_
printf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");
#endif
send_DHCP_REQUEST();
break;
case STATE_DHCP_REREQUEST :
#ifdef _DHCP_DEBUG_
printf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
#endif
send_DHCP_REQUEST();
break;
default :
break;
}
}
}
else
{
reset_DHCP_timeout();
DHCP_timeout = 1;
send_DHCP_DISCOVER();
dhcp_state = STATE_DHCP_DISCOVER;
#ifdef _DHCP_DEBUG_
printf("timeout : state : STATE_DHCP_DISCOVER\r\n");
#endif
}
}
/*
*********************************************************************************************************
* check_DHCP_leasedIP
*
* Description: check if a leased IP is valid
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
int8_t check_DHCP_leasedIP(void)
{
uint8_t tmp;
int32_t ret;
//WIZchip RCR value changed for ARP Timeout count control
tmp = getRCR();
setRCR(0x03);
#ifdef _DHCP_DEBUG_
printf("<Check the IP Conflict %d.%d.%d.%d: ",DHCP_allocated_ip[0],DHCP_allocated_ip[1],DHCP_allocated_ip[2],DHCP_allocated_ip[3]);
#endif
// IP conflict detection : ARP request - ARP reply
// Broadcasting ARP Request for check the IP conflict using UDP sendto() function
ret = sendto(SOCK_DHCP, (uint8_t *)"CHECK_IP_CONFLICT", 17, DHCP_allocated_ip, 5000);
// RCR value restore
setRCR(tmp);
if(ret){
// Received ARP reply or etc : IP address conflict occur, DHCP Failed
send_DHCP_DECLINE();
ret = dhcp_time;
while((dhcp_time - ret) < 2) ; // wait for 1s over; wait to complete to send DECLINE message;
return 0;
}
else
{
// UDP send Timeout occurred : allocated IP address is unique, DHCP Success
#ifdef _DHCP_DEBUG_
printf("\r\n> Check leased IP - OK\r\n");
#endif
return 1;
}
}
/*
*********************************************************************************************************
* DHCP_timer_handler
*
* Description: timer interrupt handler(For checking dhcp lease time).
* Arguments : None.
* Returns : None.
* Note : Increase 'my_time' each one second.
*********************************************************************************************************
*/
void DHCP_timer_handler(void)
{
if(dhcp_tick_cnt++ > 1000)
{
dhcp_tick_cnt = 0;
dhcp_time++;
}
}
/*
*********************************************************************************************************
* Init_dhcp_client
*
* Description: Initialize the DHCP client
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
void init_dhcp_client(void)
{
uint8 txsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};
uint8 rxsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};
//uint8 ip_broadcast[4]={255,};
uint8 ip_0[4]={0,};
DHCP_XID = 0x12345678;
memset(OLD_SIP,0,sizeof(OLD_SIP));
memset(DHCP_SIP,0,sizeof(DHCP_SIP));
memset(DHCP_REAL_SIP,0,sizeof(GET_SN_MASK));
iinchip_init();
setSHAR(ConfigMsg.mac);
setSUBR(ip_0);
setGAR(ip_0);
setSIPR(ip_0);
printf("MAC=%02x:%02x:%02x:%02x:%02x:%02x\r\n",DHCP_CHADDR[0],DHCP_CHADDR[1],DHCP_CHADDR[2],DHCP_CHADDR[3],DHCP_CHADDR[4],DHCP_CHADDR[5]);
sysinit(txsize, rxsize);
//clear ip setted flag
dhcp_state = STATE_DHCP_READY;
#ifdef _DHCP_DEBUG
printf("init_dhcp_client:%u\r\n",SOCK_DHCP);
#endif
}
/*
*********************************************************************************************************
* DHCP_run
*
* Description: Do the DHCP client
* Arguments : None.
* Returns : None.
* Note :
*********************************************************************************************************
*/
uint8_t DHCP_run(void)//20180625
{
uint8_t type;
uint8_t ret;
if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED;
if(getSn_SR(SOCK_DHCP) != SOCK_UDP)
socket(SOCK_DHCP, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
ret = DHCP_RUNNING;
type = parseDHCPMSG();
switch ( dhcp_state ) {
case STATE_DHCP_READY :
DHCP_allocated_ip[0] = 0;
DHCP_allocated_ip[1] = 0;
DHCP_allocated_ip[2] = 0;
DHCP_allocated_ip[3] = 0;
send_DHCP_DISCOVER();
dhcp_time = 0;
dhcp_state = STATE_DHCP_DISCOVER;
break;
case STATE_DHCP_DISCOVER :
if (type == DHCP_OFFER)
{
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_OFFER\r\n");
#endif
DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0];
DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1];
DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2];
DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3];
send_DHCP_REQUEST();
dhcp_time = 0;
dhcp_state = STATE_DHCP_REQUEST;
}
else
ret = check_DHCP_timeout();
break;
case STATE_DHCP_REQUEST :
if (type == DHCP_ACK)
{
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_ACK\r\n");
#endif
if (check_DHCP_leasedIP())
{
// Network info assignment from DHCP
printf("ip:%d.%d.%d.%d\r\n",DHCP_allocated_ip[0],DHCP_allocated_ip[1],DHCP_allocated_ip[2],DHCP_allocated_ip[3]);
printf("sn:%d.%d.%d.%d\r\n",DHCP_allocated_sn[0],DHCP_allocated_sn[1],DHCP_allocated_sn[2],DHCP_allocated_sn[3]);
printf("gw:%d.%d.%d.%d\r\n",DHCP_allocated_gw[0],DHCP_allocated_gw[1],DHCP_allocated_gw[2],DHCP_allocated_gw[3]);
dhcp_ip_assign();
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
}
else
{
// IP address conflict occurred
reset_DHCP_timeout();
dhcp_ip_conflict();
dhcp_state = STATE_DHCP_READY;
}
}
else if (type == DHCP_NAK)
{
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_NACK\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_DISCOVER;
}
else
ret = check_DHCP_timeout();
break;
case STATE_DHCP_LEASED :
ret = DHCP_IP_LEASED;
if ((dhcp_lease_time != DEFAULT_LEASETIME) && ((dhcp_lease_time/2) < dhcp_time)) {
#ifdef _DHCP_DEBUG_
printf("> Maintains the IP address \r\n");
#endif
type = 0;
OLD_allocated_ip[0] = DHCP_allocated_ip[0];
OLD_allocated_ip[1] = DHCP_allocated_ip[1];
OLD_allocated_ip[2] = DHCP_allocated_ip[2];
OLD_allocated_ip[3] = DHCP_allocated_ip[3];
DHCP_XID++;
send_DHCP_REQUEST();
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_REREQUEST;
}
break;
case STATE_DHCP_REREQUEST :
ret = DHCP_IP_LEASED;
if (type == DHCP_ACK) {
dhcp_retry_count = 0;
if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] ||
OLD_allocated_ip[1] != DHCP_allocated_ip[1] ||
OLD_allocated_ip[2] != DHCP_allocated_ip[2] ||
OLD_allocated_ip[3] != DHCP_allocated_ip[3])
{
ret = DHCP_IP_CHANGED;
dhcp_ip_update();
#ifdef _DHCP_DEBUG_
printf(">IP changed.\r\n");
#endif
}
#ifdef _DHCP_DEBUG_
else printf(">IP is continued.\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_LEASED;
}
else if (type == DHCP_NAK)
{
#ifdef _DHCP_DEBUG_
printf("> Receive DHCP_NACK, Failed to maintain ip\r\n");
#endif
reset_DHCP_timeout();
dhcp_state = STATE_DHCP_DISCOVER;
}
else ret = check_DHCP_timeout();
break;
default :
break;
}
return ret;
}
/*
*
@file socket.c
@brief setting chip register for socket
last update : 2013. Nov
*
*/
//#include "stm32f10x_type.h"
#include "stm32f10x.h"
#include "config.h"
#include "stdio.h"
#include "w5500.h"
#include "socket.h"
#include "util.h"
static uint16 local_port;
extern uint16 sent_ptr;
/**
@brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5200 done it.
@return 1 for sucess else 0.
*/
uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag)
{
uint8 ret;
if (
((protocol&0x0F) == Sn_MR_TCP) ||
((protocol&0x0F) == Sn_MR_UDP) ||
((protocol&0x0F) == Sn_MR_IPRAW) ||
((protocol&0x0F) == Sn_MR_MACRAW) ||
((protocol&0x0F) == Sn_MR_PPPOE)
)
{
close(s);
IINCHIP_WRITE(Sn_MR(s) ,protocol | flag);
if (port != 0) {
IINCHIP_WRITE( Sn_PORT0(s) ,(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE( Sn_PORT1(s) ,(uint8)(port & 0x00ff));
} else {
local_port++; // if don't set the source port, set local_port number.
IINCHIP_WRITE(Sn_PORT0(s) ,(uint8)((local_port & 0xff00) >> 8));
IINCHIP_WRITE(Sn_PORT1(s) ,(uint8)(local_port & 0x00ff));
}
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_OPEN); // run sockinit Sn_CR
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
/**
@brief This function close the socket and parameter is "s" which represent the socket number
*/
void close(SOCKET s)
{
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CLOSE);
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s)) )
;
/* ------- */
/* all clear */
IINCHIP_WRITE( Sn_IR(s) , 0xFF);
}
/**
@brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
@return 1 for success else 0.
*/
uint8 listen(SOCKET s)
{
uint8 ret;
if (IINCHIP_READ( Sn_SR(s) ) == SOCK_INIT)
{
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_LISTEN);
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s) ) )
;
/* ------- */
ret = 1;
}
else
{
ret = 0;
}
return ret;
}
/**
@brief This function established the connection for the channel in Active (client) mode.
This function waits for the untill the connection is established.
@return 1 for success else 0.
*/
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
uint8 ret;
if
(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00)
)
{
ret = 0;
}
else
{
ret = 1;
// set destination IP
IINCHIP_WRITE( Sn_DIPR0(s), addr[0]);
IINCHIP_WRITE( Sn_DIPR1(s), addr[1]);
IINCHIP_WRITE( Sn_DIPR2(s), addr[2]);
IINCHIP_WRITE( Sn_DIPR3(s), addr[3]);
IINCHIP_WRITE( Sn_DPORT0(s), (uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE( Sn_DPORT1(s), (uint8)(port & 0x00ff));
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CONNECT);
/* wait for completion */
while ( IINCHIP_READ(Sn_CR(s) ) ) ;
while ( IINCHIP_READ(Sn_SR(s)) != SOCK_SYNSENT )
{
if(IINCHIP_READ(Sn_SR(s)) == SOCK_ESTABLISHED)
{
break;
}
if (getSn_IR(s) & Sn_IR_TIMEOUT)
{
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_TIMEOUT)); // clear TIMEOUT Interrupt
ret = 0;
break;
}
}
}
return ret;
}
/**
@brief This function used for disconnect the socket and parameter is "s" which represent the socket number
@return 1 for success else 0.
*/
void disconnect(SOCKET s)
{
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_DISCON);
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s) ) )
;
/* ------- */
}
/**
@brief This function used to send the data in TCP mode
@return 1 for success else 0.
*/
uint16 send(SOCKET s, const uint8 * buf, uint16 len)
{
uint8 status=0;
uint16 ret=0;
uint16 freesize=0;
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
// if freebuf is available, start.
do
{
freesize = getSn_TX_FSR(s);
status = IINCHIP_READ(Sn_SR(s));
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
{
ret = 0;
break;
}
} while (freesize < ret);
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_SEND);
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s) ) );
while ( (IINCHIP_READ(Sn_IR(s) ) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
status = IINCHIP_READ(Sn_SR(s));
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT) )
{
printf("SEND_OK Problem!!\r\n");
close(s);
return 0;
}
}
IINCHIP_WRITE( Sn_IR(s) , Sn_IR_SEND_OK);
#ifdef __DEF_IINCHIP_INT__
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
#else
IINCHIP_WRITE( Sn_IR(s) , Sn_IR_SEND_OK);
#endif
return ret;
}
/**
@brief This function is an application I/F function which is used to receive the data in TCP mode.
It continues to wait for data as much as the application wants to receive.
@return received data size for success else -1.
*/
uint16 recv(SOCKET s, uint8 * buf, uint16 len)
{
uint16 ret=0;
if ( len > 0 )
{
recv_data_processing(s, buf, len);
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_RECV);
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s) ));
/* ------- */
ret = len;
}
return ret;
}
/**
@brief This function is an application I/F function which is used to send the data for other then TCP mode.
Unlike TCP transmission, The peer's destination address and the port is needed.
@return This function return send data size for success else -1.
*/
uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port)
{
uint16 ret=0;
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
if( ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)) )//||(ret == 0) )
{
/* added return value */
ret = 0;
}
else
{
IINCHIP_WRITE( Sn_DIPR0(s), addr[0]);
IINCHIP_WRITE( Sn_DIPR1(s), addr[1]);
IINCHIP_WRITE( Sn_DIPR2(s), addr[2]);
IINCHIP_WRITE( Sn_DIPR3(s), addr[3]);
IINCHIP_WRITE( Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE( Sn_DPORT1(s),(uint8)(port & 0x00ff));
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_SEND); /* send command flag */
/* wait to process the command... */
while( IINCHIP_READ( Sn_CR(s) ) );
/* ------- */
while( (IINCHIP_READ( Sn_IR(s) ) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )//判断发送是否完成
{
if (IINCHIP_READ( Sn_IR(s) ) & Sn_IR_TIMEOUT)//判断发送命令是否超时
{
/* clear interrupt */
IINCHIP_WRITE( Sn_IR(s) , (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
return 0;
}
}
IINCHIP_WRITE( Sn_IR(s) , Sn_IR_SEND_OK);
}
return ret;
}
/**
@brief This function is an application I/F function which is used to receive the data in other then
TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
@return This function return received data size for success else -1.
*/
uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port)
{
uint8 head[8];
uint16 data_len=0;
uint16 ptr=0;
uint32 addrbsb =0;
if ( len > 0 )
{
ptr = IINCHIP_READ(Sn_RX_RD0(s) );
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD1(s));
addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x18;
switch (IINCHIP_READ(Sn_MR(s) ) & 0x07)
{
case Sn_MR_UDP :
wiz_read_buf(addrbsb, head, 0x08);
ptr += 8;
// read peer's IP address, port number.
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
data_len = head[6];
data_len = (data_len << 8) + head[7];
addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x18;
wiz_read_buf(addrbsb, buf, data_len);
ptr += data_len;
IINCHIP_WRITE( Sn_RX_RD0(s), (uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE( Sn_RX_RD1(s), (uint8)(ptr & 0x00ff));
break;
case Sn_MR_IPRAW :
wiz_read_buf(addrbsb, head, 0x06);
ptr += 6;
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
data_len = head[4];
data_len = (data_len << 8) + head[5];
addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x18;
wiz_read_buf(addrbsb, buf, data_len);
ptr += data_len;
IINCHIP_WRITE( Sn_RX_RD0(s), (uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE( Sn_RX_RD1(s), (uint8)(ptr & 0x00ff));
break;
case Sn_MR_MACRAW :
wiz_read_buf(addrbsb, head, 0x02);
ptr+=2;
data_len = head[0];
data_len = (data_len<<8) + head[1] - 2;
if(data_len > 1514)
{
printf("data_len over 1514\r\n");
while(1);
}
addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x18;
wiz_read_buf(addrbsb, buf, data_len);
ptr += data_len;
IINCHIP_WRITE( Sn_RX_RD0(s), (uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE( Sn_RX_RD1(s), (uint8)(ptr & 0x00ff));
break;
default :
break;
}
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_RECV);
/* wait to process the command... */
while( IINCHIP_READ( Sn_CR(s)) ) ;
/* ------- */
}
return data_len;
}
#ifdef __MACRAW__
void macraw_open(void)
{
uint8 sock_num;
uint16 dummyPort = 0;
uint8 mFlag = 0;
sock_num = 0;
close(sock_num); // Close the 0-th socket
socket(sock_num, Sn_MR_MACRAW, dummyPort,mFlag); // OPen the 0-th socket with MACRAW mode
}
uint16 macraw_send( const uint8 * buf, uint16 len )
{
uint16 ret=0;
uint8 sock_num;
sock_num =0;
if (len > getIINCHIP_TxMAX(sock_num)) ret = getIINCHIP_TxMAX(sock_num); // check size not to exceed MAX size.
else ret = len;
send_data_processing(sock_num, (uint8 *)buf, len);
//W5500 SEND COMMAND
IINCHIP_WRITE(Sn_CR(sock_num),Sn_CR_SEND);
while( IINCHIP_READ(Sn_CR(sock_num)) );
while ( (IINCHIP_READ(Sn_IR(sock_num)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK );
IINCHIP_WRITE(Sn_IR(sock_num), Sn_IR_SEND_OK);
return ret;
}
uint16 macraw_recv( uint8 * buf, uint16 len )
{
uint8 sock_num;
uint16 data_len=0;
uint16 dummyPort = 0;
uint16 ptr = 0;
uint8 mFlag = 0;
sock_num = 0;
if ( len > 0 )
{
data_len = 0;
ptr = IINCHIP_READ(Sn_RX_RD0(sock_num));
ptr = (uint16)((ptr & 0x00ff) << 8) + IINCHIP_READ( Sn_RX_RD1(sock_num) );
//-- read_data(s, (uint8 *)ptr, data, len); // read data
data_len = IINCHIP_READ_RXBUF(0, ptr);
ptr++;
data_len = ((data_len<<8) + IINCHIP_READ_RXBUF(0, ptr)) - 2;
ptr++;
if(data_len > 1514)
{
printf("data_len over 1514\r\n");
printf("\r\nptr: %X, data_len: %X", ptr, data_len);
//while(1);
/** recommand : close and open **/
close(sock_num); // Close the 0-th socket
socket(sock_num, Sn_MR_MACRAW, dummyPort,mFlag); // OPen the 0-th socket with MACRAW mode
return 0;
}
IINCHIP_READ_RXBUF_BURST(sock_num, ptr, data_len, (uint8*)(buf));
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(sock_num),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE(Sn_RX_RD1(sock_num),(uint8)(ptr & 0x00ff));
IINCHIP_WRITE(Sn_CR(sock_num), Sn_CR_RECV);
while( IINCHIP_READ(Sn_CR(sock_num)) ) ;
}
return data_len;
}
#endif
五、代码运行结果
单片机DHCP连接上同一个路由器,查看本机地址为如下图所示
可以看到串口输出的信息,在本机可以成功pingW5500端口的地址
ping 192.168.31.176结果如下
将单片机烧录显示网页程序,连接同一个wifi后访端口地址192.168.31.111结果如下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构