• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdio.h>
17 #include "stdint.h"
18 #include "los_config.h"
19 #include "lwip/mem.h"
20 #include "lwip/memp.h"
21 #include "lwip/tcp.h"
22 #include "lwip/udp.h"
23 #include "netif/etharp.h"
24 #include "lwip/dhcp.h"
25 #include "lwip/tcpip.h"
26 #include "lwip/priv/tcp_priv.h"
27 #include "lwip/timeouts.h"
28 #include "lwip/netif.h"
29 #include "lwip/ip4_addr.h"
30 #include "lwip/sockets.h"
31 #include "gd32f4xx.h"
32 #include "gd32f4xx_enet_eval.h"
33 #include "gd32f4xx_enet.h"
34 #include "cmsis_os2.h"
35 #include "los_interrupt.h"
36 #include "ethernetif.h"
37 #include "lwip_adapter.h"
38 
39 err_t ethernetif_init(struct netif *netif);
40 #define MAX_DHCP_TRIES 4
41 #define DELAY250_MS 250
42 #define DELAY1000_MS 1000
43 #define IRQ_PRIORITY 2
44 #define CREATE_IRQ_MODE 5
45 static EthLinkInfo gEthLinkInfo = {.useStaticIp = 1, .useStaticMac = 1};
46 
47 typedef enum { DHCP_START = 0, DHCP_WAIT_ADDRESS, DHCP_ADDRESS_ASSIGNED, DHCP_TIMEOUT } dhcp_state_enum;
48 
49 #ifdef USE_DHCP
50 dhcp_state_enum dhcp_state = DHCP_START;
51 #endif
52 
53 struct netif g_mynetif;
54 unsigned int tcp_timer = 0;
55 unsigned int arp_timer = 0;
56 ip_addr_t ip_address = {0};
57 
58 void lwip_dhcp_process_handle(void);
59 
lwip_stack_init(void)60 void lwip_stack_init(void)
61 {
62     ip_addr_t ipaddr;
63     ip_addr_t netmask;
64     ip_addr_t gw;
65 
66     tcpip_init(NULL, NULL);
67 
68 #ifdef TIMEOUT_CHECK_USE_LWIP
69     sys_timeouts_init();
70 #endif
71 
72 #ifdef USE_DHCP
73     ipaddr.addr = 0;
74     netmask.addr = 0;
75     gw.addr = 0;
76 #else
77     IP_ADDR4(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
78     IP_ADDR4(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
79     IP_ADDR4(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
80 
81 #endif /* USE_DHCP */
82 
83     netif_add(&g_mynetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
84     /* registers the default network interface */
85     netif_set_default(&g_mynetif);
86 
87     /* when the netif is fully configured this function must be called */
88     netif_set_up(&g_mynetif);
89 }
90 
91 #ifdef USE_DHCP
dhcp_task(void * pvParameters)92 void dhcp_task(void *pvParameters)
93 {
94     ip_addr_t ipaddr;
95     ip_addr_t netmask;
96     ip_addr_t gw;
97     struct dhcp *dhcp_client;
98 
99     for (;;) {
100         switch (dhcp_state) {
101             case DHCP_START:
102                 dhcp_start(&g_mynetif);
103                 /* IP address should be set to 0 every time we want to assign a new DHCP address */
104                 dhcp_state = DHCP_WAIT_ADDRESS;
105                 printf("dhcp start\n");
106                 break;
107 
108             case DHCP_WAIT_ADDRESS:
109                 /* read the new IP address */
110                 ip_address.addr = g_mynetif.ip_addr.addr;
111                 printf("dhcp wait addr\n");
112                 if (ip_address.addr != 0) {
113                     dhcp_state = DHCP_ADDRESS_ASSIGNED;
114                     printf("\r\nDHCP -- eval board ip address: %d.%d.%d.%d \r\n", ip4_addr1_16(&ip_address),
115                            ip4_addr2_16(&ip_address), ip4_addr3_16(&ip_address), ip4_addr4_16(&ip_address));
116                 } else {
117                     /* DHCP timeout */
118                     dhcp_client = netif_dhcp_data(&g_mynetif);
119                     if (dhcp_client->tries > MAX_DHCP_TRIES) {
120                         dhcp_state = DHCP_TIMEOUT;
121                         /* stop DHCP */
122                         dhcp_stop(&g_mynetif);
123                         printf("dhcp set static addr\n");
124                         /* static address used */
125                         IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
126                         IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
127                         IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
128                         netif_set_addr(&g_mynetif, &ipaddr, &netmask, &gw);
129                     }
130                 }
131                 break;
132 
133             default:
134                 break;
135         }
136         osDelay(DELAY250_MS);
137     }
138 }
139 #endif
140 
141 #ifdef USE_ENET_INTERRUPT
nvic_configuration(void)142 static void nvic_configuration(void)
143 {
144     nvic_irq_enable(ENET_IRQn, IRQ_PRIORITY, 0);
145 }
146 #endif
147 
148 static __IO UINT32 enet_init_status = 0;
149 
enet_taskEntery(void * param)150 void enet_taskEntery(void *param)
151 {
152     ErrStatus reval_state = ERROR;
153 
154 #ifdef USE_ENET_INTERRUPT
155     nvic_configuration();
156 #endif /* USE_ENET_INTERRUPT */
157 
158     /* configure the GPIO ports for ethernet pins */
159     enet_gpio_config();
160 
161     /* enable ethernet clock  */
162     rcu_periph_clock_enable(RCU_ENET);
163     rcu_periph_clock_enable(RCU_ENETTX);
164     rcu_periph_clock_enable(RCU_ENETRX);
165 
166     /* reset ethernet on AHB bus */
167     enet_deinit();
168     reval_state = enet_software_reset();
169     while (ERROR == reval_state) {
170         printf("enet reset \n");
171         osDelay(DELAY1000_MS);
172     }
173 
174 #ifdef USE_ENET_INTERRUPT
175     enet_interrupt_enable(ENET_DMA_INT_NIE);
176     enet_interrupt_enable(ENET_DMA_INT_RIE);
177 #endif /* USE_ENET_INTERRUPT */
178 
179     lwip_stack_init();
180     LOS_HwiCreate(ENET_IRQn, 0, CREATE_IRQ_MODE, (HWI_PROC_FUNC)ENET_IRQHandler_CB, 0);
181 
182     net_state_callBack callback = (net_state_callBack)param;
183     uint16_t phy_value;
184     uint16_t status = 0;
185     while (1) {
186         enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value);
187         if (status == (phy_value & PHY_LINKED_STATUS)) {
188             osDelay(DELAY1000_MS);
189             continue;
190         }
191         status = phy_value & PHY_LINKED_STATUS;
192         if (status != RESET) {           /* link status changes from down to up */
193             if (enet_init_status == 0) { /* init phy once */
194 #ifdef CHECKSUM_BY_HARDWARE
195                 enet_init_status =
196                     enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS);
197 #else
198                 enet_init_status =
199                     enet_init(ENET_AUTO_NEGOTIATION, ENET_NO_AUTOCHECKSUM, ENET_BROADCAST_FRAMES_PASS);
200 #endif
201             }
202             PHY_STATUS_CALLBACK(callback, STATE_UPDATE_LINK_DOWN);
203         } else {
204             /* link status changes from up to down */
205             PHY_STATUS_CALLBACK(callback, STATE_UPDATE_LINK_UP);
206         }
207         osDelay(DELAY1000_MS);
208     }
209 }
210 
enet_adapter_init(net_state_callBack callBack)211 void enet_adapter_init(net_state_callBack callBack)
212 {
213     osThreadAttr_t attr = {.name = "net_init",
214                            .attr_bits = 0U,
215                            .cb_mem = NULL,
216                            .stack_mem = NULL,
217                            .stack_size = ENET_TASK_STACK_SIZE,
218                            .priority = ENET_TASK_PRIORITY};
219     if (osThreadNew((osThreadFunc_t)enet_taskEntery, (void *)callBack, &attr) == NULL) {
220         printf("Create net task failed! \n");
221     }
222 
223 #ifdef USE_DHCP
224     /* start DHCP client */
225     osThreadAttr_t attr1 = {
226         .name = "DHCP", .attr_bits = 0U, .cb_mem = NULL, .stack_mem = NULL, .stack_size = 1024, .priority = 29};
227     if (osThreadNew((osThreadFunc_t)dhcp_task, NULL, &attr1) == NULL) {
228         printf("Create DHCP task failed! \n");
229     }
230 #endif
231 }
232