feat(ethercat): 添加ESP32使能控制功能通过EtherCAT SDO

添加0x2503对象字典项用于通过EtherCAT SDO控制ESP32 WiFi使能信号,
解决WiFi关断后无法重新开启的问题。同时添加sys/esp32_en.h/.cpp文件
提供GPIO控制接口。

SPI诊断命令(0xA2)扩展支持ESP32 EN引脚控制,用于诊断备援。
ESP32掉电重启后自动清理SPI链路状态,防止通信异常。
This commit is contained in:
cbb
2026-09-24 03:18:18 +08:00
parent 5fd986299c
commit 28d8426052
10 changed files with 272 additions and 5 deletions
@@ -38,6 +38,7 @@ extern "C" {
#include "sys/critical.h"
#include "sys/systick.h"
#include "sys/cpu_load.h"
#include "sys/esp32_en.h"
#include <cstdio>
#include <cstring>
@@ -558,6 +559,8 @@ void AppSpiCommand::processCommand()
g_pendingAckSeq = hdr.tx_seq;
if (frame_type == V2_TYPE_LINK_HELLO) {
/* 合法 HELLO 已到:停掉起机补清,避免 reset 打断建连 */
Esp32En::cancelRelinkFromSpi();
g_sessionId = hdr.session_id;
g_txSeq = 0;
g_expectedRxSeq = 0;
@@ -693,6 +696,41 @@ void AppSpiCommand::cancelRing()
updateDataReady();
}
void AppSpiCommand::resetEsp32Link()
{
/* ESP32 被 PC9 掉电可能死在半笔 CS 里,SPI0/DMA/EXTI 都可能卡死。
* 做一次完整外设重初始化(对齐 init 的硬件序列),而不是只清软件状态。
* 仅在 PC9 翻转、对端确定不在发帧时调用。 */
nvic_irq_disable(EXTI10_15_IRQn);
exti_interrupt_disable(EXTI_15);
g_v2Active = false;
g_sessionId = 0U;
g_txSeq = 0U;
g_expectedRxSeq = 0U;
g_pendingAckSeq = 0U;
g_localCredit = 1U;
s_lastReqSeq = 0xFFU;
s_lastRespLen = 0U;
s_hasCachedResp = false;
m_csActive = false;
m_rxLen = 0U;
m_ringPending = false;
m_ringDeadline = 0U;
m_txLen = 0U;
memset(m_txBuf, 0xFF, sizeof(m_txBuf));
memset(m_rxBuf, 0x00, sizeof(m_rxBuf));
/* 硬件重初始化:SPI0 + DMA + CS EXTI(与 init() 同序列) */
configureDma();
configureSpi0();
armSpiDmasForNextCs();
updateDataReady();
configureExti();
printf("[SPI-APP] resetEsp32Link: SPI0/DMA/EXTI re-init done\r\n");
}
bool AppSpiCommand::requestEsp32Read(uint8_t frame_type, const uint8_t *payload, uint16_t payload_len)
{
/* 若上一次按铃尚未被 ESP32 读走,拒绝重复按铃 */
@@ -789,6 +827,9 @@ void AppSpiCommand::onCsRelease()
}
if (m_rxLen >= V2_OVERHEAD) {
processCommand();
} else {
/* 残包:SPI 可能已乱,重配外设 */
configureSpi0();
}
armSpiDmasForNextCs();
updateDataReady();
@@ -843,7 +884,9 @@ void AppSpiCommand::onCsRelease()
if (shouldIgnoreTransaction(m_rxBuf, m_rxLen)) {
m_rxLen = 0U;
/* v2 DATA_READY: 无待处理帧时 updateDataReady() 释放 PB6。 */
/* 起机毛刺/相位漂移后仅 re-arm DMA 不够:SPI0 可能已 OVR 卡死。
* 顺手重配 SPI0+DMA(不动 EXTI/session),下一笔 HELLO 才能收进来。 */
configureSpi0();
armSpiDmasForNextCs();
updateDataReady();
return;