Over 10 years we help companies reach their financial and branding goals. Engitech is a values-driven technology agency dedicated.

Gallery

Contacts

411 University St, Seattle, USA

engitech@oceanthemes.net

+1 -800-456-478-23

S32K144 Peripherals

UART Peripheral in S32K144 MCU

So hello guys, welcome back to NXP Semiconductors S32K144 MCU Tutorial series. In the last blog we had started with S32K144 MCU GPIO Peripheral. In this blog we are going to explore the UART Peripheral. Going to Start with UART peripheral. Objective would be to get.

  • familiarity with UART peripheral for S32K144 MCU.
  • Would be understanding UART peripheral from Hardware point of view in S32K144 MCU.
  • Going to understand then how to use UART peripheral via S32K SDK/uart driver.
  • Would also be demonstrating the uart_echo_pall sketch.

So read along the blog and do tell me its reviews!

Table of Contents

UART Peripheral Theory

UART is a serial communication protocol which is used to interface external sensor & IoT modules to the Host MCU. IoT modules like: GSM Module, GPS Module, BLE Modules, WiFi Modules are connected to Host MCU via UART protocol. Thus, understanding of UART communication protocol and its driver implementation, plays a crucial role.

To know about UART peripheral in theory, viewers can refer to this blog.

LPUART Peripheral in S32K144 MCU

In S32K144 MCU, UART can be used via 2 peripherals: LPUART & FlexIO.

UART in S32K144 MCU

LPUART is referred as Low Power Universal Asynchronous Receiver/Transmitter. LPUART is onchip peripheral only to do UART communication protocol. UART is a serial communication protocol which is done via UART peripheral in the Microcontrollers.

Also, in S32K144, there is FlexIO peripheral through which on-board serial communication protocols like UART, I2C & SPI can be emulated. So, through FlexIO peripheral, also UART peripheral can be implemented. To know about FlexIO peripheral in S32K144, refer to this blog.

Features of UART via LPUART peripheral in S32K144 MCU:

  • LPUART peripheral of S32K144 supports full duplex mode and has NRZ data encoding (That is Logic 1 bit represents High value and Logic 0 bit represents Low value).
  • It has programmable Baud rates(
  • LPUART peripheral supports Interrupts mode, DMA mode or pooled operation mode for transmitting/receiving the data using LPUART protocol or for detecting below listed errors while LPUART communication session is happening:
  1. Transmit data register empty and transmission complete.
  2. Receive data register full.
  3. Receive overrun, parity error, framing error, and noise error.
  4. Idle receivers detect.
  5. Active edge on receive pin.
  6. Break detect supporting LIN.
  7. Receive data match.
  • S32K144 also supports hardware parity generation and checking to ensure the integrity of the data while LPUART communication is happening.
  • It has Programmable LPUART data length of 7-10 bits and LPUART stop bits of 1-2 bits.
  • S32K144 MCU has feature to use the LPUART peripheral to wake up the MCU (if it is programmed in sleep modes), it can be waked up in either of the 3 below mentioned events:
  1. Idle line wakeup
  2. Address mark wakeup
  3. Receive data match.
  • Support of request to send (RTS) and clear to send (CTS) signals, for hardware flow control,  example of hardware flow control is a half-duplex radio modem to computer interface.
  • Support of IrDA 1.4 format with programmable pulse width for IR communication.
  • LPUART peripheral of S32K144 supports independent FIFO buffer for transmission and receiving of Data.
  • Also, LPUART peripheral FIFO of S32K144 has additional features like:
  1. configurable watermark (lowest number of bytes) for transmit and receive buffer, when watermark is achieved corresponding status is changed of LPUART peripheral.
  2. Option for receiver to assert request after a configurable number of idle. 
    characters if receive FIFO is not empty.
  • Tx and Rx FIFO in S32K144 for all LPUART Instances both are of 4 words size. 1 Word is 1 byte(8 bits). So FiFo size is 4 byte long(32 bits).

LPUART Hardware Pinout in S32K144 MCU

LPUART Pinout and Hardware Instances

LPUART peripheral in S32K144 has 3 instances: LPUART0, LPUART1, LPUART2.

All the LPUART Instances has 4 pins: 

  • RX: Receiving of data
  • TX: Transmission of data
  • CTS: Clear to Send pin for hardware flow control.
  • RTS: Request to Send for hardware flow control.
    S32K144 UART Pins

Each LPUART instance supports all the 4 pins, with below mentioned pin details.

How to use LPUART Pins in S32K144 MCU for doing UART Communication?

Now for doing UART communication, we need to connect hardware UART pins of the MCU, for doing so follow the steps:

  1. At first select which instance of LPUART wanna use, once selected. As told above their are 3 instances of LPUART in S32K144 MCU.
  2. Once selected, then use above excel to short select which pin of corresponding LPUART has to be used. 
  3. Lets say we use LPUART1 and use PTC7 and PTC6 as Tx & Rx pins of LPUART.
  4. So connect these pins of MCU with external UART Module.
  5. Remember Tx pin of MCU is connected to Rx pin of external UART Module and Rx pin of MCU is connected to Tx pin of external UART Module.
  6. Here i am going to use USB to serial FTDI connector with Original S32K144 evaluation2 board.
  7. With ElecronicsV2 board, it has on-board UART driver IC at LPUART1 PTC7 and PTC6 pins.

How to configure UART Peripheral in S32K144 using S32 Design Studio IDE

UART Peripheral of S32K144 MCU can be configured using the Peripheral configuration tools of S32 Design Studio. These tools provide us with the GUI interface to configure the UART Peripheral of the MCU. To know in detail about the Peripheral configuration of S32 Design Studio refer to these.

BLE Module interfacing with S32K144 MCU
GPS Module interfacing with S32K144 MCU
WiFi Module interfacing with S32K144
GSM Module interfacing with S32K144

LPUART SDK for S32K144 MCU

LPUART SDK

S32K SDK/drivers provide an easy to use and quick way to use LPUART peripheral in S32K144, which is known as LPUART SDK.

LPUART SDK for S32K MCU’s

Each S32 SDK driver can be configured and enabled to use in the project via S32 Configuration Tool. Will be digging into that part, in next section. For now, let’s understand the LPUART SDK in some detail, so as to use UART peripheral via LPUART.

LPUART SDK files

In the SDK of LPUART there are header files and source files for LPUART Driver and LPUART Interrupt.

  • LPUART interrupt files contains functions for using &configuring of LPUART interrupts and IRQ handler in S32K144 MCU.
  • LPUART driver files contains functions for using/configuration of LPUART Peripheral.

LPUART Driver 

LPUART driver files are further divided into LPUART Peripheral Abstraction Layer (PAL) & LPUART Low-level drivers., as shown below:

LPUART Driver Files
  • LPUART Peripheral Abstraction Layer(PAL): contains functions and variables that are directly used in main.c or application code. And internally these functions use the LPUART Low-level drivers & LPUART IRQ . So if hardware is changed LPUART PAL would remain same and only internal low-level driver files need to be changed or modified. By this way we don’t have make many changes on application level.
  • LPUART Low-level driver: contains functions that configures the LPUART peripheral registers for initializing the peripheral, using the peripheral and processing the data of peripheral at hardware level. These files are the ones which actually interacts with the hardware and make it configurable to our needs. 

In the blogs we will be exploring the LPUART Peripheral Abstraction Layer files (PAL) in more details, as that would be directly used in our application project development(main.c) and driver creation of UART modules (GPS, GSM, IoT Modules and etc)

LPUART PAL

In LPUART PAL there are 2 files lpuart_driver.c and lpuart_driver.h files.

Lets get into these files:

  1. lpuart_driver.h: contains the enums, structures and function declarations that would be used in application code. Only functions which are declared in this header file can be used in main.c or application project.
  2. lpuart_driver.c: contains the function definations of the declared functions(uses the low-level driver functions) along with some static functions also that are restricted to use in this file only.

Functions

How to use LPUART PAL for doing UART Communication in S32K144 MCU.

  1. Features of LPUART PAL.
  2. Initialization and configuration API’s of UART peripheral using LPUART PAL.
  • LPUART_DRV_Init: This function is the first function that has to be used in main.c to initialize the LPUART peripheral. This function is just like Serial.begin(9600) of Arduino IDE environment.
				
					status_t LPUART_DRV_Init(uint32_t instance, lpuart_state_t * lpuartStatePtr,
                         const lpuart_user_config_t * lpuartUserConfig);

				
			

This function has 3 function parametrs as follows:

  1. instance: integer number indicating which instance of LPUART we are going to use.
  2. lpuart_user_config and lpuart_state_t: structure pointers have to be sent in this function as parameters. (For the info on these structures refers next section)
				
					#define INST_LPUART_LPUART_1  1

extern lpuart_state_t lpUartState1;

/* External declaration of LPUART configuration structure */
extern const lpuart_user_config_t lpUartInitConfig1;

lpuart_state_t lpUartState1;

const lpuart_user_config_t lpUartInitConfig1 = {
  .transferType = LPUART_USING_INTERRUPTS,
  .baudRate = 9600UL,
  .parityMode = LPUART_PARITY_DISABLED,
  .stopBitCount = LPUART_ONE_STOP_BIT,
  .bitCountPerChar = LPUART_8_BITS_PER_CHAR,
  .rxDMAChannel = 0UL,
  .txDMAChannel = 0UL
};

 /* Initialize LPUART instance */
  LPUART_DRV_Init(INST_LPUART_LPUART_1, &lpUartState1, &lpUartInitConfig1);
 
				
			

In LPUART PAL their are 3 ways by which we can send and receive data.

  1. Interrupt based
  2. DMA Based 
  3. Pooling Based.

In this blog, we are going to explore and understand pooling based method and it’s API. As to use by interrupt and DMA based, we have to know about Interrupt and DMA. So we are going to cover Interrupt and DMA based LPUART communication under topics: Interrupts in S32K144 and DMA in S32K144 MCU.

What is pooling method in Embedded?

LPUART PAL API’s for doing pooling based communication

  • LPUART_DRV_SendDataPolling
				
					status_t LPUART_DRV_SendDataPolling(uint32_t instance, const uint8_t *txBuff, uint32_t txSize);

				
			

This function has 3 parametrs:

  1. instance: integer number indicating which instance of LPUART we are going to use.
  2. txBuff: buffer pointer, pointing to the data which needs to be send out.
  3. txSize: size of data that has to be sent.
				
					  /* Welcome message displayed at the console */
#define welcomeMsg "This example is an simple echo using LPUART\r\n\
it will send back any character you send to it.\r\n\
The board will greet you if you send 'Hello Board'\r\
\nNow you can begin typing:\r\n"

  
  /* Send a welcome message */
  LPUART_DRV_SendDataPolling(INST_LPUART_LPUART_1, (uint8_t *)welcomeMsg, strlen(welcomeMsg));

				
			
  • LPUART_DRV_ReceiveDataPolling
				
					status_t LPUART_DRV_ReceiveDataPolling(uint32_t instance, uint8_t *rxBuff, uint32_t rxSize);

				
			

This function has 3 function parameters:

  1. instance: integer number indicating which instance of LPUART we are going to use.
  2. rxBuff: buffer pointer, would be containing the received data.
  3. rxSize: size of data that has to be received.
				
					  /* Receive buffer size */
#define BUFFER_SIZE 256U

/* Buffer used to receive data from the console */
uint8_t buffer[BUFFER_SIZE];

LPUART_DRV_ReceiveDataPolling(INST_LPUART_LPUART_1, buffer, 1U);
    
				
			
Data Types

There are 2 structures that are important and will be used often

  • lpuart_user_config_t: This structure has members to configure the LPUART according to user defined settings.
				
					/*! @brief LPUART configuration structure
 *
 * Implements : lpuart_user_config_t_Class
 */
typedef struct
{
    uint32_t baudRate;                           /*!< LPUART baud rate */
    lpuart_parity_mode_t parityMode;             /*!< parity mode, disabled (default), even, odd */
    lpuart_stop_bit_count_t stopBitCount;        /*!< number of stop bits, 1 stop bit (default) or 2 stop bits */
    lpuart_bit_count_per_char_t bitCountPerChar; /*!< number of bits in a character (8-default, 9 or 10);
                                                      for 9/10 bits chars, users must provide appropriate buffers
                                                      to the send/receive functions (bits 8/9 in subsequent bytes);
                                                      for DMA transmission only 8-bit char is supported. */
    lpuart_transfer_type_t transferType;         /*!< Type of LPUART transfer (interrupt/dma based) */
    uint8_t rxDMAChannel;                        /*!< Channel number for DMA rx channel.
                                                      If DMA mode isn't used this field will be ignored. */
    uint8_t txDMAChannel;                        /*!< Channel number for DMA tx channel.
                                                      If DMA mode isn't used this field will be ignored. */
} lpuart_user_config_t;


				
			
				
					/* External declaration of LPUART configuration structure */
extern const lpuart_user_config_t lpUartInitConfig1;

const lpuart_user_config_t lpUartInitConfig1 = {
  .transferType = LPUART_USING_INTERRUPTS,
  .baudRate = 9600UL,
  .parityMode = LPUART_PARITY_DISABLED,
  .stopBitCount = LPUART_ONE_STOP_BIT,
  .bitCountPerChar = LPUART_8_BITS_PER_CHAR,
  .rxDMAChannel = 0UL,
  .txDMAChannel = 0UL
};
				
			
  • lpuart_state_t: This structure has data members, which keep track of the on-going transfers . 
				
					/*!
 * @brief Runtime state of the LPUART driver.
 *
 * Note that the caller provides memory for the driver state structures during
 * initialization because the driver does not statically allocate memory.
 *
 * Implements : lpuart_state_t_Class
 */
typedef struct
{
    const uint8_t * txBuff;              /*!< The buffer of data being sent.*/
    uint8_t * rxBuff;                    /*!< The buffer of received data.*/
    volatile uint32_t txSize;            /*!< The remaining number of bytes to be transmitted. */
    volatile uint32_t rxSize;            /*!< The remaining number of bytes to be received. */
    volatile bool isTxBusy;              /*!< True if there is an active transmit.*/
    volatile bool isRxBusy;              /*!< True if there is an active receive.*/
    volatile bool isTxBlocking;          /*!< True if transmit is blocking transaction. */
    volatile bool isRxBlocking;          /*!< True if receive is blocking transaction. */
    lpuart_bit_count_per_char_t bitCountPerChar; /*!< number of bits in a char (8/9/10) */
    uart_callback_t rxCallback;          /*!< Callback to invoke for data receive
                                              Note: when the transmission is interrupt based, the callback
                                              is being called upon receiving a byte; when DMA transmission
                                              is used, the bytes are copied to the rx buffer by the DMA engine
                                              and the callback is called when all the bytes have been transferred. */
    void * rxCallbackParam;              /*!< Receive callback parameter pointer.*/
    uart_callback_t txCallback;          /*!< Callback to invoke for data send
                                              Note: when the transmission is interrupt based, the callback
                                              is being called upon sending a byte; when DMA transmission
                                              is used, the bytes are copied to the tx buffer by the DMA engine
                                              and the callback is called when all the bytes have been transferred. */
    void * txCallbackParam;              /*!< Transmit callback parameter pointer.*/
    lpuart_transfer_type_t transferType; /*!< Type of LPUART transfer (interrupt/dma based) */
#if FEATURE_LPUART_HAS_DMA_ENABLE
    uint8_t rxDMAChannel;                /*!< DMA channel number for DMA-based rx. */
    uint8_t txDMAChannel;                /*!< DMA channel number for DMA-based tx. */
#endif
    semaphore_t rxComplete;              /*!< Synchronization object for blocking Rx timeout condition */
    semaphore_t txComplete;              /*!< Synchronization object for blocking Tx timeout condition */
    volatile status_t transmitStatus;    /*!< Status of last driver transmit operation */
    volatile status_t receiveStatus;     /*!< Status of last driver receive operation */
} lpuart_state_t;

				
			
				
					extern lpuart_state_t lpUartState1;

lpuart_state_t lpUartState1;

				
			

UART Demo Code for S32K144 MCU

 S32 SDK/provides as example demo on LPUART driver to demonstarate how to use the LPUART driver for UART communicatio protocol. Demo Example is named as: lpuart_echo_s32k144

				
					/*
 * Copyright 2020 NXP
 * All rights reserved.
 *
 * NXP Confidential. This software is owned or controlled by NXP and may only be
 * used strictly in accordance with the applicable license terms. By expressly
 * accepting such terms or by downloading, installing, activating and/or otherwise
 * using the software, you are agreeing that you have read, and that you agree to
 * comply with and are bound by, such license terms. If you do not agree to be
 * bound by the applicable license terms, then you may not retain, install,
 * activate or otherwise use the software. The production use license in
 * Section 2.3 is expressly granted for this software.
 */
/* ###################################################################
**     Filename    : main.c
**     Project     : lpuart_echo_s32k144
**     Processor   : S32K144
**     Version     : Driver 01.00
**     Compiler    : GNU C Compiler
**     Date/Time   : 2020-02-20, 12:27, # CodeGen: 1
**     Abstract    :
**         Main module.
**         This module contains user's application code.
**     Settings    :
**     Contents    :
**         No public methods
**
** ###################################################################*/
/*!
** @file main.c
** @version 01.00
** @brief
**         Main module.
**         This module contains user's application code.
*/
/*!
**  @addtogroup main_module main module documentation
**  @{
*/
/* MODULE main */

/* Including needed modules to compile this module/procedure */
#include "sdk_project_config.h"
#include <stdio.h>
#include <string.h>

volatile int exit_code = 0;

/* Welcome message displayed at the console */
#define welcomeMsg "This example is an simple echo using LPUART\r\n\
it will send back any character you send to it.\r\n\
The board will greet you if you send 'Hello Board'\r\
\nNow you can begin typing:\r\n"

/* Error message displayed at the console, in case data is received erroneously */
#define errorMsg "An error occurred! The application will stop!\r\n"

/* Timeout in ms for blocking operations */
#define TIMEOUT     500U

/* Receive buffer size */
#define BUFFER_SIZE 256U

/* Buffer used to receive data from the console */
uint8_t buffer[BUFFER_SIZE];
uint8_t bufferIdx;

/* UART rx callback for continuous reception, byte by byte */
void rxCallback(void *driverState, uart_event_t event, void *userData)
{
    /* Unused parameters */
    (void)driverState;
    (void)userData;

    /* Check the event type */
    if (event == UART_EVENT_RX_FULL)
    {
        /* The reception stops when newline is received or the buffer is full */
        if ((buffer[bufferIdx] != '\n') && (bufferIdx != (BUFFER_SIZE - 2U)))
        {
            /* Update the buffer index and the rx buffer */
            bufferIdx++;
            LPUART_DRV_SetRxBuffer(INST_LPUART_LPUART_1, &buffer[bufferIdx], 1U);
        }
    }
}

/*!
 \brief The main function for the project.
 \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
 */
int main(void)
{
  /* Write your local variable definition here */
  status_t status;
  /* Declare a buffer used to store the received data */
  uint32_t bytesRemaining;

  /* Write your code here */
  /* For example: for(;;) { } */

  /* Initialize and configure clocks
   *     -    see clock manager component for details
   */
  CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
                 g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
  CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);

  /* Initialize pins
   *    -    See PinSettings component for more info
   */
  PINS_DRV_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);

  /* Initialize LPUART instance */
  LPUART_DRV_Init(INST_LPUART_LPUART_1, &lpUartState1, &lpUartInitConfig1);
  /* Install the callback for rx events */
  LPUART_DRV_InstallRxCallback(INST_LPUART_LPUART_1, rxCallback, NULL);
  /* Send a welcome message */
  LPUART_DRV_SendDataBlocking(INST_LPUART_LPUART_1, (uint8_t *)welcomeMsg, strlen(welcomeMsg), TIMEOUT);

  /* Infinite loop:
   *     - Receive data from user
   *     - Echo the received data back
   */
  while (1)
  {
      /* Receive and store data byte by byte until new line character is received,
       * or the buffer becomes full (256 characters received)
       */
      LPUART_DRV_ReceiveData(INST_LPUART_LPUART_1, buffer, 1U);
      /* Wait for transfer to be completed */
      while(LPUART_DRV_GetReceiveStatus(INST_LPUART_LPUART_1, &bytesRemaining) == STATUS_BUSY);

      /* Check the status */
      status = LPUART_DRV_GetReceiveStatus(INST_LPUART_LPUART_1, &bytesRemaining);

      if (status != STATUS_SUCCESS)
      {
          /* If an error occurred, send the error message and exit the loop */
          LPUART_DRV_SendDataBlocking(INST_LPUART_LPUART_1, (uint8_t *)errorMsg, strlen(errorMsg), TIMEOUT);
          break;
      }

      /* Append string terminator to the received data */
      bufferIdx++;
      buffer[bufferIdx] = 0U;

      /* If the received string is "Hello Board", send back "Hello World" */
      if(strcmp((char *)buffer, "Hello Board\n") == 0)
      {
          strcpy((char *)buffer, "Hello World\n");
      }

      /* Send the received data back */
      LPUART_DRV_SendDataBlocking(INST_LPUART_LPUART_1, buffer, bufferIdx, TIMEOUT);
      /* Reset the buffer index to start a new reception */
      bufferIdx = 0U;
  }

  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

/* END main */
/*!
 ** @}
 */

				
			
lpuart_echo_s32k144 demo code explanation:

Next blogs to read

Automotive Protocols
Rohan Singhal

Introduction to CAN Communication

Table of Contents   Why Was the CAN Protocol Introduced? Let’s start from the basics: why did we need the CAN protocol in the first place? Imagine the electronics in a car before CAN was introduced. Each part of the car’s electronics had to be directly wired to every other part it needed to communicate with. This point-to-point wiring system had some big problems: Too Many Wires: As cars got more advanced, they needed more electronic control units (ECUs) to handle all the new features. Each new feature meant adding more wires, making the system very complicated and heavy. High Costs: More wires didn’t just mean more complexity; it also meant higher costs. Building and maintaining such a complicated wiring system was expensive, and finding and fixing problems in all those wires took a lot of time and money. Hard to Expand: Want to add a new feature to the car? That meant even more wires and changes to the existing setup, which was a real headache. The system wasn’t built to easily handle new additions. Interference Problems: With so many wires, there was a lot of electromagnetic interference (EMI). This interference could mess up the signals being sent through the wires, making the whole system less reliable. Explaining the CAN Protocol The Controller Area Network (CAN) is a robust protocol for connecting electronic control units (ECUs) in vehicles and other distributed systems. CAN was introduced to address the need for a more efficient, reliable, and flexible communication system in automotive applications. Let us explore how CAN works, starting with its fundamental layers. The Physical Layer of CAN The physical layer of CAN consists of a two-wire bus system called CAN_H (high) and CAN_L (low). Data is transmitted differentially, meaning the voltage difference between the two wires represents the actual data. This approach provides excellent resistance to noise and interference, ensuring reliable communication among all nodes on the network. Data Link Layer in CAN The data link layer is responsible for managing the data exchange between nodes on the CAN network. It consists of several key functions: Framing: CAN frames consist of several fields, including the identifier, control, data, CRC, ACK, and end of frame. These fields structure the data and control information for transmission. Addressing: Instead of traditional addresses, CAN uses message identifiers for addressing. Each message has a unique identifier that determines its priority and relevance to nodes on the network. Error Detection: CAN employs multiple error detection mechanisms, such as the Cyclic Redundancy Check (CRC), acknowledgment checks, and form checks. If an error is detected, the erroneous message is discarded, and an error frame is transmitted. Arbitration: When multiple nodes attempt to send messages simultaneously, CAN uses a non-destructive bitwise arbitration process. The message with the highest priority (lowest identifier value) wins the arbitration and continues transmission, while others wait for the next opportunity. Importance of Synchronization Synchronization is critical for the correct operation of the CAN network. To achieve this, all nodes synchronize their clocks at the start of each message transmission and continuously resynchronize throughout the message. This synchronization ensures that all nodes interpret the bit timings accurately and maintain a consistent understanding of the message. Hard synchronization occurs at the beginning of every message. When a node receives the start bit, which is indicated by a transition from recessive to dominant, it aligns its clock with that transition. Resynchronization happens throughout the entire message. As the message is being sent, nodes continually adjust their clocks based on the expected bit timings. If a node detects that a bit transition occurred earlier or later than expected, it adjusts its internal clock to stay in sync with the others. Exploring the Versions of CAN Protocol The Controller Area Network (CAN) protocol has evolved over time, leading to various versions, each offering enhancements over its predecessors. Here, we’ll overview the different CAN versions, with a primary focus on CAN 2.0. Versions of the CAN Protocol 1. CAN 2.0A (Standard CAN) Identifier Length: 11 bits Message Size: Up to 2,048 unique message IDs Data Speed: Typically up to 1 Mbps Features: Standard data frames and error detection mechanism. 2. CAN 2.0B (Extended CAN) Identifier Length: 29 bits Message Size: Up to 536 million unique message IDs Data Speed: Typically up to 1 Mbps Features: Extended identifier field for more complex applications. 3. CAN FD (Flexible Data Rate) Enhanced Data Rate: Supports faster data transmission rates, up to 8 Mbps Data Length: Up to 64 bytes of data per frame Features: Flexible data rate and extended data field for more efficient communication. 4. CAN XL Higher Bandwidth: Supports even faster data rates, exceeding 10 Mbps. Extended Data Length: Capable of handling larger amounts of data Features: Improved protocol efficiency and higher performance for demanding applications Focus on CAN 2.0 While all versions of CAN offer unique advantages, our primary focus will be on CAN 2.0, the foundation of the CAN protocol. CAN 2.0A (Standard CAN) CAN 2.0A FRAME STRUCTURE OVERVIEW 1. Arbitration Field The Arbitration Field is crucial for determining the priority of the message during arbitration: SOF(Start of Frame); 1 bit Determines the starting Identifier: 11 bits Uniquely identifies the message. Lower values have higher priority. RTR (Remote Transmission Request): 1 bit Indicates if the frame is a data frame (0) or a remote frame (1) requesting data. 2. Control Field Reserved bit: 2 bits DLC (Data Length Code): 4 bits Specifies the number of data bytes (0 to 8) in the Data Field. This allows the receiver to know how many bytes to expect. 3. Data Field Data Field: 0 to 8 bytes Contains the message content. 4. CRC Field CRC (Cyclic Redundancy Check): 15 bits For error checking of the Data Field. CRC Delimiter: 1 bit (recessive). 5. Acknowledgment Field ACK Slot: 1 bit (dominant if the frame is received correctly). ACK Delimiter: 1 bit (recessive). 6. End of Frame End of Frame: 7 bits (recessive). 7. Interframe Space Interframe Space: Variable recessive bits. Interframe Space and

Read More »
Peripheral Drivers(Non Autosar)
Kunal Gupta

FlexCAN Peripheral Software Stack Explanation using NXP S32K144 MCU

Overview and motive Objective is to: To get to know what is FlexCAN driver and its features. To Understand How to use FlexCAN Driver(software environment setup and chronology in software configuration)). FlexCAN Driver GUI explanation for configuring FlexCAN Peripheral. Relation of functions of FlexCAN Driver functions via FlexCAN peripheral features. In Depth Understanding of FlexCAN driver functions/data types, with questions like What and why? Chronology of APIs for using basic features of FlexCAN Peripheral for doing CAN communication(How and When?) By basic features we mean the CAN transmission and reception via Mailbox and FiFo mechanism using polling&Interrupt method. What is FlexCAN Driver FlexCAN Driver are set of libraries which are used for using FlexCAN peripheral to do CAN communication via NXP S32K1xx Microcontrollers. Here by library, we mean a set of .h and .c files written in c language. These set of FlexCAN libraries are: Library of FlexCAN Peripheral Hardware registers. Library for FlexCAN Peripheral Interrupt Handlers. Library for FlexCAN peripheral API’s. Miscellaneous files for FlexCAN. Now in FlexCAN Driver there are 3 sets: FlexCAN_Ip.h/.c FlexCAN_Ip_Hw_Access.h/.c FlexCAN IP_Irq.h/.c 3 extra header files: FlexCAN_Ip_DeviceReg.h/FlexCAN_Ip_Types.h/FlexCAN_Ip_Wrapper.h: The first one contains the function and data types through which different features of FlexCAN peripheral are used. Features like of sending data, receiving data, configuring message id filter table and etc. It contains functions like: FlexCAN_IP_Send(). FlexCAN_IP_receive, FlexCAN_IP_RXFIFO and etc. The Second one also contains the functions and data types through which FlexCAN Peripheral registers. Are accessed. Kind of like Bare Metal codes of FlexCAN peripheral are written in this files. And the Functions of this file are used by FlexCAN_Ip.h/.c files. Third one contains the function definition and data types for for IRQ handler of FlexCAN Peripheral And the last one contains the misceeleneours Data types and macros for using flexCAN peripheral. In our application code, we are just going to add FlexCAN_Ip.h header file to access the FlexCAN Driver in our code. And these files are located in the root directory of S32 DS where software installtion of RTD package takes place. FlexCAN Driver and Code Configuration tool relation. Now for using the FlexCAN peripheral, there is a feature of code configuration tool in S32DS via which we can configure the FlexCAN Driver in Gui base. That is instead of writing code, we can confiure how to use FlexCAN Module by GUI presentation. The code configuration tool in S32 Design Studio, generates the set of .c/.h files for FlexCAN peripheral. These are different from library files which I have explained above.  In these generated files it defines and initializes some of the variables. These variables are then used by FlexCAN APIs in the application code. This support of code configuration tool makes it easy for configuring FlexCAN module in easy way via GUI presentation and variables which are generated by code configuration tool are used as parameters in FlexCAN APIs to use them in application code. So, in short to say, code configuration tool generates the values of some of the parameters that has to be send in FlexCAN Driver API. Closure of FlexCAN Driver: There are number of files, functions and data types but for now we are going to concentrate on those which will be required for using FlexCAN in Standard CAN, in normal mode for transmitting and receiving via mailbox and FiFo mechanism. In FlexCAN library there are number of functions and data types through which all the features of FlexCAN peripheral can be used. But we are not going to dwell into all functions and data types. We are just going to cover the functions and data types through which we can send and transmit can data via mailbox/rxfifo mechanisms. As this is the scope of this course and module, for other functions and features you can explore our Advance CAN Courses or can reach out to us privately, Software to install to use FlexCAN Peripheral Driver To use FlexCAN Peripheral Driver, we need to install following things in your Host Desktop/PC: S32 Design Studio IDE 3.4 or 3.5 (any will work though here, we are going to use S32 Design Studio 3.4) S32K1 Real Time Drivers Version 1.0.0 S32 Design Studio 3.4 S32K1 Real Time Drivers Version 1.0.0 S32K1 RTD V1.0.0 is Software Stack for using NXP S32K1xx microcontrollers. It Contains Peripheral Driver library files for using the S32K1xx microcontroller peripherals. It supports all peripherals of S32K1xx MCU’s.  This Software Stack contains 2 packages: Autosaur MCAL layer complaint and standard based peripheral driver files for S32K1xx MCU’s. It is Autosar 4.4.0 complaint. Non-Autosar based peripheral driver files for S32K1xx MCU’s.  It is a collection of peripheral drivers designed to simplify and accelerate application development on NXP microcontrollers. From Learning point of view and long-term skill development, having handson with Autosaur MCAL layer based peripheral driver file would be a good starting point. But as a fresher it might be more challenging to start with autosar standard. So In this blog, we are going to explore Non-Autosar based peripheral driver for FlexCAN module.  Further once having basic Handson with Non-Autosar, will explore Autosar MCAL layer based peripheral driver. Refer to this blog/video to get to know how to install S32 Design Studio 3.4 and Install S32K1 Real Time Drivers v1.0.0. Also it is recommended to explore Code Configuration Tool and Project Creation Modules of S32 Design Studio IDE, so as to get understanding how to use S32 Design Studio throughout the learning cycle. How to use FlexCAN Peripheral Driver FlexCAN Driver can be used via S32 Design Studio Code Configuration tool which provides Graphical User Interface manner in S32 Design Studio IDE, through which we can generate the FlexCAN driver libraries and code automatically in our project. This thing makes it easy to develop applications fast and easy way. The Code Configuration tool generates 2 things: Library Files to use FlexCAN Peripheral. Configured parameters in the form of Data Types (structures, macros, arrays and etc.), which are used as input parameters in different functions of library files. Chronology to follow

Read More »

Author

Kunal Gupta

Leave a comment

Stay Updated With Us

Error: Contact form not found.

      Blog