1
0
Fork 0
mirror of https://github.com/radex/radmatrix.git synced 2024-10-04 03:37:46 +00:00

wip: pio-based delay

This commit is contained in:
radex 2024-05-30 11:39:56 +02:00
parent 3880a58137
commit d43bdba36e
Signed by: radex
SSH key fingerprint: SHA256:hvqRXAGG1h89yqnS+cyFTLKQbzjWD4uXIqw7Y+0ws30
3 changed files with 103 additions and 12 deletions

View file

@ -7,8 +7,9 @@
#include "leds.h"
#include "leds.pio.h"
PIO pusher_pio = pio0;
PIO leds_pio = pio0;
uint pusher_sm = 255; // invalid
uint delay_sm = 255; // invalid
// NOTE: RCLK, SRCLK capture on *rising* edge
inline void pulsePin(uint8_t pin) {
@ -89,6 +90,7 @@ void leds_initPusher();
void leds_initRenderer() {
leds_initPusher();
leds_initDelay();
multicore_reset_core1();
multicore_launch_core1(main2);
}
@ -143,14 +145,14 @@ void leds_render() {
// - DMA?
for (int xModule = 0; xModule < COL_MODULES; xModule++) {
uint32_t pxValues = buffer[bufferOffset + xModule];
pio_sm_put_blocking(pusher_pio, pusher_sm, pxValues);
pio_sm_put_blocking(leds_pio, pusher_sm, pxValues);
}
// wait until pushing and RCLK latch are done
while (!pio_interrupt_get(pusher_pio, 0)) {
while (!pio_interrupt_get(leds_pio, 0)) {
tight_loop_contents();
}
pio_interrupt_clear(pusher_pio, pusher_sm);
pio_interrupt_clear(leds_pio, pusher_sm);
// show for a certain period
outputEnable(ROW_OE, true);
@ -167,7 +169,7 @@ void leds_render() {
}
void leds_initPusher() {
PIO pio = pusher_pio;
PIO pio = leds_pio;
uint sm = pio_claim_unused_sm(pio, true);
pusher_sm = sm;
@ -204,3 +206,26 @@ void leds_initPusher() {
pio_sm_init(pio, sm, offset, &config);
pio_sm_set_enabled(pio, sm, true);
}
void leds_initDelay() {
PIO pio = leds_pio;
uint sm = pio_claim_unused_sm(pio, true);
delay_sm = sm;
uint offset = pio_add_program(pio, &leds_delay_program);
pio_sm_config config = leds_delay_program_get_default_config(offset);
sm_config_set_clkdiv_int_frac(&config, 1, 0);
// Shift OSR to the right, autopull
sm_config_set_out_shift(&config, true, true, 32);
// Set sideset (OE) pin, connect to pad, set as output
sm_config_set_sideset_pins(&config, ROW_OE);
pio_gpio_init(pio, ROW_OE);
pio_sm_set_consecutive_pindirs(pio, sm, ROW_OE, 1, true);
// Load our configuration, and jump to the start of the program
pio_sm_init(pio, sm, offset, &config);
pio_sm_set_enabled(pio, sm, true);
}

View file

@ -1,3 +1,6 @@
.define public irq_did_latch 0
.define public irq_delaying 1
.program leds_px_pusher
.side_set 1 opt
public entry_point:
@ -22,10 +25,32 @@ end:
jmp x-- end_of_row
.wrap
end_of_row:
; indicate to main processor that row was processed
irq set 0
; wait until previous row's delay is complete
wait 0 irq irq_delaying
; signal that row is processed
irq set irq_did_latch
; clock RCLK (latch onto register output stage)
set pins, 1 [3]
set pins, 0
; wait for next row
jmp entry_point
.program leds_delay
.side_set 1 opt
.define public output_on 0
.define public output_off 1
public entry_point:
; begin only after data is latched
wait 1 irq irq_did_latch
; signal that delay is ongoing
irq set irq_delaying
; x = number of cycles to delay
out x, 32
loop:
; busy loop for x cycles
; enable output
jmp x-- loop side output_on
end:
; signal that delay is complete
; disable output
irq clear irq_delaying side output_off

View file

@ -8,6 +8,9 @@
#include "hardware/pio.h"
#endif
#define irq_did_latch 0
#define irq_delaying 1
// -------------- //
// leds_px_pusher //
// -------------- //
@ -25,16 +28,17 @@ static const uint16_t leds_px_pusher_program_instructions[] = {
0x7028, // 3: out x, 8 side 0
0x0045, // 4: jmp x--, 5
// .wrap
0xc000, // 5: irq nowait 0
0xe301, // 6: set pins, 1 [3]
0xe000, // 7: set pins, 0
0x0000, // 8: jmp 0
0x2041, // 5: wait 0 irq, 1
0xc000, // 6: irq nowait 0
0xe301, // 7: set pins, 1 [3]
0xe000, // 8: set pins, 0
0x0000, // 9: jmp 0
};
#if !PICO_NO_HARDWARE
static const struct pio_program leds_px_pusher_program = {
.instructions = leds_px_pusher_program_instructions,
.length = 9,
.length = 10,
.origin = -1,
};
@ -46,3 +50,40 @@ static inline pio_sm_config leds_px_pusher_program_get_default_config(uint offse
}
#endif
// ---------- //
// leds_delay //
// ---------- //
#define leds_delay_wrap_target 0
#define leds_delay_wrap 4
#define leds_delay_output_on 0
#define leds_delay_output_off 1
#define leds_delay_offset_entry_point 0u
static const uint16_t leds_delay_program_instructions[] = {
// .wrap_target
0x20c0, // 0: wait 1 irq, 0
0xc001, // 1: irq nowait 1
0x6020, // 2: out x, 32
0x1043, // 3: jmp x--, 3 side 0
0xd841, // 4: irq clear 1 side 1
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program leds_delay_program = {
.instructions = leds_delay_program_instructions,
.length = 5,
.origin = -1,
};
static inline pio_sm_config leds_delay_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + leds_delay_wrap_target, offset + leds_delay_wrap);
sm_config_set_sideset(&c, 2, true, false);
return c;
}
#endif