Files
99_7018_lmx/apps/earphone/xtell_remote_control/task_func.c
2025-12-18 18:33:00 +08:00

491 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "task_func.h"
#include "./nvs/nvs.h"
#include "timer.h"
#include "system/includes.h"
#include "user_cfg.h"
#include "earphone.h" // 宏定义 EARPHONE_STATE_...
#include "ble_user.h"
#include "le_client_demo.h"
#include "le_common.h"
#include "./ble_handler/client_handler.h"
#include "./RFID/include/rfid_main.h"
#include "./RFID/include/READER_REG.h"
// ==================================================================================================================================================================
// 宏定义与日志
// ==================================================================================================================================================================
#define RC_LOG_ENABLE 1
#if RC_LOG_ENABLE
#define rc_log(format, ...) printf("[RC_APP] " format, ##__VA_ARGS__)
#else
#define rc_log(format, ...)
#endif
// ==================================================================================================================================================================
// 外部函数声明
// ==================================================================================================================================================================
extern void TYPE_V_EVENT(char* uid);
extern void TYPE_A_EVENT(char* uid);
// ==================================================================================================================================================================
// 静态函数声明
// ==================================================================================================================================================================
static RFID_Device_Type_t get_rfid_device_type(const u8* uid);
// BLE 状态转换的辅助函数
static void rc_ble_state_set_connecting(void);
static void rc_ble_state_set_connected(void);
static void rc_ble_state_set_disconnected(void);
//进程名称
static char control_key_task_name[] = "control_key";
//进程运行中标志
static u8 key_detect_sign = 0; //为1表示正在运行
// ==================================================================================================================================================================
// 全局变量
// ==================================================================================================================================================================
static RC_Context_t g_rc_context; // 全局上下文实例
static u16 g_rfid_timer_id = 0; // RFID 定时器ID
static u16 g_ble_timer_id = 0; // BLE 定时器ID
static u8 current_board_mac[MAIN_BOARD_MAC_ADDR_LENGTH] = {0}; //当前连接主板的名称 -- mac
// ==================================================================================================================================================================
// rfid功能相关
// ==================================================================================================================================================================
/**
* @brief RFID回调处理函数 (由定时器周期性调用)
*/
void rc_rfid_callback_handler(void *priv)
{
u8 uid[UID_LENGTH] = {0};
//读id卡
// TYPE_V_EVENT((char *)uid);
TYPE_A_EVENT((char *)uid);
//是否有rfid卡靠近
u8 is_new_data = 0;
for (int i = 0; i < UID_LENGTH; i++) {
if (uid[i] != 0x00) {
is_new_data = 1;
break;
}
}
if (!is_new_data) {
return; //没有rfid卡靠近返回
}
rc_log("New RFID card detected.\n");
RFID_Device_Type_t device_type = get_rfid_device_type(uid);
switch (device_type) {
case RFID_DEVICE_TYPE_MAIN_BOARD: //船主板上的rfid卡
if(strncmp(uid, current_board_mac, UID_LENGTH) == 0){
// 扫到的rfid卡的uid和当前连接的主板mac相同
return;
}
//扫到新的主板
rc_log("Device is Main Board. Storing MAC...\n");
// 将新的MAC地址写入Flash
nvs_write_main_board_mac(uid);
// memset(current_board_mac, uid, sizeof(current_board_mac));
// TODO发送指令让主板断开经典蓝牙连接
// TODO: 切断BLE
// g_ble_connect_new_device(current_board_mac); //连接新主板
break;
case RFID_DEVICE_TYPE_REMOTE_CONTROL: //扫的是遥控器
rc_log("Device is another Remote Control.\n");
if(g_rc_context.team != TEAM_YES){
nvs_clear_info(); //清楚nfc数据
return; //非组队状态
}
if (g_ble_get_state() == BLE_ST_NOTIFY_IDICATE) {
rc_log("Sending teaming request to main board...\n");
//TODO:
//向主板发送新的遥控器rfid uid
} else {
rc_log("Not connected to main board, ignoring teaming request.\n");
}
break;
default:
rc_log("Unknown RFID device type.\n");
break;
}
}
// ==================================================================================================================================================================
// ble功能相关
// ==================================================================================================================================================================
/**
* @brief BLE回调处理函数 (由定时器周期性调用)s
*/
void rc_ble_callback_handler(void *priv)
{
u8 read_uid[UID_LENGTH] = {0};
nvs_read_main_board_mac(read_uid); //读nvs
//读到的是当前连接的主板uid
if((strncmp(read_uid, current_board_mac, UID_LENGTH) == 0) && g_ble_get_state()){
return;
}
//
// bool is_connected = ble_hid_is_connected();
// // 状态机转换
// if (is_connected && g_rc_context.state != RC_STATE_CONNECTED) {
// rc_ble_state_set_connected();
// } else if (!is_connected && g_rc_context.state != RC_STATE_DISCONNECTED) {
// rc_ble_state_set_disconnected();
// }
// // 状态机行为
// switch (g_rc_context.state) {
// case RC_STATE_DISCONNECTED:
// {
// u8 target_mac[MAC_ADDR_LENGTH] = {0};
// // 检查Flash中是否有已配对的MAC
// if (nvs_read_main_board_mac(target_mac) > 0) {
// rc_log("Found paired MAC. Start scanning...\n");
// // 启动扫描和连接。SDK的HID实现会自动连接到已配对的设备。
// EARPHONE_STATE_SET_PAGE_SCAN_ENABLE();
// } else {
// rc_log("No paired MAC found. Waiting for RFID pairing...\n");
// }
// }
// break;
// case RC_STATE_CONNECTING:
// // 在这个状态下,我们只是等待 is_connected 变为 true
// rc_log("Waiting for connection result...\n");
// break;
// case RC_STATE_CONNECTED:
// // 已连接,目前无需周期性操作
// // rc_log("BLE is connected.\n");
// break;
// default:
// break;
// }
}
/**
* @brief 根据UID前缀判断设备类型
*/
static RFID_Device_Type_t get_rfid_device_type(const u8* uid)
{
if (uid == NULL) {
return RFID_DEVICE_TYPE_UNKNOWN;
}
// 根据 RC_app_main.h 中定义的UID前缀进行判断
if (uid[0] == UID_PREFIX_MAIN_BOARD) {
return RFID_DEVICE_TYPE_MAIN_BOARD;
} else if (uid[0] == UID_PREFIX_REMOTE_CONTROL) {
return RFID_DEVICE_TYPE_REMOTE_CONTROL;
}
return RFID_DEVICE_TYPE_UNKNOWN;
}
// ==================================================================================================================================================================
// 遥感按键相关
// ==================================================================================================================================================================
/**
* @brief 遥感按键初始化
*
*/
void control_key_init(void){
//Yout
adc_add_sample_ch(AD_CH_PG5);
gpio_set_die(IO_PORTG_05, 0);
gpio_set_direction(IO_PORTG_05, 1);
gpio_set_pull_down(IO_PORTG_05, 0);
gpio_set_pull_up(IO_PORTG_05, 0);
//Xout
adc_add_sample_ch(AD_CH_PG7);
gpio_set_die(IO_PORTG_07, 0);
gpio_set_direction(IO_PORTG_07, 1);
gpio_set_pull_down(IO_PORTG_07, 0);
gpio_set_pull_up(IO_PORTG_07, 0);
//key 1默认为高按下为低
gpio_set_die(IO_PORTG_06, 1);
gpio_set_direction(IO_PORTG_06, 1);
gpio_set_pull_down(IO_PORTG_06, 0);
gpio_set_pull_up(IO_PORTG_06, 1);
}
/**
* @brief 获取遥感按键值
*
* @param Xout_adc x轴遥感adc
* @param Yout_adc y轴遥感adc
* @param key1_state 按键1值
* @param key2_state 按键2值
*/
void control_key_get_value(u16* Xout_adc, u16* Yout_adc, u8* key1_state, u8* key2_state){
*Xout_adc = (u16)adc_get_value(AD_CH_PG5) * 64;
*Yout_adc = (u16)adc_get_value(AD_CH_PG7) * 64;
if(*Yout_adc >= 65535){
*Yout_adc = 65535;
}
if(*Xout_adc >= 65535){
*Xout_adc = 65535;
}
*key1_state = gpio_read(IO_PORTG_06);
rc_log("adc_get_value: Xout = %d, Yout = %d, key1_state = %d, key2_state = %d\n", *Xout_adc , *Yout_adc, *key1_state, 1);
}
/**
* @brief 按键的处理任务
*
*/
void contol_key_task(void){
static u16 vbat_value = 0; //当前剩余电量
static u16 Xout_adc = 0;
static u16 Yout_adc = 0;
static u8 key1_state = 1;
u8 ble_data_buff[12] = {0xBE, 0xBB, 0x09, 0x01, //0-3
0x00, 0x00, 0x00, 0x00, //4-7 遥感值:上下、左右
0x00, 0x00, //8、9 两个按键
0x00, //10 电量百分比
0x00}; //11 校验和
control_key_init(); //遥感按键初始化
while(1){
extern u16 get_vbat_level(void);
vbat_value = get_vbat_level(); //当前电量
control_key_get_value(&Xout_adc, &Yout_adc, &key1_state, NULL); //遥感值
ble_data_buff[4] = (u8)(Yout_adc & 0xFF);
ble_data_buff[5] = (u8)((Yout_adc >> 8) & 0xFF);
ble_data_buff[6] = (u8)(Xout_adc & 0xFF);
ble_data_buff[7] = (u8)((Xout_adc >> 8) & 0xFF);
ble_data_buff[8] = key1_state;
ble_data_buff[9] = 0x01;
ble_data_buff[10] = get_vbat_percent();
ble_data_buff[11] = 0;
for(int i = 0 ;i < 11; i++){
ble_data_buff[11] += ble_data_buff[i];
}
g_send_data_to_ble_server(ble_data_buff, sizeof(ble_data_buff));
/*
1000
700
500
*/
os_time_dly(60); //10ms为单位
}
}
/**
* @brief 和主板ble连接上后会被调用
*
*/
void create_key_detect_thread(void){
key_detect_sign = 1;
os_task_create(contol_key_task, NULL, 1, 2048, 128, control_key_task_name);
}
/**
* @brief 和主板ble断连后会被调用
*
*/
void destroy_key_detect_thread(void){
if(key_detect_sign == 1){
key_detect_sign = 0;
os_task_del(control_key_task_name);
}
}
// ==================================================================================================================================================================
// 辅助函数
// ==================================================================================================================================================================
/**
* @brief 进入 CONNECTING 状态的逻辑
*/
static void rc_ble_state_set_connecting(void)
{
rc_log("State transition to -> CONNECTING\n");
g_rc_context.state = RC_STATE_CONNECTING;
// 可以在这里控制LED灯效例如黄灯呼吸闪烁
}
/**
* @brief 进入 CONNECTED 状态的逻辑
*/
static void rc_ble_state_set_connected(void)
{
rc_log("State transition to -> CONNECTED\n");
g_rc_context.state = RC_STATE_CONNECTED;
// 停止扫描以省电
EARPHONE_STATE_CANCEL_PAGE_SCAN();
// 发送指令,要求主板连接遥控器的经典蓝牙
u8 classic_conn_req_payload[] = {0x01, 0x02, 0x03};
rc_log("Sending request for classic BT connection.\n");
ble_hid_data_send(0xFE, classic_conn_req_payload, sizeof(classic_conn_req_payload));
// 在这里控制LED灯效例如蓝灯呼吸闪烁三次后熄灭
}
/**
* @brief 进入 DISCONNECTED 状态的逻辑
*/
static void rc_ble_state_set_disconnected(void)
{
rc_log("State transition to -> DISCONNECTED\n");
g_rc_context.state = RC_STATE_DISCONNECTED;
// 在这里控制LED灯效例如黄灯呼吸闪烁
}
// ==================================================================================================================================================================
// 初始化函数
// ==================================================================================================================================================================
/**
* @brief 遥控器应用主初始化函数
*/
void rc_app_main_init(void)
{
rc_log("Initializing Remote Control App...\n");
// 初始化全局上下文
memset(&g_rc_context, 0, sizeof(RC_Context_t));
g_rc_context.state = RC_STATE_DISCONNECTED; // 初始状态为未连接
g_rc_context.team = TEAM_NO;
FM176XX_HardInit();
// 检查并启动RFID处理定时器
if (g_rfid_timer_id == 0) {
// g_rfid_timer_id = sys_timer_add(NULL, rc_rfid_callback_handler, RC_RFID_CALLBACK_INTERVAL_MS);
rc_log("RFID handler timer started (ID: %d).\n", g_rfid_timer_id);
}
// 检查并启动BLE处理定时器
if (g_ble_timer_id == 0) {
// g_ble_timer_id = sys_timer_add(NULL, rc_ble_callback_handler, RC_BLE_CALLBACK_INTERVAL_MS);
rc_log("BLE handler timer started (ID: %d).\n", g_ble_timer_id);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
//test
#define TEST_FUNCTION 1
void g_i2c_scanner_probe(u8* device_addr, u8* found_number)
{
printf("Starting I2C bus scan...\n");
int devices_found = 0;
// I2C地址范围是 0x08 到 0x77
for (uint8_t addr_7bit = 0x00; addr_7bit < 0x7F; addr_7bit++)
{
// 构建8位的写地址
uint8_t write_addr_8bit = (addr_7bit << 1);
//传入使用的iic句柄编号
soft_iic_start(0);
// 尝试发送写地址,并检查返回值
// iic_tx_byte 返回 1 表示收到了 ACK
if (soft_iic_tx_byte(0, write_addr_8bit))
{
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);
printf("=====================================================================\n");
devices_found++;
}
//传入使用的iic句柄编号
soft_iic_stop(0);
mdelay(2); // 短暂延时
}
if (devices_found == 0) {
printf("Scan finished. No I2C devices found.\n");
} else {
printf("Scan finished. Found %d device(s).\n", devices_found);
}
}
void test_task(void){
#if TEST_FUNCTION == 1
unsigned char reg_data = 0;
FM176XX_HardInit();
rfid_delay_ms(5); // 硬件初始化后增加一个短暂延时,确保芯片稳定
int result = FM176XX_SoftReset();
if (result != SUCCESS)
{
rc_log("FM176XX HardReset FAIL\r\n");
}
else
{
rc_log("FM176XX HardReset SUCCESS\r\n");
}
rfid_delay_ms(10); // 复位后延时
// 读取芯片版本号,确认通信是否正常
GetReg(REG_VERSION, &reg_data);
rc_log("REG_VERSION = %02X\r\n", reg_data);
u8 device_buff[10];
u8 founds = 0;
extern void g_i2c_scanner_probe(u8* device_addr, u8* found_number);
g_i2c_scanner_probe(device_buff,&founds);
while(1){
u8 uid[UID_LENGTH] = {0};
//读id卡
TYPE_V_EVENT((char *)uid);
// TYPE_A_EVENT((char *)uid);
os_time_dly(500);
}
#endif
}
void test_func_main(void){
#if TEST_FUNCTION == 1
os_task_create(test_task, NULL, 1, 1024, 128, "rfid_test");
// os_task_create(contol_key_task, NULL, 1, 2048, 128, control_key_task_name);
#endif
}