Add PIO TMDS encode to moon example, as a separate build target

two-pixels-per-word
Luke Wren 2021-01-23 17:18:43 +00:00
rodzic 1f4cbf8716
commit 38ded59624
2 zmienionych plików z 70 dodań i 20 usunięć

Wyświetl plik

@ -1,6 +1,4 @@
# Replace TMDS with 10 bit UART (same baud rate):
# add_definitions(-DDVI_SERIAL_DEBUG=1)
# add_definitions(-DRUN_FROM_CRYSTAL)
# First target: executable that uses regular software encode loop
add_executable(moon
main.c
@ -8,14 +6,38 @@ add_executable(moon
target_compile_options(moon PRIVATE -Wall)
target_compile_definitions(moon PRIVATE DVI_VERTICAL_REPEAT=1 DVI_N_TMDS_BUFFERS=3 DVI_MONOCHROME_TMDS)
target_compile_definitions(moon PRIVATE
DVI_VERTICAL_REPEAT=1
DVI_N_TMDS_BUFFERS=3
DVI_MONOCHROME_TMDS
)
target_link_libraries(moon
pico_stdlib
pico_multicore
libdvi
)
# create map/bin/hex file etc.
pico_add_extra_outputs(moon)
# Second target (same source): executable that offloads TMDS encode to PIO + DMA
add_executable(moon_pio_encode
main.c
)
target_compile_options(moon_pio_encode PRIVATE -Wall)
target_compile_definitions(moon_pio_encode PRIVATE
DVI_VERTICAL_REPEAT=1
DVI_N_TMDS_BUFFERS=3
DVI_MONOCHROME_TMDS
USE_PIO_TMDS_ENCODE
)
target_link_libraries(moon_pio_encode
pico_stdlib
libdvi
)
pico_add_extra_outputs(moon_pio_encode)

Wyświetl plik

@ -1,18 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#include "pico/multicore.h"
#include "hardware/clocks.h"
#include "hardware/irq.h"
#include "hardware/sync.h"
#include "hardware/gpio.h"
#include "hardware/vreg.h"
#include "dvi.h"
#include "dvi_serialiser.h"
#include "common_dvi_pin_configs.h"
#include "tmds_encode_1bpp.pio.h"
#include "tmds_encode.h"
// Display a full-resolution 1bpp image. By default this uses the fast 1bpp
// encode routine from libdvi (which is actually fast enough for bitplaned
// RGB111). If USE_PIO_TMDS_ENCODE is defined, the TMDS encode can be
// offloaded to a slower encode loop on a spare state machine.
// Pick one:
#define MODE_640x480_60Hz
@ -46,28 +46,56 @@ struct dvi_inst dvi0;
int main() {
vreg_set_voltage(VREG_VSEL);
sleep_ms(10);
// Run system at TMDS bit clock
set_sys_clock_khz(BIT_CLOCK_MHZ * 1000, true);
setup_default_uart();
for (int i = DEBUG_PIN0; i < DEBUG_PIN0 + DEBUG_N_PINS; ++i) {
gpio_init(i);
gpio_set_dir(i, GPIO_OUT);
}
dvi0.timing = &DVI_TIMING;
dvi0.ser_cfg = DEFAULT_DVI_SERIAL_CONFIG;
dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());
dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
dvi_start(&dvi0);
// Set up extra SM, and DMA channels, to offload TMDS encode if necessary
#ifdef USE_PIO_TMDS_ENCODE
PIO encode_pio = dvi0.ser_cfg.pio;
uint encode_sm = pio_claim_unused_sm(encode_pio, true);
tmds_encode_1bpp_init(encode_pio, encode_sm);
uint dma_chan_put = dma_claim_unused_channel(true);
dma_channel_config c = dma_channel_get_default_config(dma_chan_put);
channel_config_set_dreq(&c, pio_get_dreq(encode_pio, encode_sm, true));
dma_channel_configure(dma_chan_put, &c,
&encode_pio->txf[encode_sm],
NULL,
FRAME_WIDTH / 32,
false
);
uint dma_chan_get = dma_claim_unused_channel(true);
c = dma_channel_get_default_config(dma_chan_get);
channel_config_set_dreq(&c, pio_get_dreq(encode_pio, encode_sm, false));
channel_config_set_write_increment(&c, true);
channel_config_set_read_increment(&c, false);
dma_channel_configure(dma_chan_get, &c,
NULL,
&encode_pio->rxf[encode_sm],
FRAME_WIDTH,
false
);
#endif
dvi_start(&dvi0);
while (true) {
for (uint y = 0; y < FRAME_HEIGHT; ++y) {
const uint32_t *colourbuf = &((const uint32_t*)moon_img)[y * FRAME_WIDTH / 32];
uint32_t *tmdsbuf;
queue_remove_blocking_u32(&dvi0.q_tmds_free, &tmdsbuf);
#ifndef USE_PIO_TMDS_ENCODE
tmds_encode_1bpp(colourbuf, tmdsbuf, FRAME_WIDTH);
#else
dma_channel_set_read_addr(dma_chan_put, colourbuf, true);
dma_channel_set_write_addr(dma_chan_get, tmdsbuf, true);
dma_channel_wait_for_finish_blocking(dma_chan_get);
#endif
queue_add_blocking_u32(&dvi0.q_tmds_valid, &tmdsbuf);
}
}