013 - Porting uGOAL to another Platform

This page gives you a brief overview of porting the uGOAL software package to your desired platform. The benefits of uGOAL as Software Package is the small footprint and the minimalistic API of the platform driver.

The following example shows the porting to the S32K144 Evaluation Board from NXP. This Board comes with a helpfully Getting-Started to explore the board and connectors, GPIO Headers, the debugging methods and much more.

Installation and First Start of S32DS

We’re using the provided IDE S32 Design Studio (S32DS) for ARM to create an empty project as boilerplate.

At first, we have to install the S32 Design Studio for ARM and the PE Micro Debugger Tool to use the Debug Feature too. The Installation Guide asks for an Activation Key, which you should receive via Mail after a succesful registration at the NXP Website.

Installing the S32 Design Studio
Extensions and Updates

At the first start the S32DS Extensions and Updates Screen should appear. We’ll use the S32K1xx Software Development Kit (SDK) package here to start with developing so this package must be installed.

The Processor Expert of the SDK takes care of e.g., clock-, board- or peripheral configuration. The User can then use the generated code and provided abstraction layer to simply select the desired peripheral and start e.g., an SPI communication, without dealing with Hardware Registers of the Board. However, not all manufacturer provide such handy tools for a rapid development.

If you don’t have any experience with the development board, we highly recommend trying some example projects which comes with the IDE and start to debug to get an idea, how the IDE and the Debugging works.

Import an Example Project and Debug

We’ll start with an empty workspace and choose an example project for e.g. SPI, which comes with the SDK. We choosed the SDK “S32SDK S32K1xx RTM v3.0.0 Example Projects” and the Project “lpspi_transfer_s32k144”. This project uses the Low Power Serial Peripheral Interface.

The Code must be generated by the button “Generate Processor Expert Code” [1] and can then be build [2].

After clicking “Debug As…” and choosing the Configuration with the GDB PEmicro Interface, the Image is flashed onto the Development Board and the S32DS switches to the Debug View.

If this works, we’ll head to the next step: the configuring of the necessary peripherals.

Identifying the Arduino Footprint

The S32K144 has an Arduino Footprint which defines some functionality onto specific GPIOs. This way, we can use our red Arduino Adaptershield to connect the System on Module with the Development Board.

The Pinout of the S32K144 is listed at the Quickstartguide. According to this, following Pins has to be used at the S32K144:

 

SoM

S32K144

I2C CLK

PTA3

I2C DATA

PTA2

 

 

SPI CLK

PTB2

SPI MISO

PTB3

SPI MOSI

PTB4

SPI CS

PTB5

 

 

RESET

PTC11

SYNC0

PTC10

SYNC1

PTB11

Configure Peripherals

Routing and Pinmuxing

Now we can take a look at the peripherals LPSPI, LPI2C, LPUART and GPIO and choose the right Pins at the Table Row “Pin/Signal Selection” for each protocol according to the table above - the “Direction” is selected automatically. Some of the Pins are preselected, due to the use of the Example Project. However, we can just remove these unused Pins.

The GPIO PTC11 is connected to the Reset Pin at the SoM and must be defined as Output with default level High.

Optional: For EtherCAT Distributed Clocks, we have to configure the SYNC0 and SYNC1 Pins to fire an external Interrupt if a rising edge is detected. This is done in the Tab “Functional Properties”. The Pull-Down Resistor is activated and the initial value at the PTC10 and PTB11 is Low - this will suppress Interrupts caused by Noise or undefined GPIOs.

Configuring Components and create Code

After the pinmuxing is done we have to configure the peripheral components to work with the SoM.

The Project uses the component SPI to transfer some data of the integrated ADC. We want to use this channel to communicate with the SoM, so some modifications are necessary. The SoM can theoretically handle up to 20 MHz - we’ll use 2 MHz for a reliable communication. The Option “PCS continuous” has to be checked to send the whole SPI frame of about 128 Byte to the SoM in one bunch, otherwise the CS pin would be released after each byte.

The Component “Receive:lpspi” can be removed, as well as the “adConv1:adc” and “flexTimer_pwm1:ftm_pwm”.

 

 

We’ll add the components “lpuart” and “lpi2c” [1] via Drag and Drop to the directory “components” [2]. After configuring the UART for e.g., 125000 Baudrate and the I2C for 100000 Hz, we hit the Button “Generate Processor Expert Code” [3].

Check Functionality with Test Code

The Processor Expert provides all available Functions to initialize and use the peripherie at the Components window at the bottom left. Other IDEs like the STMCubeIDE already adds the Function Calls with the required Parameters at the Code Generation - the NXP S32DS renounces it. Thus, finding the right parameters and function calls to get the Board running might be difficult. Luckily, the Example Project already contains this step.

The main function already initializes the clock, as shown below.

int main(void) { /* Write your local variable definition here */ /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ #ifdef PEX_RTOS_INIT PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of Processor Expert internal initialization. ***/ /* 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);

In the next step, we have to add some of the function calls from the Components window via Drag and Drop to the main.c file. We’re adding the init-functions to initialize the GPIOs, I2C, UART and SPI. Some of the Parameters are defined at the header-files of the corresponding components. The Header-files of the components must be also included.

/* User includes (#include below this line is not maintained by Processor Expert) */ #include "clockMan1.h" #include "pin_mux.h" #include "lpspiCom1.h" #include "lpi2c1.h" #include "lpuart1.h"
int main(void) { ... /* initialize GPIOs and Reset Pin */ PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); /* initialize i2c to set LEDs on adapter shield */ LPI2C_DRV_MasterInit(INST_LPI2C1, &lpi2c1_MasterConfig0, &mLpi2c1MasterState); /* UART for logging */ LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0); /* SPI for SoM connection, set timeouts between CS and MOSI */ LPSPI_DRV_MasterInit(LPSPICOM1, &lpspiCom1State, &lpspiCom1_MasterConfig0);

Does this work? Let's find out with a while-loop after the initialization:

Build the Project and start debugging lead us to our first problem… we hit an assert! The value of the config->pinPortIdx is 6, this means the Pin 6 is not configured correctly. If we take a look at the callstack we can see, that the function PINS_Init(&config[0]); provokes this error. The GPIO at g_pin_mux_InitConfigArr[0] doesn’t have a specified direction. If we take a look at the Processor Expert Window at the Components, we can spot the error: PTB6 has no specified direction. Removing the whole Pin (we don’t need this Pin yet) should fix this issue.

 

Now the program compiles and runs without any problem. We highly recommend the usage of a Logic Analyzer or an Oscilloscope to check the signals at the components. The SPI signals should look like the image below. Other Components can also be checked this way.

Integrating uGOAL

Into main.c

After configuring the whole peripheri of the development board and making sure, every component works like it should, we’ll have to integrate uGOAL into the project and the main.c.

Importing the uGOAL source code is done by right click into the Project Explorer and selecting “Import->General-File System”. Choose the uGOAL Delivery.

Not all directories have to be imported as you won’t need all the directories and subdirectories. The tools directory contains the Project Generator itself. The projects directories contain all available projects but for the initial start, we just need one application. The applications in projects/ugoal/... are simple applications without many features - perfect to start with!

The next step is adding the paths to the include paths, so the Compiler will add the uGOAL sources and headerfiles to the Binary.

 

 

The main.c needs the Header file goal_includes.h. The Initialization of uGOAL is done with three functions, which have to be called before entering any loop. After this, the uGOAL-Loop will take care of the cyclic communication to the SoM via SPI.

But the most important is missing: the platform driver, so we’ll head to the last chapter.

Into plat.c

The platform driver is the interface between uGOAL and the microcontroller. If you followed this application note, you probably have an empty driver as a template available. This template driver contains the API uGOAL needs.

With the help of the Processor Expert and the generated code, the last step - filling the platform driver with the necessary functions - should be an easy task.