Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8082

SDK • Re: Doubling RGB to VGA

$
0
0
The way I do it is to have the PIO trigger an interrupt at the end of each line. The interrupt handler then sets the start address for the DMA. This happens to be code for VGA222 with 720x400 or 640x480 native resolutions and 320x240 or 360x200 line doubled. The full code is on https://github.com/UKTailwind/PicoMiteAllVersions in files VGA222.c/h and Custom.c. Sorry the PIO is just the machine code but the idea may help. The PIO is different from other VGA implementations in that all the VGA configuration is loaded just once at initialisation and then the only overhead is the line address irq which is trivial so almost no processor involvement. I'm running this on the second processor hence the tight loop but that isn't necessary.

Code:

// ------------ DMA IRQ handler ------------static void __not_in_flash_func(dma_line_complete_irq)(void){        // acknowledge interrupt        dma_hw->ints0 = 1u << g_dma_chan;        // advance line index        g_index++;        if (g_index >= g_N)                g_index = 0;        // next line address        uint32_t src_addr = g_Tadd[g_index];        // write directly to al3_read_addr_trig to restart DMA safely        dma_hw->ch[g_dma_chan].al3_read_addr_trig = src_addr;}uint32_t *g_vgalinemap = NULL;const uint16_t vga0[] = {    0x80A0,    0xA427,    0xA442,    0x0442,    0xC019,    0xC318,    //    0x80A0,    0xA047,    0xA022,    0x20C1,    0xC042,    0x20C2,    0xC000,    0x004B,    //    0x80A0,    0xA047,    0xA022,    0x29C0,    0x80A0,    0x6906,    0x6906,    0x6906,    0x6906,    0x6606,    0x6062,    0x0052,    0xA003,};const uint16_t vga1[] = {    0x90A0,    0xB0C7,    0x9018,    0x90A0,    0xB0C7,    0x9019,    0x90A0,    0xB047,    0xD007,    0x9098,    0xB027,    0x30C0,    0x20C0,    0x004C,    0x9099,    0xB027,    0x30C0,    0x1050,    0xD009,    0xB022,    0x30C0,    0x1054,    //    0x90A0,    0xB047,    0x90A0,    0xB027,    0x30C1,    0x005B,    0xB022,    0x105D,    0xD00A};const uint16_t vga2[] = {    0x80A0,    0xA0C7,    0x8018,    0x80A0,    0xA0C7,    0x8019,    0x80A0,    0xA047,    0xC007,    0x8098,    0xA027,    0x20C0,    0x30C0,    0x104C,    0x8099,    0xA027,    0x20C0,    0x0050,    0xC009,    0xA022,    0x20C0,    0x0054,    //    0x90A0,    0xB047,    0x90A0,    0xB027,    0x30C1,    0x005B,    0xB022,    0x105D,    0xD00A};void init_vga222(void){    int maplines = display_details[Option.DISPLAY_TYPE].vertical * display_details[Option.DISPLAY_TYPE].bits;    if (display_details[Option.DISPLAY_TYPE].bits == 1)        for (int i = 0; i < maplines; i++)        {            g_vgalinemap[i] = (uint32_t)FRAMEBUFFER + i * hvisible / pixelsperword * sizeof(uint32_t);        }    else if (display_details[Option.DISPLAY_TYPE].bits == 2)        for (int i = 0; i < maplines; i += 2)        {            g_vgalinemap[i] = (uint32_t)FRAMEBUFFER + (i / 2) * hvisible / pixelsperword * sizeof(uint32_t);            g_vgalinemap[i + 1] = g_vgalinemap[i];        }    pio1->irq = 255; // clear all irq in the statemachines on the pio    pio0->irq = 255; // clear all irq in the statemachines on the pio    gpio_set_function(PinDef[Option.VGA_HSYNC].GPno, GPIO_FUNC_PIO1);    gpio_set_function(PinDef[Option.VGA_HSYNC].GPno + 1, GPIO_FUNC_PIO1);    ExtCfg(Option.VGA_HSYNC, EXT_BOOT_RESERVED, 0);    ExtCfg(PINMAP[PinDef[Option.VGA_HSYNC].GPno + 1], EXT_BOOT_RESERVED, 0);    for (int i = 0; i < 6; i++)    {        gpio_set_function(PinDef[Option.VGA_BLUE].GPno + i, GPIO_FUNC_PIO0);        gpio_set_drive_strength(PinDef[Option.VGA_BLUE].GPno + i, GPIO_DRIVE_STRENGTH_8MA);        ExtCfg(PINMAP[PinDef[Option.VGA_BLUE].GPno + i], EXT_BOOT_RESERVED, 0);    }    struct pio_program program;    program.length = sizeof(vga0) / sizeof(uint16_t);    program.origin = 0;    program.instructions = vga0;    for (int sm = 0; sm < 4; sm++)        hw_clear_bits(&pio0->ctrl, 1 << (PIO_CTRL_SM_ENABLE_LSB + sm));    pio_clear_instruction_memory(pio0);    pio_add_program(pio0, &program);    program.length = sizeof(vga1) / sizeof(uint16_t);    program.origin = 0;    program.instructions = (VGA640 ? vga1 : vga2);    for (int sm = 0; sm < 4; sm++)        hw_clear_bits(&pio1->ctrl, 1 << (PIO_CTRL_SM_ENABLE_LSB + sm));    pio_clear_instruction_memory(pio1);    pio_add_program(pio1, &program);    PIO0 = false;    PIO1 = false;    int clock = clock_get_hz(clk_sys);    configurePIO(pio0, 0, clock / display_details[Option.DISPLAY_TYPE].bits, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 5, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0);    startPIO(pio0, 0);    configurePIO(pio0, 1, clock, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 8, 13, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0);    startPIO(pio0, 1);    configurePIO(pio0, 2, clock / display_details[Option.DISPLAY_TYPE].bits, 14, 0, 0, 0, 0, 0, 0, 0, PinDef[Option.VGA_BLUE].GPno, 6, 1, 0, -1, 16, 26, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0);    startPIO(pio0, 2);    configurePIO(pio1, 0, clock, 0, 0, PinDef[Option.VGA_HSYNC].GPno + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 8, 21, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1);    startPIO(pio1, 0);    configurePIO(pio1, 1, clock / display_details[Option.DISPLAY_TYPE].bits, 22, 0, PinDef[Option.VGA_HSYNC].GPno, 1, 1, 0, 0, 0, 0, 0, 0, 0, -1, 25, 30, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0);    startPIO(pio1, 1);    pio_sm_put_blocking(pio0, 1, vvisible - 1);    pio_sm_put_blocking(pio0, 2, hvisible / pixelsperword - 1);    pio_sm_put_blocking(pio1, 0, vsync - 1);    pio_sm_put_blocking(pio1, 0, vbackporch - 1);    pio_sm_put_blocking(pio1, 0, vvisible + vfrontporch - 2);    pio_sm_put_blocking(pio1, 1, hbackporchclock - 1);    pio_sm_put_blocking(pio1, 1, hsyncclock - 1);    syncPIO(0, 15, 0, 15);    setup_dma_pio_lines(pio0, 2, dma_tx_chan3,                        g_vgalinemap, maplines, hvisible / pixelsperword);    pio_sm_put_blocking(pio0, 0, hwholeline - 1);    while (1)    {        tight_loop_contents();    }}

Statistics: Posted by matherp — Wed Nov 26, 2025 7:09 pm



Viewing all articles
Browse latest Browse all 8082

Trending Articles