FRDM-KL25Z FRDM-STBC-AGM01 - Example project in KDS 3.0.0 using KSDK 1.2.0 and Processor Expert

Document created by Tomas Vaverka Employee on Jul 31, 2015Last modified by Tomas Vaverka Employee on Aug 4, 2015
Version 4Show Document
  • View in full screen mode

Hi Everyone,

 

This tutorial is a guide on how to create a simple application in the Kinetis Design Studio that reads the data from both sensors on the FRDM-STBC-AGM01 board using an interrupt technique through the I2C interface. The Processor Expert is used to configure the I2C interface and GPIO on the MKL25Z128 MCU. I will not cover the Sensor Fusion libraryand the ISF.

 

Before you begin please make sure that both the Kinetis Design Studio (Eclipse based) and the Kinetis SDK are setup and you can already compile and debug code. If not, please refer to Erich's blog: Tutorial: Adafruit WS2812B NeoPixels with the Freescale FRDM-K64F Board – Part 2: Software Tools | MCU on Eclipse http://centaurian.co.uk/2015/05/22/toolchain-ksdk-1-2-0-with-eclipse-4-4-luna-and-gnu-arm-plugin/

 

 

1. Create a new project in KDS

 

Within KDS, click on "File" menu item and select "New" > "Kinetis Project"

newkinetisproject_thumb.png

 

Name and set location of your project. I use the default location under the workspace area. Click Next.

nameproject_thumb.png

 

Select the development board used (in my case it is the FRDM-KL25Z) and click Next.

developmentboard.png

 

Select “KSDK 1.2.0”. Set location to KSDK path, I use an absolute path. The location of my KSDK is in the default location where KSDK would install to. Ensure “Processor Expert” checkbox is checked. Press Next.

sdkandpeselect_thumb.png

 

Make sure that “GNU C Compiler” is selected. Click the "Finish" button.

compiler_thumb.png

 

 

2. Open Processor Expert

 

Open the Processor Expert perspective, this should be a button on the top right hand side of Eclipse.

openpeperspective_thumb.png

 

If it is not there, try clicking on the “Open Perspective” button and then selecting “Processor Expert” in the form that appears.

openperspective_thumb.png

addpeperspective_thumb.png

 

 

3. Add I2C component

 

Click on the “Components Library” tab, search for the component “fsl_i2c” and double click on it.

component_fsl_i2c_thumb.png

 

Select the "i2cCom1:fsl_i2c" in the Components window.

select_i2ccom1_thumb.png

 

In the "Component Inspector" tab configure the I2C component. As you can see in the FRDM-STBC-AGM01 schematic, with jumpers J6 and J7 in their default position (2-3), the I2C signals are routed to the I2C1 module (PTC1 and PTC2 pins) of the KL25Z MCU. The 7-bit I2C slave address of the FXOS8700CQ is 0x1E (to enter hex values, switch the format to the ‘H’ mode) since both SA0 and SA1 pins are shorted to GND. The address of the FXAS21002C is 0x20 since SA0 pin is also shorted to GND. The I2C bus clock frequency is set to 400 kHz.

i2c_setting_thumb.png

 

 

4. Add GPIO component

 

Click on the “Components Library” tab, search for the component “fsl_gpio” and double click on it.

component_fsl_gpio_thumb.png

 

Select the "gpio1:fsl_gpio" in the Components window.

select_gpiofsl_thumb.png

 

In the "Component Inspector" tab configure the GPIO component. The INT1_8700 output is connected to the PTD4 pin and the INT1_21002 pin to the PTA5 pin of the KL25Z MCU. These both interrupt pins are configured as push-pull active-low outputs, so the corresponding PTD4/PTA5 pin configuration is GPIO with an interrupt on falling edge.

gpio_setting_thumb.png

 

To enable both the PORTA and PORTD interrupts, select the “Events” tab and then select “generate code” next to PORTA IRQ and PORTD IRQ handlers.

fsl_gpio_events_thumb.png

 

 

5. Add Wait component

 

Click on the “Components Library” tab, search for the component “Wait” and double click on it.

component_wait_thumb.png

 

At this point we have done all we can within Processor Expert. Make sure you save all on the project at this point then on the Components window, click on the "Generate code" button.

generatecode_thumb.png

 

 

6. Add your code

 

Here is the initialization of the FXOS8700CQ and FXAS21002C.

 

/******************************************************************************
* FXOS8700CQ initialization function
******************************************************************************/

void FXOS8700CQ_Init (void)
{
  FXOS8700CQ_WriteRegister(CTRL_REG2, 0x40); // Reset all registers to POR values
  WAIT1_Waitms(1);

  FXOS8700CQ_WriteRegister(XYZ_DATA_CFG_REG, 0x00); // +/-2g range with 0.244mg/LSB

  FXOS8700CQ_WriteRegister(M_CTRL_REG1, 0x1F); // Hybrid mode (accelerometer + magnetometer), max OSR
  FXOS8700CQ_WriteRegister(M_CTRL_REG2, 0x20); // M_OUT_X_MSB register 0x33 follows the OUT_Z_LSB register 0x06 (used for burst read)

  FXOS8700CQ_WriteRegister(CTRL_REG2, 0x02); // High Resolution mode
  FXOS8700CQ_WriteRegister(CTRL_REG3, 0x00); // Push-pull, active low interrupt
  FXOS8700CQ_WriteRegister(CTRL_REG4, 0x01); // Enable DRDY interrupt
  FXOS8700CQ_WriteRegister(CTRL_REG5, 0x01); // DRDY interrupt routed to INT1 - PTD4
  FXOS8700CQ_WriteRegister(CTRL_REG1, 0x25); // ODR = 25Hz, Reduced noise, Active mode
}

 

/******************************************************************************
* FXAS21002C initialization function
******************************************************************************/

void FXAS21002C_Init (void)
{
  FXAS21002C_WriteRegister(GYRO_CTRL_REG1, 0x40); // Reset all registers to POR values
  WAIT1_Waitms(1);

  FXAS21002C_WriteRegister(GYRO_CTRL_REG0, 0x03); // High-pass filter disabled, +/-250 dps range -> 7.8125 mdps/LSB = 128 LSB/dps
  FXAS21002C_WriteRegister(GYRO_CTRL_REG2, 0x0C); // Enable DRDY interrupt, mapped to INT1 - PTA5, push-pull, active low interrupt
  FXAS21002C_WriteRegister(GYRO_CTRL_REG1, 0x16); // ODR = 25Hz, Active mode
}

 

 

In the ISRs (look for the file Events.c), only the interrupt flags are cleared and the DataReady variables are set to indicate the arrival of new data.

 

void PORTA_IRQHandler(void)
{
  /* Clear interrupt flag.*/
  PORT_HAL_ClearPortIntFlag(PORTA_BASE_PTR);
  /* Write your code here ... */
  FXAS21002C_DataReady = 1;
}

 

void PORTD_IRQHandler(void)
{
  /* Clear interrupt flag.*/
  PORT_HAL_ClearPortIntFlag(PORTD_BASE_PTR);
  /* Write your code here ... */
  FXOS8700CQ_DataReady = 1;
}

 

 

The output values from accelerometer registers 0x01 – 0x06 are first converted to signed 14-bit integer values and afterwards to real values in g’s. Similarly, the output values from magnetometer registers 0x33 – 0x38 are first converted to signed 16-bit integer values and afterwards to real values in microtesla (µT).

 

if (FXOS8700CQ_DataReady)         // Is a new set of accel+mag data ready?
{
   FXOS8700CQ_DataReady = 0;
   
   FXOS8700CQ_ReadRegisters(OUT_X_MSB_REG, 12, AccelMagData);         // Read FXOS8700CQ data output registers 0x01-0x06 and 0x33 - 0x38
   
   // 14-bit accelerometer data
   Xout_Accel_14_bit = ((int16_t) (AccelMagData[0]<<8 | AccelMagData[1])) >> 2;             // Compute 14-bit X-axis acceleration output value
   Yout_Accel_14_bit = ((int16_t) (AccelMagData[2]<<8 | AccelMagData[3])) >> 2;             // Compute 14-bit Y-axis acceleration output value
   Zout_Accel_14_bit = ((int16_t) (AccelMagData[4]<<8 | AccelMagData[5])) >> 2;             // Compute 14-bit Z-axis acceleration output value
   
   // Accelerometer data converted to g's
   Xout_g = ((float) Xout_Accel_14_bit) / SENSITIVITY_2G;         // Compute X-axis output value in g's
   Yout_g = ((float) Yout_Accel_14_bit) / SENSITIVITY_2G;         // Compute Y-axis output value in g's
   Zout_g = ((float) Zout_Accel_14_bit) / SENSITIVITY_2G;         // Compute Z-axis output value in g's

   // 16-bit magnetometer data
   Xout_Mag_16_bit = (int16_t) (AccelMagData[6]<<8 | AccelMagData[7]);        // Compute 16-bit X-axis magnetic output value
   Yout_Mag_16_bit = (int16_t) (AccelMagData[8]<<8 | AccelMagData[9]);        // Compute 16-bit Y-axis magnetic output value
   Zout_Mag_16_bit = (int16_t) (AccelMagData[10]<<8 | AccelMagData[11]);      // Compute 16-bit Z-axis magnetic output value

   // Magnetometer data converted to microteslas
   Xout_uT = (float) (Xout_Mag_16_bit) / SENSITIVITY_MAG;             // Compute X-axis output magnetic value in uT
   Yout_uT = (float) (Yout_Mag_16_bit) / SENSITIVITY_MAG;             // Compute Y-axis output magnetic value in uT
   Zout_uT = (float) (Zout_Mag_16_bit) / SENSITIVITY_MAG;             // Compute Z-axis output magnetic value in uT
}

 

 

Similarly, the output values from gyroscope registers 0x01 – 0x06 are first converted to signed 16-bit integer values and afterwards to real values in degrees per second. Temperature is also read out from the 0x12 register.

 

if (FXAS21002C_DataReady)         // Is a new set of gyro data ready?
{
   FXAS21002C_DataReady = 0;

   FXAS21002C_ReadRegisters(GYRO_OUT_X_MSB_REG, 6, GyroData);         // Read FXAS21002C data output registers 0x01-0x06

   // 16-bit gyro data
   Xout_Gyro_16_bit = (int16_t) (GyroData[0]<<8 | GyroData[1]);         // Compute 16-bit X-axis output value
   Yout_Gyro_16_bit = (int16_t) (GyroData[2]<<8 | GyroData[3]);         // Compute 16-bit Y-axis output value
   Zout_Gyro_16_bit = (int16_t) (GyroData[4]<<8 | GyroData[5]);         // Compute 16-bit Z-axis output value

   // Gyro data converted to dps
   Roll = (float) (Xout_Gyro_16_bit) / SENSITIVITY_250;               // Compute X-axis output value in dps
   Pitch = (float) (Yout_Gyro_16_bit) / SENSITIVITY_250;              // Compute Y-axis output value in dps
   Yaw = (float) (Zout_Gyro_16_bit) / SENSITIVITY_250;                // Compute Z-axis output value in dps

   // Temperature data
   FXAS21002C_ReadRegisters(GYRO_TEMP_REG, 1, GyroData);
   Temp = (int8_t) (GyroData[0]);
}

 

 

The complete project including the I2C communication routines and sensor's header files is attached.

 

 

6. Build and debug the project

 

To build the project, select the root folder of the project in the Project Explorer view and click the "Hammer" icon to build it.

build_thumb.png

 

If everything goes well, no errors are shown in the "Problems" view:

problems_thumb.png

 

The .elf (binary) file has been created inside the "Debug" folder:

Elf_file thumb.png

 

Connect the SDA port on the FRDM-KL25Z board to a USB port on your computer. To debug the project for the first time, select the root folder of the project in the Project Explorer view and open the "Debug Configurations" window.

Debug_config_thumb.png

 

Select the ""GDB PEMicro Interface Debugging" and click the "New launch configuration" icon.

debug_config_1_thumb.png

 

In the "Debugger" tab, select the "OpenSDA Embedded Debug - USB Port" interface and the KL25Z128M4 as a target device. Click the "Debug" button.

debugger_thumb.png

 

Click the "Resume" button to run the project.

debug_perspective_thumb.png

 

You can pause the execution and look at the data using the "Suspend" button.

variables_thumb.png

 

 

Now you can edit, build and debug the project again. As we used a debug configuration, it is listed under the "Debug" icon, so you can start it from there.

debug_active_thumb.png

 

 

Well done if you managed to follow along and get it all working. As a bonus I have attached the FreeMASTER project that will allow you to visualize the gathered data.

 

If there are any questions regarding this simple project, do not hesitate to ask below. Your feedback or suggestions are also welcome.

 

Regards,

Tomas

Outcomes