bll_single_line_half_duplex.c 10 KB

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