Jelajahi Sumber

同步 Mini7 ONE 功能并重构 ESP32 Wi-Fi 收发

- 同步状态维持时间、裂解参数持久化、温控状态与灯效,保留 ONE/PLUS 模块差异。
- 使用 256 字节接收环流式解析 AT、提示符和 IPD,完整帧交给 DecodeNew。
- 串行化 CIPSEND/载荷/结果事务;不确定超时停止重发,避免 AT 混入 TCP 数据。
- 保留 SoftAP 配网,共用流解析及发送流程;TCP 设置 6000ms 发送超时。
- 修复接收环覆盖、重复读取 DR、串口发送覆盖 Wi-Fi 缓存和忙状态返回。
- mini7_V2_debug 使用 ONE 宏;ST-LINK 烧录并通过 COM10 验证联网。
- 添加实际解码器主机回归测试,覆盖分包、跨环、连续帧、超时和配网。

验证:ONE/PLUS 主机回归通过;最终 debug ONE 完整编译 0 错误、3 条原有警告。
设备周期查询约 2 分钟:58 个有效 TCP 应答、62 次 SEND OK,无校验/溢出/超时异常。
范围限制:未验证完整实验流程;环境温度 -104(通道未加载)仍待排查。
yidong 6 hari lalu
induk
melakukan
b0abd91790

+ 6 - 0
BoardInterface/onechip_devinf_define.h

@@ -103,6 +103,9 @@ typedef struct {
 	void * beep_port;	
 	uint8_t amplifState;
 	uint8_t lysisState;
+    uint32_t amplifStateTime;
+    /* Channel 1: lysis for ONE, slave amplification for PLUS. */
+    uint32_t lysisStateTime;
 	uint8_t updateSt;
 	uint8_t amplif_error_code; //错误码 
 	uint8_t lysis_error_code; //错误码 
@@ -136,6 +139,9 @@ typedef struct {
 	float lysis_Kp;
 	float lysis_Ki;
 	float lysis_Kd;
+    float lysis_idleTemp;
+    float lysis_Goal;
+    float lysis_HeatTime;
 #endif	
 #ifdef ONECHIP_MINI_PLUS
 	float amplif_Kp_Slave;

+ 6 - 5
Core/Src/main.c

@@ -193,7 +193,6 @@ int main(void)
 	sysinf.scannerUart = &huart4;
 	svanner_receive_Rec_Start(sysinf.scannerUart);
 	sysinf.ESPUart = &huart2;
-	esp_receive_Rec_Start(sysinf.ESPUart);
 	
 	SensorInitial();
   loadTemp_mts01Cfg();
@@ -273,6 +272,8 @@ int main(void)
 #ifdef MINI7_V2_DEBUG   
 	sysinf.log_level =  VAN_LOG_ERROR|VAN_LOG_INFO|VAN_LOG_TEMP|VAN_LOG_WIFI;
 #endif	
+  /* Start RX after blocking self-checks, immediately before servicing it. */
+  esp_receive_Rec_Start(sysinf.ESPUart);
   while (1)
   {
     /* USER CODE END WHILE */
@@ -293,14 +294,14 @@ int main(void)
           }
       }
 
-		if(sysinf.deal_espFlag){
-			sysinf.deal_espFlag =0;
-			WIFI_process();
-		}
+		/* Drain UART every loop; Wi-Fi deadlines use HAL_GetTick(). */
+		WIFI_process();
 		if(	sysinf.s1_flag == 1){
       Refresh_IWDG();
 			sysinf.s1_flag = 0;
 			HAL_GPIO_TogglePin((GPIO_TypeDef *)sysinf.run_led_port, sysinf.run_led_pin); /*green*/      
+      sysinf.amplifStateTime++;
+      sysinf.lysisStateTime++;
       update_work();
       resetSampleData(&sysinf.psmMaster);
       resetSampleData(&sysinf.psmSlave);

+ 2 - 2
Core/Src/stm32f1xx_it.c

@@ -304,9 +304,9 @@ void USART2_IRQHandler(void)
 {
   /* USER CODE BEGIN USART2_IRQn 0 */
 
-	HAL_UART_Rec_IDLE(&huart2);
+	esp_receive_Rec_IDLE(&huart2);
   /* USER CODE END USART2_IRQn 0 */
-  HAL_UART_IRQHandler(&huart2);
+  /* ESP RX is handled above; do not read DR twice. */
   /* USER CODE BEGIN USART2_IRQn 1 */
   /* USER CODE END USART2_IRQn 1 */
 }

File diff ditekan karena terlalu besar
+ 416 - 714
DriverInterface/ESP32_WROOM_32D.c


+ 2 - 0
DriverInterface/ESP32_WROOM_32D.h

@@ -26,7 +26,9 @@ enum WIFI_State
   WIFI_LINK_AP,   //连接AP
   WIFI_GET_IP,    //查询IP
   WIFI_SETMUX,      //打开多链接
+  WIFI_IPDINFO,  // fixed +IPD header format
   WIFI_LISTEN,    //监听广播
+  WIFI_TCPOPT,   // TCP send timeout
   WIFI_TRANS,    //数据传输
   WIFI_CLOSE,    //关闭链接
   WIFI_ERROR,    //错误状态

+ 47 - 59
DriverInterface/communication.c

@@ -15,12 +15,8 @@ extern uint8_t wifi_tx_buf[WIFI_TX_BUF_SIZE];
 extern uint16_t wifi_tx_len;
 uint8_t com_tx_buf[WIFI_TX_BUF_SIZE];
 unsigned int check_to_pc_busy(void){
-	/*判断是否可以发送,缓冲区为空或者索引为0*/
-	CmdMessage *pMessage = (CmdMessage *)wifi_tx_buf;
-	if(pMessage->seq == 0 || pMessage->len == 0){
-		return 1;
-	}
-	return 0;	
+    if (sysinf.pc_channel_recv == PC_CONNECT_TYPE_UART) return 1;
+    return WIFI_SendIlde();
 }
 
 /********************************************************************
@@ -101,15 +97,12 @@ int data_send_to_pc(pc_cmd_type cmd, char *data, unsigned short len)
 
 	if((sysinf.pc_channel_recv  == PC_CONNECT_TYPE_WIFI || cmd == PC_CMD_SETIP ) && ((PC_CMD_SETWIFI != cmd) && (PC_CMD_UPDATETEMP != cmd) && (PC_CMD_DATASCOPE != cmd)))
 	{	
-         if(wifi_tx_len == 0){                
-            wifi_tx_len = sendlen;		
-            memcpy(wifi_tx_buf, com_tx_buf, wifi_tx_len);
-            return WIFI_ReSend();
-         }
+         int result = WIFI_Send_Data(com_tx_buf, sendlen, 1);
+         return result < 0 ? result : 0;
 	}
 	else
 	{	
-        Van_Debug_UART_Send_DMA((unsigned char *)com_tx_buf, sendlen); //将收到的信息发送出		
+        Van_Debug_UART_Send_DMA((unsigned char *)com_tx_buf, sendlen); //将收到的信息发送出
 		memset(com_tx_buf, 0, sizeof(com_tx_buf));
 	}
    return 0;
@@ -118,7 +111,7 @@ int data_send_to_pc(pc_cmd_type cmd, char *data, unsigned short len)
 int data_send_to_pc_withindex(pc_cmd_type cmd, char *data, unsigned short len, unsigned char index)
 {
     uint16_t check;
-    int ret = -1;
+    if (len > WIFI_TX_BUF_SIZE - 8 || (!data && len)) return -1;
     msg.head = 0x55aa;
     msg.seq = index;
     msg.cmd = cmd;
@@ -131,26 +124,21 @@ int data_send_to_pc_withindex(pc_cmd_type cmd, char *data, unsigned short len, u
 	check += checkSum((const unsigned char *)data, len);
 	msg.checksum = check & 0xFF;
 	msg.tail = (check >> 8);	
-	if(check_to_pc_busy()){		
-		memcpy(&wifi_tx_buf[0], (uint8_t*)&msg, MSG_CMDFRAME_LEN);
-		memcpy(&wifi_tx_buf[MSG_CMDFRAME_LEN], data, len);
-		memcpy(&wifi_tx_buf[MSG_CMDFRAME_LEN+len],  (uint8_t*)&check, 2);
-	}else{
-		return ret;
-	}	
+
 	if((sysinf.pc_channel_recv  == PC_CONNECT_TYPE_WIFI || cmd == PC_CMD_SETIP ) && PC_CMD_SETWIFI != cmd)
 	{	
-        if(wifi_tx_len == 0){
-            wifi_tx_len = MSG_CMDFRAME_LEN+len+2;			
-            return WIFI_ReSend();
-        }
+        int result = WIFI_Send_MSG((uint8_t *)&msg, (uint8_t *)data, (uint8_t *)&check, len);
+        return result < 0 ? result : 0;
 	}
 	else
 	{	
-	    wifi_tx_len = MSG_CMDFRAME_LEN+len+2;	
-        Van_Debug_UART_Send_DMA((unsigned char *)wifi_tx_buf, wifi_tx_len); //将收到的信息发送出		
-		memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
-        wifi_tx_len = 0;
+		memcpy(&com_tx_buf[0], (uint8_t*)&msg, MSG_CMDFRAME_LEN);
+		memcpy(&com_tx_buf[MSG_CMDFRAME_LEN], data, len);
+		memcpy(&com_tx_buf[MSG_CMDFRAME_LEN+len],  (uint8_t*)&check, 2);
+	    uint16_t sendlen = MSG_CMDFRAME_LEN+len+2;
+        Van_Debug_UART_Send_DMA((unsigned char *)com_tx_buf, sendlen); //将收到的信息发送出
+		memset(com_tx_buf, 0, sizeof(com_tx_buf));
+
 	}
    return 0;
 }
@@ -393,9 +381,11 @@ int handshake_response(CmdMessage *pMsg, unsigned char result)
 	
 int AskState_response(CmdMessage *pMsg, unsigned char result)
 {
-        stateinfDef st;
+        stateinfDef st = {0};
         st.amplifState =sysinf.amplifState;
         st.lysisState =sysinf.lysisState;
+        st.amplifStateTime = sysinf.amplifStateTime;
+        st.lysisStateTime = sysinf.lysisStateTime;
         memcpy(st.SN, &sysinf.SN, 7);
 
    	data_send_to_pc(PC_CMD_ASKSTATE, (char *)&st, sizeof(stateinfDef));  
@@ -616,13 +606,17 @@ int updateDate_response(CmdMessage *pMsg, unsigned char result)
 
 int send_temp_parm(uint8_t cmd, uint8_t *parg)
 {
-	/*设置温度*/
-    sysinf.lysis.idletemp =  *(float *)(parg+4);
-    sysinf.lysis.pid.goal =  *(float *)(parg+8);
-    sysinf.lysis.worktime =  *(float *)(parg+12);
-    sysinf.lysis.worktime *= 10;
-    sysinf.lysis.recGoalFlag = 1;
-	return 1;
+#ifdef ONECHIP_MINI_ONE
+    sysinf.lysis_idleTemp = *(float *)(parg+4);
+    sysinf.lysis_Goal = *(float *)(parg+8);
+    sysinf.lysis_HeatTime = *(float *)(parg+12);
+    updatParm_lysis();
+    cfg_save_cfg_param();
+    return 1;
+#else
+    /* PLUS has no lysis controller; configure heaters with amplifier commands. */
+    return 0;
+#endif
 }
 int setTemp_response(CmdMessage *pMsg, uint8_t result)
 {
@@ -845,7 +839,7 @@ int con_heat_action(uint8_t cmd, uint8_t *parg )
             *(float *)(data+16) = sysinf.lysis_Kp;	
             *(float *)(data+20) = sysinf.lysis_Ki;	
             *(float *)(data+24) = sysinf.lysis_Kd;		
-            *(float *)(data+28) = sysinf.lysis.lastgaol;	
+            *(float *)(data+28) = sysinf.lysis.setgaol;
             *(float *)(data+32) = sysinf.lysis.idletemp;	
             *(float *)(data+36) = sysinf.lysis.worktime/10;	
 #endif  
@@ -1052,29 +1046,23 @@ void deal_mUnion_cmd(CmdMessage *pMsg)
 
 
 void update_work(void) {
-   float temp;
-   unsigned int st;
-
-    if(sysinf.log_level & VAN_LOG_TEMP ){
-        char data[20];
-        get_master_st(&temp,&st); 
+    float temp, pwm;
+    unsigned int st;
+    if (sysinf.log_level & VAN_LOG_TEMP) {
+        char data[28] = {0};
+        get_master_st(&temp, &st, &pwm);
         *(unsigned int *)(data+0) = st;
-        *(float *)(data+4) =temp;
+        *(float *)(data+4) = temp;
+        *(float *)(data+8) = pwm;
 #ifdef ONECHIP_MINI_ONE
-        get_lysis_st(&temp,&st);
-        *(unsigned int *)(data+8) = st; 
-        *(float *)(data+12) = temp; 
-#endif   
-#ifdef ONECHIP_MINI_PLUS
-        get_slave_st(&temp,&st);
-        *(unsigned int *)(data+8) = st; 
-        *(float *)(data+12) = temp; 
-#endif   
-       
-        *(float *)(data+16) = sysinf.cabinTem;    
-        data_send_to_pc(PC_CMD_UPDATETEMP, data,sizeof(data));        
+        get_lysis_st(&temp, &st, &pwm);
+#else
+        get_slave_st(&temp, &st, &pwm);
+#endif
+        *(unsigned int *)(data+12) = st;
+        *(float *)(data+16) = temp;
+        *(float *)(data+20) = pwm;
+        *(float *)(data+24) = sysinf.cabinTem;
+        data_send_to_pc(PC_CMD_UPDATETEMP, data, sizeof(data));
     }
-
-    // Van_Device_Printf(VAN_LOG_TEMP,"st:%d %f %d %f\n\r",sysinf.psmMaster.state,sysinf.heaterMaster.pid.realtemp,sysinf.lysis.thermostat_st,sysinf.lysis.pid.realtemp);
-	return ;
 }

+ 3 - 0
DriverInterface/communication.h

@@ -73,6 +73,9 @@ typedef struct _sysinf
 	unsigned char amplifState;
 	unsigned char lysisState;
   unsigned char updateSt;
+    unsigned char res;
+    unsigned int amplifStateTime;
+    unsigned int lysisStateTime;
 }stateinfDef;
 #define MSG_CMDFRAME_LEN (6)
 typedef struct 

+ 5 - 2
DriverInterface/onchip_flash.c

@@ -189,11 +189,14 @@ void cfg_load_default_param(void)
 
 #ifdef ONECHIP_MINI_ONE
 	sysinf.lysis_offset = -6;
-	sysinf.lysis_overHeat = 3;
+	sysinf.lysis_overHeat = 0;
 	sysinf.lysis_overHeatTime    = 10;
-	sysinf.lysis_Kp = 5;
+	sysinf.lysis_Kp = 20;
 	sysinf.lysis_Ki = 0.01;
 	sysinf.lysis_Kd = 0;
+    sysinf.lysis_idleTemp = 0;
+    sysinf.lysis_Goal = 95;
+    sysinf.lysis_HeatTime = 270;
 #endif	
 #ifdef ONECHIP_MINI_PLUS
 	sysinf.amplif_Kp_Slave = 20;

+ 28 - 40
DriverInterface/state_mini.c

@@ -131,15 +131,17 @@ int TrigStateCheck(ProcessStateMachine_t *sts)
 {
 	 return (HAL_GPIO_ReadPin((GPIO_TypeDef *)sts->card_port,sts->card_pin)) ? 1 : 0; // 
 }
-uint32_t get_master_st(float *temp,unsigned int *st) {
+uint32_t get_master_st(float *temp,unsigned int *st,float *pwm) {
 	*temp = sysinf.heaterMaster.pid.realtemp;
+    *pwm = sysinf.heaterMaster.pid.variate;
 	*st = sysinf.psmMaster.state;
 	return 0;
 }
 
 
-uint32_t get_slave_st(float *temp,unsigned int *st) {
+uint32_t get_slave_st(float *temp,unsigned int *st,float *pwm) {
 	*temp = sysinf.heaterSlave.pid.realtemp;
+    *pwm = sysinf.heaterSlave.pid.variate;
 	*st = sysinf.psmSlave.state;
 	return 0;
 }
@@ -281,6 +283,7 @@ uint8_t error_set(uint8_t error,uint8_t id)
  ********************************************************************/
 void error_clear(void)
 {
+    sysinf.updateError = 0;
     error_info.error_code = 0;
 	error_info.error_report = 0;
     beep_set(BEEP_MUTE);
@@ -294,9 +297,11 @@ void resend_error_update(void){
 }
 void re_send_state(void){
 	 if(sysinf.updateSt == 1){
-        stateinfDef st;
+        stateinfDef st = {0};
         st.amplifState =sysinf.amplifState;
         st.lysisState =sysinf.lysisState;
+        st.amplifStateTime = sysinf.amplifStateTime;
+        st.lysisStateTime = sysinf.lysisStateTime;
         memcpy(st.SN, &sysinf.SN, 7);
         data_send_to_pc(PC_CMD_UPDATESTATE, (char *)&st, sizeof(stateinfDef));  
 	 }
@@ -304,47 +309,30 @@ void re_send_state(void){
   
 
 
-void updateAmplifState(uint8_t newset,uint8_t id){
-    if(id==0){
-        if(sysinf.amplifState != newset){
-            sysinf.amplifState = newset;
-            if(newset == SYS_STATE_ERROR_HW){                
-#ifdef ONECHIP_MINI_ONE
-                sysinf.lysisState = newset;
-#endif
-            beep_set(BEEP_ERR_HW);
-            }else if(newset == SYS_STATE_ERROR_HM){
-                beep_set(BEEP_ERR_HM);
-            }
-            sysinf.updateSt = 1;
-        }    
-    }else{
-        if(sysinf.lysisState != newset){
-            sysinf.lysisState = newset;
-            if(newset == SYS_STATE_ERROR_HW){              
+void updateAmplifState(uint8_t newset, uint8_t id)
+{
+    uint8_t *state = id == 0 ? &sysinf.amplifState : &sysinf.lysisState;
+    uint32_t *elapsed = id == 0 ? &sysinf.amplifStateTime : &sysinf.lysisStateTime;
+    if (*state == newset) return;
+    *state = newset;
+    *elapsed = 0;
+    if (newset == SYS_STATE_ERROR_HW) {
 #ifdef ONECHIP_MINI_ONE
-                sysinf.lysisState = newset;
+        /* ONE shares the device hardware-fault state; PLUS channels stay independent. */
+        if (sysinf.amplifState != newset) sysinf.amplifStateTime = 0;
+        if (sysinf.lysisState != newset) sysinf.lysisStateTime = 0;
+        sysinf.amplifState = sysinf.lysisState = newset;
 #endif
-                beep_set(BEEP_ERR_HW);
-            }else if(newset == SYS_STATE_ERROR_HM){
-                beep_set(BEEP_ERR_HM);
-            }
-            sysinf.updateSt = 1;
-        }
+        beep_set(BEEP_ERR_HW);
+    } else if (newset == SYS_STATE_ERROR_HM) {
+        beep_set(BEEP_ERR_HM);
     }
+    sysinf.updateSt = 1;
 }
-        
-void updateLysisState(uint8_t newset){
-    if(sysinf.lysisState != newset){
-        sysinf.lysisState = newset;
-        if(newset == SYS_STATE_ERROR_HW){
-            sysinf.lysisState = newset;
-            beep_set(BEEP_ERR_HW);
-        }else if(newset == SYS_STATE_ERROR_HM){
-            beep_set(BEEP_ERR_HM);
-        }
-        sysinf.updateSt = 1;
-    }
+
+void updateLysisState(uint8_t newset)
+{
+    updateAmplifState(newset, 1);
 }
 
 void usr_state_machine(ProcessStateMachine_t *sts, heat_ctrl_def *heater)

+ 2 - 2
DriverInterface/state_mini.h

@@ -238,8 +238,8 @@ typedef struct ProcessStateMachine
 
 void resend_error_update(void);
 void re_send_state(void);
-uint32_t get_master_st(float *temp,unsigned int *st);
-uint32_t get_slave_st(float *temp,unsigned int *st);
+uint32_t get_master_st(float *temp,unsigned int *st,float *pwm);
+uint32_t get_slave_st(float *temp,unsigned int *st,float *pwm);
 void updateAmplifState(uint8_t newset,uint8_t id);
 void updateLysisState(uint8_t newset);
 void updateData_next(unsigned int recdex,unsigned char * part);

+ 54 - 38
DriverInterface/usr_lysis.c

@@ -11,6 +11,8 @@
 
 #ifdef ONECHIP_MINI_ONE
 
+
+
 #define MIN_TEMPERATUARE 5
 #define MAX_TEMPERATUARE 120 
 #define COOL_WORK_THD 5 
@@ -27,6 +29,7 @@
 #define HEAT_ARRIVE_EDGE 0.5 
 #define GOTO_IDLE_GAP  3000 
 #define HEATCHECK_OUT  85 
+#define CARD_STDCHANGE_TIME 100
 
 
 
@@ -50,6 +53,9 @@ void updatParm_lysis(void) {
 	sysinf.lysis.pid.Kp = sysinf.lysis_Kp;
 	sysinf.lysis.pid.Ki = sysinf.lysis_Ki ;
 	sysinf.lysis.pid.Kd = sysinf.lysis_Kd;
+	sysinf.lysis.idletemp	= sysinf.lysis_idleTemp;
+	sysinf.lysis.setgaol	= sysinf.lysis_Goal;
+	sysinf.lysis.worktime	= sysinf.lysis_HeatTime * 10;
 }
 
 
@@ -89,7 +95,6 @@ uint32_t Therm_Check(void) {
  */
 void set_lysis(float goal) {
    sysinf.lysis.pid.goal = goal;
-   sysinf.lysis.lastgaol = goal;
    if(goal > (sysinf.lysis.overHeat + sysinf.lysis.pid.realtemp )){
 		sysinf.lysis.pid_st = PID_OVERHEAT;
 		sysinf.lysis.pid.goal += sysinf.lysis.overHeat;
@@ -168,21 +173,23 @@ uint32_t Pid_work(void) {
   return 0;
 }
 
-uint32_t get_lysis_st(float *temp,unsigned int *st) {
+uint32_t get_lysis_st(float *temp,unsigned int *st,float *pwm) {
 
 	*temp = sysinf.lysis.pid.realtemp;
 	*st = sysinf.lysis.thermostat_st;
+	*pwm = sysinf.lysis.pid.variate;
 	return 0;
 }
 uint32_t lysis_work(void) {
   float temp;
   static uint32_t last10ms;
+  static uint32_t cardStChang;
   static float firstTemp;
   lysis_ctr_def *ptherm = &sysinf.lysis;
 
   temp = getADC_Chanel_value(1);  
   if(temp < MIN_TEMPERATUARE || temp > MAX_TEMPERATUARE){
-	error_set(ERROR_TEMPSENSOR_EER,1);		
+	error_set(ERROR_TEMPSENSOR_EER, 1);
 	updateLysisState(SYS_STATE_ERROR_HW);
 	ptherm->thermostat_st = THERMOSTAT_ERROR;
 	ptherm->firstin = true;
@@ -196,10 +203,7 @@ uint32_t lysis_work(void) {
 			ptherm->firstin = false;
 			updateLysisState(SYS_STATE_PREPARE);sysinf.lysisState = SYS_STATE_PREPARE; 
 			firstTemp = getADC_Chanel_value(1);
-			set_lysis(95);				
-   			ptherm->pid.goal = 95;	
-    		ptherm->worktime = 3000;	
-    		ptherm->lastgaol = 95;
+			set_lysis(sysinf.lysis.setgaol);
 			last10ms = sysinf.conter10ms;			
 		}else{
 			float heattemp = getADC_Chanel_value(1); 
@@ -212,7 +216,7 @@ uint32_t lysis_work(void) {
 				/*超时判断*/
 				ptherm->thermostat_st = THERMOSTAT_ERROR;
 				updateLysisState(SYS_STATE_ERROR_HW);
-				error_set(ERROR_HEATFUC_EER,1);
+				error_set(ERROR_HEATFUC_EER, 1);
 				ptherm->firstin = true;
 			}
 		}	
@@ -260,43 +264,47 @@ uint32_t lysis_work(void) {
 	}break;
 	case THERMOSTAT_IDLE:{
 		if(ptherm->firstin){			
-			updateLysisState(SYS_STATE_READY);
+			// updateLysisState(SYS_STATE_READY);
 			ptherm->firstin = false;
 			Close_therm(0);
 			ptherm->recGoalFlag = 0;
 			firstTemp = getADC_Chanel_value(1);
-			
+			updateLysisState(SYS_STATE_CHECK);
+			cardStChang = 0;
 		}else{	
-		    if(ptherm->recGoalFlag){
-				set_lysis(ptherm->pid.goal);	
-				ptherm->recGoalFlag = 0;	
-				updateLysisState(SYS_STATE_PREHEAT);
-				firstTemp = getADC_Chanel_value(1);
+		    if(Read_Tupe()==1){
+					if(((sysinf.conter10ms - last10ms)>CARD_STDCHANGE_TIME)&&cardStChang){
+						set_lysis(ptherm->setgaol);
+						ptherm->recGoalFlag = 0;
+						firstTemp = getADC_Chanel_value(1);
+						ptherm->thermostat_st = THERMOSTAT_WORK;
+						ptherm->firstin = 1;
+					}
+			}else{
 				last10ms = sysinf.conter10ms;
+				cardStChang = 1;
 			}
-			if(ptherm->pid_stable){
-				ptherm->thermostat_st = THERMOSTAT_INSERT;
-				ptherm->firstin = true;	
-			}
+		}
+	}break;
+	case THERMOSTAT_INSERT:{
+		if(ptherm->firstin){
+			ptherm->firstin = false;
+			updateLysisState(SYS_STATE_RUNING);
+			last10ms = sysinf.conter10ms;
+		}else{
+			/*加热异常判断*/
 			if(((ptherm->pid.realtemp - firstTemp) < HEAT_WORK_THD)&&
 				((sysinf.conter10ms-last10ms)> HEAT_TEST_TIME)&&((ptherm->pid.goal - firstTemp) > 10.0)){
 					/*目标温差大于10,加热启动30s之内没升温2.5° 超时判断*/
 					ptherm->thermostat_st = THERMOSTAT_ERROR;
 					updateLysisState(SYS_STATE_ERROR_HW);
-					error_set(ERROR_HEATFUC_EER,1);
+					error_set(ERROR_HEATFUC_EER, 1);
 					ptherm->firstin = true;
 			  }
-		}
-	}break;
-	case THERMOSTAT_INSERT:{
-		if(ptherm->firstin){			
-			updateLysisState(SYS_STATE_CHECK);
-			ptherm->firstin = false;
-		}else{	
-		    if(Read_Tupe()){
+			if((ptherm->pid.realtemp + 5) >ptherm->setgaol )	{
 				ptherm->thermostat_st = THERMOSTAT_WORK;
-				ptherm->firstin = true;		
-				}
+				ptherm->firstin = true;
+			}
 		}
 	}break;
 	case THERMOSTAT_WORK:{
@@ -304,6 +312,7 @@ uint32_t lysis_work(void) {
 			updateLysisState(SYS_STATE_RUNING);
 			ptherm->firstin = false;
 			ptherm->pid_stable_time = 0;
+			last10ms = sysinf.conter10ms;
 		}else{
 //		    if(Read_Tupe()){
 //				last10ms = conter10ms;
@@ -312,14 +321,14 @@ uint32_t lysis_work(void) {
 //					Close_therm(0);
 //					ptherm->eerst = THERMOSTAT_TUBENOEXIST_EER;
 //					ptherm->thermostat_st = THERMOSTAT_ERROR;
-//					error_set(ERROR_TUPE_MOVE); 
+//					error_set(ERROR_TUPE_MOVE, 1);
 //					last10ms = conter10ms;	
 //					ptherm->firstin = TRUE;			
 //				}
 //			}
 //			if(ptherm->pid_stable)
 			{
-				ptherm->pid_stable_time ++;
+				ptherm->pid_stable_time = (sysinf.conter10ms - last10ms)/10;
 				if(ptherm->pid_stable_time > ptherm->worktime){
 					ptherm->thermostat_st = THERMOSTAT_END;
 					ptherm->firstin = true;		
@@ -334,12 +343,17 @@ uint32_t lysis_work(void) {
 			Close_therm(0);
 			beep_set(BEEP_WORKEND);
 			last10ms = sysinf.conter10ms;
-		}else{			
-			if((sysinf.conter10ms-last10ms)> GOTO_IDLE_GAP){
-//			if(Read_Tupe() == 0){
+			cardStChang = 0;
+		}else{
+			if(Read_Tupe() == 0){
 			/*管管移除,进入到预热状态*/
-				ptherm->thermostat_st = THERMOSTAT_IDLE;
-				ptherm->firstin = true;
+				if(((sysinf.conter10ms - last10ms)>CARD_STDCHANGE_TIME)&&cardStChang){
+					ptherm->thermostat_st = THERMOSTAT_IDLE;
+					ptherm->firstin = true;
+				}
+			}else{
+				last10ms = sysinf.conter10ms;
+				cardStChang = 1;
 			}
 		}
 	}break;
@@ -361,4 +375,6 @@ uint32_t Close_Therm_work(void) {
   ptherm->firstin = true;
   return 0;
 }
-#endif  
+
+
+#endif /* ONECHIP_MINI_ONE */

+ 2 - 2
DriverInterface/usr_lysis.h

@@ -77,7 +77,7 @@ typedef struct
     float overCoolTime;       
     float idletemp;  	      
     float worktime;  	      
-    float lastgaol;  		     
+    float setgaol;
     pid_def  pid;	
 	unsigned int pwdId;
     float cabinTem;    
@@ -94,6 +94,6 @@ void updatParm_lysis(void);
 void set_lysis(float goal) ;
 uint32_t lysis_work(void);
 uint32_t Close_lysis_work(void);
-uint32_t get_lysis_st(float *temp,unsigned int *st);
+uint32_t get_lysis_st(float *temp,unsigned int *st,float *pwm);
 /***********************************/
 #endif /* USR_HEATER_H_ */

+ 5 - 2
DriverInterface/usr_protocol_type.h

@@ -10,8 +10,11 @@
 #ifndef _USR_PROTOCOL_TYPE_
 #define _USR_PROTOCOL_TYPE_
 
-#define  ONECHIP_MINI_ONE
-//#define  ONECHIP_MINI_PLUS
+#if defined(ONECHIP_MINI_ONE) && defined(ONECHIP_MINI_PLUS)
+#error "Select exactly one Mini7 device type"
+#elif !defined(ONECHIP_MINI_ONE) && !defined(ONECHIP_MINI_PLUS)
+#define ONECHIP_MINI_ONE
+#endif
 
 
 #define __WIFI_ENABLE__ 1   //wifi使能

+ 22 - 60
DriverInterface/van_BSP_ESPUart.c

@@ -1,71 +1,33 @@
-/*
- * uart_rcv.c
- *
- *  Created on: 2022年4月20日
- *      Author: dell
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
 #include "onechip_include_header.h"
 
-
-
+/* ISR is the sole writer of last; foreground is the sole writer of head.
+ * One slot remains empty to distinguish full from empty. */
 uint8_t g_wifi_rx_buf[WIFI_RX_BUF_SIZE];
-uint32_t g_wifi_rx_last;
-uint32_t g_wifi_rx_head;
-uint32_t g_wifi_rx_last_tick = 0;   /* 最近一次收到ESP数据的时间戳(10ms单位,0=未收到) */
+volatile uint32_t g_wifi_rx_last, g_wifi_rx_head, g_wifi_rx_last_tick;
+volatile uint8_t g_wifi_rx_fault;
 
 void esp_receive_Rec_IDLE(UART_HandleTypeDef *huart)
 {
-	// if ((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET))
-	// {
-	// 	__HAL_UART_CLEAR_IDLEFLAG(huart);
-	// 	g_wifi_rx_len		= WIFI_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
-	// 	HAL_UART_DMAStop(huart); 
-	// 	HAL_UART_Receive_DMA(huart, g_wifi_rx_buf, WIFI_RX_BUF_SIZE);	
-	// }
-   // 手动判断并读取
-    if (__HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE)) {
-        uint8_t data = (uint8_t)(huart->Instance->DR & 0xFF);
-		__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_RXNE);
-        g_wifi_rx_buf[g_wifi_rx_last++] = data;
-		if(g_wifi_rx_last == WIFI_RX_BUF_SIZE){
-			g_wifi_rx_last = 0;
-		}
-		g_wifi_rx_last_tick = sysinf.conter10ms;   /* 记录最近接收时间戳 */
-        // 存缓冲区...
-      
-        // 清除RXNE标志(读DR后自动清除,这里不需要额外操作)
-        // 但若要用HAL方式清除可调用:__HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_RXNE);
-    }
-    
-    // 处理错误(如ORE)
-    if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE)) {
-        __HAL_UART_CLEAR_OREFLAG(huart);
-        // 也可读取DR丢弃数据
-        volatile uint8_t temp = huart->Instance->DR;
-        (void)temp;
+    uint32_t sr = huart->Instance->SR;
+    if (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_FE | USART_SR_NE)) {
+        uint8_t byte = (uint8_t)huart->Instance->DR; /* SR then DR clears errors */
+        if (sr & (USART_SR_ORE | USART_SR_FE | USART_SR_NE)) g_wifi_rx_fault = 2;
+        if (sr & USART_SR_RXNE) {
+            uint32_t next = (g_wifi_rx_last + 1) % WIFI_RX_BUF_SIZE;
+            if (next == g_wifi_rx_head) g_wifi_rx_fault = 1;
+            else { g_wifi_rx_buf[g_wifi_rx_last] = byte; g_wifi_rx_last = next; }
+            g_wifi_rx_last_tick = sysinf.conter10ms;
+        }
     }
-
-	
 }
 
+/* Discard only the current snapshot; never reset the ISR write cursor. */
+void wifi_receive_clear(void) { g_wifi_rx_head = g_wifi_rx_last; }
 
-
-void wifi_receive_clear(void){
-	memset(g_wifi_rx_buf,0,WIFI_RX_BUF_SIZE);
-	g_wifi_rx_last = 0;
-	g_wifi_rx_head = 0;
-}
-
-
-
-
-void esp_receive_Rec_Start(UART_HandleTypeDef *huart){
-		__HAL_UART_CLEAR_IDLEFLAG(huart);
-	  memset((char *)g_wifi_rx_buf,0,WIFI_RX_BUF_SIZE);
-	// 	HAL_UART_Receive_DMA(huart, g_wifi_rx_buf, WIFI_RX_BUF_SIZE);	
-	__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
+void esp_receive_Rec_Start(UART_HandleTypeDef *huart)
+{
+    __HAL_UART_CLEAR_IDLEFLAG(huart);
+    wifi_receive_clear();
+    g_wifi_rx_fault = 0;
+    __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
 }

+ 16 - 7
DriverInterface/ws2812.c

@@ -159,7 +159,8 @@ void light_set(uint8_t mode_select, uint16_t speed_ms, uint32_t rgb_color, uint8
     lihgt_ctrl.light_color[channel] = rgb_color;
 
     //两边步调同步
-    if(lihgt_ctrl.light_mode[0] == lihgt_ctrl.light_mode[1])
+    if((lihgt_ctrl.light_mode[0] == lihgt_ctrl.light_mode[1]) &&
+       (lihgt_ctrl.light_color[0] == lihgt_ctrl.light_color[1]))
     {
         lihgt_ctrl.breath_count[0] = lihgt_ctrl.breath_count[1];
         lihgt_ctrl.breath_dir[0] = lihgt_ctrl.breath_dir[1];
@@ -189,11 +190,13 @@ void light_update(void){
         light_set(MODE_NORMAL,1000, COLOR_RED,1);	//
         return ;
 #endif
-    } else   if(sysinf.pc_link_timeout == OFFLINE_TIME){
-        light_set(MODE_BLINK,1000, COLOR_YELLOW,0);	//
-        light_set(MODE_BLINK,1000, COLOR_YELLOW,1);	//
-        sysinf.pc_channel_recv  = PC_CONNECT_TYPE_NULL;
-        return ;
+    } else if(sysinf.pc_link_timeout >= OFFLINE_TIME){
+        light_set(MODE_BLINK,1000, COLOR_YELLOW,0);
+        sysinf.pc_channel_recv = PC_CONNECT_TYPE_NULL;
+#ifdef ONECHIP_MINI_PLUS
+        light_set(MODE_BLINK,1000, COLOR_YELLOW,1);
+        return;
+#endif
     }   else if(sysinf.pc_link_timeout < OFFLINE_TIME){
         switch (sysinf.amplifState){
             case SYS_STATE_PREPARE:
@@ -222,7 +225,13 @@ void light_update(void){
         light_set(MODE_NORMAL,1000, COLOR_RED,0);	//仪器故障,双边同步
 #endif
         light_set(MODE_NORMAL,1000, COLOR_RED,1);	//
-    }   else if(sysinf.pc_link_timeout < OFFLINE_TIME){
+    } else if(
+#ifdef ONECHIP_MINI_ONE
+        1 /* Lysis operates independently of the PC connection. */
+#else
+        sysinf.pc_link_timeout < OFFLINE_TIME
+#endif
+    ){
         switch (sysinf.lysisState){
             case SYS_STATE_PREPARE:
             case SYS_STATE_PREHEAT:            

+ 1 - 1
MDK-ARM/mini7_V2.uvprojx

@@ -1101,7 +1101,7 @@
             <v6Rtti>0</v6Rtti>
             <VariousControls>
               <MiscControls></MiscControls>
-              <Define>USE_HAL_DRIVER,STM32F103xE,ONECHIP_MINI_PLUS,MINI7_V2_DEBUG</Define>
+              <Define>USE_HAL_DRIVER,STM32F103xE,ONECHIP_MINI_ONE,MINI7_V2_DEBUG</Define>
               <Undefine></Undefine>
               <IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../BoardInterface;../DriverInterface;../tshell</IncludePath>
             </VariousControls>

+ 63 - 0
tests/wifi_refactor/README.txt

@@ -0,0 +1,63 @@
+ESP32 receive/transmit refactor validation
+
+Active implementation is entirely in DriverInterface/ESP32_WROOM_32D.c.
+The older wifi_stream.h / wifi_receive_stream.inc files are not included.
+
+Preserved contracts:
+- WriteComm2(char *, uint16_t) is the only physical send path.
+- g_wifi_rx_buf remains 256 bytes. g_wifi_rx_last is the ISR write cursor;
+  g_wifi_rx_head is the main-loop read cursor.
+- Every complete Mini7 message is decoded by the Keil project's existing
+  tshell/van_com_algorithm.c DecodeNew, including its legacy checksum rules.
+- Command formatting goes through my_sprintf, now bounded by vsnprintf.
+- Diagnostics use Van_Device_Printf(VAN_LOG_WIFI, ...).
+
+Receiving:
+- Main loop drains the ring without the former 100ms gate.
+- ISR detects ring-full/ORE; it does not silently overwrite unread bytes.
+- AT lines, prompts and +IPD payloads are consumed in wire order.
+- CIPMUX=1 and CIPDINFO=0 are configured explicitly.
+- STA dispatches connection 0; SoftAP provisioning accepts client IDs 0..4
+  through the same streaming parser, without mixing clients' JSON fragments.
+- Mini7 partial frames survive multiple +IPD segments, with a 128-byte maximum
+  inbound payload matching CMD_BUF_SIZE. The actual ring stays 256 bytes.
+- Complete frames use a separate contiguous DecodeNew window so decoding
+  cannot move the hardware ring cursor or erase newly arrived input.
+
+Sending:
+- IDLE -> WAIT_PROMPT (3000ms) -> WAIT_RESULT (7000ms) -> IDLE.
+- Payload is sent once per prompt transaction, without a trailing extra byte.
+- TCP connection success is followed by CIPTCPOPT=0,,,6000; only its OK enables
+  application TX. UDP skips TCP options.
+- Explicit ERROR before prompt or SEND FAIL after payload releases the pending
+  frame; existing application-level ACK/retry logic is responsible for retry.
+- Ambiguous timeout, UART write failure, malformed +IPD or ring overrun latches
+  TX_FAULT and sends no further AT. Reset ESP/the device; ready clears the latch.
+  There is no hardware ESP reset pin configured in this module.
+- Close/SSID requests are deferred until the current transaction finishes.
+
+Host test:
+  python tests/wifi_refactor/build_host_test.py
+  In a Visual Studio compiler shell:
+  cl /nologo /TC /utf-8 /DONECHIP_MINI_ONE tests/wifi_refactor/generated.c DriverInterface/cJSON.c /Fe:tests/wifi_refactor/test.exe /Fo:tests/wifi_refactor/
+  tests/wifi_refactor/test.exe
+
+The generator reads the CURRENT production C and actual DecodeNew, not a
+duplicate decoder model. Covers maximum frame fragmentation, ring wrap,
+1000 frames, binary delimiters, corruption, callbacks receiving new bytes,
+prompt timeout, duplicate prompt, send-result timing, UART error, TCP/UDP setup.
+Repeat with /DONECHIP_MINI_PLUS to test the other device variant.
+Also covers IPD payloads larger than the ring, SoftAP setup/fragmented JSON,
+prompt-only payload release, busy provisioning requests and bounded searches.
+
+2026-10-26 hardware smoke test:
+- Full rebuild of mini7_V2_debug with ONECHIP_MINI_ONE: 0 errors, 3 existing
+  warnings (debug watchdog unreachable code x2, unused stub_RtR x1).
+- ST-LINK programming and verification passed; application reset and running.
+- COM10 and the existing tool_for_mini TCP/UDP server used for validation.
+- 10:32:32..10:34:37: 58 valid TCP responses, 62 SEND OK, maximum observed
+  response gap 5 seconds, no observed checksum errors, UART faults, AT timeouts,
+  reset commands or SEND FAIL. Covers periodic status queries, not a full run.
+- Ambient temperature -104 indicates an unloaded sensor channel, unresolved.
+- Both Keil targets share output files: use a full rebuild when changing target.
+- Raw serial/network logs and AXF files are local artifacts, not test sources.

+ 14 - 0
tests/wifi_refactor/build_host_test.py

@@ -0,0 +1,14 @@
+from pathlib import Path
+
+root = Path(__file__).resolve().parents[2]
+folder = Path(__file__).resolve().parent
+header = (root / 'DriverInterface/ESP32_WROOM_32D.h').read_text(encoding='utf-8')
+header = header.replace('#include "onechip_include_header.h"', '')
+source = (root / 'DriverInterface/ESP32_WROOM_32D.c').read_text(encoding='utf-8')
+source = source.replace('#include "ESP32_WROOM_32D.h"', '')
+decoder = (root / 'tshell/van_com_algorithm.c').read_text(encoding='utf-8')
+decoder = decoder[decoder.index('int DecodeNew('):decoder.index('\n\nfloat PIDRealize')]
+parts = [folder.joinpath('host_prefix.h').read_text(), header, decoder, source,
+         folder.joinpath('host_main.c').read_text()]
+(folder / 'generated.c').write_text('\n'.join(parts), encoding='utf-8')
+print('Generated host test from current ESP32_WROOM_32D.c and DecodeNew.')

+ 107 - 0
tests/wifi_refactor/host_main.c

@@ -0,0 +1,107 @@
+static void reset(void) {
+    prov_active=prov_request=prov_step=prov_len=prov_ready=prov_bad=0;
+    saves=0;
+    wifi_state=WIFI_TRANS;tx_phase=TX_IDLE;wifi_tx_len=0;
+    at_pending=at_retries=wifi_ack_delay=deferred_close=wifi_set_ssid=0;
+    g_wifi_rx_head=g_wifi_rx_last=0;g_wifi_rx_fault=0;
+    ticks=writes=commands=uart_fail=inject_prompt=0;
+    retry_wait=0;
+    wifi_rx_reset();
+}
+static void feed(const char *p) {put(p,(unsigned)strlen(p));WIFI_recv_deal();}
+static unsigned make_frame(uint8_t *b, unsigned size) {
+    unsigned i,sum;
+    b[0]=0xaa;b[1]=0x55;b[2]=1;b[3]=0x12;b[4]=size;b[5]=0;
+    for(i=0;i<size;i++) b[6+i]=(uint8_t)i;
+    if(size>=3) {b[6]='>';b[7]='\r';b[8]='\n';}
+    sum=checkSum(b+2,size+4);b[size+6]=sum;b[size+7]=sum>>8;
+    return size+8;
+}
+int main(void) {
+    uint8_t b[136],payload[10]={0};
+    unsigned n,i,split;
+    char header[40],tiny[3];
+    /* Real production formatting and real DecodeNew are compiled below. */
+    assert(my_sprintf(tiny,sizeof(tiny),"%s","abcd")==4 && !strcmp(tiny,"ab"));
+    reset();g_wifi_rx_head=g_wifi_rx_last=253;
+    assert(WIFI_Send_Data(payload,10,1)==10);
+    assert(!strcmp(last_write,"AT+CIPSEND=0,10\r\n"));
+    assert(WIFI_ReSend()==-2 && writes==1);
+    feed("\r\nOK\r\n> ");
+    assert(writes==2 && last_len==10 && tx_phase==TX_WAIT_RESULT);
+    feed(">");assert(writes==2);
+    ticks=6500;WIFI_send_deal();assert(tx_phase==TX_WAIT_RESULT);
+    feed("\r\nSEND OK\r\n");assert(tx_phase==TX_IDLE && wifi_tx_len==0);
+    reset();WIFI_Send_Data(payload,10,1);ticks=3000;WIFI_send_deal();
+    assert(tx_phase==TX_FAULT && writes==1);
+    ticks=100000;WIFI_send_deal();assert(writes==1);
+    feed("ready\r\n");assert(tx_phase==TX_IDLE && wifi_state==WIFI_POWERON);
+    /* Every split point of a maximum-size protocol frame across IPD segments. */
+    n=make_frame(b,128);
+    for(split=0;split<=n;split++) {
+        reset();my_sprintf(header,sizeof(header),"+IPD,0,%d",split);
+        feed(header);feed(":");put(b,split);WIFI_recv_deal();
+        my_sprintf(header,sizeof(header),"+IPD,0,%d:",n-split);
+        feed(header);put(b+split,n-split);WIFI_recv_deal();
+        assert(commands==1 && tx_phase!=TX_FAULT);
+    }
+    reset();n=make_frame(b,4);WIFI_Send_Data(payload,10,1);
+    /* Prompt before IPD in the same ring snapshot, binary delimiters inside. */
+    put("> +IPD,0,24:",12);put(b,n);put(b,n);WIFI_recv_deal();
+    assert(writes==2 && commands==2);
+    reset();WIFI_Send_Data(payload,10,1);inject_prompt=1;
+    put("+IPD,0,12:",10);put(b,n);WIFI_recv_deal();
+    assert(commands==1 && writes==2); /* Arrival during dispatch is preserved. */
+    reset();feed("+IPD,0,24:");b[n-1]^=1;put(b,n);b[n-1]^=1;put(b,n);
+    WIFI_recv_deal();assert(commands==1);
+    for(i=0;i<1000;i++) {feed("+IPD,0,12:");put(b,n);WIFI_recv_deal();}
+    assert(commands==1001);
+    reset();feed("+IPD,1,12:");put(b,n);WIFI_recv_deal();assert(commands==0);
+    reset();feed("+IPD,0,1200:");
+    for(i=0;i<100;i++) {put(b,n);WIFI_recv_deal();}
+    assert(commands==100 && !rx_ipd_left); /* larger than the hardware ring */
+    reset();g_wifi_rx_fault=1;WIFI_recv_deal();assert(tx_phase==TX_FAULT);
+    reset();uart_fail=1;assert(WIFI_Send_Data(payload,10,1)<0 && tx_phase==TX_FAULT);
+    reset();wifi_enter(WIFI_LISTEN);sysinf.connectTcpFlag=1;
+    strcpy(sysinf.TCP_IP_Addr,"192.168.3.1");strcpy(sysinf.TCP_IP_PORT,"8002");
+    WIFI_send_deal();assert(strstr(last_write,"AT+CIPSTART=0,\"TCP\""));
+    feed("0,CONNECT\r\nOK\r\n");assert(wifi_state==WIFI_TCPOPT);
+    WIFI_send_deal();assert(!strcmp(last_write,"AT+CIPTCPOPT=0,,,6000\r\n"));
+    feed("OK\r\n");assert(wifi_state==WIFI_TRANS);
+    reset();wifi_enter(WIFI_LISTEN);sysinf.connectTcpFlag=0;
+    WIFI_send_deal();feed("OK\r\n");assert(wifi_state==WIFI_TRANS);
+    reset();wifi_enter(WIFI_CWLAP);strcpy(sysinf.wifiname,"lab");WIFI_send_deal();
+    feed("+CWLAP:(3,\"lab\",-45,\"12:34:56:78:90:ab\",1)\r\nOK\r\n");
+    assert(wifi_state==WIFI_DISAUTO && !strcmp(MAC_ADDR,"12:34:56:78:90:ab"));
+    reset();wifi_enter(WIFI_CWLAP);WIFI_send_deal();feed("ERROR\r\n");
+    WIFI_send_deal();assert(writes==1);ticks=1999;WIFI_send_deal();assert(writes==1);
+    ticks=2000;WIFI_send_deal();assert(writes==2);
+    reset();wifi_enter(WIFI_LINK_AP);WIFI_send_deal();
+    feed("WIFI DISCONNECT\r\n");assert(wifi_state==WIFI_LINK_AP && at_pending);
+    feed("WIFI CONNECTED\r\nWIFI GOT IP\r\nOK\r\n");assert(wifi_state==WIFI_GET_IP);
+    reset();feed("WIFI DISCONNECT\r\n");assert(wifi_state==WIFI_POWEROFF);
+    /* Full SoftAP setup and fragmented JSON, including a nonzero link ID. */
+    reset();assert(WIFI_provision_request());WIFI_process();
+    assert(prov_active && !strcmp(last_write,"AT+RST\r\n"));
+    feed("OK\r\nready\r\n");
+    for (i=1;i<=8;i++) {WIFI_process();assert(at_pending);feed("OK\r\n");}
+    WIFI_process();assert(prov_step==10);
+    feed("+IPD,2,16:{\"ssid\":\"lab\",\"p");
+    feed("+IPD,2,13:assword\":\"x\"}");
+    WIFI_process();assert(prov_step==11 && saves==1);
+    assert(strstr(last_write,"AT+CIPSEND=2,"));
+    i=writes;feed("OK\r\n");assert(writes==i);
+    feed(">");assert(writes==i+1 && strstr(last_write,"accepted"));
+    feed("SEND OK\r\n");WIFI_process();assert(!prov_active);
+    /* A queued provisioning request cannot interrupt an active payload. */
+    reset();WIFI_Send_Data(payload,10,1);WIFI_provision_request();WIFI_process();
+    assert(!prov_active && writes==1);
+    ticks=3000;WIFI_process();assert(tx_phase==TX_FAULT && !prov_active && writes==1);
+    reset();feed("+IPD,0,-1:");assert(tx_phase==TX_FAULT);
+    reset();assert(WIFI_SendIlde());WIFI_Send_Data(payload,10,1);assert(!WIFI_SendIlde());
+    /* Search must not match stale bytes beyond the valid ring tail. */
+    reset();memcpy(g_wifi_rx_buf,"xxOK",4);g_wifi_rx_last=3;
+    assert(!find_str_loop(g_wifi_rx_buf,256,&g_wifi_rx_head,3,"OK"));
+    puts("PASS: DecodeNew, splits/wrap, 1000 frames, AT/IPD ordering, timeouts, TCP/UDP, SoftAP, valid-range search");
+    return 0;
+}

+ 66 - 0
tests/wifi_refactor/host_prefix.h

@@ -0,0 +1,66 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../../DriverInterface/cJSON.h"
+static unsigned saves;
+static uint8_t cfg_save_cfg_param(void) { ++saves; return 1; }
+#define WIFI_RX_BUF_SIZE 256
+#define WIFI_TX_BUF_SIZE 512
+#define CMD_BUF_SIZE 128
+#define HAL_OK 0
+#define PC_CMD_SETIP 11
+#define PC_CMD_SETWIFI 10
+#define PC_CONNECT_TYPE_WIFI 1
+#define UINON_CMD_THEROM_GET 0x58
+#define VAN_COM_HEADER_FALG 0x55aa
+#define VAN_COM_TAIL_FALG 0x5aa5
+#define SIZEOF_MSG_ST 8
+#define Van_Device_Printf(...) ((void)0)
+typedef int UART_HandleTypeDef;
+typedef struct {
+    unsigned short head;
+    unsigned char seq,cmd;
+    unsigned short len;
+    char *data;
+    unsigned char checksum,tail;
+} CmdMessage;
+static struct {
+    void *ESPUart;
+    int connectTcpFlag, s10_flag, pc_channel_recv, pc_link_timeout;
+    char wifiname[64], password[64], TCP_IP_Addr[64], TCP_IP_PORT[8];
+    char SN[8];
+} sysinf;
+uint8_t g_wifi_rx_buf[256];
+volatile uint32_t g_wifi_rx_last, g_wifi_rx_head;
+volatile uint8_t g_wifi_rx_fault;
+static uint32_t ticks;
+static int writes, commands, uart_fail, inject_prompt;
+static char last_write[1024];
+static unsigned last_len;
+static uint32_t HAL_GetTick(void) { return ticks; }
+static int HAL_UART_Transmit(UART_HandleTypeDef *u, const uint8_t *p, unsigned n, unsigned timeout) {
+    (void)u;(void)timeout;
+    assert(n < sizeof(last_write)); memcpy(last_write,p,n);last_write[n]=0;last_len=n;writes++;
+    return uart_fail;
+}
+static void put(const void *p, unsigned n) {
+    const uint8_t *b=p;
+    while(n--) {
+        unsigned next=(g_wifi_rx_last+1)%256;
+        assert(next!=g_wifi_rx_head);
+        g_wifi_rx_buf[g_wifi_rx_last]=*b++;g_wifi_rx_last=next;
+    }
+}
+static void query_pc_cmd(CmdMessage *m) {
+    assert(m->len<=128);
+    m->data[m->len]=0; commands++;
+    if(inject_prompt) {inject_prompt=0;put(">",1);}
+}
+static void deal_mUnion_cmd(CmdMessage *m) {query_pc_cmd(m);}
+static int data_send_to_pc(int cmd,char *p,unsigned n) {(void)cmd;(void)p;(void)n;return 0;}
+static unsigned short checkSum(const unsigned char *p,unsigned n) {
+    unsigned sum=0;while(n--)sum+=*p++;return (unsigned short)sum;
+}

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini