Files
vd_960/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/peripheral_main.c
T
wangfq 22224416a3 test(vd960DBN): Flash/SPI 全禁用实验 — 定位 SPI 操作触发复位
UART2 隔离后(06fb009)依旧 80ms 复位循环+乱码 → 排除 Loop 数据路径
Hex 日志: 乱码紧跟 snap ok 后的 offlog_boot SPI 写, 复位标志全 0
= NRST 毛刺复位特征, 疑似 SPI 总线(PA4-7)串扰 NRST/调试线 或 电源瞬态
本版: #if 1 跳过 storage/offlog/snap/offlog_boot/load_cfg 全部 SPI 调用
判定: 稳定 → SPI 触发实锤, 硬件查电源/NRST/布线
      仍复位 → 与 SPI 无关, 纯硬件(电源/晶振/其他)
2026-08-12 19:21:57 +08:00

424 lines
13 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.
/********************************** (C) COPYRIGHT *******************************
* File Name : main.c
* Author : WCH
* Version : V1.1
* Date : 2020/08/06
* Description : Peripheral slave application main function and task system initialization
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/******************************************************************************/
/* Header file contains */
#include "CONFIG.h"
#include "HAL.h"
#include "gattprofile.h"
#include "peripheral.h"
#include "cmcng.h"
#include <string.h>
#include "dbn_ble_srv.h"
#include "eth_driver.h"
#include "net_srv.h"
#include "storage.h"
#include "offlog.h"
#include "snapshot.h"
#include "tcp_json_srv.h"
#include "loop_uart_proto.h"
#include "iot_mqtt_srv.h"
/*********************************************************************
* GLOBAL TYPEDEFS
*/
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
#define KEY_GPIO (RCC_APB2Periph_GPIOA)
#define KEY_BV BV(0)
#define KEY_IN (GPIO_ReadInputDataBit(KEY_GPIO, KEY_BV)==0)
#define HAL_PUSH_BUTTON() (KEY1_IN) //Add custom button
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
// #else
// uint8_t MACAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
#endif
uint8_t gMacAddr[6] = { 0x38, 0x3B, 0x26, 0x11, 0xA4 ,0x35 };
/* Used for app judgment file effectiveness */
const uint32_t Address = 0xFFFFFFFF;
__attribute__((aligned(4))) uint32_t Image_Flag __attribute__((section(".ImageFlag"))) = (uint32_t)&Address;
uint8_t g_dev_number[6] = ""; // Ʒ
uint8_t g_dev_password[6] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
uint8_t g_ble_safe_flag = 0;
uint32_t g_ble_safe_counter_ori = 0;
uint32_t g_ble_safe_counter_dst = 0;
char g_flag_debug = 1;
uint8_t g_dg_device_type = DDType_DLD950V4; // ????????????????
uint8_t g_dg_sub_dev_type = DDType_DLD950V4;
Sub_Code_Enable g_sub_code_enable = {0,};
uint32_t g_activ_counter = 0;
uint32_t g_counter_bt_timeout = 0;
uint8_t g_flag_bt_state = 0;
uint8_t g_flag_bt_disable = 0;
uint8_t g_max_counter_bt_min = 0;
uint32_t g_max_counter_bt_timeout = 0; //BT_DISABLE_IDLE_TIMEOUT * 60 * 1000; // ms unit
__IO uint32_t TimingDelayInc;
__IO uint32_t TimingDelayDec;
uint8_t trigB;
Pkg_Uart g_pkg_uart_1 = { 0, 0, 0, "", 0};
Pkg_Uart g_pkg_uart_2 = { 0, 0, 0, "", 0};
Flag_Counter g_flag_counter_key = {0, 0, 0};
Flag_Counter g_flag_counter_ota = {0, 0, 0};
uint8_t g_storage_uart_num = 0;
uint32_t g_storage_uart_baud = 19200;//9600;
uint8_t g_storage_uart_num_2 = 1;
uint32_t g_storage_uart_baud_2 = 115200; //115200;
uint32_t mstick(void){
return TimingDelayInc;
}
void InitPkgUart(Pkg_Uart * pkg){
memset(pkg->pkg, 0, BUFF_STACK_SIZE);
pkg->flag = 0;
pkg->tick = 0;
pkg->len = 0;
pkg->offset = 0;
}
/*********************************************************************
* @fn TIM2_Init
*
* @brief Initializes TIM2.
*
* @return none
*/
void TIM2_Init( void )
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure={0};
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000;
TIM_TimeBaseStructure.TIM_Prescaler = WCHNETTIMERPERIOD * 1000 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update ,ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
NVIC_EnableIRQ(TIM2_IRQn);
}
/*********************************************************************
* @fn TIM3_Init
*
* @brief Initializes TIM3.
*
* @return none
*/
void TIM3_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure={0};
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = { 0 };
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
////10ms
// TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000;
// TIM_TimeBaseStructure.TIM_Prescaler = 10 * 1000 - 1;
//1ms
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000;
TIM_TimeBaseStructure.TIM_Prescaler = 1 * 1000 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
NVIC_EnableIRQ(TIM3_IRQn);
}
void key_event_srv(void){
// if(g_flag_counter_key.tick > 1000){
// PRINT("key_tick_timeup_______: %d\n", GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0));
// g_flag_counter_key.tick = 0;
// }
if(g_flag_counter_key.flag){
uint8_t _pkg[7] = {0};
uint8_t i = 0;
switch (g_flag_counter_key.flag) {
case KEY_ET_BLE_ENABLE: {
PRINT("______KEY_ET_BLE_ENABLE\n");
NVIC_SystemReset();
} break;
case KEY_ET_REBOOT: {
PRINT("__________KEY_ET_REBOOT\n");
_pkg[i++] = 0x7F;
_pkg[i++] = 0x00;
_pkg[i++] = 0x01;
_pkg[i++] = 0x6D;
_pkg[i++] = 0x6C;
_pkg[i++] = 0x6E;
UART2_SendString(_pkg, i); //1 send loop mcu reboot;
Delay_Ms(10);
// 2 DBN dev reboot
NVIC_SystemReset();
} break;
case KEY_ET_FACTORY: {
PRINT("_____________KEY_ET_FACTORY\n");
_pkg[i++] = 0x7F;
_pkg[i++] = 0x00;
_pkg[i++] = 0x01;
_pkg[i++] = 0x92;
_pkg[i++] = 0x93;
_pkg[i++] = 0x93;
UART2_SendString(_pkg, i); //1 send loop mcu factory init
} break;
case KEY_ET_NETBLE_FACTORY: {
//2 DBN dev factory init;
factory_dev_info();
Delay_Ms(10);
NVIC_SystemReset();
} break;
}
g_flag_counter_key.flag = 0;
}
}
/*********************************************************************
* @fn Main_Circulation
*
* @brief Main loop
*
* @return none
*/
__attribute__((section(".highcode")))
__attribute__((noinline))
void Main_Circulation(void)
{
uint32_t _counter = 0;
while(1)
{
TMOS_SystemProcess();
if(g_net_state.flag < 2)
{
net_srv_init();
}
if(g_net_state.flag == 2)
{
if(g_sub_code_enable.iot_enable){
if(iot_net_info.mode == IOT_Addr_IP_Mode){
if(get_ipstr_to_array(iot_net_info.remote_addr, RemoteIP) == 0){
WCHNET_CreateTcpMqttSocket();
}
}
else{
//DNS
}
}
else
{
WCHNET_CreateTcpSocket();
}
}
/*Ethernet library main task function,
* which needs to be called cyclically*/
WCHNET_MainTask();
/*Query the Ethernet global interrupt,
* if there is an interrupt, call the global interrupt handler*/
if(WCHNET_QueryGlobalInt())
{
WCHNET_HandleGlobalInt();
}
uart_srv();
snap_flush(); /* 快照落盘: 无条件挂主循环 (原在 iot_enable 分支, TCP 模式不落盘) */
poll_dbn_ble();
if (g_sub_code_enable.iot_enable) {
iot_mqtt_publish_sensor(); // Push 0xC0 sensor data to MQTT broker
iot_mqtt_poll(); // IoT MQTT state machine + PINGREQ keepalive
} else {
tcp_json_push_sensor(); // Push 0xC0 sensor data to TCP JSON client
tcp_json_poll();
}
key_event_srv();
}
}
/*********************************************************************
* @fn main
*
* @brief Main function
*
* @return none
*/
int main(void)
{
SystemCoreClockUpdate();
Delay_Init();
#ifdef DEBUG
// USART_Printf_Init( 115200 );
USART_Printf_Init( 256000 );
#endif
/* 诊断: 复位原因寄存器 (bit31=IWDG bit30=WWDG bit29=LPWR bit26=NRST bit25=POR bit24=软复位)
每次上电必打, 区分看门狗死锁 vs 掉电 vs 外部复位 */
PRINT("RST_REASON: 0x%08lx\n", (unsigned long)OFFLOG_RCC_RSTSCKR);
PRINT("%s\n", VER_LIB);
PRINT("SystemCoreClock:%d\n", SystemCoreClock);
/* ===== 实验: 禁用全部 Flash/SPI 操作 (2026-08-12) =====
目的: 验证 SPI 操作是否触发复位循环 (UART2 隔离后依旧复位+乱码,
乱码紧跟 offlog_boot 的 SPI 写, 疑似 SPI 信号串扰 NRST/调试线)
#if 1 = 跳过全部 SPI; 通过后改 0 或删除本块恢复 */
#if 1
PRINT("ISOLATE: flash/SPI disabled (flash isolation test)\n");
#else
GetMacAddr(gMacAddr);
storage_init();
PRINT("INIT: storage ok\n");
offlog_init();
PRINT("INIT: offlog ok\n");
snap_init();
PRINT("INIT: snap ok\n");
/* 复位原因: 必须在初始化后立即读 (离复位时刻最近), 并清除标志,
保证下次上电只反映本次复位原因 (RCC_RSTSCKR, STM32F1/CH32V20x 兼容) */
{
uint32_t rcc_rst = OFFLOG_RCC_RSTSCKR;
offlog_boot(rcc_rst);
OFFLOG_RCC_RSTSCKR |= OFFLOG_RST_RMVF; /* RMVF (bit24): 清复位标志 (原写 bit27=PORRSTF 无效) */
}
load_cfg_from_flash();
output_cfg_from_flash();
#endif
PRINT("MAC: %02X %02X %02X %02X %02X %02X\r\n", gMacAddr[0],gMacAddr[1], gMacAddr[2], gMacAddr[3],gMacAddr[4],gMacAddr[5]);
PRINT("net version:%x\n", WCHNET_GetVer());
WCHBLE_Init();
HAL_Init();
uart_init();
/* ===== 实验: 禁用 UART2 (Loop 口) 隔离测试 (2026-08-12) =====
目的: 验证 Loop MCU 数据/干扰是否导致复位循环 (RST_REASON 全 0 瞬态复位)
做法: USART2 关断 + PA3 脱离 UART 功能(上拉输入) — 等效软件断开 Loop
通过后删除此块; 另: 禁用后快照无帧入队, 同步验证快照 SPI 活动非诱因 */
{
GPIO_InitTypeDef gpio;
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
USART_Cmd(USART2, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_IPU; /* PA3 脱离 UART2, 上拉输入 */
gpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio);
PRINT("ISOLATE: UART2 disabled (Loop isolation test)\n");
}
TIM3_Init();
TIM2_Init();
GAPRole_PeripheralInit();
Peripheral_Init();
Main_Circulation();
}
void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn TIM3_IRQHandler, 1ms
*
* @brief This function handles TIM2 exception.
*
* @return none
*/
void TIM3_IRQHandler(void)
{
TimingDelayInc++;
g_activ_counter++;
if(g_pkg_uart_2.offset){
if(g_pkg_uart_2.flag == 0){
g_pkg_uart_2.tick++;
if(g_pkg_uart_2.tick > 8){
g_pkg_uart_2.flag = 1;
}
}
}
// Safety: reset frame parser if stuck in non-IDLE state too long
if(g_lup_parser.state != LUP_FRAME_STATE_IDLE){
if(g_pkg_uart_2.tick > 20){
lup_frame_reset();
g_pkg_uart_2.tick = 0;
}
}
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0){//HAL_PUSH_BUTTON()){
g_flag_counter_key.tick++;
}
else{
if(g_flag_counter_key.tick){
if(g_flag_counter_key.tick < 2000){
g_flag_counter_key.flag = KEY_ET_BLE_ENABLE;
}
else if(g_flag_counter_key.tick < 6000){
g_flag_counter_key.flag = KEY_ET_REBOOT;
}
else if(g_flag_counter_key.tick < 10000){
g_flag_counter_key.flag = KEY_ET_FACTORY;
}
else{
g_flag_counter_key.flag = KEY_ET_NETBLE_FACTORY;
}
g_flag_counter_key.tick = 0;
}
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
/******************************** endfile @ main ******************************/