refactor(vd960Loop): 算法回退到 DLD154V4B,四通道适配

- 用 DLD154V4B vd1_task/per_channel 替换 vds_task 复杂算法
- 移除 FUNCTION_B/二次判断/快速变化/多重确认等增强特性
- 保留平坦性离开算法 (CN200910309382),每通道独立状态
- 灵敏度表改为 DLD154V4B 4级: {216,108,36,10} / {108,72,18,9}
- 清理废弃类型: FltHistoryManager, Loop_ACS_Info, StageRangeConfig 等
- 首次添加 vd960DBN 完整源码
This commit is contained in:
wangfq
2026-06-25 16:21:57 +08:00
parent 6fd4e564e3
commit 95808f9f25
966 changed files with 406958 additions and 84 deletions

View File

@@ -0,0 +1,428 @@
/**
******************************************************************************
* @file CFIG_FLASH.h
* @author wfq
* @version V1.0
* @date 2025-02-07
* @brief ??????????¡ã?¡À???????????????
* @attention
******************************************************************************
*/
#include "storage.h"
#include "config.h"
#include "cmcng.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "net_srv.h"
#define DEV_USER_FLASH_MAGIC PRODUCT_MODEL
#define CFG_FLASH_BLOCK_SIZE 0x200
#define DEV_CNG_ADDR_BASE (0x00) // + 0x200)
void factory_dev_info(void)
{
uint16_t i, j;
uint32_t _offset = 0;
uint16_t len = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
memcpy(mBuff, DEV_USER_FLASH_MAGIC, sizeof(DEV_USER_FLASH_MAGIC));
_offset = DEV_NUMER_ADDR_OFFSET;
memcpy(g_dev_number, gMacAddr, 6);
memcpy(&mBuff[_offset], g_dev_number, sizeof(g_dev_number));
mBuff[DEV_SUB_CODE_ADDR_OFFSET] = 0x01; // SSC net
mBuff[DEV_BUS_BAUD_ADDR_OFFSET] = BT_DISABLE_IDLE_TIMEOUT;
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 1] = (uint8_t)UART_BAUD_DEFAULT_PORT_1;
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 2] = (uint8_t)(UART_BAUD_DEFAULT_PORT_1 >> 8);
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 3] = (uint8_t)(UART_BAUD_DEFAULT_PORT_1 >> 16);
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 4] = 0x02;
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 5] = (uint8_t)UART_BAUD_DEFAULT_PORT_2;
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 6] = (uint8_t)(UART_BAUD_DEFAULT_PORT_2 >> 8);
mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 7] = (uint8_t)(UART_BAUD_DEFAULT_PORT_2 >> 16);
sprintf((char *)(&mBuff[DEV_PASSWORD_ADDR_OFFSET]), "%s", "123456");
// for(i = 0; i < CFG_FLASH_BLOCK_SIZE; i++){
// PRINT(" %02X", mBuff[i]);
// }
// PRINT("\nWill_Write_cng:");
SPI_Flash_Write(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
free(mBuff);
Delay_Ms(50);
Local_Net_Cfg lcfg = {
{gMacAddr[0], gMacAddr[1], gMacAddr[2], gMacAddr[3], gMacAddr[4], gMacAddr[5]},
{192,168,1,188},
{255,255,255,0},
{192,168,1,1},
{192,168,1,1},
5550,NET_REPORT_INTERVAL, 5505, // Master Port: tcp, udp, udp_message
5550, 4900 // Dev Port: tcp, udp
};
NET_CENTER_INFO ccfg = {
{192,168,1,222},
4999,5550,NET_REPORT_INTERVAL, {1,2}
};
IOT_NET_INFO icfg = {
"121.37.20.199",
1883,
" ",
"admin",
"password",
0
};
IOT_Topic _topic = {
0,
TOPIC_DEFAULT_PUBLISH,
TOPIC_DEFAULT_SUBSCRIBE
};
write_net_config(&lcfg, &ccfg, &icfg, &_topic);
}
char get_ble_safe_flag(void)
{
return g_ble_safe_flag;
}
void open_ble_safe_flag(void)
{
if(g_ble_safe_flag == 1)
{
return;
}
g_ble_safe_counter_dst = 0;
g_ble_safe_counter_ori = g_ble_safe_counter_dst;
g_ble_safe_flag = 1;
}
void close_ble_safe_flag(void)
{
if(g_ble_safe_flag == 0)
{
return;
}
g_ble_safe_flag = 0;
}
char check_ble_safe_pass(uint8_t * devpass)
{
if((g_dev_password[0] != devpass[0]) ||
(g_dev_password[1] != devpass[1]) ||
(g_dev_password[2] != devpass[2]) ||
(g_dev_password[3] != devpass[3]) ||
(g_dev_password[4] != devpass[4]) ||
(g_dev_password[5] != devpass[5]))
{
close_ble_safe_flag();
return 0;
}
open_ble_safe_flag();
return 1;
}
void set_ble_safe_pass(uint8_t * devpass)
{
uint16_t len = 0;
uint16_t _offset = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
SPI_Flash_Read(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
_offset = DEV_PASSWORD_ADDR_OFFSET;
mBuff[_offset++] = devpass[0];
mBuff[_offset++] = devpass[1];
mBuff[_offset++] = devpass[2];
mBuff[_offset++] = devpass[3];
mBuff[_offset++] = devpass[4];
mBuff[_offset++] = devpass[5];
SPI_Flash_Write(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
free(mBuff);
}
void write_net_config(Local_Net_Cfg *local, NET_CENTER_INFO *center, IOT_NET_INFO *iotcfg, IOT_Topic *iottopic)
{
uint16_t i;
uint32_t _offset = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
SPI_Flash_Read(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
_offset = NET_LOCAL_CFG_ADDR_OFFSET;
memcpy(&mBuff[_offset], local, sizeof(Local_Net_Cfg));
_offset = NET_CENTER_CFG_ADDR_OFFSET;
memcpy(&mBuff[_offset], center, sizeof(NET_CENTER_INFO));
_offset = IOT_NET_CFG_ADDR;
memcpy(&mBuff[_offset], iotcfg, sizeof(IOT_NET_INFO));
_offset = IOT_TOPIC_CFG_ADDR;
memcpy(&mBuff[_offset], iottopic, sizeof(IOT_Topic));
// for(i = 0; i < CFG_FLASH_BLOCK_SIZE; i++){
// PRINT(" %02X", mBuff[i]);
// }
// PRINT(" \nEND_Factory\n");
SPI_Flash_Write(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
free(mBuff);
Delay_Ms(50);
}
void load_cfg_from_flash(void)
{
uint16_t i, j;
uint32_t _offset = 0;
uint16_t len = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
SPI_Flash_Read(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
// for(i = 0; i < CFG_FLASH_BLOCK_SIZE; i++){
// PRINT(" %02X", mBuff[i]);
// }
// PRINT("\n");
if(strncmp(mBuff, DEV_USER_FLASH_MAGIC, sizeof(DEV_USER_FLASH_MAGIC)) != 0)
{
free(mBuff);
PRINT("Will_Factory_dev_____\n");
factory_dev_info();
NVIC_SystemReset();
}
_offset = DEV_NUMER_ADDR_OFFSET;
memcpy(g_dev_number, &mBuff[_offset], 6);
memcpy(g_dev_number, &mBuff[DEV_NUMER_ADDR_OFFSET], 6); //
sprintf(g_dev_number_str, "%02X%02X%02X%02X%02X%02X",g_dev_number[0],g_dev_number[1],g_dev_number[2],g_dev_number[3],g_dev_number[4],g_dev_number[5]);
g_sub_code_enable.code_set = *(uint16_t *)(&mBuff[DEV_SUB_CODE_ADDR_OFFSET]);
g_max_counter_bt_min = mBuff[DEV_BUS_BAUD_ADDR_OFFSET];
g_max_counter_bt_timeout = g_max_counter_bt_min * 60 * 1000;
g_storage_uart_baud = (mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 1]) | (mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 2] << 8) | (mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 3] << 16);
g_storage_uart_baud_2 = (mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 5]) | (mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 6] << 8) | (mBuff[DEV_BUS_BAUD_ADDR_OFFSET + 7] << 16);
memcpy(g_dev_password, &mBuff[DEV_PASSWORD_ADDR_OFFSET], 6);
memcpy(local_net_cfg.mac, g_dev_number, 6);
_offset = NET_LOCAL_CFG_ADDR_OFFSET;
Local_Net_Cfg *lnet = (Local_Net_Cfg *)(&mBuff[_offset]);
// memcpy(local_net_cfg.mac, lnet->mac, 6);
memcpy(local_net_cfg.lip, lnet->lip, 4);
memcpy(local_net_cfg.sub, lnet->sub, 4);
memcpy(local_net_cfg.gw, lnet->gw, 4);
memcpy(local_net_cfg.dns, lnet->dns, 4);
local_net_cfg.port_ssc_tcp = lnet->port_ssc_tcp;
local_net_cfg.port_ssc_udp = lnet->port_ssc_udp;
local_net_cfg.port_ssc_udp_message = lnet->port_ssc_udp_message;
local_net_cfg.port_dev_tcp = lnet->port_dev_tcp;
local_net_cfg.port_dev_udp = lnet->port_dev_udp;
_offset = NET_CENTER_CFG_ADDR_OFFSET;
NET_CENTER_INFO *cinfo = (NET_CENTER_INFO *)(&mBuff[_offset]);
memcpy(net_center_info.lssc_ip, cinfo->lssc_ip, 4);
net_center_info.msg_port = cinfo->msg_port;
net_center_info.tcp_port = cinfo->tcp_port;
net_center_info.udp_port = cinfo->udp_port;
memcpy(net_center_info.sw_ver, cinfo->sw_ver, 2);
_offset = IOT_NET_CFG_ADDR;
IOT_NET_INFO *iinfo = (IOT_NET_INFO *)(&mBuff[_offset]);
memcpy(iot_net_info.remote_addr, iinfo->remote_addr, 64);
iot_net_info.mqtt_port = iinfo->mqtt_port;
memcpy(iot_net_info.client_id, iinfo->client_id, 64);
memcpy(iot_net_info.username, iinfo->username, 64);
memcpy(iot_net_info.password, iinfo->password, 32);
//check dns or ip mode
iot_net_info.mode = iinfo->mode; //dns or ip mode
_offset = IOT_TOPIC_CFG_ADDR;
IOT_Topic *_topic = (IOT_Topic *)(&mBuff[_offset]);
g_iot_topic.clientid_enable = _topic->clientid_enable;
memcpy(g_iot_topic.topic_pub, _topic->topic_pub, 64);
memcpy(g_iot_topic.topic_sub, _topic->topic_sub, 64);
free(mBuff);
g_sub_code_enable.net_enable = g_sub_code_enable.code_set & 0x01;
g_sub_code_enable.iot_enable = (g_sub_code_enable.code_set >> 1) & 0x01;
g_sub_code_enable.custom_enable = (g_sub_code_enable.code_set >> 2) & 0x01;
g_sub_code_enable.loop_enable = (g_sub_code_enable.code_set >> 3) & 0x01;
g_sub_code_enable.dgdus_enable = (g_sub_code_enable.code_set >> 4) & 0x01;
g_sub_code_enable.wbdus_enable = (g_sub_code_enable.code_set >> 5) & 0x01;
g_sub_code_enable.radar_enable = (g_sub_code_enable.code_set >> 6) & 0x01;
// g_sub_code_enable.laser_enable = (g_sub_code_enable.code_set >> 9) & 0x01;
// g_sub_code_enable.lora_enable = (g_sub_code_enable.code_set >> 15) & 0x01;
}
void output_cfg_from_flash(void)
{
// if(g_flag_debug)
// {
PRINT("\nBaud1:%d, Baud2:%d\n", g_storage_uart_baud, g_storage_uart_baud_2);
PRINT("\nGet Net config:\n");
PRINT("Local Net Config: "
" mac:%02X-%02X-%02X-%02X-%02X-%02X\n"
" ip:%d.%d.%d.%d\n"
" submask:%d.%d.%d.%d\n"
" gateway:%d.%d.%d.%d\n"
" dns:%d.%d.%d.%d\n"
" ssc_port tcp: %d, udp:%d, udp_msg:%d\n"
" dev_port tcp: %d, udp:%d\n",
local_net_cfg.mac[0],local_net_cfg.mac[1],local_net_cfg.mac[2],local_net_cfg.mac[3],local_net_cfg.mac[4],local_net_cfg.mac[5],
local_net_cfg.lip[0],local_net_cfg.lip[1],local_net_cfg.lip[2],local_net_cfg.lip[3],
local_net_cfg.sub[0],local_net_cfg.sub[1],local_net_cfg.sub[2],local_net_cfg.sub[3],
local_net_cfg.gw[0],local_net_cfg.gw[1],local_net_cfg.gw[2],local_net_cfg.gw[3],
local_net_cfg.dns[0],local_net_cfg.dns[1],local_net_cfg.dns[2],local_net_cfg.dns[3],
local_net_cfg.port_ssc_tcp, local_net_cfg.port_ssc_udp, local_net_cfg.port_ssc_udp_message,
local_net_cfg.port_dev_tcp, local_net_cfg.port_dev_udp
);
PRINT("Net Center Config:\n");
PRINT(
" lssc_ip:%d.%d.%d.%d\n"
" msg_port:%d, tcp_port:%d, udp_port:%d, sw_ver:%d.%d\n",
net_center_info.lssc_ip[0], net_center_info.lssc_ip[1], net_center_info.lssc_ip[2], net_center_info.lssc_ip[3],
net_center_info.msg_port, net_center_info.tcp_port, net_center_info.udp_port,
net_center_info.sw_ver[0], net_center_info.sw_ver[1]);
PRINT("Iot Net Config:\n");
PRINT(
" remote_addr:%s\n"
" mqtt_port:%d, client_id:%s\n"
" username:%s\n"
" password:%s\n"
" mode:%d\n\n",
iot_net_info.remote_addr, iot_net_info.mqtt_port, iot_net_info.client_id,
iot_net_info.username, iot_net_info.password, iot_net_info.mode);
PRINT("Iot Topic Config:\n");
PRINT(
" clientid_enable:%d\n"
" topic_pub:%s\n"
" topic_sub:%s\n",
g_iot_topic.clientid_enable, g_iot_topic.topic_pub, g_iot_topic.topic_sub);
// }
}
// g_sub_code_enable.code_set get ready first.
void update_sub_code_enable(void)
{
uint32_t _offset = 0;
uint16_t len = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
PRINT("Err_When_malloc__\n");
free(mBuff);
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
SPI_Flash_Read(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
_offset = DEV_SUB_CODE_ADDR_OFFSET;
memcpy(&mBuff[_offset], &(g_sub_code_enable.code_set), sizeof(g_sub_code_enable.code_set));
SPI_Flash_Write(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
free(mBuff);
}
//
void alter_dev_serila(uint8_t *serial)
{
uint32_t _offset = 0;
uint16_t len = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
SPI_Flash_Read(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
memcpy(&mBuff[DEV_NUMER_ADDR_OFFSET], serial, 6);
SPI_Flash_Write(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
free(mBuff);
}
void alter_dev_baud(uint8_t *baudbuf)
{
uint32_t _offset = 0;
uint8_t *mBuff = (uint8_t *)malloc(CFG_FLASH_BLOCK_SIZE);
if(mBuff == NULL)
{
return;
}
memset(mBuff, 0, CFG_FLASH_BLOCK_SIZE);
SPI_Flash_Read(mBuff, DEV_CNG_ADDR_BASE, CFG_FLASH_BLOCK_SIZE);
memcpy(&mBuff[DEV_BUS_BAUD_ADDR_OFFSET], baudbuf, 8);
free(mBuff);
}

View File

@@ -0,0 +1,86 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_it.c
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : Main Interrupt Service Routines.
*********************************************************************************
* 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.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "ch32v20x_it.h"
#include "eth_driver.h"
#include "CONFIG.h"
/*********************************************************************
* LOCAL FUNCTIONS
*/
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void BB_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void ETH_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn NMI_Handler
*
* @brief This function handles NMI exception.
*
* @return None
*/
void NMI_Handler(void)
{
}
/*********************************************************************
* @fn HardFault_Handler
*
* @brief This function handles Hard Fault exception.
*
* @return None
*/
void HardFault_Handler(void)
{
NVIC_SystemReset();
while(1)
{
}
}
/*********************************************************************
* @fn BB_IRQHandler
*
* @brief BB Interrupt for BLE.
*
* @return None
*/
void BB_IRQHandler(void)
{
BB_IRQLibHandler();
}
/*********************************************************************
* @fn ETH_IRQHandler
*
* @brief This function handles ETH exception.
*
* @return none
*/
void ETH_IRQHandler(void)
{
WCHNET_ETHIsr();
}
void TIM2_IRQHandler( void )
{
WCHNET_TimeIsr(WCHNETTIMERPERIOD);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}

View File

@@ -0,0 +1,922 @@
/*
* dbn_ble_srv.c
*
* Created on: Aug 27, 2024
* Author: Thinkpad
*/
#include "dbn_ble_srv.h"
#include "cmcng.h"
#include "storage.h"
#include <string.h>
#include "net_srv.h"
uint8_t g_flag_notify_temp = 0; //临时通知notify flag, 0 disable, 1 enable
BLE_Notify_Buf g_notify_buftemp = {0,0, ""};
BLE_Notify_Buf g_ble_rcv_buf = {0,0, ""};
BLE_Notify_Buf g_tmp_report_buf = {0,0, ""};
Buf_DBN_BLE g_buf_ble_response = {0,0,0,0,0,0,0,""};
DBN_BLE_State g_dbn_ble_state_acs_enable = {0};
uint8_t tmp_ble_buf[MAX_BLE_TMP_BUF_LEN] = "";
extern uint8_t loop1_FLAG_CUT;
void clear_ble_notify_buf(BLE_Notify_Buf * buf)
{
buf->len = 0;
buf->flag = 0;
memset(buf, 0, MAX_BLE_Notify_Buf_LEN);
}
void clear_buf_dbn_ble(Buf_DBN_BLE * buf)
{
uint8_t i = 0;
buf->flag = 0;
buf->magic = 0;
buf->cmd = 0;
memset(buf->dat, 0, buf->dat_len);
buf->dat_len = 0;
buf->dat_offset = 0;
buf->pkg_amount = 0;
buf->pkg_seq = 0;
}
void clear_buf_dbn_ble_all(Buf_DBN_BLE * buf)
{
uint8_t i = 0;
// if(g_flag_debug)
{
// PRINT("\nclear_buf_dbn_ble_flag:%02X,magic:%02X,pkg_amount:%02X,seq:%02X,cmd:%02X, dat_len:%d,offset:%d\n",
// buf->flag,buf->magic,buf->pkg_amount, buf->pkg_seq,buf->cmd, buf->dat_len,buf->dat_offset);
// for(i = 0; i < buf->dat_len; i++)
// {
// PRINT(" %02X", buf->dat[i]);
// }
// PRINT("\n");
}
buf->flag = 0;
buf->magic = 0;
buf->cmd = 0;
memset(buf->dat, 0, MAX_BLE_BUF_LEN);
buf->dat_len = 0;
buf->dat_offset = 0;
buf->pkg_amount = 0;
buf->pkg_seq = 0;
}
// 0: 包检测异常
//检测包是否完整Magic Byte, Header Byte, CK Byte, 校验字节(异或校验,以及和校验)
uint8_t check_pkg(uint8_t * pkg, uint8_t len)
{
if(len < 6) //min length of ble pkg is 6
return 0;
uint8_t magic = pkg[0];
uint8_t _len = pkg[2]; //data_len
if(magic == 0x9F){
// if(_len + 4 < len){
// return 0;
// }
if(pkg[1] == 0x01 && pkg[2] == 0x00 && pkg[3] == 0x01 && pkg[4] == 0xA5 && pkg[5] == 0xA7){
g_flag_counter_ota.tick = 0;
g_flag_counter_ota.flag = 1;
PRINT("Come into OTA___\n");
}
}
if(_len + 5 < len)
{
return 0;
}
uint8_t _dxor = 0;
uint8_t _dsum = 0;
uint8_t _cklen = _len + 3; //不计算 校验字节
uint8_t i = 0;
for(i = 1; i < _cklen; i++)
{
_dxor ^= pkg[i];
_dsum += pkg[i];
}
if((_dxor != pkg[_cklen]) || (_dsum != pkg[_cklen+1]))
{
// if(g_flag_debug)
// {
// PRINT("_dxor:0x%02X - 0x%02X, _dsum:0x%02X - 0x%02X\r\n", _dxor, pkg[_cklen], _dsum, pkg[_cklen + 1] );
// }
return 0;
}
return magic;
}
static uint8_t set_dev_info_to_ready(uint8_t *dat_dst)
{
uint8_t i = 0, j = 0;
for(i = 0; i < 6; i++)
{
dat_dst[i] = gMacAddr[i];
// PRINT(" %02X",dat_dst[i] );
}
// memcpy(dat_dst, MACAddr, sizeof(MACAddr));
// i += sizeof(MACAddr);
dat_dst[i++] = HARDWARE_VER_MAIN;
dat_dst[i++] = HARDWARE_VER_SUB;
dat_dst[i++] = FIRMWARE_VER_MAIN;
dat_dst[i++] = FIRMWARE_VER_SUB;
// Dev Model
dat_dst[i++] = strlen(PRODUCT_MODEL);
memcpy(&dat_dst[i], PRODUCT_MODEL, strlen(PRODUCT_MODEL));
i += strlen(PRODUCT_MODEL);
// Dev Number
for(j = 0; j < 6; j++, i++)
{
dat_dst[i] = g_dev_number[j];
}
// sub_code
// memcpy(&dat_dst[i], &(g_sub_code_enable.code_set), sizeof(g_sub_code_enable.code_set));
// i += sizeof(g_sub_code_enable.code_set);
dat_dst[i++] = 0;
dat_dst[i++] = 0;
dat_dst[i++] = 0; // g_bus_dus_amount_stored.bus1_amount;
dat_dst[i++] = 0; //g_bus_dus_amount_stored.bus2_amount;
return i;
}
static uint8_t set_net_info_to_ready(uint8_t * dat_dst)
{
uint8_t i = 0;
memcpy(&dat_dst[i], local_net_cfg.lip, 4);
i += 4;
memcpy(&dat_dst[i], local_net_cfg.sub, 4);
i += 4;
memcpy(&dat_dst[i], local_net_cfg.gw, 4);
i += 4;
memcpy(&dat_dst[i], net_center_info.lssc_ip, 4);
i += 4;
memcpy(&dat_dst[i], local_net_cfg.dns, 4);
i += 4;
dat_dst[i++] = local_net_cfg.port_ssc_tcp;
dat_dst[i++] = local_net_cfg.port_ssc_tcp >> 8;
dat_dst[i++] = local_net_cfg.port_ssc_udp;
dat_dst[i++] = local_net_cfg.port_ssc_udp >> 8;
dat_dst[i++] = local_net_cfg.port_ssc_udp_message;
dat_dst[i++] = local_net_cfg.port_ssc_udp_message >> 8;
dat_dst[i++] = local_net_cfg.port_dev_tcp;
dat_dst[i++] = local_net_cfg.port_dev_tcp >> 8;
dat_dst[i++] = local_net_cfg.port_dev_udp;
dat_dst[i++] = local_net_cfg.port_dev_udp >> 8;
return i;
}
void set_response_iot_net(Buf_DBN_BLE *response_dst)
{ // config iot_net
uint8_t ret = 0;
uint8_t i = 0;
int _len = 0;
clear_buf_dbn_ble(response_dst);
response_dst->magic = MAGIC_BYTE_DBN_DEFAULT;
response_dst->cmd = CMD_DBN_GET_IOT_NET;
memcpy(response_dst->dat, iot_net_info.remote_addr, strlen(iot_net_info.remote_addr));
i += strlen(iot_net_info.remote_addr);
i++;
_len = sprintf(&(response_dst->dat[i]), "%d", iot_net_info.mqtt_port);
i += _len;
i++;
memcpy(&(response_dst->dat[i]), iot_net_info.client_id, strlen(iot_net_info.client_id));
i += strlen(iot_net_info.client_id);
i++;
memcpy(&(response_dst->dat[i]), iot_net_info.username, strlen(iot_net_info.username));
i += strlen(iot_net_info.username);
i++;
memcpy(&(response_dst->dat[i]), iot_net_info.password, strlen(iot_net_info.password));
i += strlen(iot_net_info.password);
response_dst->dat_len = i;
response_dst->pkg_amount = i / MAX_BLE_DAT_RESPONSE_LEN;
if((i % MAX_BLE_DAT_RESPONSE_LEN) > 0)
{
response_dst->pkg_amount += 1;
}
response_dst->pkg_seq = 0;
response_dst->flag = 1;
}
void set_response_iot_topic(Buf_DBN_BLE *response_dst)
{ //config iot_topic
uint8_t ret = 0;
uint8_t i = 0;
int _len = 0;
clear_buf_dbn_ble(response_dst);
response_dst->magic = MAGIC_BYTE_DBN_DEFAULT;
response_dst->cmd = CMD_DBN_GET_IOT_TOPIC;
response_dst->dat[0] = g_iot_topic.clientid_enable + 0x30;
i++;
i++;
memcpy(&(response_dst->dat[i]), g_iot_topic.topic_pub, strlen(g_iot_topic.topic_pub));
i += strlen(g_iot_topic.topic_pub);
i++;
memcpy(&(response_dst->dat[i]), g_iot_topic.topic_sub, strlen(g_iot_topic.topic_sub));
i += strlen(g_iot_topic.topic_sub);
response_dst->dat_len = i;
response_dst->pkg_amount = i / MAX_BLE_DAT_RESPONSE_LEN;
if((i % MAX_BLE_DAT_RESPONSE_LEN) > 0)
{
response_dst->pkg_amount += 1;
}
response_dst->pkg_seq = 0;
response_dst->flag = 1;
}
uint8_t set_response_buf(Buf_DBN_BLE *response_dst, uint8_t magic, uint8_t cmd, uint8_t * dat, uint8_t dat_len)
{
uint8_t ret = 0;
uint8_t i = 0;
clear_buf_dbn_ble(response_dst);
response_dst->magic = magic;
response_dst->cmd = cmd;
uint8_t _amount = dat_len / MAX_BLE_DAT_RESPONSE_LEN;
if((dat_len % MAX_BLE_DAT_RESPONSE_LEN) > 0)
{
_amount++;
}
response_dst->pkg_amount = _amount;
response_dst->pkg_seq = 0;
response_dst->dat_len = dat_len;
for(i = 0; i < dat_len; i++)
{
response_dst->dat[i] = dat[i];
}
response_dst->flag = 1;
return ret;
}
uint16_t compute_ckb(uint8_t header_0, uint8_t header_1, uint8_t header_cmd, uint8_t *dat, uint8_t dat_len)
{
uint16_t ret = 0;
uint8_t i = 0;
uint8_t _dxor = header_0 ^ header_1 ^ header_cmd;
uint8_t _dsum = header_0 + header_1 + header_cmd;
for(i = 0; i < dat_len; i++)
{
_dxor ^= dat[i];
_dsum += dat[i];
}
ret = _dxor;
ret = (ret << 8) + (_dsum % 0x100);
return ret;
}
uint8_t set_response_tran_to_notify(uint8_t *dat_ori, uint8_t dat_len, BLE_Notify_Buf * notify_dst)
{
uint8_t ret = 0;
uint8_t i = 0;
if(g_flag_bt_state == 0){
return ret;
}
if(notify_dst->flag)
{ //dst not idle
return ret;
}
if(dat_len < 6)
{
return ret;
}
for(i = 0; i < dat_len; i++)
{
notify_dst->buf[i] = dat_ori[i];
}
notify_dst->len = dat_len;
notify_dst->flag = 1;
}
//response_ori must set_response_buf first
uint8_t set_response_to_notify(Buf_DBN_BLE *response_ori, BLE_Notify_Buf * notify_dst)
{
uint8_t ret = 0;
uint8_t i = 0;
uint16_t _ckbl = 0;
if(notify_dst->flag)
{ //dst not idle
return ret;
}
if(response_ori->flag == 0)
{ //ori idle
return ret;
}
if(response_ori->pkg_amount <= 1)
{
//没有分包的情况
notify_dst->buf[0] = response_ori->magic;
if(response_ori->magic == MAGIC_BYTE_DBN_TRANSPARENT)
{
notify_dst->buf[1] = response_ori->pkg_seq;
}
else
{
notify_dst->buf[1] = 0;
}
notify_dst->buf[2] = response_ori->dat_len + 1; // 1 is cmd_byte
notify_dst->buf[3] = response_ori->cmd;
_ckbl = compute_ckb(notify_dst->buf[1], notify_dst->buf[2], notify_dst->buf[3], response_ori->dat, response_ori->dat_len);
for(i = 0; i < response_ori->dat_len; i++)
{
notify_dst->buf[i + 4] = response_ori->dat[i];
}
notify_dst->buf[i + 4] = (uint8_t)(_ckbl >> 8);
i++;
notify_dst->buf[i + 4] = (uint8_t)(_ckbl);
i++;
notify_dst->len = i + 4;
// if(g_flag_debug)
// {
// PRINT("set_response_to_notify_dst__\n");
// for(i = 0; i < notify_dst->len; i++)
// {
// PRINT(" %02X", notify_dst->buf[i]);
// }
// }
notify_dst->flag = 1;
clear_buf_dbn_ble(response_ori);
return 1;
}
else
{
notify_dst->buf[0] = response_ori->magic;
uint8_t _pkg_amount = response_ori->pkg_amount;
uint8_t _pkg_seq = response_ori->pkg_seq;
uint8_t _remain_len = response_ori->dat_len - response_ori->dat_offset;
if(_remain_len > MAX_BLE_DAT_RESPONSE_LEN)
{
_remain_len = MAX_BLE_DAT_RESPONSE_LEN;
}
_pkg_seq += 1;
notify_dst->buf[1] = (_pkg_amount << 4)|(_pkg_seq);
notify_dst->buf[2] = _remain_len + 1; // 1 is cmd_byte
notify_dst->buf[3] = response_ori->cmd;
_ckbl = compute_ckb(notify_dst->buf[1], notify_dst->buf[2], notify_dst->buf[3],
&(response_ori->dat[response_ori->dat_offset]), _remain_len);
for(i = 0; i < _remain_len; i++)
{
notify_dst->buf[i + 4] = response_ori->dat[response_ori->dat_offset + i];
}
notify_dst->buf[i + 4] = (uint8_t)(_ckbl >> 8);
i++;
notify_dst->buf[i + 4] = (uint8_t)(_ckbl);
i++;
response_ori->dat_offset += _remain_len;
response_ori->pkg_seq += 1;
notify_dst->len = i + 4;
// if(g_flag_debug)
// {
// PRINT("\nset_notify_dst,amount:%d,seq:%d,offset:%d\n", response_ori->pkg_amount,response_ori->pkg_seq, response_ori->dat_offset);
// for(i = 0; i < notify_dst->len; i++)
// {
// PRINT(" %02X", notify_dst->buf[i]);
// }
// PRINT("\n");
// }
notify_dst->flag = 1;
if(response_ori->pkg_amount == response_ori->pkg_seq)
{
clear_buf_dbn_ble(response_ori);
}
return 1;
}
}
static uint8_t unpack_packs(uint8_t *pkg, uint8_t len)
{
static uint8_t _offset = 0;
uint8_t _header_0 = pkg[1];
uint8_t _header_0_high = _header_0 >> 4;
uint8_t _header_0_low = _header_0 % 0x10;
uint8_t _len = pkg[2];
uint8_t _cmd = pkg[3];
uint8_t i = 0, j = 0, k = 0;
uint8_t _amount = 0;
if(_header_0_high)
{
if(_header_0_low == 1)
{
g_buf_ble_response.magic = pkg[0];
g_buf_ble_response.pkg_amount = _header_0_high;
g_buf_ble_response.pkg_seq = _header_0_low;
g_buf_ble_response.cmd = _cmd;
memcpy(&g_buf_ble_response.dat, &pkg[4], _len - 1);
_offset = _len - 1;
g_buf_ble_response.dat_len = _len - 1;
}
else
{
if((g_buf_ble_response.pkg_amount != _header_0_high) || (g_buf_ble_response.cmd != _cmd))
{
//printf("\nNot_the_right_sub_pack!\n");
clear_buf_dbn_ble_all(&g_buf_ble_response);
return 0;
}
if(g_buf_ble_response.pkg_seq != (_header_0_low -1))
{
//printf("\nNot_the_right_sub_pack!!\n");
clear_buf_dbn_ble_all(&g_buf_ble_response);
return 0;
}
g_buf_ble_response.pkg_seq = _header_0_low;
g_buf_ble_response.dat_len += (_len - 1); // not include cmd_byte
memcpy(&g_buf_ble_response.dat[_offset], &pkg[4], _len - 1);
_offset += (_len - 1);
}
}
else
{
clear_buf_dbn_ble(&g_buf_ble_response);
g_buf_ble_response.magic = pkg[0];
g_buf_ble_response.pkg_amount = 1;
g_buf_ble_response.pkg_seq = 0;
g_buf_ble_response.cmd = _cmd;
g_buf_ble_response.dat_len = (_len - 1);
memcpy(g_buf_ble_response.dat, &pkg[4], _len - 1);
}
if(_header_0_high == _header_0_low)
{
// received end.
// if(g_flag_debug)
// {
// printf("\nReceive_pack_over:\n");
// for(i = 0; i < g_buf_ble_response.dat_len; i++)
// {
// printf(" %02X", g_buf_ble_response.dat[i]);
// }
// printf("\nEnd\n");
// }
if(g_buf_ble_response.cmd == CMD_DBN_CHECK_PASS)
{
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
if(g_buf_ble_response.dat_len != 6)
{
//response pass failed
tmp_ble_buf[0] = 0x01;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
}
else
{
char _pass = check_ble_safe_pass(g_buf_ble_response.dat);
if(_pass)
{
//response ok
tmp_ble_buf[0] = 0x0;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
}
else
{
//response failed
tmp_ble_buf[0] = 0x01;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
}
}
} //end if g_buf_ble_response.cmd == CMD_DBN_CHECK_PASS
else if(g_buf_ble_response.cmd == CMD_DBN_MODIFY_PASS)
{
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
if(g_buf_ble_response.dat_len != 12)
{
//response failed
tmp_ble_buf[0] = 0x01;
}
else
{
char _pass = check_ble_safe_pass(g_buf_ble_response.dat);
if(_pass)
{
//response ok
set_ble_safe_pass(&g_buf_ble_response.dat[6]);
tmp_ble_buf[0] = 0x00;
}
else
{
//response failed
tmp_ble_buf[0] = 0x01;
}
}
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
} //end if g_buf_ble_response.cmd == CMD_DBN_MODIFY_PASS
else if(g_buf_ble_response.cmd == CMD_DBN_SET_IOT_NET)
{
for(i = 0, j = 0, k = 0; i < g_buf_ble_response.dat_len; i++)
{
if(g_buf_ble_response.dat[i] == 0x00)
{
j++;
if(k == 0)
{
//iot _host
PRINT("Rcv_Host:%s\n", tmp_ble_buf);
memcpy(iot_net_info.remote_addr, tmp_ble_buf, j);
}
else if(k == 1)
{
PRINT("Rcv_Port:%s\n", tmp_ble_buf);
uint16_t _port = 0;
for(j = 0; j < strlen(tmp_ble_buf); j++)
{
_port *= 10;
_port += tmp_ble_buf[j] - 0x30;
}
iot_net_info.mqtt_port = _port;
}
else if(k == 2)
{
PRINT("Rcv_Client:%s\n", tmp_ble_buf);
if((strlen(tmp_ble_buf) == 1) && (tmp_ble_buf[0] == 0x20))
{
PRINT("Client_use local_serial\n");
}
else
{
memcpy(iot_net_info.client_id, tmp_ble_buf, j);
}
}
else if(k == 3)
{
PRINT("Rcv_Username:%s\n", tmp_ble_buf);
memcpy(iot_net_info.username, tmp_ble_buf, j);
}
else if(k == 4)
{
PRINT("Rcv_Pass:%s\n", tmp_ble_buf);
memcpy(iot_net_info.password, tmp_ble_buf, j);
}
k++;
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
j = 0;
}
else
{
tmp_ble_buf[j] = g_buf_ble_response.dat[i];
j++;
}
}
if(k == 4)
{
PRINT("Rcv_Pass:%s\n", tmp_ble_buf);
memcpy(iot_net_info.password, tmp_ble_buf, strlen(tmp_ble_buf) + 1);
}
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &g_iot_topic);
// response finally
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
//clear_buf_dbn_ble_all(&g_buf_ble_response);
} //end if CMD_DBN_SET_IOT_NET
else if(g_buf_ble_response.cmd == CMD_DBN_SET_IOT_TOPIC)
{
for(i = 0, j = 0, k = 0; i < g_buf_ble_response.dat_len; i++)
{
if(g_buf_ble_response.dat[i] == 0x00)
{
//j++;
if(k == 0)
{
g_iot_topic.clientid_enable = tmp_ble_buf[0] - 0x30;
}
else if(k == 1)
{
// if(g_flag_debug)
// {
// printf("rcv_topic_pub_:%s\n", tmp_ble_buf);
// for(f = 0; f < j; f++)
// {
// printf(" %02X", tmp_ble_buf[f]);
// }
// printf(", j:%d\n", j);
// }
memset(g_iot_topic.topic_pub, 0, MAX_TOPIC_LENGTH);
memcpy(g_iot_topic.topic_pub, tmp_ble_buf, j + 1);
}
k++;
j = 0;
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
}
else
{
tmp_ble_buf[j] = g_buf_ble_response.dat[i];
j++;
}
}
if(k == 2)
{
// if(g_flag_debug)
// {
// printf("rcv_topic_sub_:%s\n", tmp_ble_buf);
// }
memset(g_iot_topic.topic_sub, 0, MAX_TOPIC_LENGTH);
memcpy(g_iot_topic.topic_sub, tmp_ble_buf, strlen(tmp_ble_buf) + 1);
}
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &g_iot_topic);
// response finally
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
} // end if CMD_DBN_SET_IOT_TOPIC
}
return 0;
}
void manage_dbn_ble_default(uint8_t *pkg, uint8_t len)
{
uint8_t _header_0 = pkg[1];
uint8_t _header_0_high = 0;
uint8_t _header_0_low = _header_0 % 0x10;
uint8_t _len = pkg[2];
uint8_t _cmd = pkg[3];
uint8_t _tmp = 0;
uint8_t i = 0, k = 0;
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
switch(_cmd)
{
case CMD_DBN_GET_DEV_INFO:
{
i = set_dev_info_to_ready(tmp_ble_buf);
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
// printf("\nGet_dev_info\n");
} break;
case CMD_DBN_SET_LSSC_NET:
{
//printf("Set_Net_info_len:%d\n", len);
if(len < 34)
{
return;
}
i = 4;
memcpy(local_net_cfg.lip, &pkg[i], 4);
i += 4;
memcpy(local_net_cfg.sub, &pkg[i], 4);
i += 4;
memcpy(local_net_cfg.gw, &pkg[i], 4);
i += 4;
memcpy(net_center_info.lssc_ip, &pkg[i], 4);
//i += 4;
//printf("Reset_lip:%d\n",local_net_cfg.lip[3]);
i = 24;
//printf("Reset_lport:%02X %02X\n",pkg[24], pkg[25]);
//memcpy(local_net_cfg.dns
// local_net_cfg.port_ssc_tcp = *(uint16_t *)(&pkg[24]); //TOOD: Will err, why?
local_net_cfg.port_ssc_tcp = (pkg[25] << 8) | pkg[24];// This is OK
i += 2;
// local_net_cfg.port_ssc_udp = *(uint16_t *)(&pkg[i]);
local_net_cfg.port_ssc_udp =(pkg[27] <<8 ) | pkg[26];
i += 2;
// local_net_cfg.port_ssc_udp_message = *(uint16_t *)(&pkg[i]);
local_net_cfg.port_ssc_udp_message = (pkg[29] << 8) | pkg[28];
i += 2;
// local_net_cfg.port_dev_tcp = *(uint16_t *)(&pkg[i]);
local_net_cfg.port_dev_tcp = (pkg[31] << 8) | pkg[30];
net_center_info.tcp_port = local_net_cfg.port_dev_tcp;
i += 2;
// local_net_cfg.port_dev_udp = *(uint16_t *)(&pkg[32]);
local_net_cfg.port_dev_udp = (pkg[33] << 8) | pkg[32];
//printf("Will_reset_net_param___\n");
write_net_config(&local_net_cfg, &net_center_info, &iot_net_info, &g_iot_topic);
//response
tmp_ble_buf[0] = 0;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
} break;
case CMD_DBN_GET_LSSC_NET:
{
i = set_net_info_to_ready(tmp_ble_buf);
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
// printf("Get_Net_Info\n");
} break;
case CMD_DBN_GET_IOT_NET:
{
set_response_iot_net(&g_buf_ble_response);
} break;
case CMD_DBN_SET_IOT_NET:
{
unpack_packs(pkg, len);
} break;
case CMD_DBN_SET_IOT_TOPIC:
{
unpack_packs(pkg, len);
} break;
case CMD_DBN_GET_IOT_TOPIC:
{
set_response_iot_topic(&g_buf_ble_response);
} break;
case CMD_DBN_RESET_DEV:
{
//Restart Dev
NVIC_SystemReset();
} break;
case CMD_DBN_CHECK_PASS:
{
unpack_packs(pkg, len);
} break;
case CMD_DBN_SET_CJQ_PARAM:
{
// PRINT("\nSet_Cjq_param\n");
// unpack_pkg_set_cjq_param(pkg, len);
tmp_ble_buf[0] = 0;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
// para_store_init();
} break;
case CMD_DBN_GET_CJQ_PARAM:
{
i = 0;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
// PRINT("\nGet_Cjq_param\n");
} break;
case CMD_DBN_LOOP_SENS_LIST: {
// PRINT("SENS_CNG: %02X\n", pkg[4]);
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
} break;
case CMD_DBN_SET_FACTORY:
case CMD_DBN_SET_CJQ_FACTORY: {
// 出厂初始化
tmp_ble_buf[0] = 0;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
factory_dev_info();
Delay_Ms(10);
//TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
} break;
case CMD_DBN_RW_UART_BAUD:{ //
uint8_t _rw = pkg[4];
uint32_t _baud = 0;
i = 0;
tmp_ble_buf[i++] = _rw;
tmp_ble_buf[i++] = 0x01; //status
if(_rw == 0){// read baud
tmp_ble_buf[i++] = g_max_counter_bt_min; // Idle Ble timeout
tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud; //1 g_storage_uart_baud? 2 g_storage_uart_baud_2
tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 8);
tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 16);
tmp_ble_buf[i++] = 0x02;
tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud_2;
tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud_2 >> 8);
tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud_2 >> 16);
// 4BYte Reserved
}
else { // write baud
alter_dev_baud(&pkg[5]); //
g_storage_uart_num = pkg[5];
g_storage_uart_baud = pkg[6];
g_storage_uart_baud |= (uint16_t)(pkg[7] << 8) & 0xFF00;
g_storage_uart_baud |= (uint32_t)(pkg[8] << 16) & 0xFF0000;
tmp_ble_buf[i++] = g_storage_uart_baud;
tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud;
tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 8);
tmp_ble_buf[i++] = (uint8_t)(g_storage_uart_baud >> 16);
tmp_ble_buf[i++] = 0x00; tmp_ble_buf[i++] = 0x00; tmp_ble_buf[i++] = 0x00; tmp_ble_buf[i++] = 0x00; // 4BYte Reserved
}
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
} break;
case CMD_DBN_UPDATE_DEV_SERIAL:
{
alter_dev_serila(&pkg[4]);
//response
tmp_ble_buf[0] = 1;
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, 1);
} break;
case CMD_SENS_ACS_ENABLE: {
// 线圈动态
g_dbn_ble_state_acs_enable.enable = pkg[5];
if(g_dbn_ble_state_acs_enable.enable){
g_dbn_ble_state_acs_enable.interval = pkg[6] * 0x7F;
g_dbn_ble_state_acs_enable.timeout_min = pkg[7];
if(g_dbn_ble_state_acs_enable.timeout_min){
g_dbn_ble_state_acs_enable.counter = mstick();
g_dbn_ble_state_acs_enable.timeout_counter = g_dbn_ble_state_acs_enable.timeout_min * 60 * 100; // TODO: min --> ms
}
g_dbn_ble_state_acs_enable.flag = 1;
}
else{
g_dbn_ble_state_acs_enable.flag = 0;
}
PRINT("Rcv_acs_enable_flag: %d\n", g_dbn_ble_state_acs_enable.flag);
} break;
default:
{
} break;
}
}
void manage_dbn_ble_transparent(uint8_t *pkg, uint8_t len)
{
//
// transparent_485(pkg, len);
// UART1_SendString(pkg, len);
UART2_SendString(pkg, len);
}
void poll_dbn_ble(void)
{
uint8_t i = 0;
uint8_t magic = 0;
if(g_ble_rcv_buf.flag)
{
if(g_flag_debug && g_flag_counter_ota.flag == 0)
{
PRINT("profile ChangeCB CHAR1?..:%s, len:%d \n", g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
for(i = 0; i < g_ble_rcv_buf.len; i++)
{
PRINT(" %02X", g_ble_rcv_buf.buf[i]);
}
PRINT("\n");
}
if(g_flag_counter_ota.flag == 0){
magic = check_pkg(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
}
// printf("_magic: %02X\n", magic);
if(g_flag_counter_ota.flag){
manage_dbn_ble_transparent(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
}
else{
if(magic != 0)
{
if(magic == MAGIC_BYTE_DBN_DEFAULT)
{
manage_dbn_ble_default(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
}
else if (magic == MAGIC_BYTE_DBN_TRANSPARENT)
{
manage_dbn_ble_transparent(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
}
}
}
// memcpy(g_notify_buftemp.buf, g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
// g_notify_buftemp.len = g_ble_rcv_buf.len;
// g_flag_notify_temp = 1;
clear_ble_notify_buf(&g_ble_rcv_buf);
}
if(g_notify_buftemp.flag == 0)
{
// report_sens_acs();
g_flag_notify_temp = set_response_to_notify(&g_buf_ble_response, &g_notify_buftemp);
}
}

View File

@@ -0,0 +1,37 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_conf.h
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : Library configuration file.
*********************************************************************************
* 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.
*******************************************************************************/
#ifndef __CH32V20x_CONF_H
#define __CH32V20x_CONF_H
#include "ch32v20x_adc.h"
#include "ch32v20x_bkp.h"
#include "ch32v20x_can.h"
#include "ch32v20x_crc.h"
#include "ch32v20x_dbgmcu.h"
#include "ch32v20x_dma.h"
#include "ch32v20x_exti.h"
#include "ch32v20x_flash.h"
#include "ch32v20x_gpio.h"
#include "ch32v20x_i2c.h"
#include "ch32v20x_iwdg.h"
#include "ch32v20x_pwr.h"
#include "ch32v20x_rcc.h"
#include "ch32v20x_rtc.h"
#include "ch32v20x_spi.h"
#include "ch32v20x_tim.h"
#include "ch32v20x_usart.h"
#include "ch32v20x_wwdg.h"
#include "ch32v20x_it.h"
#include "ch32v20x_misc.h"
#endif /* __CH32V20x_CONF_H */

View File

@@ -0,0 +1,18 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32v20x_it.h
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : This file contains the headers of the interrupt handlers.
*********************************************************************************
* 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.
*******************************************************************************/
#ifndef __CH32V20x_IT_H
#define __CH32V20x_IT_H
#include "debug.h"
#endif /* __CH32V20x_IT_H */

View File

@@ -0,0 +1,165 @@
/*
* cmcng.h
*
* Created on: Aug 27, 2024
* Author: Thinkpad
*/
#ifndef INCLUDE_CMCNG_H_
#define INCLUDE_CMCNG_H_
#include <stdint.h>
#define PRODUCT_MODEL "DLD960GA"
#define FIRMWARE_VER "1.0"
#define HARDWARE_VER "1.0"
#define FIRMWARE_VER_MAIN 1
#define FIRMWARE_VER_SUB 1
#define HARDWARE_VER_MAIN 1
#define HARDWARE_VER_SUB 1
#define BUFF_STACK_SIZE 512 //128
#define MAX_UART_TXRX_LEN 32
#define MAX_TOUCHUAN_DISABLE_TIME 15
#define BT_DISABLE_IDLE_TIMEOUT 0 //10 // 蓝牙空闲超时 关闭时间默认10 min
typedef enum
{
DDType_DNT900 = 1, //1 ???????? DNT900
DDType_WireDUS, //2???ù?¨???????? DG
DDType_4G_1,
DDType_WireDus_Wb, //4 ???ù?¨???????? ?ò??
DDType_LoraAreaMain, //5 Lora ?????÷?ú
DDType_LoraAreaSub, //6 Lora ???????ú
DDType_LoraLotMain, //7 Lora ?????÷?ú
DDType_LoraLotSub, //8 Lora ???????ú
DDType_LoraBroadcast, //9 Lora ????????
DDType_LoraRelay, //10 Lora ?????? ???? DLR101
DDType_Relay, //11 ?????????? ?¨??RS485-2 ??·?
DDType_4G_IOT, //12 4G ??±¨??????????????MQTT
DDType_Wire_Collect_IOT, //13 ????????±¨??????????????MQTT
DDType_Wire_Display_IOT, //14 ????????·?????????MQTT
DDType_Radar_Lot, //15 ?×??????
DDType_DLD950 = 20, //DLD950
DDType_DBN101 = 21,
DDType_DNT910 = 22, //DNT910,DNT920
DDType_DNT920 = 23,
DDType_DLD950V4 = 24,
}DG_Device_Type;
typedef enum
{
KEY_ET_None = 0,
KEY_ET_BLE_ENABLE, //1
KEY_ET_REBOOT,
KEY_ET_FACTORY,
KEY_ET_NETBLE_FACTORY
} KEY_EVENT_Type;
typedef struct _SUB_CODE_ENABLE_
{
uint16_t code_set;
uint8_t net_enable;
uint8_t iot_enable;
uint8_t custom_enable;
uint8_t loop_enable; // ?÷??????
uint8_t dgdus_enable;
uint8_t wbdus_enable;
uint8_t radar_enable;
uint8_t laser_enable; // lora?¤???×??????
uint8_t lora_enable; // Lora ????
//uint8_t input_enable;
} Sub_Code_Enable;
extern Sub_Code_Enable g_sub_code_enable;
typedef struct _PKG_UART_
{
uint8_t flag;
uint16_t offset;
uint16_t len;
uint8_t pkg[BUFF_STACK_SIZE];
uint32_t tick;
}Pkg_Uart;
extern Pkg_Uart g_pkg_uart_1;
extern Pkg_Uart g_pkg_uart_2;
#define RX_BUFFER_LEN BUFF_STACK_SIZE
typedef struct
{
volatile uint8_t DMA_USE_BUFFER;
uint8_t Rx_Buffer[2][RX_BUFFER_LEN];
} USART_DMA_UNIT;
typedef struct _DBN_BLE_STATE_
{
uint8_t flag; // if need to report
uint8_t enable; // 是否使能
uint8_t send_flag;
uint8_t obj_amount;
uint8_t cmd;
uint8_t sens_type;
uint8_t dat_len ;
uint8_t dat_offset;
uint8_t pkg_amount;
uint8_t pkg_seq;
uint16_t interval;
uint32_t counter;
uint8_t timeout_min; // minute
uint32_t timeout_counter;
} DBN_BLE_State;
extern DBN_BLE_State g_dbn_ble_state_acs_enable;
typedef struct _FLAG_COUNTER_
{
uint32_t flag;
uint32_t timeout;
uint32_t tick;
} Flag_Counter;
extern Flag_Counter g_flag_counter_key;
extern Flag_Counter g_flag_counter_ota;
extern char g_flag_debug;
extern uint8_t g_dev_number[6];
extern uint8_t g_dev_password[6];
extern uint8_t g_ble_safe_flag;
extern uint32_t g_ble_safe_counter_ori;
extern uint32_t g_ble_safe_counter_dst;
// extern uint8_t MACAddr[6];
extern uint8_t gMacAddr[6];
extern char g_dev_number_str[13];
extern uint32_t g_activ_counter;
extern uint8_t g_dg_sub_dev_type;
extern uint8_t g_dg_device_type;
extern uint8_t g_max_counter_bt_min;
extern uint32_t g_max_counter_bt_timeout;
extern uint8_t g_storage_uart_num;
extern uint8_t g_storage_uart_num_2;
extern uint32_t g_storage_uart_baud;
extern uint32_t g_storage_uart_baud_2;
extern uint8_t g_flag_bt_state;
uint32_t mstick(void);
void InitPkgUart(Pkg_Uart * pkg);
void uart_init(void);
void uart_srv(void);
void UART2_SendString(uint8_t *buf, uint16_t len);
void UART1_SendString(uint8_t *buf, uint16_t len);
#endif /* INCLUDE_CMCNG_H_ */

View File

@@ -0,0 +1,124 @@
/*
* dbn_ble_srv.h
*
* Created on: Aug 27, 2024
* Author: Thinkpad
*/
#ifndef INCLUDE_DBN_BLE_SRV_H_
#define INCLUDE_DBN_BLE_SRV_H_
#include "config.h"
#include <stdint.h>
/*
* Magic | Header | Data | CheckByte
* | Addr/Sub Len CMD | | Xor Sum
* 1Byte | 1B 1B 1B | xx | 1B 1B
*
* * Len = len(CMD) + len(Data)
*/
#define MAGIC_BYTE_DBN_DEFAULT 0x8F
#define MAGIC_BYTE_DBN_TRANSPARENT 0x7F // 用于 显示屏协议、地感协议、探头协议等
#define MAGIC_BYTE_DBN_SUB_OTA 0x9F // 用于 透传子设备OTA升级
#define CMD_DBN_UPDATE_DEV_SERIAL 0x09
#define CMD_DBN_GET_DEV_INFO 0x10
#define CMD_DBN_SET_LSSC_NET 0x11
#define CMD_DBN_GET_LSSC_NET 0x12
#define CMD_DBN_SET_IOT_NET 0x13
#define CMD_DBN_GET_IOT_NET 0x14
#define CMD_DBN_SET_IOT_TOPIC 0x15
#define CMD_DBN_GET_IOT_TOPIC 0x16
#define CMD_DBN_SET_SUB_TRAFFIC_PARAM 0x17
#define CMD_DBN_GET_SUB_TRAFFIC_PARAM 0x18
#define CMD_DBN_CHECK_PASS 0x1C
#define CMD_DBN_MODIFY_PASS 0x1D
#define CMD_DBN_SET_FACTORY 0x1E
#define CMD_DBN_RESET_DEV 0x1F
#define CMD_DBN_SET_NOTIFY 0x20
#define CMD_DBN_SET_NOTIFY_LOOP 0x21
#define CMD_DBN_SET_SUB_CODE 0x22 //使能 子功能
#define CMD_DBN_SET_CJQ_PARAM 0x23 // 设置 车检器参数
#define CMD_DBN_GET_CJQ_PARAM 0x24 // 读取 车检器参数
#define CMD_DBN_RW_UART_BAUD 0x31
#define CMD_DBN_LOOP_SAMPLE_PARAM 0x87
#define CMD_DBN_LOOP_BALANCE_PARAM 0x88
#define CMD_DBN_LOOP_RELEASE_PLANB 0x89
#define CMD_DBN_LOOP_SENS_LIST 0x8A
#define CMD_DBN_SET_CJQ_FACTORY 0x92
#define CMD_SUB_SENS_REPORT 0xC0 //设备主动上报传感信息
// #define CMD_REQUIRE_DEV_MAC_ADDR 0xC1
// #define CMD_CHANGE_DEV_ADDR_BY_MAC 0xC2
// #define CMD_SET_LED 0xC3
// #define CMD_SET_RELAY 0xC4
#define CMD_SENS_ACS_ENABLE 0xC5 // 设备主动上报 使能
#define MAX_BLE_DAT_RESPONSE_LEN (BLE_BUFF_MAX_LEN - 4) // 14 //返回 的所有字节数不能超过20个字节除去 magic、header和ckb校验字节剩下数据的字节数为14
#define MAX_BLE_Notify_Buf_LEN BLE_BUFF_MAX_LEN //24
#define MAX_BLE_BUF_LEN BLE_BUFF_MAX_LEN //128
#define MAX_BLE_TMP_BUF_LEN BLE_BUFF_MAX_LEN
typedef struct _BLE_Notify_Buf_
{
uint8_t flag; //0 idle, 1 buf ready
uint8_t len;
uint8_t buf[MAX_BLE_Notify_Buf_LEN];
}BLE_Notify_Buf;
typedef struct _BUF_DBN_BLE_
{
uint8_t flag;
uint8_t magic;
uint8_t cmd;
uint8_t dat_len ;
uint8_t dat_offset;
uint8_t pkg_amount;
uint8_t pkg_seq;
uint8_t dat[MAX_BLE_BUF_LEN];
} Buf_DBN_BLE;
extern Buf_DBN_BLE g_buf_ble_response;
extern BLE_Notify_Buf g_notify_buftemp;
extern uint8_t g_flag_notify_temp;
extern BLE_Notify_Buf g_ble_rcv_buf;
extern uint16_t loop1_LPCNT;
extern uint8_t g_freq_sens;
extern uint8_t loop1_SensLevel;
extern uint8_t g_freq_level;
extern uint32_t g_sys_freq;
extern float g_freq_tmp;
void clear_ble_notify_buf(BLE_Notify_Buf * buf);
uint8_t set_response_tran_to_notify(uint8_t *dat_ori, uint8_t dat_len, BLE_Notify_Buf * notify_dst);
void poll_dbn_ble(void);
void report_sens_acs(void);
void set_factory_param(void);
void factory_dev(void);
void para_store_init(void);
#endif /* INCLUDE_DBN_BLE_SRV_H_ */

View File

@@ -0,0 +1,167 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : net_config.h
* Author : WCH
* Version : V1.30
* Date : 2022/06/02
* Description : This file contains the configurations of
* Ethernet protocol stack library
*********************************************************************************
* 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.
*******************************************************************************/
#ifndef __NET_CONFIG_H__
#define __NET_CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* socket configuration, IPRAW + UDP + TCP + TCP_LISTEN = number of sockets
*/
#define WCHNET_NUM_IPRAW 0 /* Number of IPRAW connections */
#define WCHNET_NUM_UDP 1 /* The number of UDP connections */
#define WCHNET_NUM_TCP 1 /* Number of TCP connections */
#define WCHNET_NUM_TCP_LISTEN 0 /* Number of TCP listening */
/* The number of sockets, the maximum is 31 */
#define WCHNET_MAX_SOCKET_NUM (WCHNET_NUM_IPRAW+WCHNET_NUM_UDP+WCHNET_NUM_TCP+WCHNET_NUM_TCP_LISTEN)
#define WCHNET_TCP_MSS 576 //1024 //1460 /* Size of TCP MSS*/
#define WCHNET_NUM_POOL_BUF (WCHNET_NUM_TCP*2+2) /* The number of POOL BUFs, the number of receive queues */
/*********************************************************************
* MAC queue configuration
*/
#define ETH_TXBUFNB 1 /* The number of descriptors sent by the MAC */
#define ETH_RXBUFNB 4 /* Number of MAC received descriptors */
#ifndef ETH_MAX_PACKET_SIZE
#define ETH_RX_BUF_SZE 1520 /* MAC receive buffer length, an integer multiple of 4 */
#define ETH_TX_BUF_SZE 1520 /* MAC send buffer length, an integer multiple of 4 */
#else
#define ETH_RX_BUF_SZE ETH_MAX_PACKET_SIZE
#define ETH_TX_BUF_SZE ETH_MAX_PACKET_SIZE
#endif
/*********************************************************************
* Functional configuration
*/
#define WCHNET_PING_ENABLE 1 /* PING is enabled, PING is enabled by default */
#define TCP_RETRY_COUNT 20 /* The number of TCP retransmissions, the default value is 20 */
#define TCP_RETRY_PERIOD 10 /* TCP retransmission period, the default value is 10, the unit is 50ms */
#define SOCKET_SEND_RETRY 0 /* Send failed retry configuration, 1: enable, 0: disable */
#define FINE_DHCP_PERIOD 8 /* Fine DHCP period, the default value is 8, the unit is 250ms */
#define CFG0_TCP_SEND_COPY 1 /* TCP send buffer copy, 1: copy, 0: not copy */
#define CFG0_TCP_RECV_COPY 1 /* TCP receive replication optimization, internal debugging use */
#define CFG0_TCP_OLD_DELETE 0 /* Delete oldest TCP connection, 1: enable, 0: disable */
#define CFG0_IP_REASS_PBUFS 0 /* Number of reassembled IP PBUFs */
#define CFG0_TCP_DEALY_ACK_DISABLE 1 /* 1: disable TCP delay ACK 0: enable TCP delay ACK */
/*********************************************************************
* Memory related configuration
*/
/* If you want to achieve a higher transmission speed,
* try to increase RECE_BUF_LEN to (WCHNET_TCP_MSS*4)
* and increase WCHNET_NUM_TCP_SEG to (WCHNET_NUM_TCP*4)*/
#define RECE_BUF_LEN (WCHNET_TCP_MSS*2) /* socket receive buffer size */
#define WCHNET_NUM_PBUF WCHNET_NUM_POOL_BUF /* Number of PBUF structures */
#define WCHNET_NUM_TCP_SEG (WCHNET_NUM_TCP*2) /* The number of TCP segments used to send */
#define WCHNET_MEM_HEAP_SIZE (((WCHNET_TCP_MSS+0x10+54+8)*WCHNET_NUM_TCP_SEG)+ETH_TX_BUF_SZE+64+2*0x18) /* memory heap size */
#define WCHNET_NUM_ARP_TABLE 50 /* Number of ARP lists */
#define WCHNET_MEM_ALIGNMENT 4 /* 4 byte alignment */
#if CFG0_IP_REASS_PBUFS
#define WCHNET_NUM_IP_REASSDATA 2 /* Number of reassembled IP structures */
/*1: When using the fragmentation function,
* ensure that the size of WCHNET_SIZE_POOL_BUF is large enough to store a single fragmented packet*/
#define WCHNET_SIZE_POOL_BUF (((1500 + 14 + 4) + 3) & ~3) /* Buffer size for receiving a single packet */
/*2: When creating a socket that can receive fragmented packets,
* ensure that "RecvBufLen" member of the "struct _SOCK_INF" structure
* (the parameter initialized when calling WCHNET_SocketCreat) is sufficient
* to receive a complete fragmented packet */
#else
#define WCHNET_NUM_IP_REASSDATA 0 /* Number of reassembled IP structures */
#define WCHNET_SIZE_POOL_BUF (((WCHNET_TCP_MSS + 40 + 14 + 4) + 3) & ~3) /* Buffer size for receiving a single packet */
#endif
/* Check receive buffer */
#if(WCHNET_NUM_POOL_BUF * WCHNET_SIZE_POOL_BUF < ETH_RX_BUF_SZE)
#error "WCHNET_NUM_POOL_BUF or WCHNET_TCP_MSS Error"
#error "Please Increase WCHNET_NUM_POOL_BUF or WCHNET_TCP_MSS to make sure the receive buffer is sufficient"
#endif
/* Check the configuration of the SOCKET quantity */
#if( WCHNET_NUM_TCP_LISTEN && !WCHNET_NUM_TCP )
#error "WCHNET_NUM_TCP Error,Please Configure WCHNET_NUM_TCP >= 1"
#endif
/* Check byte alignment must be a multiple of 4 */
#if((WCHNET_MEM_ALIGNMENT % 4) || (WCHNET_MEM_ALIGNMENT == 0))
#error "WCHNET_MEM_ALIGNMENT Error,Please Configure WCHNET_MEM_ALIGNMENT = 4 * N, N >=1"
#endif
/* TCP maximum segment length */
#if((WCHNET_TCP_MSS > 1460) || (WCHNET_TCP_MSS < 60))
#error "WCHNET_TCP_MSS Error,Please Configure WCHNET_TCP_MSS >= 60 && WCHNET_TCP_MSS <= 1460"
#endif
/* Number of ARP cache tables */
#if((WCHNET_NUM_ARP_TABLE > 0X7F) || (WCHNET_NUM_ARP_TABLE < 1))
#error "WCHNET_NUM_ARP_TABLE Error,Please Configure WCHNET_NUM_ARP_TABLE >= 1 && WCHNET_NUM_ARP_TABLE <= 0X7F"
#endif
/* Check POOL BUF configuration */
#if(WCHNET_NUM_POOL_BUF < 1)
#error "WCHNET_NUM_POOL_BUF Error,Please Configure WCHNET_NUM_POOL_BUF >= 1"
#endif
/* Check PBUF structure configuration */
#if(WCHNET_NUM_PBUF < 1)
#error "WCHNET_NUM_PBUF Error,Please Configure WCHNET_NUM_PBUF >= 1"
#endif
/* Check IP Assignment Configuration */
#if(CFG0_IP_REASS_PBUFS && ((WCHNET_NUM_IP_REASSDATA > 10) || (WCHNET_NUM_IP_REASSDATA < 1)))
#error "WCHNET_NUM_IP_REASSDATA Error,Please Configure WCHNET_NUM_IP_REASSDATA < 10 && WCHNET_NUM_IP_REASSDATA >= 1 "
#endif
/* Check the number of reassembled IP PBUFs */
#if(CFG0_IP_REASS_PBUFS > WCHNET_NUM_POOL_BUF)
#error "WCHNET_NUM_POOL_BUF Error,Please Configure CFG0_IP_REASS_PBUFS < WCHNET_NUM_POOL_BUF"
#endif
/* Check Timer period, in Ms. */
#if(WCHNETTIMERPERIOD > 50)
#error "WCHNETTIMERPERIOD Error,Please Configure WCHNETTIMERPERIOD < 50"
#endif
/* Configuration value 0 */
#define WCHNET_MISC_CONFIG0 (((CFG0_TCP_SEND_COPY) << 0) |\
((CFG0_TCP_RECV_COPY) << 1) |\
((CFG0_TCP_OLD_DELETE) << 2) |\
((CFG0_IP_REASS_PBUFS) << 3) |\
((CFG0_TCP_DEALY_ACK_DISABLE) << 8))
/* Configuration value 1 */
#define WCHNET_MISC_CONFIG1 (((WCHNET_MAX_SOCKET_NUM)<<0)|\
((WCHNET_PING_ENABLE) << 13) |\
((TCP_RETRY_COUNT) << 14) |\
((TCP_RETRY_PERIOD) << 19) |\
((SOCKET_SEND_RETRY) << 25) |\
((FINE_DHCP_PERIOD) << 27))
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,289 @@
/**
******************************************************************************
* @file net_srv.c
* @author wangfq
* @version V1.0
* @date 2026-03-02
* @brief net message handle: unpack, exeute, response
*
******************************************************************************
*/
#ifndef __NET_SRV_H__
#define __NET_SRV_H__
#include <stdint.h>
#define MAX_COUNTER_NET_STATE_NORMAL 100
//#define RECE_BUF_LEN 512 /* ?????????????ó?? */
#define MAX_REPORT_INTERVAL_MS 30000 //60000 //180??
#define MIN_REPORT_INTERVAL_MS 6000 // 6??
#define MAX_REPORT_TIMEOUT_MS 4000 // 4??
#define MAX_REPORT_INTERVAL 3
#define MAX_CLEAR_COUNTER_INTERVAL 4900 // 6hour=6*3600
#define PORT_TCP_DEFAULT 5550
#define NET_REPORT_INTERVAL 300 // 300 second
#define COM_LSSC_MESSAGE_UDP_PORT 5505 //ssc UDP message port
#define COM_LSSC_TCP_PORT 5550
#define COM_LSSC_UDP_PORT 5500
#define COM_DEV_MESSAGE_PORT 4900 //udp dev local message port
#define TOPIC_DEFAULT_SUBSCRIBE "ptpc/display"
#define TOPIC_DEFAULT_PUBLISH "gtpc/display/Initialize"
#define UART_BAUD_DEFAULT_PORT_1 115200 // 与Loop MCU 通信的波特率 TTL, g_storage_uart_baud_1
#define UART_BAUD_DEFAULT_PORT_2 115200 // baud2 TTL g_storage_uart_baud_2
typedef enum
{
IOT_Addr_IP_Mode = 0,
IOT_Addr_DN_Mode // Domain Name Mode
}IOT_Host_Mode;
typedef struct _LOCAL_NET_CFG
{
uint8_t mac[6];
uint8_t lip[4]; /*local IP±???IP???·*/
uint8_t sub[4]; /*×???????*/
uint8_t gw[4];
uint8_t dns[4]; /*DNS·????÷???·*/
uint16_t port_ssc_tcp;
uint16_t port_ssc_udp;
uint16_t port_ssc_udp_message; // use for interval of report
uint16_t port_dev_tcp; //use for server http port
uint16_t port_dev_udp;
}Local_Net_Cfg; //32
extern Local_Net_Cfg local_net_cfg;
typedef struct _NET_CENTER_INFO_
{
uint8_t lssc_ip[4]; //Local Sotfware Service Center ±????í??·???????
uint16_t msg_port;
uint16_t tcp_port; // use for server http port
uint16_t udp_port;
uint8_t sw_ver[2];
}NET_CENTER_INFO;
extern NET_CENTER_INFO net_center_info;
typedef struct _IOT_NET_INFO_
{
uint8_t remote_addr[64];
uint16_t mqtt_port;
uint8_t client_id[64]; //?????±±í??????±??ú?ò????
uint8_t username[64];
uint8_t password[32];
uint8_t mode; //0xXX ??0???? 0 IP, 1 dns, ??1???? 0 disable, 1 enable
//ip, iot_disable, 0x00:0000 0000,
//dns,iot_disable, 0x01:0000 0001,
//ip, iot_enable, 0x02:0000 0010,
//dns,iot_enable, 0x03:0000 0011
}IOT_NET_INFO;
extern IOT_NET_INFO iot_net_info;
#define MAX_TOPIC_LENGTH 64
typedef struct _IOT_TOPIC_
{
uint8_t clientid_enable; // ?÷????·?°ü??¤CClientID
uint8_t topic_pub[MAX_TOPIC_LENGTH];
uint8_t topic_sub[MAX_TOPIC_LENGTH];
} IOT_Topic;
extern IOT_Topic g_iot_topic;
#define MQTT_KEEPALIVE_INTERVAL 9
typedef struct _NET_STATE_
{
uint8_t flag;
uint8_t intstat;
uint32_t counter;
} Net_State;
extern Net_State g_net_state;
void write_net_config(Local_Net_Cfg *local, NET_CENTER_INFO *center, IOT_NET_INFO *iotcfg, IOT_Topic *iottopic);
#define DPG_API_KEY_METHOD "\"Method\""
#define DPG_API_KEY_CODE "\"Code\""
#define DPG_API_KEY_DATA "\"Data\""
#define DPG_API_KEY_IP "\"Ip\""
#define DPG_API_KEY_PORT "\"Port\""
#define DPG_API_KEY_PORT_MST "\"PortMsg\""
#define DPG_API_KEY_Mac "\"Mac\""
#define DPG_API_KEY_SubnetMask "\"SubnetMask\""
#define DPG_API_KEY_DNS "\"DNS\""
#define DPG_API_KEY_DEVICE_CODE "\"Device_code\""
#define DPG_API_KEY_DEVICE_ID "\"Device_id\""
#define DPG_API_KEY_EXTRA_ID "\"Extra_id\""
#define DPG_API_KEY_PARAMS "\"Params\""
#define DPG_API_KEY_AREA_NUM "\"Area_num\""
#define DPG_API_KEY_EXTRA_ID "\"Extra_id\""
#define DPG_API_KEY_AREA_AMOUNT "\"Area_amount\""
#define DPG_API_KEY_DEV_AMOUNT "\"Dev_amount\""
#define DPG_API_KEY_DEV_MODE "\"Dev_mode\""
#define DPG_API_KEY_TOTAL_AMOUNT "\"Total_amount\""
#define DPG_API_KEY_FREE_LOT "\"Free_lot\""
#define DPG_API_KEY_DEV_MODE "\"Dev_mode\""
#define DPG_API_KEY_DisplayLED "\"DisplayLED\""
#define DPG_API_KEY_LED_Addr "\"LED_Addr\""
#define DPG_API_KEY_Content "\"_Content\""
#define DPG_API_KEY_INFO_ENABLE "\"Info_Enable\""
#define DPG_API_KEY_Color "\"Color\""
#define DPG_API_KEY_Duration "\"Duration\""
#define DPG_API_KEY_Bus_Num "\"Bus_Num\""
#define DPG_API_KEY_Sub_Amount "\"Sub_Amount\""
#define DPG_API_KEY_Sub_Dev "\"Sub_Dev\""
#define DPG_API_KEY_Dev_Ip "\"Dev_Ip\""
#define DPG_API_KEY_Gateway_Ip "\"Gateway_Ip\""
#define DPG_API_KEY_Gateway_Port "\"Gateway_Port\""
#define DPG_API_KEY_Server_Ip "\"Server_Ip\""
#define DPG_API_KEY_Server_Port "\"Server_Port\""
#define IOT_API_KEY_HOST "\"Iot_Host\""
#define IOT_API_KEY_PORT "\"Iot_Port\""
#define IOT_API_KEY_USERNAME "\"UserName\""
//add by wfq 20190812
#define DPG_KEY_PARAMS_JSON "\"Params\""
#define KEY_CODE_AccessReport "AccessReport"
#define KEY_CODE_DPG_Addr "\"Dpg_Addr\""
#define KEY_CODE_Access_Channel "\"Access_Channel\""
#define KEY_CODE_State_InOut "\"State_InOut\""
#define KEY_CODE_Time_Stamp "\"TimeStamp\""
#define KEY_CODE_Time_Counter "\"Time_Counter\""
#define KEY_CODE_Bus_Num "\"Bus_Num\""
#define KEY_CODE_Dus_Addr_Enable "\"Dus_Addr_Enable\""
//-------------------
#define SSC_Code_Initialize "\"Initialize\""
#define SSC_Code_UnInitialize "\"UnInitialize\""
#define SSC_Code_Connect "\"Connect\""
#define SSC_Code_DisConnect "\"DisConnect\""
#define SSC_Code_SendCommand "\"SendCommand\""
#define SSC_Code_Speak "\"Speak\""
#define SSC_Code_Count_Off "Count_Off"
#define SSC_Code_Device_Info "Device_Info"
#define SSC_Code_Devs_Info "Devs_Info" //add by wfq 2020-07-14 ?????????????°??×??è±????è±?????
#define SSC_Code_Global_Require "Global_Get"
#define SSC_Code_Global_Set "Global_Set"
#define SSC_Code_Collect_ALL "Collect_All" //?????ù????????????
#define SSC_Code_Collect_Single "Collect_Single" //??????????????????
#define SSC_Code_Config "Config"
#define SSC_Code_DisplayLED "DisplayLED"
#define SSC_Code_Device_Net_Set "Device_Net_Set" //?????è±?????????
#define SSC_Code_HeartBeat "HeartBeat"
#define SSC_Code_CDev_Subs "CDev_Subs" //????×??è±????·????
#define SSC_Code_Device_IOT_Set "Dev_IOT_Set" //?è??IOT???????? MQTT???·?????????????§??????
#define SSC_Code_ACS_Collect_Area "ACS_Collect_Area"
#define SSC_Code_ACS_Collect_Counter "ACS_Collect_Counter" //?????????????????¨?????? add 2021-01-04
#define SSC_Code_Collect_NT_BUS "Collect_NT_BUS" //??????????????×??????·????
#define SSC_Code_CDetail_NT_BUS "CDetail_NT_BUS" //??????????????×????ê?????·???? add 2022-04-19
#define SSC_Code_Radar_Reset "Radar_Reset" //?×?????? 2021-04-23
#define SSC_Code_SerialNet "SerialNet" //485???????? 2021-04-23
#define SSC_Code_Dev_Reset "Dev_Reset" // ?è±??????? 2024-12-13
#define SSC_Code_GetDeviceInfo "\"GetDeviceInfo\""
#define SSC_Code_SetDeviceInfo "\"SetDeviceInfo\""
#define SSC_Code_SetDeviceInfoEX "\"SetDeviceInfoEX\""
#define SSC_Code_StateChangedEvent "\"StateChangedEventReg\""
#define KEY_IOT_HOST "\"Host\""
#define KEY_IOT_PORT "\"Port\""
#define KEY_IOT_USERNAME "\"UserName\""
#define KEY_IOT_PASSWORD "\"Password\""
#define KEY_IOT_MODE "\"Mode\""
//add by wfq 2019-08-14
#define SSC_Code_ACS_Collect_Access "ACS_Collect_Access"
#define SSC_Code_TimeStamp "TimeStamp"
#define SSC_Code_Dev_Time "Dev_Time"
#define SSC_Code_SSC_Time "\"SSC_Time\""
//add by wfq 2020-7-11
#define SSC_Code_ACS_NT_Event "ACS_NT_Event"
#define SSC_Code_GetDusCFG "GetDusCFG" //add by wfq 2020-7-23
#define SSC_Code_SetDusCFG "SetDusCFG" //add by wfq 2020-7-23
#define SSC_Code_ACS_Collect_CJQ "ACS_Collect_CJQ"
//add by wangfq 2022-04-14
#define SSC_Code_Tran_Sub "Tran_Sub" // ??×??è±??¨??????
#define SSC_Code_Dev_Type "\"Dev_Type\"" // ?è±??à?? ×?·????? 20 DLD950
#define SSC_Code_Cmd "Cmd"
#define SSC_Code_Detail "Detail"
extern uint8_t g_flag_timestamp;
extern uint8_t RemoteIP[4];
void manage_udp_message(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_count_off(uint8_t socket, uint8_t count_mode, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_device_reset(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_device_net_set(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_dev_iot_config(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_set_display_led(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_tran_sub(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_radar_reset(uint8_t socket, uint8_t *ip, uint16_t port, uint8_t *buf, uint32_t len);
void unpack_ssc_timestamp(uint8_t *buf, uint32_t len);
void unpack_ssc_collect_cjq_acs_response(uint8_t socket, uint8_t *buf, uint32_t len);
//void acs_dus_report(void);
//void rcv_acs_dus_report_reponse(void);
void dev_response_heartbeat(char *dat);
void dev_send_heartbeat(void);
void dev_get_timestamp_send(void);
void manage_tcp_message(uint8_t socket, uint8_t *buf, uint32_t len);
void manage_mqtt_recv_message(char * msg, int length);
void GetMacAddr(unsigned char *pMAC);
void mStopIfError(u8 iError);
void net_srv_init(void);
void WCHNET_CreateTcpMqttSocket(void);
void WCHNET_CreateTcpSocket(void);
void WCHNET_HandleSockInt(uint8_t socketid, uint8_t intstat);
int get_ipstr_to_array(char *src, uint8_t *dst);
void WCHNET_HandleGlobalInt(void);
#endif

View File

@@ -0,0 +1,67 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : peripheral.h
* Author : WCH
* Version : V1.0
* Date : 2018/12/11
* Description :
*********************************************************************************
* 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.
*******************************************************************************/
#ifndef PERIPHERAL_H
#define PERIPHERAL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************************************************************
* INCLUDES
*/
#include "dbn_ble_srv.h"
/*********************************************************************
* CONSTANTS
*/
// Peripheral Task Events
#define SBP_START_DEVICE_EVT 0x0001
#define SBP_PERIODIC_EVT 0x0002
#define SBP_READ_RSSI_EVT 0x0004
#define SBP_PARAM_UPDATE_EVT 0x0008
#define SBP_PHY_UPDATE_EVT 0x0010
/*********************************************************************
* MACROS
*/
typedef struct
{
uint16_t connHandle; // Connection handle of current connection
uint16_t connInterval;
uint16_t connSlaveLatency;
uint16_t connTimeout;
} peripheralConnItem_t;
/*********************************************************************
* FUNCTIONS
*/
/*
* Task Initialization for the BLE Application
*/
extern void Peripheral_Init(void);
/*
* Task Event Processor for the BLE Application
*/
extern uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events);
/*********************************************************************
*********************************************************************/
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,8 @@
#ifndef __SIMPLE_JSON_H_
#define __SIMPLE_JSON_H_
void simple_parse_json(const char * data, char *key_str, char *value_str);
#endif

View File

@@ -0,0 +1,36 @@
#ifndef _STORAGE_H__
#define _STORAGE_H__
#include <stdint.h>
#define DEV_NUMER_ADDR_OFFSET 0x10
#define DEV_SUB_CODE_ADDR_OFFSET 0x20 //2byte [0x20,0x21]
#define DEV_BUS_BAUD_ADDR_OFFSET 0x22 //8byte [0x22,0x29]
#define DEV_PASSWORD_ADDR_OFFSET 0x2A //6byte [0x2A, 0x2F]
#define NET_LOCAL_CFG_ADDR_OFFSET 0x30 // 0x70 // sizeof(Local_Net_Cfg):32byte
#define NET_CENTER_CFG_ADDR_OFFSET 0x50 // sizeof(NET_CENTER_INFO): 12byte
#define IOT_NET_CFG_ADDR 0x60 // sizeof(IOT_NET_INFO):226(0xE2),
#define IOT_TOPIC_CFG_ADDR (0x60 + 232) // sizeof(IOT_Topic): 129(0x81)
char get_ble_safe_flag(void);
void open_ble_safe_flag(void);
void close_ble_safe_flag(void);
char check_ble_safe_pass(uint8_t * devpass);
void set_ble_safe_pass(uint8_t * devpass);
void alter_dev_serila(uint8_t *serial);
void alter_dev_baud(uint8_t *baudbuf);
void factory_dev_info(void);
void output_cfg_from_flash(void);
void load_cfg_from_flash(void);
void SPI_Flash_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t size);
void SPI_Flash_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t size);
void storage_init(void);
#endif

View File

@@ -0,0 +1,31 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : system_ch32v20x.h
* Author : WCH
* Version : V1.0.0
* Date : 2022/06/16
* Description : CH32V20x Device Peripheral Access Layer System Header File.
*********************************************************************************
* 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.
*******************************************************************************/
#ifndef __SYSTEM_ch32v20x_H
#define __SYSTEM_ch32v20x_H
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
/* System_Exported_Functions */
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
#endif /*__CH32V20x_SYSTEM_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,828 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : peripheral.C
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
* Description : Peripheral slave multi-connection application,
* initialize broadcast connection parameters, then broadcast,
* after connecting to the host, request to update connection parameters,
* and transmit data through custom services
*********************************************************************************
* 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.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "CONFIG.h"
#include "devinfoservice.h"
#include "gattprofile.h"
#include "peripheral.h"
#include "cmcng.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD 50 //100 //200 // 1600
// How often to perform read rssi event
#define SBP_READ_RSSI_EVT_PERIOD 3200
// Parameter update delay
#define SBP_PARAM_UPDATE_DELAY 200 //6400
// PHY update delay
#define SBP_PHY_UPDATE_DELAY 200 //2400
// What is the advertising interval when device is discoverable (units of 625us, 80=50ms)
#define DEFAULT_ADVERTISING_INTERVAL 80
// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
// Minimum connection interval (units of 1.25ms, 6=7.5ms)
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6
// Maximum connection interval (units of 1.25ms, 100=125ms)
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 100
// Slave latency to use parameter update
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
// Supervision timeout value (units of 10ms, 100=1s)
#define DEFAULT_DESIRED_CONN_TIMEOUT 100
// Company Identifier: WCH
#define WCH_COMPANY_ID 0x07D7
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] = {
// complete name
0x12, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
// 'S',
// 'i',
// 'm',
// 'p',
// 'l',
// 'e',
// ' ',
// 'P',
// 'e',
// 'r',
// 'i',
// 'p',
// 'h',
// 'e',
// 'r',
// 'a',
// 'l',
'D','L','D','9','6','0', 'G', 'A', '\0',
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertising)
static uint8_t advertData[] = {
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};
// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "DLD960GA"; // "Simple Peripheral";
// Connection item list
static peripheralConnItem_t peripheralConnList;
static uint16_t peripheralMTU = ATT_MTU_SIZE;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
static void performPeriodicTask(void);
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len);
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
uint16_t connSlaveLatency, uint16_t connTimeout);
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList);
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi);
static void peripheralChar4Notify(uint8_t *pValue, uint16_t len);
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapRolesCBs_t Peripheral_PeripheralCBs = {
peripheralStateNotificationCB, // Profile State Change Callbacks
peripheralRssiCB, // When a valid RSSI is read from controller (not used by application)
peripheralParamUpdateCB
};
// Broadcast Callbacks
static gapRolesBroadcasterCBs_t Broadcaster_BroadcasterCBs = {
NULL, // Not used in peripheral role
NULL // Receive scan request callback
};
// GAP Bond Manager Callbacks
static gapBondCBs_t Peripheral_BondMgrCBs = {
NULL, // Passcode callback (not used by application)
NULL, // Pairing / Bonding state Callback (not used by application)
NULL // oob callback
};
// Simple GATT Profile Callbacks
static simpleProfileCBs_t Peripheral_SimpleProfileCBs = {
simpleProfileChangeCB // Characteristic value change callback
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Peripheral_Init
*
* @brief Initialization function for the Peripheral App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notificaiton ... ).
*
* @param task_id - the ID assigned by TMOS. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void Peripheral_Init()
{
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
// Setup the GAP Peripheral Role Profile
{
uint8_t initial_advertising_enable = TRUE;
uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16_t desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
// Set the GAP Role Parameters
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);
}
{
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
// Set advertising interval
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
// Enable scan req notify
GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, ENABLE);
}
// Setup the GAP Bond Manager
{
uint32_t passkey = 0; // passkey "000000"
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8_t mitm = TRUE;
uint8_t bonding = TRUE;
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
}
// Initialize GATT attributes
GGS_AddService(GATT_ALL_SERVICES); // GAP
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
DevInfo_AddService(); // Device Information Service
SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
// Set the GAP Characteristics
GGS_SetParameter(GGS_DEVICE_NAME_ATT, sizeof(attDeviceName), attDeviceName);
// Setup the SimpleProfile Characteristic Values
{
uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = {1};
uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = {2};
uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {3};
uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {4};
// uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {1, 2, 3, 4, 5};
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, SIMPLEPROFILE_CHAR1_LEN, charValue1);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, charValue2);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN, charValue3);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, charValue4);
// SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5);
}
// Init Connection Item
peripheralInitConnItem(&peripheralConnList);
// Register callback with SimpleGATTprofile
SimpleProfile_RegisterAppCBs(&Peripheral_SimpleProfileCBs);
// Register receive scan request callback
GAPRole_BroadcasterSetCB(&Broadcaster_BroadcasterCBs);
// Setup a delayed profile startup
tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
}
/*********************************************************************
* @fn peripheralInitConnItem
*
* @brief Init Connection Item
*
* @param peripheralConnList -
*
* @return NULL
*/
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList)
{
peripheralConnList->connHandle = GAP_CONNHANDLE_INIT;
peripheralConnList->connInterval = 0;
peripheralConnList->connSlaveLatency = 0;
peripheralConnList->connTimeout = 0;
}
/*********************************************************************
* @fn Peripheral_ProcessEvent
*
* @brief Peripheral Application Task event processor. This function
* is called to process all events for the task. Events
* include timers, messages and any other user defined events.
*
* @param task_id - The TMOS assigned task ID.
* @param events - events to process. This is a bit map and can
* contain more than one event.
*
* @return events not processed
*/
uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
{
// VOID task_id; // TMOS required parameter that isn't used in this function
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
{
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & SBP_START_DEVICE_EVT)
{
// Start the Device
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
return (events ^ SBP_START_DEVICE_EVT);
}
if(events & SBP_PERIODIC_EVT)
{
// Restart timer
if(SBP_PERIODIC_EVT_PERIOD)
{
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
}
// Perform periodic application task
performPeriodicTask();
return (events ^ SBP_PERIODIC_EVT);
}
if(events & SBP_PARAM_UPDATE_EVT)
{
// Send connect param update request
GAPRole_PeripheralConnParamUpdateReq(peripheralConnList.connHandle,
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
DEFAULT_DESIRED_SLAVE_LATENCY,
DEFAULT_DESIRED_CONN_TIMEOUT,
Peripheral_TaskID);
return (events ^ SBP_PARAM_UPDATE_EVT);
}
if(events & SBP_PHY_UPDATE_EVT)
{
// start phy update
PRINT("PHY Update %x...\n", GAPRole_UpdatePHY(peripheralConnList.connHandle, 0, GAP_PHY_BIT_LE_2M,
GAP_PHY_BIT_LE_2M, 0));
return (events ^ SBP_PHY_UPDATE_EVT);
}
if(events & SBP_READ_RSSI_EVT)
{
GAPRole_ReadRssiCmd(peripheralConnList.connHandle);
tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
return (events ^ SBP_READ_RSSI_EVT);
}
// Discard unknown events
return 0;
}
/*********************************************************************
* @fn Peripheral_ProcessGAPMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void Peripheral_ProcessGAPMsg(gapRoleEvent_t *pEvent)
{
switch(pEvent->gap.opcode)
{
case GAP_SCAN_REQUEST_EVENT:
{
// PRINT("Receive scan req from %x %x %x %x %x %x ..\n", pEvent->scanReqEvt.scannerAddr[0],
// pEvent->scanReqEvt.scannerAddr[1], pEvent->scanReqEvt.scannerAddr[2], pEvent->scanReqEvt.scannerAddr[3],
// pEvent->scanReqEvt.scannerAddr[4], pEvent->scanReqEvt.scannerAddr[5]);
break;
}
case GAP_PHY_UPDATE_EVENT:
{
PRINT("Phy update Rx:%x Tx:%x ..\n", pEvent->linkPhyUpdate.connRxPHYS, pEvent->linkPhyUpdate.connTxPHYS);
break;
}
default:
break;
}
}
/*********************************************************************
* @fn Peripheral_ProcessTMOSMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
{
switch(pMsg->event)
{
case GAP_MSG_EVENT:
{
Peripheral_ProcessGAPMsg((gapRoleEvent_t *)pMsg);
break;
}
case GATT_MSG_EVENT:
{
gattMsgEvent_t *pMsgEvent;
pMsgEvent = (gattMsgEvent_t *)pMsg;
if(pMsgEvent->method == ATT_MTU_UPDATED_EVENT)
{
peripheralMTU = pMsgEvent->msg.exchangeMTUReq.clientRxMTU;
PRINT("mtu exchange: %d\n", pMsgEvent->msg.exchangeMTUReq.clientRxMTU);
}
break;
}
default:
break;
}
}
/*********************************************************************
* @fn Peripheral_LinkEstablished
*
* @brief Process link established.
*
* @param pEvent - event to process
*
* @return none
*/
static void Peripheral_LinkEstablished(gapRoleEvent_t *pEvent)
{
gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
// See if already connected
if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT)
{
GAPRole_TerminateLink(pEvent->linkCmpl.connectionHandle);
PRINT("Connection max...\n");
}
else
{
peripheralConnList.connHandle = event->connectionHandle;
peripheralConnList.connInterval = event->connInterval;
peripheralConnList.connSlaveLatency = event->connLatency;
peripheralConnList.connTimeout = event->connTimeout;
// Set timer for periodic event
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
// Set timer for param update event
tmos_start_task(Peripheral_TaskID, SBP_PARAM_UPDATE_EVT, SBP_PARAM_UPDATE_DELAY);
// Start read rssi
tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
PRINT("Conn %x - Int %x \n", event->connectionHandle, event->connInterval);
char _tmp[32] = "";
sprintf(_tmp, "Conn %x - Int %x \n", event->connectionHandle, event->connInterval);
}
}
/*********************************************************************
* @fn Peripheral_LinkTerminated
*
* @brief Process link terminated.
*
* @param pEvent - event to process
*
* @return none
*/
static void Peripheral_LinkTerminated(gapRoleEvent_t *pEvent)
{
gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pEvent;
if(event->connectionHandle == peripheralConnList.connHandle)
{
peripheralConnList.connHandle = GAP_CONNHANDLE_INIT;
peripheralConnList.connInterval = 0;
peripheralConnList.connSlaveLatency = 0;
peripheralConnList.connTimeout = 0;
tmos_stop_task(Peripheral_TaskID, SBP_PERIODIC_EVT);
tmos_stop_task(Peripheral_TaskID, SBP_READ_RSSI_EVT);
// Restart advertising
{
uint8_t advertising_enable = TRUE;
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
}
}
else
{
PRINT("ERR..\n");
}
}
/*********************************************************************
* @fn peripheralRssiCB
*
* @brief RSSI callback.
*
* @param connHandle - connection handle
* @param rssi - RSSI
*
* @return none
*/
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi)
{
// PRINT("RSSI -%d dB Conn %x \n", -rssi, connHandle);
}
/*********************************************************************
* @fn peripheralParamUpdateCB
*
* @brief Parameter update complete callback
*
* @param connHandle - connect handle
* connInterval - connect interval
* connSlaveLatency - connect slave latency
* connTimeout - connect timeout
*
* @return none
*/
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
uint16_t connSlaveLatency, uint16_t connTimeout)
{
if(connHandle == peripheralConnList.connHandle)
{
peripheralConnList.connInterval = connInterval;
peripheralConnList.connSlaveLatency = connSlaveLatency;
peripheralConnList.connTimeout = connTimeout;
PRINT("Update %x - Int %x \n", connHandle, connInterval);
}
else
{
PRINT("ERR..\n");
}
}
/*********************************************************************
* @fn peripheralStateNotificationCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
{
switch(newState & GAPROLE_STATE_ADV_MASK)
{
case GAPROLE_STARTED:
PRINT("Initialized..\n");
break;
case GAPROLE_ADVERTISING:
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
{
Peripheral_LinkTerminated(pEvent);
PRINT("Disconnected.. Reason1:%x\n", pEvent->linkTerminate.reason);
PRINT("Advertising..\n");
char _tmp[32] = "";
sprintf(_tmp, "Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
g_flag_bt_state = 0;
}
else if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
{
PRINT("Advertising..\n");
}
break;
case GAPROLE_CONNECTED:
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
{
Peripheral_LinkEstablished(pEvent);
PRINT("Connected..\n");
g_flag_bt_state = 1;
}
break;
case GAPROLE_CONNECTED_ADV:
if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
{
PRINT("Connected Advertising..\n");
}
break;
case GAPROLE_WAITING:
if(pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT)
{
PRINT("Waiting for advertising..\n");
}
else if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
{
Peripheral_LinkTerminated(pEvent);
g_flag_bt_state = 0;
PRINT("Disconnected.. Reason2:%x\n", pEvent->linkTerminate.reason);
NVIC_SystemReset();
}
else if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
{
if(pEvent->gap.hdr.status != SUCCESS)
{
PRINT("Waiting for advertising..\n");
}
else
{
PRINT("Error..\n");
}
}
else
{
PRINT("Error..%x\n", pEvent->gap.opcode);
}
break;
case GAPROLE_ERROR:
g_flag_bt_state = 0;
PRINT("Error..\n");
break;
default:
break;
}
}
/*********************************************************************
* @fn performPeriodicTask
*
* @brief Perform a periodic application task. This function gets
* called every five seconds as a result of the SBP_PERIODIC_EVT
* TMOS event. In this example, the value of the third
* characteristic in the SimpleGATTProfile service is retrieved
* from the profile, and then copied into the value of the
* the fourth characteristic.
*
* @param none
*
* @return none
*/
static void performPeriodicTask(void)
{
// uint8_t notiData[SIMPLEPROFILE_CHAR4_LEN] = {0x88};
// peripheralChar4Notify(notiData, SIMPLEPROFILE_CHAR4_LEN);
if(g_flag_notify_temp){
g_flag_notify_temp = 0;
peripheralChar4Notify(g_notify_buftemp.buf, g_notify_buftemp.len);
clear_ble_notify_buf(&g_notify_buftemp);
}
}
/*********************************************************************
* @fn peripheralChar4Notify
*
* @brief Prepare and send simpleProfileChar4 notification
*
* @param pValue - data to notify
* len - length of data
*
* @return none
*/
static void peripheralChar4Notify(uint8_t *pValue, uint16_t len)
{
attHandleValueNoti_t noti;
if(len > (peripheralMTU - 3))
{
PRINT("Too large noti\n");
return;
}
noti.len = len;
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
if(noti.pValue)
{
tmos_memcpy(noti.pValue, pValue, noti.len);
if(simpleProfile_Notify(peripheralConnList.connHandle, &noti) != SUCCESS)
{
GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
}
}
}
void Jump_OTA(void);
/*********************************************************************
* @fn simpleProfileChangeCB
*
* @brief Callback from SimpleBLEProfile indicating a value change
*
* @param paramID - parameter ID of the value that was changed.
* pValue - pointer to data that was changed
* len - length of data
*
* @return none
*/
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
{
switch(paramID)
{
case SIMPLEPROFILE_CHAR1:
{
// uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
// tmos_memcpy(newValue, pValue, len);
// PRINT("profile ChangeCB CHAR1.. \n");
g_ble_rcv_buf.len = len;
tmos_memcpy(g_ble_rcv_buf.buf, pValue, len);
g_ble_rcv_buf.flag = 1;
break;
}
case SIMPLEPROFILE_CHAR3:
{
uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
tmos_memcpy(newValue, pValue, len);
if(newValue[0] == 0x3F && newValue[1] == 0xF3 && newValue[2] == 0x23 &&
newValue[3] == 'O' && newValue[4] == 'T' && newValue[5] == 'A'){
PRINT("profile ChangeCB CHAR3..\n");
PRINT("jump OTA \n");
Delay_Ms(5);
Jump_OTA();
}
break;
}
default:
// should not reach here!
break;
}
}
/* OTA upgrade logo */
#define IMAGE_OTA_FLAG 0x03
/* Store on the DataFlash address, the position of Bluetooth cannot be occupied */
#define OTA_DATAFLASH_ADD 0x08077000
/* Flash data temporary storage */
__attribute__((aligned(8))) uint8_t block_buf[256];
/*********************************************************************
* @fn FLASH_read
*
* @brief ¶Á flash
*
* @return none
*/
void FLASH_read(uint32_t addr, uint8_t *pData, uint32_t len)
{
uint32_t i;
for(i=0;i<len;i++)
{
*pData++ = *(uint8_t*)addr++;
}
}
/*********************************************************************
* @fn Jump_OTA
*
* @brief Jump to OTA upgrade
*
* @return none
*/
void Jump_OTA(void)
{
uint16_t i;
uint32_t ver_flag;
/* Read the first block */
FLASH_read(OTA_DATAFLASH_ADD, (uint8_t *)&block_buf[0], 4);
FLASH_Unlock_Fast();
/* Erase the first block */
FLASH_ErasePage_Fast( OTA_DATAFLASH_ADD );
/* Update Image information */
block_buf[0] = IMAGE_OTA_FLAG;
block_buf[1] = 0x5A;
block_buf[2] = 0x5A;
block_buf[3] = 0x5A;
/* Programming DataFlash */
FLASH_ProgramPage_Fast(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0]);
FLASH_Lock_Fast();
/* Software reset */
NVIC_SystemReset();
}
/*********************************************************************
*********************************************************************/

View File

@@ -0,0 +1,360 @@
/********************************** (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"
/*********************************************************************
* 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();
poll_dbn_ble();
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
PRINT("%s\n", VER_LIB);
PRINT("SystemCoreClock:%d\n", SystemCoreClock);
GetMacAddr(gMacAddr);
storage_init();
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;
}
}
}
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 ******************************/

View File

@@ -0,0 +1,211 @@
/*******************************************************
* File name: simple_json.c
* Author : wfq
* Versions : 1.0
* Description: simple json parse function.
* Do not solve the completed json_string or string with json-string.
* Completed: like array.
* Must satisfy the yipai dev-protocol, and test by yipai dev-protocol.
* History:
* 1.Date: 2016-10-10
* Author: wfq
* Action: create
*********************************************************/
#include "simple_json.h"
#include <string.h>
#include <stdio.h>
void simple_parse_json(const char * data, char *key_str, char *value_str)
{
char *p, *q, *t, *y;
//char * zq; //[ ]
int len = 0;
if(data == NULL)
{
printf("\r\nsimple_parse_json data is NULL\r\n");
return;
}
if(strlen(value_str) != 0)
{
printf("clear value:%s\n", value_str);
memset(value_str, 0, strlen(value_str));
}
p = strstr(data, key_str);
if(p == NULL) return;
p += strlen(key_str) + 1;
// printf("\nmy_parse_json2, first,data:%s\n", p);
while(*p == ' ')
{
p++;
}
// printf("\nmy_parse_json2, sec,data:%s\n", p);
q = strchr(p, '{');
t = strchr(p, '\"');
y = strchr(p, ',');
//zq = strchr(p, '[');
if((q == NULL) && (t == NULL) && (y == NULL))
{
q = strstr(p, "\r\n");
if(q == NULL) q = strstr(p, "\n");
if(q == NULL) q = strstr(p, "}");
if(q == NULL) len = strlen(p);
else len = strlen(p) - strlen(q);
memcpy(value_str, p, len);
return;
}
if((q == NULL) || ((t != NULL) && (strlen(t) > strlen(q))))
{
if((y != NULL) && (strlen(y) > strlen(t)))
{
len = strlen(p) - strlen(y);
memcpy(value_str, p, len);
return;
}
else
{
t += 1;
q = strstr(t, "\",");
if(q == NULL)
{
q = strstr(t, "\"\r\n");
if(q == NULL)
{
q = strstr(t, "\"\n");
if(q == NULL)
{
q = strstr(t, "\"");
}
}
}
len = strlen(t) - strlen(q);
memcpy(value_str, t, len);
}
}
else
{
q += 1;
y = strstr(q, "},");
if(y == NULL)
{
y = strstr(q, "}\r\n");
if(y == NULL) strstr(q, "}\n");
}
len = strlen(q) - strlen(y);
memcpy(value_str, q, len);
return;
}
}
char * simpleJsonGetObject(const char * data, const char * key)
{
if(data == NULL)
{
return NULL;
}
return NULL;
}
void simple_json_getarray_item(const char * data, char *key_str, char *value_str)
{
char *p, *q, *t, *y;
//char * zq; //[ ]
int len = 0;
if(data == NULL)
{
printf("\r\nsimple_parse_json data is NULL\r\n");
return;
}
if(strlen(value_str) != 0)
{
printf("clear value:%s\n", value_str);
memset(value_str, 0, strlen(value_str));
}
p = strstr(data, key_str);
if(p == NULL) return;
p += strlen(key_str) + 1;
// printf("\nmy_parse_json2, first,data:%s\n", p);
while(*p == ' ')
{
p++;
}
// printf("\nmy_parse_json2, sec,data:%s\n", p);
q = strchr(p, '{');
t = strchr(p, '\"');
y = strchr(p, ',');
//zq = strchr(p, '[');
if((q == NULL) && (t == NULL) && (y == NULL))
{
q = strstr(p, "\r\n");
if(q == NULL) q = strstr(p, "\n");
if(q == NULL) q = strstr(p, "}");
if(q == NULL) len = strlen(p);
else len = strlen(p) - strlen(q);
memcpy(value_str, p, len);
return;
}
if((q == NULL) || ((t != NULL) && (strlen(t) > strlen(q))))
{
if((y != NULL) && (strlen(y) > strlen(t)))
{
len = strlen(p) - strlen(y);
memcpy(value_str, p, len);
return;
}
else
{
t += 1;
q = strstr(t, "\",");
if(q == NULL)
{
q = strstr(t, "\"\r\n");
if(q == NULL)
{
q = strstr(t, "\"\n");
if(q == NULL)
{
q = strstr(t, "\"");
}
}
}
len = strlen(t) - strlen(q);
memcpy(value_str, t, len);
}
}
else
{
q += 1;
y = strstr(q, "},");
if(y == NULL)
{
y = strstr(q, "}\r\n");
if(y == NULL) strstr(q, "}\n");
}
len = strlen(q) - strlen(y);
memcpy(value_str, q, len);
return;
}
}

View File

@@ -0,0 +1,499 @@
/*
*@Note
*SPI interface operation flash peripheral routine:
*Master:SPI1_SCK(PA5)¡¢SPI1_MISO(PA6)¡¢SPI1_MOSI(PA7).
*This example demonstrates SPI operation Winbond W25Qxx SPIFLASH.
*
*pins:
* CS -- PA4
* DO -- PA6(SPI1_MISO)
* WP -- 3.3V
* DI -- PA7(SPI1_MOSI)
* CLK -- PA5(SPI1_SCK)
* HOLD -- 3.3V
*
*/
#include "debug.h"
#include "string.h"
/* Winbond SPIFalsh ID */
#define W25Q80 0XEF13
#define W25Q16 0XEF14
#define W25Q32 0XEF15
#define W25Q64 0XEF16 //64Mbit, 8MByte
#define W25Q128 0XEF17
/* Winbond SPIFalsh Instruction List */
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
/* Global define */
/* Global Variable */
u8 SPI_FLASH_BUF[4096];
const u8 TEXT_Buf[] = {"CH32V203 SPI FLASH W25Qxx"};
#define SIZE sizeof(TEXT_Buf)
/*********************************************************************
* @fn SPI1_ReadWriteByte
*
* @brief SPI1 read or write one byte.
*
* @param TxData - write one byte data.
*
* @return Read one byte data.
*/
u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 i = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, TxData);
i = 0;
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
/*********************************************************************
* @fn SPI_Flash_Init
*
* @brief Configuring the SPI for operation flash.
*
* @return none
*/
void SPI_Flash_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
SPI_InitTypeDef SPI_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
/*********************************************************************
* @fn SPI_Flash_ReadSR
*
* @brief Read W25Qxx status register.
* £¡£¡BIT7 6 5 4 3 2 1 0
* £¡£¡SPR RV TB BP2 BP1 BP0 WEL BUSY
*
* @return byte - status register value.
*/
u8 SPI_Flash_ReadSR(void)
{
u8 byte = 0;
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_ReadStatusReg);
byte = SPI1_ReadWriteByte(0Xff);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
return byte;
}
/*********************************************************************
* @fn SPI_FLASH_Write_SR
*
* @brief Write W25Qxx status register.
*
* @param sr - status register value.
*
* @return none
*/
void SPI_FLASH_Write_SR(u8 sr)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_WriteStatusReg);
SPI1_ReadWriteByte(sr);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
}
/*********************************************************************
* @fn SPI_Flash_Wait_Busy
*
* @brief Wait flash free.
*
* @return none
*/
void SPI_Flash_Wait_Busy(void)
{
while((SPI_Flash_ReadSR() & 0x01) == 0x01);
}
/*********************************************************************
* @fn SPI_FLASH_Write_Enable
*
* @brief Enable flash write.
*
* @return none
*/
void SPI_FLASH_Write_Enable(void)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_WriteEnable);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
}
/*********************************************************************
* @fn SPI_FLASH_Write_Disable
*
* @brief Disable flash write.
*
* @return none
*/
void SPI_FLASH_Write_Disable(void)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_WriteDisable);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
}
/*********************************************************************
* @fn SPI_Flash_ReadID
*
* @brief Read flash ID.
*
* @return Temp - FLASH ID.
*/
u16 SPI_Flash_ReadID(void)
{
u16 Temp = 0;
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_ManufactDeviceID);
SPI1_ReadWriteByte(0x00);
SPI1_ReadWriteByte(0x00);
SPI1_ReadWriteByte(0x00);
Temp |= SPI1_ReadWriteByte(0xFF) << 8;
Temp |= SPI1_ReadWriteByte(0xFF);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
return Temp;
}
/*********************************************************************
* @fn SPI_Flash_Erase_Sector
*
* @brief Erase one sector(4Kbyte).
*
* @param Dst_Addr - 0 £¡£¡ 2047
*
* @return none
*/
void SPI_Flash_Erase_Sector(u32 Dst_Addr)
{
Dst_Addr *= 4096;
SPI_FLASH_Write_Enable();
SPI_Flash_Wait_Busy();
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_SectorErase);
SPI1_ReadWriteByte((u8)((Dst_Addr) >> 16));
SPI1_ReadWriteByte((u8)((Dst_Addr) >> 8));
SPI1_ReadWriteByte((u8)Dst_Addr);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
SPI_Flash_Wait_Busy();
}
/*********************************************************************
* @fn SPI_Flash_Read
*
* @brief Read data from flash.
*
* @param pBuffer -
* ReadAddr -Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Read(u8 *pBuffer, u32 ReadAddr, u16 size)
{
u16 i;
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_ReadData);
SPI1_ReadWriteByte((u8)((ReadAddr) >> 16));
SPI1_ReadWriteByte((u8)((ReadAddr) >> 8));
SPI1_ReadWriteByte((u8)ReadAddr);
for(i = 0; i < size; i++){
pBuffer[i] = SPI1_ReadWriteByte(0XFF);
}
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
}
/*********************************************************************
* @fn SPI_Flash_Write_Page
*
* @brief Write data by one page.
*
* @param pBuffer -
* WriteAddr - Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Write_Page(u8 *pBuffer, u32 WriteAddr, u16 size)
{
u16 i;
SPI_FLASH_Write_Enable();
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_PageProgram);
SPI1_ReadWriteByte((u8)((WriteAddr) >> 16));
SPI1_ReadWriteByte((u8)((WriteAddr) >> 8));
SPI1_ReadWriteByte((u8)WriteAddr);
for(i = 0; i < size; i++){
SPI1_ReadWriteByte(pBuffer[i]);
}
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
SPI_Flash_Wait_Busy();
}
/*********************************************************************
* @fn SPI_Flash_Write_NoCheck
*
* @brief Write data to flash.(need Erase)
* All data in address rang is 0xFF.
*
* @param pBuffer -
* WriteAddr - Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Write_NoCheck(u8 *pBuffer, u32 WriteAddr, u16 size)
{
u16 pageremain;
pageremain = 256 - WriteAddr % 256;
if(size <= pageremain)
pageremain = size;
while(1)
{
SPI_Flash_Write_Page(pBuffer, WriteAddr, pageremain);
if(size == pageremain)
{
break;
}
else
{
pBuffer += pageremain;
WriteAddr += pageremain;
size -= pageremain;
if(size > 256)
pageremain = 256;
else
pageremain = size;
}
}
}
/*********************************************************************
* @fn SPI_Flash_Write
*
* @brief Write data to flash.(no need Erase)
*
* @param pBuffer -
* WriteAddr - Initial address(24bit).
* size - Data length.
*
* @return none
*/
void SPI_Flash_Write(u8 *pBuffer, u32 WriteAddr, u16 size)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
secpos = WriteAddr / 4096;
secoff = WriteAddr % 4096;
secremain = 4096 - secoff;
if(size <= secremain)
secremain = size;
while(1)
{
SPI_Flash_Read(SPI_FLASH_BUF, secpos * 4096, 4096);
for(i = 0; i < secremain; i++){
if(SPI_FLASH_BUF[secoff + i] != 0XFF)
break;
}
if(i < secremain)
{
SPI_Flash_Erase_Sector(secpos);
for(i = 0; i < secremain; i++)
{
SPI_FLASH_BUF[i + secoff] = pBuffer[i];
}
SPI_Flash_Write_NoCheck(SPI_FLASH_BUF, secpos * 4096, 4096);
}
else
{
SPI_Flash_Write_NoCheck(pBuffer, WriteAddr, secremain);
}
if(size == secremain)
{
break;
}
else
{
secpos++;
secoff = 0;
pBuffer += secremain;
WriteAddr += secremain;
size -= secremain;
if(size > 4096)
{
secremain = 4096;
}
else
{
secremain = size;
}
}
}
}
/*********************************************************************
* @fn SPI_Flash_Erase_Chip
*
* @brief Erase all FLASH pages.
*
* @return none
*/
void SPI_Flash_Erase_Chip(void)
{
SPI_FLASH_Write_Enable();
SPI_Flash_Wait_Busy();
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_ChipErase);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
SPI_Flash_Wait_Busy();
}
/*********************************************************************
* @fn SPI_Flash_PowerDown
*
* @brief Enter power down mode.
*
* @return none
*/
void SPI_Flash_PowerDown(void)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_PowerDown);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
Delay_Us(3);
}
/*********************************************************************
* @fn SPI_Flash_WAKEUP
*
* @brief Power down wake up.
*
* @return none
*/
void SPI_Flash_WAKEUP(void)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);
SPI1_ReadWriteByte(W25X_ReleasePowerDown);
GPIO_WriteBit(GPIOA, GPIO_Pin_4, 1);
Delay_Us(3);
}
void storage_init(void)
{
SPI_Flash_Init();
uint16_t Flash_Model = SPI_Flash_ReadID();
switch(Flash_Model)
{
case W25Q80: PRINT("W25Q80 OK!\r\n"); break;
case W25Q16: PRINT("W25Q16 OK!\r\n"); break;
case W25Q32: PRINT("W25Q32 OK!\r\n"); break;
case W25Q64: PRINT("W25Q64 OK!\r\n"); break;
case W25Q128: PRINT("W25Q128 OK!\r\n"); break;
default: PRINT("Fail!\r\n"); break;
}
// TODO: if read Flash_Model failed, must stop running.
}

View File

@@ -0,0 +1,990 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : system_ch32v20x.c
* Author : WCH
* Version : V1.0.0
* Date : 2021/06/06
* Description : CH32V20x Device Peripheral Access Layer System Source File.
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
* For HSE = 8Mhz (other CH32V203x)
*********************************************************************************
* 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.
*******************************************************************************/
#include "ch32v20x.h"
/*
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
* reset the HSI is used as SYSCLK source).
* If none of the define below is enabled, the HSI is used as System clock source.
*/
//#define SYSCLK_FREQ_HSE HSE_VALUE
//#define SYSCLK_FREQ_48MHz_HSE 48000000
//#define SYSCLK_FREQ_56MHz_HSE 56000000
//#define SYSCLK_FREQ_72MHz_HSE 72000000
// #define SYSCLK_FREQ_96MHz_HSE 96000000
#define SYSCLK_FREQ_120MHz_HSE 120000000
// #define SYSCLK_FREQ_144MHz_HSE 144000000
//#define SYSCLK_FREQ_HSI HSI_VALUE
//#define SYSCLK_FREQ_48MHz_HSI 48000000
//#define SYSCLK_FREQ_56MHz_HSI 56000000
//#define SYSCLK_FREQ_72MHz_HSI 72000000
//#define SYSCLK_FREQ_96MHz_HSI 96000000
//#define SYSCLK_FREQ_120MHz_HSI 120000000
//#define SYSCLK_FREQ_144MHz_HSI 144000000
/* Clock Definitions */
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_96MHz_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_120MHz_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_144MHz_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_96MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_120MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_144MHz_HSI
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
#else
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
#endif
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
/* system_private_function_proto_types */
static void SetSysClock(void);
#ifdef SYSCLK_FREQ_HSE
static void SetSysClockToHSE( void );
#elif defined SYSCLK_FREQ_48MHz_HSE
static void SetSysClockTo48_HSE( void );
#elif defined SYSCLK_FREQ_56MHz_HSE
static void SetSysClockTo56_HSE( void );
#elif defined SYSCLK_FREQ_72MHz_HSE
static void SetSysClockTo72_HSE( void );
#elif defined SYSCLK_FREQ_96MHz_HSE
static void SetSysClockTo96_HSE( void );
#elif defined SYSCLK_FREQ_120MHz_HSE
static void SetSysClockTo120_HSE( void );
#elif defined SYSCLK_FREQ_144MHz_HSE
static void SetSysClockTo144_HSE( void );
#elif defined SYSCLK_FREQ_48MHz_HSI
static void SetSysClockTo48_HSI( void );
#elif defined SYSCLK_FREQ_56MHz_HSI
static void SetSysClockTo56_HSI( void );
#elif defined SYSCLK_FREQ_72MHz_HSI
static void SetSysClockTo72_HSI( void );
#elif defined SYSCLK_FREQ_96MHz_HSI
static void SetSysClockTo96_HSI( void );
#elif defined SYSCLK_FREQ_120MHz_HSI
static void SetSysClockTo120_HSI( void );
#elif defined SYSCLK_FREQ_144MHz_HSI
static void SetSysClockTo144_HSI( void );
#endif
/*********************************************************************
* @fn SystemInit
*
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
* the PLL and update the SystemCoreClock variable.
*
* @return none
*/
void SystemInit (void)
{
RCC->CTLR |= (uint32_t)0x00000001;
RCC->CFGR0 &= (uint32_t)0xF0FF0000;
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
RCC->CFGR0 &= (uint32_t)0xFF00FFFF;
RCC->INTR = 0x009F0000;
SetSysClock();
}
/*********************************************************************
* @fn SystemCoreClockUpdate
*
* @brief Update SystemCoreClock variable according to Clock Register Values.
*
* @return none
*/
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
tmp = RCC->CFGR0 & RCC_SWS;
switch (tmp)
{
case 0x00:
SystemCoreClock = HSI_VALUE;
break;
case 0x04:
SystemCoreClock = HSE_VALUE;
break;
case 0x08:
pllmull = RCC->CFGR0 & RCC_PLLMULL;
pllsource = RCC->CFGR0 & RCC_PLLSRC;
pllmull = ( pllmull >> 18) + 2;
if(pllmull == 17) pllmull = 18;
if (pllsource == 0x00)
{
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
SystemCoreClock = HSI_VALUE * pllmull;
}
else{
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
}
}
else
{
#if defined (CH32V20x_D8W) || defined (CH32V20x_D8)
if(((RCC->CFGR0 & (3<<22)) == (3<<22)) && (RCC_USB5PRE_JUDGE()== SET))
{
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
}
else
#endif
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
{
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
#else
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
#endif
}
else
{
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
#else
SystemCoreClock = HSE_VALUE * pllmull;
#endif
}
}
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
SystemCoreClock >>= tmp;
}
/*********************************************************************
* @fn SetSysClock
*
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClock(void)
{
//GPIO_IPD_Unused();
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_48MHz_HSE
SetSysClockTo48_HSE();
#elif defined SYSCLK_FREQ_56MHz_HSE
SetSysClockTo56_HSE();
#elif defined SYSCLK_FREQ_72MHz_HSE
SetSysClockTo72_HSE();
#elif defined SYSCLK_FREQ_96MHz_HSE
SetSysClockTo96_HSE();
#elif defined SYSCLK_FREQ_120MHz_HSE
SetSysClockTo120_HSE();
#elif defined SYSCLK_FREQ_144MHz_HSE
SetSysClockTo144_HSE();
#elif defined SYSCLK_FREQ_48MHz_HSI
SetSysClockTo48_HSI();
#elif defined SYSCLK_FREQ_56MHz_HSI
SetSysClockTo56_HSI();
#elif defined SYSCLK_FREQ_72MHz_HSI
SetSysClockTo72_HSI();
#elif defined SYSCLK_FREQ_96MHz_HSI
SetSysClockTo96_HSI();
#elif defined SYSCLK_FREQ_120MHz_HSI
SetSysClockTo120_HSI();
#elif defined SYSCLK_FREQ_144MHz_HSI
SetSysClockTo144_HSI();
#endif
/* If none of the define above is enabled, the HSI is used as System clock
* source (default after reset)
*/
}
#ifdef SYSCLK_FREQ_HSE
/*********************************************************************
* @fn SetSysClockToHSE
*
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockToHSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
/* Select HSE as system clock source
* CH32V20x_D6 (HSE=8MHZ)
* CH32V20x_D8 (HSE=32MHZ)
* CH32V20x_D8W (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
/* Wait till HSE is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
{
}
}
else
{
/* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_48MHz_HSE
/*********************************************************************
* @fn SetSysClockTo48_HSE
*
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo48_HSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
else
{
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_56MHz_HSE
/*********************************************************************
* @fn SetSysClockTo56_HSE
*
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo56_HSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
else
{
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_72MHz_HSE
/*********************************************************************
* @fn SetSysClockTo72_HSE
*
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo72_HSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
else
{
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_96MHz_HSE
/*********************************************************************
* @fn SetSysClockTo96_HSE
*
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo96_HSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
else
{
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_120MHz_HSE
/*********************************************************************
* @fn SetSysClockTo120_HSE
*
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo120_HSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if(HSEStatus == (uint32_t)0x01)
{
#if defined (CH32V20x_D8W)
RCC->CFGR0 |= (uint32_t)(3<<22);
/* HCLK = SYSCLK/2 */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
#else
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
#endif
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
else
{
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_144MHz_HSE
/*********************************************************************
* @fn SetSysClockTo144_HSE
*
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo144_HSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC->CTLR |= ((uint32_t)RCC_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CTLR & RCC_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CTLR & RCC_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
*/
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
else
{
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
#elif defined SYSCLK_FREQ_48MHz_HSI
/*********************************************************************
* @fn SetSysClockTo48_HSI
*
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo48_HSI(void)
{
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
#elif defined SYSCLK_FREQ_56MHz_HSI
/*********************************************************************
* @fn SetSysClockTo56_HSI
*
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo56_HSI(void)
{
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
#elif defined SYSCLK_FREQ_72MHz_HSI
/*********************************************************************
* @fn SetSysClockTo72_HSI
*
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo72_HSI(void)
{
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
#elif defined SYSCLK_FREQ_96MHz_HSI
/*********************************************************************
* @fn SetSysClockTo96_HSI
*
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo96_HSI(void)
{
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
#elif defined SYSCLK_FREQ_120MHz_HSI
/*********************************************************************
* @fn SetSysClockTo120_HSI
*
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo120_HSI(void)
{
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
#elif defined SYSCLK_FREQ_144MHz_HSI
/*********************************************************************
* @fn SetSysClockTo144_HSI
*
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
*
* @return none
*/
static void SetSysClockTo144_HSI(void)
{
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
/* HCLK = SYSCLK */
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
/* Enable PLL */
RCC->CTLR |= RCC_PLLON;
/* Wait till PLL is ready */
while((RCC->CTLR & RCC_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
{
}
}
#endif

View File

@@ -0,0 +1,186 @@
/*
* usart_biz.c
*
* Created on: 2026-02-26
* Author: wangfq
*/
#include "config.h"
#include "cmcng.h"
#include <string.h>
#include "dbn_ble_srv.h"
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void uart_init(void){
GPIO_InitTypeDef GPIO_InitStructure = {0};
USART_InitTypeDef USART_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
// usart1 : peripheral / DEBUG
//usart2 :loop mcu
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Tx
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // Rx
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 192000;//115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
// USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // 配合DMA但测试不能接收原因未知。
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//GPIO_Mode_IPU; // Key
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*********************************************************************
* @fn USART1_IRQHandler
*
* @brief This function handles USART1 global interrupt request.
*
* @return none
*/
void USART1_IRQHandler(void)
{
}
/*********************************************************************
* @fn USART2_IRQHandler
*
* @brief This function handles USART2 global interrupt request.
*
* @return none
*/
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
uint8_t _dat = USART_ReceiveData(USART2);
if(g_pkg_uart_2.offset == 0){
if(_dat != 0){
g_pkg_uart_2.pkg[g_pkg_uart_2.offset++] = _dat;
}
}
else{
if(g_pkg_uart_2.offset < BUFF_STACK_SIZE){
g_pkg_uart_2.pkg[g_pkg_uart_2.offset++] = _dat;
}
else{
g_pkg_uart_2.flag = 1;
}
}
if(g_pkg_uart_2.offset){
g_pkg_uart_2.tick = 0;
}
}
}
void UART2_SendString(uint8_t *buf, uint16_t len)
{
uint16_t _len = len;
while(_len){
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
USART_SendData(USART2, *buf++);
_len--;
}
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
void UART1_SendString(uint8_t *buf, uint16_t len)
{
uint16_t _len = len;
while(_len){
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1, *buf++);
_len--;
}
}
void uart_srv(void)
{
uint8_t i;
uint8_t _report_flag = 0;
if(g_pkg_uart_2.flag){
if(g_flag_counter_ota.flag == 0){
if(g_pkg_uart_2.pkg[0] == 0x7F){
if(g_pkg_uart_2.pkg[3] == 0xC0 && g_pkg_uart_2.pkg[4] == 0x0C)
{
if(g_dbn_ble_state_acs_enable.flag == 0){
_report_flag = 1;
}
else{
g_pkg_uart_2.pkg[0] = 0x8F;
}
}
for(i = 0; i < g_pkg_uart_2.offset; i++){
PRINT(" %02X", g_pkg_uart_2.pkg[i]);
}
PRINT("\n");
if(_report_flag){
InitPkgUart(&g_pkg_uart_2);
}
}
else {
PRINT("Rcv_len:%d,dat: %s\n", g_pkg_uart_2.offset, g_pkg_uart_2.pkg);
}
}
else{
// PRINT("From_Loop: ");
// for(i = 0; i < g_pkg_uart_2.offset; i++){
// PRINT(" %02X", g_pkg_uart_2.pkg[i]);
// }
// PRINT("\n");
}
if(g_flag_bt_state){
g_flag_notify_temp = set_response_tran_to_notify(g_pkg_uart_2.pkg, g_pkg_uart_2.offset, &g_notify_buftemp);
}
else{
g_dbn_ble_state_acs_enable.flag = 0;
}
InitPkgUart(&g_pkg_uart_2);
}
}