0:09
hello and welcome to controllers tech
0:13
before i start this video i would like
0:15
to apologize for the video quality
0:18
actually i lost my originally recorded
0:21
file and now i only have this 720p
0:24
extracted version of it
0:26
it is still watchable and anyway i will
0:28
add the commentary at each step so it
0:31
shouldn't be a big trouble
0:33
let's continue with the video now
0:36
we have already talked about the can
0:38
protocol and we have seen some examples
0:40
of how it actually works
0:43
if you haven't seen those videos yet i
0:45
would advise you to watch those videos
0:49
the link to the playlist is in the
0:53
today in the video we will talk about
0:55
the fd can or flexible data rate can
0:59
as the name suggests it's an upgrade
1:01
over the regular version of the can
1:05
i am not going to talk about what f d
1:07
can is or how it is different from the
1:09
simple can or what's the use of it
1:12
i am sure there are plenty of videos on
1:15
this topic rather this video is more
1:17
focused on the stm32 part about the
1:20
configuration and how to start
1:24
this video will cover the loopback mode
1:26
as there is a lot to explain in the
1:28
configuration section also
1:31
later we will move to the normal mode
1:33
where we will communicate between 2
1:35
devices using the fd can
1:38
all right let's see the document
1:40
provided by sd for the fd can it is
1:46
this here is the can fd format
1:49
by the way the major advantage of using
1:51
the f-d-can is we can send up to 64
1:54
bytes of data instead of 8 bytes in the
1:58
also we can transfer relatively smaller
2:01
data at a higher rate compared to the
2:08
here you can see the difference in the
2:10
data frame between the can 2.0 and the
2:15
things are almost similar with a little
2:18
bit of addition in the control field
2:21
you can read this document to understand
2:25
one additional and important thing we
2:28
have in ft can is the ram
2:31
basically all the messages filters and
2:34
some other memory things are all stored
2:37
so if your controller has more than one
2:39
fd can instance you have to share the
2:42
ram between them and to do that you need
2:44
to define the regions for both instances
2:48
but in today's tutorial we are only
2:50
working with the loopback mode and
2:52
therefore we will be using only one
2:56
so we don't need to worry about the ram
2:58
for now but we will see this in some
3:00
other tutorial where we will actually
3:02
look at how to partition the ram for
3:06
next comes the filters
3:08
the fd can have four different types of
3:12
during configuring the filters we come
3:14
across the two very important parameters
3:17
the folder id1 and the filter id2
3:21
all the different types of filters
3:23
consider these parameters in their own
3:27
the range filter will filter all the
3:29
messages from the identifiers which are
3:31
in the range provided by the id1 and id2
3:36
the dual id filter will filter only the
3:38
messages from the 2 identifiers that is
3:44
leave the third one for now we will talk
3:48
the fourth is the mask filter which is
3:51
similar to what we used in the can
3:52
protocol and id1 will act as the id and
3:56
id2 will act as the mask
3:59
note that i used the term filter the
4:01
data rather than accept the data
4:04
this is because whether the filter
4:06
messages should be accepted or rejected
4:08
can be controlled in the software
4:11
after filters we have the reception
4:15
we can receive data in the rx fifo zero
4:18
or fifo 1 just like we could in the can
4:23
also each r x fifo can store up to 64
4:26
elements and each element can store up
4:32
additionally we have the dedicated rx
4:36
there are up to 64 rx buffers available
4:39
and each buffer can again store up to 64
4:44
then we have the t-x buffers and t-x
4:46
fifo to send the data
4:49
there is a lot here and if you want
4:51
further information you can read this
4:58
there are different test modes available
5:00
for the fd can but we will be focusing
5:03
on the external loopback
5:08
mode in this mode the rx pin is
5:12
connected to the tx pin internally but
5:14
the data is still available on the tx
5:16
pin so if you want to see the output in
5:18
the oscilloscope this is what you should
5:25
on the other hand in the internal
5:27
loopback mode the tx pin is disconnected
5:30
from the fd can so to keep the external
5:33
system unaffected while you test this
5:37
in both the modes the rx pin is
5:40
disconnected from fdcan
5:43
i am going to use the external loopback
5:45
mode in this video but you can also use
5:48
the internal loopback
5:50
so let's start with the cube id and
5:53
we'll create a new project
5:58
today i will be using the h745
6:01
controller as this is the one which has
6:04
the fd can give some name to the project
6:15
in the meantime let's take a look at the
6:28
and you can see the pins p h 13 and p h
6:31
14 are the tx and rx pins
6:35
they're connected to the transceiver
6:37
which is already there on the board
6:41
mcp2562 fd is the transceiver used on
6:44
the board i have and therefore i don't
6:46
need to connect the external module to
6:50
if you don't have it you need to connect
6:52
it externally just like we did it in the
6:57
and we have a terminating resistance
7:00
along with the jumper and finally here
7:03
are the output pins on the board where
7:05
pin 1 is connected to can high and pin 2
7:08
is connected to can low
7:10
all right let's clear the pin out first
7:16
now we will enable the clock and i am
7:19
going to use the internal clock today
7:22
i generally don't use it but you will
7:25
see in a while why i'm insisting on
7:27
using the internal clock
7:29
i am leaving everything as it is with
7:31
the input clock of 64 megahertz
7:37
in the connectivity section we will
7:39
enable the fdcon1 for the cortex m7
7:43
before we configure this let's make sure
7:47
here pb9 is selected as the tx pin by
7:50
default and ph 14 as the rx pin
7:55
but according to the schematic the t-x
8:00
so i am going to change the t-x pin to
8:04
alright we have the p-h-13 as the t-x
8:07
pin and p-h-14 as the rx pin
8:11
now we have the configuration part and
8:14
if you notice this does not look like
8:16
what we did in regular can
8:19
there are a lot of additional things but
8:21
we will take a look at them all
8:24
first let's see the frame format
8:28
the canofd is backward compatible with
8:30
the regular can and if you wanted to use
8:32
it as the regular can you select the
8:36
we're going to use the fd mode without
8:41
let me explain this bit rate switching
8:44
basically it allows you to have
8:46
different bit rates for the arbitration
8:48
phase and the data phase
8:50
so the arbitration field will be
8:52
transmitted at the standard bit rate
8:54
throughout the can bus but different
8:56
devices can transmit data at different
8:58
speeds depending on the requirement
9:01
i will keep the arbitration and data at
9:03
the same bit rate so i am choosing the
9:06
one without the bitrate switching
9:08
now comes the mode we are using the
9:13
enable the auto transmission and disable
9:18
all right now comes all these weird sets
9:22
we need to use some calculator for this
9:25
and therefore here is a website for the
9:28
i will put the link to all these
9:30
documents in the description
9:33
so here you can choose like we're
9:35
configuring the f d can
9:38
we have the three inputs here
9:41
first one is the clock frequency and
9:43
this is the clock at which the can
9:45
peripheral is running
9:47
then the clock tolerance and this is the
9:50
tolerance of the actual input clock in
9:54
and the third is the node delay which is
9:57
the sum of input and output delay of the
10:00
you can find it in the data sheet of the
10:02
transceiver you're using
10:05
the board i am using has this particular
10:09
this is mentioned in the schematic of
10:13
all right let's start with the first one
10:16
you can find this in the clock
10:18
configuration and as you can see here
10:21
the input clock to fd can is 50
10:25
this frequency needs to be in kilo hertz
10:30
next comes the clock tolerance
10:33
this is the tolerance of the input clock
10:35
and as you can see in the clock
10:37
configuration i am using the high speed
10:39
internal clock of 64 megahertz
10:43
the reason behind using the internal
10:45
clock was that the characteristics are
10:47
available in the device data sheet
10:51
in the data sheet look for the h-s-i
10:54
oscillator characteristics
10:56
here you can see the h-s-i frequency
11:00
along with the minimum and maximum
11:03
to calculate the clock tolerance we have
11:06
to subtract either of them with the
11:07
typical value and then divide the answer
11:10
from the typical value
11:12
i am taking the max value minus the
11:15
typical value and then divide by the
11:19
now multiply the answer with 100.
11:23
this gives us the percentage tolerance
11:28
but to change it to the parts per
11:30
million we need to multiply this with 10
11:46
the last parameter here is the node
11:50
you can find it from the transceiver
11:53
you have to look for the a-c
11:57
here you can see the propagation delay
12:00
which ranges from 90 to 180 nanoseconds
12:03
depending on whether you are using the
12:05
load resistance or not
12:08
i will take the maximum delay
12:15
now at the can device
12:18
next we need to add the nominal bit rate
12:20
which is the arbitration bit rate and
12:24
as i mentioned earlier i am going to use
12:27
the same bit rate for both here i am
12:29
setting it to 500 megabits per second
12:34
now click recalculate
12:39
we have got ourselves the values that we
12:41
can use in the parameters in cube em x
12:45
let's try to input them
12:54
first we have the nominal sink jump
12:56
width which is s j w under the nominal
12:59
section and the value is 13.
13:07
next we have the data prescaler which is
13:15
one more thing we need to take care of
13:17
is what are the ranges of these values
13:20
like the prescaler can range from 1 to
13:23
32 the sync jump width can range from 1
13:28
if we look at the data t segment or sync
13:31
jump values they are out of the range
13:35
so we cant just input these values like
13:37
this we need to change them
13:40
we will change this sample point in the
13:42
data field to change the data values
13:46
you can see the values are reducing
13:49
all right we got the option to increase
13:53
now the values seem to be in the range
13:57
since we modified only the data bit
13:59
calculations the nominal part is not
14:02
affected by this and only the data
14:06
anyway let's input our new values in the
14:12
the prescaler is 2 the sink jump width
14:14
is 13 and the time segment 1 is 36
14:19
oh we can't have this value higher than
14:23
let's keep increasing the sample point
14:26
i changed the sample point to 75 and the
14:29
prescaler is now 25 and other values
14:33
looks really small too
14:35
so the prescaler is 25 the sink jump
14:38
width is 1 the time segment 1 is 2 and
14:50
all right we are finally done with that
14:54
next comes the message ram offset
14:57
as i explained earlier we divide the ram
14:59
between the different instances of the
15:01
fd can but since we are only using one
15:04
instance let's keep this to zero that is
15:07
to the beginning of the message ram
15:10
next is the number of the standard
15:11
filters and extended filters
15:15
since we are only going to use a single
15:17
standard id for transferring the data a
15:20
single filter is enough for our
15:23
so one standard filter and zero extended
15:28
next is the rx fifo zero element number
15:31
basically how many elements are we using
15:34
for the rx fifo zero
15:37
i have explained this in the beginning
15:39
we are provided with up to 64 elements
15:42
where each element can store up to 64
15:46
i am going to use only one element and
15:48
the size of this element will be 12
15:52
i am choosing 12 bytes because just to
15:55
show you that we can transfer more than
15:57
8 bytes at once which was the limitation
15:59
in the regular can framework
16:02
we are not using the fifo 1 or rx
16:05
buffers or tx events or t x buffers so
16:10
we will use the t x fifo elements as we
16:13
need to send the data to t x fifo in
16:16
order to transfer it via the can bus
16:19
so i am using 1 t t-x fifo element whose
16:22
size is going to be the same 12 bytes
16:27
next is the configuration for nominal
16:33
and the time segments are 86 and 13.
16:37
you can see the baud rate is 500
16:40
megabits the same we set while
16:42
calculating these parameters
16:45
now since we are using the rx fifo to
16:47
receive the data we will also use the
16:52
so go to the nvic tab and enable the fd
16:55
can one interrupt zero
16:58
zero is for fifo zero remember there are
17:01
two fifo fifo zero and fifo one and
17:04
since we are using fifo zero we need to
17:07
enable the interrupt zero
17:10
this completes the configuration click
17:12
save to generate the project
17:15
let me close the main file for the m4
17:18
core and build the m7 project once
17:21
i am not using the m4 core so i am
17:24
disabling all the connections to the
17:28
this is specific to my controller and
17:30
you don't need to do any of this
17:37
all right we will start with filter
17:41
after the ft can has been initialized we
17:44
will set up the filters
17:46
first of all we will define a filter
17:48
typed f for the configuration
17:51
here is the filter configuration i am
17:55
all right let's see this in detail
17:58
first we have the id type which is set
18:01
to standard id this parameter sets the
18:04
type of filter we are using whether it's
18:06
for standard id or the extended id
18:10
next is the filter index basically the
18:12
number of the filter we are using
18:15
since i am only using a single filter
18:20
next is the filter type
18:22
i have explained this in the beginning
18:24
that there are many types of filters
18:26
available in the fd can and here we will
18:29
be using the mask filter
18:31
here you can see the other types of
18:33
filters available such as the range
18:35
filter which filters the data between
18:41
we have the dual filter which only
18:43
filters the id1 and id2
18:46
we have the mask filter which we have
18:48
already covered in the can protocol you
18:50
can see the top right corner for the
18:54
the last one is again the range filter
18:56
but without the extended id mask
19:01
here we are using the mask filter with
19:03
the id as 11 hexa and the same mask bits
19:07
next parameter is the filter
19:11
this is an important one as it
19:13
configures what should be done if the
19:15
filter matches the incoming data
19:18
the options available are filter to rx
19:21
fifo zero or fifo 1 or reject the data
19:26
basically when the incoming data goes
19:28
through the filters and if it
19:30
successfully passes what should we do
19:34
we can send the data to fifo or we can
19:37
reject that data or we can set the data
19:42
we can also send the data to rx buffers
19:45
but in this case the filter types will
19:47
be ignored and all the data passes to
19:52
so we can design acceptance filters or
19:54
rejection filters or even some high
19:57
priority filters to treat some data as
20:02
we can design multiple filters and
20:04
that's why we have the filter index
20:06
which stores a particular configuration
20:08
in a particular filter element
20:11
i have set the filter to rx fifo zero so
20:14
if the data is passed through the filter
20:17
it will be then saved to the rx fifo
20:21
finally we will call the function hal fd
20:24
can filter config to set the
20:25
configuration of the filter
20:35
i am going to use the code similar to
20:37
what we did in the can peripheral so
20:39
here is the main file from the normal
20:41
mode of the convideo we did
20:44
first we will define the tx and rx
20:47
headers along with the t-x and r-x
20:51
since we are using the f-d-can we need
20:54
to change these type def
20:56
also the t-x and r-x data will be 12
21:08
next we have the message pending
21:10
callback that we will see later
21:13
in the main function we need to start
21:18
and then activate the notification for
21:20
the new data so the interrupt will be
21:22
triggered whenever a new data is
21:25
this will eventually call the callback
21:27
function and here we can process the
21:31
we will do the same in our main file
21:35
start the fdcon1 and then activate the
21:37
notification for the new data
21:44
of course the functions are a little bit
21:46
different from the regular can
21:49
here the interrupt flag we are using is
21:51
our x fifo zero new message
21:55
which triggers the interrupt when a new
21:57
message arrives in the rx fifo zero
22:01
by the way the third parameter here is
22:03
the buffer index which is used if you
22:06
are using rx buffers to store data
22:08
instead of fifo so we will keep it zero
22:12
next we have to configure the t-x header
22:14
which will be transmitted along the data
22:18
here are all the parameters we need to
22:22
i have already set them up so let's see
22:24
them first is the identifier basically
22:28
the id of the transmitter which is set
22:33
this is because we have configured the
22:37
next we have the id type which is set to
22:41
as i mentioned before we will not be
22:46
next is the frame type which is set to
22:51
basically it configures whether we are
22:53
sending a data frame or a remote frame
22:57
next is the data length which is set to
23:01
there is this error state indicator
23:06
the e s i bit is the part of the
23:08
arbitration field and indicates if there
23:10
is some error during the transmission
23:14
the bitrate switch is set to off as we
23:18
next is the f d format which indicates
23:21
what type of the can we are using
23:24
the ft can is backward compatible with
23:26
the regular can so if you are using
23:28
classical can or the fd can you need to
23:33
we are not using any t-x events or the
23:35
message markers so they are disabled
23:39
one more thing these parameters just
23:41
indicate the settings we have already
23:43
configured and changing them does not
23:46
change the configuration
23:48
basically t x headers just carry the
23:50
information about our peripheral onto
23:54
now that we have set up the t-x header
23:56
it's time to send the data
23:59
so i am defining a variable index
24:04
and in the while loop i am going to
24:06
store its incremented value in the t-x
24:12
t-x buffer is 12 bytes so each time this
24:16
loop runs the tx buffer should have a
24:21
now we will use the function add message
24:26
as the name suggests it will add the t-x
24:28
buffer to t-x-fifo q and then the data
24:31
in the queue will be transmitted to the
24:35
the parameters are the instance the t-x
24:38
header and the t-x data itself
24:41
let's run this loop every second
24:44
this completes the transmission part now
24:46
we will see the reception part when the
24:49
incoming message successfully gets
24:51
passed through the filter a fifo zero
24:54
callback will trigger
25:03
here we will check if the interrupt was
25:05
triggered by the new message flag
25:08
remember that we activated the
25:10
notification for this flag such that if
25:12
a new data arrives in the rx500
25:15
the interrupt will trigger
25:17
here we will use the getrx message
25:20
function to copy the message from fifo
25:28
the parameters of this function are the
25:30
f d can instance the r x location which
25:33
is basically the r x fifo zero in our
25:35
case the pointer to the r x header where
25:38
the r x header will be stored and
25:40
finally the pointer to the rx data where
25:42
the actual data will be stored
25:45
after receiving the data from the rx
25:48
fifo we will activate the notification
25:52
this needs to be done because the how
25:54
was deactivating the interrupt for me
25:57
if it works all right for you then you
26:00
don't need to do it again
26:02
all right that finishes up everything
26:04
let's build and debug the code
26:08
i have added the t-x and r-x buffers in
26:10
the live expressions
26:13
let's set a break point here before
26:15
copying the r-x message
26:25
so we hit the break point and you can
26:27
see the tx buffer has been populated
26:29
with the values of the index variable
26:32
now this function will copy the data
26:34
from the fifo to the rx buffer so let's
26:39
you can see we got the data into the rx
26:43
let's run it again and now the tx buffer
26:46
has a new set of data and if we step
26:48
over this function the same data gets
26:50
copied into the rx buffer also
26:54
so the tx buffer is transmitting some
26:56
data and through the loop pack the same
26:58
data is received by the rx buffer
27:02
i can't show you the output in the logic
27:04
analyzer as mine doesn't have the fd can
27:08
i hope this was clear
27:11
video was too long but this needed to be
27:15
i will continue this and in the next fd
27:18
can video i will cover the normal mode
27:21
hopefully we will also see the ram
27:25
the link to the code is in the
27:29
leave comments in case of any doubt
27:32
keep watching and have a nice day ahead