What's the best way to do bit-banging with timers and DMA?
Hello,
I want to implement VGA signal generation on my STM32L432KC board. For start, getting the vertical sync and horizontal sync timings right would be great. I found a nice website with hsync, vsync and pixel timings and I thought that using resolution of 800x600 pixels at 60 Hz would be the easiest, since the clock frequency is easily divisible to smaller integer numbers (eg. instead of having 800 pixels of horizontal resolution with 40 MHz pixel clock, I can have 10 MHz pixel clock at the cost of smaller 200 px horizontal resolution).
To achieve precise timings, I want to use a timer (let's say, running at 10 MHz) and some counters, so I will know where am I on horizontal and vertical axes (eg. I know I'm in the start of the visible area in 3rd line, so I need to start displaying proper buffer of pixels). Also, I'd like to have some interrupts, so eg. when I start drawing a line, I want to generate the next line [so I won't be using a frame buffer, at least for now]).
I tried to toggle a GPIO pin really fast with DMA, like this:
/* DMA configuration code from dma.c file */
hdma_memtomem_dma2_channel1.Instance = DMA2_Channel1;
hdma_memtomem_dma2_channel1.Init.Request = DMA_REQUEST_0;
hdma_memtomem_dma2_channel1.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma_memtomem_dma2_channel1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_memtomem_dma2_channel1.Init.MemInc = DMA_MINC_ENABLE;
hdma_memtomem_dma2_channel1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_memtomem_dma2_channel1.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_memtomem_dma2_channel1.Init.Mode = DMA_CIRCULAR;
hdma_memtomem_dma2_channel1.Init.Priority = DMA_PRIORITY_HIGH;
/* this piece of code is placed before the infinite while loop */
HAL_DMA_Start(&hdma_memtomem_dma2_channel1, (uint32_t)LUT, ((uint32_t)&(GPIOB->BSRR)), 4);LUT is an array that contains four words that just specifies which pins in GPIOB register to turn on or off. The code works, it toggles a pin at 4 MHz frequency (I have no idea why exactly this frequency) and it doesn't work for 2 element array for some reason.
Now, how can I use a timer to execute DMA copy at some set frequency? Can I do it faster than 4 MHz? Also, is there a better way to manipulate GPIO pins with DMA or is my hacky method enough? Where do I go from here? And lastly, I'd be really grateful for some resources that could help me.
