Files
vd_960/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/peripheral_main.c
T
wangfq eadc67584f fix(vd960DBN): 复位原因位定义错位修正 — RST_REASON=0x08000000=PORRSTF
现场: RST_REASON 打印 0x08000000, 对照 WCH ch32v20x.h 发现
offlog.h 位定义整体错位 (IWDG=bit31实为bit29, SFT=bit24实为bit28,
POR=bit25实为bit27, LPWR=bit29实为bit31)
结论: 0x08000000=PORRSTF=上电/掉电复位 → 电源跌落方向 (SPI擦除电流脉冲?)
修正:
- offlog.h 位定义对齐 WCH 库, 新增 OFFLOG_RST_RMVF=bit24
- peripheral_main.c RMVF 清除改 bit24 (原写 bit27=PORRSTF 只读位,
  复位标志从未清除, 历史累积污染诊断)
- 协议文档 boot 事件位解析同步
测试回归全过
2026-08-12 18:58:16 +08:00

399 lines
12 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);
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();
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();
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 ******************************/