Bare metal DMA2D
Hello all
I have a custom STM32L496RGTx-based board onto which I'm migrating a legacy rendering engine. I'd really like to accelerate text rendering and I'm looking into DMA2D for a4 format font data.
I have a little test setup which attempts to populate a buffer from supplied a4 test data like this:
static void draw_a4(const uint8_t* a4) {
uint16_t w=24;
uint16_t h=24;
uint16_t buf[w * h]; // rgb565 raster buffer
uint32_t back = (uint32_t)&buf;
uint32_t data = (uint32_t)a4;
__HAL_RCC_DMA2D_CLK_ENABLE();
/* constant bg configuration */
DMA2D->BGPFCCR = (DMA2D->BGPFCCR & 0x00fc00c0) | /* DMA2D Background PFC Control Register reserved bits */
(0b11111111 << 24) | /* alpha value (0xff) */
(0 << 16) | /* alpha mode */
(0 << 8) | /* clut size */
(0 << 5 ) | /* start clut loading */
(0 << 4) | /* clut color mode */
(0b1010 << 0); /* color mode argb8888 */
DMA2D->BGCOLR = 0xff00ffff; /* DMA2D Background Color Register */
DMA2D->BGMAR = 0; /* DMA2D Background Memory Address Register */
DMA2D->BGOR = 0; /* DMA2D Background Offset Register */
/* constant fg configuration */
DMA2D->FGPFCCR = (DMA2D->FGPFCCR & 0x00fc00c0) | /* DMA2D Foreground PFC Control Register */
(0b11111111 << 24) | /* alpha value */
(0 << 16) | /* alpha mode */
(0 << 8) | /* clut size */
(0 << 5 ) | /* start clut loading */
(0 << 4) | /* clut color mode */
(0b1010 << 0); /* color mode a4 */
DMA2D->FGCOLR = 0xffffff00; /* DMA2D Foreground Color Register */
DMA2D->FGMAR = data; /* DMA2D Foreground Memory Address Register */
DMA2D->FGOR = 0; /* DMA2D Foreground Offset Register */
/* output configuration */
DMA2D->OPFCCR = (DMA2D->OPFCCR & 0xfffffff8) | (0b010 << 0); /* DMA2D output PFC control register (rgb565) */
DMA2D->OOR = 0; /* DMA2D Output Offset Register */
DMA2D->OMAR = back; /* output buffer */
DMA2D->NLR = (DMA2D->NLR & 0xc0000000) | /* DMA2D Number of Line Register */
(w << 16) | /* number of pixels per line */
(h); /* Number of lines */
DMA2D->CR = (DMA2D->CR & 0xfffcc0f8) | /* DMA2D control register */
(0b10 << 16) | /* mode (FG and BG fetch with PFC and blending) */
(0 << 13) | /* Configuration Error Interrupt Enable */
(0 << 12) | /* CLUT transfer complete interrupt enable */
(0 << 11) | /* CLUT access error interrupt enable */
(0 << 10) | /* Transfer watermark interrupt enable */
(0 << 9) | /* Transfer complete interrupt enable */
(0 << 8) | /* Transfer error interrupt enable */
(0 << 2) | /* abort */
(0 << 1) | /* suspend */
(0 << 0); /* transfer */
DMA2D->CR = DMA2D->CR | DMA2D_CR_START; /* set start bit to start the transfer */
while(DMA2D->CR & DMA2D_CR_START) { } // wait for chromart idleAs soon as I kick-off the transfer on line 58, the TEIF bit in DMA2D->ISR gets set, indicating a transfer error and the data, but I can't for the life of me work out what would cause something like that. I've tried a few different combinations for the parameters but always with the same result.
Is there anything forehead slappingly obviously wrong my code or some sort of other configuration required ?
