Files
433_STM32/User/wiz_interface/wiz_interface.c

327 lines
9.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();
}