Skip to content

Commit d670068

Browse files
committed
ev3-pru1: add PWMs for EV3 LEDs
This adds PWMs so that we can adjust the brighness of the LEDs on the EV3. The 366Hz duty cycle was selected for code efficency since we can reuse the same timer as the tacho. This increases the firmware size by 112 bytes. Issue: ev3dev/ev3dev#1160
1 parent bcfdbbb commit d670068

File tree

1 file changed

+40
-8
lines changed

1 file changed

+40
-8
lines changed

ev3-pru1/main.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,19 @@ enum ev3_pru_tacho {
3737
NUM_EV3_PRU_TACHO
3838
};
3939

40+
enum ev3_pru_pwm {
41+
EV3_PRU_PWM_0,
42+
EV3_PRU_PWM_1,
43+
EV3_PRU_PWM_2,
44+
EV3_PRU_PWM_3,
45+
NUM_EV3_PRU_PWM
46+
};
47+
4048
struct ev3_pru_tacho_remote_data {
4149
uint32_t position[NUM_EV3_PRU_TACHO][EV3_PRU_TACHO_RING_BUF_SIZE];
4250
uint32_t timestamp[NUM_EV3_PRU_TACHO][EV3_PRU_TACHO_RING_BUF_SIZE];
4351
uint32_t head[NUM_EV3_PRU_TACHO];
52+
uint8_t pwm[NUM_EV3_PRU_PWM];
4453
};
4554

4655
/* end Linux */
@@ -88,11 +97,11 @@ static uint8_t tacho_state[NUM_EV3_PRU_TACHO];
8897
static uint32_t tacho_prev_timestamp[NUM_EV3_PRU_TACHO];
8998
static uint32_t tacho_counts[NUM_EV3_PRU_TACHO];
9099

91-
static void update_tacho_state(enum ev3_pru_tacho idx, uint8_t new_state)
100+
static void update_tacho_state(enum ev3_pru_tacho idx, uint8_t new_state, uint32_t now)
92101
{
93102
uint8_t current_state = tacho_state[idx] & 0x3;
94103
enum direction new_dir = UNKNOWN;
95-
uint32_t now, elapsed;
104+
uint32_t elapsed;
96105

97106
switch (current_state) {
98107
case 0x0:
@@ -131,7 +140,6 @@ static void update_tacho_state(enum ev3_pru_tacho idx, uint8_t new_state)
131140
tacho_state[idx] = new_state;
132141
tacho_counts[idx] += new_dir;
133142

134-
now = TIMER64P0.TIM34;
135143
elapsed = now - tacho_prev_timestamp[idx];
136144

137145
// if there was a change in count or if count hasn't changed for 50ms
@@ -146,7 +154,18 @@ static void update_tacho_state(enum ev3_pru_tacho idx, uint8_t new_state)
146154
}
147155
}
148156

149-
int main(void) {
157+
static void update_pwm(enum ev3_pru_pwm pwm, uint8_t pwm_count, uint32_t gpio_flags)
158+
{
159+
if (pwm_count < REMOTE_DATA.pwm[pwm]) {
160+
GPIO.SET_DATA67 = gpio_flags;
161+
}
162+
else {
163+
GPIO.CLR_DATA67 = gpio_flags;
164+
}
165+
}
166+
167+
int main(void)
168+
{
150169
volatile uint8_t *status;
151170
struct pru_rpmsg_transport transport;
152171
uint16_t src, dst, len;
@@ -166,10 +185,23 @@ int main(void) {
166185
while (true) {
167186
// wait for the ARM to kick us
168187
while (!(__R31 & HOST_INT)) {
169-
update_tacho_state(EV3_PRU_TACHO_A, TACHO_STATE(A));
170-
update_tacho_state(EV3_PRU_TACHO_B, TACHO_STATE(B));
171-
update_tacho_state(EV3_PRU_TACHO_C, TACHO_STATE(C));
172-
update_tacho_state(EV3_PRU_TACHO_D, TACHO_STATE(D));
188+
uint32_t now = TIMER64P0.TIM34;
189+
uint8_t pwm_count;
190+
191+
update_tacho_state(EV3_PRU_TACHO_A, TACHO_STATE(A), now);
192+
update_tacho_state(EV3_PRU_TACHO_B, TACHO_STATE(B), now);
193+
update_tacho_state(EV3_PRU_TACHO_C, TACHO_STATE(C), now);
194+
update_tacho_state(EV3_PRU_TACHO_D, TACHO_STATE(D), now);
195+
196+
// this gives us a PWM period of 366Hz with a max duty
197+
// cycle of 256 counts (24MHz / 256 / 256)
198+
pwm_count = now >> 8;
199+
200+
// update PWM outputs
201+
update_pwm(EV3_PRU_PWM_0, pwm_count, 1 << 13); // LED0, GPIO 6[13]
202+
update_pwm(EV3_PRU_PWM_1, pwm_count, 1 << 7); // LED1, GPIO 6[7]
203+
update_pwm(EV3_PRU_PWM_2, pwm_count, 1 << 14); // LED2, GPIO 6[14]
204+
update_pwm(EV3_PRU_PWM_3, pwm_count, 1 << 12); // LED3, GPIO 6[12]
173205
}
174206

175207
// clear the interrupt

0 commit comments

Comments
 (0)