sseg: add support for PWM per segment
This commit is contained in:
parent
455118882b
commit
c82a54b06c
16
src/main.c
16
src/main.c
|
@ -132,6 +132,18 @@ static void update_countdown_fsm(uint32_t time_ms)
|
|||
sseg_set_char(2, 'f', false);
|
||||
}
|
||||
|
||||
{ // animation block
|
||||
uint32_t modtime = time_in_state % 3000;
|
||||
|
||||
if(modtime < 500) {
|
||||
sseg_set_pwm_percent(0, 100 - 75 * modtime / 500);
|
||||
} else if(modtime < 1000) {
|
||||
sseg_set_pwm_percent(1, 100 - 75 * (modtime - 500) / 500);
|
||||
} else if(modtime < 1500) {
|
||||
sseg_set_pwm_percent(2, 100 - 75 * (modtime - 1000) / 500);
|
||||
}
|
||||
}
|
||||
|
||||
if(buttons_get_events(BTN_ON) & BTN_EVENT_PRESSED) {
|
||||
m_countdown_state = COUNTDOWN_STARTING;
|
||||
}
|
||||
|
@ -148,6 +160,10 @@ static void update_countdown_fsm(uint32_t time_ms)
|
|||
sseg_set_char(0, '|', false);
|
||||
sseg_set_char(1, ' ', false);
|
||||
sseg_set_char(2, ' ', false);
|
||||
|
||||
sseg_set_pwm_percent(0, 100);
|
||||
sseg_set_pwm_percent(1, 100);
|
||||
sseg_set_pwm_percent(2, 100);
|
||||
break;
|
||||
|
||||
case 500:
|
||||
|
|
21
src/sseg.c
21
src/sseg.c
|
@ -23,10 +23,11 @@
|
|||
#define SSEG_START_PIN 0
|
||||
|
||||
static volatile uint32_t m_dma_buffer[4] __attribute__((aligned(4*sizeof(uint32_t *)))) = {
|
||||
0x0000013D, // segment 0 = 'Z' = '2'
|
||||
0x00000277, // segment 1 = A
|
||||
0x00000476, // segment 2 = M
|
||||
0x00000000, // dummy entry
|
||||
//AABBDDCC; DD = segment code; CC = PWM off time; BB = multiplexer pins; AA = PWM on time
|
||||
0xFF013D00, // segment 0 = 'Z' = '2'
|
||||
0xFF027700, // segment 1 = A
|
||||
0xFF047600, // segment 2 = M
|
||||
0x00000000, // dummy entry (all off, for the shortest possible time)
|
||||
};
|
||||
|
||||
static PIO m_pio;
|
||||
|
@ -173,5 +174,15 @@ void sseg_loop(void)
|
|||
void sseg_set_char(uint8_t seg, char c, bool with_dot)
|
||||
{
|
||||
uint dot_bit = with_dot ? 0x80 : 0x00;
|
||||
m_dma_buffer[seg] = (m_dma_buffer[seg] & 0xFFFFFF00) | dot_bit | ascii_to_sseg(c);
|
||||
m_dma_buffer[seg] = (m_dma_buffer[seg] & 0xFFFF00FF) | ((dot_bit | ascii_to_sseg(c)) << 8);
|
||||
}
|
||||
|
||||
void sseg_set_pwm_times(uint8_t seg, uint8_t on_time, uint8_t off_time)
|
||||
{
|
||||
m_dma_buffer[seg] = (m_dma_buffer[seg] & 0x00FFFF00) | ((uint32_t)on_time << 24) | (uint32_t)off_time;
|
||||
}
|
||||
|
||||
void sseg_set_pwm_percent(uint8_t seg, uint8_t on_percent)
|
||||
{
|
||||
sseg_set_pwm_times(seg, on_percent, 100-on_percent);
|
||||
}
|
||||
|
|
|
@ -9,4 +9,7 @@ void sseg_loop(void);
|
|||
|
||||
void sseg_set_char(uint8_t seg, char c, bool with_dot);
|
||||
|
||||
void sseg_set_pwm_times(uint8_t seg, uint8_t on_time, uint8_t off_time);
|
||||
void sseg_set_pwm_percent(uint8_t seg, uint8_t on_percent);
|
||||
|
||||
#endif // SSEG_H
|
||||
|
|
12
src/sseg.pio
12
src/sseg.pio
|
@ -3,8 +3,14 @@
|
|||
; Repeatedly get one word of data from the TX FIFO, stalling when the FIFO is
|
||||
; empty. Write the least significant bit to the OUT pin group.
|
||||
|
||||
loop:
|
||||
next_digit:
|
||||
set pins, 0x00 ; set MUX pins to 0
|
||||
pull
|
||||
out pins, 11 [31] ; write the data from the FIFO to the outputs and wait some time
|
||||
jmp loop [31] ; repeat and wait some extra time
|
||||
out x, 8 ; load "pwm on" cycle count into the scratch register
|
||||
off_loop:
|
||||
jmp x--, off_loop
|
||||
out pins, 16 ; set the segment pins (only the lower 11 bits are used)
|
||||
out x, 8 ; load "pwm on" cycle count into the scratch register
|
||||
on_loop:
|
||||
jmp x--, on_loop
|
||||
jmp next_digit ; repeat the whole process
|
||||
|
|
Loading…
Reference in a new issue