;
; Hunter Adams (vha3@cornell.edu)
; HSync generation for VGA driver
; Program name
.program hsync
; frontporch: 16 clocks (0.64us at 25MHz)
; sync pulse: 96 clocks (3.84us at 25MHz)
; back porch: 48 clocks (1.92us at 25MHz)
; active for: 640 clcks (25.6us at 25MHz)
;
; High for 704 cycles (28.16us at 25MHz)
; Low for 96 cycles (3.84us at 25MHz)
; Total period of 800 cycles (32us at 25MHz)
;
pull block ; Pull from FIFO to OSR (only happens once)
.wrap_target ; Program wraps to here
; ACTIVE + FRONTPORCH
mov x, osr ; Copy value from OSR to x scratch register
activeporch:
jmp x-- activeporch ; Remain high in active mode and front porch
; SYNC PULSE
pulse:
set pins, 0 [31] ; Low for hsync pulse (32 cycles)
set pins, 0 [31] ; Low for hsync pulse (64 cycles)
set pins, 0 [31] ; Low for hsync pulse (96 cycles)
; BACKPORCH
backporch:
set pins, 1 [31] ; High for back porch (32 cycles)
set pins, 1 [12] ; High for back porch (45 cycles)
irq 0 [1] ; Set IRQ to signal end of line (47 cycles)
.wrap
% c-sdk {
static inline void hsync_program_init(PIO pio, uint sm, uint offset, uint pin) {
// creates state machine configuration object c, sets
// to default configurations. I believe this function is auto-generated
// and gets a name of _program_get_default_config
// Yes, page 40 of SDK guide
pio_sm_config c = hsync_program_get_default_config(offset);
// Map the state machine's SET pin group to one pin, namely the `pin`
// parameter to this function.
sm_config_set_set_pins(&c, pin, 1);
// Set clock division (div by 5 for 25 MHz state machine)
sm_config_set_clkdiv(&c, 5) ;
// Set this pin's GPIO function (connect PIO to the pad)
pio_gpio_init(pio, pin);
// pio_gpio_init(pio, pin+1);
// 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 (commented out so can be synchronized w/ vsync)
// pio_sm_set_enabled(pio, sm, true);
}
%}