 GPDMA part, we want to have a look on the new or not so new peripheral, it's a similar peripheral as is on U5 but it's still quite new compared to previous STM32 devices. So we have some overview of the peripheral then have a look how the example we will use will work then we will use some example with the ADC and UART using the linked list item controlled GPDMA then have some conclusion and then in the cheat sheet there is some additional steps you can play with so to have a quick overview of the DMA so it's a new DMA and on the H5 there are two hardware instances so there are two DMA controllers. It has integrated the DMA MOOCs features so you can map any request to this DMA and it allows linked list the base programming so you can have like a sequence of different transfers and this is what we will demonstrate in the hands-on and of course the main benefit is that we offload the CPU and can do some independent transfers so quick look on the bus so here we have a comparison with the F4 so on the left side we have two DMAs so you can see for example in this case DMA1 was connected to some peripherals the DMA2 is connected to another set of peripherals on the H5 we have two instances but they are basically the same they have the same configuration they can access the same peripheral so it up to you how you split the load between them if it's needed and both have two ports that's similar as on the F4 so usually the port one is more suitable for accessing the memories and port zero is more suitable for accessing the peripherals but it's up to you how you configure it we can support the different type of transfers from peripheral to memory memory to peripheral memory to memory or even peripheral to peripheral you can also do some autonomous data transfer during the slick mode each controller has eight concurrent DMA channels so inside the controller we can have eight different transfers happening so compared to U5 in U5 we had one DMA controller with 16 channels here we have two controllers with eight channels so it allows more concurrent things happening at the same time and we have priority between the different channels and you have basically four levels with the last one being sort of real-time priority so that will block any other transfers inside the GP DMA we can also do some data handling so we can do some reordering of the bytes or some padding sign extensions so that can be useful when you copy data from one peripheral to another but there is some little bit alignment of the data or something like that all the channels support the linear addressing mode so we increase the you can fill some part of memory and two channels in each controller supports so code to the addressing mode so you can basically skip some part of the data so this could be used like in graphics when you copy some picture but can have many different usages and in the cheat sheet later on that this one is used for sorting the data so we will use this linked list mode so basically it's like a structure in the memory which contains the configuration for each transfer and then we have another part of memory that contains another transfer so inside this structure we have the values of different registers and at the end we have the linked list register that can point to another item so here is the overview of the GP DMA structure so we have some DMA requests so that's when the peripheral that is sending or accepting the data notifies us that it's ready we can have some triggers so we can trigger the transfer on some event and here the slave AHB bus for register configuration the master ports for accessing the bus metrics maybe one more interesting thing it contains also the security and privilege management so you can configure some DMA channels to be secure or privileged or non-secure non-privileged and they can have some restricted access to some memories or peripherals there is some overview again we have eight channels some of the channels have small 5-4 size because for most cases it's not necessary to have a big 5-4 and some other channels as a larger one so it's up to you if you need the larger 5-4 you use different channel number but you can assign any peripheral to any channel you want okay so we will use ADC1 to convert port channels in the continuous mode and we will generate the DMA requests we will also use USART3 to send the obtained data to the terminal on the PC and we will use timer 15 to trigger that transfer we will use the linked list mode so we will rotate between these different transfers so the reason to trigger with the timer 15 is that you want to reduce the data we sent over the UART because if we would be running in the continuous mode we would overload the terminal and we wouldn't see anything and it might also crash on our PC and also we can demonstrate this trigger feature which I think is also quite nice here's how it works so at the beginning we will load the configuration of the note 1 from the linked list so here we have two transfers in the linked list and once it's loaded it will wait for the trigger from the timer of 15 once it received trigger from timer 15 it will start based on the request from ADC1 it will start the transmitting data to the memory of the different channels we will have it sequentially in the memory once this transfer is finished the GPDMA will load from the memory the next configuration for the registers and then it will start the transfer to the UART3 and it will send the same data to the USART3 then it should go back to the beginning and again load the GPDMA note 1 again I will switch to the cube IDE I will close this project and start a new one so I will again start with the board selector and I will and I will again select yes to initialize the peripherals okay so we have the project generated so let's start with the ADC configuration here we already have some channel preselected but that's for USB-C so you will not use that but we will select channel 0 channel 2 in single-ended mode channel 6 and channel 13 so just four channels that are available on the board to use it for the conversions then we will in the configuration we will enable the continuous conversion mode so we don't need to time the ADC to start the conversion it will convert continuously the same for the DMA to enable the continuous requests and we will also enable the low-power autowave so basically when the DMA doesn't read the data the ADC will stop and it will not overflow yeah and here we need to configure the sequence so here we will select 4 so we will convert the 4 channels we select it for each rank we will select the different channel so 0, 2, then 6 and finally the 13 one more thing I will do is change this pre-scaler to 8 so this should result in some reasonable clock frequency for the ADC it seems to work even with the two but it's out of the out of the specification and also one of the things you will probably fix in the future release yeah so now we will configure the DMA so I does to go to the GPDMA one so we go there here I will select the channel 6 in linked list mode so for this hands-on itself we could use other channels as well but later in the cheat sheet so we don't have time to do it there but in the cheat sheet there are some examples that use the 2D addressing so that's why we select this one and here we will select the execution mode as circular okay and I think that's all for there then I will go to the timer timer 15 select internal clock source now I will select the timing so we will want to generate event each second so for the pre-scaler I will select the 50 000 minus one so it's like that and for the counter period it's 5000 minus one and in the trigger event selection I select the update event otherwise we wouldn't trigger the transfer so then we should configure the UART but here it's done from the board itself so we don't need to change anything and in the utilities we will configure the linked list for the DMA so I click here to add a new list I click here back on the queue name to configure the queue parameters and I change it to circular and here I need to enter the name of the first note in the loop which should be your note name so it's this one that is already there so now I change to this one and here I will configure the parameters and so first we will select the request so this one it should be ADC one then we will in the channel configuration we will use peripheral to memory we are reading data from the ADC for the source data we will select half word because we have 12 bit ADC so 16 bit half word we will read and we don't increment the address we are still reading from the same register for the destination settings we will select the incrementing because we will fill a buffer in the in a RAM and again we select a half word size and for the trigger we will select the request on rising edge and we will select the timer 15 which is at the bottom of the select list and this configuration we leave at the default and now we select the runtime configuration so this is basically a code that is pasted by kubemax so this one I will for the source address I will use the data register of the ADC and for the data I will use some variable we will define in the code and for data size we will use 64 times 2 so this data size is in bytes so we will transfer 64 samples but each sample has two bytes now we need to add the second node so here I click the add node at the dot I will rename it to your node name 2 in the request I will now select the usr 3dx so we will send data to the pc in the channel configuration I will select memory to peripheral we are sending the samples we got from ADC so we will transfer from SRAM to peripheral so source data setting we increment because we are in the memory but we leave the byte size so now we will send the data per bytes the destination address we don't increment and leave the byte size and we just configure the runtime configuration we again read from the data and we write to the usr data register and again we will send the same amount of bytes so again it's 64 times 2 we got some issues with the with the kubemynx here so the workaround is quite simple I just closed the ioc file and I open it again because there was some I know that we faced some issues when we didn't do it then the code generated was wrong so and again I just generate the code here I will go to the linked list c file and modify there the pointer to the data we will use in the main c file I put the include for the linked list and I define some variables at the this main file we will start the transfer yeah I think that's all so here we call the function generated by the linked list utility to initialize it then we configure it to the gpdma1 channel 6 then here we do some trick to enable the dma transfer for the uart and enable it and then we start the dma start the adc and finally start the timer 15 so now this should send some data over the uart to the to the pc so I now have some jump wires on the channels I should see some different values so I can see that each second I receive some data from the adc so basically without cpu doing anything I can periodically send some data over the uart to the comport so we had a look how the gpdma is implemented on the h5 we summarize some some of the key features and we demonstrated that we can do some autonomous data transfer without the cp load and briefly introduce the linked list based programming of course if you want to use the let's say regular dma transfers like the normal mode or circular mode from the old stm32 so you can do it and it's in the cuba mix you can configure it without the need to configure the linked list what's next so we already shared the link with the cheat sheet and then there is some additional steps you can more evolve this example that you can do some for example some data sorting so now the data were in order that there is channel one channel two channel three channel four and again channel one for each sample and you can reorder it so you have all samples from channel one then all samples from channel two and so on you can do some more advanced data manipulation yeah so this is basically described here so you sort the values from different channels to have it separately in different buffers and the other demonstration is that you can generate some events at the end of the transfer so you can look at the LED when the transfer is finished