/*Includes ----------------------------------------------*/ #include "ble_gap.h" #include "ble_comm.h" #include "bsp_time.h" #include "system.h" #include "hal_mt.h" #include "hal_led.h" #include "app_flash.h" #include "app_single_line_pair.h" /*Private macro ------------------------------------------------*/ #define APP_SINGLE_LINE_PAIR_TRIGGER_TIMES 1 //触发次数 #define APP_SINGLE_LINE_PAIR_CMD 0x00 //配对指令 #define APP_SINGLE_LINE_PAIR_LR_CMD 0x01 //获取左右指令 #define APP_SINGLE_LINE_PAIR_TIMEOUT ((FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS* \ FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN*8) / 1000) //配对超时时间 单位:ms /*STRUCTION -----------------------------------------------------*/ typedef enum { APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE = 0, //配对状态 —— 配对完成 APP_SINGLE_LINE_PAIR_STATE_PAIR_ING, //配对状态 —— 配对中 APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL, //配对状态 —— 配对失败 } APP_SINGLE_LINE_PAIR_STATE_e; //配对状态 typedef struct _app_single_line_pair { APP_SINGLE_LINE_PAIR_ROLE_e role; //角色 APP_SINGLE_LINE_PAIR_STATE_e state; //配对状态 uint8_t mac[6]; //物理地址 int trigger_times; //触发次数 uint32_t pair_timeout_ms; //配对超时 int pair_flow; //配对流程 int save_adv_scan_flow; //保存、广播、扫描流程 } App_Single_Line_Pair_t; /*Local Variable ----------------------------------------------*/ static App_Single_Line_Pair_t ob_app_single_line_pair; /*Local Functions ----------------------------------------------*/ static void app_single_line_pair_Process(void); static void app_single_line_pair_save_adv_or_scan_Process(void) { static uint32_t tim =0; char buf[16]; switch(ob_app_single_line_pair.save_adv_scan_flow) { case 0: MT_Run(500); if(memcmp(&mFlash.mClient.macAddr[3],&ob_app_single_line_pair.mac[3],3) == 0 && memcmp(&mFlash.macHost[0],&ob_app_single_line_pair.mac[0],3) == 0) //若已配对过 { DEBUG_LOG(">>>>>>>>already paired \r\n"); //只有配对成功时,才运行。 Process_Stop(app_single_line_pair_save_adv_or_scan_Process); //关灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); //更新状态 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE; } else //若没配对过 { //配对时候清空所有的步数 if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_DATEStep,"clear step fail");break;} memset(&mFlash.mStep,0,sizeof(FlashStep_t)); mFlash.mClient.isConfig = 'C'; if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DATEStep,"save step fail"); //右鞋地址 mFlash.mClient.macAddr[0] = 0; mFlash.mClient.macAddr[1] = 0; mFlash.mClient.macAddr[2] = 0; mFlash.mClient.macAddr[3] = ob_app_single_line_pair.mac[3]; mFlash.mClient.macAddr[4] = ob_app_single_line_pair.mac[4]; mFlash.mClient.macAddr[5] = ob_app_single_line_pair.mac[5]; //左鞋地址 mFlash.macHost[0] = ob_app_single_line_pair.mac[0]; mFlash.macHost[1] = ob_app_single_line_pair.mac[1]; mFlash.macHost[2] = ob_app_single_line_pair.mac[2]; mFlash.macHost[3] = 0; mFlash.macHost[4] = 0; mFlash.macHost[5] = 0; ob_app_single_line_pair.save_adv_scan_flow =1; tim = TIME_GetTicks(); } break; case 1: if(TIME_GetTicks()-tim>=10000) { tim = TIME_GetTicks();//10秒超时退出 //只有配对成功时,才运行。 Process_Stop(app_single_line_pair_save_adv_or_scan_Process); //关灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); //更新状态 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL; } if(ob_app_single_line_pair.role == APP_SINGLE_LINE_PAIR_ROLE_HOST) //主机处理 { if(host_isconnect()) { host_disconnect(); } else { DEBUG_LOG(">>>>>ST_scan_start =0 \r\n"); memset(buf,0,sizeof(buf)); sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]); DEBUG_LOG("scanName(%d):%s\n",strlen(buf),buf); host_set_scan_name(buf,strlen(buf)); ST_scan_stop(); ST_scan_start(); //只有配对成功时,才运行。 Process_Stop(app_single_line_pair_save_adv_or_scan_Process); //关灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); //更新状态 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE; } } else //从机处理 { if(slave_isconnect()) { slave_disconnect(); } else { memset(buf,0,sizeof(buf)); sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]); DEBUG_LOG("advName(%d):%s\n",strlen(buf),buf); slave_set_adv_name(buf,strlen(buf)); advertising_stop(); slave_adv_init(); DEBUG_LOG(">>>>>>>>advertising_start =0 \r\n"); advertising_start(); //只有配对成功时,才运行。 Process_Stop(app_single_line_pair_save_adv_or_scan_Process); //关灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); //更新状态 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE; } } break; } } static void app_single_line_pair_host_process(uint8_t byte) { static int index = 0; DEBUG_LOG("host_process:%d\r\n",byte); switch(ob_app_single_line_pair.pair_flow) { case 0: //接收指令阶段 if(byte == APP_SINGLE_LINE_PAIR_CMD) { if(bll_single_line_half_duplex_is_ready_to_transfer() == 0) { if(bll_single_line_half_duplex_transfer_onebyte(ob_app_single_line_pair.mac[0]) == 0) { index = 0; ob_app_single_line_pair.pair_flow = 1; } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 } } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 } } //获取左右指令 if(byte == APP_SINGLE_LINE_PAIR_LR_CMD) { if(bll_single_line_half_duplex_is_ready_to_transfer() == 0) { if(mFlash.isHost == 1) bll_single_line_half_duplex_transfer_onebyte(0x55); else bll_single_line_half_duplex_transfer_onebyte(0x56); } } break; case 1: //发送数据阶段 ob_app_single_line_pair.mac[3 + index] = byte; if(bll_single_line_half_duplex_is_ready_to_transfer() == 0 && index != 2) { if(bll_single_line_half_duplex_transfer_onebyte(ob_app_single_line_pair.mac[index + 1]) == 0) { index++; } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 } } else { if(index == 2) { ob_app_single_line_pair.pair_flow = 0; ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE; ob_app_single_line_pair.save_adv_scan_flow = 0; //注册线程任务,用于处理保存、广播、扫描 Process_Start(0,"app_single_line_pair_save_adv_or_scan_Process",app_single_line_pair_save_adv_or_scan_Process); } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 } } break; } } static void app_single_line_pair_slave_process(uint8_t byte) { static int index = 0; DEBUG_LOG("--->s index:%d flow:%d byte:%d\r\n",index,ob_app_single_line_pair.pair_flow,byte); switch(ob_app_single_line_pair.pair_flow) { case 0: //接收指令阶段 if(byte == APP_SINGLE_LINE_PAIR_CMD) { //更改状态 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_ING; //记录配对开始时间 ob_app_single_line_pair.pair_timeout_ms = TIME_GetTicks(); DEBUG_LOG("cmd TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER); //全功率配对 Process_SetHoldOn(app_single_line_pair_Process,1); //亮灯 LED_Start(LED_PAIR,COLOR_BLUE); if(bll_single_line_half_duplex_is_ready_to_transfer() == 0) { if(bll_single_line_half_duplex_transfer_onebyte(APP_SINGLE_LINE_PAIR_CMD) == 0)//回馈指令 { index = 0; ob_app_single_line_pair.pair_flow = 1; } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 DEBUG_LOG("============>err 1\r\n"); } } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 DEBUG_LOG("============>err 2\r\n"); } } //获取左右指令 if(byte == APP_SINGLE_LINE_PAIR_LR_CMD) { if(bll_single_line_half_duplex_is_ready_to_transfer() == 0) { if(mFlash.isHost == 1) bll_single_line_half_duplex_transfer_onebyte(0x55); else bll_single_line_half_duplex_transfer_onebyte(0x56); } } break; case 1: //发送数据阶段 ob_app_single_line_pair.mac[index] = byte; if(bll_single_line_half_duplex_is_ready_to_transfer() == 0 && index != 3) { if(bll_single_line_half_duplex_transfer_onebyte(ob_app_single_line_pair.mac[3 + index]) == 0) { index++; if(index == 3) { ob_app_single_line_pair.pair_flow = 0; ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE; ob_app_single_line_pair.save_adv_scan_flow = 0; //注册线程任务,用于处理保存、广播、扫描 Process_Start(0,"app_single_line_pair_save_adv_or_scan_Process",app_single_line_pair_save_adv_or_scan_Process); } } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 DEBUG_LOG("============>err 3\r\n"); } } else { ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败 DEBUG_LOG("============>err 4\r\n"); } break; } } static void app_single_line_pair_Process(void) { //角色切换 if(mFlash.isHost == 1 && ob_app_single_line_pair.role != APP_SINGLE_LINE_PAIR_ROLE_HOST) { app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_HOST); } else if(mFlash.isHost == 0 && ob_app_single_line_pair.role != APP_SINGLE_LINE_PAIR_ROLE_SLAVE) { app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_SLAVE); } switch(ob_app_single_line_pair.role) { case APP_SINGLE_LINE_PAIR_ROLE_HOST: //主机行为 //配对完成或配对失败 if(ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE || ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL) { //配对操作失败,必须得超时才能尝试下一轮。 if(ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL && TIME_GetTicks() - ob_app_single_line_pair.pair_timeout_ms < APP_SINGLE_LINE_PAIR_TIMEOUT) { ob_app_single_line_pair.pair_flow = 0; //更新触发次数 ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES; //灭灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); DEBUG_LOG("o fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER); return; } //允许发送 if(bll_single_line_half_duplex_is_ready_to_transfer() == 0) { //触发次数不为0 if(ob_app_single_line_pair.trigger_times != 0) { //发送配对指令 if(bll_single_line_half_duplex_transfer_onebyte(APP_SINGLE_LINE_PAIR_CMD) == 0) { //更改状态 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_ING; DEBUG_LOG("cmd TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER); LED_Start(LED_PAIR,COLOR_BLUE); ob_app_single_line_pair.pair_flow = 0; //记录配对开始时间 ob_app_single_line_pair.pair_timeout_ms = TIME_GetTicks(); //减少触发次数 ob_app_single_line_pair.trigger_times--; //全功率配对 Process_SetHoldOn(app_single_line_pair_Process,1); } } } else { //更新触发次数 ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES; } } else { //监控是否超时,主机要比从机多一个字节的传输时间来确保从机已经超时。 if(TIME_GetTicks() - ob_app_single_line_pair.pair_timeout_ms >= (APP_SINGLE_LINE_PAIR_TIMEOUT + (FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN * FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS / 1000)) && \ ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_ING) { //配对超时失败 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL; ob_app_single_line_pair.pair_flow = 0; //更新触发次数 ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES; DEBUG_LOG("t fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER); //灭灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); } } break; case APP_SINGLE_LINE_PAIR_ROLE_SLAVE: //从机行为 //监控是否超时。 if(TIME_GetTicks() - ob_app_single_line_pair.pair_timeout_ms >= (APP_SINGLE_LINE_PAIR_TIMEOUT - (FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN * FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS / 1000)) && \ ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_ING) { //配对超时失败 ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL; DEBUG_LOG("t fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER); } if(ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL) { ob_app_single_line_pair.pair_flow = 0; DEBUG_LOG("o fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER); //灭灯 LED_Stop(LED_PAIR); //取消全功率配对 Process_SetHoldOn(app_single_line_pair_Process,0); } break; } } /*API ----------------------------------------------*/ /** @brief 初始化单线配对应用 @param role - [in] 角色 @return 错误代码 - [out] -1失败,0成功 */ int app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_e role) { int ret; ble_gap_addr_t mAddr; //初始化单线半双工业务 ret = bll_single_line_half_duplex_Init((BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_e)role); //重置 memset(&ob_app_single_line_pair, 0, sizeof(ob_app_single_line_pair)); //初始化结构体 uint32_t err_code = sd_ble_gap_addr_get(&mAddr); if(err_code != NRF_SUCCESS)return -1; if(role == APP_SINGLE_LINE_PAIR_ROLE_HOST) { ob_app_single_line_pair.mac[0] = mAddr.addr[0]; ob_app_single_line_pair.mac[1] = mAddr.addr[1]; ob_app_single_line_pair.mac[2] = mAddr.addr[2]; bll_single_line_half_duplex_receive_register(app_single_line_pair_host_process); } else { ob_app_single_line_pair.mac[3] = mAddr.addr[0]; ob_app_single_line_pair.mac[4] = mAddr.addr[1]; ob_app_single_line_pair.mac[5] = mAddr.addr[2]; bll_single_line_half_duplex_receive_register(app_single_line_pair_slave_process); } ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES; ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE; ob_app_single_line_pair.role = role; //初始化配对线程 Process_Start(1000,"app_single_line_pair_Process",app_single_line_pair_Process); return (ret == 0)?0:-1; }