How to Build and Configure a CAN with S32K to Emulate Automotive Body Control Infrastructure

Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to Build and Configure a CAN with S32K to Emulate Automotive Body Control Infrastructure

NXP Employee
NXP Employee

This article shows how to configure an CAN bus nodes with NXP's Model-Based Design Toolbox. The application show how you can easily mix together various communication protocols like CAN, I2C and UART to achieve a complex setup that allows to read the temperature from a remote sensors, convert that data into a CAN message, sent it via CAN bus, decode the information and display it's variation in time using a host PC application.


Nowadays the market faces an abundance of cost effective micro-controller solutions that are reliable, performant and integrates various functionalities of the shelf, making easier than ever to prototype complex applications. One of such solutions is the NXP’s S32K scalable family of AEC-Q100 qualified 32-bit ARM Cortex-M4F and Cortex-M0+ based MCUs targeted for general purpose automotive and high reliability industrial applications.


NXP’s S32K144EVB Development Kit is one of the choices that puts in your hands a small form factor, low cost (US$49) and feature-rich platform which can prove to be a perfect development system for quick application prototyping and demonstration.

Fig. 1: S32K144EVB's main features

The main component of this development platform is the S32K144 MCU that integrates in a single SoC a 32bit Cortex M4F core capable of running at 112MHz with 512KB of Flash memory and 54KB of RAM. Dedicated hardware peripherals and a large collection of IP communication blocks makes this MCU a suitable candidate for various industrial and automotive applications.


In today’s fast growing complex than ever automotive market these is a lot of interest in various modules capable to control and coordinate multiple functionalities. Such microprocessors need to be flawlessly integrated within the cars various computing domains and must be ultra-reliable when operating in a such harsh environment.

Fig. 2: A typical vehicle distributed control architecture and places where S32K is a perfect match

NXP’s S32K product families are specifically designed to address all these aspects, and to demonstrate how easy it is to build complex applications let us consider a typical use case that maps over a distributed automotive Body Control Module domain as the one shown in Fig. 2.


Let us suppose we wish to implement a distributed network of sensors that read data from key points, process and aggregate those data and ultimately sent them via CAN bus to a gateway that informs the upper layers.


We can easily prototype such scenario in a couple of minutes with NXP’s S32K development boards and NXP’s Model-Based Design MATLAB toolboxes.


For the hardware setup, two S32K144EVB development boards are used. These are connected through CAN bus (both on CAN0 instance available directly on the board via J13 connector) and supplied with a 12 volts external power supply due to the CAN transceivers power requirements. The one which acts as CAN node-SLAVE has an Si7021 temperature sensor, connected on FlexIO I2C protocol using PTD0 GPIO as I2C SDA and PTD1 GPIOI as I2C SCL communication lines.  A CAN sniffer was also added to catch some packets over the network.


The real hardware setup with the main components and layout is shown in Fig. 3.

Fig. 3: CAN-bus network used to emulate a car body control module

The main components of the setup are:

  • Two S32K144EVB development kits which are configured to act as MASTER (1) and SLAVE (2). The boards are supply with 12V (6) and connected via a PC via microUSB (7) for program loading and debugging during development phase;
  • One Si7021 temperature sensor that support I2C communication protocol is connected with the SLAVE (2) via FlexIO I2C peripheral;
  • CAN (5) network that interconnects the two boards, allowing to pass control and data messages;
  • CAN sniffer (4) that acts like a diagnostic tool;


The application is developed using NXP's Model-Based Design Toolbox for S32K14x which allows the user to directly generate and download the application to the actual hardware from MATLAB/Simulink.

The approach we chose for the data exchange protocol is based on the following concepts:

  • The CAN node-MASTER sends periodically (every 0.5 seconds) over CAN bus a message with the ID 0x3FF to trigger a new data acquisition;
  • The CAN node-SLAVE receives the message and if the ID matches it will initiate a temperature measurement routine. This measurements is done via I2C communication protocol with a dedicated temperature sensor;
  • After acquisition is completed, the node-SLAVE sends back a CAN message with the ID 0x3FE containing in the first 4 bytes a “timestamp” (an uint32 variable that increments every main loop) and the temperature value (floating point conversion in deg C of the temperature read from the actual sensor)
  • The verification is done on the PC side by using the FreeMASTER which is connected over the UART interface with the CAN node-MASTER and configured to show the values received over the CAN bus. The FreeMASTER is used in case no CAN sniffer is available

Part A: CAN node-SLAVE Programming

The job of the SLAVE board is to measure the temperature from the sensor and to send the values via CAN bus to the MASTER board that acts like a gateway. The Simulink model used to receive/transmit CAN messages and data exchange with the sensor via the I2C protocol over FlexIO is shown below.

Fig. 4: Simulink model for the application running on the SLAVE board: It implements 2 communication protocols: CAN and I2C

This model implements three basic functionalities:

  1. Reading data from sensor
  2. Handle the CAN receive messages
  3. Handle the CAN transmit messages

A.1. Reading Data From Sensor

The temperature sensor uses I2C protocol for exchanging the temperature values. To achieve that, the FlexIO peripheral must be configured by adding a FlexIO_I2C_Master_Config block.

A standard I2C peripheral can be used to implement the communication with the sensor. To demonstrate the capabilities of the S32K144 we choose to use the FlexIO peripheral since it can be configured in multiple way to extend the functionalities of standard communication ports.  


The instance 0 of FlexIO peripheral is configured to run in the polling mode with a communication baud rate of 400 kHz and as dedicated communication lines: PTD0/PTD1 general purpose input/outputs pins selected to implement SDA and SCL I2C functionalities. 

Fig. 5: FlexIO peripheral configuration

When the temperature acquisition is needed, the S32K144 acts as an I2C master and sends a packet consisting of command “227” (0xE3) to the device with the address  “64” (0x40)  and “Stop bit” by using

FlexIO_I2C_Master_Transmit block.  The temperature sensor responds on I2C bus with two bytes of “raw” temperature, therefore a FlexIO_I2C_Master_Receive block need to be configured to wait two bytes from the address “64” (0x40) like in Fig 6. Also, a block that converts the data from “raw’ temperature in Celsius degrees is added.

Fig. 6: FlexIO I2C communication between S32K144 and Si7021 temperature sensor

If you want to read more about using  FlexIO MBDT blocks please read the following article at this link: [FlexIO] Flex your muscles with the latest MBDToolbox release 


A.2. Handle the CAN receive messages 

To receive and transmit data over the CAN bus, a FCAN_Config block must be added in the model. The settings are very generous because it offers to user the possibility of using in addition of standard settings some advanced options like enabling CAN FD, RX FIFO (the board can filter which messages to receive) and also Pretended Networking (some messages can also wake up the processor from sleep state).


For this example we are going to use the CAN0 instance in normal mode with a maximum of 16 message buffers as in Fig. 7.

Fig. 7: CAN peripheral configuration

To receive a CAN message, the CAN receive interrupt must be armed using the FCAN_Receive block like in the Fig. 8. The “Once” flag variable was used because the next interrupt will be armed inside the sub-system called by the Rx complete interrupt trigger.

Fig. 8: CAN receive message handling

When a message is received, it triggers the RX_Complete_Event. The only point of interest is the message ID because a message from the 0x3FF (node-MASTER) means a starting conversion. If the address is 0x3FF the Red LED is toggled, the RX ISR is rearmed and “flag” variable is set, for later start measuring the temperature and send the value over CAN bus.

Fig. 9: Get CAN message on an interrupt

A.3. Handle the CAN transmit messages 

Once the “flag” variable has been set in the RX_Complete_Event, the temperature information received from the I2C sensors is saved in the “temperature” variable so it is ready to be sent to the master node (0x3FE).  


For that a FCAN_Send block is configured like in the Fig. 10. The block requires an 8 byte pack of data (“timestamp”  and “temperature”) and a data length which is a Constant of value “8”.

Fig. 10: CAN transmit message

Part B: CAN node-MASTER Programming

The job of the MASTER board, is to send periodically (every half second) a message to the slave and to handle receive back of the temperature over CAN bus. Also, the CAN node-MASTER can responds to a FreeMASTER queries. The node-MASTER Simulink model that implements these functionalities is shown in Fig. 11.

Fig. 11: Simulink model for the application running on the MASTER board: It implements 2 communication protocols: CAN and UART

The CAN on the board that acts like node-MASTER needs to be configured with the same bus settings as the slave board. Sending data is done in the exactly same way as for slave. The only difference here, is that a TX_Complet_ISR block was added for calling an sub-system when the packet has been sent. This allows us to toggle the blue LED as an additional indication for message transmit.

Fig. 12: CAN transmit message to trigger temperature acquisition on node-slave

The MASTER and SLAVE are receiving CAN bus messages in a similar way using same type of Simulink blocks - arming once the trigger and then calling a sub-system from the FCAN_ISR block. The only difference on the node-MASTER side is that this time we really want to process those 8 bytes received as message payload, therefore we need to call the RX_Complete_Event sub-system using the ID and Data received as arguments.  The ID is checked and the Data is unpacked in the time-stamp and temperature variables.

Fig. 13: Handling the incoming CAN messages on node-MASTER


Once the models are completed and the generated code is downloaded on each the devices there are at least 2 simple ways to check the correct functionality of the master-slave CAN application on S32K144.

The first method is based on FreeMASTER tool that can be configured to read the data out of the node-MASTER via the UART interface. As it can be seen from Fig. 14, the measured temperature is about 26 degrees Celsius and the time-stamp is continuously increasing.

Fig. 14: Checking the application with FreeMASTER over the UART interface.

The second method that might be more expensive is based on the existence of a CAN-Sniffer. In our case we used an IXXAT can to usb converter to check the messaged on the CAN bus. This device is mainly used for debugging the CAN bus by sniffing the exchanged messages on the bus. In the Fig. 15, it can be seen “ping-pong” of messages between master (x3FF) and slave (3FE) at specific time intervals.

Fig. 15: Checking CAN messages with dedicated hardware sniffer

We hope you find this information useful. Feel free to LIKE this article and comment below.

The models used in this article are attached below.

Labels (1)
9 Replies

Contributor II

constantinrazvan.chivu‌ Amazing topic.
Thank you for posting such a helpful tutorial!

I have been trying to use the same tutorials with two different NXP EVB. The first is S32K144 and the second is S32K148. In order to adapt the model, I did the following changes.
1: Changed the Block's libraries-link to the new NXP library.

2: Changed the MBD_S32K14x_Config_Information to match different boards.

3: Changed the FCAN_Config to match different boards.

4: Changed the LED outputs to match different boards.

The model is not performing as expected in the tutorial and since I don't have a CAN sniffer, I find it difficult to debug the code.

Kindly find attached the updated/edited master (S32K148) and salve (S32K144) models. Can you help me figure out where the problem is?

Much appreciated.


0 Kudos

Contributor III

Very nice topic!

Is there an example on how to send 2 different messages in different time base?


0 Kudos

NXP Employee
NXP Employee


Are you looking for a way to send one CAN message at some frequency and another CAN message at a different frequency? 

If yes, then you have 2 options to do this:

- first, a software approach where you are using a soft-timer as a scheduler - more explained by gramirezv‌ in this article ((How-to) Multitasking on S32K144 MBDT Simulink )

- second, a hardware approach where you are using a timer to do the scheduling for you

If you have 1 timer free on your board, that would be the way to go and just default to the software timer if you have none that you can use. 

The implementation would be easy:

- get 2 timer blocks (LPIT) and generate an ISR at the desired periods (while having CAN Send in the respective ISRs) - here you can control the period from the LPIT settings


- get 1 timer block to trigger 1 CAN Send, and leave the other in the main loop (not inside another ISR) - here you can control the period by setting the fixed step value

Kind regards,


Contributor II

Hi, this tutorial is amazing!

I am new to simulink and I wanted to use an I2C sensor which is not FlexIO. What configuration settings are needed for something like that.

Is there an article that explains it?

Thank you

NXP Employee
NXP Employee

Hello siddharthpimprikar‌,

Thank you for your appreciation!

Let me clarify some things first: I2C is a protocol that allows the serial data connection between many devices with unique 7 bits addresses over just 2 wires SDA/SCL while FlexIO is an adaptable peripheral on our S32K, which supports a wide range of protocols like UART, I2C, SPI, according to the user’s needs, so there should be no problems connecting your I2C sensor using our FlexIO peripheral.

In the above article, the section A.1 describes how to read data from a sensor, using PTD0(SDA) and PTD1(SCL) as I2C lines, how to address your sensor and how to get data from it, but obviously, you should read your sensor’s datasheet, which can tell you more about the configuration settings you need.  

For more information about FlexIO, we recommend you to read constantinrazvan.chivu's article [FlexIO] Flex your muscles with the latest MBDToolbox release and the “Chapter 51 Flexible I/O (FlexIO)” from the S32K reference manual.

What we recommend you to do is to download and install our toolbox, in which you will find more other examples of I2C communication.

Good luck, 


Contributor II


Thank you this was helpful!

I am using a lux sensor( calculating the actual value from the raw value is slightly tricky here). 

But I have understood the procedure better.



Contributor I


I am also trying same kind of sensor. can you help me for reading any i2c slave device using s32k142 board. 




0 Kudos

NXP Employee
NXP Employee

Hello @vaibhav_n,

The approach is the same on the S32K142 board. The only difference is that you have to identify the right pins and the right address of the sensor.

Which sensor are you trying to use?

Hope this helps,


0 Kudos

Contributor I

Thanks for the reply. i am using APDS9300 ambient light sensor. 

0 Kudos