0:09
hello and welcome to controllers Tech
0:12
this is the second video in the ADC
0:16
32 in the previous video we saw how to
0:19
configure the ADC peripheral and how to
0:22
read the ADC data in the blocking mode
0:25
today we will cover the interrupt mode
0:27
and the dma mode to read the data
0:29
continuously in the background basically
0:32
without affecting the other tasks
0:35
CPU we will continue the project where
0:38
we left in the previous
0:40
tutorial let's open the cube MX to
0:44
project go to the adc1 nvic tab and
0:49
enable the interrupt for the
0:51
ADC note that the continuous conversion
0:56
disabled we will first see how the ADC
0:59
behaves with this being disabled and
1:01
then we will enable it later in the code
1:04
itself that is all I am changing the
1:07
rest of the configuration is same as the
1:09
previous video all right now inside the
1:12
main function start the ADC in the
1:15
interrupt mode once the ADC finishes the
1:19
conversion an interrupt will trigger and
1:21
the conversion complete call back will
1:24
called inside this call back we will
1:28
result here we will again read the ADC
1:31
value and store it in our
1:33
variable then call the mar function to
1:36
amp this value in the range of 0 to
1:40
100 let's change this minimum value to
1:44
1,700 as this is what we got in the
1:48
result let's build and debug this
1:51
project keep in mind that the continuous
1:54
conversion mode is still disabled right
1:57
now we will first see how the ADC
2:00
behaves with it being
2:02
disabled I am setting one breako inside
2:07
function all right we have hit the break
2:10
point this means the ADC has finished
2:13
the conversion and that is why the call
2:16
called we will read the value and map it
2:24
debugger we do not hit the break point
2:27
again this means that the ADC is not
2:30
converting the results
2:31
anymore you can see the count value is
2:34
increasing so the while loop is working
2:37
normally as it should this is happening
2:40
because we have not enabled the
2:41
continuous conversion mode we can still
2:45
make it work by calling the ADC start
2:47
function again inside the interrupt call
2:57
part all right we keep hitting the break
3:00
point this means that the conversion is
3:04
continuously Let's test the output with
3:07
slider the count variable is
3:09
incrementing every 500 milliseconds so
3:12
the while loop is working
3:14
normally let's move the slider now you
3:18
can see the value variable is more
3:20
responsible now the value is increasing
3:24
as we are moving the slider towards the
3:27
end the interrupt is working fine but
3:30
this is not the way to do it we do not
3:33
need to start the ADC each time the call
3:37
called instead we can just enable The
3:39
Continuous conversion mode Let's browse
3:43
down to the ADC initialization code and
3:46
here change it to enable now the
3:48
continuous conversion is enabled so the
3:51
ADC will automatically start the next
3:53
conversion as soon as the first one is
3:56
finished since we are using only one
3:58
channel the same channel will keep
4:02
continuously I have disabled this
4:04
function here so let's test the project
4:07
again the breake point is hitting again
4:10
again that means the interrupt is
4:13
continuously let's remove the breake
4:15
point and run the debugger again we will
4:18
now test it with the slider you can see
4:21
the value variable is changing as for
4:24
the slider's movement so the ADC is
4:27
working fine in the interrupt mode all
4:29
also the conversion is taking place in
4:32
the background and the while loop works
4:35
as usual now keep in mind that if the
4:38
ADC clock is very high the interrupt
4:40
will trigger at a higher rate and this
4:43
might make the while loop
4:44
unusable to prevent this make sure that
4:47
the ADC clock is at a reasonable
4:51
frequency now we will see the use of
4:54
dma using dma for a single channel is
4:57
useless as the conversion complete
5:00
interrupt will trigger at the same rate
5:03
mode so basically we do not have any
5:07
advantage I will demonstrate how to use
5:10
anyway we need to enable the dma so open
5:14
the Cub MX again now go to the dma
5:20
dma we want to enable the dma for adc1
5:24
the direction is from peripheral to
5:26
memory and the dma priority is low
5:30
select the dma mode to Circular and make
5:33
sure the data width is half word if you
5:35
have selected the resolution higher than
5:38
Bits the circular mode allows the dma to
5:41
continuously request the data whereas in
5:43
the normal mode the dma will request the
5:46
data only once and we need to start the
5:48
dma again for another
5:51
request we also need to change the data
5:56
also here we have the option for oneshot
5:58
dma mode mode which is used when we want
6:01
to receive the data using dma only
6:04
once whereas in the circular mode the
6:07
dma will continuously request the data
6:11
ADC the circular mode is used along with
6:14
the dma circular mode we have another
6:17
option available in the f44 6 re for the
6:21
same here you can see the image showing
6:24
the configuration for the F
6:27
446 we have the option for continuous
6:31
request so if you want to enable
6:34
continuous data reception this must be
6:37
enabled we do not have any option in the
6:40
f103 C8 so we will only enable the
6:43
circular mode and the data reception
6:47
automatically let's enable this
6:49
continuous conversion mode as it is
6:51
needed for continuous data
6:54
reception that is all we need to
6:56
configure click save to generate the
7:00
in the main function instead of the
7:02
interrupt mode Let's Start the ADC in
7:05
the dma mode in the dma mode we need to
7:09
provide the array where the converted
7:11
Channel data will be stored let's define
7:14
a 16-bit array of 10 Elements which is
7:17
basically 20 bytes in
7:19
size since we are using a single Channel
7:22
we will request the data for one element
7:26
once the data is transferred by the dma
7:29
it will Trigg trigger the conversion
7:30
complete interrupt just like the
7:32
interrupt mode did we can also request
7:35
the data for all the 10 elements in case
7:38
of a single channel the dma will receive
7:41
the data for 10 elements from the same
7:43
channel and it will then trigger a
7:45
single interrupt for all 10
7:47
elements we don't need the get value
7:50
function as the converted data is
7:52
already stored in the array the received
7:55
data is stored in the zeroth element of
7:58
the array so we use it to map the value
8:02
range we have got a warning here and
8:05
that is because the array is defined as
8:07
16 bits while the function expects a
8:11
variable let's typ cast it to the 32-bit
8:15
pointer all right let's debug this
8:19
project you can see the zeroth element
8:21
of the ADC value is varying as the dma
8:24
is continuously updating the data in it
8:28
the count variable is incrementing every
8:30
500 milliseconds so the while loop is
8:33
working fine as well now we will move
8:37
slider the value variable is updating as
8:41
expected the slider is on the extreme
8:44
right and the value is
8:46
100 now the slider is on the extreme
8:49
left and the value is zero so the dma
8:53
reception is working fine
8:55
also let me quickly show what happens
8:58
when we receive the data for all the 10
9:01
elements we can take the average of all
9:04
the 10 elements and then feed the result
9:07
function but I will leave it as it is
9:11
you can see all the elements of the
9:13
array vary in the similar manner the dma
9:16
mode is more useful while converting
9:18
multiple channels and we will see it in
9:22
videos the rest of this video is
9:25
exclusive to the cortex M7 based MCU
9:29
while using the cortex M7 based MCU we
9:33
must enable the instruction and data
9:35
cache it is recommended by the street as
9:39
using these cache improves the system
9:42
overall the cache configuration is
9:45
available in the cortex M7
9:48
section now we know that when it comes
9:50
to Cache the dma does not operate as
9:53
usual we will first see what issues
9:56
there will be and then how to solve them
9:58
using different methods
10:00
available so I have only enabled the
10:03
cache the rest of the code is still
10:06
unchanged let's build and debug the
10:09
project now you can see that the ADC
10:13
value array is not updating at all the
10:16
count variable is incrementing as usual
10:19
so the while loop is working fine the
10:22
break point inside the call back
10:24
function is continuously getting the hit
10:26
that means the interrupt is triggering
10:28
at the usual ual rate it's just that the
10:32
data is not being updated and this is
10:36
coherency it will always happen whenever
10:38
you try to use the dma with cach
10:41
enabled I have already discussed it in
10:43
my mpu related videos which you can find
10:49
playlist these videos discuss the issues
10:52
and how to resolve them you must check
10:55
out these videos if you are using or
10:58
planning on using a X M7 based MCU
11:02
anyway I will summarize the solution
11:04
here quickly we need to invalidate the
11:07
cache in the region where the ADC value
11:09
array is located to do so we will first
11:13
relocate this array to some other memory
11:16
location this can be done by using the
11:18
section attribute we need to Define this
11:22
ADC array section inside the flash
11:25
script here I am relocating it to the
11:27
address 30 million hex it is basically
11:47
D2 all right let's build the project
11:50
once there seems to be some error in the
11:56
relocation actually there should have
11:58
been spaces here here all right
12:00
everything seems fine now once you click
12:04
on the main file you can see the ram D2
12:06
is now occupied with 20 bytes if you
12:10
check the memory detail you can see that
12:12
the array has been relocated to the ram
12:15
D2 now the first method to deal with
12:18
this issue is that we invalidate the
12:20
cache each time before the dma transfers
12:23
the data we don't have an issue of data
12:25
loss in case of the ADC so I will just
12:28
invalidate the cache here call the
12:31
function invalidate data cache by
12:33
address and pass the address of the ADC
12:35
value array and the size of the array in
12:38
bytes note that the cache must be
12:41
invalidated before the dma transfer
12:43
starts but since data loss is not an
12:45
issue in ADC we can afford losing the
12:48
First Data value you can see the ADC
12:52
value array is now updating as it should
12:56
if we move the slider the value variable
12:58
is Al changing according to the slider's
13:02
movement so the dma is now able to
13:04
transfer the data while the cache is
13:08
enabled there is another method to deal
13:10
with the cache where we can use the mpu
13:13
to set the memory region
13:15
non-cashable let's open the cube MX and
13:18
open the cortex M7 section again enable
13:22
the mpu with privileged access only
13:26
enable the mpu region and set the base
13:29
region address same as where we located
13:31
the ADC value array the ADC array is 20
13:35
bytes in size but here we have a minimum
13:38
size available as 32
13:40
bytes so let's set 32
13:43
bytes set the access to All Access
13:47
permitted disable the instruction access
13:50
enable the sharability permission
13:52
disable the cacheability permission and
13:55
disable the buffer ability
13:57
permission that is all for the mpu click
14:00
save to generate the project I have
14:03
commented out the invalidate cache
14:05
command so now we are completely relying
14:09
configuration here you can see the mpu
14:12
related code has been generated at the
14:14
end of the main file all right let's
14:17
build and debug the project
14:23
now you can see the ADC value array is
14:26
updating as usual so the dma is working
14:30
fine again with the cache being enabled
14:33
this is it for the video I hope you
14:36
understood how to use the interrupt and
14:38
dma to read a single channel of the ADC
14:42
we will continue the series in the next
14:44
video where we will start reading the
14:46
multiple channels of the same
14:48
ADC that is it for today you can
14:52
download the project from the link in
14:54
the description leave comments in case
14:56
of any doubt keep watching Ing and have