Files
E3_boot/interface_ethernet.c
2025-08-22 09:29:06 +08:00

293 lines
9.8 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 <stdbool.h>
#include <stdio.h>
#include "debug.h"
#include <string.h>
#include <udelay/udelay.h>
#include "interface_ethernet.h"
#include "eth_cfg.h"
#include "lwip/timeouts.h"
#include "sdrv_eth.h"
#include "IAP_Task.h"
//参数管理
#define MAX_BUFFER_SIZE (sizeof(((RequestContext *)0)->param_request->arr))
#define MAX_PACKET_SIZE 1024 // 定义最大包大小为1K
struct udp_pcb *udpcb_1;
struct udp_pcb *udpcb_2;
struct udp_pcb *udpcb_3;
bool eth_pool_rx = false;
UnEthernetFault ethernet_fault_Info = {
.bit_data.auto_count = 0,
.bit_data.manual_count = 0,
.bit_data.auto_state = 0,
.bit_data.manual_state = 0,
};
StrEthernetParameter ethernet_parameter = {
.local_ip = {192,168,17,20},
.mask = {255,255,255,0},
.computer_ip = {192,168,17,3},
.local_communication_port = 8011,
.Local_upper_port = 8000,
.Local_download_port = 7811,
.upper_ip = {192,168,17,3},
.download_ip = {192,168,17,183},
.target_upper_port = 8000,
.target_download_port = 7811,
.target_communication_port = 8011,
};
static bool g_eth1_rx_pkt;
static void eth_dma_rx_int_cb(struct net_driver_s *dev)
{
if (dev == &g_eth1_dev)
g_eth1_rx_pkt = true;
}
void lwip_Ethernet(void)
{
// 接收ETH帧并传递给LWIP协议栈
// 如果使能接收中断因为ISR里会disable接收中断因此这里对于
// 中断接收标志(g_eth1_rx_pkt)的处理过程中不会有
// 新的接收中断被响应,所以,这里不存在原子性问题。
if ((!eth_pool_rx && g_eth1_rx_pkt) || eth_pool_rx)
{
g_eth1_rx_pkt = false;
dwc_eth_rx(&g_eth1_dev, eth_pool_rx);
}
// LWIP协议栈接口用于做LWIP超时检测
sys_check_timeouts();
// printf("lwipInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间
}
//err_t
//udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
void UdpSendToData(uint8_t udpcbID, uint8_t *buf, uint16_t len, uint8_t *sip, uint16_t port)
{
struct pbuf *DesPuff = NULL;
ip4_addr_t Desaddr;
//----------------------------------------------------------------------------------------------------
IP4_ADDR(&Desaddr,sip[0],sip[1],sip[2],sip[3]);//地址值转换
DesPuff = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL); /* 申请内存 */
pbuf_take(DesPuff, buf, len); /* 将g_lwip_demo_sendbuf中的数据打包进pbuf结构中 */
if(UDPCB_1 == udpcbID)
{
udp_sendto(udpcb_1, DesPuff, &Desaddr, port);
}
else if(UDPCB_2 == udpcbID)
{
udp_sendto(udpcb_2, DesPuff, &Desaddr, port);
}
else
{
}
pbuf_free(DesPuff); /* 释放内存 */
}
// udpcbID UDP索引
//recv 回调函数
//port 绑定端口
void UDP_Echo_Init(uint8_t udpcbID, udp_recv_fn recv, uint16_t port)
{
//------------------------------------------
if(UDPCB_1 == udpcbID)
{
/* 新建一个控制块*/
udpcb_1 = udp_new();
ASSERT(udpcb_1);
/* 绑定端口号 */
udp_bind(udpcb_1, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_1, recv, (void *)udpcbID);
}
else if(UDPCB_2 == udpcbID)
{
/* 新建一个控制块*/
udpcb_2 = udp_new();
ASSERT(udpcb_2);
/* 绑定端口号 */
udp_bind(udpcb_2, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_2, recv, (void *)udpcbID);
}
else if(UDPCB_3 == udpcbID)
{
/* 新建一个控制块*/
udpcb_3 = udp_new();
ASSERT(udpcb_3);
/* 绑定端口号 */
udp_bind(udpcb_3, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_3, recv, (void *)udpcbID);
}
else
{
}
}
void udp_Callback_2(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
uint16_t FrameHeader = 0;
uint8_t *Abuf = (uint8_t *)(p->payload);
// Eth_Rx_Flag = 1;
FrameHeader = ( (Abuf[0] << 8) | (Abuf[1]) );
if(WDT_Refresh == FrameHeader)//喂狗
{
WDTReFresh_flag = true;//接收到帧就更新
ssdk_printf(SSDK_CRIT, "WDT_Refresh:0x%x\r\n", WDTReFresh_flag);
}
pbuf_free(p);
}
void udp_Callback_1(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
uint8_t *Abuf = (uint8_t *)(p->payload);
Flash_info Bbuf = {0};
Flash_info *buf = &Bbuf;
uint16_t FrameHeader = 0;
//------------------------------------------------------------------------------
des_ipaddr[0] = addr->addr & 0xff; /* IADDR4 */
des_ipaddr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */
des_ipaddr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */
des_ipaddr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */
Eth_Rx_Flag ++;
Flash_RxBuf_1.Download_Mode = DOWNLOAD_ETH;//以太网下载模式
for(uint16_t i = 0;i < (p->len);i++)//数据转移
{
buf->dataBuffer[i] = Abuf[i];
}
buf->length = p->len;//长度
FrameHeader = ( (buf->dataBuffer[0] << 8) | (buf->dataBuffer[1]) );
switch(ethCmdSTT)
{
case 0:
if(FrameHeader == CRC_UPDATE )//CRC指令
{
memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//复制数据
flash_eth_time = 1;
if( (FlashBufInitial == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_1.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_1.Flash_RxBufSta)) )//初始状态写完成crc错误重发
{
Flash_RxBuf_1.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC
Flash_RxBuf_1.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//帧长度
Flash_RxBuf_1.Flash_RxBufLenNow = 0;
Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//切换状态
ethCmdSTT = 10;
}
else if( (FlashBufInitial == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufCRCFail == (Flash_RxBuf_2.Flash_RxBufSta)) || (FlashBufWrite == (Flash_RxBuf_2.Flash_RxBufSta)) )//初始状态写完成crc错误重发
{
Flash_RxBuf_2.Flash_RxBufCRC = ( (buf->dataBuffer[2] << 8) | (buf->dataBuffer[3]) );//CRC
Flash_RxBuf_2.Flash_RxBufLen = ( (buf->dataBuffer[5] << 16) | (buf->dataBuffer[6] << 8) | (buf->dataBuffer[7]) );//帧长度
Flash_RxBuf_2.Flash_RxBufLenNow = 0;
Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//切换状态
ethCmdSTT = 20;
}
else{}
}
else if(1024 == buf->length )//直接发送1K的数据没有收到CRC就直接发送数据认为丢帧
{
ENET_RxBuf_1.RxData[0] = (uint8_t)(LOST_FRAME >> 8);//高位 手动添加ID方便后面判断
ENET_RxBuf_1.RxData[1] = (uint8_t)(LOST_FRAME);
ethCmdSTT = 0;
}
else//其他指令
{
memcpy(&ENET_RxBuf_1.RxData[0],buf->dataBuffer,buf->length);//复制数据
ssdk_printf(SSDK_CRIT, "ENET_RxBuf[0] :0x%x, ENET_RxBuf[1]:0x%x\r\n", ENET_RxBuf_1.RxData[0],ENET_RxBuf_1.RxData[1]);
ethCmdSTT = 0;
}
break;
case 10:
ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//高位 手动添加ID方便后面判断
ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE);
memcpy(&Flash_RxBuf_1.RxData[Flash_RxBuf_1.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//复制数据
Flash_RxBuf_1.Flash_RxBufLenNow = (Flash_RxBuf_1.Flash_RxBufLenNow) + (buf->length);
if( (Flash_RxBuf_1.Flash_RxBufLenNow) >= (Flash_RxBuf_1.Flash_RxBufLen) )//接收长度满足要求
{
Flash_RxBuf_1.Flash_RxBufSta = FlashBufComplete;//切换状态
ethCmdSTT = 0;
flash_eth_time = 0;
}
else
{
flash_eth_time = 1;
Flash_RxBuf_1.Flash_RxBufSta = FlashBufInComplete;//切换状态
ethCmdSTT = 10;
}
break;
case 20://缓存2
ENET_RxBuf_1.RxData[0] = (uint8_t)(CRC_UPDATE >> 8);//高位 手动添加ID方便后面判断
ENET_RxBuf_1.RxData[1] = (uint8_t)(CRC_UPDATE);
memcpy(&Flash_RxBuf_2.RxData[Flash_RxBuf_2.Flash_RxBufLenNow],buf->dataBuffer,buf->length);//复制数据
Flash_RxBuf_2.Flash_RxBufLenNow = (Flash_RxBuf_2.Flash_RxBufLenNow) + (buf->length);
if( (Flash_RxBuf_2.Flash_RxBufLenNow) >= (Flash_RxBuf_2.Flash_RxBufLen) )//接收长度满足要求
{
Flash_RxBuf_2.Flash_RxBufSta = FlashBufComplete;//切换状态
ethCmdSTT = 0;
flash_eth_time = 0;
}
else
{
flash_eth_time = 1;
Flash_RxBuf_2.Flash_RxBufSta = FlashBufInComplete;//切换状态
ethCmdSTT = 20;
}
break;
}
pbuf_free(p);
}
// APP模块的初始化
void ethernetInterfaceInit(void)
{
//-----------------------------------
if (!eth_pool_rx) {
// 使能DMA Rx中断。Tx未使用中断因为ETH速率很高
// Tx中断处理耗时反而可能拖慢发送速度。
dwc_eth_enable_dma_rx_int(&g_eth1_dev, eth_dma_rx_int_cb);
}
}