led.c 15 KB

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