bll_single_line_half_duplex.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /*Includes ----------------------------------------------*/
  2. #include "nrf_delay.h"
  3. #include "tool.h"
  4. #include "bsp_adc.h"
  5. #include "bsp_pwm.h"
  6. #include "bsp_time.h"
  7. #include "exception.h"
  8. #include "system.h"
  9. #include "bll_single_line_half_duplex.h"
  10. /*Private macro ------------------------------------------------*/
  11. #define BLL_SINGLE_LINE_HALF_DUPLEX_CHARGING_VOL_THRESHOLD 2000 //充电电压阈值
  12. #define BLL_SINGLE_LINE_HALF_DUPLEX_CONNECTION_VOL_THRESHOLD 200 //连接电压阈值
  13. #define BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE_ALLOWANCE 20 //周期余量 单位:ms
  14. #define BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE ((StandByPower_Interval/2)+BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE_ALLOWANCE) //半双工周期(一发或一收为一周期) 单位:ms
  15. #define BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN 5 //接收最大回调数
  16. /*STRUCTION -----------------------------------------------------*/
  17. typedef enum
  18. {
  19. BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_ING = 0, //状态 —— 接收中
  20. BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING = 1, //状态 —— 发送中
  21. BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE = 2, //状态 —— 接收完成
  22. BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_DONE = 3, //状态 —— 发送完成
  23. } BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_e;
  24. typedef struct _bll_single_line_half_duplex
  25. {
  26. bool error; //错误标志位
  27. BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_e role; //角色
  28. BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_e status; //状态
  29. uint32_t status_start_ms; //状态开始时间
  30. bll_single_line_half_duplex_receive_cb receive_cb[BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN]; //注册的接收回调
  31. uint32_t error_calib_ms; //误差校准
  32. } Bll_Single_Line_Half_Duplex_t;
  33. /*Local Variable ----------------------------------------------*/
  34. static Bll_Single_Line_Half_Duplex_t ob_bll_single_line_half_duplex;
  35. /*Local Functions ----------------------------------------------*/
  36. static void bll_single_line_half_duplex_receive_Process(void)
  37. {
  38. uint8_t byte;
  39. uint32_t error_calib_ms = NRF_RTC0->COUNTER;
  40. //误差校准
  41. if(error_calib_ms < ob_bll_single_line_half_duplex.error_calib_ms)error_calib_ms += 16777216;
  42. if((error_calib_ms - ob_bll_single_line_half_duplex.error_calib_ms)/32.768 <= (FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000))
  43. {
  44. 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));
  45. return;
  46. }
  47. if(fml_single_line_simplex_receive(&byte, 1) > 0)
  48. {
  49. for(int i = 0; i < BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN; i++)
  50. {
  51. //注册回调函数不为空
  52. if(ob_bll_single_line_half_duplex.receive_cb[i] != NULL)
  53. {
  54. ob_bll_single_line_half_duplex.receive_cb[i](byte);
  55. }
  56. }
  57. //处理完后,取消全功率
  58. Process_SetHoldOn(bll_single_line_half_duplex_receive_Process,0);
  59. //只有在触发接收时,才运行。
  60. Process_Stop(bll_single_line_half_duplex_receive_Process);
  61. }
  62. }
  63. static void bll_single_line_half_duplex_transfer_Process(void)
  64. {
  65. uint32_t cur_time_ms = TIME_GetTicks();
  66. uint32_t time_diff;
  67. //时间溢出处理
  68. if(ob_bll_single_line_half_duplex.status_start_ms > cur_time_ms)
  69. {
  70. time_diff = 0xFFFFFFFF - ob_bll_single_line_half_duplex.status_start_ms + cur_time_ms;
  71. }
  72. else
  73. {
  74. time_diff = cur_time_ms - ob_bll_single_line_half_duplex.status_start_ms;
  75. }
  76. //当角色为主机时
  77. if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST)
  78. {
  79. //若是传输中。。。。
  80. if(time_diff >= BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE && ob_bll_single_line_half_duplex.status == BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING)
  81. {
  82. //修改状态 —— 接收中。。。
  83. ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_ING;
  84. //获取周期开始时间
  85. ob_bll_single_line_half_duplex.status_start_ms = TIME_GetTicks();
  86. }
  87. //若是接收中。。。。
  88. if(time_diff >= BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE && ob_bll_single_line_half_duplex.status == BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_ING)
  89. {
  90. //修改状态 —— 接收完成
  91. ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE;
  92. //处理完后,取消全功率
  93. Process_SetHoldOn(bll_single_line_half_duplex_transfer_Process,0);
  94. //只有在触发接收时,才运行。
  95. Process_Stop(bll_single_line_half_duplex_transfer_Process);
  96. }
  97. }
  98. //当角色为从机时
  99. if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_SLAVE)
  100. {
  101. //若是传输中。。。。
  102. if(time_diff >= BLL_SINGLE_LINE_HALF_DUPLEX_CYCLE && ob_bll_single_line_half_duplex.status == BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING)
  103. {
  104. //修改状态 —— 传输完成。。。
  105. ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_DONE;
  106. //处理完后,取消全功率
  107. Process_SetHoldOn(bll_single_line_half_duplex_transfer_Process,0);
  108. //只有在触发接收时,才运行。
  109. Process_Stop(bll_single_line_half_duplex_transfer_Process);
  110. }
  111. }
  112. }
  113. static void bll_single_line_half_duplex_receive_time_callback(void)
  114. {
  115. //当角色为从机时
  116. if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_SLAVE)
  117. {
  118. //修改状态 —— 接收完成
  119. ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE;
  120. //获取周期开始时间
  121. ob_bll_single_line_half_duplex.status_start_ms = TIME_GetTicks();
  122. }
  123. //中断唤醒时,定时器的值还未累积,这时获取的值是上次唤醒前的定时器值。
  124. ob_bll_single_line_half_duplex.error_calib_ms = NRF_RTC0->COUNTER;
  125. //注册线程任务,用于接收处理,回调给注册的回调函数
  126. Process_Start((FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000),"bll_single_line_half_duplex_receive_Process",bll_single_line_half_duplex_receive_Process);
  127. //接收到数据后,全功率运行回调处理
  128. Process_SetHoldOn(bll_single_line_half_duplex_receive_Process,1);
  129. }
  130. /*API ----------------------------------------------*/
  131. /**
  132. @brief 初始化单线半双工业务
  133. @param 无
  134. @return 错误代码 - [out] -1失败,0成功
  135. */
  136. int bll_single_line_half_duplex_Init(BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_e role)
  137. {
  138. int ret;
  139. fml_single_line_simplex_UnInit();
  140. ret = fml_single_line_simplex_Init((FML_SINGLE_LINE_SIMPLEX_ROLE_e)role);
  141. //重置
  142. memset(&ob_bll_single_line_half_duplex,0,sizeof(ob_bll_single_line_half_duplex));
  143. //初始化结构体
  144. ob_bll_single_line_half_duplex.role = role;
  145. if(role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST)ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE;
  146. else ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_DONE;
  147. //注册接收回调
  148. if(ret != -1)fml_single_line_simplex_receive_time_callback(bll_single_line_half_duplex_receive_time_callback);
  149. //注册线程任务,用于接收处理,回调给注册的回调函数
  150. Process_Start((FML_SINGLE_LINE_SIMPLEX_END_CODE_T/1000),"bll_single_line_half_duplex_receive_Process",bll_single_line_half_duplex_receive_Process);
  151. //只有在触发接收时,才运行。
  152. Process_Stop(bll_single_line_half_duplex_receive_Process);
  153. //注册线程任务,用于传输处理
  154. Process_Start(0,"bll_single_line_half_duplex_transfer_Process",bll_single_line_half_duplex_transfer_Process);
  155. //只有在触发发送时,才运行。
  156. Process_Stop(bll_single_line_half_duplex_transfer_Process);
  157. if(ret == -1)
  158. {
  159. ob_bll_single_line_half_duplex.error = true;
  160. }
  161. return (ret == 0)?0:-1;
  162. }
  163. /**
  164. @brief 单线半双工传输是否可发送
  165. @param 无
  166. @return 错误代码 - [out] -4不能使用,-3没有连上线,-2处于接收周期,-1正在发送中,0成功
  167. */
  168. int bll_single_line_half_duplex_is_ready_to_transfer(void)
  169. {
  170. int ret = 0;
  171. int16_t adc_value;
  172. if(ob_bll_single_line_half_duplex.error == true)return -4;
  173. //检测是否正在发送中
  174. if(fml_single_line_simplex_pwm_transfer_is_done() == -1)ret = -1;
  175. if(ret < 0)return ret;
  176. //检测是否处于接收周期
  177. if(ob_bll_single_line_half_duplex.status != BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_RECEIVE_DONE)ret = -2;
  178. if(ret < 0)return ret;
  179. //检测是否连上线(物理)
  180. fml_single_line_simplex_UnInit();
  181. ADC_Disable();
  182. ADC_SetPinChannel(FML_SINGLE_LINE_SIMPLEX_PIN, 4, NRF_GPIO_PIN_NOPULL);
  183. ADC_Initialize();
  184. ADC_Read(4, &adc_value);
  185. SEGGER_RTT_printf(0,"adc_value:%d\n",adc_value);
  186. if(!(adc_value >= BLL_SINGLE_LINE_HALF_DUPLEX_CONNECTION_VOL_THRESHOLD && adc_value < BLL_SINGLE_LINE_HALF_DUPLEX_CHARGING_VOL_THRESHOLD))ret = -3;
  187. ADC_Disable();
  188. ADC_RemovePinChannel(FML_SINGLE_LINE_SIMPLEX_PIN, 4);
  189. ADC_Initialize();
  190. fml_single_line_simplex_Init((FML_SINGLE_LINE_SIMPLEX_ROLE_e)ob_bll_single_line_half_duplex.role);
  191. fml_single_line_simplex_receive_time_callback(bll_single_line_half_duplex_receive_time_callback);
  192. DEBUG_LOG("===>is ready ret:%d\r\n",ret);
  193. return ret;
  194. }
  195. /**
  196. @brief 单线半双工传输 —— 发送
  197. @param byte - [in] 发送的字节
  198. @return 错误代码 - [out] -3不能使用,-2发送失败,-1没准备好传输,0成功
  199. */
  200. int bll_single_line_half_duplex_transfer_onebyte(uint8_t byte)
  201. {
  202. int ret = 0;
  203. if(ob_bll_single_line_half_duplex.error == true)return -3;
  204. //检测是否准备好传输
  205. if(bll_single_line_half_duplex_is_ready_to_transfer() != 0)ret = -1;
  206. //发送
  207. if(fml_single_line_simplex_pwm_transfer_onebyte(byte) == -1)ret = -2;
  208. //修改状态
  209. ob_bll_single_line_half_duplex.status = BLL_SINGLE_LINE_HALF_DUPLEX_STATUS_TRANSFER_ING;
  210. //当角色为主机时
  211. if(ob_bll_single_line_half_duplex.role == BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST)
  212. {
  213. //获取周期开始时间
  214. ob_bll_single_line_half_duplex.status_start_ms = TIME_GetTicks();
  215. }
  216. //注册线程任务,用于处理发送数据的状态
  217. Process_Start(0,"bll_single_line_half_duplex_transfer_Process",bll_single_line_half_duplex_transfer_Process);
  218. //全功率运行
  219. Process_SetHoldOn(bll_single_line_half_duplex_transfer_Process,1);
  220. return ret;
  221. }
  222. /**
  223. @brief 单线半双工传输 —— 接收
  224. @param cb - [in] 接收回调函数
  225. @return 错误代码 - [out] -1失败,0成功
  226. */
  227. int bll_single_line_half_duplex_receive_register(bll_single_line_half_duplex_receive_cb cb)
  228. {
  229. static uint8_t cur_index = 0;
  230. if(cb == NULL)return -1;
  231. if(ob_bll_single_line_half_duplex.error == true)return -1;
  232. if(cur_index >= BLL_SINGLE_LINE_HALF_DUPLEX_RECEIVE_CB_MAX_LEN)return -1;
  233. ob_bll_single_line_half_duplex.receive_cb[cur_index++] = cb;
  234. return 0;
  235. }