Just a FYI to anyone using the STM32F2 or STM32F4 and some other in the series. DMA1 does not workwith all perhipherals on these devices, and DMA2 has to be used. However, only Timers 1 and 8 interact with DMA2. The STM32 Cube does not warn that DMA1 can't be used with GPIO
Oh man you are just one of a kind, you just saved me from a huge headache with this Application code I had to write and for a few months I couldn't find the right solution for After watching this video and trying it out, it worked just as I wanted it to, totally loved it. we need more practical embedded engineering like this on the internet. I'm tired of USART and all the communication and IOT tutorials, we want more Timmer-related stuff, more ADCs, things that relate to instrumentation and precision. Please keep up the great work.
I tried many times with STM32H750VBT. I used different Timers and both DMA1/2. In the end it worked, using (uint32_t)&GPIOx->ODR instead of (uint32_t)&GPIOx->BSRR. My only problem leftover for now is, that even using circular mode, after each burst, there is a gap in the output, (seems linear) depending on the counter period i choose.
Awesome! This is very helpful for me, as I need similar thing. Big thanks! Is there a possibility to somehow tune it to have 6MHz CLK signal without so much jitter you showed at the ending of your video? Different platform? Other tricks?
Hello again what if I want to use 2 GPIO Ports for my Bit-Pattern as one Port does not have enough pins? for example Port A and also Port B We can probably put the destination Address as (uint32_t)&(GPIOA->BSRR)&(GPIOB->BSRR) but how does the Source Address know which port we are referring to? For example: How does it know the pixelclock[0] = 0x00000001; belongs to PA1 or PB1? Could you please elaborate on that?
I do not think you can combine addresses like that. You need to think about how the DMA controller works in the background. Which is essentially moving data from one address to another address. I would be very surprised if the DMA could write to 2 addresses (2 GPIO ports) at the same time. If you need so many high-speed parallel signals you might really hit the limits of an MCU and consider an FPGA. However, maybe you can use 2 seperate DMA channels (triggered on the same timer) to achieve what you want. But when you do this, make sure, that the DMA channels do not block each other by using the same bus. There are tables in the datasheet of the MCU which describe the DMA channels (which can be active at the same time) because the BUS fabric architecture is dependent on which MCU you use. And if that works there might still be a chance that both GPIO ports have a slight difference in timing, perhaps non-static so that you have jitter between the signals of both ports. I would try this and then measure the output signals. I hope this helps.
@@simonmartin_ch Thank you Simon for your kind guidance, I DO appreciate your time and effort. I use F103C8T6 running at 72Mhz my update event Clock is 1Mhz so 500khz Frequency and the smallest pulse I make is around 5us = 5 update events, I get very low jitter with this config. which is very important for me. In fact, I have just enough GPIO pins in port B for this task( around 14 I need), however, I'm a bit conservative about future updates on software, so I may add a few more another reason for using two ports was that unfortunately all the pins of a specific port are not placed all side-by-side in an LQFP48 package so they come out of every corner of the MCU and contaminate my sensitive Analog sections and ADC reads, (haven't tested it yet, so it may or may not). At the end of the day, if using two ports with DMA would cause more jitter and instability, I would most probably go with one port solution for now and work on my Embedded skills to find a better solution in the future maybe.
If i understand your question right, yes this is possible for some peripherals like UART, SPI, I2C. It is called a "DMA transfer complete interrupt" or "DMA transfer complete callback" function.
If ODR values are not changed, then there is something wrong with the DMA. Is the DMA configured correctly? Is it started? I assume you followed every step in the tutorial carefully (therefore yes) So perhaps it has something to do with the available DMA channels which differ between the architectures. Maybe try a different DMA channel and/or timer.
By clk, you mean one of the GPIO signals generated by the DMA? You could run the DMA in regular mode instead of circular. and then only use a data array which produces 8 clk cycles. But if you only want to stop one signal while the othes continue, it becomes more tricky.
@@simonmartin_ch the code is running perfectly. thanks to you. but I want to stop both the output and the clk pin to stop after 8 pulses. I only want 8-bit outputs at pulses(1 bit = 1 pulse). but I am unable to stop the clk and output. although I try regular DMA. still not working. Any suggestion.
Did you find a way to do this, I need to stop the DMA, change the data buffer en then start the dma again. So as to enable a sort of binary data sending functionality via a pin that gets toggled. However I can't stop the dma at the right points. There is a dma abort function but that takes up too much time to execute..?
@@markusmulder8040Correct, stopping the DMA is inefficient. Use regular DMA configuration in the CubeMX interface. Then start the DMA exactly the same way. HAL_DMA_Start(&hdma, my_data, &destination, lenght);