From bbe42f31bbc76dbb404c0fceb0efbdfc20be7f51 Mon Sep 17 00:00:00 2001 From: giomba Date: Mon, 10 Oct 2022 19:10:52 +0200 Subject: [PATCH] Add freerunning VGA pixel clock draft. --- CMakeLists.txt | 10 +++++- src/main.c | 87 ++++++++++++++++++++++++++++++++++++++++++++------ src/vga.pio | 9 ++++++ 3 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 src/vga.pio diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a269a7..f22f1bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,11 @@ add_executable(ceda2vga src/main.c ) +pico_generate_pio_header(ceda2vga + ${CMAKE_CURRENT_LIST_DIR}/src/vga.pio + ) + +# configure stdio to make I/O on virtual usb serial port pico_enable_stdio_usb(ceda2vga 1) pico_enable_stdio_uart(ceda2vga 0) @@ -33,7 +38,10 @@ pico_enable_stdio_uart(ceda2vga 0) pico_add_extra_outputs(ceda2vga) # pull in common dependencies -target_link_libraries(ceda2vga pico_stdlib) +target_link_libraries(ceda2vga + pico_stdlib + hardware_pio + ) # add url via pico_set_program_url # example_auto_set_url(ceda2vga) diff --git a/src/main.c b/src/main.c index 6062022..e098766 100644 --- a/src/main.c +++ b/src/main.c @@ -7,22 +7,89 @@ * */ +#include "hardware/clocks.h" +#include "hardware/pio.h" +#include "hardware/pll.h" +#include "hardware/structs/pio.h" #include "pico/stdlib.h" +#include + +#include "vga.pio.h" + #include -int main() { - stdio_init_all(); - unsigned int count = 0; +#define FRAMES 2 +#define HPIXEL 640 +#define VPIXEL 480 +#define BPP 1 + +typedef struct Frame +{ + uint8_t data[HPIXEL * VPIXEL * BPP / 8]; +} Frame; + +static Frame frames[FRAMES] = {0}; + +static void vga_program_init(PIO pio, uint sm, uint offset) +{ + // magic definition of the called function? + pio_sm_config c = vga_free_run_program_get_default_config(offset); + sm_config_set_out_pins(&c, 22, 1); + + pio_gpio_init(pio, 22); + pio_sm_set_consecutive_pindirs(pio, sm, 22, 1, true); + + pio_sm_init(pio, sm, offset, &c); + + pio_sm_set_clkdiv_int_frac(pio, sm, 1, 0); + + pio->sm->shiftctrl = (1 << PIO_SM0_SHIFTCTRL_FJOIN_TX_LSB) | + (1 << PIO_SM0_SHIFTCTRL_OUT_SHIFTDIR_LSB) | + (1 << PIO_SM0_SHIFTCTRL_OUT_SHIFTDIR_LSB) | + (1 << PIO_SM0_SHIFTCTRL_AUTOPULL_LSB); + + pio_sm_set_enabled(pio, sm, true); +} + +int main() +{ + // main clock = VCO / divider1 / divider2 = 126MHz + pll_init(pll_sys, 1, 1500 * MHZ, 6, 2); + + stdio_init_all(); + +#if 0 const uint LED_PIN = PICO_DEFAULT_LED_PIN; gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); - while (true) { - gpio_put(LED_PIN, 1); - sleep_ms(5000); - gpio_put(LED_PIN, 0); - sleep_ms(5000); - printf("Hello world: %d\n", ++count); - } +#endif + + // "draw" an horizontal dotted line (?) + for (unsigned int c = 0; c < 20; c += 3) + { + frames[0].data[80 * 64 + 20 + c] = 0x55; + } + for (unsigned int c = 0; c < 20; c += 3) + { + frames[0].data[80 * 128 + 20 + c] = 0x99; + } + + PIO pio = pio0; + uint offset = pio_add_program(pio, &vga_free_run_program); + uint sm = pio_claim_unused_sm(pio, true); + vga_program_init(pio, sm, offset); + + printf("Welcome.\n"); + + while (true) + { + for (size_t i = 0; i < sizeof(frames[0].data); ++i) + { + pio_sm_put_blocking(pio, sm, frames[0].data[i]); + } + printf("."); + sleep_ms(1000); + } } diff --git a/src/vga.pio b/src/vga.pio new file mode 100644 index 0000000..e17f1df --- /dev/null +++ b/src/vga.pio @@ -0,0 +1,9 @@ +.program vga_free_run + + +entrypoint: + pull +loop: + out pins, 1 [2] + jmp loop +