This is the fourth article in the Beginner’s Guide series and it aims to showcase how to configure the CAN peripheral to be able to send and receive CAN messages over the CAN Bus using the MR-CANHUBK344 Evaluation Board.
For more details about the MR-CANHUBK344 board or step-by-step instructions on how to run a Simulink® model on it using MBDT, please check out the first article in the series: Interacting with Digital Inputs/Outputs on MR-CANHUBK344.
This article’s application consists of reading digital and analog inputs, processing them before they are sent across the CAN Bus from one CAN instance to another, and then controlling digital and analog outputs based on the received message.
On top of the requirements from the first article, the application that we are developing in this article requires the Vehicle Network ToolboxTM from MathWorks.
In this article we are going to show the messages that are sent across the CAN Bus using a device that can interact with the CAN Bus. The specific model we are using is the PCAN-USB Pro FD.
This chapter will focus on the changes that have to be made in the configuration project in order for the board’s components to communicate properly with each other. It will focus mainly on the CAN-related settings, as the settings for the DIO, ADC and PWM have been explained in the previous articles.
The MR-CANHUBK344 board has 6 CAN instances, with 3 different transceivers among them. CAN0 and CAN1 use TJA1443ATK, CAN2 and CAN3 use TJA1463ATK and CAN4 and CAN5 use TJA1153. Each of the CAN instances has 2 identical connectors, wired to each other, labelled A and B, to allow for daisy chain wiring.
In this article we will focus on communicating between the CAN0 and CAN1 instances.
Note: A CAN bus usually requires 60 Ohm termination at both ends of a CAN bus. This may be accomplished using one of the included CAN Term boards.
For a CAN instance to work properly, the unused connector (if there is one) has to be connected to a CAN Term board, which is included in the MR-CANHUBK344 package.
Below you can find a schematic that shows how the CAN0 instance is connected to its transceiver and how the signals are routed between them:
The pins for the CAN instances can be found by searching for the component name inside the schematic.
For this article’s purpose, I have extracted the necessary pins below. The _RX and _TX pins are linked directly to the CAN instance, while the _ERRN, _STB and _EN pins correspond to the transceiver associated to the CAN instance, like illustrated in the schematic above.
To start configuring the pins, we have to open the Pins Tool, inside the S32 Configuration Tools. To quickly open the configuration project for a model, you can click on the Configure button from the window that appears when double-clicking a MBDT Block. Once the software has opened, clicking the Pins button will open the Pins Tool.
Inside the Pins Tool, we will focus on the top-left window, called the Pins tab.
First, we check if the pin we are trying to add already exists in the configuration by typing the name in the search bar.
Here we can see that no other pin is configured for this purpose (by the lack of green checkmarks in the box to the left).
This has to be done for every of the 12 pins that we are configuring. This process has been showcased in detail in the first article, Interacting with Digital Inputs/Outputs on MR-CANHUBK344.
Here is a case where the pin already exists. The steps that have to be taken in order to remove the old configuration consist of clicking the green checkmark, and then unchecking the currently selected option in the window that pops up.
After checking every pin, we can start adding the ones we want to configure.
Note: CAN_RX, CAN_ERRN are inputs, while CAN_TX, CAN_STB and CAN_EN are outputs. The CAN_STB and CAN_EN are outputs because we will set appropriate values to them to initialize the transceiver by switching it into the normal operating mode, while the CAN_ERRN is an input because it is used to inform the MCU about possible problems that can take place when initializing the transceiver.
To do that, we type the pin’s value in the search bar. As an example, let’s look at some of the pins that we are configuring:
The LED_CAN0 pin is connected to a red LED placed near the CAN connector which is used separately from the CAN, similarly to any other LED on the board. It also shares the same inverted logic as the other LEDs.
It has the corresponding value PTC18, which we type in the filter. Afterwards, we populate the Identifier and Label fields with the pin’s name. Then we click the checkmark to the left and select the appropriate option in the window that shows up. Here, the for the LED we select the SIUL2:gpio,82 option. Since we are configuring an LED, which is an output, we also select the Output option in the window that asks for the pin’s direction.
The process is similar for the other pins, but keep in mind that when configuring the CAN_RX and CAN_TX pins, you have to choose another signal from the list of available signals. Given the difference between the pins we are configuring, the CAN_ERRN, CAN_EN and CAN_STB are connected to the SIUL2 peripheral as inputs/outputs, while the CAN_RX and CAN_TX are connected to their respective CAN peripheral. Here is how that looks for the CAN0_RX pin:
This is how the signals for the CAN0 and CAN1 instances look after being configured:
To be able to see the signals in a similar manner, you can type “CAN” in the search bar of the bottom window, called Routing Details.
Next, we have to return to the Peripherals Tool by clicking the highlighted button.
To start configuring the CAN instances, the first step is to open the Can_43_FlexCAN component and navigate to the CanController tab, inside the CanConfigSet panel.
Here we are going to configure the two CAN controllers that correspond to the CAN0 and CAN1 instances.
The CanController section provides all the necessary settings to configure a CAN controller instance, as required by the application. You can expect to interact with some of them more frequently than the rest, so we are focusing on explaining what these do.
The Name field controls the name that is associated to the controller and it is used to reference the controller in other menus.
Can Hardware Channel controls which physical CAN instance is connected to the current controller.
The Can Controller Activation checkbox enables the Can Controller. Without it, the controller does not function.
CAN Rx/Tx Processing Type enables/disables read and write operations through Can_MainFunction_Read(), respectively Can_MainFunction_Write(), for handling PDU (Protocol Data Unit) events while set to polling. If the parameter is set to POLLING or MIXED, then the functions mentioned will be polling for RX Indication or TX Confirmation. If the parameter is set to MIXED, then only the hardware objects which have the attribute CanHardwareObjectUsesPolling set to true will be affected. Alternatively, if the parameter is set to INTERRUPT,
Can FD ISO controls whether the Flexible Data-Rate feature is enabled on the Controller. In this example, we use the Can FD protocol for communicating between CAN instances so it will be checked.
The Can Controller Default Baudrate field is responsible for choosing which Baudrate configuration to assign to the controller. The Baudrate configuration will be presented in the following screen.
CanCpuClockRef allows you to select the reference clock. For the CAN peripheral, there are 2 clocks available, FLEXCAN_PE_CLK0_2 and FLEXCAN_PE_CLK3_5, covering the CAN0, CAN1, CAN2 and CAN3, CAN4, CAN5 respectively. These clocks can be configured inside the Mcu component, which will be shown in the following chapters.
The Name field is used to select it in the Can Controller Default Baudrate field from the previous screen.
Can Automatic Time Segments Calculation can be used to automatically set the Can Propagation Segment, Can Phase Segment 1 and Can Phase Segment 2 according to the Bitrate and the Can Controller Prescaler.
Can Controller Prescaler sets the prescaler for the controller, based on the Clock selected.
Can Controller BaudRate (Kbps) controls the speed that the data is transferred at.
In the following section, containing Can Propagation Segment, Can Phase Segment 1 and Can Phase Segment 2 you can configure the timings of the CAN transfer.
And finally, in the bottom section you can configure the timings for the Flexible Data-Rate protocol, by changing the Can FD Controller Baudrate, Can FD Propagation Segment, Can FD Phase Segment 1, Can FD phase Segment 2, Can FD Resynch Jump Width and Can FD Prescaler. These can be seen as FD equivalents for the previous settings.
The first section allows you to configure the CanRamBlock associated with the current Can Controller. A CAN controller’s CAN RAM contains CAN hardware objects defined as a PDU buffer. The CAN RAM block can store message buffers in different configurations of sizes.
According to the S32K3XX reference manual, the RAM block can store 32 messages of 8 bytes, 21 messages of 16 bytes, 12 messages of 32 bytes or 7 messages of 64 bytes.
In the second section, CanRxFifo, the RX Fifo can be added or removed. According to the S32K3XX Reference manual, only the CAN0 allows the use of Enhanced RX FIFO. So if you are using another CAN instance and the FD protocol, the CanRxFifo should be disabled duo to the incompatibility between CanLegacyFifo and the FD protocol.
Since this article’s application involves 2 CAN instances communicating with each other, it means that another Can Controller has to be set up besides the one that is already here.
To have a solid starting point for the second Can Controller’s configuration, you can copy the current controller’s configuration and paste it into a new one.
After completing the steps above, you will end up with 2 identical Can Controllers, which will cause conflicts due to duplicate items. To solve this, fill in the details for the second Can Controller.
In this case, that only involves changing the Name, the Can Hardware Channel, the Can Controller ID (which should simply increment) and Can Controller Default Baudrate (the correct one becomes available in the dropdown list after changing the Name field).
The last setting that needs to be changed on this newly created Can Controller is deleting the CanRxFifo, since the CAN1 does not have the Enhanced Fifo feature and we are using the FD protocol at the same time.
The next step is configuring the Can Hardware Objects inside the CanHardwareObect tab, still under the CanConfigSet menu.
Working in a similar manner to the previous subchapter, we will focus on the explaining the options that you can expect to use.
First of all, as a general rule, the RX objects should be placed before the TX objects in the list of objects. So there shouldn’t be any RX object with an ID that is higher or equal to the lowest TX object’s ID.
The Name field controls the name associated to the hardware object that is displayed inside MBDT blocks.
The Can ID Message Type controls whether the can message’s ID type is Extended, Mixed or Standard.
Can Object ID acts as an identifier for the hardware objects. It starts with 0 and should continue without any gaps.
Can Object Type controls whether the hardware object will be used to receive or transmit CAN messages.
Can Controller Reference selects which Can Controller this object is configured for.
Can Hw Object Count defines the number of elements in the hardware FIFO.
The CanHwFilter is used for filtering messages.
The Can Hw Filter Mask determines which part of the filter is active.
The decimal number 536870911 converted to binary is 11111111111111111111111111111 (29 digits). This means that the mask enables the entire filter, since the extended ID format has 29 bits.
The Can Hw Filter Code is the ID that the message would be compared to, based on the filter mask.
Let’s look at the example in the image:
Filter Code: 00000000000000000001111110000 (1008 in decimal)
Filter Mask: 11111111111111111111111111111
Allowed IDs: 00000000000000000001111110000 (1008 in decimal)
This means that the filter only allows messages coming from the extended ID 1008.
If you want the filter to allow more than one value, you have to modify the filter mask in such a way that the filter does not check if every bit is equal to the filter code.
Filter Code: 00000000000000000001111110000 (1008 in decimal)
Filter Mask: 11111111111111111111111111110
Allowed IDs: 00000000000000000001111110000,
(1008 and 1009 in decimal)
In this case, the filter mask allows the last bit to be different from the filter code.
Since the Can Hardware Objects that already exist are properly configured for the CanController_0, we do not have to perform any changes.
But, for the CAN1 to be able to communicate with the CAN0 instance, we have to add a TX (Transmit) hardware object for it.
To do that, click on the highlighted + Button and then configure the object accordingly. As an alternative, you could copy the configuration from CanHardwareObject_Can0_Tx_Interrupt and simply change the fields that are relevant to the CAN1.
This means changing the Name to reflect the correct controller, updating the Can Object ID, making sure that the Can Object Type is set to TRANSMIT, and changing the Can Controller Reference to point towards the CanController1.
After finishing these configuration steps, the CAN0 would be set up to both receive and send messages, while the CAN1 is configured to only send messages.
The CAN Interface is found between the low-level CAN drivers and the upper communication service layers from the AUTOSAR stack. It provides a way to interact with different CAN Hardware device types like CAN Transceivers and CAN Controllers.
Next, the newly created Can Controller (for the CAN1) has to be added to the CanInterface, in the CanIfCtrlCfg section, inside the CanIfCtrlDrvCfg menu.
To add a new CanIfCtrlCfg element, press the + button, and then you have to update the CanIfCtrlId field and choose the right Can Controller for the CanIfCtrlCanCtrlRef.
In order for the CAN instances to work properly, their clock has to be enabled in the McuModeSettingsConf tab, under McuModuleConfiguration, in the Mcu component.
Once on this page, you have to scroll down and verify that the Clocks corresponding to your FlexCAN instances are enabled. By default, they are enabled in this current configuration, but it is important to remember that the CAN peripherals require to have their clocks.
To change the reference clock, CanCpuClockRef, for a set of Can Controllers, you can find them in the McuClockSettingsConfig > McuClockReferencePoint.
The last step in the Configuration Tool is to set up the Interrupts for the CAN instances that we are using in this model so that we can use Interrupt-based blocks. To do that, head to the Platform component, by clicking the Platform button on the left of the Peripherals Tool.
Afterwards, we have to navigate to the Interrupt Controller tab, where we can see all the interrupts that are currently configured.
To configure the CAN instances, scroll down until you see the FlexCAN instances that you are configuring. In this article we use the CAN0 and CAN1 instances, so we are configuring these two instances.
When it comes to FlexCAN interrupts, the FlexCAN0_0 contains 9 general interrupt requests, while the FlexCAN0_1 – FlexCAN0_3 instances contain 96 message buffer interrupts. More details about the interrupt mappings can be found inside the reference manual, S32K3XXRM, by consulting the attached file called S32K3xx_interrupt_map.xlsx.
As you can see, one of them is already configured, so we only have to configure the FlexCAN1 instance as follows:
The Input/Output pins configured previously also have to be configured in the Dio component, similarly to chapter 2.3. from the first article, Interacting with Digital Inputs/Outputs on MR-CANHUBK344.
Now, inside the Dio component, we are configuring the input/output pins that will be used later in the model to enable the transceivers.
Briefly going over the process, we have to remove the default pins that do not match the configuration we are working on. In this situation, it means removing the CanController_0_EN, CanController_0_STB and CanController_0_ERRN channels from the DioPort PTC_H.
Afterwards, we add the Input/Output pins configured previously.
This article’s application involves using the Adc and Pwm components, as well as the FreeMASTER functionality, the way they were configured in the previous articles.
For details on how to configure Uart and FreeMASTER, please refer to the second article, Sending data via UART and monitoring signals with FreeMASTER.
As for the Adc and Pwm configurations, you can find step-by-step instructions in the third article of this series, Controlling LED intensity with ADC and PWM.
For these components, there is no difference from the setups described in the referenced articles.
This article’s application aims to incorporate the previous components into a single example. This application consists of gathering data from two inputs, the ADC potentiometer and the USER_SW2 button, processing it, packaging it and sending it across the CAN Bus, so that it can be received by the other CAN instance and then control two outputs. The two outputs are a Blue LED that turns on according to the USER_SW2 button presses, and a Red LED whose intensity varies based on the rotation from the potentiometer.
The following diagram aims to provide a better understanding for the flow of this application:
Now, let’s break down the model into smaller pieces.
Starting from the top left, the model uses a few variables. These have been grouped based on their purpose. For example, the Channel1 variable from the ADC is responsible for holding the value read from the ADC. Similarly, in the case of the CAN instances, the variables Data and Length represent the message that has been received across the CAN Bus.
The last panel is the most important one, representing the values of the Dio and Aio peripherals right after the CAN message has been unpacked.
Moving on to the Initializations section, this is where we perform the operations needed to prepare the components. In this specific case, we initialize the 2 CAN transceivers by setting 2 of their inputs to HIGH.
In the initialization subsystem, a result buffer is set for the ADC conversion and the group notifications are enabled, so the configured ADC callback would be executed when the conversion on the group finishes.
Finally, we turn the LEDs of the board off since this board uses inverted logic for the LEDs, which means they would normally turn on along with the board.
The FreeMASTER Config block is used for enabling FreeMASTER functionality for this project.
Moving on, there’s one more block to talk about before explaining the active parts of the model, which executes each step and which starts the group conversion for the ADC. Once the conversion is done, the hardware interrupt for the ADC will be triggered and the subsystem linked to the hardware interrupt callback block will output the ADC signal.
The conversion to single data type takes place because the CAN Pack block is configured to accept a floating-point number which represents a voltage between 0V and 3.3V, corresponding to how much the potentiometer is turned.
As specified, we start by collecting data from the inputs, the Aio and Dio. In the case of the Aio, we scale the value to represent the voltage read by the ADC.
To be able to package the data and interpret it after the transfer, we are using a DBC file. DBC is a CAN Database file, which describes what kind of signals will be stored and sent through the CAN message.
Afterwards, the data is then sent to a VNT packing block (VNT stands for Vehicle Network ToolboxTM). By opening the CAN PACK block, we can see that the signals configured in the DBC file have been parsed properly and the block now expects them as an input.
The ADC value will be a 32-bit variable, representing a voltage between 0V-3.3V, while the Dio variable will only have 1 bit, representing whether or not the button is pressed. In total, the variables take up 5 bytes, which becomes the length of the message.
The next block, CAN Unpack, is used to extract the raw data from the CAN Frame, since that’s what will be sent by the CAN Transmission block.
Can_Write is one of the available functions for the Can block and as the name suggests, it’s responsible for sending the CAN Message across the CAN Bus.
The second dropdown item allows the user to select which CanHardwareObject will be sending the data. The items that appear here are the items configured as TRANSMIT in the menu seen in section 2.3.2. In this application, the data is being sent using an interrupt-based hardware object.
The CAN FD Message checkbox selects whether the message being sent is using the CAN FD protocol and the Extended ID CAN Message selects the format for the ID.
These should reflect the settings done in the configuration software.
The second half of the application start with the CAN0 receiving the message sent by the CAN1.
One important thing to note about how this works is that receiving the message is based on the CanIf_RxIndication, which triggers the Hardware Interrupt Callback. Afterwards, we can access the data.
In the Hardware_Interrupt_Handler block, after selecting Can as the Interrupt Group, the following list of Can-related callbacks is made available.
This application requires the ability to read incoming CAN Messages, so the CanIf_RxIndication is used for that purpose. CanIf_RxIndication is a callback which has an interrupt-based execution, being called whenever a CAN frame is received.
Before obtaining the actual values from inside the CAN Message, we have to, once again, use the CAN Pack and Unpack blocks to extract the data and decode it according to the DBC file.
Now that we have the values, we use the ADC value to proportionally change the brightness of the Red LED, and we use the value of the DIO to turn on or off the Blue LED.
To validate the model, we can use the FreeMASTER tool to read and graph the values. As we can see, the received message is made up of 5 bytes of data, which represent the Adc Value and the Dio Value.
Below you can see the variables' representaton on a graph made in real time in the FreeMASTER software. The red signal represents the value read from the potentiometer, situated between 0V and 3.3V. The blue signal corresponds to the state of the button: if the button is pressed, the blue signal will be equal to 1; otherwise the signal will be 0.
On the bottom of the window, you can see the values of the signals at the time the screen capture happened. Apart from the ADC_Received and Dio_Received variables, which correspond to the red and blue signals from the graph, the other variables provide details about the last CAN message received.
By connecting the device capable of reading CAN messages, we can also see them being transmitted through the CAN Bus. Here we use the PCAN-View software application to show the messages captured by the PCAN-USB Pro FD.
After following the steps in the tutorial, you should now be able to include the MR-CANHUBK344 board into applications that require CAN Communications, either between the MR-CANHUBK344 board and a third party, or even between different CAN instances from the same board.
This article’s application also serves as an example on how to manage the workflow of adding multiple MBDT components into a single model.
Simulink is a registered trademark and Vehicle Network Toolbox is a trademark of The MathWorks, Inc. See mathworks.com/trademarks for a list of additional trademarks.