Compare commits

4 Commits

Author SHA1 Message Date
Ben Kyd
ff2e22ccfc files 2023-06-15 12:00:00 +01:00
Ben Kyd
38010a5fa6 lol 2023-06-15 20:07:12 +01:00
Ben Kyd
8423640e35 Seeing if i can get this to work 2023-06-09 23:57:12 +01:00
Benjamin Kyd
6253ee1e27 Merge pull request #1 from benkyd/add-license-1
Create LICENSE
2021-10-29 15:23:24 +01:00
52 changed files with 84655 additions and 84443 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,42 +1,35 @@
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# initalize pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH "/home/ben/pico/pico-sdk")
# Pull in Raspberry Pi Pico SDK (must be before project)
set(PICO_SDK_FETCH_FROM_GIT on)
include(pico_sdk_import.cmake)
project(pico_vga C CXX ASM)
add_executable(pico_vga)
include_directories(${CMAKE_SOURCE_DIR}/src)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -O2")
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
add_executable(pico_vga
src/main.c
src/vga.c
)
pico_set_program_name(pico_vga "pico_vga")
pico_set_program_version(pico_vga "0.1")
target_link_libraries(pico_vga
pico_stdlib
hardware_pio
hardware_dma
hardware_irq
hardware_clocks
)
pico_generate_pio_header(pico_vga ${CMAKE_CURRENT_LIST_DIR}/src/vga.pio)
pico_enable_stdio_usb(pico_vga 1)
pico_enable_stdio_uart(pico_vga 0)
pico_generate_pio_header(pico_vga ${CMAKE_CURRENT_LIST_DIR}/video.pio)
target_sources(pico_vga PRIVATE
main.c
vga.c
)
# Add the standard library to the build
target_link_libraries(pico_vga
pico_stdlib
hardware_pio
hardware_dma
hardware_irq
)
pico_add_extra_outputs(pico_vga)

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -2,10 +2,13 @@
"board": {
"active_layer": 0,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 0.8500000238418579,
"tracks": 1.0,
"vias": 1.0,
@@ -48,15 +51,13 @@
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
37,
38
],
@@ -65,7 +66,7 @@
},
"meta": {
"filename": "picovga.kicad_prl",
"version": 2
"version": 3
},
"project": {
"files": []

View File

@@ -1,5 +1,6 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"board_outline_line_width": 0.09999999999999999,
@@ -51,25 +52,34 @@
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 1
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"drill_too_small": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_near_hole": "error",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"microvia_drill_too_small": "error",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
@@ -78,9 +88,15 @@
"padstack": "error",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "error",
"silk_overlap": "error",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_dangling": "warning",
"track_width": "error",
@@ -96,27 +112,77 @@
"allow_microvias": false,
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.0,
"min_hole_clearance": 0.0,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.19999999999999998,
"min_microvia_drill": 0.09999999999999999,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.7999999999999999,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.19999999999999998,
"min_via_annular_width": 0.049999999999999996,
"min_via_diameter": 0.39999999999999997,
"solder_mask_clearance": 0.0,
"solder_mask_min_width": 0.0,
"solder_mask_to_copper_clearance": 0.0,
"solder_paste_clearance": 0.0,
"solder_paste_margin_ratio": 0.0
"solder_paste_margin_ratio": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpadsmd": true,
"td_onroundshapesonly": false,
"td_ontrackend": false,
"td_onviapad": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"via_dimensions": [],
"zones_allow_external_fillets": false,
"zones_use_no_outline": true
},
"layer_presets": []
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
@@ -134,6 +200,7 @@
0,
0,
0,
0,
1,
0,
0,
@@ -147,6 +214,7 @@
0,
1,
0,
0,
1,
0,
2,
@@ -160,6 +228,7 @@
0,
0,
0,
0,
1,
0,
1,
@@ -173,6 +242,7 @@
0,
0,
0,
0,
1,
1,
2,
@@ -186,6 +256,7 @@
0,
0,
0,
0,
1,
0,
0,
@@ -193,12 +264,27 @@
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
@@ -212,6 +298,7 @@
0,
1,
0,
0,
1,
0,
0,
@@ -225,6 +312,7 @@
1,
2,
0,
0,
1,
0,
2,
@@ -238,6 +326,7 @@
0,
1,
0,
0,
1,
0,
2,
@@ -251,6 +340,7 @@
1,
1,
0,
0,
1,
0,
2,
@@ -269,21 +359,31 @@
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_label_syntax": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
@@ -293,6 +393,9 @@
"pin_to_pin": "warning",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
@@ -308,7 +411,7 @@
"net_settings": {
"classes": [
{
"bus_width": 6.0,
"bus_width": 6,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
@@ -322,13 +425,15 @@
"track_width": 0.25,
"via_diameter": 0.8,
"via_drill": 0.4,
"wire_width": 6.0
"wire_width": 6
}
],
"meta": {
"version": 0
"version": 3
},
"net_colors": null
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
@@ -342,31 +447,96 @@
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "Quantity",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"name": "Grouped By Value",
"sort_asc": true,
"sort_field": "Reference"
},
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_bus_thickness": 12.0,
"default_junction_size": 36.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"default_wire_thickness": 6.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.3,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.3
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 0
"version": 1
},
"net_format_name": "",
"page_layout_descr_file": "",
"plot_directory": "",
"spice_adjust_passive_values": false,
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},

40
main.c
View File

@@ -1,40 +0,0 @@
// Copyright Benjamin Kyd 2021 All Rights Reserved
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "pico/stdlib.h"
#include "vga.h"
// PIN LAYOUT
// PIN 0-3 RED DAC
// PIN 4-7 GREEN DAC
// PIN 8-11 BLUE DAC
// PIN 12 HSYNC
// PIN 13 VSYNC
int main()
{
stdio_init_all();
sleep_ms(1400);
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
gpio_put(PICO_DEFAULT_LED_PIN, 1);
printf("VGA Initalizing...\n");
const video_timing_t video_timing = vga_timing_800x600_60;
vga_init(&video_timing);
while(true)
{
tight_loop_contents();
}
}

18
makefile Normal file
View File

@@ -0,0 +1,18 @@
.ONESHELL:
all: compile mount flash
compile:
cd build && cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=on && make
mount: compile
sudo mount -L RPI-RP2 /mnt
flash: mount
sudo cp build/pico_vga.uf2 /mnt
echo "Copied pico_vga.uf2 to pico"
clean:
rm -rf build
mkdir build

View File

@@ -29,11 +29,22 @@ if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)

32
src/main.c Normal file
View File

@@ -0,0 +1,32 @@
// Copyright Benjamin Kyd 2023 All Rights Reserved
//
// GPIO 0-3: RED DAC, 4-7: GREEN DAC, 8-11: BLUE DAC
// GPIO 12: HSYNC, GPIO 13: VSYNC
#include "pico/stdlib.h"
#include "vga.h"
static void draw_test_pattern(void) {
for (int y = 0; y < VGA_FB_HEIGHT; y++) {
for (int x = 0; x < VGA_FB_WIDTH; x++) {
uint8_t r = (uint8_t)((x * 15) / VGA_FB_WIDTH);
uint8_t g = (uint8_t)((y * 15) / VGA_FB_HEIGHT);
uint8_t b = 8;
if (x % 10 == 0 || y % 10 == 0) {
r = g = b = 15;
}
vga_framebuffer[y][x] = vga_rgb(r, g, b);
}
}
}
int main(void) {
vga_init();
draw_test_pattern();
while (true) {
tight_loop_contents();
}
}

118
src/vga.c Normal file
View File

@@ -0,0 +1,118 @@
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "vga.h"
#include "vga.pio.h"
#define H_ACTIVE 800
#define H_FRONT_PORCH 40
#define H_SYNC_PULSE 128
#define H_BACK_PORCH 88
#define H_TOTAL 1056
#define V_ACTIVE 600
#define V_FRONT_PORCH 1
#define V_SYNC_PULSE 4
#define V_BACK_PORCH 23
#define V_TOTAL 628
#define HSYNC_BIT (1u << 12)
#define VSYNC_BIT (1u << 13)
#define VGA_PIO pio0
#define VGA_SM 0
#define VGA_DMA_CHAN 0
static uint32_t scanline_buf[2][H_TOTAL];
static volatile int active_buf = 0;
static volatile uint32_t current_line = 0;
vga_pixel_t vga_framebuffer[VGA_FB_HEIGHT][VGA_FB_WIDTH];
static void build_scanline(uint32_t *buf, uint32_t line) {
const bool vsync = (line >= (uint32_t)(V_ACTIVE + V_FRONT_PORCH)) &&
(line < (uint32_t)(V_ACTIVE + V_FRONT_PORCH + V_SYNC_PULSE));
const uint32_t vsync_bit = vsync ? VSYNC_BIT : 0u;
uint32_t *ptr = buf;
if (line < V_ACTIVE) {
const uint32_t fy = line >> 2;
const vga_pixel_t *row = vga_framebuffer[fy < VGA_FB_HEIGHT ? fy : VGA_FB_HEIGHT - 1u];
for (int x = 0; x < H_ACTIVE; x++) {
*ptr++ = (uint32_t)row[x >> 2] | vsync_bit;
}
} else {
for (int x = 0; x < H_ACTIVE; x++) {
*ptr++ = vsync_bit;
}
}
for (int x = 0; x < H_FRONT_PORCH; x++) *ptr++ = vsync_bit;
const uint32_t hsync_word = HSYNC_BIT | vsync_bit;
for (int x = 0; x < H_SYNC_PULSE; x++) *ptr++ = hsync_word;
for (int x = 0; x < H_BACK_PORCH; x++) *ptr++ = vsync_bit;
}
static void dma_irq_handler(void) {
dma_hw->ints0 = 1u << VGA_DMA_CHAN;
current_line++;
if (current_line >= V_TOTAL) current_line = 0;
active_buf ^= 1;
dma_channel_set_read_addr(VGA_DMA_CHAN, scanline_buf[active_buf], false);
dma_channel_set_trans_count(VGA_DMA_CHAN, H_TOTAL, true);
const uint32_t next_line = (current_line + 1u) % V_TOTAL;
build_scanline(scanline_buf[active_buf ^ 1], next_line);
}
void vga_init(void) {
set_sys_clock_khz(120000, true);
const uint offset = pio_add_program(VGA_PIO, &vga_out_program);
pio_sm_config c = vga_out_program_get_default_config(offset);
sm_config_set_out_pins(&c, 0, 14);
sm_config_set_out_shift(&c, true, true, 14);
sm_config_set_clkdiv(&c, 3.0f);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
for (int i = 0; i < 14; i++) pio_gpio_init(VGA_PIO, i);
pio_sm_set_consecutive_pindirs(VGA_PIO, VGA_SM, 0, 14, true);
pio_sm_init(VGA_PIO, VGA_SM, offset, &c);
dma_channel_config dc = dma_channel_get_default_config(VGA_DMA_CHAN);
channel_config_set_transfer_data_size(&dc, DMA_SIZE_32);
channel_config_set_read_increment(&dc, true);
channel_config_set_write_increment(&dc, false);
channel_config_set_dreq(&dc, pio_get_dreq(VGA_PIO, VGA_SM, true));
dma_channel_configure(
VGA_DMA_CHAN, &dc,
&VGA_PIO->txf[VGA_SM],
scanline_buf[0],
H_TOTAL,
false
);
dma_channel_set_irq0_enabled(VGA_DMA_CHAN, true);
irq_set_exclusive_handler(DMA_IRQ_0, dma_irq_handler);
irq_set_enabled(DMA_IRQ_0, true);
build_scanline(scanline_buf[0], 0);
build_scanline(scanline_buf[1], 1);
active_buf = 0;
current_line = 0;
pio_sm_set_enabled(VGA_PIO, VGA_SM, true);
dma_channel_set_read_addr(VGA_DMA_CHAN, scanline_buf[0], false);
dma_channel_set_trans_count(VGA_DMA_CHAN, H_TOTAL, true);
}

23
src/vga.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef PICOVGA_VGA_H_
#define PICOVGA_VGA_H_
#include <stdint.h>
#define VGA_FB_WIDTH 200
#define VGA_FB_HEIGHT 150
typedef uint16_t vga_pixel_t;
static inline vga_pixel_t vga_rgb(uint8_t r, uint8_t g, uint8_t b) {
return (uint16_t)((r & 0xF) | ((g & 0xF) << 4) | ((b & 0xF) << 8));
}
static inline vga_pixel_t vga_rgb8(uint8_t r, uint8_t g, uint8_t b) {
return vga_rgb(r >> 4, g >> 4, b >> 4);
}
extern vga_pixel_t vga_framebuffer[VGA_FB_HEIGHT][VGA_FB_WIDTH];
void vga_init(void);
#endif

19
src/vga.pio Normal file
View File

@@ -0,0 +1,19 @@
;
; VGA pixel output PIO program
;
; Outputs 14 bits per pixel clock cycle to GPIO 0-13:
; bits [3:0] = RED (GPIO 0-3)
; bits [7:4] = GREEN (GPIO 4-7)
; bits [11:8] = BLUE (GPIO 8-11)
; bit [12] = HSYNC (GPIO 12) - positive polarity for 800x600@60Hz
; bit [13] = VSYNC (GPIO 13) - positive polarity for 800x600@60Hz
;
; Each 32-bit FIFO word = one pixel (14 bits used, 18 bits discarded via autopull).
; PIO clock divider must be set so instruction rate = pixel clock (40 MHz).
;
.program vga_out
.wrap_target
out pins, 14 ; output 14 bits to GPIO 0-13
.wrap

60
vga.c
View File

@@ -1,60 +0,0 @@
// Copyright Benjamin Kyd 2021 All Rights Reserved
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "vga.h"
#include "video.pio.h"
const video_timing_t vga_timing_800x600_60 =
{
.clock_freq = 38400000,
.h_active = 800,
.v_active = 600,
.h_front_porch = 4 * 8,
.h_pulse = 10 * 8,
.h_total = 128 * 8,
.h_sync_polarity = 0,
.v_front_porch = 1,
.v_pulse = 3,
.v_total = 625,
.v_sync_polarity = 0,
.enable_clock = 0,
.clock_polarity = 0,
.enable_den = 0
};
#define PIN_START 8
#define PIN_COUNT 2
void vga_init(const video_timing_t* timing)
{
// Calculate the PIO clock divider
uint sys_clock = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
float clock_div = ((float)sys_clock * 1000.f) / (float)timing->clock_freq;
printf("System clock frequency %i\n", sys_clock);
printf("Pixel clock frequency %i\n", timing->clock_freq);
printf("Clock divider %f\n", clock_div);
// setup 2 buffers with DMA
// setup swap
// use pin mask (5 pins for 1 bit colour, 12 for 4)
}

40
vga.h
View File

@@ -1,40 +0,0 @@
#ifndef PICOVGA_VGA_H_
#define PICOVGA_VGA_H_
#include "pico/types.h"
typedef struct video_timing {
uint32_t clock_freq;
uint16_t h_active;
uint16_t v_active;
uint16_t h_front_porch;
uint16_t h_pulse;
uint16_t h_total;
uint8_t h_sync_polarity;
uint16_t v_front_porch;
uint16_t v_pulse;
uint16_t v_total;
uint8_t v_sync_polarity;
uint8_t enable_clock;
uint8_t clock_polarity;
uint8_t enable_den;
} video_timing_t;
const video_timing_t vga_timing_800x600_60;
// typedef struct video {
// uint16_t*
// } video_t;
void vga_init(const video_timing_t* timing);
void vga_start();
void vga_swap_buffers();
#endif

View File

@@ -1,5 +0,0 @@
WHITE - VSYNC -
BLACK - HSYNC -
RED - VGA_R -
GREEN - VGA_G -
BLUE - VGA_B -

View File

@@ -1,28 +0,0 @@
; Copyright Benjamin Kyd 2021 All Rights Reserved
.program video
; write 5 bits from the TX FIFO to the pin mask
.wrap_target
out pins 2
.wrap
% c-sdk {
static inline void video_program_init(PIO pio, uint sm, uint offset, uint pin, float clk_div) {
pio_sm_config c = video_program_get_default_config(offset);
// Map the state machine's OUT pin group to one pin, namely the `pin`
// parameter to this function.
sm_config_set_out_pins(&c, pin, 1);
// Set this pin's GPIO function (connect PIO to the pad)
pio_gpio_init(pio, pin);
// Set the pin direction to output at the PIO
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
// Load our configuration, and jump to the start of the program
pio_sm_init(pio, sm, offset, &c);
// Set the state machine running
pio_sm_set_enabled(pio, sm, true);
}
%}