Skip to content

Commit 1730c31

Browse files
committed
added DMA double buffering for consideration
1 parent 41684ab commit 1730c31

3 files changed

Lines changed: 52 additions & 11 deletions

File tree

libs/graphics/lcd_fsmc.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,9 @@ void LCD_init_hardware() {
560560

561561
#ifdef LCD_TEARING
562562
jshPinSetState(LCD_TEARING, JSHPINSTATE_GPIO_IN_PULLDOWN);
563-
#endif
563+
#endif
564+
565+
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
564566
}
565567

566568
#endif // NOT ILI9325_BITBANG
@@ -1917,12 +1919,41 @@ void lcdFSMC_blitStart(JsGraphics *gfx, int x, int y, int w, int h) {
19171919
// Wait for the ILI9488 Tearing Effect signal to indicate start of V-blank.
19181920
// TE pin is push-pull: HIGH during V-blank (500-2000us safe write window),
19191921
// LOW during scan (10-40ms panel refresh from GRAM).
1920-
// 10ms delay to avoid tight hot loops eating power
1921-
while (!jshPinGetValue(LCD_TEARING)) jshDelayMicroseconds(10);
1922+
while (!jshPinGetValue(LCD_TEARING));
19221923
#endif
19231924
lcdSetWindow(gfx, x, y, x+w-1, y+h-1);
19241925
lcdSetWrite();
19251926
}
1927+
1928+
void lcdFSMC_dmaStart(uint16_t *buf, int count) {
1929+
// disable stream and wait for disable before send
1930+
DMA2_Stream0->CR &= ~DMA_SxCR_EN;
1931+
while (DMA2_Stream0->CR & DMA_SxCR_EN);
1932+
1933+
// clear interrup and error flags
1934+
DMA2->LIFCR = DMA_LIFCR_CTCIF0 |
1935+
DMA_LIFCR_CHTIF0 |
1936+
DMA_LIFCR_CTEIF0 |
1937+
DMA_LIFCR_CDMEIF0 |
1938+
DMA_LIFCR_CFEIF0;
1939+
1940+
DMA2_Stream0->PAR = (uint32_t)buf;
1941+
DMA2_Stream0->M0AR = (uint32_t)&LCD_RAM;
1942+
DMA2_Stream0->NDTR = (uint16_t)count;
1943+
DMA2_Stream0->FCR = 0; // direct mode
1944+
1945+
DMA2_Stream0->CR = DMA_SxCR_DIR_1 | // mem-to-mem mode
1946+
DMA_SxCR_PINC | // increment pointer (buf++)
1947+
DMA_SxCR_PSIZE_0 | // src size: 16-bit (half-word)
1948+
DMA_SxCR_MSIZE_0 | // dest size: 16-bit (half-word)
1949+
DMA_SxCR_EN; // enable stream
1950+
}
1951+
1952+
void lcdFSMC_dmaWait(void) {
1953+
while (DMA2_Stream0->NDTR);
1954+
DMA2_Stream0->CR &= ~1U;
1955+
}
1956+
19261957
void lcdFSMC_setCursor(JsGraphics *gfx, int x, int y) {
19271958
lcdSetCursor(gfx,x,y);
19281959
//lcdSetWindow(gfx,x,y,gfx->data.width-1,y);

libs/graphics/lcd_fsmc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ void lcdFSMC_blitStart(JsGraphics *gfx, int x, int y, int w, int h);
2222
void lcdFSMC_setCursor(JsGraphics *gfx, int x, int y);
2323
void lcdFSMC_blitPixel(unsigned int col);
2424
void lcdFSMC_blitEnd();
25+
void lcdFSMC_dmaStart(uint16_t *buf, int count);
26+
void lcdFSMC_dmaWait(void);
2527

2628
void lcdFSMC_setPower(bool isOn);
2729

libs/pipboy/jswrap_pipboy.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ bool audioRepeats; // should this stream repeat?
8383

8484
JsSysTime videoFrameTime;
8585
JsSysTime videoNextFrameTime;
86+
static uint16_t blitRowA[480];
87+
static uint16_t blitRowB[480];
8688
bool debugInfo = false;
8789
int startX=0;
8890
int startY=0;
@@ -2025,6 +2027,8 @@ void jswrap_pb_blitScreen(JsVar *image, JsVar *options) {
20252027
yoffset += 320; // to avoid negative values
20262028
lcdFSMC_blitStart(gfx, 0,y1, 480,y2+1-y1);
20272029
for (int y=y1;y<=y2;y++) {
2030+
uint16_t *rowBuf = (y & 1) ? blitRowB : blitRowA; // double buffer selection
2031+
20282032
// work out row pointers
20292033
row1 = &imgPtr[((y+yoffset-ydiff)%320)*120]; // 480 pixels, 2bpp = 120 bytes per row
20302034
row2 = &imgPtr[((y+yoffset)%320)*120]; // 480 pixels, 2bpp = 120 bytes per row
@@ -2033,19 +2037,20 @@ void jswrap_pb_blitScreen(JsVar *image, JsVar *options) {
20332037

20342038
uint32_t pixels = 0;
20352039
uint8_t pixelUp, pixelDn;
2040+
int p = 0; // index into DMA row buffer
2041+
#define BLITPIXEL \
2042+
filterResult32 = (pixels&mulx1) + ((pixels&mulx2)<<1); /* Apply 8x 2bit filter */ \
2043+
filterResult32 = (filterResult32&0x0F0F0F0F) + ((filterResult32>>4)&0x0F0F0F0F) ; /* Merge each nibble, now we have 8 bits to play with */ \
2044+
filterResult32 = filterResult32 + (filterResult32>>8); \
2045+
filterResult32 = (filterResult32 + (filterResult32>>16)) & 255; \
2046+
filterResult32 = ((((pixelUp+pixelDn)<<1) + filterResult32)*3)>>3; /* blur upper and lower lines */ \
2047+
if (filterResult32>15) filterResult32=15; \
2048+
rowBuf[p++] = palette[filterResult32];
20362049
for (int x=0;x<120;x++) {
20372050
uint8_t p4up = *(row1++);
20382051
uint8_t p4 = *(row2++);
20392052
uint8_t p4dn = *(row3++);
20402053
uint32_t filterResult32;
2041-
#define BLITPIXEL \
2042-
filterResult32 = (pixels&mulx1) + ((pixels&mulx2)<<1); /* Apply 8x 2bit filter */ \
2043-
filterResult32 = (filterResult32&0x0F0F0F0F) + ((filterResult32>>4)&0x0F0F0F0F) ; /* Merge each nibble, now we have 8 bits to play with */ \
2044-
filterResult32 = filterResult32 + (filterResult32>>8); \
2045-
filterResult32 = (filterResult32 + (filterResult32>>16)) & 255; \
2046-
filterResult32 = ((((pixelUp+pixelDn)<<1) + filterResult32)*3)>>3; /* blur upper and lower lines */ \
2047-
if (filterResult32>15) filterResult32=15; \
2048-
lcdFSMC_blitPixel(palette[filterResult32]);
20492054
pixelUp = (p4up>>5);
20502055
pixelDn = (p4dn>>5);
20512056
pixels = (pixels<<4) | (p4>>6);
@@ -2064,7 +2069,10 @@ void jswrap_pb_blitScreen(JsVar *image, JsVar *options) {
20642069
BLITPIXEL
20652070
#undef BLITPIXEL
20662071
}
2072+
if (y != y1) lcdFSMC_dmaWait();
2073+
lcdFSMC_dmaStart(rowBuf, 480);
20672074
}
2075+
lcdFSMC_dmaWait();
20682076
lcdFSMC_blitEnd();
20692077
_jswrap_graphics_freeImageInfo(&img);
20702078
}

0 commit comments

Comments
 (0)