led.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #include "led.h"
  2. #include "user_ws2812b.h"
  3. #include "define.h"
  4. #include "stdarg.h"
  5. tmosTaskID led_task_id = INVALID_TASK_ID;
  6. static uint32_t alarm_stat = 0;
  7. static uint16_t led_task_process_event(uint8_t task_id, uint16_t events);
  8. static void prvSet_led_duty(LED_TYPE type);
  9. static led_work_s led_work[LED_TYPE_MAX] = {
  10. {
  11. .idx = RIGHT_LED,
  12. .color = {
  13. .red = 0,
  14. .green = 0xFF,
  15. .blue = 0,
  16. },
  17. .workStat = LED_WORK_OFF,
  18. .viewStat = LED_VIEW_NULL,
  19. .single_flicker_period = 0,
  20. .flicker_period = 0,
  21. .flicker_onperiod = 0,
  22. .flicker_count = 0,
  23. .duty_on = 95,
  24. .duty_value = 0,
  25. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  26. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  27. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  28. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  29. },
  30. {
  31. .idx = DEV_LED,
  32. .color = {
  33. .red = 0,
  34. .green = 0xFF,
  35. .blue = 0,
  36. },
  37. .workStat = LED_WORK_OFF,
  38. .viewStat = LED_VIEW_NULL,
  39. .single_flicker_period = 0,
  40. .flicker_period = 0,
  41. .flicker_onperiod = 0,
  42. .flicker_count = 0,
  43. .duty_on = 95,
  44. .duty_value = 0,
  45. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  46. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  47. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  48. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  49. },
  50. {
  51. .idx = LEFT_LED,
  52. .color = {
  53. .red = 0,
  54. .green = 0xFF,
  55. .blue = 0,
  56. },
  57. .workStat = LED_WORK_OFF,
  58. .viewStat = LED_VIEW_NULL,
  59. .single_flicker_period = 0,
  60. .flicker_period = 0,
  61. .flicker_onperiod = 0,
  62. .flicker_count = 0,
  63. .duty_on = 95,
  64. .duty_value = 0,
  65. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  66. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  67. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  68. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  69. },
  70. };
  71. /*******************************************************************************
  72. * @函数名称 prvSet_led_duty
  73. * @函数说明 设置指示灯亮度
  74. * @输入参数 type:灯下标
  75. * @输出参数 无
  76. * @返回参数 无
  77. *******************************************************************************/
  78. static void prvSet_led_duty(LED_TYPE type)
  79. {
  80. vUser_ws2812b_set_stat(type, led_work[type].color.red, led_work[type].color.green,
  81. led_work[type].color.blue, led_work[type].duty_value);
  82. }
  83. /*******************************************************************************
  84. * @函数名称 led_invert
  85. * @函数说明 LED闪烁处理
  86. * @输入参数 led_work:led灯结构体直针
  87. * @输出参数 无
  88. * @返回参数 无
  89. *******************************************************************************/
  90. static void led_invert(led_work_s *led_work)
  91. {
  92. if(led_work->flicker_count > 0)
  93. {
  94. if(led_work->single_flicker_period == 0)
  95. {
  96. led_work->single_flicker_period = led_work->flicker_period;
  97. led_work->stat = LED_STAT_ON;
  98. led_work->duty_value = 100;
  99. prvSet_led_duty(led_work->idx);
  100. }
  101. else if(led_work->single_flicker_period == (led_work->flicker_period - led_work->flicker_onperiod))
  102. {
  103. led_work->single_flicker_period--;
  104. led_work->stat = LED_STAT_OFF;
  105. led_work->duty_value = 0;
  106. prvSet_led_duty(led_work->idx);
  107. led_work->flicker_count--;
  108. }
  109. else{
  110. led_work->single_flicker_period--;
  111. }
  112. }
  113. else{
  114. led_work->workStat = LED_WORK_OFF;
  115. led_work->duty_value = 0;
  116. prvSet_led_duty(led_work->idx);
  117. }
  118. }
  119. /*******************************************************************************
  120. * @函数名称 led_heart
  121. * @函数说明 LED呼吸灯处理
  122. * @输入参数 led_work:led灯结构体直针
  123. * @输出参数 无
  124. * @返回参数 无
  125. *******************************************************************************/
  126. static void led_heart(led_work_s *led_work)
  127. {
  128. if(led_work->flicker_count > 0)
  129. {
  130. uint32_t off_period = led_work->flicker_period - led_work->flicker_onperiod;
  131. if(led_work->single_flicker_period == 0)
  132. {
  133. led_work->single_flicker_period = led_work->flicker_period;
  134. led_work->duty_value = 0;
  135. led_work->single_off_durationTime = led_work->off_durationTime;
  136. prvSet_led_duty(led_work->idx);
  137. led_work->flicker_count--;
  138. }
  139. else if(led_work->single_flicker_period == off_period)
  140. {
  141. led_work->single_flicker_period--;
  142. led_work->duty_value = 100;
  143. led_work->single_on_durationTime = led_work->on_durationTime;
  144. prvSet_led_duty(led_work->idx);
  145. }
  146. else{
  147. if(led_work->single_flicker_period > off_period)
  148. {
  149. if(led_work->single_off_durationTime == 0)
  150. {
  151. led_work->single_flicker_period--;
  152. led_work->duty_value = (led_work->flicker_period - led_work->single_flicker_period) * 100 / led_work->flicker_onperiod;
  153. prvSet_led_duty(led_work->idx);
  154. }
  155. else{
  156. led_work->single_off_durationTime--;
  157. }
  158. }
  159. else{
  160. if(led_work->single_on_durationTime == 0)
  161. {
  162. led_work->single_flicker_period--;
  163. led_work->duty_value = led_work->single_flicker_period * 100 / off_period;
  164. prvSet_led_duty(led_work->idx);
  165. }
  166. else{
  167. led_work->single_on_durationTime--;
  168. }
  169. }
  170. }
  171. }
  172. else{
  173. led_work->workStat = LED_WORK_OFF;
  174. }
  175. }
  176. /*******************************************************************************
  177. * @函数名称 led_indication
  178. * @函数说明 LED灯处理
  179. * @输入参数 led_work:led灯结构体直针
  180. * @输出参数 无
  181. * @返回参数 无
  182. *******************************************************************************/
  183. static void led_indication(led_work_s *led_work)
  184. {
  185. switch(led_work->workStat)
  186. {
  187. case LED_WORK_OFF:
  188. {
  189. break;
  190. }
  191. case LED_WORK_ON:
  192. {
  193. break;
  194. }
  195. case LED_WORK_INVERT:
  196. {
  197. led_invert(led_work);
  198. break;
  199. }
  200. case LED_WORK_BREATHE:
  201. {
  202. led_heart(led_work);
  203. break;
  204. }
  205. default:break;
  206. }
  207. }
  208. /*******************************************************************************
  209. * @函数名称 led_task
  210. * @函数说明 LED任务
  211. * @输入参数 无
  212. * @输出参数 无
  213. * @返回参数 无
  214. *******************************************************************************/
  215. static void led_task(void)
  216. {
  217. for(int i = 0; i < LED_TYPE_MAX; i++)
  218. {
  219. led_indication(&led_work[i]);
  220. }
  221. }
  222. /*******************************************************************************
  223. * @函数名称 led_task
  224. * @函数说明 task的event处理回调函数,需要在注册task时候,传进去
  225. * @输入参数 task_id:任务ID
  226. events:事件
  227. * @输出参数 无
  228. * @返回参数 无
  229. *******************************************************************************/
  230. static uint16_t led_task_process_event(uint8_t task_id, uint16_t events)
  231. {
  232. //event 处理
  233. if(events & (1 << LED_QUEUE_TIME))
  234. {
  235. led_task();
  236. return (events ^ (1 << LED_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  237. }
  238. return 0;
  239. }
  240. /*******************************************************************************
  241. * @函数名称 set_led_indication
  242. * @函数说明 LED参数设置
  243. * @输入参数 type:LED灯号
  244. color:颜色
  245. workStat:状态
  246. * @输出参数 无
  247. * @返回参数 无
  248. *******************************************************************************/
  249. bool set_led_indication(LED_TYPE type, uint32_t color, LED_WORK_STAT work_stat, ...)
  250. {
  251. bool stat = false;
  252. if(type >= LED_TYPE_MAX)
  253. {
  254. goto exit;
  255. }
  256. led_work[type].color.red = (color >> 16) & 0xFF;
  257. led_work[type].color.green = (color >> 8) & 0xFF;
  258. led_work[type].color.blue = color & 0xFF;
  259. if(work_stat == LED_WORK_OFF || work_stat == LED_WORK_ON)
  260. {
  261. led_work[type].workStat = work_stat;
  262. led_work[type].duty_value = (work_stat == LED_WORK_ON) ? 100 : 0;
  263. prvSet_led_duty(led_work[type].idx);
  264. stat = true;
  265. }
  266. else if(work_stat == LED_WORK_INVERT || work_stat == LED_WORK_BREATHE)
  267. {
  268. led_work[type].workStat = work_stat;
  269. led_work[type].duty_value = 0;
  270. led_work[type].stat = LED_STAT_OFF;
  271. va_list ap; //保存所有参数
  272. va_start(ap, work_stat); //第一个参数的位置
  273. led_work[type].flicker_period = va_arg(ap, uint32_t)/LED_INTERVAL;
  274. led_work[type].flicker_onperiod = va_arg(ap, uint32_t)/LED_INTERVAL;
  275. led_work[type].flicker_count = va_arg(ap, uint32_t);
  276. if(led_work[type].flicker_count == 0)
  277. {
  278. led_work[type].flicker_count = 0x7FFFFFFF;
  279. }
  280. led_work[type].single_flicker_period = led_work[type].flicker_period;
  281. if(work_stat == LED_WORK_BREATHE)
  282. {
  283. led_work[type].on_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
  284. led_work[type].off_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
  285. led_work[type].single_on_durationTime = led_work[type].on_durationTime;
  286. led_work[type].single_off_durationTime = led_work[type].off_durationTime;
  287. }
  288. va_end(ap);
  289. for(int i = 0; i < LED_TYPE_MAX; i++)
  290. {
  291. if(led_work[i].workStat == LED_WORK_INVERT
  292. || led_work[i].workStat == LED_WORK_BREATHE)
  293. {
  294. led_work[i].single_flicker_period = led_work[i].flicker_period;
  295. led_work[i].duty_value = 0;
  296. if(led_work[i].workStat == LED_WORK_BREATHE)
  297. {
  298. led_work[i].single_on_durationTime = led_work[i].on_durationTime;
  299. led_work[i].single_off_durationTime = led_work[i].off_durationTime;
  300. }
  301. }
  302. }
  303. stat = true;
  304. }
  305. exit:
  306. return stat;
  307. }
  308. /*******************************************************************************
  309. * @函数名称 led_task_init
  310. * @函数说明 LED任务初始化
  311. * @输入参数 无
  312. * @输出参数 无
  313. * @返回参数 无
  314. *******************************************************************************/
  315. void led_task_init(void)
  316. {
  317. led_task_id = TMOS_ProcessEventRegister(led_task_process_event);
  318. PRINT("led_task_id=%d\n", led_task_id);
  319. }
  320. /*******************************************************************************
  321. * @函数名称 led_task_start
  322. * @函数说明 LED任务开始
  323. * @输入参数 无
  324. * @输出参数 无
  325. * @返回参数 无
  326. *******************************************************************************/
  327. void led_task_start(void)
  328. {
  329. bStatus_t stat = tmos_start_reload_task(led_task_id, (1 << LED_QUEUE_TIME), MS1_TO_SYSTEM_TIME(LED_INTERVAL));
  330. }
  331. /*******************************************************************************
  332. * @函数名称 vUser_led_set_view_stat
  333. * @函数说明 设置LED工作状态
  334. * @输入参数 stat:led工作状态
  335. * @输出参数 无
  336. * @返回参数 无
  337. *******************************************************************************/
  338. void vUser_led_set_view_stat(led_view_stat_e stat)
  339. {
  340. // PRINT("set led stat:%d,%d\n", idx, stat);
  341. switch(stat)
  342. {
  343. case LED_VIEW_ENTER_OTA:{
  344. set_led_indication(DEV_LED, WS2812B_BLE_RGB, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
  345. set_led_indication(LEFT_LED, WS2812B_BLE_RGB, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
  346. set_led_indication(RIGHT_LED, WS2812B_BLE_RGB, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
  347. }break;
  348. case LED_VIEW_OTA:{
  349. set_led_indication(DEV_LED, WS2812B_BLE_RGB, LED_WORK_BREATHE, 200, 100, 0, 10, 10);
  350. set_led_indication(LEFT_LED, WS2812B_BLE_RGB, LED_WORK_BREATHE, 200, 100, 0, 10, 10);
  351. set_led_indication(RIGHT_LED, WS2812B_BLE_RGB, LED_WORK_BREATHE, 200, 100, 0, 10, 10);
  352. }break;
  353. default:break;
  354. }
  355. }