led.c 13 KB

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