led.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. #include "led.h"
  2. #include "define.h"
  3. #include "stdarg.h"
  4. tmosTaskID led_task_id = INVALID_TASK_ID;
  5. static uint16_t led_task_process_event(uint8_t task_id, uint16_t events);
  6. static void led_dev_duty(uint16_t duty);
  7. static void left_dev_duty(uint16_t duty);
  8. static void right_dev_duty(uint16_t duty);
  9. static led_work_s led_work[LED_TYPE_MAX] = {
  10. {
  11. .idx = DEV_LED,
  12. .set_duty = led_dev_duty,
  13. .color = RED_LED,
  14. .workStat = LED_WORK_OFF,
  15. .single_flicker_period = 0,
  16. .flicker_period = 0,
  17. .flicker_onperiod = 0,
  18. .flicker_count = 0,
  19. .duty_on = 95,
  20. .duty_value = 0,
  21. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  22. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  23. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  24. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  25. },
  26. {
  27. .idx = LEFT_LED,
  28. .set_duty = left_dev_duty,
  29. .color = RED_LED,
  30. .workStat = LED_WORK_OFF,
  31. .single_flicker_period = 0,
  32. .flicker_period = 0,
  33. .flicker_onperiod = 0,
  34. .flicker_count = 0,
  35. .duty_on = 95,
  36. .duty_value = 0,
  37. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  38. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  39. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  40. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  41. },
  42. {
  43. .idx = RIGHT_LED,
  44. .set_duty = right_dev_duty,
  45. .color = RED_LED,
  46. .workStat = LED_WORK_OFF,
  47. .single_flicker_period = 0,
  48. .flicker_period = 0,
  49. .flicker_onperiod = 0,
  50. .flicker_count = 0,
  51. .duty_on = 95,
  52. .duty_value = 0,
  53. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  54. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  55. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  56. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  57. },
  58. };
  59. /*******************************************************************************
  60. * @函数名称 led_pwm_init
  61. * @函数说明 初始化
  62. * @输入参数 无
  63. * @输出参数 无
  64. * @返回参数 无
  65. *******************************************************************************/
  66. static void led_pwm_init(void)
  67. {
  68. GPIO_InitTypeDef GPIO_InitStructure={0};
  69. TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
  70. TIM_OCInitTypeDef TIM_OutputCompareInitStructure;
  71. TIM_BDTRInitTypeDef BDTR_Structure;
  72. TIM5_TimeBaseInitTypeDef TIM5_BaseInitStructure;
  73. TIM5_OCInitTypeDef TIM5_OutputCompareInitStructure;
  74. TIM5_BDTRInitTypeDef BDTR5_Structure;
  75. LED_GPIO_RCC_ENABLE;
  76. GPIO_InitStructure.GPIO_Pin = DEV_LED_PIN;
  77. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  78. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  79. GPIO_Init(DEV_LED_GPIO, &GPIO_InitStructure );
  80. GPIO_InitStructure.GPIO_Pin = LEFT_LED_R_PIN;
  81. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  82. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  83. GPIO_Init(LEFT_LED_R_GPIO, &GPIO_InitStructure );
  84. GPIO_InitStructure.GPIO_Pin = LEFT_LED_G_PIN;
  85. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  86. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  87. GPIO_Init(LEFT_LED_G_GPIO, &GPIO_InitStructure );
  88. GPIO_InitStructure.GPIO_Pin = RIGHT_LED_R_PIN;
  89. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  90. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  91. GPIO_Init(RIGHT_LED_R_GPIO, &GPIO_InitStructure );
  92. GPIO_InitStructure.GPIO_Pin = RIGHT_LED_G_PIN;
  93. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  94. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  95. GPIO_Init(RIGHT_LED_G_GPIO, &GPIO_InitStructure );
  96. LED_PWM_RCC_ENABLE;
  97. #ifdef LED_REMAPCONFIG_ENABLE
  98. LED_REMAPCONFIG_ENABLE;
  99. #endif
  100. TIM_BaseInitStructure.TIM_Period = TIM_LED_PERIOD;
  101. TIM_BaseInitStructure.TIM_Prescaler = TIM_LED_PRESCALER - 1;
  102. TIM_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
  103. TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  104. TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
  105. TIM_TimeBaseInit(TIM_IND_LED,&TIM_BaseInitStructure);
  106. TIM_OutputCompareInitStructure.TIM_OCMode =TIM_OCMode_PWM1; //占空比设置的高电平
  107. TIM_OutputCompareInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  108. TIM_OutputCompareInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_Low;
  109. TIM_OutputCompareInitStructure.TIM_OutputState =TIM_OutputState_Enable;
  110. TIM_OutputCompareInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  111. TIM_OutputCompareInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  112. TIM_OutputCompareInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  113. TIM_OutputCompareInitStructure.TIM_Pulse = 0;
  114. BDTR_Structure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  115. BDTR_Structure.TIM_Break = TIM_Break_Disable;
  116. BDTR_Structure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  117. BDTR_Structure.TIM_DeadTime = 0x80;
  118. BDTR_Structure.TIM_LOCKLevel = TIM_LOCKLevel_1;
  119. BDTR_Structure.TIM_OSSIState = TIM_OSSIState_Enable;
  120. BDTR_Structure.TIM_OSSRState = TIM_OSSRState_Enable;
  121. TIM_BDTRConfig(TIM_IND_LED,&BDTR_Structure);
  122. LEFT_LED_R_INIT(&TIM_OutputCompareInitStructure);
  123. LEFT_LED_G_INIT(&TIM_OutputCompareInitStructure);
  124. RIGHT_LED_R_INIT(&TIM_OutputCompareInitStructure);
  125. RIGHT_LED_G_INIT(&TIM_OutputCompareInitStructure);
  126. TIM5_BaseInitStructure.TIM_Period = TIM_LED_PERIOD;
  127. TIM5_BaseInitStructure.TIM_Prescaler = TIM_LED_PRESCALER - 1;
  128. TIM5_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
  129. TIM5_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  130. TIM5_BaseInitStructure.TIM_RepetitionCounter = 0;
  131. TIM5_TimeBaseInit(&TIM5_BaseInitStructure);
  132. TIM5_OutputCompareInitStructure.TIM_OCMode =TIM_OCMode_PWM2; //占空比设置的高电平
  133. TIM5_OutputCompareInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  134. TIM5_OutputCompareInitStructure.TIM_OCNPolarity =TIM_OCNPolarity_Low;
  135. TIM5_OutputCompareInitStructure.TIM_OutputState =TIM_OutputState_Enable;
  136. TIM5_OutputCompareInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  137. TIM5_OutputCompareInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  138. TIM5_OutputCompareInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  139. TIM5_OutputCompareInitStructure.TIM_Pulse = 0;
  140. BDTR5_Structure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
  141. BDTR5_Structure.TIM_Break = TIM_Break_Disable;
  142. BDTR5_Structure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  143. BDTR5_Structure.TIM_DeadTime = 0x80;
  144. BDTR5_Structure.TIM_LOCKLevel = TIM_LOCKLevel_1;
  145. BDTR5_Structure.TIM_OSSIState = TIM_OSSIState_Enable;
  146. BDTR5_Structure.TIM_OSSRState = TIM_OSSRState_Enable;
  147. TIM5_BDTRConfig(&BDTR5_Structure);
  148. DEV_LED_INIT(&TIM5_OutputCompareInitStructure);
  149. DEV_LED_RUN;
  150. LEFT_LED_R_RUN;
  151. LEFT_LED_G_RUN;
  152. RIGHT_LED_R_RUN;
  153. RIGHT_LED_G_RUN;
  154. DEV_LED_COMPARE(0);
  155. LEFT_LED_R_COMPARE(0);
  156. LEFT_LED_G_COMPARE(0);
  157. LEFT_LED_R_COMPARE(0);
  158. LEFT_LED_G_COMPARE(0);
  159. TIM_Cmd(TIM_DEV_LED,ENABLE);
  160. TIM_Cmd(TIM_IND_LED,ENABLE);
  161. }
  162. /*******************************************************************************
  163. * @函数名称 led_dev_duty
  164. * @函数说明 设置设备指示灯PWM百分比
  165. * @输入参数 duty:百分比
  166. * @输出参数 无
  167. * @返回参数 无
  168. *******************************************************************************/
  169. static void led_dev_duty(uint16_t duty)
  170. {
  171. uint16_t value = TIM_LED_PERIOD * duty / 100;
  172. DEV_LED_COMPARE(value);
  173. }
  174. /*******************************************************************************
  175. * @函数名称 left_dev_duty
  176. * @函数说明 设置左边指示灯PWM百分比
  177. * @输入参数 duty:百分比
  178. * @输出参数 无
  179. * @返回参数 无
  180. *******************************************************************************/
  181. static void left_dev_duty(uint16_t duty)
  182. {
  183. uint16_t value = TIM_LED_PERIOD * duty / 100;
  184. if(led_work[LEFT_LED].color == RED_LED)
  185. {
  186. LEFT_LED_G_COMPARE(LED_OFF_DUTY);
  187. LEFT_LED_R_COMPARE(duty);
  188. }
  189. else if(led_work[LEFT_LED].color == GREEN_LED)
  190. {
  191. LEFT_LED_R_COMPARE(LED_OFF_DUTY);
  192. LEFT_LED_G_COMPARE(duty);
  193. }
  194. else if(led_work[LEFT_LED].color == YELLOW_LED)
  195. {
  196. LEFT_LED_R_COMPARE(duty);
  197. LEFT_LED_G_COMPARE(duty);
  198. }
  199. }
  200. /*******************************************************************************
  201. * @函数名称 right_dev_duty
  202. * @函数说明 设置右边指示灯PWM百分比
  203. * @输入参数 duty:百分比
  204. * @输出参数 无
  205. * @返回参数 无
  206. *******************************************************************************/
  207. static void right_dev_duty(uint16_t duty)
  208. {
  209. uint16_t value = TIM_LED_PERIOD * duty / 100;
  210. if(led_work[RIGHT_LED].color == RED_LED)
  211. {
  212. RIGHT_LED_G_COMPARE(LED_OFF_DUTY);
  213. RIGHT_LED_R_COMPARE(duty);
  214. }
  215. else if(led_work[RIGHT_LED].color == GREEN_LED)
  216. {
  217. RIGHT_LED_R_COMPARE(LED_OFF_DUTY);
  218. RIGHT_LED_G_COMPARE(duty);
  219. }
  220. else if(led_work[RIGHT_LED].color == YELLOW_LED)
  221. {
  222. RIGHT_LED_R_COMPARE(duty);
  223. RIGHT_LED_G_COMPARE(duty);
  224. }
  225. }
  226. /*******************************************************************************
  227. * @函数名称 led_invert
  228. * @函数说明 LED闪烁处理
  229. * @输入参数 led_work:led灯结构体直针
  230. * @输出参数 无
  231. * @返回参数 无
  232. *******************************************************************************/
  233. static void led_invert(led_work_s *led_work)
  234. {
  235. if(led_work->flicker_count > 0)
  236. {
  237. if(led_work->single_flicker_period == 0)
  238. {
  239. led_work->single_flicker_period = led_work->flicker_period;
  240. led_work->stat = LED_STAT_ON;
  241. led_work->set_duty(LED_ON_DUTY);
  242. }
  243. else if(led_work->single_flicker_period == (led_work->flicker_period - led_work->flicker_onperiod))
  244. {
  245. led_work->single_flicker_period--;
  246. led_work->stat = LED_STAT_OFF;
  247. led_work->set_duty(LED_OFF_DUTY);
  248. led_work->flicker_count--;
  249. }
  250. else{
  251. led_work->single_flicker_period--;
  252. }
  253. }
  254. else{
  255. led_work->workStat = LED_WORK_OFF;
  256. led_work->set_duty(LED_OFF_DUTY);
  257. }
  258. }
  259. /*******************************************************************************
  260. * @函数名称 led_heart
  261. * @函数说明 LED呼吸灯处理
  262. * @输入参数 led_work:led灯结构体直针
  263. * @输出参数 无
  264. * @返回参数 无
  265. *******************************************************************************/
  266. static void led_heart(led_work_s *led_work)
  267. {
  268. if(led_work->flicker_count > 0)
  269. {
  270. uint32_t off_period = led_work->flicker_period - led_work->flicker_onperiod;
  271. if(led_work->single_flicker_period == 0)
  272. {
  273. led_work->single_flicker_period = led_work->flicker_period;
  274. led_work->duty_value = 0;
  275. led_work->single_off_durationTime = led_work->off_durationTime;
  276. led_work->set_duty(led_work->duty_value);
  277. led_work->flicker_count--;
  278. }
  279. else if(led_work->single_flicker_period == off_period)
  280. {
  281. led_work->single_flicker_period--;
  282. led_work->duty_value = led_work->duty_on;
  283. led_work->single_on_durationTime = led_work->on_durationTime;
  284. led_work->set_duty(led_work->duty_value);
  285. }
  286. else{
  287. if(led_work->single_flicker_period > off_period)
  288. {
  289. if(led_work->single_off_durationTime == 0)
  290. {
  291. led_work->single_flicker_period--;
  292. led_work->duty_value = (led_work->flicker_period - led_work->single_flicker_period) * 100 / led_work->flicker_onperiod;
  293. led_work->set_duty(led_work->duty_value);
  294. }
  295. else{
  296. led_work->single_off_durationTime--;
  297. }
  298. }
  299. else{
  300. if(led_work->single_on_durationTime == 0)
  301. {
  302. led_work->single_flicker_period--;
  303. led_work->duty_value = led_work->single_flicker_period * 100 / off_period;
  304. led_work->set_duty(led_work->duty_value);
  305. }
  306. else{
  307. led_work->single_on_durationTime--;
  308. }
  309. }
  310. }
  311. }
  312. else{
  313. led_work->workStat = LED_WORK_OFF;
  314. }
  315. }
  316. /*******************************************************************************
  317. * @函数名称 led_indication
  318. * @函数说明 LED灯处理
  319. * @输入参数 led_work:led灯结构体直针
  320. * @输出参数 无
  321. * @返回参数 无
  322. *******************************************************************************/
  323. static void led_indication(led_work_s *led_work)
  324. {
  325. switch(led_work->workStat)
  326. {
  327. case LED_WORK_OFF:
  328. {
  329. break;
  330. }
  331. case LED_WORK_ON:
  332. {
  333. break;
  334. }
  335. case LED_WORK_INVERT:
  336. {
  337. led_invert(led_work);
  338. break;
  339. }
  340. case LED_WORK_BREATHE:
  341. {
  342. led_heart(led_work);
  343. break;
  344. }
  345. default:break;
  346. }
  347. }
  348. /*******************************************************************************
  349. * @函数名称 led_task
  350. * @函数说明 LED任务
  351. * @输入参数 无
  352. * @输出参数 无
  353. * @返回参数 无
  354. *******************************************************************************/
  355. static void led_task(void)
  356. {
  357. for(int i = 0; i < LED_TYPE_MAX; i++)
  358. {
  359. led_indication(&led_work[i]);
  360. }
  361. }
  362. /*******************************************************************************
  363. * @函数名称 led_task
  364. * @函数说明 task的event处理回调函数,需要在注册task时候,传进去
  365. * @输入参数 task_id:任务ID
  366. events:事件
  367. * @输出参数 无
  368. * @返回参数 无
  369. *******************************************************************************/
  370. static uint16_t led_task_process_event(uint8_t task_id, uint16_t events)
  371. {
  372. //event 处理
  373. if(events & (1 << LED_QUEUE_TIME))
  374. {
  375. led_task();
  376. return (events ^ (1 << LED_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  377. }
  378. return 0;
  379. }
  380. /*******************************************************************************
  381. * @函数名称 set_led_indication
  382. * @函数说明 LED参数设置
  383. * @输入参数 type:LED灯号
  384. color:颜色
  385. workStat:状态
  386. * @输出参数 无
  387. * @返回参数 无
  388. *******************************************************************************/
  389. bool set_led_indication(LED_TYPE type, LED_COLOR color, LED_WORK_STAT work_stat, ...)
  390. {
  391. bool stat = false;
  392. if(type >= LED_TYPE_MAX)
  393. {
  394. goto exit;
  395. }
  396. if(color > YELLOW_LED)
  397. {
  398. goto exit;
  399. }
  400. if(work_stat == LED_WORK_OFF || work_stat == LED_WORK_ON)
  401. {
  402. led_work[type].color = color;
  403. led_work[type].workStat = work_stat;
  404. led_work[type].set_duty((work_stat == LED_WORK_ON) ? LED_ON_DUTY : LED_OFF_DUTY);
  405. stat = true;
  406. }
  407. else if(work_stat == LED_WORK_INVERT || work_stat == LED_WORK_BREATHE)
  408. {
  409. led_work[type].color = color;
  410. led_work[type].workStat = work_stat;
  411. led_work[type].duty_value = 0;
  412. led_work[type].stat = LED_STAT_OFF;
  413. va_list ap; //保存所有参数
  414. va_start(ap, work_stat); //第一个参数的位置
  415. led_work[type].flicker_period = va_arg(ap, uint32_t)/LED_INTERVAL;
  416. led_work[type].flicker_onperiod = va_arg(ap, uint32_t)/LED_INTERVAL;
  417. led_work[type].flicker_count = va_arg(ap, uint32_t);
  418. if(led_work[type].flicker_count == 0)
  419. {
  420. led_work[type].flicker_count = 0x7FFFFFFF;
  421. }
  422. led_work[type].single_flicker_period = led_work[type].flicker_period;
  423. if(work_stat == LED_WORK_BREATHE)
  424. {
  425. led_work[type].on_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
  426. led_work[type].off_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
  427. led_work[type].single_on_durationTime = led_work[type].on_durationTime;
  428. led_work[type].single_off_durationTime = led_work[type].off_durationTime;
  429. }
  430. va_end(ap);
  431. stat = true;
  432. }
  433. exit:
  434. return stat;
  435. }
  436. /*******************************************************************************
  437. * @函数名称 led_task_init
  438. * @函数说明 LED任务初始化
  439. * @输入参数 无
  440. * @输出参数 无
  441. * @返回参数 无
  442. *******************************************************************************/
  443. void led_task_init(void)
  444. {
  445. led_task_id = TMOS_ProcessEventRegister(led_task_process_event);
  446. PRINT("led_task_id=%d\n", led_task_id);
  447. led_pwm_init();
  448. }
  449. /*******************************************************************************
  450. * @函数名称 led_task_start
  451. * @函数说明 LED任务开始
  452. * @输入参数 无
  453. * @输出参数 无
  454. * @返回参数 无
  455. *******************************************************************************/
  456. void led_task_start(void)
  457. {
  458. bStatus_t stat = tmos_start_reload_task(led_task_id, (1 << LED_QUEUE_TIME), MS1_TO_SYSTEM_TIME(LED_INTERVAL));
  459. }
  460. /*******************************************************************************
  461. * @函数名称 vUser_led_set_view_stat
  462. * @函数说明 设置LED工作状态
  463. * @输入参数 stat:led工作状态
  464. * @输出参数 无
  465. * @返回参数 无
  466. *******************************************************************************/
  467. void vUser_led_set_view_stat(led_view_stat_e stat)
  468. {
  469. // PRINT("set led stat:%d,%d\n", idx, stat);
  470. switch(stat)
  471. {
  472. case LED_VIEW_ENTER_OTA:{
  473. set_led_indication(DEV_LED, YELLOW_LED, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
  474. set_led_indication(LEFT_LED, YELLOW_LED, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
  475. set_led_indication(RIGHT_LED, YELLOW_LED, LED_WORK_BREATHE, 3000, 1500, 0, 500, 500);
  476. }break;
  477. case LED_VIEW_OTA:{
  478. set_led_indication(DEV_LED, YELLOW_LED, LED_WORK_BREATHE, 200, 100, 0, 10, 10);
  479. set_led_indication(LEFT_LED, YELLOW_LED, LED_WORK_BREATHE, 200, 100, 0, 10, 10);
  480. set_led_indication(RIGHT_LED, YELLOW_LED, LED_WORK_BREATHE, 200, 100, 0, 10, 10);
  481. }break;
  482. default:break;
  483. }
  484. }