Files
433_STM32/User/wiz_interface/wiz_interface.c

327 lines
9.0 KiB
C
Raw Normal View History

#include "wiz_interface.h"
#include "wiz_platform.h"
#include "wizchip_conf.h"
#include "dhcp.h"
#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define W5500_VERSION 0x04
struct wiz_timer
{
void (*func)(void); // Callback function pointer for a function to execute when the timer fires
uint32_t trigger_time; // Trigger time(ms)
uint32_t count_time; // Current count value(ms)
struct wiz_timer *next; // next timer node
};
struct wiz_timer *wiz_timer_head = NULL;
volatile uint32_t wiz_delay_ms_count = 0;
/**
* @brief Create wiz_timer Node
* @param func :Callback function pointer for a function to execute when the timer fires
* @param time :Trigger time, usually in milliseconds
*
* @return Returns pointer to wiz_timer node when successfully created, otherwise returns NULL
*/
static struct wiz_timer *create_wiz_timer_node(void (*func)(void), uint32_t time)
{
struct wiz_timer *newNode = (struct wiz_timer *)malloc(sizeof(struct wiz_timer));
if (newNode == NULL)
{
printf("Memory allocation failed.\n");
return NULL;
}
newNode->func = func;
newNode->trigger_time = time;
newNode->count_time = 0;
newNode->next = NULL;
return newNode;
}
/**
* @brief Add a new timer node to the timer chain table
* @param func Callback function pointer, called when the timer time is reached
* @param time Trigger time (ms)
*/
void wiz_add_timer(void (*func)(void), uint32_t time)
{
struct wiz_timer *newNode = create_wiz_timer_node(func, time);
if (wiz_timer_head == NULL)
{
wiz_timer_head = newNode;
return;
}
struct wiz_timer *temp = wiz_timer_head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
/**
* @brief Delete the timer for the specified callback function
* @param func callback function pointer
* @return none
*/
void wiz_delete_timer(void (*func)(void))
{
struct wiz_timer *temp = wiz_timer_head;
struct wiz_timer *prev = NULL;
if (temp != NULL && temp->func == func)
{
wiz_timer_head = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->func != func)
{
prev = temp;
temp = temp->next;
}
if (temp == NULL)
return;
prev->next = temp->next;
free(temp);
}
/**
* @brief wiz timer event handler (using HAL_GetTick)
*
* You must add this function to your 1ms timer interrupt
*
*/
void wiz_timer_handler(void)
{
static uint32_t last_tick = 0;
uint32_t current_tick = HAL_GetTick();
if (current_tick != last_tick) {
last_tick = current_tick;
struct wiz_timer *temp = wiz_timer_head;
while (temp != NULL)
{
temp->count_time++;
if (temp->count_time >= temp->trigger_time)
{
temp->count_time = 0;
temp->func();
}
temp = temp->next;
}
}
}
/**
* @brief Delay function in milliseconds (using HAL_GetTick)
* @param nms :Delay Time
*/
void wiz_user_delay_ms(uint32_t nms)
{
uint32_t start = HAL_GetTick();
while ((HAL_GetTick() - start) < nms) {
}
}
/**
* @brief Check the WIZCHIP version (with timeout)
*/
void wizchip_version_check(void)
{
uint8_t error_count = 0;
uint32_t start_tick = HAL_GetTick();
while ((HAL_GetTick() - start_tick) < 5000)
{
wiz_user_delay_ms(100);
if (getVERSIONR() != W5500_VERSION)
{
error_count++;
if (error_count > 5)
{
printf("WARN: W5500 version check failed, SPI may be disconnected\r\n");
break;
}
}
else
{
break;
}
}
}
/**
* @brief Print PHY information
*/
void wiz_print_phy_info(void)
{
uint8_t get_phy_conf;
get_phy_conf = getPHYCFGR();
printf("The current Mbtis speed : %dMbps\r\n", get_phy_conf & 0x02 ? 100 : 10);
printf("The current Duplex Mode : %s\r\n", get_phy_conf & 0x04 ? "Full-Duplex" : "Half-Duplex");
}
/**
* @brief Ethernet Link Detection (with timeout)
*/
void wiz_phy_link_check(void)
{
uint8_t phy_link_status;
uint32_t start_tick = HAL_GetTick();
while ((HAL_GetTick() - start_tick) < 10000)
{
wiz_user_delay_ms(500);
ctlwizchip(CW_GET_PHYLINK, (void *)&phy_link_status);
if (phy_link_status == PHY_LINK_ON)
{
printf("PHY link\r\n");
wiz_print_phy_info();
return;
}
}
printf("WARN: PHY link timeout, using static config\r\n");
}
/**
* @brief wizchip init function
* @param none
* @return none
*/
void wizchip_initialize(void)
{
printf(" -> [WIZ] 注册SPI回调...\r\n");
wizchip_spi_cb_reg();
printf(" -> [WIZ] 执行硬件复位(测试延时是否卡死)...\r\n");
wizchip_reset(); // <--- 之前是死在这里
printf(" -> [WIZ] 硬件复位通过!说明 TIM2 定时器工作完全正常!\r\n");
printf(" -> [WIZ] 检查SPI通信与芯片版本号...\r\n");
wizchip_version_check(); // <--- 如果 SPI 线接错了会死在这里
printf(" -> [WIZ] 版本号检查通过SPI 通信正常!\r\n");
wiz_phy_link_check();
}
/**
* @brief print network information
* @param none
* @return none
*/
void print_network_information(void)
{
wiz_NetInfo net_info;
wizchip_getnetinfo(&net_info); // Get chip configuration information
if (net_info.dhcp == NETINFO_DHCP)
{
printf("====================================================================================================\r\n");
printf(" %s network configuration : DHCP\r\n\r\n", _WIZCHIP_ID_);
}
else
{
printf("====================================================================================================\r\n");
printf(" %s network configuration : static\r\n\r\n", _WIZCHIP_ID_);
}
printf(" MAC : %02X:%02X:%02X:%02X:%02X:%02X\r\n", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]);
printf(" IP : %d.%d.%d.%d\r\n", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]);
printf(" Subnet Mask : %d.%d.%d.%d\r\n", net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3]);
printf(" Gateway : %d.%d.%d.%d\r\n", net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]);
printf(" DNS : %d.%d.%d.%d\r\n", net_info.dns[0], net_info.dns[1], net_info.dns[2], net_info.dns[3]);
printf("====================================================================================================\r\n\r\n");
}
/**
* @brief DHCP process
* @param sn :socket number
* @param buffer :socket buffer
*/
static uint8_t wiz_dhcp_process(uint8_t sn, uint8_t *buffer)
{
wiz_NetInfo conf_info;
uint8_t dhcp_run_flag = 1;
uint8_t dhcp_ok_flag = 0;
/* Registration DHCP_time_handler to 1 second timer */
wiz_add_timer(DHCP_time_handler, 1000);
DHCP_init(sn, buffer);
printf("DHCP running\r\n");
while (1)
{
switch (DHCP_run()) // Do the DHCP client
{
case DHCP_IP_LEASED: // DHCP Acquiring network information successfully
{
if (dhcp_ok_flag == 0)
{
dhcp_ok_flag = 1;
dhcp_run_flag = 0;
}
break;
}
case DHCP_FAILED:
{
dhcp_run_flag = 0;
break;
}
}
if (dhcp_run_flag == 0)
{
printf("DHCP %s!\r\n", dhcp_ok_flag ? "success" : "fail");
DHCP_stop();
/*DHCP obtained successfully, cancel the registration DHCP_time_handler*/
wiz_delete_timer(DHCP_time_handler);
if (dhcp_ok_flag)
{
getIPfromDHCP(conf_info.ip);
getGWfromDHCP(conf_info.gw);
getSNfromDHCP(conf_info.sn);
getDNSfromDHCP(conf_info.dns);
conf_info.dhcp = NETINFO_DHCP;
getSHAR(conf_info.mac);
wizchip_setnetinfo(&conf_info); // Update network information to network information obtained by DHCP
return 1;
}
return 0;
}
}
}
/**
* @brief set network information
*
* First determine whether to use DHCP. If DHCP is used, first obtain the Internet Protocol Address through DHCP.
* When DHCP fails, use static IP to configure network information. If static IP is used, configure network information directly
*
* @param sn: socketid
* @param ethernet_buff:
* @param net_info: network information struct
* @return none
*/
void network_init(uint8_t *ethernet_buff, wiz_NetInfo *conf_info)
{
int ret;
wizchip_setnetinfo(conf_info); // Configuring Network Information
if (conf_info->dhcp == NETINFO_DHCP)
{
ret = wiz_dhcp_process(0, ethernet_buff);
if (ret == 0)
{
conf_info->dhcp = NETINFO_STATIC;
wizchip_setnetinfo(conf_info);
}
}
print_network_information();
}