Compare commits
2 Commits
0cf72757e9
...
4f26826d4b
Author | SHA1 | Date |
---|---|---|
giomba | 4f26826d4b | |
giomba | 9fcb7b3e99 |
75
src/main.c
75
src/main.c
|
@ -114,11 +114,26 @@ void setup_clocks(void)
|
|||
static bool dma_ready = false;
|
||||
static int dma_channel;
|
||||
|
||||
/**
|
||||
* @brief Represents a program running on the SM of a PIO.
|
||||
*
|
||||
*/
|
||||
typedef struct PIORun
|
||||
{
|
||||
PIO pio; //< executing PIO
|
||||
uint offset; //< PIO memory offset for program
|
||||
uint sm; //< executing SM
|
||||
} PIORun;
|
||||
|
||||
PIORun *vga_pixel_ptr = NULL;
|
||||
|
||||
void new_frame_handler(void)
|
||||
{
|
||||
// restart DMA
|
||||
if (dma_ready)
|
||||
dma_channel_set_read_addr(dma_channel, &frames[0].data[0], true);
|
||||
if (vga_pixel_ptr && dma_ready)
|
||||
{
|
||||
pio_sm_put_blocking(vga_pixel_ptr->pio, vga_pixel_ptr->sm, 0);
|
||||
dma_channel_set_read_addr(dma_channel, &frames[0].data[4], true);
|
||||
}
|
||||
|
||||
pio_interrupt_clear(pio0_hw, 1);
|
||||
}
|
||||
|
@ -134,16 +149,21 @@ void set_pixel(uint16_t x, uint16_t y)
|
|||
frames[0].data[y * 80 + x / 8] |= (1 << x % 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Represents a program running on the SM of a PIO.
|
||||
*
|
||||
*/
|
||||
typedef struct PIORun
|
||||
void clear_pixel(uint16_t x, uint16_t y)
|
||||
{
|
||||
PIO pio; //< executing PIO
|
||||
uint offset; //< PIO memory offset for program
|
||||
uint sm; //< executing SM
|
||||
} PIORun;
|
||||
frames[0].data[y * 80 + x / 8] &= ~(1 << x % 8);
|
||||
}
|
||||
|
||||
void draw_simple_line(uint16_t x, uint16_t y, uint16_t len, bool horizontal)
|
||||
{
|
||||
for (uint16_t i = 0; i < len; ++i)
|
||||
{
|
||||
if (horizontal)
|
||||
set_pixel(x + i, y);
|
||||
else
|
||||
set_pixel(x, y + i);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -157,17 +177,33 @@ int main()
|
|||
// horizontal lines
|
||||
for (uint16_t x = 0; x < 639; ++x) // last pixel high -> bad
|
||||
{
|
||||
set_pixel(x, 0);
|
||||
if ((x / 32) % 2 == 0)
|
||||
set_pixel(x, 20);
|
||||
if ((x / 32) % 2 == 1)
|
||||
set_pixel(x, 23);
|
||||
set_pixel(x, 239);
|
||||
set_pixel(x, 479);
|
||||
}
|
||||
// vertical lines
|
||||
for (uint16_t y = 0; y < 480; ++y)
|
||||
for (uint16_t y = 21; y < 480; ++y)
|
||||
{
|
||||
set_pixel(0 + ((y - 20) / 10) * 4, y);
|
||||
set_pixel(0, y);
|
||||
set_pixel(239, y);
|
||||
set_pixel(319, y);
|
||||
set_pixel(638, y);
|
||||
}
|
||||
// try to find strangeness using stairs
|
||||
for (uint16_t x = 0; x < 639; ++x)
|
||||
{
|
||||
set_pixel(x, (x / 32) * 4 + 120);
|
||||
}
|
||||
// draw "E" - nice because it's not symmetrical along X
|
||||
draw_simple_line(100, 100, 8, true);
|
||||
draw_simple_line(100, 100, 8, false);
|
||||
draw_simple_line(100, 104, 8, true);
|
||||
draw_simple_line(100, 108, 8, true);
|
||||
|
||||
clear_pixel(639, 479);
|
||||
|
||||
// Running programs on PIO
|
||||
PIORun vga_hsync, vga_vsync, vga_pixel;
|
||||
|
@ -188,8 +224,8 @@ int main()
|
|||
vga_hsync.sm = pio_claim_unused_sm(vga_hsync.pio, true);
|
||||
vga_hsync_program_init(vga_hsync.pio, vga_hsync.sm, vga_hsync.offset);
|
||||
// low pulse is X pixels long, and SM runs at 4x of pixel clock
|
||||
pio_sm_put_blocking(vga_hsync.pio, vga_hsync.sm, (64 - 1));
|
||||
pio_sm_put_blocking(vga_hsync.pio, vga_hsync.sm, (640 - 1));
|
||||
pio_sm_put_blocking(vga_hsync.pio, vga_hsync.sm, (64 - 2));
|
||||
pio_sm_put_blocking(vga_hsync.pio, vga_hsync.sm, (640 + 16 - 1)); // 16 is front porch
|
||||
printf("OK\n");
|
||||
|
||||
// VGA VSYNC program
|
||||
|
@ -205,6 +241,7 @@ int main()
|
|||
printf("OK\n");
|
||||
|
||||
// VGA pixel program
|
||||
vga_pixel_ptr = &vga_pixel;
|
||||
printf("Starting VGA pixel machine... ");
|
||||
if (!pio_can_add_program(vga_pixel.pio, &vga_free_run_program))
|
||||
panic("cannot add program");
|
||||
|
@ -227,8 +264,8 @@ int main()
|
|||
irq_set_exclusive_handler(DMA_IRQ_0, dma_handler);
|
||||
irq_set_enabled(DMA_IRQ_0, true);
|
||||
|
||||
dma_channel_configure(dma_channel, &dma_config, &pio0_hw->txf[2], &frames[0].data[0], 9600,
|
||||
false);
|
||||
dma_channel_configure(dma_channel, &dma_config, &pio0_hw->txf[2], &frames[0].data[0], 9600 - 1,
|
||||
true);
|
||||
|
||||
dma_ready = true;
|
||||
printf("OK\n");
|
||||
|
|
10
src/vga.pio
10
src/vga.pio
|
@ -8,7 +8,7 @@ entrypoint_vga_free_run:
|
|||
mov x, y
|
||||
wait irq 7
|
||||
loop:
|
||||
out pins, 1 [3]
|
||||
out pins, 1 [2]
|
||||
jmp x-- loop
|
||||
.wrap
|
||||
|
||||
|
@ -27,10 +27,9 @@ hsync_pulse:
|
|||
jmp x-- hsync_pulse [3]
|
||||
|
||||
set pins, 1 [1]
|
||||
set y, 24
|
||||
set y, 27
|
||||
hsync_back_porch:
|
||||
jmp y-- hsync_back_porch [19]
|
||||
|
||||
jmp y-- hsync_back_porch [16]
|
||||
irq set 7
|
||||
|
||||
mov x, osr [3]
|
||||
|
@ -53,11 +52,12 @@ vsync_pulse:
|
|||
set pins, 0
|
||||
jmp x-- vsync_pulse
|
||||
|
||||
irq set 1
|
||||
|
||||
mov x, osr
|
||||
vsync_idle:
|
||||
wait irq 0
|
||||
set pins, 1
|
||||
jmp x-- vsync_idle
|
||||
|
||||
irq set 1
|
||||
.wrap
|
||||
|
|
Loading…
Reference in New Issue