init: DLD154Pro 单线圈蓝牙车检器,从 DLD110SV4 复制初始代码和文档
This commit is contained in:
@@ -0,0 +1,855 @@
|
||||
/*
|
||||
* dbn_ble_srv.c
|
||||
*
|
||||
* Created on: Aug 27, 2024
|
||||
* Author: Thinkpad
|
||||
*/
|
||||
|
||||
#include "dbn_ble_srv.h"
|
||||
#include "cmcng.h"
|
||||
#include "storage.h"
|
||||
#include "CH59x_common.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,""};
|
||||
|
||||
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(_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] = MACAddr[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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//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
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void unpack_pkg_set_cjq_param(uint8_t *pkg, uint8_t len)
|
||||
{
|
||||
uint8_t i = 4, k = 0;
|
||||
uint8_t tmp[7] = {0};
|
||||
k = pkg[i++];
|
||||
g_loop_cng_unit.sensitvity = k & 0x0F;
|
||||
g_loop_cng_unit.loopFreq_Level = k >> 4;
|
||||
g_loop_cng_unit.delay_time = pkg[i++];
|
||||
k = pkg[i++];
|
||||
g_loop_cng_unit.output_mode = k & 0x03;
|
||||
g_loop_cng_unit.loopSafe_Timeout = k >> 3;
|
||||
g_loop_cng_unit.exist_mode = pkg[i++];
|
||||
g_loop_cng_unit.direction_mode = pkg[i++];
|
||||
|
||||
g_function_mode = (g_loop_cng_unit.direction_mode >> 4) & 0x0F;
|
||||
|
||||
g_hold_time = g_loop_cng_unit.exist_mode * 30 * 20;
|
||||
|
||||
i = 0;
|
||||
tmp[i++] = g_loop_cng_unit.sensitvity;
|
||||
tmp[i++] = g_loop_cng_unit.delay_time;
|
||||
tmp[i++] = g_loop_cng_unit.output_mode;
|
||||
tmp[i++] = g_loop_cng_unit.direction_mode; //默认 0
|
||||
tmp[i++] = g_loop_cng_unit.loopFreq_Level;
|
||||
tmp[i++] = g_loop_cng_unit.loopSafe_Timeout;
|
||||
tmp[i++] = g_loop_cng_unit.exist_mode;
|
||||
|
||||
write_cfg_to_store(4, tmp, 7);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void usart_packet_processing_acs_loop(uint8_t flag)
|
||||
{
|
||||
static uint32_t _current_freq = 0;
|
||||
static uint32_t _last_freq = 0;
|
||||
|
||||
clear_ble_notify_buf(&g_tmp_report_buf);
|
||||
|
||||
uint8_t i = 0,j;
|
||||
uint32_t _loop_capvd = g_loop_acs_info.loop_capvd;
|
||||
g_tmp_report_buf.flag = flag;
|
||||
|
||||
|
||||
g_loop_acs_info.condition = (g_env_activity > 150) ? 15 : (g_env_activity / 10);
|
||||
if(loop1_FLAG_CUT){
|
||||
g_loop_acs_info.condition = 15;
|
||||
}
|
||||
g_tmp_report_buf.buf[i++] = SENS_LOOP_DYNAMIC;
|
||||
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_acs_info.loop_num << 6) | (g_freq_level << 4) | (g_loop_acs_info.condition & 0x0F);
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_acs_info.relay2_state << 6) | (g_loop_acs_info.relay2_cng << 4) | (g_loop_acs_info.relay1_state << 2) | (g_loop_acs_info.relay1_cng & 0x3);
|
||||
g_tmp_report_buf.buf[i++] = (loop1_FLAG_CUT << 7) | (g_loop_acs_info.car_state << 4) | (g_loop_acs_info.direction & 0x0F);
|
||||
|
||||
g_freq_tmp = (float)(g_sys_freq )/((float)(_loop_capvd)/((float)(loop1_LPCNT))); // ?? ???????
|
||||
|
||||
// why + 360? balance value ,补偿,经验值,可以根据示波器比较再进行调整
|
||||
_current_freq = (uint32_t)(g_freq_tmp) + 360 ;// * 32);
|
||||
// if(flag)
|
||||
{
|
||||
g_loop_acs_info.frequent = _current_freq;
|
||||
_last_freq = _current_freq;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// if(_current_freq > _last_freq)
|
||||
// {
|
||||
// if(_current_freq - _last_freq > 30)
|
||||
// {
|
||||
// //稳定显示,过滤低数值的变动
|
||||
// g_loop_acs_info.frequent = _current_freq;
|
||||
// _last_freq = _current_freq;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(_last_freq - _current_freq > 30)
|
||||
// {
|
||||
// // 稳定显示,过滤低数值的变动
|
||||
// g_loop_acs_info.frequent = _current_freq;
|
||||
// _last_freq = _current_freq;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// g_tmp_report_buf.buf[i++] = (uint8_t)flt_mgr.init_freq;
|
||||
// g_tmp_report_buf.buf[i++] = (flt_mgr.init_freq >> 8) % 0x100;
|
||||
// g_tmp_report_buf.buf[i++] = (flt_mgr.init_freq >> 16) % 0x100;
|
||||
|
||||
if(g_loop_acs_info.flag_change){
|
||||
g_loop_acs_info.flag_change = 0;
|
||||
}
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_power_up_state == 0) ? 1 : ((uint8_t)g_loop_cut_amount);
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_power_up_state == 0) ? 0 : ((g_loop_cut_amount >> 8) % 0x100);
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_power_up_state == 0) ? 0 : ((g_loop_cut_amount >> 16) % 0x100);
|
||||
|
||||
g_tmp_report_buf.buf[i++] = (uint8_t)g_loop_acs_info.frequent;
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_acs_info.frequent >> 8) % 0x100;
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_acs_info.frequent >> 16) % 0x100;
|
||||
|
||||
g_tmp_report_buf.buf[i++] = (uint8_t)g_loop_acs_info.variation;
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_acs_info.variation >> 8) % 0x100;
|
||||
g_tmp_report_buf.buf[i++] = (g_loop_acs_info.variation >> 16) % 0x100;
|
||||
|
||||
|
||||
g_tmp_report_buf.len = i;
|
||||
|
||||
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, CMD_SUB_SENS_REPORT, g_tmp_report_buf.buf, g_tmp_report_buf.len);
|
||||
}
|
||||
|
||||
|
||||
void report_sens_acs(void)
|
||||
{
|
||||
uint8_t _ret = 0;
|
||||
|
||||
if(g_dbn_ble_state_acs_enable.enable)
|
||||
{
|
||||
// 上报线圈动态数据
|
||||
|
||||
|
||||
// switch(g_dbn_ble_state_acs_enable.sens_type)
|
||||
// {
|
||||
// //case SENS_LOOP_DYNAMIC:
|
||||
// default:
|
||||
// {
|
||||
// 线圈动态信息
|
||||
if(g_loop_acs_info.flag_event)
|
||||
{
|
||||
// if(g_loop_acs_info.report_counter >= 3)
|
||||
{
|
||||
// refresh_loop_acs_info();
|
||||
g_loop_acs_info.flag_event = 0;
|
||||
g_loop_acs_info.report_counter = 0;
|
||||
|
||||
// report
|
||||
usart_packet_processing_acs_loop(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(g_loop_acs_info.report_counter >= 120)
|
||||
{
|
||||
// refresh_loop_acs_info();
|
||||
g_loop_acs_info.report_counter = 0;
|
||||
|
||||
// report
|
||||
usart_packet_processing_acs_loop(0);
|
||||
// response_bt_dat(usart_packet_processing_acs_loop(0));
|
||||
}
|
||||
|
||||
if(g_dbn_ble_state_acs_enable.timeout_min)
|
||||
{
|
||||
if(mstick() - g_dbn_ble_state_acs_enable.counter >= g_dbn_ble_state_acs_enable.timeout_counter)
|
||||
{
|
||||
g_dbn_ble_state_acs_enable.flag = 0;
|
||||
g_dbn_ble_state_acs_enable.enable = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// } break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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_RESET_DEV:
|
||||
{
|
||||
//Restart Dev
|
||||
SYS_ResetExecute();
|
||||
} 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;
|
||||
tmp_ble_buf[i++] = (g_freq_sens + 1) | (g_loop_cng_unit.loopFreq_Level << 4);
|
||||
tmp_ble_buf[i++] = g_loop_cng_unit.delay_time;
|
||||
tmp_ble_buf[i++] = g_loop_cng_unit.output_mode | (g_loop_cng_unit.loopSafe_Timeout << 3);
|
||||
tmp_ble_buf[i++] = g_loop_cng_unit.exist_mode;
|
||||
tmp_ble_buf[i++] = g_loop_sens_list.total << 4;
|
||||
tmp_ble_buf[i++] = (g_loop_power_up_state == 0) ? 1 : ((uint8_t)(g_loop_cut_amount));
|
||||
tmp_ble_buf[i++] = (uint8_t)(g_loop_cut_amount >> 8);
|
||||
tmp_ble_buf[i++] = g_function_mode;
|
||||
|
||||
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_SAMPLE_PARAM:{
|
||||
// // 获取/设置 地感采样参数
|
||||
//// PRINT("SAMPLE_CNG: %02X\n", pkg[4]);
|
||||
// if(pkg[4] == 0){
|
||||
// // get param
|
||||
// i = 0;
|
||||
// tmp_ble_buf[i++] = 0x10;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.sample_cng.flag;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.sample_cng.max_amplitude;
|
||||
// tmp_ble_buf[i++] = (g_loop_balance_planB.sample_cng.max_amplitude >> 8) & 0xFF;
|
||||
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
// }
|
||||
// else {
|
||||
// // set param
|
||||
// i = 0;
|
||||
// k = 4;
|
||||
// tmp_ble_buf[i++] = 0x11;
|
||||
// tmp_ble_buf[i++] = pkg[k++];
|
||||
// tmp_ble_buf[i++] = pkg[k++];
|
||||
// tmp_ble_buf[i++] = pkg[k++];
|
||||
//
|
||||
// g_loop_balance_planB.sample_cng.flag = tmp_ble_buf[1];
|
||||
// g_loop_balance_planB.sample_cng.max_amplitude = tmp_ble_buf[2] | ((tmp_ble_buf[3] << 8 ) & 0xFF00);
|
||||
//
|
||||
// write_cfg_to_store(Addr_Loop_PlanB_Cng_Offset, &tmp_ble_buf[1], sizeof(Loop_Sample_Cng));
|
||||
//
|
||||
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
//
|
||||
// //TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
|
||||
// para_store_init();
|
||||
// }
|
||||
//
|
||||
// } break;
|
||||
// case CMD_DBN_LOOP_BALANCE_PARAM: {
|
||||
// // 获取/设置 漂移补偿参数
|
||||
//// PRINT("Balance_CNG: %02X\n", pkg[4]);
|
||||
// if(pkg[4] == 0){
|
||||
// // get param
|
||||
// i = 0;
|
||||
// tmp_ble_buf[i++] = 0x10;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.balance_ori_cng.flag;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.balance_ori_cng.max_cnt;
|
||||
// tmp_ble_buf[i++] = (g_loop_balance_planB.balance_ori_cng.max_cnt >> 8) & 0xFF;
|
||||
//
|
||||
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
// }
|
||||
// else{
|
||||
// // set param
|
||||
// i = 0;
|
||||
// k = 4;
|
||||
// tmp_ble_buf[i++] = 0x11;
|
||||
// tmp_ble_buf[i++] = pkg[k++];
|
||||
// tmp_ble_buf[i++] = pkg[k++];
|
||||
// tmp_ble_buf[i++] = pkg[k++];
|
||||
//
|
||||
// g_loop_balance_planB.balance_ori_cng.flag = tmp_ble_buf[1];
|
||||
// g_loop_balance_planB.balance_ori_cng.max_cnt = tmp_ble_buf[2] | ((tmp_ble_buf[3] << 8 ) & 0xFF00);
|
||||
//
|
||||
// write_cfg_to_store(Addr_Loop_PlanB_Cng_Offset + sizeof(Loop_Sample_Cng), &tmp_ble_buf[1], sizeof(Loop_Balance_Ori_Cng));
|
||||
//
|
||||
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
//
|
||||
// //TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
|
||||
// para_store_init();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// } break;
|
||||
// case CMD_DBN_LOOP_RELEASE_PLANB: {
|
||||
// // 获取/设置 释放去抖动算法参数
|
||||
//// PRINT("Release2_CNG: %02X\n", pkg[4]);
|
||||
// if(pkg[4] == 0){
|
||||
// // get param
|
||||
// i = 0;
|
||||
// tmp_ble_buf[i++] = 0x10;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_ori_planB.flag_weight;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_ori_planB.max_amplitude;
|
||||
// tmp_ble_buf[i++] = (g_loop_balance_planB.release_ori_planB.max_amplitude >> 8) & 0xFF;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_ori_planB.timeout;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.flag_weight;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.rate_first;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.rate_second;
|
||||
// tmp_ble_buf[i++] = g_loop_balance_planB.release_change_rate.mode;
|
||||
//
|
||||
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
// }
|
||||
// else{
|
||||
// // set param
|
||||
// i = 0; k = 0;
|
||||
// tmp_ble_buf[i++] = 0x11;
|
||||
// memcpy(&tmp_ble_buf[1], &pkg[4], 8);
|
||||
// i += 8;
|
||||
//
|
||||
// write_cfg_to_store(Addr_Loop_PlanB_Cng_Offset + sizeof(Loop_Sample_Cng) + sizeof(Loop_Balance_Ori_Cng), &tmp_ble_buf[1], 8);
|
||||
//
|
||||
// set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
//
|
||||
// //TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
|
||||
// para_store_init();
|
||||
// }
|
||||
// } break;
|
||||
case CMD_DBN_LOOP_SENS_LIST: {
|
||||
// PRINT("SENS_CNG: %02X\n", pkg[4]);
|
||||
memset(tmp_ble_buf, 0, MAX_BLE_TMP_BUF_LEN);
|
||||
if(pkg[4] == 0x00){
|
||||
// get param
|
||||
i = 0;
|
||||
tmp_ble_buf[i++] = 0x10;
|
||||
tmp_ble_buf[i++] = g_loop_sens_list.total;
|
||||
for(k = 0; k < g_loop_sens_list.total; k++){
|
||||
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_in;
|
||||
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_in >> 8;
|
||||
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_out;
|
||||
tmp_ble_buf[i++] = g_loop_sens_list.sens[k].sens_out >> 8;
|
||||
}
|
||||
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
}
|
||||
else {
|
||||
// set param
|
||||
i = 0; k = 5;
|
||||
|
||||
tmp_ble_buf[i++] = 0x11;
|
||||
g_loop_sens_list.total = pkg[k];
|
||||
if(g_loop_sens_list.total > MAX_LOOP_SENS_AMOUNT){
|
||||
g_loop_sens_list.total = MAX_LOOP_SENS_AMOUNT;
|
||||
}
|
||||
k = 1 + g_loop_sens_list.total * 4;
|
||||
memcpy(&tmp_ble_buf[i], &pkg[5], k);
|
||||
i += k;
|
||||
|
||||
write_cfg_to_store(Addr_Loop_Sens_List_Offset, &tmp_ble_buf[1], (i - 1));
|
||||
DelayMs(10);
|
||||
|
||||
set_response_buf(&g_buf_ble_response, MAGIC_BYTE_DBN_DEFAULT, _cmd, tmp_ble_buf, i);
|
||||
write_cfg_to_store(Addr_Loop_Sens_List_Offset, &tmp_ble_buf[1], (i - 1));
|
||||
DelayMs(10);
|
||||
|
||||
//TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
|
||||
para_store_init();
|
||||
}
|
||||
} break;
|
||||
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);
|
||||
|
||||
set_factory_param();
|
||||
factory_dev();
|
||||
DelayMs(10);
|
||||
//TODO: 不整个设备复位,复位除了蓝牙的部分,即蓝牙正常,其他部分重新初始化
|
||||
para_store_init();
|
||||
} break;
|
||||
case CMD_SENS_ACS_ENABLE: {
|
||||
// 线圈动态
|
||||
g_dbn_ble_state_acs_enable.enable = pkg[5];
|
||||
|
||||
if(g_dbn_ble_state_acs_enable.enable){
|
||||
g_loop_acs_info.condition = 0;
|
||||
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;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void poll_dbn_ble(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t magic = 0;
|
||||
if(g_ble_rcv_buf.flag)
|
||||
{
|
||||
// if(g_flag_debug)
|
||||
// {
|
||||
// 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");
|
||||
// }
|
||||
magic = check_pkg(g_ble_rcv_buf.buf, g_ble_rcv_buf.len);
|
||||
// printf("_magic: %02X\n", magic);
|
||||
if(magic != 0)
|
||||
{
|
||||
// if(magic == MAGIC_BYTE_DBN_DEFAULT)
|
||||
{
|
||||
manage_dbn_ble_default(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* cmcng.h
|
||||
*
|
||||
* Created on: Aug 27, 2024
|
||||
* Author: Thinkpad
|
||||
* 2026-07-18: 算法移� DLD154V4B, 移除 FltHistoryManager / SecondOrderState /
|
||||
* StageRangeConfig ç‰æ—§ç®—法结构
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_CMCNG_H_
|
||||
#define INCLUDE_CMCNG_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PRODUCT_MODEL "DLD110S"
|
||||
#define FIRMWARE_VER "4.30"
|
||||
#define HARDWARE_VER "4.01"
|
||||
#define FIRMWARE_VER_MAIN 4
|
||||
#define FIRMWARE_VER_SUB 30
|
||||
#define HARDWARE_VER_MAIN 4
|
||||
#define HARDWARE_VER_SUB 1
|
||||
|
||||
/* 功能模�� (direction_mode �4�, �议�留; 新算法��消�) */
|
||||
#define FUNCTION_A 0x01 // äºŒæ¬¡åˆ¤æ– (已废å¼?)
|
||||
#define FUNCTION_B 0x02 // 二次判æ–增强æ�¡ä»¶åˆ¤æ– (已废å¼?)
|
||||
#define FUNCTION_C 0x04 //
|
||||
#define FUNCTION_D 0x08 //
|
||||
|
||||
|
||||
extern uint16_t g_hold_time;
|
||||
extern char g_flag_debug;
|
||||
extern uint8_t g_dev_number[6];
|
||||
extern uint8_t MACAddr[6];
|
||||
|
||||
extern uint8_t g_loop_cut_last;
|
||||
extern uint32_t g_loop_cut_amount;
|
||||
extern uint8_t g_loop_power_up_state;
|
||||
|
||||
extern uint8_t g_function_mode;
|
||||
|
||||
/* 新算法状� (DLD154V4B 移�) */
|
||||
extern uint8_t g_loop_stable; // 稳定期结æ�Ÿæ ‡å¿? (0=æ”¶æ•›ä¸?, 1=稳定)
|
||||
extern uint8_t g_env_activity; // 环境活跃åº? (BLE condition å—æ®µæ�¥æº�)
|
||||
|
||||
uint32_t mstick(void);
|
||||
|
||||
#endif /* INCLUDE_CMCNG_H_ */
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 CMD_DBN_GET_DEV_INFO 0x10
|
||||
|
||||
#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_DEV_RESET 0x6D
|
||||
|
||||
#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);
|
||||
|
||||
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_ */
|
||||
@@ -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
|
||||
|
||||
/*********************************************************************
|
||||
* 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
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* storage.h
|
||||
*
|
||||
* Created on: Aug 27, 2024
|
||||
* Author: Thinkpad
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_STORAGE_H_
|
||||
#define INCLUDE_STORAGE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// #define Addr_Loop_PlanB_Cng_Offset 0x10
|
||||
// #define Addr_Flag_Sample_In 0x10
|
||||
// #define Addr_Sample_Max_Amplitude 0x11
|
||||
// #define Addr_Flag_Balance_Ori_In 0x13
|
||||
// #define Addr_Balance_Ori_In_Max_Cnt 0x14
|
||||
// #define Addr_Flag_Release_Ori_PlanB 0x16
|
||||
// #define Addr_Release_Ori_PlanB_TimeOut 0x17
|
||||
// #define Addr_Release_Ori_PlanB_Weight 0x18
|
||||
// #define Addr_Release_Ori_Amplitude 0x19
|
||||
// #define Addr_Flag_Release_Rate 0x1B
|
||||
// #define Addr_Release_Rate_First 0x1C
|
||||
// #define Addr_Release_Rate_Second 0x1D
|
||||
// #define Addr_Release_Rate_Weight 0x1E
|
||||
// #define Addr_Release_Rate_Mode 0x1F
|
||||
|
||||
#define Addr_Loop_Sens_List_Offset 0x20
|
||||
|
||||
#define Addr_Sens_Array_In 0x20
|
||||
#define Addr_Sens_Array_Out 0x30
|
||||
|
||||
|
||||
#define MAX_LOOP_SENS_AMOUNT 3 // 4 // 5
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct _Loop_Sample_CNG_
|
||||
{
|
||||
uint8_t flag;
|
||||
uint16_t max_amplitude; // 最大幅值
|
||||
}Loop_Sample_Cng;
|
||||
|
||||
typedef struct _Loop_Balance_Ori_CNG_
|
||||
{
|
||||
uint8_t flag;
|
||||
uint16_t max_cnt ; // 最大补偿次数
|
||||
}Loop_Balance_Ori_Cng; // 漂移补偿
|
||||
|
||||
typedef struct _Loop_Release_Ori_PlanB_
|
||||
{
|
||||
uint8_t flag_weight;
|
||||
uint16_t max_amplitude; //最大幅值
|
||||
uint8_t timeout; // 单位:分钟
|
||||
}Loop_Release_Ori_PlanB;
|
||||
|
||||
typedef struct _Loop_Release_Change_Rate_
|
||||
{
|
||||
uint8_t flag_weight;
|
||||
uint8_t rate_first;
|
||||
uint8_t rate_second;
|
||||
uint8_t mode;
|
||||
}Loop_Release_Change_Rate;
|
||||
|
||||
|
||||
typedef struct _Loop_Balance_PlanB_
|
||||
{
|
||||
Loop_Sample_Cng sample_cng;
|
||||
Loop_Balance_Ori_Cng balance_ori_cng;
|
||||
Loop_Release_Ori_PlanB release_ori_planB;
|
||||
Loop_Release_Change_Rate release_change_rate;
|
||||
}Loop_Balance_PlanB;
|
||||
|
||||
extern Loop_Balance_PlanB g_loop_balance_planB;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t sensitvity; // 高四位表示灵敏度的数量,低四位表示当前灵敏度的序号(从0开始)
|
||||
uint8_t delay_time;
|
||||
uint8_t output_mode;
|
||||
uint8_t direction_mode; // 方向判别模式,0 触发模式, 非0 表示方向判别模式
|
||||
uint8_t loopFreq_Level; // 高低频
|
||||
uint8_t loopSafe_Timeout; // 线圈安全模式, 0表示关闭,非0表示开启,以10秒为单位
|
||||
uint8_t exist_mode; // 0 永久存在,非0,表示有限存在的时间,单位为10秒
|
||||
}Loop_Cng_Unit;
|
||||
extern Loop_Cng_Unit g_loop_cng_unit;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t sens_in;
|
||||
uint16_t sens_out;
|
||||
}Loop_Single_Sens;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t total;
|
||||
Loop_Single_Sens sens[MAX_LOOP_SENS_AMOUNT];
|
||||
}Loop_Sens_List;
|
||||
extern Loop_Sens_List g_loop_sens_list;
|
||||
|
||||
|
||||
|
||||
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 enum
|
||||
{
|
||||
SENS_NONE = 0,
|
||||
SENS_SUB_INFO = 1, // 传感器设备信息
|
||||
SENS_OBJ_DYNAMIC = 2, // 动态目标类型
|
||||
SENS_SOUTPUT_STATUS = 3, // 当前开关量输出的状态
|
||||
SENS_DETAIL_CNG = 4, // 详细配置
|
||||
SENS_LOOP_DYNAMIC = 5, // 线圈动态信息
|
||||
SENS_OBJ_BackGround = 6, //
|
||||
SENS_OBJ_INSIDE = 7, //
|
||||
SENS_LOOP_TREND,
|
||||
SENS_OBJ_DYNAMIC_SIMPLE,
|
||||
SENS_OBJ_STATIC_XuJing, //10, 0x0A
|
||||
SENS_DOBULE_LOOP_ESTIMATE //0x0B, 线圈环境评估
|
||||
} SUB_SENS_TYPE; // 传感数据类型
|
||||
|
||||
|
||||
|
||||
typedef struct _LOOP_ACS_INFO
|
||||
{
|
||||
uint8_t flag_event;
|
||||
uint8_t loop_num;
|
||||
uint8_t freq_level;
|
||||
uint8_t sensity;
|
||||
uint8_t relay1_cng;
|
||||
uint8_t relay1_state;
|
||||
uint8_t relay2_cng;
|
||||
uint8_t relay2_state;
|
||||
uint8_t loop_state;
|
||||
uint8_t output_mode;
|
||||
uint8_t dir_mode;
|
||||
uint8_t delay;
|
||||
uint8_t car_state;
|
||||
uint8_t direction;
|
||||
uint8_t flag_loop_safe;
|
||||
uint32_t loop_safe_counter;
|
||||
uint8_t condition;
|
||||
uint8_t flag_change;
|
||||
uint32_t frequent;
|
||||
uint32_t loop_capvd;
|
||||
int32_t variation;
|
||||
uint32_t event_counter;
|
||||
uint32_t report_counter;
|
||||
} Loop_ACS_Info;
|
||||
extern Loop_ACS_Info g_loop_acs_info;
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#define HOLD_TIME 5*1200
|
||||
#define LC_HOLD_TIME 4*1200 //时间4分钟
|
||||
#define IN_DELAY 10
|
||||
#define OUT_DELAY 39
|
||||
#define PLUSE_DELAY 10
|
||||
|
||||
|
||||
void write_cfg_to_store(uint32_t wAddr, uint8_t * p, uint32_t len);
|
||||
void read_cfg_from_store(uint32_t addr, uint8_t *p, uint32_t len);
|
||||
|
||||
|
||||
#endif /* INCLUDE_STORAGE_H_ */
|
||||
@@ -0,0 +1,784 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : peripheral.C
|
||||
* Author : WCH
|
||||
* Version : V1.0
|
||||
* Date : 2018/12/10
|
||||
* 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.
|
||||
*******************************************************************************/
|
||||
|
||||
/*********************************************************************
|
||||
* INCLUDES
|
||||
*/
|
||||
#include "CONFIG.h"
|
||||
#include "devinfoservice.h"
|
||||
#include "gattprofile.h"
|
||||
#include "peripheral.h"
|
||||
|
||||
/*********************************************************************
|
||||
* MACROS
|
||||
*/
|
||||
extern uint8_t g_flag_bt_state;
|
||||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
// How often to perform periodic event
|
||||
#define SBP_PERIODIC_EVT_PERIOD 200 //800 //1600
|
||||
|
||||
// How often to perform read rssi event
|
||||
#define SBP_READ_RSSI_EVT_PERIOD 3200
|
||||
|
||||
// Parameter update delay
|
||||
#define SBP_PARAM_UPDATE_DELAY 6400
|
||||
|
||||
// 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
|
||||
0x08,
|
||||
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
|
||||
// 'S',
|
||||
// 'i',
|
||||
// 'm',
|
||||
// 'p',
|
||||
// 'l',
|
||||
// 'e',
|
||||
// ' ',
|
||||
// 'P',
|
||||
// 'e',
|
||||
// 'r',
|
||||
// 'i',
|
||||
// 'p',
|
||||
// 'h',
|
||||
// 'e',
|
||||
// 'r',
|
||||
// 'a',
|
||||
// 'l',
|
||||
'D','L','D','1','1','0','S',
|
||||
// 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] = "DLD110S";// "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)
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Set the GAP Characteristics
|
||||
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
|
||||
|
||||
{
|
||||
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
|
||||
|
||||
// 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_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;
|
||||
peripheralMTU = ATT_MTU_SIZE;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @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);
|
||||
g_flag_bt_state = 0;
|
||||
// PRINT("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
|
||||
}
|
||||
// PRINT("Advertising..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED:
|
||||
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
|
||||
{
|
||||
Peripheral_LinkEstablished(pEvent);
|
||||
}
|
||||
g_flag_bt_state = 1;
|
||||
// PRINT("Connected..\n");
|
||||
break;
|
||||
|
||||
case GAPROLE_CONNECTED_ADV:
|
||||
// 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.. Reason:%x\n", pEvent->linkTerminate.reason);
|
||||
}
|
||||
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:
|
||||
// PRINT("Error..\n");
|
||||
g_flag_bt_state = 0;
|
||||
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, ¬i) != SUCCESS)
|
||||
{
|
||||
GATT_bm_free((gattMsg_t *)¬i, 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);
|
||||
|
||||
g_ble_rcv_buf.len = len;
|
||||
tmos_memcpy(g_ble_rcv_buf.buf, pValue, len);
|
||||
// PRINT("profile ChangeCB CHAR3..len:%d,dat:%s.\n", len, g_ble_rcv_buf.buf);
|
||||
if(g_ble_rcv_buf.buf[0] == 0x3F && g_ble_rcv_buf.buf[1] == 0xF3 && g_ble_rcv_buf.buf[2] == 0x23 &&
|
||||
g_ble_rcv_buf.buf[3] == 'O' && g_ble_rcv_buf.buf[4] == 'T' && g_ble_rcv_buf.buf[5] == 'A'){
|
||||
// 0x4F, 0x54, 0x41
|
||||
// PRINT("jump OTA \n");
|
||||
mDelaymS(5);
|
||||
Jump_OTA();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// should not reach here!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* OTA 升级标志 */
|
||||
#define IMAGE_OTA_FLAG 0x03
|
||||
|
||||
/* 存放在DataFlash地址,不能占用蓝牙的位置 */
|
||||
#define OTA_DATAFLASH_ADD 0x00077000 - FLASH_ROM_MAX_SIZE
|
||||
|
||||
/* flash的数据临时存储 */
|
||||
__attribute__((aligned(8))) uint8_t block_buf[16];
|
||||
|
||||
/*********************************************************************
|
||||
* @fn Jump_OTA
|
||||
*
|
||||
* @brief 跳转OTA升级
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void Jump_OTA(void)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t ver_flag;
|
||||
|
||||
/* 读取第一块 */
|
||||
EEPROM_READ(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0], 4);
|
||||
|
||||
/* 擦除第一块 */
|
||||
EEPROM_ERASE(OTA_DATAFLASH_ADD, EEPROM_PAGE_SIZE);
|
||||
|
||||
/* 更新Image信息 */
|
||||
block_buf[0] = IMAGE_OTA_FLAG;
|
||||
|
||||
/* 编程DataFlash */
|
||||
EEPROM_WRITE(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0], 4);
|
||||
|
||||
/* 软复位 */
|
||||
SYS_ResetExecute();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* storage.c
|
||||
*
|
||||
* Created on: Aug 27, 2024
|
||||
* Author: Thinkpad
|
||||
*/
|
||||
|
||||
#include "storage.h"
|
||||
#include "CH59x_common.h"
|
||||
|
||||
|
||||
Loop_Balance_PlanB g_loop_balance_planB;
|
||||
Loop_Cng_Unit g_loop_cng_unit;
|
||||
Loop_Sens_List g_loop_sens_list;
|
||||
|
||||
|
||||
void write_cfg_to_store(uint32_t wAddr, uint8_t * p, uint32_t len)
|
||||
{
|
||||
EEPROM_WRITE(wAddr, p, len);
|
||||
}
|
||||
|
||||
|
||||
void read_cfg_from_store(uint32_t addr, uint8_t *p, uint32_t len)
|
||||
{
|
||||
EEPROM_READ(addr, p, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user