Compare commits

...

5 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
Benjamin Kyd
1cda58217b Create LICENSE 2021-10-29 15:23:03 +01:00
53 changed files with 84676 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)

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Benjamin Kyd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

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);
}
%}