dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
led_pwm.c
Go to the documentation of this file.
1 
11 /*
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, see <http://www.gnu.org/licenses/>
24  */
25 
26 #include "pios.h" /* PIOS_LED_* -- FIXME: include is too coarse */
27 #include "led_pwm.h" /* API definition */
28 
29 static uint32_t led_pwm_on_p(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t uptime, uint8_t *fraction) {
30  /* 0 - pwm_sweep_steps */
31  uint32_t curr_step = (uptime / pwm_period) % pwm_sweep_steps;
32 
33  /* fraction of pwm_period */
34  uint32_t pwm_duty = pwm_period * curr_step / pwm_sweep_steps;
35 
36  /* ticks once per full sweep */
37  uint32_t curr_sweep = (uptime / (pwm_period * pwm_sweep_steps));
38 
39  /* reverse direction in odd sweeps */
40  if (curr_sweep & 1) {
41  pwm_duty = pwm_period - pwm_duty;
42  }
43 
44  if (fraction) {
45  *fraction = 255 * pwm_duty / pwm_period;
46  }
47 
48  return ((uptime % pwm_period) > pwm_duty) ? 1 : 0;
49 }
50 
51 void led_pwm_config(struct led_pwm_state *leds,
52  uint32_t pwm_1_period_us,
53  uint32_t pwm_1_sweep_steps,
54  uint32_t pwm_2_period_us,
55  uint32_t pwm_2_sweep_steps)
56 {
57  /* PWM #1 */
58  if (pwm_1_period_us > 0) {
59  leds->pwm_1_enabled = true;
60  leds->pwm_1_period_us = pwm_1_period_us;
61  leds->pwm_1_sweep_steps = pwm_1_sweep_steps;
62  } else {
63  leds->pwm_1_enabled = false;
64  }
65 
66 
67  /* PWM #2 */
68  if (pwm_2_period_us > 0) {
69  leds->pwm_2_enabled = true;
70  leds->pwm_2_period_us = pwm_2_period_us;
71  leds->pwm_2_sweep_steps = pwm_2_sweep_steps;
72  } else {
73  leds->pwm_2_enabled = false;
74  }
75 }
76 
77 void led_pwm_add_ticks(struct led_pwm_state *leds, uint32_t elapsed_us)
78 {
79  leds->uptime_us += elapsed_us;
80 }
81 
83 {
84  uint8_t led1_fraction = 128;
85 
86  /*
87  * Compute states of emulated PWM timers
88  */
89  bool pwm_1_led_state = true; /* forces LED on when pwm1 is disabled */
90  if (leds->pwm_1_enabled) {
91  pwm_1_led_state = led_pwm_on_p(leds->pwm_1_period_us,
92  leds->pwm_1_sweep_steps,
93  leds->uptime_us,
94  &led1_fraction);
95  }
96 
97 #ifdef PIOS_LED_ALARM
98  uint8_t led2_fraction = 0;
99 
100  bool pwm_2_led_state = false; /* forces LED off when pwm2 is disabled */
101  if (leds->pwm_2_enabled) {
102  pwm_2_led_state = led_pwm_on_p(leds->pwm_2_period_us,
103  leds->pwm_2_sweep_steps,
104  leds->uptime_us,
105  &led2_fraction);
106  }
107 #endif
108 
109  /*
110  * Toggle the LEDs based on the 2 emulated PWM timers
111  */
112 
113  if (pwm_1_led_state) {
115  } else {
117  }
118 
119 #ifdef PIOS_INCLUDE_WS2811
120 #define WS2811_UPDATE_INTERVAL 15000 // 67Hz!
121 
122  if ((leds->uptime_us - leds->last_ws2811_us) >= WS2811_UPDATE_INTERVAL) {
123  leds->last_ws2811_us = leds->uptime_us;
124 
125  PIOS_WS2811_set_all(pios_ws2811, led1_fraction / 2,
126  led2_fraction / 3, 0);
128  }
129 #endif
130 
131 #ifdef PIOS_LED_ALARM
133  if (pwm_2_led_state) {
135  } else {
137  }
138  }
139 #endif
140 
141  return true;
142 }
143 
static uint32_t led_pwm_on_p(uint32_t pwm_period, uint32_t pwm_sweep_steps, uint32_t uptime, uint8_t *fraction)
Definition: led_pwm.c:29
Main PiOS header to include all the compiled in PiOS options.
bool led_pwm_update_leds(struct led_pwm_state *leds)
Definition: led_pwm.c:82
uint32_t pwm_2_sweep_steps
Definition: led_pwm.h:41
void PIOS_ANNUNC_Off(uint32_t annunc_id)
uint32_t pwm_1_period_us
Definition: led_pwm.h:36
void led_pwm_add_ticks(struct led_pwm_state *leds, uint32_t elapsed_us)
Definition: led_pwm.c:77
#define PIOS_LED_ALARM
Definition: pios_board.h:86
void PIOS_WS2811_set_all(ws2811_dev_t dev, uint8_t r, uint8_t g, uint8_t b)
Sets all LEDs to a color value.
Definition: pios_ws2811.c:219
uint32_t pwm_2_period_us
Definition: led_pwm.h:40
bool pwm_2_enabled
Definition: led_pwm.h:39
void led_pwm_config(struct led_pwm_state *leds, uint32_t pwm_1_period_us, uint32_t pwm_1_sweep_steps, uint32_t pwm_2_period_us, uint32_t pwm_2_sweep_steps)
Definition: led_pwm.c:51
ws2811_dev_t pios_ws2811
Definition: pios_board.c:66
uint32_t pwm_1_sweep_steps
Definition: led_pwm.h:37
void PIOS_ANNUNC_On(uint32_t annunc_id)
bool pwm_1_enabled
Definition: led_pwm.h:35
void PIOS_WS2811_trigger_update(ws2811_dev_t dev)
Trigger an update of the LED strand.
Definition: pios_ws2811.c:197
uint32_t uptime_us
Definition: led_pwm.h:33
#define PIOS_LED_HEARTBEAT
Definition: pios_board.h:85