2025-01-15 10:10 AM
I am making a game console on the aforementioned board. The game is loaded from an SD card and runs in user mode. As such I have a couple of system calls which allows the game to work properly. The game in question is already done, now I am just working on scaling it, since it operates on 256x160 resolution which is fairly small to see with naked eye. I would like to scale it to 768x480, or times 3 the original resolution. As such, I have this function which should scale the content using DMA2D. The code example is down below.
extern DMA2D_HandleTypeDef hdma2d;
void dma2d_scale_image(uint32_t src, uint32_t mid, uint32_t dst, uint32_t w, uint32_t h, uint8_t scaling_factor) {
uint32_t dstW = w * scaling_factor, dstH = h * scaling_factor;
/* columns */
hdma2d.Instance->FGOR = w - 1;
hdma2d.Instance->OOR = dstW - 1;
for (int i=0; i<dstW; i++) {
volatile uint32_t s = src + (i/scaling_factor) * 4;
HAL_StatusTypeDef status = HAL_DMA2D_Start(&hdma2d, s, mid + i * 4, 1, h);
HAL_DMA2D_PollForTransfer(&hdma2d, 0xFFFFFFFF);
}
/* rows */
hdma2d.Instance->FGOR = 0;
hdma2d.Instance->OOR = dstW * (scaling_factor - 1);
for (int i=0; i<scaling_factor; i++) {
HAL_DMA2D_Start(&hdma2d, mid, dst + (dstW * i * 4), dstW, h);
HAL_DMA2D_PollForTransfer(&hdma2d, 0xFFFFFFFF);
}
}
The scaling code using DMA2D is much faster than doing it through code directly, about 2.5x faster. It also uses a "mid" buffer to store partial scaling results, without corrupting the image in question.
I have tested this code on constant 2d array data and it worked fine. However, when using it inside the actual game, the DMA2D wrote zeroes to the target framebuffer instead of scaling the image. I have tried moving addresses around and initializing the framebuffer to 0xFF bytes to make sure it is actually writing and it really does appear like it is writing zeroes no matter the source. I tried disabling dcache, since I heard it can cause problems, but that didn't seem to help, unless I did it wrong. All of this is happening inside SDRAM, so memory region from 0xC0000000 to 0xC1000000. Since both the framebuffer, the mid buffer and the actual game are stored inside SDRAM. When I tested it however, I was took constant data, which I assume is written in flash and scaled it to RAM, and the mid buffer was also in RAM.
Does anyone know why this discrepancy happens and how I could go about fixing it? Thanks