文章目录
w5500_conf.h 文件内容
包含一些相关的硬件初始化和用户参数配置。
#ifndef _W5500_CONF_H_
#define _W5500_CONF_H_
#include "stm32f10x.h"
#include "stdio.h"
#include "types.h"
#define __GNUC__
typedef void (*pFunction)(void);
extern uint8 remote_ip[4]; /* 远端IP地址 */
extern uint16 remote_port; /* 远端端口号 */
extern uint16 local_port; /* 定义本地端口 */
extern uint8 use_dhcp; /* 是否使用DHCP获取IP */
extern uint8 use_eeprom; /* 是否使用EEPROM中的IP配置信息 */
/*定义SPI2作为W5500的硬件接口*/
#define WIZ_SPIx_GPIO_PORT GPIOB /* GPIO端口 */
#define WIZ_SPIx_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define WIZ_SPIx SPI2 /* 定义W5500所用的SPI接口 */
#define WIZ_SPIx_CLK_CMD RCC_APB1PeriphClockCmd
#define WIZ_SPIx_CLK RCC_APB1Periph_SPI2 /* 定义W5500所用的SPI接口时钟 */
#define WIZ_SPIx_SCLK GPIO_Pin_13 /* 定义W5500的时钟管脚 */
#define WIZ_SPIx_MISO GPIO_Pin_14 /* 定义W5500的MISO管脚 */
#define WIZ_SPIx_MOSI GPIO_Pin_15 /* 定义W5500的MOSI管脚 */
#define WIZ_SPIx_SCS GPIO_Pin_12 /* 定义W5500的片选管脚 */
#define WIZ_SPIx_SCS_PORT GPIOB /* GPIO端口 */
#define WIZ_SPIx_SCS_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define WIZ_RESET GPIO_Pin_7 /* 定义W5500的RESET管脚 */
#define WIZ_SPIx_RESET_PORT GPIOC /* GPIO端口 */
#define WIZ_SPIx_RESET_CLK RCC_APB2Periph_GPIOC /* GPIO端口时钟 */
#define WIZ_INT GPIO_Pin_6 /* 定义W5500的INT管脚 */
#define WIZ_SPIx_INT_PORT GPIOC /* GPIO端口 */
#define WIZ_SPIx_INT_CLK RCC_APB2Periph_GPIOC /* GPIO端口时钟 */
#define FW_VER_HIGH 1
#define FW_VER_LOW 0
#define ON 1
#define OFF 0
#define HIGH 1
#define LOW 0
#define MAX_BUF_SIZE 1460 /*定义每个数据包的大小*/
#define KEEP_ALIVE_TIME 30 // 30sec
#define TX_RX_MAX_BUF_SIZE 2048
#define IP_FROM_DEFINE 0 /*使用初始定义的IP信息*/
#define IP_FROM_DHCP 1 /*使用DHCP获取IP信息*/
extern uint8 ip_from; /*选择IP信息配置源*/
#pragma pack(1) //以字节对齐
/*此结构体定义了W5500可供配置的主要参数*/
typedef struct _CONFIG_MSG
{
uint8 mac[6]; /*MAC地址*/
uint8 lip[4]; /*local IP本地IP地址*/
uint8 sub[4]; /*子网掩码*/
uint8 gw[4]; /*网关*/
uint8 dns[4]; /*DNS服务器地址*/
uint8 rip[4]; /*remote IP远程IP地址*/
uint8 sw_ver[2]; /*软件版本号*/
} CONFIG_MSG;
#pragma pack()
extern CONFIG_MSG ConfigMsg;
extern uint8 dhcp_ok; /*DHCP获取成功*/
extern uint32 dhcp_time; /*DHCP运行计数*/
extern vu8 ntptimer; /*NPT秒计数*/
/*MCU配置相关函数*/
void gpio_for_w5500_config(void); /*SPI接口reset 及中断引脚*/
void timer2_init(void); /*STM32定时器2初始化*/
void timer2_isr(void); /*定时器中断执行的函数*/
void reboot(void); /*STM32软复位*/
/*W5500SPI相关函数*/
void IINCHIP_WRITE( uint32 addrbsb, uint8 data); /*写入一个8位数据到W5500*/
uint8 IINCHIP_READ(uint32 addrbsb); /*从W5500读出一个8位数据*/
uint16 wiz_write_buf(uint32 addrbsb,uint8* buf,uint16 len); /*向W5500写入len字节数据*/
uint16 wiz_read_buf(uint32 addrbsb, uint8* buf,uint16 len); /*从W5500读出len字节数据*/
/*W5500基本配置相关函数*/
void reset_w5500(void); /*硬复位W5500*/
void set_w5500_mac(void); /*配置W5500的MAC地址*/
void set_w5500_ip(void); /*配置W5500的IP地址*/
/*需要用定时的的应用函数*/
void dhcp_timer_init(void); /*dhcp用到的定时器初始化*/
void ntp_timer_init(void); /*npt用到的定时器初始化*/
#endif
w5500_conf.c 文件内容
w5500_conf.c则是相应的硬件实现
/*
**************************************************************************************************
* @file w5500_conf.c
* @author WIZnet Software Team
* @version V1.0
* @date 2015-02-14
* @brief 配置MCU,移植W5500程序需要修改的文件,配置W5500的MAC和IP地址
**************************************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include "w5500_conf.h"
#include "utility.h"
#include "w5500.h"
#include "dhcp.h"
#include "bsp_TiMbase.h"
CONFIG_MSG ConfigMsg; /*配置结构体*/
/*定义MAC地址,如果多块W5500网络适配板在同一现场工作,请使用不同的MAC地址*/
uint8 mac[6]= {0x00,0x08,0xdc,0x11,0x11,0x11};
/*定义默认IP信息*/
uint8 local_ip[4] = {192,168,1,88}; /*定义W5500默认IP地址*/
uint8 subnet[4] = {255,255,255,0}; /*定义W5500默认子网掩码*/
uint8 gateway[4] = {192,168,1,1}; /*定义W5500默认网关*/
uint8 dns_server[4]= {114,114,114,114}; /*定义W5500默认DNS*/
uint16 local_port=5000; /*定义本地端口*/
/*定义远端IP信息*/
uint8 remote_ip[4]= {192,168,1,102}; /*远端IP地址*/
uint16 remote_port=5000; /*远端端口号*/
/*IP配置方法选择,请自行选择*/
uint8 ip_from=IP_FROM_DHCP;
uint8 dhcp_ok = 0; /*dhcp成功获取IP*/
uint32 ms = 0; /*毫秒计数*/
uint32 dhcp_time = 0; /*DHCP运行计数*/
vu8 ntptimer = 0; /*NPT秒计数*/
/**
*@brief 配置W5500的IP地址
*@param 无
*@return 无
*/
void set_w5500_ip(void)
{
/*复制定义的配置信息到配置结构体*/
memcpy(ConfigMsg.mac, mac, 6);
memcpy(ConfigMsg.lip,local_ip,4);
memcpy(ConfigMsg.sub,subnet,4);
memcpy(ConfigMsg.gw,gateway,4);
memcpy(ConfigMsg.dns,dns_server,4);
if(ip_from==IP_FROM_DEFINE)
printf(" 使用定义的IP信息配置W5500\r\n");
/*使用DHCP获取IP参数,需调用DHCP子函数*/
if(ip_from==IP_FROM_DHCP)
{
/*复制DHCP获取的配置信息到配置结构体*/
if(dhcp_ok==1)
{
printf(" IP from DHCP\r\n");
memcpy(ConfigMsg.lip,DHCP_GET.lip, 4);
memcpy(ConfigMsg.sub,DHCP_GET.sub, 4);
memcpy(ConfigMsg.gw,DHCP_GET.gw, 4);
memcpy(ConfigMsg.dns,DHCP_GET.dns,4);
}
else
{
printf(" DHCP子程序未运行,或者不成功\r\n");
printf(" 使用定义的IP信息配置W5500\r\n");
}
}
/*以下配置信息,根据需要选用*/
ConfigMsg.sw_ver[0]=FW_VER_HIGH;
ConfigMsg.sw_ver[1]=FW_VER_LOW;
/*将IP配置信息写入W5500相应寄存器*/
setSUBR(ConfigMsg.sub);
setGAR(ConfigMsg.gw);
setSIPR(ConfigMsg.lip);
getSIPR (local_ip);
printf(" W5500 IP地址 : %d.%d.%d.%d\r\n", local_ip[0],local_ip[1],local_ip[2],local_ip[3]);
getSUBR(subnet);
printf(" W5500 子网掩码 : %d.%d.%d.%d\r\n", subnet[0],subnet[1],subnet[2],subnet[3]);
getGAR(gateway);
printf(" W5500 网关 : %d.%d.%d.%d\r\n", gateway[0],gateway[1],gateway[2],gateway[3]);
}
/**
*@brief 配置W5500的MAC地址
*@param 无
*@return 无
*/
void set_w5500_mac(void)
{
memcpy(ConfigMsg.mac, mac, 6);
setSHAR(ConfigMsg.mac); /**/
memcpy(DHCP_GET.mac, mac, 6);
}
/**
*@brief 配置W5500的GPIO接口
*@param 无
*@return 无
*/
void gpio_for_w5500_config(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(WIZ_SPIx_RESET_CLK|WIZ_SPIx_INT_CLK, ENABLE);
/* Enable SPI1 and GPIO clocks */
/*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,
SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO
and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */
RCC_APB2PeriphClockCmd(WIZ_SPIx_GPIO_CLK|WIZ_SPIx_SCS_CLK, ENABLE);
/*!< SPI_FLASH_SPI Periph clock enable */
WIZ_SPIx_CLK_CMD(WIZ_SPIx_CLK, ENABLE);
/*!< Configure SPI_FLASH_SPI pins: SCK */
GPIO_InitStructure.GPIO_Pin = WIZ_SPIx_SCLK;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(WIZ_SPIx_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure SPI_FLASH_SPI pins: MISO */
GPIO_InitStructure.GPIO_Pin = WIZ_SPIx_MISO;
GPIO_Init(WIZ_SPIx_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure SPI_FLASH_SPI pins: MOSI */
GPIO_InitStructure.GPIO_Pin = WIZ_SPIx_MOSI;
GPIO_Init(WIZ_SPIx_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */
GPIO_InitStructure.GPIO_Pin = WIZ_SPIx_SCS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(WIZ_SPIx_SCS_PORT, &GPIO_InitStructure);
/* SPI1 configuration */
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_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(WIZ_SPIx, &SPI_InitStructure);
SPI_Cmd(WIZ_SPIx, ENABLE);
/*定义RESET引脚*/
GPIO_InitStructure.GPIO_Pin = WIZ_RESET; /*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*设置引脚速率为50MHz */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚模式为通用推挽输出*/
GPIO_Init(WIZ_SPIx_RESET_PORT, &GPIO_InitStructure); /*调用库函数,初始化GPIO*/
GPIO_SetBits(WIZ_SPIx_RESET_PORT, WIZ_RESET);
/*定义INT引脚*/
GPIO_InitStructure.GPIO_Pin = WIZ_INT; /*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*设置引脚速率为50MHz*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /*设置引脚模式为通用推挽模拟上拉输入*/
GPIO_Init(WIZ_SPIx_INT_PORT, &GPIO_InitStructure); /*调用库函数,初始化GPIO*/
}
/**
*@brief W5500片选信号设置函数
*@param val: 为“0”表示片选端口为低,为“1”表示片选端口为高
*@return 无
*/
void wiz_cs(uint8_t val)
{
if (val == LOW)
{
GPIO_ResetBits(WIZ_SPIx_SCS_PORT, WIZ_SPIx_SCS);
}
else if (val == HIGH)
{
GPIO_SetBits(WIZ_SPIx_SCS_PORT, WIZ_SPIx_SCS);
}
}
/**
*@brief 设置W5500的片选端口SCSn为低
*@param 无
*@return 无
*/
void iinchip_csoff(void)
{
wiz_cs(LOW);
}
/**
*@brief 设置W5500的片选端口SCSn为高
*@param 无
*@return 无
*/
void iinchip_cson(void)
{
wiz_cs(HIGH);
}
/**
*@brief W5500复位设置函数
*@param 无
*@return 无
*/
void reset_w5500(void)
{
GPIO_ResetBits(WIZ_SPIx_RESET_PORT, WIZ_RESET);
delay_us(2);
GPIO_SetBits(WIZ_SPIx_RESET_PORT, WIZ_RESET);
delay_ms(1600);
}
uint8_t SPI_SendByte(uint8_t byte)
{
/* Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(WIZ_SPIx, SPI_I2S_FLAG_TXE) == RESET);
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(WIZ_SPIx, byte);
/* Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(WIZ_SPIx, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(WIZ_SPIx);
}
/**
*@brief STM32 SPI1读写8位数据
*@param dat:写入的8位数据
*@return 无
*/
uint8 IINCHIP_SpiSendData(uint8 dat)
{
return(SPI_SendByte(dat));
}
/**
*@brief 写入一个8位数据到W5500
*@param addrbsb: 写入数据的地址
*@param data:写入的8位数据
*@return 无
*/
void IINCHIP_WRITE( uint32 addrbsb, uint8 data)
{
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8) + 4);
IINCHIP_SpiSendData(data);
iinchip_cson();
}
/**
*@brief 从W5500读出一个8位数据
*@param addrbsb: 写入数据的地址
*@param data:从写入的地址处读取到的8位数据
*@return 无
*/
uint8 IINCHIP_READ(uint32 addrbsb)
{
uint8 data = 0;
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8)) ;
data = IINCHIP_SpiSendData(0x00);
iinchip_cson();
return data;
}
/**
*@brief 向W5500写入len字节数据
*@param addrbsb: 写入数据的地址
*@param buf:写入字符串
*@param len:字符串长度
*@return len:返回字符串长度
*/
uint16 wiz_write_buf(uint32 addrbsb,uint8* buf,uint16 len)
{
uint16 idx = 0;
if(len == 0) printf("Unexpected2 length 0\r\n");
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8) + 4);
for(idx = 0; idx < len; idx++)
{
IINCHIP_SpiSendData(buf[idx]);
}
iinchip_cson();
return len;
}
/**
*@brief 从W5500读出len字节数据
*@param addrbsb: 读取数据的地址
*@param buf:存放读取数据
*@param len:字符串长度
*@return len:返回字符串长度
*/
uint16 wiz_read_buf(uint32 addrbsb, uint8* buf,uint16 len)
{
uint16 idx = 0;
if(len == 0)
{
printf("Unexpected2 length 0\r\n");
}
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8));
for(idx = 0; idx < len; idx++)
{
buf[idx] = IINCHIP_SpiSendData(0x00);
}
iinchip_cson();
return len;
}
/**
*@brief STM32定时器2初始化
*@param 无
*@return 无
*/
void timer2_init(void)
{
TIM2_Configuration(); /* TIM2 定时配置 */
TIM2_NVIC_Configuration(); /* 定时器的中断优先级 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* TIM2 重新开时钟,开始计时 */
}
/**
*@brief dhcp用到的定时器初始化
*@param 无
*@return 无
*/
void dhcp_timer_init(void)
{
timer2_init();
}
/**
*@brief ntp用到的定时器初始化
*@param 无
*@return 无
*/
void ntp_timer_init(void)
{
timer2_init();
}
/**
*@brief 定时器2中断函数
*@param 无
*@return 无
*/
void timer2_isr(void)
{
ms++;
if(ms>=1000)
{
ms=0;
dhcp_time++; /*DHCP定时加1S*/
#ifndef __NTP_H__
ntptimer++; /*NTP重试时间加1S*/
#endif
}
}
/**
*@brief STM32系统软复位函数
*@param 无
*@return 无
*/
void reboot(void)
{
pFunction Jump_To_Application;
uint32 JumpAddress;
printf(" 系统重启中……\r\n");
JumpAddress = *(vu32*) (0x00000004);
Jump_To_Application = (pFunction) JumpAddress;
Jump_To_Application();
}
w5500.h 文件内容
w5500.h 包含各种寄存器bit的定义和相关函数的声明。
/**
******************************************************************************
* @file W5500.h
* @author WIZnet Software Team
* @version V1.0
* @date 2015-02-14
* @brief W5500寄存器地址定义/宏定义等
* @attention
******************************************************************************
**/
#ifndef _W5500_H_
#define _W5500_H_
#include "stm32f10x.h"
#include "Types.h"
#define MR (0x000000)
/**brief Gateway IP Register address*/
#define GAR0 (0x000100)
#define GAR1 (0x000200)
#define GAR2 (0x000300)
#define GAR3 (0x000400)
/**brief Subnet mask Register address*/
#define SUBR0 (0x000500)
#define SUBR1 (0x000600)
#define SUBR2 (0x000700)
#define SUBR3 (0x000800)
/**brief Source MAC Register address*/
#define SHAR0 (0x000900)
#define SHAR1 (0x000A00)
#define SHAR2 (0x000B00)
#define SHAR3 (0x000C00)
#define SHAR4 (0x000D00)
#define SHAR5 (0x000E00)
/**@brief Source IP Register address*/
#define SIPR0 (0x000F00)
#define SIPR1 (0x001000)
#define SIPR2 (0x001100)
#define SIPR3 (0x001200)
/**@brief set Interrupt low level timer register address*/
#define INTLEVEL0 (0x001300)
#define INTLEVEL1 (0x001400)
/**@brief Interrupt Register*/
#define IR (0x001500)
/**@brief Interrupt mask register*/
#define IMR (0x001600)
/**@brief Socket Interrupt Register*/
#define SIR (0x001700)
/**@brief Socket Interrupt Mask Register*/
#define SIMR (0x001800)
/**@brief Timeout register address( 1 is 100us )*/
#define RTR0 (0x001900)
#define RTR1 (0x001A00)
/**@brief Retry count reigster*/
#define WIZ_RCR (0x001B00)
/**@briefPPP LCP Request Timer register in PPPoE mode*/
#define PTIMER (0x001C00)
/**@brief PPP LCP Magic number register in PPPoE mode*/
#define PMAGIC (0x001D00)
/**@brief PPP Destination MAC Register address*/
#define PDHAR0 (0x001E00)
#define PDHAR1 (0x001F00)
#define PDHAR2 (0x002000)
#define PDHAR3 (0x002100)
#define PDHAR4 (0x002200)
#define PDHAR5 (0x002300)
/**
@brief PPP Session Identification Register
*/
#define PSID0 (0x002400)
#define PSID1 (0x002500)
/**@brief PPP Maximum Segment Size(MSS) register*/
#define PMR0 (0x002600)
#define PMR1 (0x002700)
/**@brief Unreachable IP register address in UDP mode*/
#define UIPR0 (0x002800)
#define UIPR1 (0x002900)
#define UIPR2 (0x002A00)
#define UIPR3 (0x002B00)
/**@brief Unreachable Port register address in UDP mode*/
#define UPORT0 (0x002C00)
#define UPORT1 (0x002D00)
/**@brief PHY Configuration Register*/
#define PHYCFGR (0x002E00)
/**@brief chip version register address*/
#define VERSIONR (0x003900)
/**@brief socket Mode register*/
#define Sn_MR(ch) (0x000008 + (ch<<5))
/**@brief channel Sn_CR register*/
#define Sn_CR(ch) (0x000108 + (ch<<5))
/**@brief channel interrupt register*/
#define Sn_IR(ch) (0x000208 + (ch<<5))
/**@brief channel status register*/
#define Sn_SR(ch) (0x000308 + (ch<<5))
/**@brief source port register*/
#define Sn_PORT0(ch) (0x000408 + (ch<<5))
#define Sn_PORT1(ch) (0x000508 + (ch<<5))
/**@brief Peer MAC register address*/
#define Sn_DHAR0(ch) (0x000608 + (ch<<5))
#define Sn_DHAR1(ch) (0x000708 + (ch<<5))
#define Sn_DHAR2(ch) (0x000808 + (ch<<5))
#define Sn_DHAR3(ch) (0x000908 + (ch<<5))
#define Sn_DHAR4(ch) (0x000A08 + (ch<<5))
#define Sn_DHAR5(ch) (0x000B08 + (ch<<5))
/**@brief Peer IP register address*/
#define Sn_DIPR0(ch) (0x000C08 + (ch<<5))
#define Sn_DIPR1(ch) (0x000D08 + (ch<<5))
#define Sn_DIPR2(ch) (0x000E08 + (ch<<5))
#define Sn_DIPR3(ch) (0x000F08 + (ch<<5))
/**@brief Peer port register address*/
#define Sn_DPORT0(ch) (0x001008 + (ch<<5))
#define Sn_DPORT1(ch) (0x001108 + (ch<<5))
/**@brief Maximum Segment Size(Sn_MSSR0) register address*/
#define Sn_MSSR0(ch) (0x001208 + (ch<<5))
#define Sn_MSSR1(ch) (0x001308 + (ch<<5))
#define Sn_PROTO(ch) (0x001408 + (ch<<5))
/** @brief IP Type of Service(TOS) Register */
#define Sn_TOS(ch) (0x001508 + (ch<<5))
/**@brief IP Time to live(TTL) Register */
#define Sn_TTL(ch) (0x001608 + (ch<<5))
/**@brief Receive memory size reigster*/
#define Sn_RXMEM_SIZE(ch) (0x001E08 + (ch<<5))
/**@brief Transmit memory size reigster*/
#define Sn_TXMEM_SIZE(ch) (0x001F08 + (ch<<5))
/**@brief Transmit free memory size register*/
#define Sn_TX_FSR0(ch) (0x002008 + (ch<<5))
#define Sn_TX_FSR1(ch) (0x002108 + (ch<<5))
/**
@brief Transmit memory read pointer register address
*/
#define Sn_TX_RD0(ch) (0x002208 + (ch<<5))
#define Sn_TX_RD1(ch) (0x002308 + (ch<<5))
/**@brief Transmit memory write pointer register address*/
#define Sn_TX_WR0(ch) (0x002408 + (ch<<5))
#define Sn_TX_WR1(ch) (0x002508 + (ch<<5))
/**@brief Received data size register*/
#define Sn_RX_RSR0(ch) (0x002608 + (ch<<5))
#define Sn_RX_RSR1(ch) (0x002708 + (ch<<5))
/**@brief Read point of Receive memory*/
#define Sn_RX_RD0(ch) (0x002808 + (ch<<5))
#define Sn_RX_RD1(ch) (0x002908 + (ch<<5))
/**@brief Write point of Receive memory*/
#define Sn_RX_WR0(ch) (0x002A08 + (ch<<5))
#define Sn_RX_WR1(ch) (0x002B08 + (ch<<5))
/**@brief socket interrupt mask register*/
#define Sn_IMR(ch) (0x002C08 + (ch<<5))
/**@brief frag field value in IP header register*/
#define Sn_FRAG(ch) (0x002D08 + (ch<<5))
/**@brief Keep Timer register*/
#define Sn_KPALVTR(ch) (0x002F08 + (ch<<5))
/* MODE register values */
#define MR_RST 0x80 /**< reset */
#define MR_WOL 0x20 /**< Wake on Lan */
#define MR_PB 0x10 /**< ping block */
#define MR_PPPOE 0x08 /**< enable pppoe */
#define MR_UDP_FARP 0x02 /**< enbale FORCE ARP */
/* IR register values */
#define IR_CONFLICT 0x80 /**< check ip confict */
#define IR_UNREACH 0x40 /**< get the destination unreachable message in UDP sending */
#define IR_PPPoE 0x20 /**< get the PPPoE close message */
#define IR_MAGIC 0x10 /**< get the magic packet interrupt */
/* Sn_MR values */
#define Sn_MR_CLOSE 0x00 /**< unused socket */
#define Sn_MR_TCP 0x01 /**< TCP */
#define Sn_MR_UDP 0x02 /**< UDP */
#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
#define Sn_MR_MACRAW 0x04 /**< MAC LAYER RAW SOCK */
#define Sn_MR_PPPOE 0x05 /**< PPPoE */
#define Sn_MR_UCASTB 0x10 /**< Unicast Block in UDP Multicating*/
#define Sn_MR_ND 0x20 /**< No Delayed Ack(TCP) flag */
#define Sn_MR_MC 0x20 /**< Multicast IGMP (UDP) flag */
#define Sn_MR_BCASTB 0x40 /**< Broadcast blcok in UDP Multicating */
#define Sn_MR_MULTI 0x80 /**< support UDP Multicating */
/* Sn_MR values on MACRAW MODE */
#define Sn_MR_MIP6N 0x10 /**< IPv6 packet Block */
#define Sn_MR_MMB 0x20 /**< IPv4 Multicasting Block */
//#define Sn_MR_BCASTB 0x40 /**< Broadcast blcok */
#define Sn_MR_MFEN 0x80 /**< support MAC filter enable */
/* Sn_CR values */
#define Sn_CR_OPEN 0x01 /**< initialize or open socket */
#define Sn_CR_LISTEN 0x02 /**< wait connection request in tcp mode(Server mode) */
#define Sn_CR_CONNECT 0x04 /**< send connection request in tcp mode(Client mode) */
#define Sn_CR_DISCON 0x08 /**< send closing reqeuset in tcp mode */
#define Sn_CR_CLOSE 0x10 /**< close socket */
#define Sn_CR_SEND 0x20 /**< update txbuf pointer, send data */
#define Sn_CR_SEND_MAC 0x21 /**< send data with MAC address, so without ARP process */
#define Sn_CR_SEND_KEEP 0x22 /**< send keep alive message */
#define Sn_CR_RECV 0x40 /**< update rxbuf pointer, recv data */
#ifdef __DEF_IINCHIP_PPP__
#define Sn_CR_PCON 0x23
#define Sn_CR_PDISCON 0x24
#define Sn_CR_PCR 0x25
#define Sn_CR_PCN 0x26
#define Sn_CR_PCJ 0x27
#endif
/* Sn_IR values */
#ifdef __DEF_IINCHIP_PPP__
#define Sn_IR_PRECV 0x80
#define Sn_IR_PFAIL 0x40
#define Sn_IR_PNEXT 0x20
#endif
#define Sn_IR_SEND_OK 0x10 /**< complete sending */
#define Sn_IR_TIMEOUT 0x08 /**< assert timeout */
#define Sn_IR_RECV 0x04 /**< receiving data */
#define Sn_IR_DISCON 0x02 /**< closed socket */
#define Sn_IR_CON 0x01 /**< established connection */
/* Sn_SR values */
#define SOCK_CLOSED 0x00 /**< closed */
#define SOCK_INIT 0x13 /**< init state */
#define SOCK_LISTEN 0x14 /**< listen state */
#define SOCK_SYNSENT 0x15 /**< connection state */
#define SOCK_SYNRECV 0x16 /**< connection state */
#define SOCK_ESTABLISHED 0x17 /**< success to connect */
#define SOCK_FIN_WAIT 0x18 /**< closing state */
#define SOCK_CLOSING 0x1A /**< closing state */
#define SOCK_TIME_WAIT 0x1B /**< closing state */
#define SOCK_CLOSE_WAIT 0x1C /**< closing state */
#define SOCK_LAST_ACK 0x1D /**< closing state */
#define SOCK_UDP 0x22 /**< udp socket */
#define SOCK_IPRAW 0x32 /**< ip raw mode socket */
#define SOCK_MACRAW 0x42 /**< mac raw mode socket */
#define SOCK_PPPOE 0x5F /**< pppoe socket */
/* IP PROTOCOL */
#define IPPROTO_IP 0 /**< Dummy for IP */
#define IPPROTO_ICMP 1 /**< Control message protocol */
#define IPPROTO_IGMP 2 /**< Internet group management protocol */
#define IPPROTO_GGP 3 /**< Gateway^2 (deprecated) */
#define IPPROTO_TCP 6 /**< TCP */
#define IPPROTO_PUP 12 /**< PUP */
#define IPPROTO_UDP 17 /**< UDP */
#define IPPROTO_IDP 22 /**< XNS idp */
#define IPPROTO_ND 77 /**< UNOFFICIAL net disk protocol */
#define IPPROTO_RAW 255 /**< Raw IP packet */
/*********************************************************
* iinchip access function
*********************************************************/
void iinchip_init(void); // reset iinchip
void socket_buf_init(uint8 * tx_size, uint8 * rx_size); // setting tx/rx buf size
uint8 getISR(uint8 s);
void putISR(uint8 s, uint8 val);
uint16 getIINCHIP_RxMAX(uint8 s);
uint16 getIINCHIP_TxMAX(uint8 s);
void setMR(uint8 val);
void setRTR(uint16 timeout); // set retry duration for data transmission, connection, closing ...
void setRCR(uint8 retry); // set retry count (above the value, assert timeout interrupt)
void clearIR(uint8 mask); // clear interrupt
uint8 getIR( void );
void setSn_MSS(SOCKET s, uint16 Sn_MSSR); // set maximum segment size
uint8 getSn_IR(SOCKET s); // get socket interrupt status
uint8 getSn_SR(SOCKET s); // get socket status
uint16 getSn_TX_FSR(SOCKET s); // get socket TX free buf size
uint16 getSn_RX_RSR(SOCKET s); // get socket RX recv buf size
uint8 getSn_SR(SOCKET s);
void setSn_TTL(SOCKET s, uint8 ttl);
void send_data_processing(SOCKET s, uint8 *wizdata, uint16 len);
void recv_data_processing(SOCKET s, uint8 *wizdata, uint16 len);
void setGAR(uint8 * addr); // set gateway address
void setSUBR(uint8 * addr); // set subnet mask address
void setSHAR(uint8 * addr); // set local MAC address
void setSIPR(uint8 * addr); // set local IP address
void getGAR(uint8 * addr);
void getSUBR(uint8 * addr);
void getSHAR(uint8 * addr);
void getSIPR(uint8 * addr);
void setSn_IR(uint8 s, uint8 val);
void Reset_W5500(void);
extern uint8 txsize[];
extern uint8 rxsize[];
/**
@brief WIZCHIP_OFFSET_INC on IINCHIP_READ/WRITE
* case1.
* IINCHIP_WRITE(RTR0,val);
* IINCHIP_WRITE(RTR1,val);
* case1.
* IINCHIP_WRITE(RTR0,val);
* IINCHIP_WRITE(WIZCHIP_OFFSET_INC(RTR0,1));
*/
//#define WIZCHIP_OFFSET_INC(ADDR, N) (ADDR + (N<<8)) //< Increase offset address
#endif
w5500.c 文件内容
w5500.c则是相应寄存器的访问函数。
/**
******************************************************************************
* @file W5500.c
* @author WIZnet Software Team
* @version V1.0
* @date 2015-02-14
* @brief 读写W5500寄存器底层函数
******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include "w5500_conf.h"
#include "w5500.h"
#include "socket.h"
#ifdef __DEF_IINCHIP_PPP__
#include "md5.h"
#endif
uint16 SSIZE[MAX_SOCK_NUM]= {0,0,0,0,0,0,0,0}; // Max Tx buffer
uint16 RSIZE[MAX_SOCK_NUM]= {0,0,0,0,0,0,0,0}; // Max Rx buffer
uint8 txsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};//tx buffer set K bits
uint8 rxsize[MAX_SOCK_NUM] = {2,2,2,2,2,2,2,2};//rx buffet set K bits
/**
*@brief This function is to get the Max size to receive.
*@param s: socket number
*@return This function return the RX buffer size has been setted
*/
void iinchip_init(void)
{
setMR( MR_RST );
#ifdef __DEF_IINCHIP_DBG__
printf("MR value is %02x \r\n",IINCHIP_READ_COMMON(MR));
#endif
}
/**
*@brief This function is to get the Max size to receive.
*@param s: socket number
*@return This function return the RX buffer size has been setted
*/
uint16 getIINCHIP_RxMAX(SOCKET s)
{
return RSIZE[s];
}
/**
*@brief This function is to get the Max size to receive.
*@param s: socket number
*@return This function return the RX buffer size has been setted
*/
uint16 getIINCHIP_TxMAX(SOCKET s)
{
return SSIZE[s];
}
/**
*@brief This function is to set up gateway IP address.
*@param addr: a pointer to a 4 -byte array responsible to set the Gateway IP address
*@return None
*/
void setGAR(uint8 * addr )
{
wiz_write_buf(GAR0, addr, 4);
}
/**
*@brief This function is to get gateway IP address.
*@param addr: a pointer to a 4 -byte array responsible to get the Gateway IP address
*@return None
*/
void getGAR(uint8 * addr)
{
wiz_read_buf(GAR0, addr, 4);
}
/**
*@brief This function is to set up SubnetMask address
*@param addr: a pointer to a 4 -byte array responsible to set the subway IP address.
*@return None
*/
void setSUBR(uint8 * addr)
{
wiz_write_buf(SUBR0, addr, 4);
}
/**
*@brief This function is to set up MAC address.
*@param addr: a pointer to a 6 -byte array responsible to set the MAC address.
*@return None
*/
void setSHAR(uint8 * addr)
{
wiz_write_buf(SHAR0, addr, 6);
}
/**
*@brief This function is to set up Source IP address.
*@param addr:a pointer to a 4 -byte array responsible to set the Source IP addres.
*@return None
*/
void setSIPR(uint8 * addr)
{
wiz_write_buf(SIPR0, addr, 4);
}
/**
*@brief This function is to get Subnet mask.
*@param addr:a pointer to a 4 -byte array responsible to set the Subnet mask.
*@return None
*/
void getSUBR(uint8 * addr)
{
wiz_read_buf(SUBR0, addr, 4);
}
/**
*@brief This function is to get up Source MAC .
*@param addr: a pointer to a 6 -byte array responsible to get the MAC
*@return None
*/
void getSHAR(uint8 * addr)
{
wiz_read_buf(SHAR0, addr, 6);
}
/**
*@brief This function is to get up Source IP .
*@param addr: a pointer to a 4 -byte array responsible to get the Source IP
*@return None
*/
void getSIPR(uint8 * addr)
{
wiz_read_buf(SIPR0, addr, 4);
}
/**
*@brief This function is to set the MR register.
*@param val: the value to set to MR
*@return None
*/
void setMR(uint8 val)
{
IINCHIP_WRITE(MR,val);
}
/**
*@brief This function is to get Interrupt register in common register.
*@param None
*@return The value read from the IR register
*/
uint8 getIR( void )
{
return IINCHIP_READ(IR);
}
/**
@brief This function is to set up Retransmission time.
If there is no response from the peer or delay in response then retransmission
will be there as per RTR (Retry Time-value Register)setting
*@param timeout: The value write to the RTR0 register
*@return None
*/
void setRTR(uint16 timeout)
{
IINCHIP_WRITE(RTR0,(uint8)((timeout & 0xff00) >> 8));
IINCHIP_WRITE(RTR1,(uint8)(timeout & 0x00ff));
}
/**
@brief This function is to set the number of Retransmission.
If there is no response from the peer or delay in response then recorded time
as per RTR & RCR register seeting then time out will occur.
*@param retry: Times to retry
*@return None
*/
void setRCR(uint8 retry)
{
IINCHIP_WRITE(WIZ_RCR,retry);
}
/**
*@brief This function is to the interrupt mask Enable/Disable appropriate Interrupt. ('1' : interrupt enable)
If any bit in IMR is set as '0' then there is not interrupt signal though the bit is
set in IR register.
*@param mask: the bits to clear
*@return None
*/
void clearIR(uint8 mask)
{
IINCHIP_WRITE(IR, ~mask | getIR() );
}
/**
*@brief This function is to set the maximum segment size of TCP in Active Mode), while in Passive Mode this is set by peer
*@param s: socket number
*@param Sn_MSSR: the maximum segment size
*@return None
*/
void setSn_MSS(SOCKET s, uint16 Sn_MSSR)
{
IINCHIP_WRITE( Sn_MSSR0(s), (uint8)((Sn_MSSR & 0xff00) >> 8));
IINCHIP_WRITE( Sn_MSSR1(s), (uint8)(Sn_MSSR & 0x00ff));
}
/**
*@brief This function is to set the IP Time to live(TTL) Register
*@param s: socket number
*@param Sn_MSSR: the IP Time to live
*@return None
*/
void setSn_TTL(SOCKET s, uint8 ttl)
{
IINCHIP_WRITE( Sn_TTL(s), ttl);
}
/**
*@brief This function is to read the Interrupt & Soket Status registe
*@param s: socket number
*@return socket interrupt status
*/
uint8 getSn_IR(SOCKET s)
{
return IINCHIP_READ(Sn_IR(s));
}
/**
*@brief This function is to write the Interrupt & Soket Status register to clear the interrupt
*@param s: socket number
*@return socket interrupt status
*/
void setSn_IR(uint8 s, uint8 val)
{
IINCHIP_WRITE(Sn_IR(s), val);
}
/**
*@brief This function is to get socket status
*@param s: socket number
*@return socket status
*/
uint8 getSn_SR(SOCKET s)
{
return IINCHIP_READ(Sn_SR(s));
}
/**
*@brief This fuction is to get socket TX free buf size
This gives free buffer size of transmit buffer. This is the data size that user can transmit.
User shuold check this value first and control the size of transmitting data
*@param s: socket number
*@return socket TX free buf size
*/
uint16 getSn_TX_FSR(SOCKET s)
{
uint16 val=0,val1=0;
do
{
val1 = IINCHIP_READ(Sn_TX_FSR0(s));
val1 = (val1 << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
if (val1 != 0)
{
val = IINCHIP_READ(Sn_TX_FSR0(s));
val = (val << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
}
} while (val != val1);
return val;
}
/**
*@brief This fuction is to give size of received data in receive buffer.
*@param s: socket number
*@return socket TX free buf size
*/
uint16 getSn_RX_RSR(SOCKET s)
{
uint16 val=0,val1=0;
do
{
val1 = IINCHIP_READ(Sn_RX_RSR0(s));
val1 = (val1 << 8) + IINCHIP_READ(Sn_RX_RSR1(s));
if(val1 != 0)
{
val = IINCHIP_READ(Sn_RX_RSR0(s));
val = (val << 8) + IINCHIP_READ(Sn_RX_RSR1(s));
}
} while (val != val1);
return val;
}
/**
*@brief This function is being called by send() and sendto() function also.
This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
register. User should read upper byte first and lower byte later to get proper value.
*@param s: socket number
*@param data: data buffer to send
*@param len: data length
*@return socket TX free buf size
*/
void send_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr =0;
uint32 addrbsb =0;
if(len == 0)
{
printf("CH: %d Unexpected1 length 0\r\n", s);
return;
}
ptr = IINCHIP_READ( Sn_TX_WR0(s) );
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR1(s));
addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x10;
wiz_write_buf(addrbsb, data, len);
ptr += len;
IINCHIP_WRITE( Sn_TX_WR0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE( Sn_TX_WR1(s),(uint8)(ptr & 0x00ff));
}
/**
*@brief This function is being called by recv() also.
This function read the Rx read pointer register
and after copy the data from receive buffer update the Rx write pointer register.
User should read upper byte first and lower byte later to get proper value.
*@param s: socket number
*@param data: data buffer to receive
*@param len: data length
*@return None
*/
void recv_data_processing(SOCKET s, uint8 *data, uint16 len)
{
uint16 ptr = 0;
uint32 addrbsb = 0;
if(len == 0)
{
printf("CH: %d Unexpected2 length 0\r\n", s);
return;
}
ptr = IINCHIP_READ( Sn_RX_RD0(s) );
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ( Sn_RX_RD1(s) );
addrbsb = (uint32)(ptr<<8) + (s<<5) + 0x18;
wiz_read_buf(addrbsb, data, len);
ptr += len;
IINCHIP_WRITE( Sn_RX_RD0(s), (uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE( Sn_RX_RD1(s), (uint8)(ptr & 0x00ff));
}
/**
*@brief This function set the transmit & receive buffer size as per the channels is used
*@Note: TMSR and RMSR bits are as follows\n
Maximum memory size for Tx, Rx in the W5500 is 16K Bytes,\n
In the range of 16KBytes, the memory size could be allocated dynamically by each channel.\n
Be attentive to sum of memory size shouldn't exceed 8Kbytes\n
and to data transmission and receiption from non-allocated channel may cause some problems.\n
If the 16KBytes memory is already assigned to centain channel, \n
other 3 channels couldn't be used, for there's no available memory.\n
If two 4KBytes memory are assigned to two each channels, \n
other 2 channels couldn't be used, for there's no available memory.\n
*@param tx_size: tx buffer size to set=tx_size[s]*(1024)
*@param rx_size: rx buffer size to set=rx_size[s]*(1024)
*@return None
*/
void socket_buf_init( uint8 * tx_size, uint8 * rx_size )
{
int16 i;
int16 ssum=0,rsum=0;
for (i = 0 ; i < MAX_SOCK_NUM; i++) // Set the size, masking and base address of Tx & Rx memory by each channel
{
IINCHIP_WRITE( (Sn_TXMEM_SIZE(i)), tx_size[i]);
IINCHIP_WRITE( (Sn_RXMEM_SIZE(i)), rx_size[i]);
#ifdef __DEF_IINCHIP_DBG__
printf("tx_size[%d]: %d, Sn_TXMEM_SIZE = %d\r\n",i, tx_size[i], IINCHIP_READ(Sn_TXMEM_SIZE(i)));
printf("rx_size[%d]: %d, Sn_RXMEM_SIZE = %d\r\n",i, rx_size[i], IINCHIP_READ(Sn_RXMEM_SIZE(i)));
#endif
SSIZE[i] = (int16)(0);
RSIZE[i] = (int16)(0);
if (ssum <= 16384)
{
SSIZE[i] = (int16)tx_size[i]*(1024);
}
if (rsum <= 16384)
{
RSIZE[i]=(int16)rx_size[i]*(1024);
}
ssum += SSIZE[i];
rsum += RSIZE[i];
}
}
type.h 文件内容
type.h包含了部分变量类型的定义。
#ifndef _TYPE_H_
#define _TYPE_H_
#define MAX_SOCK_NUM 8 /**< Maxmium number of socket */
typedef char int8;
typedef volatile char vint8;
typedef unsigned char uint8;
typedef volatile unsigned char vuint8;
typedef int int16;
typedef unsigned short uint16;
typedef long int32;
typedef unsigned long uint32;
typedef uint8 u_char; /**< 8-bit value */
typedef uint8 SOCKET;
typedef uint16 u_short; /**< 16-bit value */
typedef uint16 u_int; /**< 16-bit value */
typedef uint32 u_long; /**< 32-bit value */
typedef union _un_l2cval
{
u_long lVal;
u_char cVal[4];
} un_l2cval;
typedef union _un_i2cval
{
u_int iVal;
u_char cVal[2];
} un_i2cval;
#endif /* _TYPE_H_ */
socket.h 文件内容
socket.h中包含各种函数的声明,因为w5500含有8个socket,每个通信都需要指定相应的socket。
#ifndef _SOCKET_H_
#define _SOCKET_H_
#include "stm32f10x.h"
#include "Types.h"
/*Socket 端口选择,可按自己的习惯定义*/
#define SOCK_TCPS 0
#define SOCK_HUMTEM 0
#define SOCK_PING 0
#define SOCK_TCPC 1
#define SOCK_UDPS 2
#define SOCK_WEIBO 2
#define SOCK_DHCP 3
#define SOCK_HTTPS 4
#define SOCK_DNS 5
#define SOCK_SMTP 6
#define SOCK_NTP 7
//#define NETBIOS_SOCK 6 //在netbios.c已定义
extern uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag); // Opens a socket(TCP or UDP or IP_RAW mode)
extern void close(SOCKET s); // Close socket
extern uint8 connect(SOCKET s, uint8 * addr, uint16 port); // Establish TCP connection (Active connection)
extern void disconnect(SOCKET s); // disconnect the connection
extern uint8 listen(SOCKET s); // Establish TCP connection (Passive connection)
extern uint16 send(SOCKET s, const uint8 * buf, uint16 len); // Send data (TCP)
extern uint16 recv(SOCKET s, uint8 * buf, uint16 len); // Receive data (TCP)
extern uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port); // Send data (UDP/IP RAW)
extern uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port); // Receive data (UDP/IP RAW)
#ifdef __MACRAW__
void macraw_open(void);
uint16 macraw_send( const uint8 * buf, uint16 len ); //Send data (MACRAW)
uint16 macraw_recv( uint8 * buf, uint16 len ); //Recv data (MACRAW)
#endif
#endif
/* _SOCKET_H_ */
socket.c 文件内容
socket.c文件是socket接口函数的实现。
/**
******************************************************************************
* @file Socket.c
* @author WIZnet Software Team
* @version V1.0
* @date 2015-xx-xx
* @brief Socket编程相关函数
******************************************************************************
*/
#include "socket.h"
#include "W5500_conf.h"
#include "stdio.h"
#include "w5500.h"
/**
*@brief This Socket function initialize the channel in perticular mode,
and set the port and wait for W5200 done it.
*@param s: socket number.
*@param protocol: The socket to chose.
*@param port:The port to bind.
*@param flag: Set some bit of MR,such as **< No Delayed Ack(TCP) flag.
*@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
*@param s: socket number.
*@return None
*/
void close(SOCKET s)
{
IINCHIP_WRITE( Sn_CR(s) ,Sn_CR_CLOSE);
/* wait to process the command... */
while( IINCHIP_READ(Sn_CR(s) ) )
;/* ------- */
IINCHIP_WRITE( Sn_IR(s) , 0xFF); /* all clear */
}
/**
*@brief This function established the connection for the channel in passive (server) mode.
This function waits for the request from the peer.
*@param s: socket number.
*@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.
*@param s: socket number.
*@param addr: The server IP address to connect
*@param port: The server IP port to connect
*@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 s
*@param s: 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
*@param s: socket number.
*@param buf: data buffer to send.
*@param len: data length.
*@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.
*@param s: socket number.
*@param buf: data buffer to receive.
*@param len: data length.
*@return received data size for success else 0.
*/
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.
*@param s: socket number.
*@param buf: data buffer to send.
*@param len: data length.
*@param addr: IP address to send.
*@param port: IP port to send.
*@return This function return send data size for success else 0.
*/
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);
/* 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.
*@param s: socket number.
*@param buf: data buffer to receive.
*@param len: data length.
*@param addr: IP address to receive.
*@param port: IP port to receive.
*@return This function return received data size for success else 0.
*/
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 :
// printf("\r\n Sn_MR_IPRAW \r\n");
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;
// printf(" data:%d \r\n",data_len);
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 :
// printf("\r\n Sn_MR_MCRAW \r\n");
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__
/**
*@brief OPen the 0-th socket with MACRAW mode
*@param None
*@return None
*/
void macraw_open(void)
{
uint8 sock_num=0;
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);
}
/**
*@brief OPen the 0-th socket with MACRAW mode
*@param buf: data buffer to send.
*@param len: data length.
*@return This function return sended data size for success else 0.
*/
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;
}
/**
*@brief OPen the 0-th socket with MACRAW mode
*@param buf: data buffer to send.
*@param len: data length.
*@return This function return received data size for success else 0.
*/
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);
/** 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