 So now we're going to add our second node. So we're going to add our UR node into our link list now. So what we're going to have now will be our ADC node. When we finish doing our ADC transfer, we will then start our UR transfer, and then that one will link back to the start, which will then do the ADC transfer again and so on. So first thing is... Quick question, where this ADC takes data from? You're checking the channels from channels one, two, three, four. That's what we set as those four single-ended channels. Right, but the analog data. Yes, it's just receiving analog data. From where? Whatever those pins are currently floating at. Okay. The data that we're receiving isn't important. It's just showing you that data is coming in. You had zeros in your register, you're seeing different values now. I thought the data comes from some measuring something on the board or something. No, no, no. It's just taking whatever those pins are currently floating at at the time. Okay. I don't believe they're connected to anything else on the nuclear board. I haven't had a proper look at the schematics. I believe it's just floating pins because they are moving up and down when you look at the data. Okay. Yeah, so what we're reading is not relevant. It's the process that you're looking at here. But in principle, if you connect those to some source, then you will read them. Yes, yeah. If you widen different voltage sources, you should have nice stable values sat on each of those pins from whatever you're reading from. Okay. If you were reading, say, temperature sensors on each one, then you'd have a fairly slow-moving source whereas ours I think are fluctuating quite a lot because it's just floating whatever noise is on the board. Right. So what we are going to do now is our first node loads in our parameters into our DMA channel, which is going to be our ADC read. That will then go through and count down from its number of transactions it's got to do. So it will load channel one in, channel two, so on, so on, so on, until it fills the all 64 elements of our data array. As soon as we've completed that, our link list will then switch over to node two. All the parameters of node two will get loaded into the DMA channel and the process starts again. This time, the UR will be sending the data from the memory out over your UR channel. And again, it will go through each element at a time until it reaches the end and then it will jump back to configuring the ADC into the DMA channel and it will start the process over again. So let's now do this in the UR, which is why I said you could start from your homework because this is exactly what you did in your homework. So if you've started from your homework, then you've got a fairly easy time now because everything here is already done for you. So if you go back to your cube and X, we're now going to enable Usart number one on the connectivity. You're looking for Usart number one and we want to be asynchronous and that should enable pins nine and ten on our pinout diagram. We don't need to change any configurations. We can leave the board rate as its default value there, which is fine. So that's all we need for the peripheral side. Now we go back to our linked list in Utilities. We need to highlight our queue name at the top and we need to add a new list. Oh, sorry, add a new node. Sorry, not the list. We need to add a node to our existing list. So we need to give our node a new name. So I'm going to call it node two to make life easy for my screen captures. It's your node name two. No space. Just put our node name two. And the configuration that this one is going to be linked to is our Usart number one. So in request configuration, it's going to pull in Usart number one TX. We're transmitting data. So it's the TX version of Usart number one. And in the channel configuration, we need to change the direction because we are going from memory to peripheral. Our source data is the memory array. So that's going to increment. So we need to enable source address increment. Our runtime configuration is going to be our parameters from our data array. So where's my copy screens? There we go. So our source address is data because that's our data buffer. Our destination address is going to be our data register, our transmit data register for our UART number one. And our data size is going to be the same as we had for our ADC, which is 64 times two. And that's it. We don't have to change anything on data width because we're only sending out bye bye bye over the UART. Therefore, nothing has to change in our destination data settings either. Once you've configured all that, make sure your name is node name two, your node name two, and then you can generate your code again. Terminate my debug session because I left my debug session running. I want to open my project. There we go. So now hopefully, once you terminate your debug session, your code should have updated. And in main.c, you'll know if it's updated because you'll see you've now got some UART configuration in here. Therefore, you'll know your cube IDE has updated. We now need to enable the DMA for the use. Do we still have the old code or we have to write it again? No, no, all your old code should have been placed between a user code begin and a user code end, so it should all be maintained. So there's two of the lines that we pasted in earlier there, in mine, in the private variables. So everything you should have pasted, as long as you pasted in the correct locations, between a user code begin and a user code end, your code is maintained. So the first item we need to do is link the DMA to use art number one. So this we can do with one line of code. And that can go inside our user code begin to. So it sits between the link list and the ADC starts. 114 for me. Next item we need to do is enable the UART itself. So we've linked the UART to the DMA. Now we need to enable the UART. So that goes after we've linked it in your code. Make sure it goes after we've done the link. So that goes at line 115 for me. And now, sadly, in this current version, there is a bug inside our Cubemax generation. So we have to go into our linklist.c file and change our labels. Now we have to be very careful of which ones we're changing. So if you go into your linklist.c, if you scroll down at line 52, you will see your QName configuration. Then you'll see all the configuration for the ADC. And if you remember correctly, your ADC is your node name, not your node name number two. So at line 83 on my screen, this should be your node name. You need to delete the twos between line 83 and 87. Then if you scroll a bit further down your link list, you'll see your UART configuration, which is correct. That is your node name number two. It's between lines 83 and 87, just after all your configuration for your ADC. That is your node name, not your node name number two. So once you've done that, you should be able to highlight the project and build it. Again, you'll see the warnings about the casting incorrect there. And now if you run your code, launch a terminal program. So you can have a launch the inbuilt one that you've done in your homework, or you can do an external one like I'm doing here. I change my setup to be 115200. You can see there I've got data streaming out at one hell of a speed. My PC keeps thinking at me because I'm exceeding the Territor and Buffer because data is streaming so fast. I'll close that because I keep getting annoying pings in my ears. So now you can see that data is now being streamed out of your machine. I think we've set four megahertz. However fast the peripheral clock is for the UART number one there. So 115200 board, which is the maximum we set there. So you can see now that your data is reading the ADC into the Ram Buffer, then switching over and instantly sending that data straight back out and backwards and forwards. And everybody see data streaming out in a terminal window. How am I doing for time? I'll try and do the trigger one just to preview that we can slow down before we go for lunch. Everybody okay? Not really. My streaming doesn't work. Your streaming is not working? Yeah, it prints the first UART prints. I left the homework printing. So the homework printing ends in the third character and then nothing happens. So maybe it works and just kills the ham. It depends. I forget because when I did this particular one I think I ended up disabling the Hello World UART line. There should be a line in user code too. User code begin to, there should be something for your that's displaying your Hello World Buffer. Yeah, and I think I commented it out in the end. Probably comment that line out just because it conflicts with the settings that we're trying to basically do it in DMA and we end up getting a conflict. Okay, well that explains. Yeah, because at the moment you've set your Hello World to use non-DMA and we're trying to set it here to use the DMA. So you might have a conflict there. On that one. Yeah, sorry I should have said comment that line out when I was going through the code if you'd done it that way. Yeah, I apologize. Yeah, it's sensible. I just wasn't thinking. Just following Darmily. That's okay, that's alright. You're okay until this section actually because in the previous section it doesn't matter but now when we add the UART configuration obviously it then does conflict. Yeah, I should have mentioned that one, yes. It's because I'm starting from a blank project because obviously I didn't have the homework one open. Yeah, you don't get it. I left my homework one closed there at the bottom there. Yeah, so you'll need to comment that one line out. Right, so I'll try and quickly, we'll hit what I should have stopped at lunchtime. I'll try and quickly go through triggers with you before we actually do stop for lunch because I think this one's quite good for you because it's going to slow down what you're streaming out of your UART, this will. So what we're now going to do is we're going to link a timer as a trigger source or our DMA ADC command. So it'll only do the process. It'll only start the process once the timer event has expired or updated. So everything stays as before. Your link list will load your channel with your DMA config. Nothing will happen at that point until your timer generates its update event. Then it'll trigger our DMA where it'll do the same process, load all the registers or 64 cycles. Then it'll instantly go and change the settings to the UART and transmit everything else. Then it'll reload our ADC again and then sit there and wait till the next trigger event. Rather than continuous data, we're now going to send it out at whatever frequency we set for our timer update event. So if we go back to our CubeMX and we go into our linked list, which is where I currently am, we need to make sure we're editing now node name. So the configuration for the ADC one, which is node name, not node name too. Make sure you highlight the correct one and we're now going to look at the trigger section. So if I reduce all these boxes that I've opened, if I now expand the trigger section inside your node name, I want to set my trigger configuration to be DMA request on rising edge and my trigger selection is going to be timer number 15. So timer 15 trigger output. So that's setting my trigger event in my linked list. Now I've got to go and enable my timer 15. I'll expand timers on the left-hand side. Timer 15, we need to check the box to say that we're using the internal clock and in our timer parameters, we want to set our pre-scaler to 49,999. And as long as we're running at four megahertz, yes, we're at four megahertz, I want to set my counter period to be 79. Trigger output parameters need to be event selection to be update event. So that's a pre-scaler of 49,999, a count period of 79, and trigger event selection to be update event. So this is going to now hopefully when you look in your terminal window in a minute, you should only see a burst of data every second. So it'll read all the ADCs, send everything out over the UART, and then wait one second before it does it again. So it's your way of controlling how frequently your DMAs are doing its read cycles or transmit cycles. And as I say, all this is completely independent of the CPU core. Once the CPU cores set everything up, it goes to sleep, and then this will carry on actioning in the background. So once you've set your timer, we can generate code again. Project. So we know that my code's updated now because I've got timer 15 code here included in my software. Going to here. So we now need to start the timer. So that goes right at the end after we've started the ADC. And again, because we've now regenerated our code, we need to update our link list because we've regenerated, therefore the bug has reappeared again that we corrected because that's not between a user code beginning and a user code end. So again, at line 85 to 89 now on my screen, I need to change my your name to your name. Make sure you only do it on the section that follows the ADC configuration. Down here is correct. 102 to 106 is correct. And now we can rebuild and rerun our project. Debug my TerraTerm again. Bigger for you so you can see. So now when I hit run, you now only see burst of traffic coming through. Once a second, you will see a burst of data coming through now. And remember the data that we're reading from the ADCs, it's not being formatted anyway, which is why it's not appearing as anything sensible on the screen. So there's no data formatting of any sort. And we're just sending whatever that 14-bit reading is and I'm no idea what that converts on the ASCII table to a character. So you're not expecting to see anything sensible in data. It's the fact that you're just seeing burst of data now coming through once a second, which is our timer update event. So hopefully you're all seeing that now. And now we load our ADC parameters into our channel. It sits there and waits until the timer triggers. Once the timer triggers, reads all the ADC, loads in the UART parameters, writes all the UART parameters. The link list will then jump you back to the first node, which then loads in all the ADC parameters again and then it sits and waits again. So you've now hopefully seen the ADC managing by the timer to give you one second burst of data now rather than that mass streaming of data that kept overflowing the TerraTerm buffer.