Skip to content

Clion IDE-STM32+W5500 (DHCP code encapsulation)

Clion IDE-STM32+W5500 (DHCP code encapsulation)

mark

Published October 04, 2023

Original author: 詩不诉卿 · ChinaOriginal source (new tab)

Clion IDE-STM32+W5500 (DHCP code encapsulation)

Project description

Clion IDE-STM32+W5500(DHCP code encapsulation)

Header file:

#ifndef STM32_VET6_W5500_DHCP_H
#define STM32_VET6_W5500_DHCP_H

#include "w5500_dhcp_struct.h"
#include "socket.h"

#define DEVICE_ID "w5500"
#define IP_CONFLICT_STR "CHECK_IP_CONFLICT"
#define  DHCP_FLAGSBROADCAST     0x8000
/* UDP port numbers for DHCP */
#define  DHCP_SERVER_PORT        67    /* from server to client */
#define  DHCP_CLIENT_PORT        68    /* from client to server */
/* DHCP message OP code */
#define  DHCP_BOOTREQUEST        1
#define  DHCP_BOOTREPLY          2
/* DHCP message type */
#define  DHCP_DISCOVER           1
#define  DHCP_OFFER              2
#define  DHCP_REQUEST            3
#define  DHCP_DECLINE            4
#define  DHCP_ACK                5
#define  DHCP_NAK                6
#define  DHCP_RELEASE            7
#define  DHCP_INFORM             8
#define DHCP_HTYPE10MB           1
#define DHCP_HTYPE100MB          2
#define DHCP_HLENETHERNET        6
#define DHCP_HOPS                0
#define DHCP_SECS                0
#define MAGIC_COOKIE             0x63825363
#define DEFAULT_XID              0x12345678
#define MAX_DHCP_OPT    16

void dhcp_init();

void dhcp_config_registry(module_w5500_t *conf);


bool do_dhcp(SOCKET s, uint32_t wait_ms);


#endif //STM32_VET6_W5500_DHCP_H

Source file:

#include "w5500_dhcp.h"

#define DBG_ENABLE
#define DBG_SECTION_NAME "dhcp"
#define DBG_LEVEL DBG_INFO

#include "sys_dbg.h"

uint8_t EXTERN_DHCPBUF[1024];
RIP_MSG *pRIPMSG = (RIP_MSG *) EXTERN_DHCPBUF; /*DHCP消息指针*/
uint32_t DHCP_XID = DEFAULT_XID;

uint8_t OLD_SIP[4]; /*最初获取到的IP地址*/
uint8_t DHCP_SIP[4] = {0}; /*已发现的DNS服务器地址*/
uint8_t DHCP_REAL_SIP[4] = {0};/*从DHCP列表中选择使用的DHCP服务器*/

static module_w5500_t *w5500_ptr;

uint32_t dhcp_lease_time;                                           /*租约时间*/

void send_DHCP_DISCOVER(SOCKET s);                                      /*向DHCP服务器发送发现报文*/
void send_DHCP_REQUEST(SOCKET s, uint8_t pkt_type);                                       /*向DHCP服务器发送请求报文*/
void send_DHCP_RELEASE_DECLINE(SOCKET s, char msgtype);                       /*向DHCP服务器发送释放报文*/

uint8_t parseDHCPMSG(SOCKET s, uint16_t length);

uint8_t check_leasedIP(SOCKET s);           /*检查获取的IP是否冲突*/
uint8_t *SRC_MAC_ADDR = NULL;                       /*本地MAC地址*/
uint8_t *GET_SIP = NULL;                            /*从DHCP服务器获取到的本机IP*/
uint8_t *GET_GW_IP = NULL;                          /*从DHCP服务器获取到的网关地址*/
uint8_t *GET_SN_MASK = NULL;                        /*从DHCP服务器获取到的子网掩码*/
uint8_t GET_DNS_IP[4] = {0};                              /*从DHCP服务器获取到的DNS服务器地址*/
void dhcp_config_registry(module_w5500_t *conf) {
   w5500_ptr = conf;
   GET_SIP = conf->net_conf.ip;
   GET_SN_MASK = conf->net_conf.sub;
   SRC_MAC_ADDR = conf->net_conf.mac;
   GET_GW_IP = conf->net_conf.gw;
}

void dhcp_init() {
   /*该引脚需要保持低电平至少 500 us,才能重置 W5500;*/
   w5500_ptr->driver.rst_low();
   w5500_ptr->driver.delay(3);
   w5500_ptr->driver.rst_high();
   w5500_ptr->driver.delay(1600);
   w5500_chip_init();
   /*设置mac地址*/
   w5500_writes(MAC_ADDR, w5500_ptr->net_conf.mac, 6);
   /*初始化Socket的发送接收缓存大小*/
   for (uint8_t i = 0; i < w5500_ptr->base_conf.socket_num; i++) {
       w5500_write(Sn_TXMEM_SIZE(i), w5500_ptr->base_conf.tx_size[i]);
       w5500_write(Sn_RXMEM_SIZE(i), w5500_ptr->base_conf.rx_size[i]);
   }
}


uint16_t wait_DHCP_Response(SOCKET s, uint32_t timeout_ms) {
   uint16_t len = 0;
   for (int i = 0; i < timeout_ms / 10; ++i) {
       w5500_ptr->driver.delay(10);
       len = w5500_socket_rx_size_read(s);
       if (len > 0) {
           return parseDHCPMSG(s, len);
       }

   }
   return 0;
}

bool do_dhcp(SOCKET s, uint32_t wait_ms) {
   uint16_t type;
   if (udp_client_init(s, DHCP_CLIENT_PORT)) {
       // 01-发送DISCOVER包
       send_DHCP_DISCOVER(s);
       // 02-等待响应
       type = wait_DHCP_Response(s, wait_ms);
       if (type == DHCP_OFFER) {
           send_DHCP_REQUEST(s, STATE_DHCP_REQUEST); /*发送REQUEST包*/

           type = wait_DHCP_Response(s, wait_ms);
           if (type == DHCP_ACK) {
               LOG_D("dhcp_lease_time is %d", dhcp_lease_time);
               if (check_leasedIP(s)) {
                   memcpy(OLD_SIP, GET_SIP, 4);
                   DHCP_XID++;
                   send_DHCP_REQUEST(s, STATE_DHCP_LEASED);
                   type = wait_DHCP_Response(s, wait_ms);
                   if (type != DHCP_ACK && type != 0) {
                       LOG_W("release dhcp connect error:%d", type);
                   }
                   LOG_D("config ip start");
                   w5500_writes(SUB_ADDR, w5500_ptr->net_conf.sub, 4); /*子网掩码*/
                   w5500_writes(GAR_ADDR, w5500_ptr->net_conf.gw, 4); /*网关*/
                   w5500_writes(SIPR_ADDR, w5500_ptr->net_conf.ip, 4); /*IP配置*/
                   LOG_I("<DHCP GET IP OK>");
                   LOG_I("IP:%d.%d.%d.%d", w5500_ptr->net_conf.ip[0], w5500_ptr->net_conf.ip[1],
                         w5500_ptr->net_conf.ip[2], w5500_ptr->net_conf.ip[3]);
                   return true;
               } else {
                   LOG_W("state : DHCP_RET_CONFLICT");
               }
           } else if (type == DHCP_NAK) {
               LOG_W("send_DHCP_REQUEST is DHCP_NAK ");
           }
       }
   }
   return false;
}


uint8_t check_leasedIP(SOCKET s) {
   LOG_D("<Check the IP Conflict %d.%d.%d.%d: ", GET_SIP[0], GET_SIP[1], GET_SIP[2], GET_SIP[3]);
   if (sendto(s, (uint8_t *) IP_CONFLICT_STR, strlen(IP_CONFLICT_STR), GET_SIP, 5000)) {
       send_DHCP_RELEASE_DECLINE(s, 1);
       return 0;
   }
   return 1;
}

/**
*@brief   解析获得的DHCP消息
*@param  length:解析消息长度
*@return 0:解析失败  其他:解析成功
*/
uint8_t parseDHCPMSG(SOCKET s, uint16_t length) {
   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 = 0;

   len = recvfrom(s, (uint8_t *) pRIPMSG, length, svr_addr, &svr_port);

   LOG_D("DHCP_SIP:%u.%u.%u.%u", DHCP_SIP[0], DHCP_SIP[1], DHCP_SIP[2], DHCP_SIP[3]);
   LOG_D("DHCP_RIP:%u.%u.%u.%u", DHCP_REAL_SIP[0], DHCP_REAL_SIP[1], DHCP_REAL_SIP[2], DHCP_REAL_SIP[3]);
   LOG_D("svr_addr:%u.%u.%u.%u", svr_addr[0], svr_addr[1], svr_addr[2], svr_addr[3]);

   if (pRIPMSG->op != DHCP_BOOTREPLY || svr_port != DHCP_SERVER_PORT) {
       LOG_D("DHCP : NO DHCP MSG");
       return 0;
   }
   if (memcmp(pRIPMSG->chaddr, SRC_MAC_ADDR, 6) != 0 || pRIPMSG->xid != htonl(DHCP_XID)) {
       LOG_W("No My DHCP Message. This message is ignored.");
       LOG_W("\tSRC_MAC_ADDR(%02X.%02X.%02X.%02X.%02X.%02X)",
             SRC_MAC_ADDR[0], SRC_MAC_ADDR[1], SRC_MAC_ADDR[2],
             SRC_MAC_ADDR[3], SRC_MAC_ADDR[4], SRC_MAC_ADDR[5]);
       LOG_W(", pRIPMSG->chaddr(%02X.%02X.%02X.", (char) pRIPMSG->chaddr[0], (char) pRIPMSG->chaddr[1],
             (char) pRIPMSG->chaddr[2]);
       LOG_W("%02X.%02X.%02X)", pRIPMSG->chaddr[3], pRIPMSG->chaddr[4], pRIPMSG->chaddr[5]);
       LOG_W("\tpRIPMSG->xid(%08X), DHCP_XID(%08X)", pRIPMSG->xid, (DHCP_XID));
       LOG_W("\tpRIMPMSG->yiaddr:%d.%d.%d.%d", pRIPMSG->yiaddr[0], pRIPMSG->yiaddr[1], pRIPMSG->yiaddr[2],
             pRIPMSG->yiaddr[3]);
       return 0;
   }

   if (*((uint32_t *) DHCP_SIP) != 0x00000000) {
       if (*((uint32_t *) DHCP_REAL_SIP) != *((uint32_t *) svr_addr) &&
           *((uint32_t *) DHCP_SIP) != *((uint32_t *) svr_addr)) {
           LOG_D("Another DHCP sever send a response message. This is ignored.");
           LOG_D("\tIP:%u.%u.%u.%u", svr_addr[0], svr_addr[1], svr_addr[2], svr_addr[3]);
           return 0;
       }
   }
   memcpy(GET_SIP, pRIPMSG->yiaddr, 4);

   LOG_D("DHCP MSG received");
   LOG_D("yiaddr : %u.%u.%u.%u", GET_SIP[0], GET_SIP[1], GET_SIP[2], GET_SIP[3]);
   type = 0;
   p = (uint8_t *) (&pRIPMSG->op);
   p = p + 240;
   e = p + (len - 240);
   LOG_D("p : %08X  e : %08X  len : %d", (uint32_t) p, (uint32_t) e, len);
   while (p < e) {
       switch (*p++) {
           case endOption:
               return type;
           case padOption:
               break;
           case dhcpMessageType:
               opt_len = *p++;
               type = *p;
               LOG_D("dhcpMessageType : %02X", type);
               break;

           case subnetMask:
               opt_len = *p++;
               memcpy(GET_SN_MASK, p, 4);
               break;

           case routersOnSubnet:
               opt_len = *p++;
               memcpy(GET_GW_IP, p, 4);
               break;

           case dns:
               opt_len = *p++;
               memcpy(GET_DNS_IP, p, 4);
               break;

           case dhcpIPaddrLeaseTime:
               opt_len = *p++;
               dhcp_lease_time = ntohl(*((uint32_t *) p));
               break;

           case dhcpServerIdentifier:
               opt_len = *p++;
               if (*((uint32_t *) DHCP_SIP) == 0 ||
                   *((uint32_t *) DHCP_REAL_SIP) == *((uint32_t *) svr_addr) ||
                   *((uint32_t *) DHCP_SIP) == *((uint32_t *) svr_addr)) {
                   memcpy(DHCP_SIP, p, 4);
                   memcpy(DHCP_REAL_SIP, svr_addr, 4); // Copy the real ip address of my DHCP server
                   LOG_D("My dhcpServerIdentifier : %u.%u.%u.%u",
                         DHCP_SIP[0], DHCP_SIP[1], DHCP_SIP[2], DHCP_SIP[3]);
                   LOG_D("My DHCP server real IP address :%u.%u.%u.%u",
                         DHCP_REAL_SIP[0], DHCP_REAL_SIP[1], DHCP_REAL_SIP[2], DHCP_REAL_SIP[3]);
               } else {
                   LOG_D("Another dhcpServerIdentifier : MY(%u.%u.%u.%u) Another(%u.%u.%u.%u)",
                         DHCP_SIP[0], DHCP_SIP[1], DHCP_SIP[2], DHCP_SIP[3],
                         svr_addr[0], svr_addr[1], svr_addr[2], svr_addr[3]);
               }
               break;
           default:
               opt_len = *p++;
               break;
       } // switch
       p += opt_len;
   } // while
   return 0;
}


/**
*@brief  发送DISCOVER信息给DHCP服务器
*@param  无
*@return 无
*/
void send_DHCP_DISCOVER(SOCKET s) {
   uint8_t ip[4] = {255, 255, 255, 255};
   uint16_t i = 0;
   // the host name modified
   uint8_t host_name[12];
   memset((void *) pRIPMSG, 0, sizeof(RIP_MSG)); /*清空pRIPMSG的 sizeof(RIP_MSG) 个空间*/
   pRIPMSG->op = DHCP_BOOTREQUEST;
   pRIPMSG->htype = DHCP_HTYPE10MB;
   pRIPMSG->hlen = DHCP_HLENETHERNET;
   pRIPMSG->hops = DHCP_HOPS;
   pRIPMSG->xid = htonl(DHCP_XID);
   pRIPMSG->secs = htons(DHCP_SECS);
   pRIPMSG->flags = htons(DHCP_FLAGSBROADCAST);
   /*mac地址*/
   memcpy(pRIPMSG->chaddr, SRC_MAC_ADDR, 6);
   /* MAGIC_COOKIE */
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 24) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 16) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 8) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) (MAGIC_COOKIE & 0xFF);

   /* Option Request Param. */
   pRIPMSG->OPT[i++] = dhcpMessageType;
   pRIPMSG->OPT[i++] = 0x01;
   pRIPMSG->OPT[i++] = DHCP_DISCOVER;

   /*Client identifier*/
   pRIPMSG->OPT[i++] = dhcpClientIdentifier;
   pRIPMSG->OPT[i++] = 0x07;
   pRIPMSG->OPT[i++] = 0x01;

   memcpy(pRIPMSG->OPT + i, SRC_MAC_ADDR, 6);
   i += 6;
   // host name
   pRIPMSG->OPT[i++] = hostName;
   // set the host name
   sprintf((char *) host_name, "%.4s-%02X%02X%02X", DEVICE_ID,
           SRC_MAC_ADDR[3], SRC_MAC_ADDR[4], SRC_MAC_ADDR[5]);

   pRIPMSG->OPT[i++] = (uint8_t) strlen((char *) host_name);

   strcpy((char *) (&(pRIPMSG->OPT[i])), (char *) host_name);

   i += (uint16_t) strlen((char *) host_name);

   pRIPMSG->OPT[i++] = dhcpParamRequest;
   pRIPMSG->OPT[i++] = 0x06;
   pRIPMSG->OPT[i++] = subnetMask;
   pRIPMSG->OPT[i++] = routersOnSubnet;
   pRIPMSG->OPT[i++] = dns;
   pRIPMSG->OPT[i++] = domainName;
   pRIPMSG->OPT[i++] = dhcpT1value;
   pRIPMSG->OPT[i++] = dhcpT2value;
   pRIPMSG->OPT[i++] = endOption;
   /* send broadcasting packet */
   sendto(s, (uint8_t *) pRIPMSG, sizeof(RIP_MSG), ip, DHCP_SERVER_PORT);
   LOG_D("sent DHCP_DISCOVER");
}

void send_DHCP_REQUEST(SOCKET s, uint8_t pkt_type) {
   uint8_t ip[4], host_name[12];
   uint16_t i = 0;
   memset((void *) pRIPMSG, 0, sizeof(RIP_MSG));
   pRIPMSG->op = DHCP_BOOTREQUEST;
   pRIPMSG->htype = DHCP_HTYPE10MB;
   pRIPMSG->hlen = DHCP_HLENETHERNET;
   pRIPMSG->hops = DHCP_HOPS;
   pRIPMSG->xid = htonl(DHCP_XID);
   pRIPMSG->secs = htons(DHCP_SECS);

   if (pkt_type < STATE_DHCP_LEASED)
       pRIPMSG->flags = htons(DHCP_FLAGSBROADCAST);
   else {
       pRIPMSG->flags = 0; // For Unicast
       memcpy(pRIPMSG->ciaddr, GET_SIP, 4);
   }

   memcpy(pRIPMSG->chaddr, SRC_MAC_ADDR, 6);

   /* MAGIC_COOKIE */
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 24) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 16) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 8) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) (MAGIC_COOKIE & 0xFF);

   /* Option Request Param. */
   pRIPMSG->OPT[i++] = dhcpMessageType;
   pRIPMSG->OPT[i++] = 0x01;
   pRIPMSG->OPT[i++] = DHCP_REQUEST;

   pRIPMSG->OPT[i++] = dhcpClientIdentifier;
   pRIPMSG->OPT[i++] = 0x07;
   pRIPMSG->OPT[i++] = 0x01;
   memcpy(pRIPMSG->OPT + i, SRC_MAC_ADDR, 6);
   i += 6;
   if (pkt_type < STATE_DHCP_LEASED) {
       pRIPMSG->OPT[i++] = dhcpRequestedIPaddr;
       pRIPMSG->OPT[i++] = 0x04;
       memcpy(pRIPMSG->OPT + i, GET_SIP, 4);
       i += 4;
       pRIPMSG->OPT[i++] = dhcpServerIdentifier;
       pRIPMSG->OPT[i++] = 0x04;
       memcpy(pRIPMSG->OPT + i, DHCP_SIP, 4);
       i += 4;
   }
   // host name
   pRIPMSG->OPT[i++] = hostName;
   // set the host name
   sprintf((char *) host_name, (char *) "%.4s-%02X%02X%02X", DEVICE_ID, SRC_MAC_ADDR[3], SRC_MAC_ADDR[4],
           SRC_MAC_ADDR[5]);
   pRIPMSG->OPT[i++] = (uint8_t) strlen((char *) host_name);
   strcpy((char *) &(pRIPMSG->OPT[i]), (char *) host_name);
   i += strlen((char *) host_name);
   pRIPMSG->OPT[i++] = dhcpParamRequest;
   pRIPMSG->OPT[i++] = 0x08;
   pRIPMSG->OPT[i++] = subnetMask;
   pRIPMSG->OPT[i++] = routersOnSubnet;
   pRIPMSG->OPT[i++] = dns;
   pRIPMSG->OPT[i++] = domainName;
   pRIPMSG->OPT[i++] = dhcpT1value;
   pRIPMSG->OPT[i++] = dhcpT2value;
   pRIPMSG->OPT[i++] = performRouterDiscovery;
   pRIPMSG->OPT[i++] = staticRoute;
   pRIPMSG->OPT[i++] = endOption;
   /* send broadcasting packet */
   if (pkt_type < STATE_DHCP_LEASED)
       memset(ip, 0xFF, 4);
   else
       memcpy(ip, DHCP_SIP, 4);
   sendto(s, (uint8_t *) pRIPMSG, sizeof(RIP_MSG), ip, DHCP_SERVER_PORT);
   LOG_D("sent DHCP_REQUEST");
}

void send_DHCP_RELEASE_DECLINE(SOCKET s, char msgtype) {
   uint16_t i = 0;
   uint8_t ip[4];
   memset((void *) pRIPMSG, 0, sizeof(RIP_MSG));
   pRIPMSG->op = DHCP_BOOTREQUEST;
   pRIPMSG->htype = DHCP_HTYPE10MB;
   pRIPMSG->hlen = DHCP_HLENETHERNET;
   pRIPMSG->hops = DHCP_HOPS;
   pRIPMSG->xid = htonl(DHCP_XID);
   pRIPMSG->secs = htons(DHCP_SECS);
   pRIPMSG->flags = 0; // DHCP_FLAGSBROADCAST;
   memcpy(pRIPMSG->chaddr, SRC_MAC_ADDR, 6);

   /* MAGIC_COOKIE */
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 24) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 16) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) ((MAGIC_COOKIE >> 8) & 0xFF);
   pRIPMSG->OPT[i++] = (uint8_t) (MAGIC_COOKIE & 0xFF);

   /* Option Request Param. */
   pRIPMSG->OPT[i++] = dhcpMessageType;
   pRIPMSG->OPT[i++] = 0x01;
   pRIPMSG->OPT[i++] = ((!msgtype) ? DHCP_RELEASE : DHCP_DECLINE);

   pRIPMSG->OPT[i++] = dhcpClientIdentifier;
   pRIPMSG->OPT[i++] = 0x07;
   pRIPMSG->OPT[i++] = 0x01;
   memcpy(pRIPMSG->OPT + i, SRC_MAC_ADDR, 6);
   i += 6;
   pRIPMSG->OPT[i++] = dhcpServerIdentifier;
   pRIPMSG->OPT[i++] = 0x04;
   pRIPMSG->OPT[i++] = DHCP_SIP[0];
   pRIPMSG->OPT[i++] = DHCP_SIP[1];
   pRIPMSG->OPT[i++] = DHCP_SIP[2];
   pRIPMSG->OPT[i++] = DHCP_SIP[3];

   if (msgtype) {
       pRIPMSG->OPT[i++] = dhcpRequestedIPaddr;
       pRIPMSG->OPT[i++] = 0x04;
       pRIPMSG->OPT[i++] = GET_SIP[0];
       pRIPMSG->OPT[i++] = GET_SIP[1];
       pRIPMSG->OPT[i++] = GET_SIP[2];
       pRIPMSG->OPT[i++] = GET_SIP[3];
       LOG_D("sent DHCP_DECLINE\r\n");
   } else {
       LOG_D("sent DHCP_RELEASE");
   }

   pRIPMSG->OPT[i++] = endOption;

   if (msgtype)
       memset(ip, 0xFF, 4);
   else
       memcpy(ip, DHCP_SIP, 4);
   // printf("send dhcp decline\r\n");
   sendto(s, (uint8_t *) pRIPMSG, sizeof(RIP_MSG), ip, DHCP_SERVER_PORT);
}

Testing:

/*******************************************************************************
*  Copyright (c) [scl]。保留所有权利。
*     本文仅供个人学习和研究使用,禁止用于商业用途。
******************************************************************************/

#include "app_conf.h"
#include "w5500_config.h"

#if APP_CONFIG_W5500_DHCP
#define DBG_ENABLE
#define DBG_SECTION_NAME "w5500"
#define DBG_LEVEL W5500_DBG_LEVEL

#include "sys_dbg.h"
#include "w5500_dhcp.h"

#define W5500_CS stm_port_define(B,12)
#define W5500_RST stm_port_define(B,10)
static SPI_HandleTypeDef *w5500_spi = NULL;

static void send_and_rec_bytes(uint8_t *in_dat, uint8_t *out_data, uint16_t len) {
   if (in_dat == NULL && out_data == NULL) return;
   uint8_t *p_tx = in_dat;
   uint8_t *p_rx = out_data;
   if (p_rx == NULL) {
       HAL_SPI_Transmit(w5500_spi, p_tx, len, 10);
   } else {
       if (p_tx == NULL) {
           p_tx = p_rx;
       }
       HAL_SPI_TransmitReceive(w5500_spi, p_tx, p_rx, len, 10);
   }

}

static void W5500_RST_HIGH(void) { stm_pin_high(GPIOB, GPIO_PIN_10); }

static void W5500_RST_LOW(void) { stm_pin_low(GPIOB, GPIO_PIN_10); }

static void W5500_CS_LOW(void) { stm_pin_low(GPIOB, GPIO_PIN_12); }

static void W5500_CS_HIGH(void) { stm_pin_high(GPIOB, GPIO_PIN_12); }

static void W5500_Driver_MspInit(void) {
   stm32_pin_mode(W5500_CS, pin_mode_output);  /*CS*/
   stm32_pin_mode(W5500_RST, pin_mode_output); /*RST*/
   stm_pin_low(W5500_RST);
   stm_pin_low(W5500_CS);
   /*初始化SPI外设*/
   /*W5500 支持 SPI 模式 0 及模式 3..MOSI 和 MISO 信号无论是接收或发送,均遵从从最高标志位(MSB)到最低标志位(LSB)的传输序列。*/
   bsp_SpiHandleInit(w5500_spi, SPI_BAUDRATEPRESCALER_4, spi_mode_0);
}

module_w5500_t w5500_conf = {
       .base_conf={
               .socket_num = 4,
               .rx_size={4, 4, 4, 4},
               .tx_size={4, 4, 4, 4},
       },
       .net_conf={
//                .ip={192, 168, 199, 12},
//                .gw={192, 168, 199, 1},
//                .sub={255, 255, 255, 0},
       },
       .driver={
               .cs_high = W5500_CS_HIGH,
               .cs_low = W5500_CS_LOW,
               .rst_high= W5500_RST_HIGH,
               .rst_low=W5500_RST_LOW,
               .delay = HAL_Delay,
               .send_and_rec_bytes = send_and_rec_bytes
       },
       .api = {
               .msp_init=W5500_Driver_MspInit,
       }
};


static void w5500_pre_init(void) {
   /*一般做数据加载,此时系统时钟使用的是内部时钟,如需要使用系统时钟的外设不在此进行初始化*/
   w5500_spi = conv_spi_handle_ptr(handle_get_by_id(spi2_id));
   /*初始化资源*/
   module_w5500_init(&w5500_conf);
   uint32_t uid0 = HAL_GetUIDw0();
   uint32_t uid1 = HAL_GetUIDw1();
   uint32_t uid2 = HAL_GetUIDw2();
   uint8_t mac[6] = {0, uid0 >> 8, uid1, uid1 >> 8, uid2, uid2 >> 8};
   memcpy(w5500_conf.net_conf.mac, mac, sizeof(mac));
   dhcp_config_registry(&w5500_conf);
   w5500_conf.net_conf_init = dhcp_init;/*使用dhcp init*/
}

static void w5500_init(void) {

   w5500_conf.api.msp_init();/*初始化*/

}


static void w5500_after_init(void) {
   w5500_conf.net_conf_init();
   printf("w5500 invoke after\r\n");
   uint16_t try_cnt = 0;
   while (!do_dhcp(0, 0x1000)) {
       if (try_cnt > 20) {
           LOG_D("try timeout");
           break;
       }
       try_cnt++;
   }

}

app_init_export(w5500_net_conf, w5500_pre_init, w5500_init, w5500_after_init);

#endif

Result:

Clion IDE-STM32+W5500 (DHCP code encapsulation)
Clion IDE-STM32+W5500 (DHCP code encapsulation)

 

Comments

Similar projects you might like

Comments