123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*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;
- }
|