DMA 👍 Keep it up. Your videos really help me. By the way, can you try to make a video on making a usb composite device (example multiple hid)? I know this is a hard part though.
3 роки тому
Thank you, I'm glad you find them useful. I am interested in usb and I could see that concept very useful, but currently I have loads of other things on my mind ... someday
Hello there, great tutorial I was wondering if you maybe could tell me how to properly read GPIO pins to RAM with DMA? You see I am using STM32F769i and I am trying to read the whole GPIOE (because GPIOE has a blue button connected, so I can quickly see if its working) bus into RAM Now I configured TIM1 timer to push the DMA every 2Mhz and I am comparing GPIOE->IDR to my buffer to see if its working (my buffer is in DTCM section so thats its protected from coruption (at least I heard that you have to do this) My TIM1 is counting properly my DMA2_Stream5->NDTR is also decreasing properly from 16 to 0 (16 is a size of data I told DMA to copy) but for some reason my GPIOE->IDR does not equal my buffer so I think its not working properly and I am not sure why I have DMA2 configured in Circular mode with PERIPH_TO_MEMORY as well as Peripheral Aligment and Memory Aligment to DMA_PDATAALIGN_HALFWORD not sure what the problem could be whats the best way to check if DMA is doing its job properly? I would send you the code if I could but I cannot put it in youtube comment :)
Рік тому
Hey. For cases like this, you could post the code either on github, or if it's more private, you can post relavant chuncks only. Some parts can also be shared on compiler explorer. I don't have much to suggest from your description as it sounds like you have thought of everything. But as things go, precission is important and if you have but a single setting wrong, the thing might not work. You can check if dma interrupts are working - half and full copy buffer interrupt complete. You can set a global var and check in main if its set. Also make sure, that the function, whith which you start the process (something like HAL_DMA or HAL_TIM or HAL_GPIO) function, that starts DMA / peripheral function ,should be used.
@ Hi there, thanks so much for your help Its not that I don't want to share source code but its youtube, that magicly deletes all my comments if I link to github Not this time thought :) Here in this video: ua-cam.com/video/DR0MmSlkp_c/v-deo.html in the description there is a link to source code as well as picture of how it should look like when working Because yes, I made it work with registers only (the problem was because I was reading address of an array instead of actual value so thats why nothing matched Now I am trying to make it work with HAL as well if USE_REGISTERS is defined it will use register implementation, if not defined, it will use HAL with HAL DMA NDTR just doesnt move, implying that TIM1 (which does count) is not starting it or something Well if you could maybe take a look, maybe you figure out something I forgot (my brain is just stuck and not sure how to continue :) ) My ultimate goal is to make this example work on STM32H750B (buts its along way to get there, first I need to make the example work with HAL :) ) Well lep pozdrav iz Slovenije and take care :)
Hi Matej! I love your videos and I've been useful for me. I would like to ask if you know to create a project to read I2C peripheral using DMA. I've been trying but I don't to do. My project consist of to connect STM32F446ZE to accelerometer KX132 to read buffer information. This accelerometer has a internal buffer of 516 bytes of width and I want to read many buffers of this width with DMA. I use HAL_I2C_Mem_Read_DMA function to read buffer and I see the interruption HAL_I2C_MemRxCpltCallback work one time but I want to read buffer continuously. If you know any tips of this topics it will be useful for me ! Thanks for you videos, I'm waiting for more! Note: English is not my native language, sorry :(
2 роки тому
Hi, thank you for the comment. You can use the interrupt when the dma transfer is complete, to store your data, do a small amount of work (process it, filter it or just store it somewhere else) and then schedule another transfer - call the HAL_I2C_Mem_Read_DMA again. I haven't had a need for this as of yet, but I assume that something like this should work. One idea would be to just use continuous mode, but you can risk your data beeing corrupted. That's why I would manually schedule another transfer when you're ready. Hope this helps and thank you for watching.
Great tutorial! I actually am also developing a project similar to your "UART Tx and Rx with DMA" example with a tiny difference which makes a huge impact and has been a huge headache. Unlike the protocol you implemented, the one I am working on does not state that the messages have a fixed length (like the 8 byte yours does). The protocol I am implementing has variable message length which makes the Rx part of the code a problem: If I do not know the next incoming message, I cannot guess its length... consequently I cannot state how many bytes to expect in the Receive_DMA(...,...,Len) to trigger the Rx interrupt. I have a work around which is to set the Rx Len to 1 and trigger one interrupt for every byte received.... but this seems sooooooo ugly and inefficient! :( Still looking for a better solution but haven't been able to find one yet! :'(
2 роки тому
Hi, I have implemented on such protocol on our production device. The idea is simple and so is the implementation. You "assume" that the messages are comming in "slowly" and you just let DMA copy bytes into a buffer. In your "main loop" or an alternative (rtos task) you keep track on where in the buffer you have checked for a message and just parse bytes as they come. Then you have a stateful parser that check for parts of the message. For variable message length, I would have a part of message contain a size of payload, that can vary between 0 and "max". I'm welcome to other ideas, but this sistem works geat for us.
I can't find the DMA request mapping table (04:32) for the STM32H743VI. It's not in the datasheet...
3 роки тому+1
I took a look into datasheet and reference manual for the part. It's a very powerfull package, do doubt. This comes with some changes regarding data busses inside. Because it has 4 DMA controllers it uses something called DMA request multiplexer (DMAMUX) to manage DMA reuqests between peripherals and DMA controllers. Look from the page 694 onward or in section 17 of the reference manual (RM0433).
Tricky question: is there a way to receive and send from the UART via DMA COMPLETELY BYPASSING THE CPU AT ALL TIMES? No polling in the while superloop and no interrupts
Рік тому
You can configure it in circular mode and it'll write to that buffer front to back all the time. But that's not usefull since you'll be loosing information all the time. I use this mode, but then in a super loop I check the position of dma write index ajd compare it to previous read index to determine if new data was received.
@ know that the inspiration for what I want to do is you. I want to do what you did with UART on your interrupt video, where you made an app that showed on the serial monitor everything you typed. Basically loopback in UART with single characters. But I wanted to try it with "pure" DMA. Thanks for the tips!
Rather than write comments on the slides try using text. When showing source code avoid using the IDE as it takes up so much of the screen that it makes the code section harder to read.
Рік тому
Fair point. I have a large monitor so I sometimes forget to bump up the scale on the font. Drawing on the screen feels different from just shuffling through slides plus it takes me less time to prepare (although slides and script can take lots of time for bigger topics).
Really helpful for my final year project thank you never stop doing videos
Thank you very much for the excellent explanation. The best that you can find in web to understand DMA
hvala Matej, super video :-)
Muchas gracias por tu ayudar.😁
Amazing ❤
thanks for doing this video
Excellent!
Really helpful and quite insightful
Great video... Thank you sir for the clear explanation 😊
Thank you sir, very nice explanation. Really appreciated :)
🎉 thanks
Great channel!!
Hvala in LP
DMA 👍 Keep it up. Your videos really help me.
By the way, can you try to make a video on making a usb composite device (example multiple hid)? I know this is a hard part though.
Thank you, I'm glad you find them useful. I am interested in usb and I could see that concept very useful, but currently I have loads of other things on my mind ... someday
Hello there, great tutorial
I was wondering if you maybe could tell me how to properly read GPIO pins to RAM with DMA?
You see I am using STM32F769i and I am trying to read the whole GPIOE (because GPIOE has a blue button connected, so I can quickly see if its working) bus into RAM
Now I configured TIM1 timer to push the DMA every 2Mhz and I am comparing GPIOE->IDR to my buffer to see if its working (my buffer is in DTCM section so thats its protected from coruption (at least I heard that you have to do this)
My TIM1 is counting properly
my DMA2_Stream5->NDTR is also decreasing properly from 16 to 0 (16 is a size of data I told DMA to copy)
but for some reason my GPIOE->IDR does not equal my buffer so I think its not working properly and I am not sure why
I have DMA2 configured in Circular mode with PERIPH_TO_MEMORY as well as Peripheral Aligment and Memory Aligment to DMA_PDATAALIGN_HALFWORD
not sure what the problem could be
whats the best way to check if DMA is doing its job properly?
I would send you the code if I could but I cannot put it in youtube comment :)
Hey. For cases like this, you could post the code either on github, or if it's more private, you can post relavant chuncks only. Some parts can also be shared on compiler explorer.
I don't have much to suggest from your description as it sounds like you have thought of everything. But as things go, precission is important and if you have but a single setting wrong, the thing might not work.
You can check if dma interrupts are working - half and full copy buffer interrupt complete. You can set a global var and check in main if its set.
Also make sure, that the function, whith which you start the process (something like HAL_DMA or HAL_TIM or HAL_GPIO) function, that starts DMA / peripheral function ,should be used.
@ Hi there, thanks so much for your help
Its not that I don't want to share source code but its youtube, that magicly deletes all my comments if I link to github
Not this time thought :)
Here in this video: ua-cam.com/video/DR0MmSlkp_c/v-deo.html
in the description there is a link to source code as well as picture of how it should look like when working
Because yes, I made it work with registers only (the problem was because I was reading address of an array instead of actual value so thats why nothing matched
Now I am trying to make it work with HAL as well
if USE_REGISTERS is defined it will use register implementation, if not defined, it will use HAL
with HAL DMA NDTR just doesnt move, implying that TIM1 (which does count) is not starting it or something
Well if you could maybe take a look, maybe you figure out something I forgot (my brain is just stuck and not sure how to continue :) )
My ultimate goal is to make this example work on STM32H750B (buts its along way to get there, first I need to make the example work with HAL :) )
Well lep pozdrav iz Slovenije and take care :)
Hi Matej!
I love your videos and I've been useful for me. I would like to ask if you know to create a project to read I2C peripheral using DMA. I've been trying but I don't to do. My project consist of to connect STM32F446ZE to accelerometer KX132 to read buffer information. This accelerometer has a internal buffer of 516 bytes of width and I want to read many buffers of this width with DMA. I use HAL_I2C_Mem_Read_DMA function to read buffer and I see the interruption HAL_I2C_MemRxCpltCallback work one time but I want to read buffer continuously. If you know any tips of this topics it will be useful for me !
Thanks for you videos, I'm waiting for more!
Note: English is not my native language, sorry :(
Hi, thank you for the comment.
You can use the interrupt when the dma transfer is complete, to store your data, do a small amount of work (process it, filter it or just store it somewhere else) and then schedule another transfer - call the HAL_I2C_Mem_Read_DMA again. I haven't had a need for this as of yet, but I assume that something like this should work. One idea would be to just use continuous mode, but you can risk your data beeing corrupted. That's why I would manually schedule another transfer when you're ready.
Hope this helps and thank you for watching.
Great tutorial!
I actually am also developing a project similar to your "UART Tx and Rx with DMA" example with a tiny difference which makes a huge impact and has been a huge headache. Unlike the protocol you implemented, the one I am working on does not state that the messages have a fixed length (like the 8 byte yours does). The protocol I am implementing has variable message length which makes the Rx part of the code a problem: If I do not know the next incoming message, I cannot guess its length... consequently I cannot state how many bytes to expect in the Receive_DMA(...,...,Len) to trigger the Rx interrupt.
I have a work around which is to set the Rx Len to 1 and trigger one interrupt for every byte received.... but this seems sooooooo ugly and inefficient! :(
Still looking for a better solution but haven't been able to find one yet! :'(
Hi, I have implemented on such protocol on our production device.
The idea is simple and so is the implementation. You "assume" that the messages are comming in "slowly" and you just let DMA copy bytes into a buffer. In your "main loop" or an alternative (rtos task) you keep track on where in the buffer you have checked for a message and just parse bytes as they come.
Then you have a stateful parser that check for parts of the message. For variable message length, I would have a part of message contain a size of payload, that can vary between 0 and "max".
I'm welcome to other ideas, but this sistem works geat for us.
I can't find the DMA request mapping table (04:32) for the STM32H743VI. It's not in the datasheet...
I took a look into datasheet and reference manual for the part. It's a very powerfull package, do doubt. This comes with some changes regarding data busses inside. Because it has 4 DMA controllers it uses something called DMA request multiplexer (DMAMUX) to manage DMA reuqests between peripherals and DMA controllers. Look from the page 694 onward or in section 17 of the reference manual (RM0433).
Tricky question: is there a way to receive and send from the UART via DMA COMPLETELY BYPASSING THE CPU AT ALL TIMES? No polling in the while superloop and no interrupts
You can configure it in circular mode and it'll write to that buffer front to back all the time. But that's not usefull since you'll be loosing information all the time.
I use this mode, but then in a super loop I check the position of dma write index ajd compare it to previous read index to determine if new data was received.
@ know that the inspiration for what I want to do is you. I want to do what you did with UART on your interrupt video, where you made an app that showed on the serial monitor everything you typed. Basically loopback in UART with single characters. But I wanted to try it with "pure" DMA. Thanks for the tips!
Hello! Great tutorial! Which dark theme for STM32IDE do you use? It looks pretty nice!
I explain it in video 37 :)
You could make Udemy course of it. That will be cool
For now I like it beeing here, free for all to learn.
Rather than write comments on the slides try using text. When showing source code avoid using the IDE as it takes up so much of the screen that it makes the code section harder to read.
Fair point. I have a large monitor so I sometimes forget to bump up the scale on the font. Drawing on the screen feels different from just shuffling through slides plus it takes me less time to prepare (although slides and script can take lots of time for bigger topics).