中级会员
- 积分
- 241
- 金钱
- 241
- 注册时间
- 2015-12-9
- 在线时间
- 84 小时
|
就是socket0和socket1同时做客户端 有一个进不了中断,单独的时候是可以的。
/**********************************************************************************
* @file usr/bsp/src/w5500.c
* @author 泥人通信模块开发团队
* @revise cyq
* @version v1.0
* @date 2016.01.16
* @brief 本文件进行W5500的驱动工作
**********************************************************************************/
#include "inc.h"
#include <stdarg.h>
/* #include "w5500.h" */
/**
* 接口
*/
/* INT RST _GPIO */
#define w55INT_INT vB0_NVIC(); vB0_Init()
#define w55RST_INT vB1_Init()
#define w55RST_LOW GPIO_ResetBits(GPIOB, GPIO_Pin_1)
#define w55RST_HIGH GPIO_SetBits(GPIOB, GPIO_Pin_1)
/* INT中端屏蔽,line0 */
#define w55INT_OFF EXTI->IMR &=~(1<<0)
/* INT中端开启,关闭过程中的中断不需要放弃,故不清标记 */
#define w55INT_ON /* EXTI->PR=1<<11; */ EXTI->IMR |= (1<<0)
/* SPI通信相关 */
#define w55SPI_INIT vSPI3_cfg()
#define w55CS_LOW GPIO_ResetBits(GPIOA, GPIO_Pin_15)
#define w55CS_HIGH GPIO_SetBits(GPIOA, GPIO_Pin_15)
#define w55SPI_SEND_BYTE(d) ucSPI3_SendByte(d)
/* 毫秒延时 所需延时时间很短且在初始操作时使用 不要用RTOS的等待 */
#define w55DELAY_MS(t) vDelay_ms(t)
/**
* 数据变量类型
*/
/* 运行状态 */
u8 ucSocketState[w55USE_SOCKET_NUM] = {0,0,};
u8 Socket_SendOK[w55USE_SOCKET_NUM] = {0,0};
u8 Socket_SendTimeOut[w55USE_SOCKET_NUM] = {0,0};
/**
* 函数声明
*/
static void prvSetCache(void);
static void prvSetLocalNet(void);
#if 0
static u8 prvDetectGateway(void);
#endif
static void prvSocket0Handle(void);
static void prvSocket1Handle(void);
void prvWriteSocketByte(SOCKET s, u16 reg, u8 dat);
static void prvWriteSocket2Byte(SOCKET s, u16 reg, u16 dat);
static u16 prvReadSocket2Byte(SOCKET s, u16 reg);
static void prvWriteSocket4Byte(SOCKET s, u16 reg, u8 *dat_ptr);
static void prvSendShort(u16 dat);
/**
* W5500初始化,进行通信接口初始化以及一些必要的寄存器操作
*/
void vW5500Init(void)
{
w55SPI_INIT; /* SPI初始化里的时序部分两版本不一致,参考官方资料看一下 */
w55INT_INT;
w55RST_INT;
vW5500Rst();
prvSetCache();
prvSetLocalNet();
/* prvDetectGateway(); */ /* 经测试,该语句不运行无影响 */
}
/**
* 硬件复位
*/
void vW5500Rst(void)
{
w55RST_LOW;
vDelay_ms(2);
w55RST_HIGH;
vDelay_ms(1000); /* 原1600 */
/* vWriteRegByte(MR, RST); */ /* 软件复位W5500 */
/* vDelay_ms(10); */
}
/**
* 设置Tx Rx缓存区域大小
*/
void prvSetCache(void)
{
u8 i;
for (i = 0;i < 8;i++) {
prvWriteSocketByte(i,Sn_RXBUF_SIZE, 0x02); /* Socket Rx memory size=2k */
prvWriteSocketByte(i,Sn_TXBUF_SIZE, 0x02); /* Socket Tx mempry size=2k */
}
}
/**
* 设置本地网络参数
*/
void prvSetLocalNet(void)
{
u8 mac[6] = w55MAC_ADDR;
u8 gate[4];
// u8 gate1[4];
u8 mask[4] = {255,255,255,0};
gate[0] = 192;
gate[1] = 168;
gate[2] = 254;
gate[3] = 1;
vWriteRegByteBuf(GAR, gate, 4);
vWriteRegByteBuf(SUBR,mask,4);
// vWriteRegByteBuf(GAR, gate1, 4);
// vWriteRegByteBuf(SUBR,mask,4);
/* 设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,唯一标识 */
/* 该地址需要到IEEE申请,按照OUI的规定,前三个字节为厂商代码,后三个字节为产品序号 */
/* 如果自己定义物理地址,注意第一个字节必须为偶数 */
vWriteRegByteBuf(SHAR,mac,6);
vWriteRegByteBuf(SIPR,w55LOCAL_IP,4);
//vWriteRegByteBuf(SHAR,mac,6);
// vWriteRegByteBuf(SIPR,w55SERLOCAL_IP,4);
}
/**
* 启动指定端口的中断
* 根据实际需求开启需要工作的中断
*/
void vEnSocketInterrupt(void)
{
/* 启动中断,参考w5500数据手册确定自己需要的中断类型 */
/* IMR_CONFLICT是IP地址冲突异常中断,IMR_UNREACH是UDP通信时,地址无法到达的异常中断 */
/* 其它是Socket事件中断,根据需要添加 */
vWriteRegByte(wIMR,IM_IR7 | IM_IR6|IM_IR5|IM_IR4);
vWriteRegByte(SIMR,S0_IMR);
prvWriteSocketByte(0, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON); /* IMR_SENDOK 发送数据完成中断 */
vWriteRegByte(SIMR,S1_IMR);
prvWriteSocketByte(1, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);
}
#if 0
/**
* 检查端口网关服务器打开端口
* 成功返回0xff,失败返回0x00
*/
u8 prvDetectGateway(void)
{
u8 ip_adde[4];
ip_adde[0] = w55LOCAL_IP[0]+1;
ip_adde[1] = w55LOCAL_IP[1]+1;
ip_adde[2] = w55LOCAL_IP[2]+1;
ip_adde[3] = w55LOCAL_IP[3]+1;
/* 检查网关及获取网关的物理地址 */
prvWriteSocket4Byte(0,Sn_DIPR,ip_adde); /* 向目的地址寄存器写入与本机Ip不同的Ip值 */
prvWriteSocketByte(0,Sn_MR,MR_TCP); /* 设置socket为tcp模式 */
prvWriteSocketByte(0,Sn_CR,OPEN); /* 打开socket */
w55DELAY_MS(5);
/* 如果socket打开失败 */
if(vReadSocketByte(0,Sn_SR) != SOCK_INIT) {
prvWriteSocketByte(0,Sn_CR,CLOSE); /* 打开不成功,关闭socket */
return 0x00;
}
prvWriteSocketByte(0,Sn_CR,CONNECT); /* 设置socket为connect模式 */
do
{
u8 j=0;
j = vReadSocketByte(0,Sn_IR); /* 读取socket0中断标志寄存器 */
if (j!=0)
prvWriteSocketByte(0,Sn_IR,j);
w55DELAY_MS(5);
if ((j&IR_TIMEOUT) == IR_TIMEOUT) {
return 0x00;
}
else if(vReadSocketByte(0,Sn_DHAR) != 0xff) {
prvWriteSocketByte(0,Sn_CR,CLOSE); /* 关闭socket */
return 0xff;
}
}while(1);
}
#endif
/**
* 设置工作在客户端模式的端口的本地端口号及目标网络参数
*/
void vSocketClientSet(SOCKET s,u16 locport,u8* serip,u16 serport)
{
/* 设置分片长度,W5500数据手册,改值可以不修改 */
prvWriteSocket2Byte(s, Sn_MSSR, 1460); /* 最大分片字节数=1460(0x5b4) */
/* 设置端口的端口号 */
prvWriteSocket2Byte(s, Sn_PORT, locport);
/* 设置端口目的端口号 */
prvWriteSocket2Byte(s, Sn_DPORTR, serport);
/* 设置端口目的Ip地址 */
prvWriteSocket4Byte(s, Sn_DIPR, serip);
}
/**
* 设置工作在服务端模式下的端口的本地端口号
*/
void vSocketServerSet(SOCKET s,u16 locport)
{
/* 设置分片长度,W5500数据手册,改值可以不修改 */
prvWriteSocket2Byte(s, Sn_MSSR, 1460); /* 最大分片字节数=1460(0x5b4) */
/* 设置端口0的端口号 */
prvWriteSocket2Byte(s, Sn_PORT, locport);
}
/**
* 设置指定端口为UDP模式,并且设置本地端口
*/
u8 ucSocketUDPSet(SOCKET s,u16 locport)
{
prvWriteSocket2Byte(s, Sn_PORT, locport);
prvWriteSocketByte(s,Sn_MR,MR_UDP); /* 设置为UDP模式 */
prvWriteSocketByte(s,Sn_CR,OPEN); /* 打开端口 */
w55DELAY_MS(5);
if(vReadSocketByte(s,Sn_SR) != SOCK_UDP) /* 如果打开失败 */
{
prvWriteSocketByte(s,Sn_CR,CLOSE); /* 关闭端口 */
return 0x00;
}
ucSocketState[s] = w55S_CONN;
return 0xff;
}
/**
* 指定端口与远程服务器连接
* 成功返回TRUE(0xFF),失败返回FALSE(0x00)
* 当本机Socket工作在客户端时,引用该程序,与远程服务器建立连接
* 如果启动连接后出现超时中断,则与服务器连接失败,需要重新调用该程序连接
* 该程序每调用一次,就与服务器产生一次连接
*/
u8 vSocketConnect(SOCKET s)
{
prvWriteSocketByte(s,Sn_MR,MR_TCP); /* 设置socket为tcp模式 */
prvWriteSocketByte(s,Sn_CR,OPEN); /* 打开socket */
w55DELAY_MS(5);
/* 如果socket打开失败 */
if(vReadSocketByte(s,Sn_SR)!=SOCK_INIT) {
prvWriteSocketByte(s,Sn_CR,CLOSE); /* 打开不成功,关闭socket */
return FALSE;
}
prvWriteSocketByte(s,Sn_CR,CONNECT); /* 设置socket为connect模式 */
return TRUE;
}
/**
* 设置指定socket(0-7)作为服务器等待远程主机的连接
* 当本机socket工作在服务器模式时,引用该程序,等待远程主机的连接
* 该程序只调用一次,就使w5500设置为服务器模式
*/
u8 vSocketListen(SOCKET s)
{
prvWriteSocketByte(s,Sn_MR,MR_TCP); /* 设置socket为tcp模式 */
prvWriteSocketByte(s,Sn_CR,OPEN); /* 打开socket */
w55DELAY_MS(5);
/* 如果socket打开失败 */
if(vReadSocketByte(s,Sn_SR)!=SOCK_INIT) {
prvWriteSocketByte(s,Sn_CR,CLOSE); /* 打开不成功,关闭socket */
return 0x00;
}
prvWriteSocketByte(s,Sn_CR,LISTEN); /* 设置socket为侦听模式 */
w55DELAY_MS(5);
/* 如果socket设置失败 */
if(vReadSocketByte(s,Sn_SR)!=SOCK_LISTEN) {
prvWriteSocketByte(s,Sn_CR,CLOSE); /* 设置不成功,关闭socket */
return 0x00;
}
return 0xff;
/* 至此完成了socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待socket中断
* 以判断socket的连接是否成功,参考w5500数据手册的socket中断状态
* 在服务器侦听模式下不需要设置目的IP和端口 */
}
/**
* 将数据写入w5500的数据发送缓存区
*/
void vWriteSocketDataBuffer(SOCKET s, u8 *dat_ptr, u16 size)
{
u16 offset,offset1;
u16 i;
if (ucSocketState[s] != w55S_CONN) {
return;
}
w55INT_OFF;
offset = prvReadSocket2Byte(s,Sn_TX_WR);
offset1 = offset;
offset &= (S_TX_SIZE - 1); /* 计算实际的物理地址 */
w55CS_LOW;
prvSendShort(offset); /* 写16位地址 */
w55SPI_SEND_BYTE(VDM|RWB_WRITE|(s * 0x20 + 0x10)); /* 写控制字节,N个字节数据长度,写数据,选择端口s的寄存器 */
/* 如果最大地址未超过w5500发送缓存区的最大地址 */
if ((offset+size) < S_TX_SIZE) {
/* 循环写入size各字节数据 */
for (i = 0;i < size;i++) {
w55SPI_SEND_BYTE(*dat_ptr++); /* 写入一个字节的数据 */
}
}
/* 如果最大地址超过w5500发送缓存区的最大地址 */
else {
offset = S_TX_SIZE - offset;
/* 循环写入前offest个字节数据 */
for (i = 0;i < offset;i++) {
w55SPI_SEND_BYTE(*dat_ptr++); /* 写入一个字节的数据 */
}
w55CS_HIGH;
w55CS_LOW;
prvSendShort(0x00); /* 写16位地址 */
w55SPI_SEND_BYTE(VDM | RWB_WRITE | (s * 0x20 + 0x10)); /* 写控制字节,N个字节数据长度,写数据,选择端口S的寄存器 */
/* 循环写入size-offest个字节数据 */
for(;i < size;i++) {
w55SPI_SEND_BYTE(*dat_ptr++); /* 写入一个字节的数据 */
}
}
w55CS_HIGH;
offset1 += size; /* 更新实际物理地址,即下次写带发送数据到发送缓存区的起始地址 */
prvWriteSocket2Byte(s, Sn_TX_WR, offset1);
prvWriteSocketByte(s, Sn_CR, SEND); /* 启动发送命令 */
w55INT_ON;
}
/**
* 将数据写入w5500的数据发送缓存区
* UDP模式专用,指定IP和端口
* 返回 1 - 成功发送
* 2 - 发送超时
*/
u8 ucUDPSendDataBuffer(SOCKET s, u8 *dat_ptr, u16 size,u8* ip,u16 port)
{
/* 设置端口目的端口号 */
prvWriteSocket2Byte(s, Sn_DPORTR, port);
/* 设置端口目的Ip地址 */
prvWriteSocket4Byte(s, Sn_DIPR, ip);
Socket_SendTimeOut[s] = 0;
Socket_SendOK[s] = 0;
vWriteSocketDataBuffer(s,dat_ptr,size);
while(1) {
if (Socket_SendOK[s] == 1) {
return 1;
}
else if(Socket_SendTimeOut[s] == 1) {
return 2;
}
}
}
/**
* 从w5500接收数据缓存区中读取数据
* 返回值:读取到的数据长度,rx_size个字节
*/
u16 vReadSocketDataBuffer(SOCKET s, void (*rec)(u8 d))
{
u16 rx_size;
u16 offset, offset1;
u16 i;
rx_size = prvReadSocket2Byte(s,Sn_RX_RSR);
if(rx_size==0)
return 0; /* 没接收到数据则返回 */
if(rx_size>1460)
rx_size=1460;
offset = prvReadSocket2Byte(s,Sn_RX_RD);
offset1 = offset;
offset &= (S_RX_SIZE-1); /* 计算实际的物理地址 */
w55CS_LOW;
prvSendShort(offset); /* 写16位地址 */
w55SPI_SEND_BYTE(VDM|RWB_READ|(s*0x20+0x18)); /* 写控制字节,N个字节数据长度,读数据,选择端口S的寄存器 */
/* 如果最大地址未超过W5500接收缓存区的最大地址 */
if ((offset + rx_size) < S_RX_SIZE) {
/* 选换读取rx_size个字节数据 */
for(i = 0;i < rx_size;i++) {
rec(w55SPI_SEND_BYTE(0x00)); /* 发送一个哑数据读取数据 */
}
}
/* 如果最大地址超过w5500接收缓存区的最大地址 */
else {
offset = S_RX_SIZE - offset;
for(i = 0;i < offset;i++) {
rec(w55SPI_SEND_BYTE(0x00));
}
w55CS_HIGH;
w55CS_LOW;
prvSendShort(0x00); /* 写16位地址 */
w55SPI_SEND_BYTE(VDM|RWB_READ|(s*0x20+0x18)); /* 写控制字节,N个字节数据长度,读数据,选择端口s的寄存器 */
/* 循环读取后rx_size-offset个字节数据 */
for(;i < rx_size;i++) {
rec(w55SPI_SEND_BYTE(0x00));
}
}
w55CS_HIGH;
offset1 += rx_size; /* 更新实际物理地址,即下次读取接收到的数据的起始地址 */
prvWriteSocket2Byte(s, Sn_RX_RD, offset1);
prvWriteSocketByte(s, Sn_CR, RECV); /* 发送启动接收命令 */
return rx_size; /* 返回接收到数据的长度 */
}
/**
* Socket0中断处理
* 根据实际需求修改内部各种情况发生的处理代码
*/
void prvSocket0Handle(void)
{
u8 j;
j = vReadSocketByte(0,Sn_IR); /* 读取Socket0中断标志寄存器 */
prvWriteSocketByte(0,Sn_IR,j);
/* 在tcp模式下socket成功连接 */
if (j & IR_CON) {
ucSocketState[0] = w55S_CONN;
}
/* 在tcp模式下 断开连接 */
if (j & IR_DISCON) {
vSocketConnect(0);
ucSocketState[0] = w55S_INIT;
}
#if 1
/* Socket0数据发送完成 */
if (j & IR_SEND_OK) {
// Socket_SendOK[0] = 1;
}
#endif
/* Socket接收到数据 */
if (j & IR_RECV) {
xServerRx.path = 0X04;
vReadSocketDataBuffer(0,vRecUpperDat);
}
/* Socket连接或数据传输超时处理 */
if (j & IR_TIMEOUT) {
// Socket_SendOK[0] = 1;
prvWriteSocketByte(0,Sn_CR,CLOSE); /* 关闭端口 */
ucSocketState[0] = w55S_INIT;
vSocketConnect(0);
}
}
/**
* Socket1中断处理
* 根据实际需求修改内部各种情况发生的处理代码
*/
void prvSocket1Handle(void)
{
u8 k;
k = vReadSocketByte(1,Sn_IR); /* 读取Socket1中断标志寄存器 */
prvWriteSocketByte(1,Sn_IR,k);
/* 在tcp模式下socket成功连接 */
if (k & IR_CON) {
ucSocketState[1] = w55S_CONN;
}
/* 在tcp模式下 客户端主动断开 */
if (k & IR_DISCON) {
vSocketConnect(1);
ucSocketState[1] = w55S_INIT;
}
#if 0
/* Socket0数据发送完成 */
if (k & IR_SEND_OK) {
Socket_SendOK[1] = 1;
}
#endif
/* Socket接收到数据 */
if (k & IR_RECV) {
xServerRx.path = PATH_NET;
vReadSocketDataBuffer(1,vRecUpperDat);
}
/* Socket连接或数据传输超时处理 */
if (k & IR_TIMEOUT) {
prvWriteSocketByte(1,Sn_CR,CLOSE); /* 关闭端口 */
ucSocketState[1] = w55S_INIT;
vSocketConnect(1);
}
}
/**
* W5500中断处理框架
*/
void vW5500InterruptProcess(void)
{
u8 i;
IntDispose:
i = vReadRegByte(IR); /* 读取中断标志寄存器 */
vWriteRegByte(IR, (i&0xf0)); /* 回写清除中断标志 */
#if 0
/* 以下两个中断没有使能 */
/* IP地址冲突异常处理 */
if ((i & CONFLICT) == CONFLICT) {
;
}
/* UDP模式下地址无法到达异常处 */
if ((i & UNREACH) == UNREACH) {
;
}
#endif
i = vReadRegByte(SIR); /* 读取端口中断标志寄存器 */
/* Socket0事件处理 */
if((i & S0_INT) == S0_INT) {
prvSocket0Handle();
}
if ((i & S1_INT) == S1_INT) {
prvSocket1Handle();
}
/* 处理完当前中断后如果又有中断发生 */
if(vReadRegByte(SIR) != 0) {
goto IntDispose;
}
}
/**
* 通过SPI接口向W5500指定端口,指定寄存器中写入指定的一个字节数据
*/
void prvWriteSocketByte(SOCKET s, u16 reg, u8 dat)
{
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM1 | RWB_WRITE | (s * 0x20 + 0x08)); /* 通过SPI1写控制字节,1个字节数据长度,写数据,选择端口s的寄存器 */
w55SPI_SEND_BYTE(dat); /* 写1个字节数据 */
w55CS_HIGH;
}
/**
* 读取w5500指定端口指定寄存器的一个字节数据
*/
u8 vReadSocketByte(SOCKET s, u16 reg)
{
u8 i;
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM1|RWB_READ|(s*0x20+0x08)); /* 通过SPI1写控制字节,1个字节数据长度,读数据,选择端口s的寄存器 */
i = w55SPI_SEND_BYTE(0x00); /* 发送一个哑数据 */
w55CS_HIGH;
return i;
}
/**
* 通过SPI接口向指定端口指定寄存器写入两个字节数据
*/
void prvWriteSocket2Byte(SOCKET s, u16 reg, u16 dat)
{
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM2|RWB_WRITE|(s*0x20+0x08)); /* 通过SPI1写控制字节,2个字节数据长度,写数据,选择端口s的寄存器 */
prvSendShort(dat); /* 写16位数据 */
w55CS_HIGH;
}
/**
* 读指定端口寄存器的2个字节数据
*/
u16 prvReadSocket2Byte(SOCKET s, u16 reg)
{
u16 i;
w55CS_LOW;
prvSendShort(reg); /* 通过SPI写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM2|RWB_READ|(s*0x20+0x08)); /* 通过SPI1写控制字节,2个字节数据长度,读数据,选择端口s的寄存器 */
i= w55SPI_SEND_BYTE(0x00); /* 发送一个哑数据 */
i*=256;
i += w55SPI_SEND_BYTE(0x00);
w55CS_HIGH;
return i;
}
/**
* 通过SPI接口向W5500指定端口,指定寄存器中写入指定的四个字节数据
*/
void prvWriteSocket4Byte(SOCKET s, u16 reg, u8 *dat_ptr)
{
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM4 | RWB_WRITE | (s * 0x20 + 0x08)); /* 通过SPI1写控制字节,4个字节数据长度,写数据,选择端口s的寄存器 */
w55SPI_SEND_BYTE(*dat_ptr++); /* 写第1个字节数据 */
w55SPI_SEND_BYTE(*dat_ptr++); /* 写第2个字节数 */
w55SPI_SEND_BYTE(*dat_ptr++); /* 写第3个字节数据 */
w55SPI_SEND_BYTE(*dat_ptr++); /* 写第4个字节数据 */
w55CS_HIGH;
}
/**
* 通过SPI接口向W5500指定寄存器发送指定的一个字节
*/
void vWriteRegByte(u16 reg, u8 dat)
{
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM1|RWB_WRITE|COMMON_R); /* 通过SPI1写控制字节,1个字节数据长度,写数据,选择通用寄存器 */
w55SPI_SEND_BYTE(dat); /* 写1个字节数据 */
w55CS_HIGH;
}
/**
* 从指定寄存器读出一个字节数据
*/
u8 vReadRegByte(u16 reg)
{
u8 i;
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(FDM1|RWB_READ|COMMON_R); /* 通过SPI1写控制字节,1个字节数据长度,读数据,选择通用寄存器 */
i = w55SPI_SEND_BYTE(0x00); /* 发送一个哑数据 */
w55CS_HIGH;
return i;
}
/**
* 通过SPI接口向W5500指定寄存器发送指定的一串字节
*/
void vWriteRegByteBuf(u16 reg, u8 *dat_ptr, u16 size)
{
u16 i;
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(VDM|RWB_WRITE|COMMON_R); /* 通过SPI1写控制字节,N个字节数据长度,写数据,选择通用寄存器 */
/* 循环将缓冲区的size个字节数据写入W5500 */
for (i = 0;i < size;i++) {
w55SPI_SEND_BYTE(*dat_ptr++);
}
w55CS_HIGH;
}
/**
* 通过SPI接口从W5500指定寄存器读出的一串字节
*/
void vReadRegByteBuf(u16 reg, u8 *dat_ptr, u16 size)
{
u16 i;
w55CS_LOW;
prvSendShort(reg); /* 通过SPI1写16位寄存器地址 */
w55SPI_SEND_BYTE(VDM|RWB_READ|COMMON_R); /* 通过SPI1写控制字节,N个字节数据长度,读数据,选择通用寄存器 */
/* 循环发送哑数据读出数据 */
for (i = 0;i < size;i++) {
*dat_ptr++ = w55SPI_SEND_BYTE(0x00);
}
w55CS_HIGH;
}
/**
* 通过SPI接口向W5500发送一个16位的数据
*/
void prvSendShort(u16 dat)
{
w55SPI_SEND_BYTE((u8)(dat >> 8)); /* 写数据高位 */
w55SPI_SEND_BYTE((u8)(dat & 0x00FF)); /* 写数据低位 */
}
/***********************************end*************************************/
|
|