/*Includes ----------------------------------------------*/ #include "nrf_delay.h" #include "tool.h" #include "bsp_adc.h" #include "bsp_pwm.h" #include "bsp_time.h" #include "exception.h" #include "system.h" #include "bll_single_line_half_duplex.h" /*Private macro ------------------------------------------------*/ #define BLL_SINGLE_LINE_HALF_DUPLEX_CHARGING_VOL_THRESHOLD 2000 //充电电压阈值 #define BLL_SINGLE_LINE_HALF_DUPLEX_CONNECTION_VOL_THRESHOLD 200 //连接电压阈值 #define BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE_ALLOWANCE 20 //周期余量 单位:ms #define BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE ((StandByPower_Interval/2)+BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE_ALLOWANCE) //半双工周期(一发或一收为一周期) 单位:ms #define BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN 5 //接收最大回调数 /*STRUCTION -----------------------------------------------------*/ typedef enum { BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_ING = 0, //状态 —— 接收中 BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING = 1, //状态 —— 发送中 BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE = 2, //状态 —— 接收完成 BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_DONE = 3, //状态 —— 发送完成 } BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_e; typedef struct _bll_single_line_half_duplex { bool error; //错误标志位 BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_e role; //角色 BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_e status; //状态 uint32_t status_start_ms; //状态开始时间 bll_single_line_half_duplex_receive_cb receive_cb[BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN]; //注册的接收回调 uint32_t error_calib_ms; //误差校准 } Bll_Single_Line_Half_Duplex_t; /*Local Variable ----------------------------------------------*/ static Bll_Single_Line_Half_Duplex_t ob_bll_single_line_half_duplex; /*Local Functions ----------------------------------------------*/ static void bll_single_line_half_duplex_receive_Process(void) { uint8_t byte; uint32_t error_calib_ms = NRF_RTC0->COUNTER; //误差校准 if(error_calib_ms < ob_bll_single_line_half_duplex.error_calib_ms)error_calib_ms += 16777216; if((error_calib_ms - ob_bll_single_line_half_duplex.error_calib_ms)/32.768 <= (FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000)) { Process_UpdatePeroid(bll_single_line_half_duplex_receive_Process,(FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000) - ((error_calib_ms - ob_bll_single_line_half_duplex.error_calib_ms)/32.768)); return; } if(fml_single_line_simplex_receive(&byte, 1) > 0) { for(int i = 0; i < BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN; i++) { //注册回调函数不为空 if(ob_bll_single_line_half_duplex.receive_cb[i] != NULL) { ob_bll_single_line_half_duplex.receive_cb[i](byte); } } //处理完后,取消全功率 Process_SetHoldOn(bll_single_line_half_duplex_receive_Process,0); //只有在触发接收时,才运行。 Process_Stop(bll_single_line_half_duplex_receive_Process); } } static void bll_single_line_half_duplex_transfer_Process(void) { uint32_t cur_time_ms = TIME_GetTicks(); uint32_t time_diff; //时间溢出处理 if(ob_bll_single_line_half_duplex.status_start_ms > cur_time_ms) { time_diff = 0xFFFFFFFF - ob_bll_single_line_half_duplex.status_start_ms + cur_time_ms; } else { time_diff = cur_time_ms - ob_bll_single_line_half_duplex.status_start_ms; } //当角色为主机时 if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST) { //若是传输中。。。。 if(time_diff >= BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE && ob_bll_single_line_half_duplex.status == BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING) { //修改状态 —— 接收中。。。 ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_ING; //获取周期开始时间 ob_bll_single_line_half_duplex.status_start_ms = TIME_GetTicks(); } //若是接收中。。。。 if(time_diff >= BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE && ob_bll_single_line_half_duplex.status == BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_ING) { //修改状态 —— 接收完成 ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE; //处理完后,取消全功率 Process_SetHoldOn(bll_single_line_half_duplex_transfer_Process,0); //只有在触发接收时,才运行。 Process_Stop(bll_single_line_half_duplex_transfer_Process); } } //当角色为从机时 if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_SLAVE) { //若是传输中。。。。 if(time_diff >= BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE && ob_bll_single_line_half_duplex.status == BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING) { //修改状态 —— 传输完成。。。 ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_DONE; //处理完后,取消全功率 Process_SetHoldOn(bll_single_line_half_duplex_transfer_Process,0); //只有在触发接收时,才运行。 Process_Stop(bll_single_line_half_duplex_transfer_Process); } } } static void bll_single_line_half_duplex_receive_time_callback(void) { //当角色为从机时 if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_SLAVE) { //修改状态 —— 接收完成 ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE; //获取周期开始时间 ob_bll_single_line_half_duplex.status_start_ms = TIME_GetTicks(); } //中断唤醒时,定时器的值还未累积,这时获取的值是上次唤醒前的定时器值。 ob_bll_single_line_half_duplex.error_calib_ms = NRF_RTC0->COUNTER; //注册线程任务,用于接收处理,回调给注册的回调函数 Process_Start((FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000),"bll_single_line_half_duplex_receive_Process",bll_single_line_half_duplex_receive_Process); //接收到数据后,全功率运行回调处理 Process_SetHoldOn(bll_single_line_half_duplex_receive_Process,1); } /*API ----------------------------------------------*/ /** @brief 初始化单线半双工业务 @param 无 @return 错误代码 - [out] -1失败,0成功 */ int bll_single_line_half_duplex_Init(BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_e role) { int ret; fml_single_line_simplex_UnInit(); ret = fml_single_line_simplex_Init((FML_SINGLE_LINE_SIMPLEX_ROLE_e)role); //重置 memset(&ob_bll_single_line_half_duplex,0,sizeof(ob_bll_single_line_half_duplex)); //初始化结构体 ob_bll_single_line_half_duplex.role = role; if(role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST)ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE; else ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_DONE; //注册接收回调 if(ret != -1)fml_single_line_simplex_receive_time_callback(bll_single_line_half_duplex_receive_time_callback); //注册线程任务,用于接收处理,回调给注册的回调函数 Process_Start((FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000),"bll_single_line_half_duplex_receive_Process",bll_single_line_half_duplex_receive_Process); //只有在触发接收时,才运行。 Process_Stop(bll_single_line_half_duplex_receive_Process); //注册线程任务,用于传输处理 Process_Start(0,"bll_single_line_half_duplex_transfer_Process",bll_single_line_half_duplex_transfer_Process); //只有在触发发送时,才运行。 Process_Stop(bll_single_line_half_duplex_transfer_Process); if(ret == -1) { ob_bll_single_line_half_duplex.error = true; } return (ret == 0)?0:-1; } /** @brief 单线半双工传输是否可发送 @param 无 @return 错误代码 - [out] -4不能使用,-3没有连上线,-2处于接收周期,-1正在发送中,0成功 */ int bll_single_line_half_duplex_is_ready_to_transfer(void) { int ret = 0; int16_t adc_value; if(ob_bll_single_line_half_duplex.error == true)return -4; //检测是否正在发送中 if(fml_single_line_simplex_pwm_transfer_is_done() == -1)ret = -1; if(ret < 0)return ret; //检测是否处于接收周期 if(ob_bll_single_line_half_duplex.status != BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE)ret = -2; if(ret < 0)return ret; //检测是否连上线(物理) fml_single_line_simplex_UnInit(); ADC_Disable(); ADC_SetPinChannel(FML_SINGLE_LINE_SIMPLEX_PIN, 4, NRF_GPIO_PIN_NOPULL); ADC_Initialize(); ADC_Read(4, &adc_value); SEGGER_RTT_printf(0,"adc_value:%d\n",adc_value); if(!(adc_value >= BLL_SINGLE_LINE_HALF_DUPLEX_CONNECTION_VOL_THRESHOLD && adc_value < BLL_SINGLE_LINE_HALF_DUPLEX_CHARGING_VOL_THRESHOLD))ret = -3; ADC_Disable(); ADC_RemovePinChannel(FML_SINGLE_LINE_SIMPLEX_PIN, 4); ADC_Initialize(); fml_single_line_simplex_Init((FML_SINGLE_LINE_SIMPLEX_ROLE_e)ob_bll_single_line_half_duplex.role); fml_single_line_simplex_receive_time_callback(bll_single_line_half_duplex_receive_time_callback); DEBUG_LOG("===>is ready ret:%d\r\n",ret); return ret; } /** @brief 单线半双工传输 —— 发送 @param byte - [in] 发送的字节 @return 错误代码 - [out] -3不能使用,-2发送失败,-1没准备好传输,0成功 */ int bll_single_line_half_duplex_transfer_onebyte(uint8_t byte) { int ret = 0; if(ob_bll_single_line_half_duplex.error == true)return -3; //检测是否准备好传输 if(bll_single_line_half_duplex_is_ready_to_transfer() != 0)ret = -1; //发送 if(fml_single_line_simplex_pwm_transfer_onebyte(byte) == -1)ret = -2; //修改状态 ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING; //当角色为主机时 if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST) { //获取周期开始时间 ob_bll_single_line_half_duplex.status_start_ms = TIME_GetTicks(); } //注册线程任务,用于处理发送数据的状态 Process_Start(0,"bll_single_line_half_duplex_transfer_Process",bll_single_line_half_duplex_transfer_Process); //全功率运行 Process_SetHoldOn(bll_single_line_half_duplex_transfer_Process,1); return ret; } /** @brief 单线半双工传输 —— 接收 @param cb - [in] 接收回调函数 @return 错误代码 - [out] -1失败,0成功 */ int bll_single_line_half_duplex_receive_register(bll_single_line_half_duplex_receive_cb cb) { static uint8_t cur_index = 0; if(cb == NULL)return -1; if(ob_bll_single_line_half_duplex.error == true)return -1; if(cur_index >= BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN)return -1; ob_bll_single_line_half_duplex.receive_cb[cur_index++] = cb; return 0; }