#include "system/includes.h" #include "btstack/btstack_task.h" #include "app_config.h" #include "app_action.h" #include "asm/pwm_led.h" #include "tone_player.h" #include "ui_manage.h" #include "gpio.h" #include "app_main.h" #include "asm/charge.h" #include "update.h" #include "app_power_manage.h" #include "audio_config.h" #include "app_charge.h" #include "bt_profile_cfg.h" #include "dev_manager/dev_manager.h" #include "update_loader_download.h" #include "LIS2DH12.h" #include "circle_buffer.h" #include "circle_buffer.h" #include "btstack/avctp_user.h" #define xlog(format, ...) printf("[%s] " format, __func__, ##__VA_ARGS__) // --- 任务ID --- static u16 xtell_i2c_test_id; static u16 collect_data_id; static u16 send_data_id; // --- 环形缓冲区 --- #define SENSOR_DATA_BUFFER_SIZE 512 static u8 sensor_data_buffer[SENSOR_DATA_BUFFER_SIZE]; static circle_buffer_t sensor_cb; // --- 蓝牙SPP --- static u8 spp_connected = 0; //处理从手机接收到的SPP命令 static void handle_spp_command(u8 *packet, u16 size) { if (size == 10 && strncmp((const char *)packet, "disconnect", 10) == 0) { xlog("Received the 'disconnect' command, preparing to terminate the connection...\n"); // 发送一个通用的断开连接命令 user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL); } else { xlog("Received an unknown SPP command. The content is as follows:\n"); put_buf(packet, size); } } // SPP事件处理 (移除static使其全局可见) void xtell_spp_data_handler(u8 packet_type, u16 ch, u8 *packet, u16 size) { xlog("xtell_spp_data_handler\n"); switch (packet_type) { case 1: // SPP_CONNECT xlog("SPP connected\n"); spp_connected = 1; break; case 2: // SPP_DISCONNECT xlog("SPP disconnected\n"); spp_connected = 0; break; case 7: // SPP_DATA // 调用命令处理函数 handle_spp_command(packet, size); break; default: xlog("spp event error\n"); break; } } // 采集传感器数据并存入环形缓冲区的任务 void collect_and_buffer_sensor_data_task(void) { if (!spp_connected) { xlog("SPP not connected. Skipping data collection.\n"); return; // 如果未连接,则不采集数据 } motion_data_t current_motion; axis_info_xtell total_accel; axis_info_xtell linear_accel; char data_string[256]; // 从驱动获取最新的运动数据 get_motion_data(¤t_motion); total_accel = get_current_accel_mss(); linear_accel = get_linear_accel_mss(); // 将浮点数据转换为整数(乘以100以保留两位小数)进行格式化 int len = snprintf(data_string, sizeof(data_string), "T:%d,%d,%d;L:%d,%d,%d;V:%d,%d,%d;D:%d,%d,%d\n", (int)(total_accel.x * 100), (int)(total_accel.y * 100), (int)(total_accel.z * 100), (int)(linear_accel.x * 100), (int)(linear_accel.y * 100), (int)(linear_accel.z * 100), (int)(current_motion.velocity.x * 100), (int)(current_motion.velocity.y * 100), (int)(current_motion.velocity.z * 100), (int)(current_motion.distance.x * 100), (int)(current_motion.distance.y * 100), (int)(current_motion.distance.z * 100)); // 写入环形缓冲区 u16 written = circle_buffer_write(&sensor_cb, (u8*)data_string, len); if (written < len) { xlog("The circular buffer is full!\n"); } } // 从环形缓冲区读取数据并通过SPP发送的任务 void send_sensor_data_task(void) { // xlog("发送任务执行,连接状态: %d, 缓冲区大小: %d\n", spp_connected, circle_buffer_get_size(&sensor_cb)); if (!spp_connected || circle_buffer_get_size(&sensor_cb) == 0) { return; } #define MAX_SPP_PACKET_SIZE 128 // 根据实际情况调整 u8 send_buf[MAX_SPP_PACKET_SIZE]; u16 len_to_read = circle_buffer_get_size(&sensor_cb); if (len_to_read > MAX_SPP_PACKET_SIZE) { len_to_read = MAX_SPP_PACKET_SIZE; } u16 read_len = circle_buffer_read(&sensor_cb, send_buf, len_to_read); if (read_len > 0) { user_send_cmd_prepare(USER_CTRL_SPP_SEND_DATA, read_len, send_buf); } xlog("send data by spp\n"); } void create_process(u16* pid, const char* name, void *priv, void (*func)(void *priv), u32 msec){ xlog("Create Task: %s, pid=%d\n", name, *pid); if (*pid != 0) return; *pid = sys_timer_add(priv, func, msec); xlog("Task %s is created, pid=%d\n", name, *pid); } void rcsp_adv_fill_mac_addr(u8 *mac_addr_buf) //by xtell { swapX(bt_get_mac_addr(), mac_addr_buf, 6); } void xtell_main(void){ u8 mac_data[6]; soft_iic_init(0); extern u8 LIS2DH12_Config(void); LIS2DH12_Config(); rcsp_adv_fill_mac_addr(mac_data); //读取MAC地址 xlog("xtell BT mac data:%x:%x:%x:%x:%x:%x",mac_data[0],mac_data[1],mac_data[2],mac_data[3],mac_data[4],mac_data[5]); //开经典蓝牙 user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_ENABLE, 0, NULL); //打开蓝牙可发现,已连接时不能操作 delay_2ms(50); user_send_cmd_prepare(USER_CTRL_WRITE_CONN_ENABLE, 0, NULL); //打开蓝牙可连接 delay_2ms(50); // connect_last_device_from_vm(); //自动回连上一个设备 // 初始化环形缓冲区 circle_buffer_init(&sensor_cb, sensor_data_buffer, SENSOR_DATA_BUFFER_SIZE); // 注册SPP数据处理回调 (此操作已由earphone.c统一处理,此处不再需要) /* spp_data_deal_handle_register(xtell_spp_data_handler); */ // 创建一个定时器,每200ms调用一次核心计算任务 create_process(&xtell_i2c_test_id, "xtell_i2c_test", NULL, xtell_i2c_test, (u32)(SAMPLING_PERIOD_S * 1000)); // 创建一个定时器,每1000ms采集一次数据 create_process(&collect_data_id, "collect_data", NULL, collect_and_buffer_sensor_data_task, 1000); // 创建一个定时器,每200ms尝试发送一次数据 create_process(&send_data_id, "send_data", NULL, send_sensor_data_task, 200); }