# HG changeset patch # User Paul Boddie # Date 1540325660 -7200 # Node ID 424c116cadb1a7ee128dd8910c32384feb44da6b # Parent 2e21b707dbdae33698d42917bd910798f27d98f3 Introduced framebuffer usage and replaced the DMA interrupt with a Timer2 event, making the vga-pmp example consistent with the others. diff -r 2e21b707dbda -r 424c116cadb1 examples/vga-pmp/main.c --- a/examples/vga-pmp/main.c Tue Oct 23 22:11:05 2018 +0200 +++ b/examples/vga-pmp/main.c Tue Oct 23 22:14:20 2018 +0200 @@ -27,6 +27,7 @@ #include "main.h" #include "devconfig.h" #include "vga.h" +#include "display.h" @@ -35,20 +36,16 @@ static void (*state_handler)(void); static uint32_t line; +/* Pointers to pixel lines. */ + +static uint8_t *linedata, *linedatalimit, *screenstart; + /* Pixel data. */ -static uint8_t linedata[LINE_LENGTH]; static const uint8_t zerodata[ZERO_LENGTH] = {0}; - +static uint8_t framebuffer[SCREEN_SIZE]; -static void test_linedata(void) -{ - int i; - - for (i = 0; i < LINE_LENGTH; i++) - linedata[i] = (i % 2) ? 0xff : 0x00; -} /* Blink an attached LED with delays implemented using a loop. */ @@ -69,8 +66,6 @@ /* Invert outputs (LED). */ INV_REG(port, pins); - rbits(PM_REG(0, PMxCON)); uart_write_nl(); - rhex(PM_REG(0, PMxMODE)); uart_write_nl(); } } @@ -82,7 +77,12 @@ { line = 0; state_handler = vbp_active; - test_linedata(); + test_linedata(framebuffer); + + /* Initialise the current display line pointer and display limit. */ + + linedatalimit = framebuffer + SCREEN_SIZE; + screenstart = framebuffer; init_memory(); init_pins(); @@ -112,16 +112,15 @@ dma_set_transfer(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH, HW_PHYSICAL(PM_REG(0, PMxDIN)), 1, TRANSFER_CELL_SIZE); - dma_init_interrupt(0, 0b1000, 1, 3); - /* Enable DMA on the preceding channel's completion, with this also - initiating transfers. This "reset" or "zero" transfer is employed to set - the pixel level to black in a connected flip-flop. Without the flip-flop - it is superfluous. */ + /* Enable DMA on the preceding channel's completion, with the timer event + initiating the transfer. This "reset" or "zero" transfer is employed to + set the pixel level to black in a connected flip-flop. Without the + flip-flop it is superfluous. */ dma_init(1, 3); dma_set_chaining(1, dma_chain_previous); - dma_set_interrupt(1, DMA0, 1); + dma_set_interrupt(1, T2, 1); dma_set_transfer(1, PHYSICAL((uint32_t) zerodata), ZERO_LENGTH, HW_PHYSICAL(PM_REG(0, PMxDIN)), 1, ZERO_LENGTH); @@ -200,7 +199,10 @@ state_handler = visible_active; - /* NOTE: Set the line address. */ + /* Set the line address. */ + + linedata = screenstart; + dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH); /* Enable the channel for the next line. */ @@ -211,22 +213,18 @@ void visible_active(void) { - uint32_t ifs; - - /* Remove any DMA interrupt condition (CHBCIF). */ - - ifs = REG(DMAIFS) & DMA_INT_FLAGS(0, DCHxIF); - - if (ifs) - { - CLR_REG(DMA_REG(0, DCHxINT), 0b11111111); - CLR_REG(DMAIFS, ifs); - } - if (line < VFP_START) { - /* NOTE: Update the line address and handle wraparound. */ + /* Update the line address and handle wraparound. */ + if (!(line % LINE_MULTIPLIER)) + { + linedata += LINE_LENGTH; + if (linedata >= linedatalimit) + linedata -= SCREEN_SIZE; + } + + dma_set_source(0, PHYSICAL((uint32_t) linedata), LINE_LENGTH); return; }