1
0
Fork 0

optimize: use irq to signal readiness

sd2
radex 2024-05-26 23:00:49 +02:00
parent fbbcf0746c
commit 2a953464fd
Signed by: radex
SSH Key Fingerprint: SHA256:hvqRXAGG1h89yqnS+cyFTLKQbzjWD4uXIqw7Y+0ws30
5 changed files with 15 additions and 17 deletions

View File

@ -78,6 +78,7 @@ int32_t gfx_decoder_loadNextFrame() {
}
}
}
ledBufferReady = true;
// copy to framebuffer
// TODO: mutex? double buffer? or something...

View File

@ -36,6 +36,7 @@ uint8_t brightnessPhaseDelays[COLOR_BITS] = {0, 1, 6, 20, 60};
// NOTE: Alignment required to allow 4-byte reads
uint8_t framebuffer[ROW_COUNT * COL_COUNT] __attribute__((aligned(32))) = {0};
bool ledBufferReady = false;
uint32_t ledBuffer[8][ROW_COUNT * COL_MODULES] = {0};
void leds_init() {
@ -93,6 +94,11 @@ void leds_initRenderer() {
}
void leds_render() {
if (!ledBufferReady) {
outputEnable(ROW_OE, false);
return;
}
// brightness phase
bool brightPhase = brightnessPhase >= 3;
auto buffer = ledBuffer[brightnessPhase + 3];
@ -134,25 +140,16 @@ void leds_render() {
// - see if we can disable px pusher delays on improved electric interface
// - improve outer loop which adds 2us of processing on each loop
// - change busy wait into some kind of interrupt-based thing so that processing can continue
// - latch row and clock simultaneously, avoid disabling output
// - DMA?
for (int xModule = 0; xModule < COL_MODULES; xModule++) {
uint32_t pxValues = buffer[bufferOffset + xModule];
pio_sm_put_blocking(pusher_pio, pusher_sm, pxValues);
}
// wait for all data to be shifted out
while (!pio_sm_is_tx_fifo_empty(pusher_pio, pusher_sm)) {
// wait until pushing and RCLK latch are done
while (!pio_interrupt_get(pusher_pio, 0)) {
tight_loop_contents();
}
// TODO: Is there an API to wait for PIO to actually become idle?
// pio_sm_drain_tx_fifo doesn't seem to do the trick
// if not, we might need to use irqs or something
busy_wait_us(4);
// TODO: Why doesn't this work?!
// while (!pio_interrupt_get(pusher_pio, pusher_sm)) {
// tight_loop_contents();
// }
pio_interrupt_clear(pusher_pio, pusher_sm);
// show for a certain period

View File

@ -33,6 +33,7 @@ void leds_loop();
void leds_render();
extern uint8_t framebuffer[ROW_COUNT * COL_COUNT];
extern bool ledBufferReady;
extern uint32_t ledBuffer[8][ROW_COUNT * COL_MODULES];
#endif

View File

@ -6,7 +6,7 @@ public entry_point:
; pull
; push 24 bits to the shift registers
; also, return latch bit to 0
set x, 23 side 0
set x, 23 side 0
loop:
; TODO: check if delays can be lowered with a PCB
; set bit; lower clock edge
@ -23,10 +23,9 @@ end:
.wrap
end_of_row:
; indicate to main processor that row was processed
irq set 0
; clock RCLK (latch onto register output stage)
set pins, 1 [3]
set pins, 0
irq wait 0 rel
; wait for next row
jmp entry_point

View File

@ -25,9 +25,9 @@ static const uint16_t leds_px_pusher_program_instructions[] = {
0x7028, // 3: out x, 8 side 0
0x0045, // 4: jmp x--, 5
// .wrap
0xe301, // 5: set pins, 1 [3]
0xe000, // 6: set pins, 0
0xc030, // 7: irq wait 0 rel
0xc000, // 5: irq nowait 0
0xe301, // 6: set pins, 1 [3]
0xe000, // 7: set pins, 0
0x0000, // 8: jmp 0
};