30 Commits

Author SHA1 Message Date
lmx
5ecd42b5cf 气压计1s读一次,过采样率128,测量成功 2025-12-10 19:17:54 +08:00
lmx
d92818a894 cun 2025-12-10 16:21:41 +08:00
lmx
3b36715264 cun 2025-12-10 11:11:36 +08:00
lmx
c398dd9eeb cun 2025-12-10 10:23:21 +08:00
lmx
0feb648d11 wf282A读数有问题 2025-12-09 19:28:20 +08:00
lmx
5a72132d2a cun 2025-12-09 17:02:07 +08:00
lmx
2f4e1d7e5b cun 2025-12-09 16:30:25 +08:00
lmx
3f02a9f9be cun 2025-12-09 11:21:08 +08:00
lmx
6ce9deebe6 cun 2025-12-09 11:16:49 +08:00
lmx
96891516b8 cun 2025-12-09 11:10:52 +08:00
lmx
52e4b62b53 cun 2025-12-09 11:04:18 +08:00
lmx
ea610c24d3 串口输出原始数据到上位机验证 2025-12-09 09:59:41 +08:00
lmx
45158aebcf cun 2025-12-05 19:37:31 +08:00
lmx
138275a04b cun 2025-12-05 19:06:54 +08:00
lmx
89f1c93f74 蓝牙发送速率提升 2025-12-04 18:51:38 +08:00
lmx
8c2db49083 iic速率调整到400k 2025-12-02 10:24:01 +08:00
lmx
627780ea20 11月28日发客户的版本 2025-11-28 18:13:35 +08:00
lmx
ade4b0a1f8 feat: Add rfid feature and .gitignore file 2025-11-28 16:25:35 +08:00
lmx
818e8c3778 chore: Remove tracked build artifacts 2025-11-28 16:24:27 +08:00
lmx
892ed9267b feat: Add rfid feature and .gitignore file 2025-11-28 16:23:06 +08:00
lmx
4af4f13ac6 存档 2025-11-25 18:52:49 +08:00
lmx
4c5da2298f 数据按照小端模式发送 2025-11-25 18:01:17 +08:00
lmx
5c7d9ab822 cun 2025-11-25 15:27:26 +08:00
lmx
60a4e95386 cun 2025-11-25 14:27:19 +08:00
lmx
845cc33fe8 gitignore 2025-11-25 14:16:22 +08:00
lmx
f3710fbb4b 蓝牙协议完成 2025-11-21 18:50:19 +08:00
lmx
91b08dbe47 差气压计的蓝牙协议 2025-11-21 17:10:36 +08:00
lmx
591e7632d2 cun 2025-11-21 15:17:10 +08:00
lmx
baa5979ee1 暂存:数据发送协议完善中 2025-11-21 14:54:21 +08:00
lmx
bdadd5de1e cun 2025-11-21 10:53:47 +08:00
1152 changed files with 2159 additions and 279981 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# 编译生成的目标文件
*.o
*.so
*.d
# 编译生成的最终产物
*.elf
*.fw
*.ufw
*.map
*.lst
*.bc
# VSCode 用户个人设置
# 团队协作时,每个人的配置可能不同,通常不建议提交
.vscode/settings.json

33
.vscode/settings.json vendored
View File

@ -1,33 +0,0 @@
{
"files.associations": {
"board_config.h": "c",
"board_jl701n_demo_cfg.h": "c",
"colorful_lights.h": "c",
"board_jl701n_anc_cfg.h": "c",
"update_loader_download.h": "c",
"iic_soft.h": "c",
"circle_buffer.h": "c",
"default_event_handler.h": "c",
"ui_manage.h": "c",
"charge.h": "c",
"app_main.h": "c",
"app_config.h": "c",
"app_action.h": "c",
"includes.h": "c",
"key_event_deal.h": "c",
"app_umidigi_chargestore.h": "c",
"hci_lmp.h": "c",
"bluetooth.h": "c",
"SCU722.C": "cpp",
"math.h": "c",
"avctp_user.h": "c",
"string.h": "c",
"dev_manager.h": "c",
"bt_tws.h": "c",
"skiing_tracker.h": "c",
"xtell.h": "c",
"debug.h": "c",
"ano_protocol.h": "c",
"board_jl701n_demo_global_build_cfg.h": "c"
}
}

View File

@ -628,6 +628,7 @@ c_SRC_FILES := \
apps/earphone/xtell_Sensor/sensor/MMC56.c \
apps/earphone/xtell_Sensor/sensor/BMP280.c \
apps/earphone/xtell_Sensor/sensor/AK8963.c \
apps/earphone/xtell_Sensor/sensor/WF282A.c \
# 需要编译的 .S 文件

View File

@ -213,7 +213,7 @@ void write_gsensor_data_handle(void)
}
// 临时的设备扫描诊断函数
void i2c_scanner_probe(void)
void i2c_scanner_probe(u8* device_addr, u8* found_number)
{
printf("Starting I2C bus scan...\n");
int devices_found = 0;
@ -230,6 +230,7 @@ void i2c_scanner_probe(void)
// iic_tx_byte 返回 1 表示收到了 ACK
if (iic_tx_byte(gSensor_info->iic_hdl, write_addr_8bit))
{
device_addr[devices_found] = addr_7bit;
printf("=====================================================================\n");
printf("I2C device found at 7-bit address: 0x%02X\n", addr_7bit);
printf("I2C device found at 8-bit address: 0x%02X\n", write_addr_8bit);
@ -240,6 +241,7 @@ void i2c_scanner_probe(void)
iic_stop(gSensor_info->iic_hdl);
delay(gSensor_info->iic_delay); // 短暂延时
}
*found_number = devices_found;
if (devices_found == 0) {
printf("Scan finished. No I2C devices found.\n");
@ -264,7 +266,8 @@ u8 gravity_sensor_command(u8 w_chip_id, u8 register_address, u8 function_command
// xlog("iic_tx_byte id\n");
if (0 == iic_tx_byte(gSensor_info->iic_hdl, w_chip_id)) {
ret = 0;
xlog("\n gsen iic wr err 0\n");
xlog("iic write: I2C NACK on writing ADDR: 0x%X\n", w_chip_id);
// xlog("\n gsen iic wr err 0\n");
strcpy(&w_log_buffer_1, "gsen iic wr err 0\n");
goto __gcend;
}
@ -314,7 +317,7 @@ u8 _gravity_sensor_get_ndata(u8 r_chip_id, u8 register_address, u8 *buf, u8 data
iic_start(gSensor_info->iic_hdl);
if (0 == iic_tx_byte(gSensor_info->iic_hdl, r_chip_id - 1)) {
xlog("I2C NACK on writing ADDR: 0x%X\n", r_chip_id - 1);
xlog("iic read: I2C NACK on writing ADDR: 0x%X\n", r_chip_id - 1);
read_len = 0;
strcpy(&sen_log_buffer_1, "gsen iic rd err 0\n");
goto __gdend;

View File

@ -49,7 +49,7 @@
#include "classic/tws_api.h"
#include "rcsp_adv_user_update.h"
#include "bt_tws.h"
// #include "le_trans_data.h"
#if (TCFG_BLE_DEMO_SELECT == DEF_BLE_DEMO_ADV_RCSP)
#if TCFG_CHARGE_BOX_ENABLE
@ -86,8 +86,10 @@ static const char user_tag_string[] = {EIR_TAG_STRING};
/* #include "debug.h" */
//------
#define ATT_LOCAL_PAYLOAD_SIZE (200) //note: need >= 20
#define ATT_SEND_CBUF_SIZE (512) //note: need >= 20,缓存大小,可修改
// #define ATT_LOCAL_PAYLOAD_SIZE (200*10) //note: need >= 20
// #define ATT_SEND_CBUF_SIZE (1024 * 50) //note: need >= 20,缓存大小,可修改
#define ATT_LOCAL_PAYLOAD_SIZE (517) //note: need >= 20
#define ATT_SEND_CBUF_SIZE (1024 * 2) //note: need >= 20,缓存大小,可修改
#define ATT_RAM_BUFSIZE (ATT_CTRL_BLOCK_SIZE + ATT_LOCAL_PAYLOAD_SIZE + ATT_SEND_CBUF_SIZE) //note:
static u8 att_ram_buffer[ATT_RAM_BUFSIZE] __attribute__((aligned(4)));
//---------------
@ -109,9 +111,10 @@ static const uint8_t sm_min_key_size = 7;
static const uint8_t connection_update_enable = 1; ///0--disable, 1--enable
static uint8_t connection_update_cnt = 0; //
static const struct conn_update_param_t connection_param_table[] = {
{16, 24, 16, 600},
{12, 28, 14, 600},//11
{8, 20, 20, 600},//3.7
{6, 12, 0, 400},//3.7
// {16, 24, 16, 600},
// {12, 28, 14, 600},//11
// {8, 20, 20, 600},//3.7
/* {12, 28, 4, 600},//3.7 */
/* {12, 24, 30, 600},//3.05 */
};
@ -299,6 +302,17 @@ void test_data_send_packet(void)
static void can_send_now_wakeup(void)
{
// static signed char acc_data_buf[60] = {
// 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22
// };
// extern void send_data_to_ble_client(const u8* data, u16 length);
// send_data_to_ble_client(&acc_data_buf, 60);
putchar('E');
if (ble_resume_send_wakeup) {
ble_resume_send_wakeup();
@ -315,6 +329,24 @@ u8 ble_update_get_ready_jump_flag(void)
return 0;
}
// 添加到 le_rcsp_adv_module.c
static void set_connection_data_length(u16 tx_octets, u16 tx_time) //xtell
{
if (con_handle) {
ble_user_cmd_prepare(BLE_CMD_SET_DATA_LENGTH, 3, con_handle, tx_octets, tx_time);
}
}
static void set_connection_data_phy(u8 tx_phy, u8 rx_phy)//xtell
{
if (0 == con_handle) {
return;
}
u8 all_phys = 0;
u16 phy_options = 0; // 根据你的 SDK 定义调整
ble_user_cmd_prepare(BLE_CMD_SET_PHY, 5, con_handle, all_phys, tx_phy, rx_phy, phy_options);
}
/*
* @section Packet Handler
*
@ -370,6 +402,16 @@ static void cbk_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
connection_update_complete_success(packet);
break;
}
case HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE: //xtell
log_info("APP HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE\n");
set_connection_data_phy(2, 2); // 2 表示 2M PHY
break;
case HCI_SUBEVENT_LE_PHY_UPDATE_COMPLETE://xtell
log_info("APP HCI_SUBEVENT_LE_PHY_UPDATE %s\n", packet[4] ? "Fail" : "Succ"); // packet[4] 是 status
log_info("Tx PHY: %d\n", packet[5]); // packet[5] 是 TX_PHY
log_info("Rx PHY: %d\n", packet[6]); // packet[6] 是 RX_PHY
break;
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
@ -410,6 +452,7 @@ static void cbk_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
mtu = att_event_mtu_exchange_complete_get_MTU(packet) - 3;
log_info("ATT MTU = %u\n", mtu);
ble_user_cmd_prepare(BLE_CMD_ATT_MTU_SIZE, 1, mtu);
set_connection_data_length(251, 2120);//xtell
break;
case HCI_EVENT_VENDOR_REMOTE_TEST:
@ -571,6 +614,7 @@ static int app_send_user_data(u16 handle, u8 *data, u16 len, u8 handle_type)
ret = ble_user_cmd_prepare(BLE_CMD_ATT_SEND_DATA, 4, handle, data, len, handle_type);
if (ret == BLE_BUFFER_FULL) {
printf("app_send_user_data: buffer full\n");
ret = APP_BLE_BUFF_FULL;
}
@ -1663,12 +1707,8 @@ void send_version_to_sibling(void)
data[2] = ver >> 8;
tws_api_send_data_to_sibling(data, sizeof(data), TWS_FUNC_ID_SEQ_RAND_SYNC);
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////
void send_data_to_ble_client(const u8* data, u16 length)
{
// 检查数据长度是否有效
@ -1677,8 +1717,8 @@ void send_data_to_ble_client(const u8* data, u16 length)
return;
}
// 检查缓冲区空间
if (app_send_user_data_check(length)) {
// // 检查缓冲区空间
// if (app_send_user_data_check(length)) {
// 发送数据
int ret = app_send_user_data(ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, data, length, ATT_OP_NOTIFY);
if (ret == 0) { // 假设 0 表示成功
@ -1686,7 +1726,12 @@ void send_data_to_ble_client(const u8* data, u16 length)
} else {
// printf("Failed to send data: Length %d, Error code: %d\n", length, ret);
}
} else {
// } else {
// printf("Insufficient buffer space to send data: Length %d\n", length);
}
// }
}
#endif

View File

@ -530,6 +530,7 @@ void JL_rcsp_msg_deal(void *hdl, u8 event, u8 *msg)
case MSG_JL_ENTER_UPDATE_MODE:
rcsp_printf("MSG_JL_ENTER_UPDATE_MODE:%x %x\n", msg[0], msg[1]);
clk_set("sys",96*1000000L);
bt_set_low_latency_mode(0);
if (support_dual_bank_update_en && !tws_api_get_role()) {
u8 status = 0;

View File

@ -81,9 +81,9 @@ extern void printf_buf(u8 *buf, u32 len);
//------
//ATT发送的包长, note: 20 <=need >= MTU
#define ATT_LOCAL_MTU_SIZE (200) //
#define ATT_LOCAL_MTU_SIZE (517) //200
//ATT缓存的buffer大小, note: need >= 20,可修改
#define ATT_SEND_CBUF_SIZE (512) //
#define ATT_SEND_CBUF_SIZE (512 * 20) //
//共配置的RAM
#define ATT_RAM_BUFSIZE (ATT_CTRL_BLOCK_SIZE + ATT_LOCAL_MTU_SIZE + ATT_SEND_CBUF_SIZE) //note:
@ -125,9 +125,10 @@ static uint8_t connection_update_cnt = 0; //
//参数表
static const struct conn_update_param_t connection_param_table[] = {
{16, 24, 10, 600},//11
{12, 28, 10, 600},//3.7
{8, 20, 10, 600},
{6, 12, 0, 400},//11
// {16, 24, 10, 600},//11
// {12, 28, 10, 600},//3.7
// {8, 20, 10, 600},
/* {12, 28, 4, 600},//3.7 */
/* {12, 24, 30, 600},//3.05 */
};
@ -706,6 +707,8 @@ static int att_write_callback(hci_con_handle_t connection_handle, uint16_t att_h
u16 handle = att_handle;
log_info("write_callback, handle= 0x%04x,size = %d\n", handle, buffer_size);
extern void le_user_app_event(u8* buffer);
le_user_app_event(buffer);
switch (handle) {
@ -1389,6 +1392,44 @@ void hangup_ans_call_handle(u8 en)
}
#endif
void send_data_to_ble_client(const u8* data, u16 length)
{
// 检查数据长度是否有效
if (length == 0 || length > 512) {
printf("Error: Data length %d is out of range (1-512)\n", length);
return;
}
// // 检查缓冲区空间
// if (app_send_user_data_check(length)) {
// 发送数据
int ret = app_send_user_data(ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, data, length, ATT_OP_NOTIFY);
if (ret == 0) { // 假设 0 表示成功
// printf("Data sent successfully: Length %d\n", length);
} else {
printf("Failed to send data: Length %d, Error code: %d\n", length, ret);
}
// } else {
// printf("Insufficient buffer space to send data: Length %d\n", length);
// }
}
void rcsp_adv_fill_mac_addr(u8 *mac_addr_buf)
{
#if (MUTIl_CHARGING_BOX_EN)
u8 *mac_addr = get_chargebox_adv_addr();
if (mac_addr) {
swapX(mac_addr, mac_addr_buf, 6);
}
/* printf("mac_addr:"); */
/* printf_buf(mac_addr_buf, 6); */
#else
swapX(bt_get_mac_addr(), mac_addr_buf, 6);
#endif
}
#endif

View File

@ -37,7 +37,7 @@ extern void printf_buf(u8 *buf, u32 len);
//------
//ATT发送的包长, note: 20 <=need >= MTU
#define ATT_LOCAL_MTU_SIZE (517) //
//ATT缓存的buffer大小, note: need >= 20,可修改
//ATT缓存的buffer大小, +: need >= 20,可修改
#if(APP_MAIN == APP_WIRELESS_MIC_2T1)
#define ATT_SEND_CBUF_SIZE (90)
#else
@ -92,7 +92,8 @@ static uint8_t connection_update_cnt = 0; //
//参数表
static const struct conn_update_param_t connection_param_table[] = {
{WIRELESS_BLE_CONNECT_INTERVAL, WIRELESS_BLE_CONNECT_INTERVAL, 0, 100},//11
// {1, 5, 4, 600},//11
{12, 24, 0, 400}, // 建议修改为此值 (15ms - 30ms interval)
};
//共可用的参数组数
@ -421,7 +422,7 @@ static void cbk_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
case HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE:
log_info("APP HCI_SUBEVENT_LE_DATA_LENGTH_CHANGE\n");
set_connection_data_phy(CONN_SET_2M_PHY, CONN_SET_2M_PHY);
// set_connection_data_phy(CONN_SET_2M_PHY, CONN_SET_2M_PHY);
break;
case HCI_SUBEVENT_LE_PHY_UPDATE_COMPLETE:
@ -453,7 +454,7 @@ static void cbk_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *p
mtu = att_event_mtu_exchange_complete_get_MTU(packet) - 3;
log_info("ATT MTU = %u\n", mtu);
ble_op_att_set_send_mtu(mtu);
set_connection_data_length(251, 2120);
// set_connection_data_length(251, 2120);
break;
case HCI_EVENT_VENDOR_REMOTE_TEST:
@ -1067,6 +1068,44 @@ void ble_server_send_test_key_num(u8 key_num)
;
}
void send_data_to_ble_client(const u8* data, u16 length)
{
// 检查数据长度是否有效
if (length == 0 || length > 512) {
printf("Error: Data length %d is out of range (1-512)\n", length);
return;
}
// // 检查缓冲区空间
// if (app_send_user_data_check(length)) {
// 发送数据
int ret = app_send_user_data(ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, data, length, ATT_OP_NOTIFY);
if (ret == 0) { // 假设 0 表示成功
printf("Data sent successfully: Length %d\n", length);
} else {
printf("Failed to send data: Length %d, Error code: %d\n", length, ret);
}
// } else {
// printf("Insufficient buffer space to send data: Length %d\n", length);
// }
}
void rcsp_adv_fill_mac_addr(u8 *mac_addr_buf)
{
#if (MUTIl_CHARGING_BOX_EN)
u8 *mac_addr = get_chargebox_adv_addr();
if (mac_addr) {
swapX(mac_addr, mac_addr_buf, 6);
}
/* printf("mac_addr:"); */
/* printf_buf(mac_addr_buf, 6); */
#else
swapX(bt_get_mac_addr(), mac_addr_buf, 6);
#endif
}
#endif

View File

@ -81,10 +81,10 @@ const struct task_info task_info_table[] = {
#if AUDIO_ENC_MPT_SELF_ENABLE
{"enc_mpt_self", 3, 0, 512, 128 },
#endif/*AUDIO_ENC_MPT_SELF_ENABLE*/
// {"update", 1, 0, 256, 0 },
// {"tws_ota", 2, 0, 256, 0 },
// {"tws_ota_msg", 2, 0, 256, 128 },
// {"dw_update", 2, 0, 256, 128 },
{"update", 1, 0, 256, 0 },
{"tws_ota", 2, 0, 256, 0 },
{"tws_ota_msg", 2, 0, 256, 128 },
{"dw_update", 2, 0, 256, 128 },
{"rcsp_task", 2, 0, 640, 128 },
// {"aud_capture", 4, 0, 512, 256 },
// {"data_export", 5, 0, 512, 256 },

View File

@ -717,7 +717,7 @@ struct port_wakeup port0 = {
.pullup_down_enable = ENABLE, //配置I/O 内部上下拉是否使能
.edge = FALLING_EDGE, //唤醒方式选择,可选:上升沿\下降沿
.filter = PORT_FLT_8ms,
.iomap = IO_PORTB_01, //唤醒口选择
.iomap = IO_PORTA_04, //唤醒口选择
};
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)

View File

@ -23,17 +23,17 @@
//*********************************************************************************//
#define TCFG_UART0_ENABLE ENABLE_THIS_MOUDLE //串口打印模块使能
// #define TCFG_UART0_ENABLE 0 //串口打印模块使能
#define TCFG_UART0_RX_PORT NO_CONFIG_PORT //串口接收脚配置用于打印可以选择NO_CONFIG_PORT
#define TCFG_UART0_RX_PORT IO_PORT_DM//NO_CONFIG_PORT //串口接收脚配置用于打印可以选择NO_CONFIG_PORT
#define TCFG_UART0_TX_PORT IO_PORT_DP //串口发送脚配置
// #define TCFG_UART0_BAUDRATE 1000000 //串口波特率配置
#define TCFG_UART0_BAUDRATE 115200 //串口波特率配置
#define TCFG_UART0_BAUDRATE 1000000 //串口波特率配置
// #define TCFG_UART0_BAUDRATE 115200 //串口波特率配置
//*********************************************************************************//
// IIC配置 //
//*********************************************************************************//
/*软件IIC设置*/ //xtell
#define TCFG_SW_I2C0_CLK_PORT IO_PORTA_05 //软件IIC CLK脚选择 XTELL
#define TCFG_SW_I2C0_DAT_PORT IO_PORTA_06 //软件IIC DAT脚选择
#define TCFG_SW_I2C0_CLK_PORT IO_PORTB_04 //软件IIC CLK脚选择 XTELL
#define TCFG_SW_I2C0_DAT_PORT IO_PORTB_05 //软件IIC DAT脚选择
#define TCFG_SW_I2C0_DELAY_CNT 10 //IIC延时参数影响通讯时钟频率
/*硬件IIC端口选择 -- 具体看手册,这里写的不准 -- lmx
@ -47,7 +47,7 @@
*/
#define TCFG_HW_I2C0_PORTS 'B'
#define TCFG_HW_I2C0_CLK 1000000 //硬件IIC波特率:100k
#define TCFG_HW_I2C0_CLK 400000 //硬件IIC波特率:400k
//*********************************************************************************//
// 硬件SPI 配置 //
@ -87,7 +87,7 @@
//*********************************************************************************//
// USB 配置 //
//*********************************************************************************//
#define TCFG_PC_ENABLE 1//DISABLE_THIS_MOUDLE//PC模块使能
#define TCFG_PC_ENABLE 0//DISABLE_THIS_MOUDLE//PC模块使能
#define TCFG_UDISK_ENABLE 0//ENABLE_THIS_MOUDLE//U盘模块使能
#define TCFG_OTG_USB_DEV_EN BIT(0)//USB0 = BIT(0) USB1 = BIT(1)
@ -729,7 +729,7 @@ DAC硬件上的连接方式,可选的配置:
// 充电舱/蓝牙测试盒/ANC测试三者为同级关系,开启任一功能都会初始化PP0通信接口 //
//*********************************************************************************//
#define TCFG_CHARGESTORE_ENABLE DISABLE_THIS_MOUDLE //是否支持智能充电舱
#define TCFG_TEST_BOX_ENABLE ENABLE_THIS_MOUDLE //是否支持蓝牙测试盒 //xtell
#define TCFG_TEST_BOX_ENABLE DISABLE_THIS_MOUDLE//ENABLE_THIS_MOUDLE //是否支持蓝牙测试盒 //xtell
#define TCFG_ANC_BOX_ENABLE CONFIG_ANC_ENABLE //是否支持ANC测试盒
#define TCFG_UMIDIGI_BOX_ENABLE DISABLE_THIS_MOUDLE //是否支持UMIDIGI充电舱 //xtell
#if TCFG_UMIDIGI_BOX_ENABLE
@ -791,7 +791,7 @@ DAC硬件上的连接方式,可选的配置:
//*********************************************************************************//
#define TCFG_LOWPOWER_POWER_SEL PWR_DCDC15 //电源模式设置可选DCDC和LDO
#define TCFG_LOWPOWER_BTOSC_DISABLE 0 //低功耗模式下BTOSC是否保持
#define TCFG_LOWPOWER_LOWPOWER_SEL 1 //低功耗使能,蓝牙&&系统空闲可进入低功耗
#define TCFG_LOWPOWER_LOWPOWER_SEL 0 //低功耗使能,蓝牙&&系统空闲可进入低功耗
#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_30V //vddiom等级
#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC //低功耗晶振类型btosc/lrc
#if (TCFG_AUDIO_ASR_DEVELOP && TCFG_CVP_DEVELOP_ENABLE)
@ -807,7 +807,7 @@ DAC硬件上的连接方式,可选的配置:
// EQ配置 //
//*********************************************************************************//
//EQ配置使用在线EQ时EQ文件和EQ模式无效。有EQ文件时使能TCFG_USE_EQ_FILE,默认不用EQ模式切换功能
#define TCFG_EQ_ENABLE 1 //支持EQ功能,EQ总使能
#define TCFG_EQ_ENABLE 0 //支持EQ功能,EQ总使能
// #if TCFG_EQ_ENABLE
#define TCFG_EQ_ONLINE_ENABLE 0 //支持在线EQ调试,如果使用蓝牙串口调试,需要打开宏 APP_ONLINE_DEBUG否则默认使用uart调试(二选一)
#define TCFG_BT_MUSIC_EQ_ENABLE 1 //支持蓝牙音乐EQ
@ -1010,7 +1010,7 @@ DAC硬件上的连接方式,可选的配置:
//*********************************************************************************//
#define TCFG_USER_TWS_ENABLE 0 //tws功能使能
#define TCFG_USER_BLE_ENABLE 1 //BLE功能使能
#define TCFG_BT_SUPPORT_AAC 1 //AAC格式支持
#define TCFG_BT_SUPPORT_AAC 0 //AAC格式支持
#define TCFG_BT_SUPPORT_LDAC 0 //LDAC格式支持
#if TCFG_BT_SUPPORT_LDAC
@ -1084,7 +1084,7 @@ DAC硬件上的连接方式,可选的配置:
// 编解码格式配置(CodecFormat) //
//*********************************************************************************//
/*解码格式使能*/
#define TCFG_DEC_MP3_ENABLE ENABLE
#define TCFG_DEC_MP3_ENABLE DISABLE
#define TCFG_DEC_WTGV2_ENABLE ENABLE
#define TCFG_DEC_G729_ENABLE DISABLE
#define TCFG_DEC_WMA_ENABLE DISABLE
@ -1130,7 +1130,7 @@ DAC硬件上的连接方式,可选的配置:
//*********************************************************************************//
#if TCFG_USER_BLE_ENABLE
#define DUEROS_DMA_EN 0
#define TRANS_DATA_EN 0//1 //xtellota
// #define TRANS_DATA_EN 0//1 //xtellota
#define BLE_HID_EN 0
#if (DUEROS_DMA_EN)

View File

@ -8,12 +8,12 @@
/* Following Macros Affect Periods Of Both Code Compiling And Post-build */
#define CONFIG_DOUBLE_BANK_ENABLE 0 //单双备份选择(若打开了改宏,FLASH结构变为双备份结构适用于接入第三方协议的OTA PS: JL-OTA同样支持双备份升级, 需要根据实际FLASH大小同时配置CONFIG_FLASH_SIZE)
#define CONFIG_APP_OTA_ENABLE 0 //是否支持RCSP升级(JL-OTA)
#define CONFIG_DOUBLE_BANK_ENABLE 1 //单双备份选择(若打开了改宏,FLASH结构变为双备份结构适用于接入第三方协议的OTA PS: JL-OTA同样支持双备份升级, 需要根据实际FLASH大小同时配置CONFIG_FLASH_SIZE)
#define CONFIG_APP_OTA_ENABLE 1 //是否支持RCSP升级(JL-OTA)
#define CONFIG_UPDATE_JUMP_TO_MASK 0 //配置升级到loader的方式0为直接reset,1为跳转(适用于芯片电源由IO口KEEP住的方案,需要注意检查跳转前是否将使用DMA的硬件模块全部关闭)
#define CONFIG_IO_KEY_EN 0 //配置是否使用IO按键配合RESET1
#define CONFIG_IO_KEY_EN 1 //配置是否使用IO按键配合RESET1
#define CONFIG_UPDATE_WITH_MD5_CHECK_EN 0 //配置升级是否支持MD5校验
#define CONFIG_ANC_ENABLE 0 //配置是否支持ANC
@ -33,7 +33,7 @@
/* Following Macros Only For Post Bulid Configuaration */
#define CONFIG_DB_UPDATE_DATA_GENERATE_EN 0 //是否生成db_data.bin(用于第三方协议接入使用)
#define CONFIG_ONLY_GRENERATE_ALIGN_4K_CODE 0 //ufw只生成1份4K对齐的代码
#define CONFIG_ONLY_GRENERATE_ALIGN_4K_CODE 1 //ufw只生成1份4K对齐的代码
//config for supported chip version
#ifdef CONFIG_BR30_C_VERSION
@ -73,8 +73,8 @@
#if CONFIG_IO_KEY_EN
#define CONFIG_SUPPORT_RESET1
#define CONFIG_RESET1_PIN PB01 //io pin
#define CONFIG_RESET1_TIME 08 //unit:second
#define CONFIG_RESET1_PIN PA04 //io pin
#define CONFIG_RESET1_TIME 01 //unit:second
#define CONFIG_RESET1_LEVEL 0 //tigger level(0/1)
#endif

View File

@ -21,9 +21,10 @@
#define CONFIG_APP_BT_ENABLE
#ifdef CONFIG_APP_BT_ENABLE
#define TRANS_DATA_EN 0
#define BLE_WIRELESS_SERVER_EN 0
#define TRANS_DATA_EN 1
#define RCSP_BTMATE_EN 0
#define RCSP_ADV_EN 1
#define RCSP_ADV_EN 0
#define AI_APP_PROTOCOL 0
#define LL_SYNC_EN 0
#define TUYA_DEMO_EN 0
@ -65,8 +66,8 @@
#if CONFIG_APP_OTA_ENABLE
#define RCSP_UPDATE_EN 1 //是否支持rcsp升级
#if CONFIG_DOUBLE_BANK_ENABLE //双备份才能打开同步升级流程
#define OTA_TWS_SAME_TIME_ENABLE 1 //是否支持TWS同步升级
#define OTA_TWS_SAME_TIME_NEW 1 //使用新的tws ota流程
#define OTA_TWS_SAME_TIME_ENABLE 0 //是否支持TWS同步升级
#define OTA_TWS_SAME_TIME_NEW 0 //使用新的tws ota流程
#else
#define OTA_TWS_SAME_TIME_ENABLE 1//0 xtellota //是否支持TWS同步升级
#define OTA_TWS_SAME_TIME_NEW 1//0 //使用新的tws ota流程

View File

@ -204,6 +204,18 @@ int app_protocol_sys_event_handler(struct sys_event *event);
#define EARPHONE_STATE_SNIFF(a)
#define EARPHONE_STATE_ROLE_SWITCH(a)
#elif BLE_WIRELESS_SERVER_EN
#define EARPHONE_STATE_INIT() do { } while(0)
#define EARPHONE_STATE_SET_PAGE_SCAN_ENABLE() do { } while(0)
#define EARPHONE_STATE_GET_CONNECT_MAC_ADDR() do { } while(0)
#define EARPHONE_STATE_CANCEL_PAGE_SCAN() do { } while(0)
#define EARPHONE_STATE_ENTER_SOFT_POWEROFF() do { } while(0)
#define EARPHONE_STATE_TWS_INIT(a) do { } while(0)
#define EARPHONE_STATE_TWS_CONNECTED(a, b) do { } while(0)
#define SYS_EVENT_HANDLER_SPECIFIC(a) do { } while(0)
#define SYS_EVENT_REMAP(a) 0
#define EARPHONE_STATE_SNIFF(a)
#define EARPHONE_STATE_ROLE_SWITCH(a)
#else
int adv_earphone_state_init();
int adv_earphone_state_set_page_scan_enable();

View File

@ -232,7 +232,8 @@ const uint64_t config_btctler_le_features = LE_ENCRYPTION;
#else
const int config_btctler_le_roles = (LE_ADV | LE_SLAVE);
const uint64_t config_btctler_le_features = 0;
// const uint64_t config_btctler_le_features = 0;
const uint64_t config_btctler_le_features = LE_ENCRYPTION | LE_DATA_PACKET_LENGTH_EXTENSION | LE_2M_PHY;
#endif
#else
const int config_btctler_le_roles = 0;
@ -280,9 +281,13 @@ const int config_btctler_le_acl_total_nums = 1;
const int config_btctler_le_afh_en = 0;
const u32 config_vendor_le_bb = 0;
const int config_btctler_le_rx_nums = 5;
const int config_btctler_le_acl_packet_length = 27;
const int config_btctler_le_acl_total_nums = 5;
// const int config_btctler_le_rx_nums = 5;
// const int config_btctler_le_acl_packet_length = 27;
// const int config_btctler_le_acl_total_nums = 5;
const int config_btctler_le_rx_nums = 8;
const int config_btctler_le_acl_packet_length = 251;
const int config_btctler_le_acl_total_nums = 8;
#endif
/*-----------------------------------------------------------*/

View File

@ -9,11 +9,19 @@ void circle_buffer_init(circle_buffer_t *cb, void *buffer, u16 capacity, u16 ele
cb->head = 0;
cb->tail = 0;
cb->size = 0;
os_mutex_create(&cb->mutex);
}
// 销毁环形缓冲区
void circle_buffer_deinit(circle_buffer_t *cb) {
os_mutex_del(&cb->mutex, 0);
}
// 向环形缓冲区写入一个元素
bool circle_buffer_write(circle_buffer_t *cb, const void *element) {
os_mutex_pend(&cb->mutex, 0);
if (circle_buffer_is_full(cb)) {
os_mutex_post(&cb->mutex);
return false; // 缓冲区已满
}
@ -22,12 +30,15 @@ bool circle_buffer_write(circle_buffer_t *cb, const void *element) {
cb->head = (cb->head + 1) % cb->capacity;
cb->size++;
os_mutex_post(&cb->mutex);
return true;
}
// 从环形缓冲区读取一个元素
bool circle_buffer_read(circle_buffer_t *cb, void *element) {
os_mutex_pend(&cb->mutex, 0);
if (circle_buffer_is_empty(cb)) {
os_mutex_post(&cb->mutex);
return false; // 缓冲区为空
}
@ -36,25 +47,38 @@ bool circle_buffer_read(circle_buffer_t *cb, void *element) {
cb->tail = (cb->tail + 1) % cb->capacity;
cb->size--;
os_mutex_post(&cb->mutex);
return true;
}
// 获取已用空间的大小(以元素为单位)
u16 circle_buffer_get_size(circle_buffer_t *cb) {
return cb->size;
os_mutex_pend(&cb->mutex, 0);
u16 size = cb->size;
os_mutex_post(&cb->mutex);
return size;
}
// 获取剩余空间的大小(以元素为单位)
u16 circle_buffer_get_free_space(circle_buffer_t *cb) {
return cb->capacity - cb->size;
os_mutex_pend(&cb->mutex, 0);
u16 free_space = cb->capacity - cb->size;
os_mutex_post(&cb->mutex);
return free_space;
}
// 检查缓冲区是否已满
bool circle_buffer_is_full(circle_buffer_t *cb) {
return cb->size == cb->capacity;
os_mutex_pend(&cb->mutex, 0);
bool is_full = (cb->size == cb->capacity);
os_mutex_post(&cb->mutex);
return is_full;
}
// 检查缓冲区是否为空
bool circle_buffer_is_empty(circle_buffer_t *cb) {
return cb->size == 0;
os_mutex_pend(&cb->mutex, 0);
bool is_empty = (cb->size == 0);
os_mutex_post(&cb->mutex);
return is_empty;
}

View File

@ -2,6 +2,7 @@
#define CIRCLE_BUFFER_H
#include "system/includes.h"
#include "os/os_api.h"
// 定义环形缓冲区的结构体
typedef struct {
@ -11,6 +12,7 @@ typedef struct {
u16 head; // 头部指针(写入位置,以元素为单位)
u16 tail; // 尾部指针(读取位置,以元素为单位)
u16 size; // 当前已用大小(以元素为单位)
OS_MUTEX mutex; // 用于保护缓冲区的互斥锁
} circle_buffer_t;
/**
@ -22,6 +24,12 @@ typedef struct {
*/
void circle_buffer_init(circle_buffer_t *cb, void *buffer, u16 capacity, u16 element_size);
/**
* @brief 销毁环形缓冲区,释放相关资源
* @param cb 指向环形缓冲区结构体的指针
*/
void circle_buffer_deinit(circle_buffer_t *cb);
/**
* @brief 向环形缓冲区写入一个元素
* @param cb 指向环形缓冲区结构体的指针

View File

@ -1,10 +1,12 @@
/*
使用四元数求角度和去掉重力分量
*/
#include "skiing_tracker.h"
#include "../sensor/SC7U22.h"
#include <math.h>
#include <string.h>
#define G_ACCELERATION 9.81f
#define DEG_TO_RAD (3.14159265f / 180.0f)
#define ENABLE_XLOG 1
#ifdef xlog
@ -16,13 +18,83 @@
#define xlog(format, ...) ((void)0)
#endif
// --- 静止检测 ---
//两个判断是否静止的必要条件:动态零速更新(ZUPT)阈值
// 加速方差阈值,提高阈值,让“刹车”更灵敏,以便在波浪式前进等慢速漂移时也能触发零速更新
#define STOP_ACC_VARIANCE_THRESHOLD 0.2f
// 陀螺仪方差阈值
#define STOP_GYR_VARIANCE_THRESHOLD 5.0f
// 静止时候的陀螺仪模长
#define STOP_GYR_MAG_THRESHOLD 15
// --- --- ---
#define G_ACCELERATION 9.81f
#define DEG_TO_RAD (3.14159265f / 180.0f)
// --- 启动滑雪阈值 ---
// 加速度模长与重力的差值大于此值,认为开始运动;降低阈值,让“油门”更灵敏,以便能捕捉到真实的慢速启动
#define START_ACC_MAG_THRESHOLD 1.0f //0.5、1
// 陀螺仪方差阈值,以允许启动瞬间的正常抖动,但仍能过滤掉混乱的、非滑雪的晃动。
#define START_GYR_VARIANCE_THRESHOLD 15.0f
// --- --- ---
// --- 滑雪过程 ---
//加速度 模长(不含重力),低于此值视为 在做匀速运动
#define SKIING_ACC_MAG_THRESHOLD 0.5f
//陀螺仪 模长,高于此值视为 摔倒了
#define FALLEN_GRY_MAG_THRESHOLD 2000.0f //未确定
// --- --- ---
// --- 原地旋转抖动 ---
// 加速度 方差 阈值。此值比 静止检测 阈值更宽松,
#define WOBBLE_ACC_VARIANCE_THRESHOLD 0.5f
// 加速度 模长 阈值
#define WOBBLE_ACC_MAG_THRESHOLD 1.0f
// 角速度 总模长 大于此值(度/秒),认为正在进行非滑雪的旋转或摆动
#define ROTATION_GYR_MAG_THRESHOLD 30.0f
// --- --- ---
// --- 滑雪转弯动 ---
// 加速度 方差 阈值,大于此值,滑雪过程可能发生了急转弯
#define WHEEL_ACC_VARIANCE_THRESHOLD 7.0f
// 角速度 总模长 大于此值(度/秒),认为滑雪过程中进行急转弯
#define WHEEL_GYR_MAG_THRESHOLD 500.0f //
// --- --- ---
// --- 跳跃 ---
// 加速度模长低于此值(g),认为进入失重状态(IN_AIR)
#define AIRBORNE_ACC_MAG_LOW_THRESHOLD 0.4f
// 加速度模长高于此值(g),认为发生落地冲击(LANDING)
#define LANDING_ACC_MAG_HIGH_THRESHOLD 3.5f
// 起跳加速度阈值(g)用于进入TAKING_OFF状态
#define TAKEOFF_ACC_MAG_HIGH_THRESHOLD 1.8f
// 进入空中状态确认计数需要连续3个采样点加速度低于阈值才判断为起跳
#define AIRBORNE_CONFIRM_COUNT 3
// 落地状态确认计数加速度恢复到1g附近并持续2个采样点(20ms)则认为已落地
#define GROUNDED_CONFIRM_COUNT 2
// 最大滞空时间(秒),超过此时间强制认为已落地,防止状态锁死
#define MAX_TIME_IN_AIR 12.5f
// --- --- ---
// --- 用于消除积分漂移的滤波器和阈值 ---
// 高通滤波器系数 (alpha)。alpha 越接近1滤除低频(直流偏移)的效果越强,但可能滤掉真实的慢速运动。
// alpha = RC / (RC + dt)参考RC电路而来fc ≈ (1 - alpha) / (2 * π * dt)
#define HPF_ALPHA 0.999f
//0.995f 0.08 Hz 的信号
//0.999f 0.0159 Hz
// --- --- ---
// --- 低通滤波器 ---
// 低通滤波器系数 (alpha)。alpha 越小,滤波效果越强(更平滑),但延迟越大。
// alpha 推荐范围 0.7 ~ 0.95。可以从 0.85 开始尝试。
#define LPF_ALPHA 0.7f
// 加速度死区阈值 (m/s^2)。低于此阈值的加速度被认为是噪声,不参与积分。
// 设得太高会忽略真实的慢速启动,设得太低则无法有效抑制噪声。
//参考0.2f ~ 0.4f
#define ACC_DEAD_ZONE_THRESHOLD 0.05f
// --- 模拟摩擦力,进行速度衰减 ---
#define SPEED_ATTENUATION 1.0f //暂不模拟
BLE_KS_send_data_t KS_data;
static float quaternion_data[4];
#ifdef XTELL_TEST
debug_t debug1;
@ -53,7 +125,7 @@ void stop_detection(void){
}
/**
* @brief 初始化
* @brief 初始化滑雪追踪器
*
* @param tracker
*/
@ -67,6 +139,18 @@ void skiing_tracker_init(skiing_tracker_t *tracker)
tracker->state = STATIC;
}
/**
* @brief 当检测到落地时,计算空中的水平飞行距离并累加到总距离
*/
static void calculate_air_distance(skiing_tracker_t *tracker) {
float horizontal_speed_on_takeoff = sqrtf(
tracker->initial_velocity_on_takeoff[0] * tracker->initial_velocity_on_takeoff[0] +
tracker->initial_velocity_on_takeoff[1] * tracker->initial_velocity_on_takeoff[1]
);
float distance_in_air = horizontal_speed_on_takeoff * tracker->time_in_air;
tracker->distance += distance_in_air;
}
/**
@ -93,7 +177,7 @@ void q_remove_gravity_with_quaternion(const float *acc_device, const float *q, f
}
/**
* @brief 使用四元数将设备坐标系的线性加速度转换到世界坐标系,并且移除重力分量
* @brief 使用四元数将设备坐标系的线性加速度转换到世界坐标系
* @details 同样,此方法比使用欧拉角更优。
* @param acc_linear_device 输入:设备坐标系下的线性加速度 [x, y, z]
* @param q 输入:表示姿态的四元数 [w, x, y, z]
@ -117,6 +201,208 @@ void q_transform_to_world_with_quaternion(const float *acc_linear_device, const
}
/**
* @brief 计算缓冲区内三轴数据的方差之和
*
* @param buffer 传进来的三轴数据:陀螺仪/加速度
* @return float 返回方差和
*/
static float calculate_variance(float buffer[VARIANCE_BUFFER_SIZE][3])
{
float mean[3] = {0};
float variance[3] = {0};
// 计算均值
for (int i = 0; i < VARIANCE_BUFFER_SIZE; i++) {
mean[0] += buffer[i][0];
mean[1] += buffer[i][1];
mean[2] += buffer[i][2];
}
mean[0] /= VARIANCE_BUFFER_SIZE;
mean[1] /= VARIANCE_BUFFER_SIZE;
mean[2] /= VARIANCE_BUFFER_SIZE;
// 计算方差
for (int i = 0; i < VARIANCE_BUFFER_SIZE; i++) {
variance[0] += (buffer[i][0] - mean[0]) * (buffer[i][0] - mean[0]);
variance[1] += (buffer[i][1] - mean[1]) * (buffer[i][1] - mean[1]);
variance[2] += (buffer[i][2] - mean[2]) * (buffer[i][2] - mean[2]);
}
variance[0] /= VARIANCE_BUFFER_SIZE;
variance[1] /= VARIANCE_BUFFER_SIZE;
variance[2] /= VARIANCE_BUFFER_SIZE;
// 返回三轴方差之和,作为一个综合的稳定度指标
return variance[0] + variance[1] + variance[2];
}
/**
* @brief 摩擦力模拟,进行速度衰减
*
* @param tracker
*/
void forece_of_friction(skiing_tracker_t *tracker){
// 增加速度衰减,模拟摩擦力
tracker->velocity[0] *= SPEED_ATTENUATION;
tracker->velocity[1] *= SPEED_ATTENUATION;
tracker->velocity[2] = 0; // 垂直速度强制归零
}
/**
* @brief 状态机更新
*
* @param tracker 传入同步修改后传出
* @param acc_device_ms2 三轴加速度m/s^2
* @param gyr_dps 三轴陀螺仪dps
*/
static void update_state_machine(skiing_tracker_t *tracker, const float *acc_device_ms2, const float *gyr_dps)
{
// 缓冲区未填满时,不进行状态判断,默认为静止
if (!tracker->buffer_filled) {
tracker->state = STATIC;
return;
}
// --- 计算关键指标 ---
float acc_variance = calculate_variance(tracker->acc_buffer); // 计算加速度方差
float gyr_variance = calculate_variance(tracker->gyr_buffer); // 计算陀螺仪方差
float gyr_magnitude = sqrtf(gyr_dps[0]*gyr_dps[0] + gyr_dps[1]*gyr_dps[1] + gyr_dps[2]*gyr_dps[2]); //dps
float acc_magnitude = sqrtf(acc_device_ms2[0]*acc_device_ms2[0] + acc_device_ms2[1]*acc_device_ms2[1] + acc_device_ms2[2]*acc_device_ms2[2]); //m/s^s
float acc_magnitude_g = acc_magnitude / G_ACCELERATION; // 转换为g单位用于跳跃判断
#ifdef XTELL_TEST
debug1.acc_variance =acc_variance;
debug1.gyr_variance =gyr_variance;
debug1.gyr_magnitude=gyr_magnitude;
debug1.acc_magnitude=fabsf(acc_magnitude - G_ACCELERATION);
#endif
// --- 状态机逻辑 (核心修改区域) ---
#if 0 //暂时不考虑空中
// 1. 空中/落地状态的后续处理
if (tracker->state == IN_AIR) {
// A. 检测巨大冲击 -> 落地
if (acc_magnitude_g > LANDING_ACC_MAG_HIGH_THRESHOLD) {
tracker->state = LANDING;
// B. 检测超时 -> 强制落地 (安全机制)
} else if (tracker->time_in_air > MAX_TIME_IN_AIR) {
tracker->state = LANDING;
// C. 检测恢复正常重力 (平缓落地)
} else if (acc_magnitude_g > 0.8f && acc_magnitude_g < 1.5f) {
tracker->grounded_entry_counter++;
if (tracker->grounded_entry_counter >= GROUNDED_CONFIRM_COUNT) {
tracker->state = LANDING;
}
} else {
tracker->grounded_entry_counter = 0;
}
return; // 在空中或刚切换到落地,结束本次状态判断
}
// 2. 严格的 "起跳->空中" 状态转换逻辑
// 只有当处于滑行状态时,才去检测起跳意图
if (tracker->state == NO_CONSTANT_SPEED || tracker->state == CONSTANT_SPEED || tracker->state == WHEEL) {
if (acc_magnitude_g > TAKEOFF_ACC_MAG_HIGH_THRESHOLD) {
tracker->state = TAKING_OFF;
tracker->airborne_entry_counter = 0; // 准备检测失重
return;
}
}
// 只有在TAKING_OFF状态下才去检测是否进入失重
if (tracker->state == TAKING_OFF) {
if (acc_magnitude_g < AIRBORNE_ACC_MAG_LOW_THRESHOLD) {
tracker->airborne_entry_counter++;
if (tracker->airborne_entry_counter >= AIRBORNE_CONFIRM_COUNT) {
memcpy(tracker->initial_velocity_on_takeoff, tracker->velocity, sizeof(tracker->velocity));
tracker->time_in_air = 0;
tracker->state = IN_AIR;
tracker->airborne_entry_counter = 0;
tracker->grounded_entry_counter = 0;
return;
}
} else {
// 如果在起跳冲击后一段时间内没有失重,说明只是一个颠簸,恢复滑行
// 可以加一个小的超时计数器,这里为了简单先直接恢复
tracker->state = NO_CONSTANT_SPEED;
}
return; // 无论是否切换,都结束本次判断
}
#endif
// --- 静止判断 ---
if (acc_variance < STOP_ACC_VARIANCE_THRESHOLD && gyr_variance < STOP_GYR_VARIANCE_THRESHOLD && gyr_magnitude < STOP_GYR_MAG_THRESHOLD) {
tracker->state = STATIC;
return;
}
// --- 地面状态切换逻辑 ---
switch (tracker->state) {
case LANDING:
tracker->state = STATIC;
break;
case STATIC:
// 优先判断是否进入 WOBBLE 状态
// 条件:陀螺仪活动剧烈,但整体加速度变化不大(说明是原地转或晃)
if (gyr_magnitude > ROTATION_GYR_MAG_THRESHOLD && fabsf(acc_magnitude - G_ACCELERATION) < WOBBLE_ACC_MAG_THRESHOLD) {
tracker->state = WOBBLE;
}
// 只有在陀螺仪和加速度都满足“前进”特征时,才启动
else if (gyr_variance > START_GYR_VARIANCE_THRESHOLD && fabsf(acc_magnitude - G_ACCELERATION) > START_ACC_MAG_THRESHOLD) {
tracker->state = NO_CONSTANT_SPEED;
}
break;
case WOBBLE:
// 从 WOBBLE 状态启动的条件应该和从 STATIC 启动一样严格
if (gyr_variance < START_GYR_VARIANCE_THRESHOLD * 2 && fabsf(acc_magnitude - G_ACCELERATION) > START_ACC_MAG_THRESHOLD) {
tracker->state = NO_CONSTANT_SPEED;
}
// 如果陀螺仪活动减弱,则可能恢复静止
else if (gyr_magnitude < ROTATION_GYR_MAG_THRESHOLD * 0.8f) { // 增加迟滞,避免抖动
// 不直接跳回STATIC而是依赖下一轮的全局静止判断
}
break;
case NO_CONSTANT_SPEED: //非匀速状态
//暂时不考虑摔倒
// if (gyr_magnitude > FALLEN_GRY_MAG_THRESHOLD) {
// tracker->state = FALLEN; //摔倒
// } else
if (gyr_magnitude > WHEEL_GYR_MAG_THRESHOLD && acc_variance > WHEEL_ACC_VARIANCE_THRESHOLD) {
tracker->state = WHEEL; //转弯
} else if (fabsf(acc_magnitude - G_ACCELERATION) < SKIING_ACC_MAG_THRESHOLD) {
tracker->state = CONSTANT_SPEED; //匀速
}
break;
case CONSTANT_SPEED: //匀速状态
if (fabsf(acc_magnitude - G_ACCELERATION) > START_ACC_MAG_THRESHOLD) {
tracker->state = NO_CONSTANT_SPEED;
}
//TODO可以添加进入转弯或摔倒的判断
break;
case WHEEL:
// 从转弯状态,检查转弯是否结束
// 如果角速度和加速度方差都降下来了,就回到普通滑行状态
if (gyr_magnitude < WHEEL_GYR_MAG_THRESHOLD * 0.8f && acc_variance < WHEEL_ACC_VARIANCE_THRESHOLD * 0.8f) { // 乘以一个滞后系数避免抖动
tracker->state = NO_CONSTANT_SPEED;
}
break;
case FALLEN:
// TODO回到 STATIC
break;
}
}
/**
* @brief 主更新函数
*
@ -140,46 +426,140 @@ void skiing_tracker_update(skiing_tracker_t *tracker, float *acc_g, float *gyr_d
acc_device_ms2[1] = acc_g[1] * G_ACCELERATION;
acc_device_ms2[2] = acc_g[2] * G_ACCELERATION;
#if 1 //测试禁止状态下陀螺仪的三轴加速度,去掉重力分量后是否正常
float tmp_device_acc[3];
float tmp_world_acc[3];
// remove_gravity_in_device_frame(acc_device_ms2,angle,tmp_device_acc);
// transform_acc_to_world_frame(acc_device_ms2,angle,tmp_world_acc);
// 将最新数据存入缓冲区
memcpy(tracker->acc_buffer[tracker->buffer_index], acc_device_ms2, sizeof(acc_device_ms2));
memcpy(tracker->gyr_buffer[tracker->buffer_index], gyr_dps, 3 * sizeof(float));
q_remove_gravity_with_quaternion(acc_device_ms2,quaternion_data,tmp_device_acc);
q_transform_to_world_with_quaternion(tmp_device_acc,quaternion_data,tmp_world_acc);
tracker->buffer_index++;
if (tracker->buffer_index >= VARIANCE_BUFFER_SIZE) {
tracker->buffer_index = 0;
tracker->buffer_filled = 1; // 标记缓冲区已满
}
// --- 更新状态机 ---
update_state_machine(tracker, acc_device_ms2, gyr_dps);
// --- 根据状态执行不同的计算逻辑 ---
switch (tracker->state) {
case TAKING_OFF:
tracker->speed = 0.0f;
break;
case IN_AIR:
// 在空中时,只累加滞空时间
tracker->time_in_air += dt;
break;
case LANDING:
// 刚落地,计算空中距离
calculate_air_distance(tracker);
// 清理速度和滤波器状态,为恢复地面追踪做准备
memset(tracker->velocity, 0, sizeof(tracker->velocity));
tracker->speed = 0;
memset(tracker->acc_world_unfiltered_prev, 0, sizeof(tracker->acc_world_unfiltered_prev));
memset(tracker->acc_world_filtered, 0, sizeof(tracker->acc_world_filtered));
memset(tracker->acc_world_lpf, 0, sizeof(tracker->acc_world_lpf)); // 清理新增的LPF状态
break;
case WHEEL:
case NO_CONSTANT_SPEED:
float linear_acc_device[3];
float linear_acc_world[3];
// 在设备坐标系下,移除重力,得到线性加速度
q_remove_gravity_with_quaternion(acc_device_ms2, quaternion_data, linear_acc_device);
// 将设备坐标系下的线性加速度,旋转到世界坐标系
q_transform_to_world_with_quaternion(linear_acc_device, quaternion_data, linear_acc_world);
// 将最终用于积分的加速度存入 tracker 结构体
memcpy(tracker->acc_no_g, linear_acc_world, sizeof(linear_acc_world));
float acc_world_temp[3]; // 临时变量存储当前周期的加速度
for (int i = 0; i < 2; i++) { // 只处理水平方向的 x 和 y 轴
// --- 核心修改:颠倒滤波器顺序为 HPF -> LPF ---
// 1. 高通滤波 (HPF) 先行: 消除因姿态误差导致的重力泄漏(直流偏置)
// HPF的瞬态响应会产生尖峰这是正常的。
tracker->acc_world_filtered[i] = HPF_ALPHA * (tracker->acc_world_filtered[i] + tracker->acc_no_g[i] - tracker->acc_world_unfiltered_prev[i]);
tracker->acc_world_unfiltered_prev[i] = tracker->acc_no_g[i];
// 2. 低通滤波 (LPF) 殿后: 平滑掉HPF产生的尖峰和传感器自身的高频振动噪声。
// 这里使用 tracker->acc_world_filtered[i] 作为LPF的输入。
tracker->acc_world_lpf[i] = (1.0f - LPF_ALPHA) * tracker->acc_world_filtered[i] + LPF_ALPHA * tracker->acc_world_lpf[i];
// 将最终处理完的加速度值存入临时变量
acc_world_temp[i] = tracker->acc_world_lpf[i];
}
// 计算处理后加速度的水平模长
float all_device_mag = sqrtf(tmp_device_acc[0] * tmp_device_acc[0] +
tmp_device_acc[1] * tmp_device_acc[1] +
tmp_device_acc[2] * tmp_device_acc[2]);
float acc_horizontal_mag = sqrtf(acc_world_temp[0] * acc_world_temp[0] +
acc_world_temp[1] * acc_world_temp[1]);
#if XTELL_TEST
debug2.acc_magnitude = acc_horizontal_mag;
#endif
// 应用死区,并积分
if (acc_horizontal_mag > ACC_DEAD_ZONE_THRESHOLD) {
tracker->velocity[0] += acc_world_temp[0] * dt;
tracker->velocity[1] += acc_world_temp[1] * dt;
}
// 更新速度和距离
tracker->speed = sqrtf(tracker->velocity[0] * tracker->velocity[0] +
tracker->velocity[1] * tracker->velocity[1]);
tracker->distance += tracker->speed * dt;
break;
case CONSTANT_SPEED:
//保持上次的速度不变。只更新距离
tracker->distance += tracker->speed * dt;
break;
case STATIC:
case WOBBLE:
// 速度清零,抑制漂移
memset(tracker->velocity, 0, sizeof(tracker->velocity));
tracker->speed = 0.0f;
memset(tracker->acc_world_unfiltered_prev, 0, sizeof(tracker->acc_world_unfiltered_prev));
memset(tracker->acc_world_filtered, 0, sizeof(tracker->acc_world_filtered));
memset(tracker->acc_world_lpf, 0, sizeof(tracker->acc_world_lpf)); // 清理新增的LPF状态
#if XTELL_TEST
debug2.acc_magnitude = 0;
#endif
break;
case FALLEN:
// TODO
break;
default:
break;
}
#if 1
float linear_acc_device[3];
float linear_acc_world[3];
float tmp_world_acc[3];
// 在设备坐标系下,移除重力,得到线性加速度
q_remove_gravity_with_quaternion(acc_device_ms2, quaternion_data, linear_acc_device);
// 将设备坐标系下的线性加速度,旋转到世界坐标系
q_transform_to_world_with_quaternion(linear_acc_device, quaternion_data, tmp_world_acc);
float all_world_mag = sqrtf(tmp_world_acc[0] * tmp_world_acc[0] +
tmp_world_acc[1] * tmp_world_acc[1] +
tmp_world_acc[2] * tmp_world_acc[2]);
float gx_proj = 2.0f * (quaternion_data[1] * quaternion_data[3] - quaternion_data[0] * quaternion_data[2]);
float gy_proj = 2.0f * (quaternion_data[0] * quaternion_data[1] + quaternion_data[2] * quaternion_data[3]);
float gz_proj = quaternion_data[0] * quaternion_data[0] - quaternion_data[1] * quaternion_data[1] - quaternion_data[2] * quaternion_data[2] + quaternion_data[3] * quaternion_data[3];
static int count = 0;
if(count > 100){
xlog("===original(g): x %.2f, y %.2f, z %.2f===\n",acc_g[0],acc_g[1],acc_g[2]);
xlog("===device(m/s^2) no g: x %.2f, y %.2f, z %.2f, all %.2f===\n",tmp_device_acc[0],tmp_device_acc[1],tmp_device_acc[2],all_device_mag);
xlog("===world(m/s^2) no g: x %.2f, y %.2f, z %.2f, all %.2f===\n",tmp_world_acc[0],tmp_world_acc[1],tmp_world_acc[2],all_world_mag);
xlog("===gyr(dps) : x %.2f, y %.2f, z %.2f, all %.2f===\n",gyr_dps[0],gyr_dps[1],gyr_dps[2]); //angle
xlog("===world(m/s^2) no g: x %.2f, y %.2f, z %.2f, all %.2f===\n",tmp_world_acc[0],tmp_world_acc[1],tmp_world_acc[2],all_world_mag); //去掉重力加速度
xlog("===gyr(dps) : x %.2f, y %.2f, z %.2f===\n",gyr_dps[0],gyr_dps[1],gyr_dps[2]); //angle
xlog("===angle : x %.2f, y %.2f, z %.2f,===\n",angle[0],angle[1],angle[2]);
xlog("GRAVITY VECTOR in device frame: gx=%.2f, gy=%.2f, gz=%.2f\n", gx_proj, gy_proj, gz_proj);
extern mmc5603nj_cal_data_t cal_data;
xlog("cal_data:X: %.4f, Y: %.4f, Z: %.4f\n", cal_data.offset_x,cal_data.offset_y,cal_data.offset_z);
xlog("===speed(cm/s): %d\n",(int)(tracker->speed*100) );
count = 0;
}
count++;
#endif
}
@ -190,13 +570,14 @@ void skiing_tracker_update(skiing_tracker_t *tracker, float *acc_g, float *gyr_d
* @param acc_data_buf 传入的三轴加速度数据
* @param gyr_data_buf 传入的三轴陀螺仪数据
* @param angle_data 传入的欧若拉角数据
* @return BLE_send_data_t 要发送给蓝牙的数据
* @return 速度cm/s
*/
BLE_send_data_t sensor_processing_task(signed short* acc_data_buf, signed short* gyr_data_buf, float* angle_data, float* quaternion) {
uint16_t sensor_processing_task(signed short* acc_data_buf, signed short* gyr_data_buf, float* angle_data, float* quaternion) {
static int initialized = 0;
static float acc_data_g[3];
static float gyr_data_dps[3];
if(quaternion != NULL){
memcpy(quaternion_data, quaternion, 4 * sizeof(float));
}
@ -204,7 +585,6 @@ BLE_send_data_t sensor_processing_task(signed short* acc_data_buf, signed short*
// const float delta_time = DELTA_TIME+0.01f;
// const float delta_time = DELTA_TIME + 0.005f;
const float delta_time = DELTA_TIME;
BLE_send_data_t BLE_send_data;
if (!initialized) {
skiing_tracker_init(&my_skiing_tracker);
@ -249,22 +629,7 @@ BLE_send_data_t sensor_processing_task(signed short* acc_data_buf, signed short*
skiing_tracker_update(&my_skiing_tracker, acc_data_g, gyr_data_dps, angle_data, delta_time);
// BLE_send_data.skiing_state = my_skiing_tracker.state;
// for (int i = 0; i < 3; i++) {
// #ifdef XTELL_TEST
// BLE_send_data.acc_data[i] = (short)(acc_data_g[i] * 9.8f) * 100; //cm/^s2
// BLE_send_data.gyr_data[i] = (short)gyr_data_dps[i]; //dps
// BLE_send_data.angle_data[i] = angle_data[i];
// #else
// BLE_send_data.acc_data[i] = (short)acc_data_buf[i]; //原始adc数据
// BLE_send_data.gyr_data[i] = (short)gyr_data_buf[i]; //原始adc数据
// BLE_send_data.angle_data[i] = angle_data[i];
// #endif
// }
// BLE_send_data.speed_cms = (int)(my_skiing_tracker.speed * 100);
// BLE_send_data.distance_cm = (int)(my_skiing_tracker.distance * 100);
// // printf("Calculate the time interval =============== end\n");
return BLE_send_data;
return (uint16_t)(my_skiing_tracker.speed * 100);
}

View File

@ -2,6 +2,10 @@
#define SKIING_TRACKER_H
#include "../xtell.h"
#include <math.h>
#include <string.h>
// 定义滑雪者可能的状态
typedef enum {
STATIC, // 静止或动态稳定0
@ -30,7 +34,7 @@ typedef struct {
skiing_state_t state; // 当前滑雪状态
// 内部计算使用的私有成员
float acc_world[3]; // 在世界坐标系下的加速度
float acc_no_g[3]; // 去掉重力分量后的加速度
// 用于空中距离计算
float time_in_air; // 滞空时间计时器
@ -52,16 +56,7 @@ typedef struct {
float acc_world_lpf[3]; // 经过低通滤波后的世界坐标系加速度
} skiing_tracker_t;
//ble发送的数据
typedef struct{ //__attribute__((packed)){ //该结构体取消内存对齐
char sensor_state;
char skiing_state;
int speed_cms; //求出的速度cm/s
int distance_cm; //求出的距离cm
short acc_data[3]; //三轴加速度, g
short gyr_data[3]; //三轴陀螺仪, dps
float angle_data[3]; //欧若拉角
}BLE_send_data_t;
typedef struct{
int acc_KS[3]; //卡尔曼后LSB转换后的 三轴加速度数据cm/s^2
@ -84,5 +79,5 @@ typedef struct{
*/
void skiing_tracker_init(skiing_tracker_t *tracker);
BLE_send_data_t sensor_processing_task(signed short* acc_data_buf, signed short* gyr_data_buf, float* angle_data, float* quaternion);
uint16_t sensor_processing_task(signed short* acc_data_buf, signed short* gyr_data_buf, float* angle_data, float* quaternion);
#endif // SKIING_TRACKER_H

View File

@ -6,6 +6,8 @@
#include "tone_player.h"
#include "ui_manage.h"
#include "gpio.h"
#include <math.h>
#include <string.h>
#include "app_main.h"
#include "asm/charge.h"
#include "update.h"
@ -24,6 +26,11 @@
#include "./sensor/MMC56.h"
#include "./sensor/BMP280.h"
#include "./sensor/AK8963.h"
#include "./sensor/WF282A.h"
#include "asm/rtc.h"
#include "system/timer.h"
#include "adv_time_stamp_setting.h"
#include "btstack/le/le_user.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
//宏定义
#define ENABLE_XLOG 1
@ -35,6 +42,12 @@
#else
#define xlog(format, ...) ((void)0)
#endif
#define SENSOR_DATA_BUFFER_SIZE 200 // 定义缓冲区可以存储XXX个sensor_data_t元素
#define MPU_FIFO_INTERVAL 4 //隔多久读取六轴fifo单位10ms
#define MPU_FIFO_LEN 16 //(MPU_FIFO_INTERVAL*10/2.5) //400hz采用频率那每40ms的时间fifo就有16组六轴数据
//
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -42,555 +55,433 @@
//START -- 函数定义
void send_data_to_ble_client(const u8* data, u16 length);
extern void create_process(u16* pid, const char* name, void *priv, void (*func)(void *priv), u32 msec);
extern void close_process(u16* pid,char* name);
void BLE_send_fuc(void);
//END -- 函数定义
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//START -- 变量定义
static u32 timer_offset_ms = 0;
// --- 任务ID ---
static u16 xtell_i2c_test_id;
static u16 collect_data_id;
static u16 ble_send_data_id;
static u16 sensor_read_data_id;
static u16 calculate_data_id;
typedef struct{
signed short SC7U22_data[6]; //12字节
int mmc5603nj_buffer[3]; //12字节
int16_t temperature; //2
uint32_t pressure; //4
}sensor_package_t __attribute__((packed));
typedef struct{
uint8_t checkout_1;
uint8_t checkout_2;
uint8_t foot; //1左脚2右脚
uint8_t package_index;
sensor_package_t sensor_package[MPU_FIFO_LEN];//一次蓝牙发送MPU_FIFO_LEN组传感器数据
}ble_send_data_t; //一次蓝牙发送的数据内容
// --- 环形缓冲区 ---
#define SENSOR_DATA_BUFFER_SIZE 512
static u8 sensor_data_buffer[SENSOR_DATA_BUFFER_SIZE];
static circle_buffer_t sensor_cb;
static circle_buffer_t g_ble_send_cb; // 环形缓冲区管理结构体
static ble_send_data_t g_sensor_data_storage[SENSOR_DATA_BUFFER_SIZE]; //缓冲区
static int count = 0;
extern u8 foot_init;
static OS_SEM receiver_ready_sem; // 用于启动同步的信号量
//--- test ---
// 全局变量
u16 gsensor_id=0;
u16 test_id=0;
static const uart_bus_t *uart_bus = NULL;
static u16 test_id = 0;
//END -- 变量定义
//////////////////////////////////////////////////////////////////////////////////////////////////
#if 0
BLE_send_data_t BLE_send_data;
void test(){
signed short acc_data_buf[3] = {0};
signed short gyr_data_buf[3] = {0};
signed short acc_gyro_input[6] = {0};
float Angle_output[3] = {0};
// xlog("============start\n");
SL_SC7U22_RawData_Read(acc_data_buf,gyr_data_buf);
BLE_send_data = sensor_processing_task(acc_data_buf, gyr_data_buf);
u8 data[50];
data[0] = 0xBB;
data[1] = 0xBE;
data[2] = 0x01;
data[3] = sizeof(BLE_send_data_t); //后续包的数据长度
// send_data_to_ble_client(&data,sizeof(BLE_send_data_t)+4);
memcpy(&data[4], &BLE_send_data, sizeof(BLE_send_data_t));
static int count = 0;
if(count >=10){
count = 0;
char* division = "==========\n";
send_data_to_ble_client(division,strlen(division));
char log_buffer[100]; // 100个字符应该足够了
// 使用 snprintf 进行格式化
int num_chars_written = snprintf(
log_buffer, // 目标缓冲区
sizeof(log_buffer), // 目标缓冲区的最大容量
"s %d, %dcm/s, %dcm\n", // 格式化字符串
BLE_send_data.skiing_state, // 第一个 %d 的参数
BLE_send_data.speed_cms, // 第二个 %d 的参数
BLE_send_data.distance_cm // 第三个 %d 的参数
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
extern BLE_KS_send_data_t KS_data;
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"Acc:%d, %d, %d\n",
KS_data.acc_KS[0],KS_data.acc_KS[1],KS_data.acc_KS[2]
); // cm/s^2
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"Gyr_dps:%d, %d, %d\n",
KS_data.gyr_KS_dps[0],
KS_data.gyr_KS_dps[1],
KS_data.gyr_KS_dps[2]
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"angle: %d, %d, %d\n",
KS_data.angle_KS[0],
KS_data.angle_KS[1],
KS_data.angle_KS[2]
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
extern debug_t debug1;
extern debug_t debug2;
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"debug:%.2f,%.2f,%.2f(%.2f),%.2f\n",
debug1.acc_variance,
debug1.gyr_variance,
debug1.acc_magnitude,
debug2.acc_magnitude, //滤波后的加速度
debug1.gyr_magnitude
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
xlog("Call interval\n");
}
count++;
memset(&BLE_send_data, 0, sizeof(BLE_send_data_t));
memset(&data, 0, 50);
// xlog("end============\n");
// 重置计时器
void reset_ms_timer(void) {
timer_offset_ms = sys_timer_get_ms();
xlog("Timer has been reset.\n");
}
// 获取从上次重置后经过的毫秒数
u32 get_ms_timer(void) {
return sys_timer_get_ms() - timer_offset_ms;
}
#endif
#define SENSOR_DATA_BUFFER_SIZE 500 // 定义缓冲区可以存储100个sensor_data_t元素
static circle_buffer_t sensor_read; // 环形缓冲区管理结构体
typedef struct {
signed short acc_data[3];
signed short gyr_data[3];
float angle[3]; //pitch roll yaw
float quaternion_output[4]; //四元数数据
} sensor_data_t;
static sensor_data_t sensor_read_buffer[SENSOR_DATA_BUFFER_SIZE]; // 存放sensor读到的数据
static circle_buffer_t sensor_send; // 环形缓冲区管理结构体
static BLE_send_data_t sensor_send_buffer[SENSOR_DATA_BUFFER_SIZE]; // 存放ble要发送的数据
static u8 mutex1 = 0;
static u8 mutex2 = 0;
static int count_test1 = 0;
static int count_test2 = 0;
/**
* @brief //读取传感器的数据放进缓冲区
* @brief 传感器采集任务
*
*/
void sensor_read_data(){
void sensor_collect_task(void){
static ble_send_data_t send_data;
mmc5603nj_mag_data_t mmc5603nj_buffer;
float temperature = 0;
float pressure = 0;
int interval = 0;
signed short accx_buf[100];
signed short accy_buf[100];
signed short accz_buf[100];
signed short gyrx_buf[100];
signed short gyry_buf[100];
signed short gyrz_buf[100];
int fifo_num = 0;
static int SL_data_index = 0;
u8 package_index = 1;
int tmp_index = 0;
// xlog("=======sensor_read_data START\n");
static signed short combined_raw_data[6];
static int initialized = 0;
static int calibration_done = 0;
char status = 0;
if(circle_buffer_is_full(&sensor_read)){
// xlog("sensor_read_data: read buffer full\n");
return;
while(1){//4组地磁数据、16组六轴数据、1组气压计数据
interval++;
mmc5603nj_read_mag_data(&mmc5603nj_buffer); //地磁的采样率为100Hz每10ms读一次
for(int i = (interval-1)*4; i < interval*4; i++){
send_data.sensor_package[i].mmc5603nj_buffer[0] = (int32_t)(mmc5603nj_buffer.x * 1000.0f);
send_data.sensor_package[i].mmc5603nj_buffer[1] = (int32_t)(mmc5603nj_buffer.y * 1000.0f);
send_data.sensor_package[i].mmc5603nj_buffer[2] = (int32_t)(mmc5603nj_buffer.z * 1000.0f);
}
// xlog("MAG x: %.2f,y: %.2f,z: %.2f\n",mmc5603nj_buffer.x,mmc5603nj_buffer.y,mmc5603nj_buffer.z);
static sensor_data_t tmp;
SL_SC7U22_RawData_Read(tmp.acc_data,tmp.gyr_data);
// xlog("=======sensor_read_data middle 1\n");
memcpy(&combined_raw_data[0], tmp.acc_data, 3 * sizeof(signed short));
memcpy(&combined_raw_data[3], tmp.gyr_data, 3 * sizeof(signed short));
SL_SC7U22_FIFO_Read(accx_buf,accy_buf,accz_buf,gyrx_buf,gyry_buf,gyrz_buf); //一次性读取内置fifo的数据
for(int i = 0; i < MPU_FIFO_LEN/4; i++){
tmp_index = SL_data_index + i;
// if(tmp_index >= MPU_FIFO_LEN-1) tmp_index = MPU_FIFO_LEN-1;
send_data.sensor_package[tmp_index].SC7U22_data[0] = accx_buf[i]; //acc_x
send_data.sensor_package[tmp_index].SC7U22_data[1] = accy_buf[i]; //acc_y
send_data.sensor_package[tmp_index].SC7U22_data[2] = accz_buf[i]; //acc_z
send_data.sensor_package[tmp_index].SC7U22_data[3] = gyrx_buf[i]; //gyr_x
send_data.sensor_package[tmp_index].SC7U22_data[4] = gyry_buf[i]; //gyr_y
send_data.sensor_package[tmp_index].SC7U22_data[5] = gyrz_buf[i]; //gyr_z
if (!calibration_done) { //第1次启动开启零漂检测
// status = SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle, 0);
// status = SIX_SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle, 0);
// status = Original_SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle, 0);
status = Q_SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle,NULL, 0, tmp.quaternion_output);
if(count > 100){
count = 0;
char log_buffer[100]; // 100个字符应该足够了
// snprintf( log_buffer, sizeof(log_buffer),"status:%d\n",status);
// send_data_to_ble_client(&log_buffer,strlen(log_buffer));
xlog("status:%d\n", status);
}
count++;
if (status == 1) {
calibration_done = 1;
printf("Sensor calibration successful! Skiing mode is active.\n");
}
} else {
// printf("Calculate the time interval =============== start\n");
// status = SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle, 0);
// status = SIX_SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle, 0);
// status = Original_SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle, 0);
status = Q_SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle,NULL, 0, tmp.quaternion_output);
memcpy(tmp.acc_data, &combined_raw_data[0], 3 * sizeof(signed short));
memcpy(tmp.gyr_data, &combined_raw_data[3], 3 * sizeof(signed short));
if(mutex1 == 0){
mutex1 = 1;
// count_test1++;
// xlog("count_test_1: %d\n",count_test1);
circle_buffer_write(&sensor_read, &tmp);
mutex1 = 0;
}
extern void ano_send_attitude_data(float rol, float pit, float yaw, uint8_t fusion_sta) ;
ano_send_attitude_data(tmp.angle[0],tmp.angle[1],tmp.angle[2], 1);
}
// xlog("=======sensor_read_data END\n");
}
void calculate_data(){
// xlog("=======start\n");
sensor_data_t tmp;
if(circle_buffer_is_empty(&sensor_read)){
// xlog("sensor_read_buffer: read buffer empty\n");
return;
}
if(mutex1 == 0){
mutex1 = 1;
circle_buffer_read(&sensor_read, &tmp);
mutex1 = 0;
}else{
return;
}
BLE_send_data_t data_by_calculate = sensor_processing_task(tmp.acc_data, tmp.gyr_data,tmp.angle,tmp.quaternion_output);
if(circle_buffer_is_full(&sensor_send))
return;
if(mutex2 == 0){
mutex2 = 1;
circle_buffer_write(&sensor_send, &data_by_calculate);
mutex2 = 0;
}
// extern void BLE_send_data();
// BLE_send_data();
// xlog("=======end\n");
}
extern char xt_Check_Flag;
void BLE_send_data(){
// xlog("=======start\n");
if(circle_buffer_is_empty(&sensor_send)){
// xlog("sensor_send_buffer: send buffer empty\n");
return;
}
#ifdef XTELL_TEST
// #if 0
BLE_send_data_t tmp;
if(mutex2 == 0){
mutex2 = 1;
circle_buffer_read(&sensor_send, &tmp);
mutex2 = 0;
}else{
return;
}
if(count >=100){
// extern debug_t debug2;
// xlog("s %d, %dcm/s, %dcm\n",tmp.skiing_state, tmp.speed_cms, tmp.distance_cm);
// xlog("Acc:%d, %d, %d\n",tmp.acc_data[0],tmp.acc_data[1],tmp.acc_data[2]);
// xlog("Gyr:%d, %d, %d\n", tmp.gyr_data[0],tmp.gyr_data[1],tmp.gyr_data[2]);
// xlog("debug2.acc_magnitude:%.2f\n", debug2.acc_magnitude);
int num_chars_written;
count = 0;
char* division = "==========\n";
send_data_to_ble_client(division,strlen(division));
char log_buffer[100]; // 100个字符应该足够了
// extern char iic_read_len;
// extern char iic_write_result;
// num_chars_written = snprintf(log_buffer, sizeof(log_buffer),"SL_SC7U22_Check=0x%d, %d, %d\n", xt_Check_Flag, iic_read_len, iic_write_result);
// send_data_to_ble_client(&log_buffer,strlen(log_buffer));
memset(&log_buffer, 0, 100);
#if 1
// 使用 snprintf 进行格式化
num_chars_written = snprintf(
log_buffer, // 目标缓冲区
sizeof(log_buffer), // 目标缓冲区的最大容量
"s %d, %dcm/s, %dcm\n", // 格式化字符串
tmp.skiing_state, // 第一个 %d 的参数
tmp.speed_cms, // 第二个 %d 的参数
tmp.distance_cm // 第三个 %d 的参数
);
send_data_to_ble_client(&log_buffer, strlen(log_buffer));
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"Acc:%d, %d, %d\n",
tmp.acc_data[0],tmp.acc_data[1],tmp.acc_data[2]
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"Gyr:%d, %d, %d\n",
tmp.gyr_data[0],tmp.gyr_data[1],tmp.gyr_data[2]
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"Angle:%.1f, %.1f, %1.f\n",
tmp.angle_data[0],tmp.angle_data[1],tmp.angle_data[2]
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
// xlog(" Acc_x : %4d, Acc_y : %4d, Acc_z : %4d,\r\n", send_data.sensor_package[tmp_index].SC7U22_data[0], send_data.sensor_package[tmp_index].SC7U22_data[1], send_data.sensor_package[tmp_index].SC7U22_data[2]);
#if 0
float acc_g[3];
float gyr_dps[3];
acc_g[0] = (float)send_data.sensor_package[tmp_index].SC7U22_data[0] / 2048.0f;
acc_g[1] = (float)send_data.sensor_package[tmp_index].SC7U22_data[1] / 2048.0f;
acc_g[2] = (float)send_data.sensor_package[tmp_index].SC7U22_data[2] / 2048.0f;
gyr_dps[0] = (float)send_data.sensor_package[tmp_index].SC7U22_data[3] * 0.061f;
gyr_dps[1] = (float)send_data.sensor_package[tmp_index].SC7U22_data[4] * 0.061f;
gyr_dps[2] = (float)send_data.sensor_package[tmp_index].SC7U22_data[5] * 0.061f;
printf(" ACC(g): x=%.3f, y=%.3f, z=%.3f\n", acc_g[0], acc_g[1], acc_g[2]);
printf(" GYR(dps):x=%.3f, y=%.3f, z=%.3f\n", gyr_dps[0], gyr_dps[1], gyr_dps[2]);
#endif
short acc_mo_cms = sqrtf(tmp.acc_data[0]*tmp.acc_data[0] + tmp.acc_data[1]*tmp.acc_data[1] + tmp.acc_data[2]*tmp.acc_data[2])-900;
memset(&log_buffer, 0, 100);
num_chars_written = snprintf(
log_buffer,
sizeof(log_buffer),
"acc_cm/s^2:%d\n",
acc_mo_cms
);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
// xlog("s %d, %dcm/s, %dcm\n",tmp.skiing_state, tmp.speed_cms, tmp.distance_cm);
// xlog("Acc:%d, %d, %d\n", tmp.acc_data[0],tmp.acc_data[1],tmp.acc_data[2]);
// xlog("GYR:%d, %d, %d\n", tmp.gyr_data[0],tmp.gyr_data[1],tmp.gyr_data[2]);
}
count++;
// xlog("=======end\n");
SL_data_index += MPU_FIFO_LEN/4;
if(interval >= 4){ //40ms
interval = 0;
SL_data_index = 0;
#if BMP280
bmp280_read_data(&temperature, &pressure);//每40ms读取一次高精度的采样率为26.5Hz
#else
WF_GET_Temperature_Pressure(&temperature, &pressure);
#endif
for(int i = 0;i<MPU_FIFO_LEN;i++){
send_data.sensor_package[i].temperature = (int16_t)(temperature * 1000.0f);
send_data.sensor_package[i].pressure = (int32_t)(pressure * 1000.0f);
}
// xlog("temperature: %.2f,pressure: %.2f\n",temperature,pressure);
// xlog("fifo_num:%d\n",fifo_num);
send_data.checkout_1 = 0xBE;
send_data.checkout_2 = 0xBB;
send_data.foot = foot_init;
send_data.package_index = package_index;
circle_buffer_write(&g_ble_send_cb, &send_data);
os_sem_post(&receiver_ready_sem); //通知另一个发送任务
memset(&send_data, 0, sizeof(ble_send_data_t));
memset(&accx_buf, 0, sizeof(accx_buf));
memset(&accy_buf, 0, sizeof(accy_buf));
memset(&accz_buf, 0, sizeof(accz_buf));
memset(&gyrx_buf, 0, sizeof(gyrx_buf));
memset(&gyry_buf, 0, sizeof(gyry_buf));
memset(&gyrz_buf, 0, sizeof(gyrz_buf));
package_index++;
if(package_index >= 0xFF) package_index = 1;
// xlog("=====================%d============================\n",get_ms_timer());
}
os_time_dly(1); //10ms为单位
}
}
void data_log(uint8_t* data){
static u8 imu_airplane[MPU_FIFO_LEN][12];
// 检查数据包头部
if (data[0] != 0xBE || data[1] != 0xBB) {
printf("Error: Invalid data packet header.\n");
return;
}
//左右脚
uint8_t package_foot = data[2];
// 解析包索引
uint8_t package_index = data[3];
printf("--- Parsing Data Packet Index: %d ---\n", package_index);
uint8_t* p = &data[4]; // 指向数据负载的起始位置
// 循环解析16组数据
for (int i = 0; i < MPU_FIFO_LEN; i++) {
// 1. 解析六轴传感器数据 (12 bytes)
int16_t imu_raw[6];
for (int j = 0; j < 6; j++) {
imu_airplane[i][2*j] = p[0];
imu_airplane[i][2*j+1] = p[1];
// 小端模式: 低字节在前, 高字节在后
imu_raw[j] = (int16_t)(((uint16_t)p[1] << 8) | (uint16_t)p[0]);
p += 2;
}
float acc_g[3];
float gyr_dps[3];
acc_g[0] = (float)imu_raw[0] / 2048.0f;
acc_g[1] = (float)imu_raw[1] / 2048.0f;
acc_g[2] = (float)imu_raw[2] / 2048.0f;
gyr_dps[0] = (float)imu_raw[3] * 0.061f;
gyr_dps[1] = (float)imu_raw[4] * 0.061f;
gyr_dps[2] = (float)imu_raw[5] * 0.061f;
// 2. 解析地磁传感器数据 (12 bytes)
int32_t mag_raw[3];
for (int j = 0; j < 3; j++) {
// 小端模式
mag_raw[j] = (int32_t)(((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[0]);
p += 4;
}
float mag_gauss[3];
mag_gauss[0] = (float)mag_raw[0] / 1000.0f;
mag_gauss[1] = (float)mag_raw[1] / 1000.0f;
mag_gauss[2] = (float)mag_raw[2] / 1000.0f;
// 3. 解析温度数据 (2 bytes)
int16_t temp_raw = (int16_t)(((uint16_t)p[1] << 8) | (uint16_t)p[0]);
p += 2;
float temperature = (float)temp_raw / 1000.0f;
// 4. 解析气压数据 (4 bytes)
uint32_t press_raw = (uint32_t)(((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16) | ((uint32_t)p[1] << 8) | (uint32_t)p[0]);
p += 4;
float pressure = (float)press_raw / 1000.0f;
// 打印解析后的数据
if(i % 8 == 0){
printf(" ==================ble index: %d\n", *p);
printf("Package[%d]:\n", i);
printf(" ACC(g): x=%.3f, y=%.3f, z=%.3f\n", acc_g[0], acc_g[1], acc_g[2]);
printf(" GYR(dps):x=%.3f, y=%.3f, z=%.3f\n", gyr_dps[0], gyr_dps[1], gyr_dps[2]);
printf(" MAG(Gs): x=%.3f, y=%.3f, z=%.3f\n", mag_gauss[0], mag_gauss[1], mag_gauss[2]);
printf(" TEMP(C): %.3f, PRESS(Pa): %.3f\n", temperature, pressure);
}
}
// printf("--- End of Packet ---\n\n");
extern void uartSendData(void *buf, u16 len) ; // 确保u16是uint16_t或unsigned short
// uartSendData(imu_airplane, sizeof(imu_airplane));
uartSendData(data, 484); // 发送总共17字节
}
/**
* @brief ble数据发送函数
*
*/
void BLE_send_fuc(void){
ble_send_data_t send_data;
uint8_t send_buffer[484];
while(1){
os_sem_pend(&receiver_ready_sem, 0); //阻塞等待
circle_buffer_read(&g_ble_send_cb, &send_data);
// 逐字节打包数据到 send_buffer, 采用小端模式
uint8_t *p = send_buffer;
*p++ = send_data.checkout_1;
*p++ = send_data.checkout_2;
*p++ = send_data.foot;
*p++ = send_data.package_index;
for (int i = 0; i < MPU_FIFO_LEN; i++) {
sensor_package_t *pkg = &send_data.sensor_package[i];
// 1. 打包六轴数据 (6 * int16_t)
for (int j = 0; j < 6; j++) {
*p++ = (uint8_t)(pkg->SC7U22_data[j] & 0xFF);
*p++ = (uint8_t)((pkg->SC7U22_data[j] >> 8) & 0xFF);
}
// 2. 打包地磁数据 (3 * int32_t)
for (int j = 0; j < 3; j++) {
*p++ = (uint8_t)(pkg->mmc5603nj_buffer[j] & 0xFF);
*p++ = (uint8_t)((pkg->mmc5603nj_buffer[j] >> 8) & 0xFF);
*p++ = (uint8_t)((pkg->mmc5603nj_buffer[j] >> 16) & 0xFF);
*p++ = (uint8_t)((pkg->mmc5603nj_buffer[j] >> 24) & 0xFF);
}
// 3. 打包温度数据 (int16_t)
*p++ = (uint8_t)(pkg->temperature & 0xFF);
*p++ = (uint8_t)((pkg->temperature >> 8) & 0xFF);
// 4. 打包气压数据 (uint32_t)
*p++ = (uint8_t)(pkg->pressure & 0xFF);
*p++ = (uint8_t)((pkg->pressure >> 8) & 0xFF);
*p++ = (uint8_t)((pkg->pressure >> 16) & 0xFF);
*p++ = (uint8_t)((pkg->pressure >> 24) & 0xFF);
#if 0
float acc_g[3];
float gyr_dps[3];
acc_g[0] = (float)send_data.sensor_package[i].SC7U22_data[0] / 2048.0f;
acc_g[1] = (float)send_data.sensor_package[i].SC7U22_data[1] / 2048.0f;
acc_g[2] = (float)send_data.sensor_package[i].SC7U22_data[2] / 2048.0f;
gyr_dps[0] = (float)send_data.sensor_package[i].SC7U22_data[3] * 0.061f;
gyr_dps[1] = (float)send_data.sensor_package[i].SC7U22_data[4] * 0.061f;
gyr_dps[2] = (float)send_data.sensor_package[i].SC7U22_data[5] * 0.061f;
printf(" ACC(g): x=%.3f, y=%.3f, z=%.3f\n", acc_g[0], acc_g[1], acc_g[2]);
printf(" GYR(dps):x=%.3f, y=%.3f, z=%.3f\n", gyr_dps[0], gyr_dps[1], gyr_dps[2]);
#endif
}
extern void uartSendData(void *buf, u16 len) ; // 确保u16是uint16_t或unsigned short
uartSendData(send_buffer, 484); // 发送总共17字节
send_data_to_ble_client(send_buffer, 484); // 发送数据
// data_log(send_buffer);
}
}
// ------------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------------
/**
* @brief 开始采集传感器数据并通过ble发送
*
*/
void start_clloct(void){
os_task_create(sensor_collect_task,NULL,5,1024,32,"sensor_collect_task");
os_task_create(BLE_send_fuc,NULL,5,1024,32,"BLE_send_fuc");
}
/**
* @brief 停止采集和ble发送
*
*/
void stop_clloct(void){
os_task_del("sensor_collect_task");
os_task_del("BLE_send_fuc");
}
/**
* @brief 发给上位机
*
*/
void test_uart_init(void){
#if TCFG_UART0_ENABLE == 0
static u8 buff[40];
struct uart_platform_data_t u_arg = {0};
u_arg.tx_pin = IO_PORT_DP;
u_arg.rx_cbuf = buff;
u_arg.rx_cbuf_size = 32;
u_arg.frame_length = 6;
u_arg.rx_timeout = 100;
u_arg.isr_cbfun = NULL;
u_arg.baud = 1000000;
u_arg.is_9bit = 0;
uart_bus = uart_dev_open(&u_arg);
#endif
}
//iic测试调用的
#if 0
static u16 xt_iic_test_id;
char log_buffer_1[100];
extern char sen_log_buffer_1[100];
extern char sen_log_buffer_2[100];
extern char sen_log_buffer_3[100];
extern char sen_log_buffer_4[100];
extern char sen_log_buffer_5[100];
extern char w_log_buffer_1[100];
extern char w_log_buffer_2[100];
extern char w_log_buffer_3[100];
extern char w_log_buffer_4[100];
extern char w_log_buffer_5[100];
void xt_iic_test(){
char log_buffer[100];
send_data_to_ble_client(&log_buffer_1,strlen(log_buffer_1));
extern char iic_read_len;
extern char iic_write_result;
int num_chars_written = snprintf(log_buffer, sizeof(log_buffer),"SL_SC7U22_Check=0x%d,%d,%d\n", xt_Check_Flag, iic_read_len, iic_write_result);
extern void send_data_to_ble_client(const u8* data, u16 length);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
if(sen_log_buffer_1 != NULL)
send_data_to_ble_client(&sen_log_buffer_1,strlen(sen_log_buffer_1));
if(sen_log_buffer_2 != NULL)
send_data_to_ble_client(&sen_log_buffer_2,strlen(sen_log_buffer_2));
if(sen_log_buffer_3 != NULL)
send_data_to_ble_client(&sen_log_buffer_3,strlen(sen_log_buffer_3));
if(sen_log_buffer_4 != NULL)
send_data_to_ble_client(&sen_log_buffer_4,strlen(sen_log_buffer_4));
if(sen_log_buffer_5 != NULL)
send_data_to_ble_client(&sen_log_buffer_5,strlen(sen_log_buffer_5));
if(w_log_buffer_1 != NULL)
send_data_to_ble_client(&w_log_buffer_1,strlen(w_log_buffer_1));
if(w_log_buffer_2 != NULL)
send_data_to_ble_client(&w_log_buffer_2,strlen(w_log_buffer_2));
if(w_log_buffer_3 != NULL)
send_data_to_ble_client(&w_log_buffer_3,strlen(w_log_buffer_3));
if(w_log_buffer_4 != NULL)
send_data_to_ble_client(&w_log_buffer_4,strlen(w_log_buffer_4));
if(w_log_buffer_5 != NULL)
send_data_to_ble_client(&w_log_buffer_5,strlen(w_log_buffer_5));
// SL_SC7U22_Config();
void uartSendData(void *buf, u16 len) //发送数据的接口。
{
#if TCFG_UART0_ENABLE == 0
if (uart_bus) {
uart_bus->write(buf, len); //把数据写到DMA
}
#endif
}
#endif
#if 0
u16 xt_iic_test_id;
char hw_iic_init_result;
void xt_hw_iic_test(){
char log_buffer[100];
extern char iic_read_len;
extern char iic_write_result;
int num_chars_written = snprintf(log_buffer, sizeof(log_buffer),"init result:%d, SL_SC7U22_Check=0x%d,%d,%d\n",hw_iic_init_result, xt_Check_Flag, iic_read_len, iic_write_result);
extern void send_data_to_ble_client(const u8* data, u16 length);
send_data_to_ble_client(&log_buffer,strlen(log_buffer));
}
#endif
void sensor_measure(void){
// xlog("=======sensor_read_data START\n");
static signed short combined_raw_data[6];
static int initialized = 0;
static int calibration_done = 0;
char status = 0;
static sensor_data_t tmp;
mmc5603nj_mag_data_t mag_data;
SL_SC7U22_RawData_Read(tmp.acc_data,tmp.gyr_data);
// os_time_dly(1);
mmc5603nj_read_mag_data(&mag_data);
// xlog("=======sensor_read_data middle 1\n");
memcpy(&combined_raw_data[0], tmp.acc_data, 3 * sizeof(signed short));
memcpy(&combined_raw_data[3], tmp.gyr_data, 3 * sizeof(signed short));
if (!calibration_done) { //第1次启动开启零漂检测
// status = SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle, 0);
// status = SIX_SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle, 0);
// status = Original_SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle, 0);
status = Q_SL_SC7U22_Angle_Output(1, combined_raw_data, tmp.angle,&mag_data, 0, tmp.quaternion_output);
if(count > 100){
count = 0;
char log_buffer[100];
// snprintf( log_buffer, sizeof(log_buffer),"status:%d\n",status);
// send_data_to_ble_client(&log_buffer,strlen(log_buffer));
xlog("status:%d\n", status);
xlog("RawData:AX=%d,AY=%d,AZ=%d,GX=%d,GY=%d,GZ=%d\r\n",combined_raw_data[0],combined_raw_data[1],combined_raw_data[2],combined_raw_data[3],combined_raw_data[4],combined_raw_data[5]);
}
count++;
if (status == 1) {
calibration_done = 1;
printf("Sensor calibration successful! Skiing mode is active.\n");
}
} else {
// printf("Calculate the time interval =============== start\n");
// status = SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle, 0);
// status = SIX_SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle, 0);
// status = Original_SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle, 0);
status = Q_SL_SC7U22_Angle_Output(0, combined_raw_data, tmp.angle,&mag_data, 0, tmp.quaternion_output);
memcpy(tmp.acc_data, &combined_raw_data[0], 3 * sizeof(signed short));
memcpy(tmp.gyr_data, &combined_raw_data[3], 3 * sizeof(signed short));
BLE_send_data_t data_by_calculate = sensor_processing_task(tmp.acc_data, tmp.gyr_data,tmp.angle, tmp.quaternion_output);
extern void ano_send_attitude_data(float rol, float pit, float yaw, uint8_t fusion_sta) ;
ano_send_attitude_data(tmp.angle[0],tmp.angle[1],tmp.angle[2], 1);
}
// mmc5603nj_mag_data_t mag_data;
// mmc5603nj_read_mag_data(&mag_data);
// float temperature = mmc5603nj_get_temperature();
// count_test1++;
// if(count_test1 >500){
// count_test1 =0;
// xlog("Mag X: %.4f, Y: %.4f, Z: %.4f Gauss\n", mag_data.x, mag_data.y, mag_data.z);
// }
// xlog("=======sensor_read_data END\n");
}
/**
* @brief 初始化在xtell_app_main.c的app_main函数被调用
*
*/
void xtell_task_create(void){
// int ret = hw_iic_init(0);
// xlog("hw_iic_init result:%d\n",ret);
// //初始化传感器
// SL_SC7U22_Config();
#if TCFG_GSENOR_USER_IIC_TYPE
int ret = hw_iic_init(0);
xlog("init iic result:%d\n", ret); //返回0成功
#else
int ret = soft_iic_init(0);
int num_chars_written = snprintf(log_buffer_1, sizeof(log_buffer_1),"init iic: %d\n", ret);
// int num_chars_written = snprintf(log_buffer_1, sizeof(log_buffer_1),"init iic: %d\n", ret);
#endif
gpio_set_direction(IO_PORTE_05,0); //设置PE5 输出模式
gpio_set_pull_up(IO_PORTE_05,1);
gpio_direction_output(IO_PORTE_05,1);
// os_time_dly(10);
// delay_2ms(10);
// if(bmp280_init() != 0){
// xlog("bmp280 init error\n");
// }
// float temp, press;
// bmp280_read_data(&temp, &press);
// xlog("get temp: %d, get press: %d\n",temp, press);
// MPU9250_Mag_Init();
//iic总线设备扫描
// extern void i2c_scanner_probe(void);
// i2c_scanner_probe();
xlog("xtell_task_create\n");
// 初始化环形缓冲区
// circle_buffer_init(&sensor_cb, sensor_data_buffer, SENSOR_DATA_BUFFER_SIZE);
circle_buffer_init(&g_ble_send_cb, g_sensor_data_storage, SENSOR_DATA_BUFFER_SIZE, sizeof(ble_send_data_t));
ano_protocol_init(115200);
os_sem_create(&receiver_ready_sem, 0);
circle_buffer_init(&sensor_read, sensor_read_buffer, SENSOR_DATA_BUFFER_SIZE, sizeof(sensor_data_t));
circle_buffer_init(&sensor_send, sensor_send_buffer, SENSOR_DATA_BUFFER_SIZE, sizeof(BLE_send_data_t));
//初始化滑雪追踪器
// SkiingTracker_Init(&skiing_data);
xlog("SkiingTracker_Init\n");
// create_process(&sensor_read_data_id, "read",NULL, sensor_read_data, 10);
//
// create_process(&calculate_data_id, "calculate",NULL, calculate_data, 4);
// create_process(&ble_send_data_id, "send",NULL, BLE_send_data, 1);
#if 0
hw_iic_init_result = ret;
create_process(&xt_iic_test_id,"iic_test",NULL,xt_hw_iic_test,1000);
#endif
extern void test_uart_init(void);
test_uart_init();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//test
//
#define BUFF_LEN 500
static signed char acc_data_buf[BUFF_LEN] = {0};
// 1. 定义一个全局的信号量
static OS_SEM ble_send_sem;
int j = 0;
void sensor_test_task(void){
float temperature = 0;
float pressure = 0;
while(1){
WF_GET_Temperature_Pressure(&temperature, &pressure);
xlog("temperature: %.3f,pressure: %.3f\n",temperature,pressure);
os_time_dly(100);
}
}
static u16 gtest_id = 0;
void test_func(void){
// a. 初始化信号量初始值为0
// os_sem_create(&ble_send_sem, 0);
// b. 注册回调函数,让协议栈知道在准备好时该调用谁
// struct ble_server_operation_t *ble_ops;
// ble_get_server_operation_table(&ble_ops);
// ble_ops->regist_wakeup_send(NULL, on_ble_can_send);
for(int i = 0;i<BUFF_LEN;i++){
acc_data_buf[i] = i;
}
// SL_SC7U22_Config();
// mmc5603nj_init();
#if BMP280
BMP280_init();
#else
WF_Init();
#endif
// os_task_create(BLE_send_fuc,NULL,5,1024,32,"BLE_send_fuc");
// os_task_create(sensor_collect_task,NULL,5,1024,32,"sensor_collect_task");
os_task_create(sensor_test_task,NULL,5,1024,32,"sensor_test");
// data_send_task();
}

View File

@ -1,5 +1,10 @@
/*
气压计
根据手册,对于室内导航的配置推荐:
t_standby=0.5ms, filter=16, spi_en=0
osrs_t=x2, osrs_p=x16, mode=normal
采样率为26.3Hz外部每40ms读取一次
*/
#include "BMP280.h"
#include <string.h>
@ -46,6 +51,7 @@ static uint8_t bmp280_read_regs(uint8_t reg, uint8_t *buf, uint16_t len) {
* @return 补偿后的温度值 (单位: °C)
*/
static float compensate_temperature(int32_t adc_T) {
#if 1
float var1, var2, temperature;
var1 = (((float)adc_T) / 16384.0f - ((float)t1) / 1024.0f) * ((float)t2);
@ -59,6 +65,16 @@ static float compensate_temperature(int32_t adc_T) {
if (temperature > 85.0f) return 85.0f;
return temperature;
#else
int32_t var1, var2, T;
var1 = ((((adc_T>>3) - ((int32_t)t1<<1))) * ((int32_t)t2)) >> 11;
var2 = (((((adc_T>>4) - ((int32_t)t1)) * ((adc_T>>4) - ((int32_t)t1))) >> 12) *
((int32_t)t3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return (float)(T/100.0f);
#endif
}
/**
@ -67,6 +83,7 @@ static float compensate_temperature(int32_t adc_T) {
* @return 补偿后的气压值 (单位: Pa)
*/
static float compensate_pressure(int32_t adc_P) {
#if 1
float var1, var2, pressure;
var1 = ((float)t_fine / 2.0f) - 64000.0f;
@ -90,6 +107,25 @@ static float compensate_pressure(int32_t adc_P) {
if (pressure > 110000.0f) return 110000.0f;
return pressure;
#else
int32_t var1, var2, p;
var1 = ((int32_t)t_fine) - 128000;
var2 = var1 * var1 * (int32_t)p6;
var2 = var2 + ((var1*(int32_t)p5)<<17);
var2 = var2 + (((int32_t)p4)<<35);
var1 = ((var1 * var1 * (int32_t)p3)>>8) + ((var1 * (int32_t)p2)<<12);
var1 = (((((int32_t)1)<<47)+var1))*((int32_t)p1)>>33;
if (var1 == 0)
{
return 0; // avoid exception caused by division by zero
}
p = 1048576-adc_P;
p = (((p<<31)-var2)*3125)/var1;
var1 = (((int32_t)p9) * (p>>13) * (p>>13)) >> 25;
var2 = (((int32_t)p8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int32_t)p9)<<4);
return (float)(p/256);
#endif
}
/*==================================================================================*/
@ -99,26 +135,27 @@ static float compensate_pressure(int32_t adc_P) {
uint8_t bmp280_init(void) {
uint8_t BMP280_init(void) {
uint8_t id;
uint8_t calib_data[24];
// 1. 检查芯片ID
if (bmp280_read_regs(BMP280_REG_ID, &id, 1) == 0) {
printf("bmp280 get id error:%d\n",id );
return 1; // I2C读取失败
// return 1; // I2C读取失败
}
if (id != 0x58) {
printf("bmp280 check diff:%d\n",id );
return 1; // ID不匹配
// return 1; // ID不匹配
}
printf("bmp280 get id:0%X\n",id );
// 2. 软复位
bmp280_write_reg(BMP280_REG_RESET, 0xB6);
os_time_dly(10); // 等待复位完成
// 3. 一次性读取所有校准参数
if (bmp280_read_regs(BMP280_REG_CALIB_START, calib_data, 24) != 0) {
if (bmp280_read_regs(BMP280_REG_CALIB_START, calib_data, 24) == 0) {
return 2; // 读取校准数据失败
}
@ -147,18 +184,29 @@ uint8_t bmp280_init(void) {
os_time_dly(10); // 等待配置生效
printf("bmp280 init success\n");
return 0; // 初始化成功
}
/**
* @brief 获取转换后的温度和压力数据
*
* @param temperature 传出,温度
* @param pressure 传出,压力
* @return uint8_t
*/
uint8_t bmp280_read_data(float *temperature, float *pressure) {
uint8_t data[6];
int32_t adc_P, adc_T;
// printf("==========debug1===========\n");
// 一次性读取6个字节的温度和气压原始数据
if (bmp280_read_regs(BMP280_REG_PRESS_MSB, data, 6) != 0) {
if (bmp280_read_regs(BMP280_REG_PRESS_MSB, data, 6) == 0) {
printf("bmp280:read data error\n");
return 1; // 读取失败
}
// printf("==========debug2===========\n");
// 组合原始数据 (20位)
adc_P = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | (((uint32_t)(data[2])) >> 4));
adc_T = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | (((uint32_t)(data[5])) >> 4));
@ -167,12 +215,33 @@ uint8_t bmp280_read_data(float *temperature, float *pressure) {
if (adc_T == 0x80000 || adc_P == 0x80000) {
*temperature = 0.0f;
*pressure = 0.0f;
printf("bmp280:no data\n");
return 1;
}
// printf("==========debug3===========\n");
// 进行补偿计算
*temperature = compensate_temperature(adc_T);
*pressure = compensate_pressure(adc_P);
return 0; // 成功
}
/**
* @brief 获取该气压计的原始adc数据
*
* @param adc_P 传出,气压
* @param adc_T 传出,温度
*/
void bmp280_read_originanl_data(int* adc_P, int* adc_T){
uint8_t data[6];
// 一次性读取6个字节的温度和气压原始数据
if (bmp280_read_regs(BMP280_REG_PRESS_MSB, data, 6) != 0) {
return; // 读取失败
}
// 组合原始数据 (20位)
adc_P = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | (((uint32_t)(data[2])) >> 4));
adc_T = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | (((uint32_t)(data[5])) >> 4));
}

View File

@ -8,11 +8,11 @@
// I2C 从设备地址
#if BMP_PULL_UP == 1 //外部接的高
#define BMP_IIC_7BIT_ADDRESS 0x77 //7位,外部接高为0x77
#define BMP_IIC_7BIT_ADDRESS 0x76 //7位,外部接高为0x76
#define BMP_IIC_WRITE_ADDRESS (BMP_IIC_7BIT_ADDRESS<<1) //8位地址
#define BMP_IIC_READ_ADDRESS (BMP_IIC_WRITE_ADDRESS | 0x01)
#else
#define BMP_IIC_7BIT_ADDRESS 0x76 //7位,外部接为0x76
#define BMP_IIC_7BIT_ADDRESS 0x77 //7位,外部接GAO为0x77
#define BMP_IIC_WRITE_ADDRESS (BMP_IIC_7BIT_ADDRESS<<1) //8位地址
#define BMP_IIC_READ_ADDRESS (BMP_IIC_WRITE_ADDRESS | 0x01)
#endif
@ -33,7 +33,7 @@
* @return 0: 成功, 1: 芯片ID错误, 2: 读取校准参数失败
* @note 此函数会完成ID检查、软复位、读取校准参数并设置传感器为连续测量模式。
*/
uint8_t bmp280_init(void);
uint8_t BMP280_init(void);
/**
* @brief 从BMP280读取温度和气压数据
@ -43,4 +43,12 @@ uint8_t bmp280_init(void);
*/
uint8_t bmp280_read_data(float *temperature, float *pressure);
/**
* @brief 获取该气压计的原始adc数据
*
* @param adc_P 传出,气压
* @param adc_T 传出,温度
*/
void bmp280_read_originanl_data(int* adc_P, int* adc_T);
#endif // BMP280_DRIVER_H

View File

@ -1,3 +1,7 @@
/*
MMC5603nj
1-255的采样率这里设置为200Hz,5ms
*/
#include "MMC56.h"
#include "math.h"
@ -6,6 +10,9 @@
#include "gSensor/gSensor_manage.h"
#include "printf.h"
#define CALIBRATION_TIME 20000 //校准持续时间 ms
#define SAMPLE_INTERVAL 100 //校准采样间隔
// 用于跟踪当前是否处于连续测量模式
static uint8_t g_continuous_mode_enabled = 0;
mmc5603nj_cal_data_t cal_data; //校准数据
@ -27,9 +34,9 @@ uint8_t mmc5603nj_get_pid(void) {
int mmc5603nj_init(void) {
// ID
if (mmc5603nj_get_pid() != 0x80) {
if ( mmc5603nj_get_pid() != 0x10) {
printf("MMC5603NJ init failed: wrong Product ID (read: 0x%X)\n", mmc5603nj_get_pid());
return -1;
// return 0;
}
// 软件复位
@ -38,13 +45,15 @@ int mmc5603nj_init(void) {
// 设置20位分辨率 (BW[1:0] = 11)
// 同时确保所有轴都使能 (X/Y/Z_inhibit = 0)
// mmc5603nj_write_reg(MMC_INCTRL1, 0x03);
mmc5603nj_write_reg(MMC_INCTRL1, 0x03);
os_time_dly(1);
// 设置内部控制寄存器2
// CMM_EN = 1 (使能连续模式功能)
// HPOWER = 1 (高功耗模式,更稳定)
mmc5603nj_write_reg(MMC_INCTRL2, 0x90); // 0b10010000
// HPOWER = 0
// mmc5603nj_write_reg(MMC_INCTRL2, 0x10); // 0b00010000
mmc5603nj_write_reg(MMC_INCTRL2, 0x10); // 0b10010000
// 设置自动SET/RESET功能
// AUTO_SR_EN = 1
@ -53,19 +62,19 @@ int mmc5603nj_init(void) {
g_continuous_mode_enabled = 0;
printf("MMC5603NJ initialized successfully.\n");
mmc5603nj_enable_continuous_mode(0x04);
// mmc5603nj_enable_continuous_mode(0xC8); //200Hz的采样率最高支持255
mmc5603nj_enable_continuous_mode(0xCF);
return 1;
}
void mmc5603nj_start_calibration(void){
printf("\n--- Magnetometer Calibration Start ---\n");
printf("Slowly rotate the device in all directions (like drawing a 3D '8')...\n");
printf("Calibration will last for 20 seconds.\n\n");
printf("will start after 5 seconds\n\n");
os_time_dly(500);
// 定义校准时长和采样间隔
const uint32_t calibration_duration_ms = 20000; // 20秒
const uint32_t sample_interval_ms = 100; // 每100ms采样一次
// 初始化最大最小值
// 使用一个临时变量来读取数据避免干扰read函数的正常逻辑
mmc5603nj_mag_data_t temp_mag_data;
@ -81,7 +90,7 @@ int mmc5603nj_init(void) {
uint32_t start_time = os_time_get(); // 假设os_time_get()返回毫秒级时间戳
int samples = 0;
int over = calibration_duration_ms/sample_interval_ms;
int over = CALIBRATION_TIME/SAMPLE_INTERVAL;
while (samples <= over) {
// 读取原始磁力计数据
@ -98,7 +107,7 @@ int mmc5603nj_init(void) {
if (temp_mag_data.z < min_z) min_z = temp_mag_data.z;
samples++;
os_time_dly(sample_interval_ms / 10); // os_time_dly的参数通常是ticks (1 tick = 10ms)
os_time_dly(SAMPLE_INTERVAL / 10);
}
// 检查数据范围是否合理,防止传感器未动或故障
@ -106,7 +115,7 @@ int mmc5603nj_init(void) {
printf("\n--- Calibration Failed ---\n");
printf("Device might not have been rotated enough.\n");
printf("X range: %.2f, Y range: %.2f, Z range: %.2f\n", max_x - min_x, max_y - min_y, max_z - min_z);
return -1;
return;
}
// 计算硬磁偏移 (椭球中心)
@ -121,8 +130,6 @@ int mmc5603nj_init(void) {
printf(" Y: %.4f\n", cal_data.offset_y);
printf(" Z: %.4f\n", cal_data.offset_z);
printf("Please save these values and apply them in your code.\n\n");
return 0;
}
@ -195,7 +202,7 @@ void mmc5603nj_read_mag_data(mmc5603nj_mag_data_t *mag_data) {
} while ((status & 0x40) == 0 && timeout > 0);
if (timeout == 0) {
printf("Error: Magnetic measurement timeout!\n");
// printf("Error: Magnetic measurement timeout!\n");
mag_data->x = mag_data->y = mag_data->z = 0.0f;
return;
}
@ -219,3 +226,41 @@ void mmc5603nj_read_mag_data(mmc5603nj_mag_data_t *mag_data) {
mag_data->y -= cal_data.offset_y;
mag_data->z -= cal_data.offset_z;
}
void mmc5603nj_read_origin_data(uint8_t *buffer) {
if (g_continuous_mode_enabled) {
// 连续模式下,只需检查数据是否就绪
uint8_t status = 0;
mmc5603nj_read_regs(MMC_STATUS1, &status, 1);
if ((status & 0x40) == 0) { // Meas_M_done bit
// 数据未就绪,可以选择返回或等待,这里我们直接返回旧数据
return;
}
} else {
// 单次测量模式
uint8_t status = 0;
uint8_t timeout = 20;
// 触发一次带自动SET/RESET的磁场测量
mmc5603nj_write_reg(MMC_INCTRL0, 0x21); // 0b00100001 (TAKE_MEAS_M=1, AUTO_SR_EN=1)
// 等待测量完成
do {
os_time_dly(10);
mmc5603nj_read_regs(MMC_STATUS1, &status, 1);
timeout--;
} while ((status & 0x40) == 0 && timeout > 0);
if (timeout == 0) {
printf("Error: Magnetic measurement timeout!\n");
return;
}
}
// 读取9个字节的原始数据
mmc5603nj_read_regs(MMC_XOUT0, buffer, 9);
}

View File

@ -36,6 +36,14 @@
#define MMC_ST_Z 0x29
#define MMC_PID 0x39
// 定义一个结构体来存放三轴磁场数据(原始数据)
typedef struct {
float x;
float y;
float z;
} mmc5603nj_original_data_t;
// 定义一个结构体来存放三轴磁场数据(单位:高斯 Gauss
typedef struct {
float x;

View File

@ -62,7 +62,7 @@ unsigned char SL_SC7U22_I2c_Spi_Read(unsigned char sl_spi_iic, unsigned char reg
static void sl_delay(unsigned char sl_i)
{
os_time_dly(sl_i);
delay((int)sl_i);
}
char iic_read_len;
@ -131,10 +131,12 @@ unsigned char SL_SC7U22_Config(void)
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0x06);//ACC_CONF 0x07=50Hz 0x06=25Hz
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0xA8);//高性能模式连续4个数据平均1次100Hz -- lmx
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0xBC);//ACC_CON 高性能模式1600Hz -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0xBB);//ACC_CON 高性能模式800Hz -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0xBC);//ACC_CON 高性能模式1600Hz -- lmx
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0xA8);//ACC_CON 高性能模式100Hz平均数4 -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0xA8);//ACC_CON 高性能模式100Hz平均数4 -- lmx
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x40, 0x8B);//ACC_CON 高性能模式400Hz -- lmx
#if ACC_RANGE==2
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x41, 0x00);//ACC_RANGE 00±2G
@ -153,9 +155,11 @@ unsigned char SL_SC7U22_Config(void)
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x42, 0x8C);//GYR_CONF 1600Hz -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x42, 0xAC);//GYR_CONF 1600Hz -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x42, 0xAB);//GYR_CONF 800Hz -- lmx
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x42, 0xE8);//GYR_CONF 100Hz, 噪声优化开启,4个平均一次 -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x42, 0xE8);//GYR_CONF 100Hz, 噪声优化开启,4个平均一次 -- lmx
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x43, 0x00);//GYR_RANGE 2000dps
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x42, 0xCB);//GYR_CONF 噪声优化开启,高性能模式400Hz -- lmx
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x43, 0x00);//GYR_RANGE 2000dps
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x43, 0x00);//GYR_RANGE 2000dps
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x04, 0x50);//COM_CFG
@ -291,7 +295,7 @@ void SL_SC7U22_RawData_Read(signed short * acc_data_buf,signed short * gyr_data_
unsigned char Acc_FIFO_Num;
unsigned char Gyr_FIFO_Num;
unsigned char SL_SC7U22_FIFO_DATA[1024];
unsigned char SL_SC7U22_FIFO_DATA[2048];
unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf,signed short *accz_buf,signed short *gyrx_buf,signed short *gyry_buf,signed short *gyrz_buf)
{
@ -306,7 +310,8 @@ unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf
unsigned char header[2];
unsigned short j;
#if SL_Sensor_Algo_Release_Enable==0x00 //user can set to zero
// #if SL_Sensor_Algo_Release_Enable==0x00 //user can set to zero
#if 0//lmx
#if SL_SC7U22_WAIT_FIFO_LEN_ENABLE==0x00
while((fifo_num1&0x20)!=0x20)
{
@ -341,7 +346,8 @@ unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf
SL_SC7U22_I2c_Spi_Read(SL_SPI_IIC_INTERFACE, 0x20,1,&fifo_num2);
if((fifo_num1&0x10)==0x10)
{
fifo_num=2048;
// fifo_num=2048; // 原始代码,会导致溢出
fifo_num = 2048; // 传感器FIFO已满但我们的缓冲区只有1024字节所以最多读1024字节
}
else
{
@ -349,10 +355,15 @@ unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf
}
#endif
// 增加保护,确保读取的字节数不超过缓冲区大小 (1024 bytes)
// fifo_num 是 word (2 bytes) 的数量, 所以最大值是 512
if (fifo_num > 1024) {
fifo_num = 1024;
}
SL_SC7U22_I2c_Spi_Read(SL_SPI_IIC_INTERFACE, 0x21, fifo_num*2, SL_SC7U22_FIFO_DATA);//读取FIFO数据 BYTE NUM
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x1D, 0x00);//BY PASS MODE
// SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x1D, 0x20);//Stream MODE
xlog("SC7U22_FIFO_NUM1:%d\n",fifo_num);
// xlog("SC7U22_FIFO_NUM1:%d\n",fifo_num);
#if SL_Sensor_Algo_Release_Enable==0x00
// xlog("0x1F:0x%x 0x20:0x%x\n",fifo_num1,fifo_num2);
// xlog("SC7U22_FIFO_NUM1:%d\n",fifo_num);
@ -380,7 +391,7 @@ unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf
accx_buf[Acc_FIFO_Num] = ((s16)(SL_SC7U22_FIFO_DATA[i + 0] * 256 + SL_SC7U22_FIFO_DATA[i + 1])) ;
accy_buf[Acc_FIFO_Num] = ((s16)(SL_SC7U22_FIFO_DATA[i + 2] * 256 + SL_SC7U22_FIFO_DATA[i + 3])) ;
accz_buf[Acc_FIFO_Num] = ((s16)(SL_SC7U22_FIFO_DATA[i + 4] * 256 + SL_SC7U22_FIFO_DATA[i + 5])) ;
xlog("AccNum : %d ,Acc_x : %4d, Acc_y : %4d, Acc_z : %4d,\r\n",Acc_FIFO_Num, accx_buf[Acc_FIFO_Num], accy_buf[Acc_FIFO_Num], accz_buf[Acc_FIFO_Num]);
// xlog("AccNum : %d ,Acc_x : %4d, Acc_y : %4d, Acc_z : %4d,\r\n",Acc_FIFO_Num, accx_buf[Acc_FIFO_Num], accy_buf[Acc_FIFO_Num], accz_buf[Acc_FIFO_Num]);
i = i + 6;
Acc_FIFO_Num++;
}
@ -390,7 +401,7 @@ unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf
gyrx_buf[Gyr_FIFO_Num] = ((s16)(SL_SC7U22_FIFO_DATA[i + 0] * 256 + SL_SC7U22_FIFO_DATA[i + 1])) ;
gyry_buf[Gyr_FIFO_Num] = ((s16)(SL_SC7U22_FIFO_DATA[i + 2] * 256 + SL_SC7U22_FIFO_DATA[i + 3])) ;
gyrz_buf[Gyr_FIFO_Num] = ((s16)(SL_SC7U22_FIFO_DATA[i + 4] * 256 + SL_SC7U22_FIFO_DATA[i + 5])) ;
xlog("GyrNum : %d, Gyr_x : %4d, Gyr_y : %4d, Gyr_z : %4d,\r\n",Gyr_FIFO_Num, gyrx_buf[Gyr_FIFO_Num], gyry_buf[Gyr_FIFO_Num], gyrz_buf[Gyr_FIFO_Num]);
// xlog("GyrNum : %d, Gyr_x : %4d, Gyr_y : %4d, Gyr_z : %4d,\r\n",Gyr_FIFO_Num, gyrx_buf[Gyr_FIFO_Num], gyry_buf[Gyr_FIFO_Num], gyrz_buf[Gyr_FIFO_Num]);
i = i + 6;
Gyr_FIFO_Num++;
}
@ -401,8 +412,14 @@ unsigned short SL_SC7U22_FIFO_Read(signed short *accx_buf,signed short *accy_buf
i = i + 2;
}
}
if(Acc_FIFO_Num > Gyr_FIFO_Num)
fifo_len = Acc_FIFO_Num;
else
fifo_len = Gyr_FIFO_Num;
// xlog("Acc_FIFO_Num:%d,Gyr_FIFO_Num:%d\n",Acc_FIFO_Num,Gyr_FIFO_Num);
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x1D,0x00);
SL_SC7U22_I2c_Spi_Write(SL_SPI_IIC_INTERFACE, 0x1D,0x20);
return fifo_len;
}
#endif
@ -1167,10 +1184,19 @@ unsigned char Original_SL_SC7U22_Angle_Output(unsigned char calibration_en, sign
return 2; // 校准未完成,返回错误状态
}
unsigned char get_calibration_state(void){
unsigned char get_SC7U22_Error_Flag(void){
return SL_SC7U22_Error_Flag;
}
/**
* @brief 设置零漂检测标准位
*
* @param flag 0重新进行零漂检测
*/
void set_SC7U22_Error_Flag(char flag){
SL_SC7U22_Error_Flag = flag;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1182,7 +1208,7 @@ unsigned char get_calibration_state(void){
// Kp: 比例增益,决定了加速度计数据校正陀螺仪的权重。值越大,对加速度计的响应越快,但对运动加速度更敏感。
// Ki: 积分增益,决定了用于校正陀螺仪静态漂移的权重。
// Q_dt: 采样时间间隔单位这里是10ms (0.01s)对应100Hz的采样率。
#define HAVE_MAG 1
#define HAVE_MAG 0
#if HAVE_MAG == 0
// -- 无地磁 --
const float Kp = 2.0f;
@ -1190,8 +1216,8 @@ const float Ki = 0.005f;
const float Q_dt = 0.01f;
#else
// -- 有地磁 --
const float Kp = 0.3f;
const float Ki = 0.001f;
const float Kp = 2.0f;
const float Ki = 0.005f;
const float Q_dt = 0.01f;
#endif
@ -1233,7 +1259,7 @@ float Temp_Mag[3] = {0.0f, 0.0f, 0.0f};
*/
unsigned char Q_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed short *acc_gyro_input, float *Angle_output, const mmc5603nj_mag_data_t* _mag_data_input, unsigned char yaw_rst, float *quaternion_output)
{
#if 1 //有地磁置1
#if 0 //有地磁置1
unsigned char sl_i = 0;
// 如果外部强制禁用校准则将标志位置1
if (calibration_en == 0) {
@ -1312,8 +1338,6 @@ unsigned char Q_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed shor
// Error_Mag_f[0] = 0.0f - (float)Sum_Avg_Mag_f[0];
// Error_Mag_f[1] = 0.0f - (float)Sum_Avg_Mag_f[1];
// Error_Mag_f[2] = 0.0f - (float)Sum_Avg_Mag_f[2];
// xlog("AVG_Recode AX:%d,AY:%d,AZ:%d,GX:%d,GY:%d,GZ:%d\r\n", Sum_Avg_Accgyro[0], Sum_Avg_Accgyro[1], Sum_Avg_Accgyro[2], Sum_Avg_Accgyro[3], Sum_Avg_Accgyro[4], Sum_Avg_Accgyro[5]);
// xlog("Error_Recode AX:%d,AY:%d,AZ:%d,GX:%d,GY:%d,GZ:%d\r\n", Error_Accgyro[0], Error_Accgyro[1], Error_Accgyro[2], Error_Accgyro[3], Error_Accgyro[4], Error_Accgyro[5]);
}
} else {
SL_SC7U22_Error_cnt2 = 0;
@ -1497,6 +1521,8 @@ unsigned char Q_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed shor
SL_SC7U22_Error_cnt2 = 0;
SL_SC7U22_Error_cnt = 0;
for (sl_i = 0; sl_i < 6; sl_i++) Sum_Avg_Accgyro[sl_i] = Sum_Avg_Accgyro[sl_i] / 50;
Error_Accgyro[0] = 0 - Sum_Avg_Accgyro[0];
Error_Accgyro[1] = 0 - Sum_Avg_Accgyro[1];
#if ACC_RANGE==2
@ -1511,6 +1537,8 @@ unsigned char Q_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed shor
Error_Accgyro[3] = 0 - Sum_Avg_Accgyro[3];
Error_Accgyro[4] = 0 - Sum_Avg_Accgyro[4];
Error_Accgyro[5] = 0 - Sum_Avg_Accgyro[5];
// xlog("AVG_Recode AX:%d,AY:%d,AZ:%d,GX:%d,GY:%d,GZ:%d\r\n", Sum_Avg_Accgyro[0], Sum_Avg_Accgyro[1], Sum_Avg_Accgyro[2], Sum_Avg_Accgyro[3], Sum_Avg_Accgyro[4], Sum_Avg_Accgyro[5]);
// xlog("Error_Recode AX:%d,AY:%d,AZ:%d,GX:%d,GY:%d,GZ:%d\r\n", Error_Accgyro[0], Error_Accgyro[1], Error_Accgyro[2], Error_Accgyro[3], Error_Accgyro[4], Error_Accgyro[5]);
}
@ -1583,10 +1611,30 @@ unsigned char Q_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed shor
eyInt = eyInt + ey * Ki * Q_dt;
ezInt = ezInt + ez * Ki * Q_dt;
float kp_dynamic = Kp; // 默认使用全局Kp
// // 计算重力向量与Z轴的夹角余弦值
// // 当设备接近水平时abs_az_component 接近 1
// // 当设备接近垂直时abs_az_component 接近 0
// float abs_az_component = fabsf(az);
// // 设置一个阈值比如当与水平面的夹角大于75度时 (cos(75) approx 0.26)
// // 就开始降低Kp
// if (abs_az_component < 0.26f) {
// // 线性降低Kp或者直接使用一个较小的值
// // 越接近垂直az越小Kp也越小
// kp_dynamic = Kp * (abs_az_component / 0.26f);
// }
// 使用PI控制器校正陀螺仪的测量值
gx = gx + Kp * ex + exInt;
gy = gy + Kp * ey + eyInt;
gz = gz + Kp * ez + ezInt;
gx += kp_dynamic * ex + exInt;
gy += kp_dynamic * ey + eyInt;
gz += kp_dynamic * ez + ezInt;
// gx = gx + Kp * ex + exInt;
// gy = gy + Kp * ey + eyInt;
// gz = gz + Kp * ez + ezInt;
}
// 使用校正后的角速度更新四元数 (一阶毕卡法)

View File

@ -14,18 +14,18 @@ Copyright (c) 2022 Silan MEMS. All Rights Reserved.
//是否使能串口打印调试
#define SL_Sensor_Algo_Release_Enable 0x00
//是否开启FIFO模式默认STREAM模式
#define SL_SC7U22_FIFO_ENABLE 0x00
#define SL_SC7U22_FIFO_ENABLE 0x01
/***使用前请根据实际情况配置以下参数******/
/**SC7U22的SDO 接地: 0****************/
/**SC7U22的SDO 接电源:1****************/
#define SL_SC7U22_SDO_VDD_GND 1
#define SL_SC7U22_SDO_VDD_GND 0
/*****************************************/
/***使用前请根据实际IIC地址配置参数***/
/**SC7U22的IIC 接口地址为 7bits: 0****/
/**SC7U22的IIC 接口地址为 8bits: 1****/
#define SL_SC7U22_IIC_7BITS_8BITS 0
#define SL_SC7U22_IIC_7BITS_8BITS 1
/*****************************************/
#if SL_SC7U22_SDO_VDD_GND==0
#define SL_SC7U22_IIC_7BITS_ADDR 0x18
@ -131,6 +131,7 @@ unsigned char SL_SC7U22_Angle_Output(unsigned char calibration_en,signed short *
/**output Angle_output[2]: Yaw*******************************/
/**input yaw_rst: reset yaw value***************************/
void set_SC7U22_Error_Flag(char flag);
unsigned char Original_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed short *acc_gyro_input, float *Angle_output, unsigned char yaw_rst);
unsigned char SIX_SL_SC7U22_Angle_Output(unsigned char auto_calib_start, signed short *acc_gyro_input, float *Angle_output, unsigned char yaw_rst);
unsigned char Q_SL_SC7U22_Angle_Output(unsigned char calibration_en, signed short *acc_gyro_input, float *Angle_output, const mmc5603nj_mag_data_t *mag_data_input, unsigned char yaw_rst, float *quaternion_output);

View File

@ -3,171 +3,225 @@
*/
#include "wf282a.h"
#include <math.h>
#include <stdint.h> // 推荐使用标准类型
#include "gSensor/gSensor_manage.h"
#include <stdint.h>
#include "gSensor/gSensor_manage.h" // Assuming this provides gravity_sensor_command and _gravity_sensor_get_ndata
#define ENABLE_XLOG 1
#ifdef xlog
#undef xlog
#endif
#if ENABLE_XLOG
#define xlog(format, ...) printf("[XT:%s] " format, __func__, ##__VA_ARGS__)
#else
#define xlog(format, ...) ((void)0)
#endif
/*==================================================================================*/
/* WF282A 内部定义 */
/*==================================================================================*/
// 存储校准系数的静态全局变量
static int16_t c0, c1, c01, c11, c20, c21, c30;
static int32_t c00, c10;
/*==================================================================================*/
/* 封装的底层I2C读写函数 */
/* 封装的底层I2C读写函数 (Provided by user) */
/*==================================================================================*/
#define I2C_HANDLE 0
/**
* @brief 写入单个字节到WF282A寄存器
*/
static void wf282a_write_reg(uint8_t reg, uint8_t data) {
gravity_sensor_command(WF_IIC_WRITE_ADDRESS, reg, data);
}
/**
* @brief 从WF282A读取多个字节
*/
static uint32_t wf282a_read_regs(uint8_t reg, uint8_t *buf, uint8_t len) {
return _gravity_sensor_get_ndata(WF_IIC_READ_ADDRESS, reg, buf, len);
}
/*==================================================================================*/
/* 内部辅助函数 */
/*==================================================================================*/
/**
* @brief 从缓冲区中解析所有校准系数
* @param buf 包含从寄存器0x10开始读取的18个字节的校准数据
*/
static void parse_calibration_data(const uint8_t *buf) {
// c0 (12-bit)
c0 = ((int16_t)buf[0] << 4) | (buf[1] >> 4);
if (c0 & (1 << 11)) c0 |= 0xF000;
// 制造商: (tempbuf[0]<<4) + ((tempbuf[1]>>4) & 0x0F);
c0 = ((int16_t)buf[0] << 4) | ((buf[1] >> 4) & 0x0F);
// if (c0 & (1 << 11)) c0 |= 0xF000;
if(c0 > 0x7ff) c0 = c0 - 0x1000;
// c1 (12-bit)
// 制造商: tempbuf[2] + ((tempbuf[1] & 0x0F)<<8);
c1 = (((int16_t)buf[1] & 0x0F) << 8) | buf[2];
if (c1 & (1 << 11)) c1 |= 0xF000;
// if (c1 & (1 << 11)) c1 |= 0xF000;
if(c1 > 0x7ff) c1 = c1 -0x1000;
// c00 (20-bit)
c00 = ((int32_t)buf[3] << 12) | ((int32_t)buf[4] << 4) | (buf[5] >> 4);
if (c00 & (1 << 19)) c00 |= 0xFFF00000;
// 制造商: (((u32)((tempbuf[3]<<8) + tempbuf[4]))<<4)+((tempbuf[5]>>4)&0x0F);
c00 = ((int32_t)buf[3] << 12) | ((int32_t)buf[4] << 4) | ((buf[5] >> 4) & 0x0F);
// if (c00 & (1 << 19)) c00 |= 0xFFF00000;
if(c00 > 0x7ffff) c00 = c00 - 0x100000;
// c10 (20-bit)
// 制造商: (((u32)((tempbuf[5]&0x0F)<<8)+tempbuf[6])<<8)+tempbuf[7];
c10 = (((int32_t)buf[5] & 0x0F) << 16) | ((int32_t)buf[6] << 8) | buf[7];
if (c10 & (1 << 19)) c10 |= 0xFFF00000;
// if (c10 & (1 << 19)) c10 |= 0xFFF00000;
if(c10 > 0x7ffff) c10 = c10 - 0x100000;
// c01, c11, c20, c21, c30 (16-bit)
c01 = (int16_t)((uint16_t)buf[8] << 8 | buf[9]);
if (c01 > 0x7fff) c01 = c01 - 0x10000; // 制造商的符号扩展
c11 = (int16_t)((uint16_t)buf[10] << 8 | buf[11]);
if (c11 > 0x7fff) c11 = c11 - 0x10000; // 制造商的符号扩展
c20 = (int16_t)((uint16_t)buf[12] << 8 | buf[13]);
if (c20 > 0x7fff) c20 = c20 - 0x10000; // 制造商的符号扩展
c21 = (int16_t)((uint16_t)buf[14] << 8 | buf[15]);
if (c21 > 0x7fff) c21 = c21 - 0x10000; // 制造商的符号扩展
c30 = (int16_t)((uint16_t)buf[16] << 8 | buf[17]);
if (c30 > 0x7fff) c30 = c30 - 0x10000; // 制造商的符号扩展
}
/**
* @brief 获取原始温度值 (ADC)
* 在连续测量模式下,只需读取数据寄存器,无需触发或等待。
*/
static int32_t Get_Traw() {
uint8_t buff[3];
int32_t Traw;
// 从 MSB 寄存器 WF_TMP_B2 (0x03) 开始连续读取3个字节
wf282a_read_regs(WF_TMP_B2, buff, 3);
if (wf282a_read_regs(WF_TMP_B2, buff, 3) != 3) {
xlog("Failed to read raw temperature data\n");
return 0; // 返回0或一个合适的错误值
}
// buff[0] = B2 (MSB), buff[1] = B1, buff[2] = B0 (LSB)
Traw = (int32_t)buff[0] << 16 | (int32_t)buff[1] << 8 | (int32_t)buff[2];
// 24位二进制补码转32位
if (Traw & (1 << 23)) {
Traw |= 0xFF000000;
}
// if (Traw & (1 << 23)) {
// Traw |= 0xFF000000;
// }
if(Traw > 0x7fffff) Traw = Traw - 0x1000000;
return Traw;
}
/**
* @brief 获取原始气压值 (ADC)
* 在连续测量模式下,只需读取数据寄存器,无需触发或等待。
*/
static int32_t Get_Praw() {
uint8_t buff[3];
int32_t Praw;
// 从 MSB 寄存器 WF_PRS_B2 (0x00) 开始连续读取3个字节
wf282a_read_regs(WF_PRS_B2, buff, 3);
if (wf282a_read_regs(WF_PRS_B2, buff, 3) != 3) {
xlog("Failed to read raw pressure data\n");
return 0; // 返回0或一个合适的错误值
}
// buff[0] = B2 (MSB), buff[1] = B1, buff[2] = B0 (LSB)
Praw = (int32_t)buff[0] << 16 | (int32_t)buff[1] << 8 | (int32_t)buff[2];
// 24位二进制补码转32位
if (Praw & (1 << 23)) {
Praw |= 0xFF000000;
}
// // 24位二进制补码转32位
// if (Praw & (1 << 23)) {
// Praw |= 0xFF000000;
// }
if(Praw > 0x7fffff) Praw = Praw - 0x1000000;
return Praw;
}
/*==================================================================================*/
/* 4. 外部接口函数实现 */
/*==================================================================================*/
uint8_t WF_Init() {
uint8_t calib_buf[18];
uint8_t check_cfg;
xlog("WF282A: soft reset\n");
// 1. 软复位
// wf282a_write_reg(WF_RESET_REG, 0x09);//0x0C
delay(1000); // 复位后等待1000ms
// 1. 配置传感器工作模式
// 推荐配置压力8次过采样温度1次过采样测量速率16Hz
wf282a_write_reg(WF_PRS_CFG, (PM_RATE_16 << 4) | PM_PRC_8);
wf282a_write_reg(WF_TMP_CFG, (TMP_RATE_16 << 4) | TMP_PRC_1 | TMP_INT_SENSOR);
wf282a_write_reg(WF_MEAS_CFG, 0x07); // 启动连续压力和温度测量
wf282a_write_reg(WF_CFG_REG, 0x00); // 无中断或FIFO移位配置
// 读取设备id确保设备通信正常
extern uint8_t WF_GetID();
WF_GetID();
// 2. 一次性读取所有校准系数 (从0x10到0x21共18字节)
if (wf282a_read_regs(COEF_C0, calib_buf, 18) != 0) {
// 2. 读取校准系数
if (wf282a_read_regs(COEF_C0, calib_buf, 18) != 18) { //0x10, 检查是否成功读取18字节
xlog("Failed to read the calibration coefficient\n");
return 2; // 读取校准数据失败
}
parse_calibration_data(calib_buf);
// DEBUG: 打印解析后的校准系数
xlog("Parsed Coefficients: c0=%d, c1=%d, c00=%ld, c10=%ld, c01=%d, c11=%d, c20=%d, c21=%d, c30=%d\n",
c0, c1, c00, c10, c01, c11, c20, c21, c30);
#if 0 //连续测量
// 配置压力、温度和通用寄存器为连续测量模式
wf282a_write_reg(WF_PRS_CFG, (PM_RATE_32 << 4) | PM_PRC_1); //reg: 0x06
// 温度配置: 内部传感器 (TMP_INT_SENSOR), 32Hz测量速率 (TMP_RATE_32), 16x过采样 (TMP_PRC_16) -> 0x54
wf282a_write_reg(WF_TMP_CFG, TMP_EXT_SENSOR | (TMP_RATE_32 << 4) | TMP_PRC_1); //reg: 0x07
// 启动连续测量模式 (同时测量压力和温度)
wf282a_write_reg(WF_MEAS_CFG, 0x06); //reg: 0x08
//过采样率大于8要对移位置配置1
// wf282a_write_reg(WF_CFG_REG, 0x0C); //reg: 0x09
delay(40); // 稍长一点的延迟,确保传感器开始正常工作
#else
wf282a_write_reg(WF_PRS_CFG, (PM_RATE_1 << 4) | PM_PRC_128); //reg: 0x06压力
wf282a_write_reg(WF_TMP_CFG, TMP_EXT_SENSOR | (TMP_RATE_1 << 4) | TMP_PRC_128); //reg: 0x07温度
//过采样率大于8要对移位置配置1
wf282a_write_reg(WF_CFG_REG, 0x0C); //reg: 0x09
delay(40); // 稍长一点的延迟,确保传感器开始正常工作
#endif
// 3. 检查配置是否写入成功
wf282a_read_regs(WF_MEAS_CFG, &check_cfg, 1);
if (check_cfg != 0x07) {
return 1; // 错误
} else {
return 0; // 成功
}
}
void WF_Sleep() {
wf282a_write_reg(WF_MEAS_CFG, 0x00); // 待机模式
}
void WF_Wakeup() {
wf282a_write_reg(WF_MEAS_CFG, 0x07); // 恢复连续测量
// 恢复连续测量模式
wf282a_write_reg(WF_MEAS_CFG, 0x06); // 启动连续压力和温度测量
delay(40); // 恢复后等待一个测量周期
}
uint8_t WF_GetID() {
uint8_t id;
wf282a_read_regs(WF_ID_REG, &id, 1);
if (wf282a_read_regs(WF_ID_REG, &id, 1) != 1) {
xlog("Failed to read chip ID\n");
return 0; // 返回0或一个合适的错误值
}
xlog("wf get id : %d\n", id);
return id;
}
float WF_Temperature_Calculate() {
float Traw_sc;
int32_t Traw = Get_Traw();
Traw_sc = (float)Traw / KT; // 缩放原始温度值
return (float)c0 * 0.5f + (float)c1 * Traw_sc;
}
float WF_Pressure_Calculate() {
float Traw_sc, Praw_sc, Pcomp;
//外部调用
void WF_GET_Temperature_Pressure(float* temperature, float* precessure){
#if 0 //连续测量模式
int32_t Traw = Get_Traw();
xlog("DEBUG: Traw = %ld\n", Traw);
delay(5);
int32_t Praw = Get_Praw();
xlog("DEBUG: Praw = %ld\n", Praw);
#else //单次测量
wf282a_write_reg(WF_MEAS_CFG, 0x02); //内部进行一次温度测量
delay(500);
int32_t Traw = Get_Traw();
xlog("DEBUG: Traw = %ld\n", Traw);
wf282a_write_reg(WF_MEAS_CFG, 0x01); //内部进行一次压力测量
delay(500);
int32_t Praw = Get_Praw();
xlog("DEBUG: Praw = %ld\n", Praw);
Traw_sc = (float)Traw / KT; // 缩放原始温度值
Praw_sc = (float)Praw / KP; // 缩放原始压力值
#endif
// 公式: 手册给出
Pcomp = (float)c00
+ Praw_sc * ((float)c10 + Praw_sc * ((float)c20 + Praw_sc * (float)c30))
+ Traw_sc * (float)c01
+ Traw_sc * Praw_sc * ((float)c11 + Praw_sc * (float)c21);
return Pcomp;
float Traw_sc = (float)Traw / KT; // 缩放原始温度值
double Praw_sc = (double)Praw / KP; // 缩放原始压力值
double precessure_tmp = 0;
*temperature = (float)c0 * 0.5f + (float)c1 * Traw_sc;
precessure_tmp = (double)c00
+ Praw_sc * ((double)c10 + Praw_sc * ((double)c20 + Praw_sc * (double)c30))
+ Traw_sc * (double)c01
+ Traw_sc * Praw_sc * ((double)c11 + Praw_sc + (double)c21);
xlog("temperature:%.3f,precessure: %.3f\n",*temperature, precessure_tmp);
*precessure = (float)precessure_tmp; // 传出
}
float WF_Altitude_Calculate() {
float pressure_pa = WF_Pressure_Calculate();
// 使用标准大气压公式计算海拔

View File

@ -1,18 +1,26 @@
#ifndef _WF282A_H_
#define _WF282A_H_
#include <stdint.h> // 使用标准整数类型
// 标定值
#define KT 524288.0f
// 标定值 (调整为16x过采样对应的Scale Factor)
/*
Oversampling Rate Scale Factor (kP or kT)
1 (single) 524288
2 times (Low Power) 1572864
4 times 3670016
8 times 7864320
16 times (Standard) 253952
32 times 516096
64 times (High Precision) 1040384
128 times 2088960
*/
#define KT 1572864.0f
#define KP 1572864.0f
#define WF_PULL_UP 1 //外部是否接的上拉
#define WF_PULL_UP 0 //外部是否接的上拉
// I2C 从设备地址
#if WF_PULL_UP == 1 //外部接
#define WF_IIC_7BIT_ADDRESS 0x77 //7位,外部接高为0x77
#if WF_PULL_UP == 0 //外部接高为0x77
#define WF_IIC_7BIT_ADDRESS 0x77
#define WF_IIC_WRITE_ADDRESS (WF_IIC_7BIT_ADDRESS<<1) //8位地址
#define WF_IIC_READ_ADDRESS (WF_IIC_WRITE_ADDRESS | 0x01)
#else
@ -20,9 +28,7 @@
#define WF_IIC_WRITE_ADDRESS (WF_IIC_7BIT_ADDRESS<<1) //8位地址
#define WF_IIC_READ_ADDRESS (WF_IIC_WRITE_ADDRESS | 0x01)
#endif
#define WF_CHIP_ID 0X10
// 寄存器映射
// 压力数据
#define WF_PRS_B2 0x00
@ -35,14 +41,14 @@
// 配置寄存器
#define WF_PRS_CFG 0x06
#define WF_TMP_CFG 0x07
#define WF_MEAS_CFG 0x08
#define WF_MEAS_CFG 0x08 // This register is used to trigger single measurements
#define WF_CFG_REG 0x09
#define WF_INT_STS 0x0A
#define WF_FIFO_STS 0x0B
#define WF_RESET_REG 0x0C
// ID寄存器
#define WF_ID_REG 0x0D
// 校准系数寄存器
// 校准系数寄存器 (Offsets match manufacturer's i+0x10 access)
#define COEF_C0 0x10
#define COEF_C0_C1 0x11
#define COEF_C1 0x12
@ -63,44 +69,43 @@
#define COEF_C30_L 0x21
// --- 配置宏 ---
// 压力配置 (PRS_CFG[6:4]) - 测量速率
// 压力配置 (PRS_CFG[6:4]) - 后台测量速率
#define PM_RATE_1 0x00 // 1 次/秒
#define PM_RATE_2 0x01 // 2 次/秒
#define PM_RATE_4 0x02 // 4 次/秒
#define PM_RATE_8 0x03 // 8 次/秒
#define PM_RATE_16 0x04 // 16 次/秒
#define PM_RATE_32 0x05 // 32 次/秒
#define PM_RATE_32 0x05 // 32 次/秒 <--- 建议使用此速率
#define PM_RATE_64 0x06 // 64 次/秒
#define PM_RATE_128 0x07 // 128 次/秒
// 压力配置 (PRS_CFG[3:0]) - 过采样率
#define PM_PRC_1 0x00 // 1 次 (单次)
#define PM_PRC_2 0x01 // 2 次 (低功耗)
#define PM_PRC_4 0x02 // 4 次
#define PM_PRC_8 0x03 // 8 次 (标准)
#define PM_PRC_16 0x04 // 16 次 (需要移位)
#define PM_PRC_32 0x05 // 32 次 (需要移位)
#define PM_PRC_64 0x06 // 64 次 (高精度, 需要移位)
#define PM_PRC_128 0x07 // 128 次 (需要移位)
#define PM_PRC_8 0x03 // 8 次
#define PM_PRC_16 0x04 // 16 次 (标准) <--- 建议使用此过采样率
#define PM_PRC_32 0x05 // 32 次
#define PM_PRC_64 0x06 // 64 次 (高精度)
#define PM_PRC_128 0x07 // 128 次
// 温度配置 (TMP_CFG[7]) - 传感器源
#define TMP_EXT_SENSOR 0x80 // 使用外部传感器
#define TMP_INT_SENSOR 0x00 // 使用内部传感器
// 温度配置 (TMP_CFG[6:4]) - 测量速率
// 温度配置 (TMP_CFG[6:4]) - 后台测量速率
#define TMP_RATE_1 0x00 // 1 次/秒
#define TMP_RATE_2 0x01 // 2 次/秒
#define TMP_RATE_4 0x02 // 4 次/秒
#define TMP_RATE_8 0x03 // 8 次/秒
#define TMP_RATE_16 0x04 // 16 次/秒
#define TMP_RATE_32 0x05 // 32 次/秒
#define TMP_RATE_32 0x05 // 32 次/秒 <--- 建议使用此速率
#define TMP_RATE_64 0x06 // 64 次/秒
#define TMP_RATE_128 0x07 // 128 次/秒
// 温度配置 (TMP_CFG[3:0]) - 过采样率
// 温度配置 (TMP_CFG[2:0]) - 过采样率
#define TMP_PRC_1 0x00 // 1 次
#define TMP_PRC_2 0x01 // 2 次
#define TMP_PRC_4 0x02 // 4 次
#define TMP_PRC_8 0x03 // 8 次
#define TMP_PRC_16 0x04 // 16 次
#define TMP_PRC_16 0x04 // 16 次 <--- 建议使用此过采样率
#define TMP_PRC_32 0x05 // 32 次
#define TMP_PRC_64 0x06 // 64 次
#define TMP_PRC_128 0x07 // 128 次
@ -110,39 +115,39 @@
* @return 0: 成功, 1: 失败
*/
uint8_t WF_Init(void);
/**
* @brief 使传感器进入休眠/待机模式
*/
void WF_Sleep(void);
/**
* @brief 唤醒传感器,开始连续测量
* 在连续模式下通常只需要调用一次WF_Init即可无需频繁调用Wakeup
* 如果WF_Sleep被调用则需要调用WF_Wakeup来恢复连续测量
*/
void WF_Wakeup(void);
void WF_Wakeup(void); // Reinstated for continuous mode control
/**
* @brief 获取传感器芯片ID
* @return 芯片ID (应为 0x10)
*/
uint8_t WF_GetID(void);
/**
* @brief 计算并返回当前海拔高度
* @return 海拔高度 (单位: 米)
*/
float WF_Altitude_Calculate(void);
/**
* @brief 计算并返回补偿后的压力值
* @return 压力 (单位: Pa)
*/
float WF_Pressure_Calculate(void);
/**
* @brief 计算并返回补偿后的温度值
* @return 温度 (单位: °C)
*/
float WF_Temperature_Calculate(void);
void WF_GET_Temperature_Pressure(float* temperature, float* precessure);
// Added Delay_xms prototype (assuming it's implemented in .c file or globally)
void Delay_xms(uint8_t delay);
#endif // _WF282A_H_

View File

@ -1,9 +1,12 @@
#ifndef XTELL_H
#define XTELL_H
#include "system/includes.h"
#include "generic/typedef.h"
// #define KS_BLE 1
#define XTELL_TEST 1
#define ACC_RANGE 16 //g加速度满量程:2、4、8、16
#define BMP280 0
#endif

View File

@ -49,6 +49,8 @@
#include "./sensor/MMC56.h"
#include "./sensor/BMP280.h"
#include "./sensor/AK8963.h"
#include "./sensor/WF282A.h"
#include "./calculate/skiing_tracker.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
//宏定义
#define LOG_TAG_CONST EARPHONE
@ -82,15 +84,31 @@ extern u8 init_ok;
extern u8 sniff_out;
unsigned char xtell_bl_state=0; //存放经典蓝牙的连接状态0断开1是连接
u8 bt_newname =0;
unsigned char xt_ble_new_name[9] = "CM-22222";
unsigned char xt_ble_new_name[9] = "AAAAA";
static u16 play_poweron_ok_timer_id = 0;
// -- 初始化标志位 --
u8 SC7U22_init = 0x10; //六轴是否初始化
u8 MMC5603nj_init = 0x20; //地磁是否初始化
u8 barometer_init = 0x30; //气压计初始化
u8 foot_init = 0x40; //数据来源初始化左脚0x41 or 右脚0x42
// -- 线程id --
u16 gsensor_test_id = 0;
//
///////////////////////////////////////////////////////////////////////////////////////////////////
extern int bt_hci_event_handler(struct bt_event *bt);
extern void SC7U22_static_calibration(void);
extern void create_process(u16* pid, const char* name, void *priv, void (*func)(void *priv), u32 msec);
extern void close_process(u16* pid,char* name);
extern void start_collect_fuc(void);
extern void BLE_send_fuc(void);
extern void start_calibration(void);
extern void start_clloct(void);
extern void stop_clloct(void);
extern void set_foot_state(u8 state);
extern void stop_calibration(void);
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
* 模式状态机, 通过start_app()控制状态切换
@ -174,6 +192,120 @@ static int state_machine(struct application *app, enum app_state state, struct i
///////////////////////////////////////////////////////////////////////////////////////////////////
//handle
void le_user_app_event(u8* buffer){
if (buffer[0] == 0xBE && buffer[1] == 0xBB) {
if(buffer[2] == 0x01){ //后面的数据长度 1
switch (buffer[3]){
case 0x01:
// extern void gsensor_test(void);
// create_process(&gsensor_test_id,"gsensor_test",NULL,gsensor_test,1000);
xlog("ota_test");
cpu_reset();
break;
case 0xff: //测试
u8 device_buff[10];
u8 founds = 0;
extern void i2c_scanner_probe(u8* device_addr, u8* found_number);
i2c_scanner_probe(device_buff,&founds);
for(int i = 0;i < founds;i++){
send_data_to_ble_client(&device_buff,founds);
}
break;
case 0x02:
extern void test_func(void);
test_func();
break;
default:
break;
}
}else if(buffer[2] == 0x02){ //后面数据长度为2
switch (buffer[3]){ //数据包类型
case 0x00: //数据包类型为:指定传感器初始化
u8 send2_0[5] = {0xBB,0xBE,0x02,0x00,0x00};
if(buffer[4] == 0x01){ //六轴
// stop_calibration();
if (SL_SC7U22_Config() == 0) {
SC7U22_init = 0x10;
}else{
SC7U22_init = 0x11;
}
send2_0[4] = SC7U22_init;
send_data_to_ble_client(&send2_0,5);
// start_calibration();
}else if(buffer[4] == 0x02){ //地磁
if(mmc5603nj_init() == 0){
MMC5603nj_init = 0x20;
send2_0[4] = MMC5603nj_init; //地磁初始化失败
send_data_to_ble_client(&send2_0,5);
return;
}
MMC5603nj_init = 0x21;
send2_0[4] = MMC5603nj_init; //地磁初始化成功
send_data_to_ble_client(&send2_0,5);
}else if(buffer[4] == 0x03){ //气压计初始化
#if BMP280
if(BMP280_init() != 0){
//初始化失败
barometer_init = 0x30;
send2_0[4] = barometer_init;
send_data_to_ble_client(&send2_0,5);
return;
}
barometer_init = 0x31;
send2_0[4] = barometer_init; //气压计初始化成功
send_data_to_ble_client(&send2_0,5);
#else
if(WF_Init() != 0){
//初始化失败
barometer_init = 0x30;
send2_0[4] = barometer_init;
send_data_to_ble_client(&send2_0,5);
return;
}
barometer_init = 0x31;
send2_0[4] = barometer_init; //气压计初始化成功
send_data_to_ble_client(&send2_0,5);
#endif
}
break;
case 0x01: //设置传感器采集对象左脚or右脚
u8 send2_1[5] = {0xBB,0xBE,0x06,0x05,0x00};
if(buffer[4] == 0x01){ //设定数据来源是左脚
foot_init = 0x41;
}else if(buffer[4] == 0x02){//设定数据来源是右脚
foot_init = 0x42;
}
send2_1[4] = foot_init;
send_data_to_ble_client(&send2_1,9);
break;
case 0x02: //数据包类型为:获取指定传感器初始化状态
u8 send2_2[5] = {0xBB,0xBE,0x02,0x00,0x00};
if(buffer[4] == 0x01){ //六轴
send2_2[4] = SC7U22_init;
}else if(buffer[4] == 0x02){ //地磁
send2_2[4] = MMC5603nj_init;
}else if(buffer[4] == 0x03){ //气压计
send2_2[4] = barometer_init;
}
send_data_to_ble_client(&send2_2,5);
break;
case 0x03: //开始/停止滑雪计算
if(buffer[4] == 0x01){ //开始滑雪计算
if(SC7U22_init == 0x10 || MMC5603nj_init == 0x20 || barometer_init == 0x30){ //传感器未进行初始化
u8 send2_3[5] = {0xBB,0xBE,0x02,0x00,0x00};
send_data_to_ble_client(&send2_3,5);
return;
}
start_clloct();
}else if(buffer[4] == 0x02){ //停止滑雪计算
stop_clloct();
}
break;
}
}
}
}
void le_user_app_send_event(size_t command, unsigned char* data, size_t size)
@ -203,49 +335,97 @@ void le_user_app_event_handler(struct sys_event* event){
if(event->u.app.buffer[2] == 0x01){ //后面的数据长度 1
switch (event->u.app.buffer[3]){
case 0x01:
char* send_start = "will start after 5 seconds\n";
send_data_to_ble_client(send_start,strlen(send_start));
if (mmc5603nj_init() != 0) {
xlog("MMC5603NJ initialization failed!\n");
char* send_error = "calibration error\n";
send_data_to_ble_client(send_error,strlen(send_error));
// extern void gsensor_test(void);
// create_process(&gsensor_test_id,"gsensor_test",NULL,gsensor_test,1000);
xlog("ota_test");
cpu_reset();
break;
case 0xff: //测试
u8 device_buff[10];
u8 founds = 0;
extern void i2c_scanner_probe(u8* device_addr, u8* found_number);
i2c_scanner_probe(device_buff,&founds);
for(int i = 0;i < founds;i++){
send_data_to_ble_client(&device_buff,founds);
}
xlog("MMC5603NJ PID: 0x%02X\n", mmc5603nj_get_pid());
char* send_tmp = "8th calibration completed\n";
send_data_to_ble_client(send_tmp,strlen(send_tmp));
break;
case 0x02:
extern void create_process(u16* pid,char* name, void *priv, void (*func)(void *priv), u32 msec);
extern void sensor_measure(void);
static int test_id;
SL_SC7U22_Config();
create_process(&test_id, "test",NULL, sensor_measure, 10);
send_tmp = "start_detection\n";
send_data_to_ble_client(send_tmp,strlen(send_tmp));
break;
case 0x03:
extern void start_detection(void);
start_detection();
send_tmp = "start_detection\n";
send_data_to_ble_client(send_tmp,strlen(send_tmp));
break;
case 0x04:
extern void stop_detection(void);
stop_detection();
send_tmp = "stop_detection\n";
send_data_to_ble_client(send_tmp,strlen(send_tmp));
break;
case 0x05:
extern void clear_speed(void);
clear_speed();
send_tmp = "Reset speed and distances to zero\n";
send_data_to_ble_client(send_tmp,strlen(send_tmp));
extern void test_func(void);
test_func();
break;
default:
break;
}
}else if(event->u.app.buffer[2] == 0x02){ //后面数据长度为2
switch (event->u.app.buffer[3]){ //数据包类型
case 0x00: //数据包类型为:指定传感器初始化
u8 send2_0[5] = {0xBB,0xBE,0x02,0x00,0x00};
if(event->u.app.buffer[4] == 0x01){ //六轴
// stop_calibration();
if (SL_SC7U22_Config() == 0) {
SC7U22_init = 0x10; //初始化失败
}else{
SC7U22_init = 0x11;
}
send2_0[4] = SC7U22_init;
send_data_to_ble_client(&send2_0,5);
// start_calibration();
}else if(event->u.app.buffer[4] == 0x02){ //地磁
if(mmc5603nj_init() == 0){
MMC5603nj_init = 0x20;
send2_0[4] = MMC5603nj_init; //地磁初始化失败
send_data_to_ble_client(&send2_0,5);
return;
}
MMC5603nj_init = 0x21;
send2_0[4] = MMC5603nj_init; //地磁初始化成功
send_data_to_ble_client(&send2_0,5);
}else if(event->u.app.buffer[4] == 0x03){ //气压计初始化
if(BMP280_init() != 0){
//初始化失败
barometer_init = 0x30;
send2_0[4] = barometer_init;
send_data_to_ble_client(&send2_0,5);
return;
}
barometer_init = 0x31;
send2_0[4] = barometer_init; //气压计初始化成功
send_data_to_ble_client(&send2_0,5);
}
break;
case 0x01: //设置传感器采集对象左脚or右脚
u8 send2_1[9] = {0xBB,0xBE,0x06,0x05,0x00,0x00,0x00,0x00,0x00};
if(event->u.app.buffer[4] == 0x01){ //设定数据来源是左脚
foot_init = 0x41;
}else if(event->u.app.buffer[4] == 0x02){//设定数据来源是右脚
foot_init = 0x42;
}
send2_1[4] = foot_init;
send_data_to_ble_client(&send2_1,9);
break;
case 0x02: //数据包类型为:获取指定传感器初始化状态
u8 send2_2[5] = {0xBB,0xBE,0x02,0x00,0x00};
if(event->u.app.buffer[4] == 0x01){ //六轴
send2_2[4] = SC7U22_init;
}else if(event->u.app.buffer[4] == 0x02){ //地磁
send2_2[4] = MMC5603nj_init;
}else if(event->u.app.buffer[4] == 0x03){ //气压计
send2_2[4] = barometer_init;
}
send_data_to_ble_client(&send2_2,5);
break;
case 0x03: //开始/停止滑雪计算
if(event->u.app.buffer[4] == 0x01){ //开始滑雪计算
if(SC7U22_init == 0x10 || MMC5603nj_init == 0x20 || barometer_init == 0x30){ //传感器未进行初始化
u8 send2_3[5] = {0xBB,0xBE,0x02,0x00,0x00};
send_data_to_ble_client(&send2_3,5);
return;
}
start_clloct();
}else if(event->u.app.buffer[4] == 0x02){ //停止滑雪计算
stop_clloct();
}
break;
}
}
}

View File

@ -253,6 +253,7 @@
_MASK_MEM_BEGIN = ABSOLUTE(0x19fc00);
_MASK_MEM_SIZE = ABSOLUTE(0x1a4);
EXTERN(
_start
@ -274,25 +275,14 @@ cvsd_decoder
pcm_decoder
mp3_decoder
wtgv2_decoder
aac_decoder
cvsd_encoder
msbc_encoder
audio_dac_driver
);
UPDATA_SIZE = 0x80;
@ -428,6 +418,7 @@ SECTIONS
battery_notify_begin = .;
*(.battery_notify)
battery_notify_end = .;
. = ALIGN(4);
__VERSION_BEGIN = .;
KEEP(*(.sys.version))
@ -518,6 +509,7 @@ SECTIONS
*(.audio_track_data)
*(.audio_adc_data)
. = ALIGN(4);
*(.data*)
@ -726,6 +718,7 @@ SECTIONS
} > ram0
data_code_pc_limit_end = .;
__report_overlay_end = .;
@ -815,6 +808,7 @@ SECTIONS
}
SECTIONS
{
.data : ALIGN(4)
@ -846,6 +840,7 @@ SECTIONS
UPDATE_CODE_TOTAL_SIZE = update_code_end - update_code_start;
}
SECTIONS
{
.data : ALIGN(4)
@ -948,6 +943,7 @@ BTSTACK_LE_HOST_MESH_RAM_TOTAL = BTSTACK_LE_HOST_MESH_DATA_SIZE + BTSTACK_LE_HOS
BTSTACK_LE_HOST_MESH_FLASH_TOTAL = BTSTACK_LE_HOST_MESH_CODE_SIZE;
BTSTACK_CODE_SIZE = (btstack_code_end - btstack_code_start) + (btstack_data_end - btstack_data_start);
SECTIONS
{
.data : ALIGN(4)
@ -1241,6 +1237,7 @@ SECTIONS
*(.os_code)
} > ram0
}
SECTIONS
{
.data : ALIGN(4)
@ -1450,6 +1447,7 @@ SECTIONS
BTCTLER_RAM_TOTAL = (btctler_data_end - btctler_data_start) + (btctler_bss_end - btctler_bss_start);
BTCTLER_CODE_TOTAL = (btctler_code_end - btctler_code_start);
}
SECTIONS
{
.data : ALIGN(4)
@ -1567,6 +1565,7 @@ SECTIONS
*(.timer.text.cache.L1)
*(.gpio.text.cache.L1)
*(.iic_hw.text.cache.L1)
driver_data_code_end = .;
. = ALIGN(4);
} > ram0
@ -1577,6 +1576,7 @@ SECTIONS
DRIVER_DATA_CODE_TOTAL = (driver_data_code_end - driver_data_code_start);
}
SECTIONS
{
.data : ALIGN(4)
@ -2016,6 +2016,7 @@ SECTIONS
} > ram0
}
text_begin = ADDR(.text);
text_size = SIZEOF(.text);
text_end = text_begin + text_size;

View File

@ -33,19 +33,7 @@ cvsd_decoder
pcm_decoder
mp3_decoder
wtgv2_decoder
aac_decoder
cvsd_encoder

View File

Binary file not shown.

Binary file not shown.

View File

@ -61,4 +61,4 @@ copy /b text.bin + data.bin + mov_slot.bin + data_code.bin + aec.bin + aac.bin +
del !bankfiles! common.bin text.bin data.bin bank.bin
copy eq_cfg_hw_less.bin eq_cfg_hw.bin
call download/earphone/download_app_ota.bat
call download/earphone/download.bat

View File

@ -10,7 +10,7 @@ copy ..\..\ota.bin .
copy ..\..\anc_coeff.bin .
copy ..\..\anc_gains.bin .
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin ..\..\eq_cfg_hw.bin -uboot_compress -key AC69.key -format all -key 646-AC690X-7603.key
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin ..\..\eq_cfg_hw.bin -uboot_compress -format all -key 646-AC690X-7603.key
@REM..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br34 -boot 0x20000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin ..\..\cfg_tool.bin -res tone.cfg kws_command.bin p11_code.bin -uboot_compress

View File

@ -10,7 +10,7 @@ copy ..\..\ota.bin .
copy ..\..\anc_coeff.bin .
copy ..\..\anc_gains.bin .
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin ..\..\eq_cfg_hw.bin -uboot_compress -key 646-AC690X-7603.key
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin ..\..\eq_cfg_hw.bin -uboot_compress
@REM..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br34 -boot 0x20000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin ..\..\cfg_tool.bin -res tone.cfg kws_command.bin p11_code.bin -uboot_compress

View File

@ -11,7 +11,7 @@ copy ..\..\anc_coeff.bin .
copy ..\..\anc_gains.bin .
:: -format all -key AC690X-8029.key
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin ..\..\eq_cfg_hw.bin -uboot_compress -key AC690X-8029.key
..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br28 -boot 0x120000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin -res ..\..\cfg_tool.bin tone.cfg p11_code.bin ..\..\eq_cfg_hw.bin -uboot_compress
@REM..\..\isd_download.exe ..\..\isd_config.ini -tonorflash -dev br34 -boot 0x20000 -div8 -wait 300 -uboot ..\..\uboot.boot -app ..\..\app.bin ..\..\cfg_tool.bin -res tone.cfg kws_command.bin p11_code.bin -uboot_compress

View File

@ -14,13 +14,12 @@
[EXTRA_CFG_PARAM]
NEW_FLASH_FS = YES;
BR22_TWS_DB = YES;
FLASH_SIZE = 0x100000;
BR22_TWS_VERSION = 0;
FORCE_4K_ALIGN = YES;
SPECIAL_OPT = 0;
CHIP_NAME = AC701N;
ENTRY = 0x6000100;
PID = AC701N;
@ -63,6 +62,12 @@ SPI = 2_3_0_0;
UTTX = PB02;
UTBD = 1000000;
UTRX = PP00;
RESET = PA04_01_0;
[FW_ADDITIONAL]
FILE_LIST = (file = ota.bin: type = 100);
[RESERVED_CONFIG]

View File

@ -205,7 +205,7 @@ UTRX = CONFIG_UART_UPDATE_PIN; //串口升级[PB00 PB05 PA05]
/* RESET = CAT3(CONFIG_RESET_PIN, CONFIG_RESET_TIME, CONFIG_RESET_LEVEL); //port口_长按时间_有效电平长按时间有00、01、02、04、08三个值可选单位为秒当长按时间为00时则关闭长按复位功能。 */
#ifdef CONFIG_SUPPORT_RESET1
RESET1 = CAT3(CONFIG_RESET1_PIN, CONFIG_RESET1_TIME, CONFIG_RESET1_LEVEL); //port口_长按时间_有效电平长按时间有00、01、02、04、08三个值可选单位为秒当长按时间为00时则关闭长按复位功能。
RESET = CAT3(CONFIG_RESET1_PIN, CONFIG_RESET1_TIME, CONFIG_RESET1_LEVEL); //port口_长按时间_有效电平长按时间有00、01、02、04、08三个值可选单位为秒当长按时间为00时则关闭长按复位功能。
#endif
#ifdef CONFIG_VDDIO_LVD_LEVEL

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,16 +19,17 @@
#include "ble/ll_config.h"
// #define CONFIG_LE_FEATURES \
(\
LE_ENCRYPTION | \
LE_CORE_V50_FEATURES \
)
// (\
// LE_ENCRYPTION | \
// LE_CORE_V50_FEATURES \
// )
#define CONFIG_LE_FEATURES 0//(LE_ENCRYPTION)
// #define CONFIG_LE_FEATURES (LE_CORE_V50_FEATURES | LE_DATA_PACKET_LENGTH_EXTENSION)//(LE_ENCRYPTION)
#define CONFIG_LE_FEATURES 0
// #define CONFIG_LE_ROLES (LE_ADV|LE_SCAN|LE_INIT|LE_SLAVE|LE_MASTER)
// #define CONFIG_LE_ROLES (LE_ADV|LE_SCAN)
#define CONFIG_LE_ROLES (LE_ADV)
#define CONFIG_LE_ROLES (LE_ADV|LE_SCAN)
// #define CONFIG_LE_ROLES (LE_ADV)
#include "classic/lmp_config.h"

Some files were not shown because too many files have changed in this diff Show More