I2C Communication HAL Example Based on Kinetis SDK 1.1 for FRDM-K22F

At the beginning of the Year of the Sheep, the holiday is over, and I return to my job. Reflecting on the past year, I have grown a lot and gained much, grateful for the people around me. Looking forward to the new year’s journey, filled with the unknown and challenges, I gather my spirit and prepare to fight…

Let’s get straight to the point. Freescale finally launched the long-awaited low-level driver library, Kinetis SDK, last year. As the name suggests, this driver library is mainly for Freescale’s ARM family Kinetis series, and it has now been updated to version 1.1. I won’t elaborate on the specific introduction of this driver library in this article; I suggest everyone go directly to Freescale’s official website to check and download it carefully. The official link is here. Of course, the initially supported chip series is limited, but as updates continue, more and more chips will be added.

The main purpose of this article is to provide a reference for porting an I2C communication example based on the SDK HAL layer. After all, I2C is widely used in many places, such as external EEPROMs and power management chips, which need to communicate with the main MCU via I2C. So how do we write HAL layer I2C driver code based on the SDK? Although the demo examples included in the SDK already have I2C driver layer support, the driver layer has its limitations (the implementation form and functions are relatively fixed, generally suitable for demonstration purposes), while the HAL layer is much more flexible (the HAL layer effectively encapsulates the underlying registers, shielding hardware compatibility issues). Using the HAL layer maximizes the utilization of peripheral modules. The FRDM-K22 board comes with a Freescale 6-axis sensor E-Compass (3-axis accelerometer + 3-axis magnetometer), with communication interfaces available for I2C and SPI. Since this blog introduces I2C as an example, we will choose the I2C interface. The sensor is already connected to the MCU on the board, and pull-up resistors have been added, so no extra hardware work is needed; we just need to focus on the software. Below, I briefly introduce the development platform and environment:

Development Platform: FRDM-K22F, the slave address of the onboard sensor is 0x1C, communication baud rate is 90kbps.

Development Environment: IAR 7.3

Example Template: KSDK_1.1.0\demos\hello_world\iar\frdmk22f

It should be noted that the code I wrote is based on the Hello World example in SDK 1.1. The modified code has been uploaded to the attachment at the end of the blog. Simply overwrite all the contents of the .c file in the attachment with the original hello_world.c file in the SDK 1.1 installation directory, then compile and download it to the board. Run the serial debugging assistant or terminal on the PC (serial baud rate is 115200), reset the MCU, and it will print “Hello World!”. Then send any character to the board to output the data from the onboard sensor in 6 axes, as shown in the figure below:

I2C Communication HAL Example Based on Kinetis SDK 1.1 for FRDM-K22F

That’s it. Since I have already added corresponding comments in the attached code, I won’t analyze and explain them one by one in the blog (it’s a bit tedious, haha). I believe you will understand after reading the code, haha.

(Attached Code↓)

/*

* Copyright (c) 2013 – 2014, Freescale Semiconductor, Inc.

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without modification,

* are permitted provided that the following conditions are met:

*

* o Redistributions of source code must retain the above copyright notice, this list

* of conditions and the following disclaimer.

*

* o Redistributions in binary form must reproduce the above copyright notice, this

* list of conditions and the following disclaimer in the documentation and/or

* other materials provided with the distribution.

*

* o Neither the name of Freescale Semiconductor, Inc. nor the names of its

* contributors may be used to endorse or promote products derived from this

* software without specific prior written permission.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND

* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED

* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR

* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES

* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON

* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT

* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS

* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

///////////////////////////////////////////////////////////////////////////////

// Includes

///////////////////////////////////////////////////////////////////////////////

// Standard C Included Files

#include <stdio.h>

#include <stdlib.h>

// SDK Included Files

#include “board.h”

#include “fsl_debug_console.h”

#include “fsl_i2c_hal.h”

#include “fsl_device_registers.h”

#include “fsl_clock_manager.h”

////////////////////////////////////////////////////////////////////////////////

// Code

////////////////////////////////////////////////////////////////////////////////

#define WHO_AM_I_REG 0x0D

#define CTRL_REG1 0x2A

#define XYZ_DATA_CFG 0x0E

#define M_CTRL_REG1 0x5B

#define M_CTRL_REG2 0x5C

#define OUT_X_MSB 0x01

#define WHO_AM_I_MASK 0xC7

#define ACTIVE_MASK 0x01

void I2C_Init(void);

void FXOS8700_Init(void);

i2c_status_t Hal_Dev_FXOS8700_Read_Reg(uint8_t addr, uint8_t *Buff, uint8_t len);

i2c_status_t Hal_Dev_FXOS8700_Write_Reg(uint8_t addr, uint8_t data);

typedef struct

{

int16_t x;

int16_t y;

int16_t z;

} SRAWDATA;

int main (void)

{

// RX buffers

//! @param receiveBuff Buffer used to hold received data

uint8_t receiveBuff;

uint8_t Buffer_Temp[12];

SRAWDATA AccelData, MagnData;

// Initialize standard SDK demo application pins

hardware_init();

// Call this function to initialize the console UART. This function

// enables the use of STDIO functions (printf, scanf, etc.)

dbg_uart_init();

configure_i2c_pins(BOARD_FXOS8700_I2C_INSTANCE);

FXOS8700_Init();

// Print the initial banner

PRINTF(“\r\nHello World!\n\n\r”);

while(1)

{

// First, get character

receiveBuff = GETCHAR();

Hal_Dev_FXOS8700_Read_Reg(OUT_X_MSB, Buffer_Temp, 12);

// copy the 14 bit accelerometer byte data into 16 bit words

AccelData.x = (int16_t)(((Buffer_Temp[0] << 8) | Buffer_Temp[1])) >> 2;

AccelData.y = (int16_t)(((Buffer_Temp[2] << 8) | Buffer_Temp[3])) >> 2;

AccelData.z = (int16_t)(((Buffer_Temp[4] << 8) | Buffer_Temp[5])) >> 2;

// copy the magnetometer byte data into 16 bit words

MagnData.x = (Buffer_Temp[6] << 8) | Buffer_Temp[7];

MagnData.y = (Buffer_Temp[8] << 8) | Buffer_Temp[9];

MagnData.z = (Buffer_Temp[10] << 8) | Buffer_Temp[11];

// Printf the Accelerometer and Magnetometer’s information

PRINTF(“The Accelerometer x-value: %d\n\r”, AccelData.x);

PRINTF(“The Accelerometer y-value: %d\n\r”, AccelData.y);

PRINTF(“The Accelerometer z-value: %d\n\r”, AccelData.z);

PRINTF(“The Magnetometer x-value: %d\n\r”, MagnData.x);

PRINTF(“The Magnetometer y-value: %d\n\r”, MagnData.y);

PRINTF(“The Magnetometer z-value: %d\n\r”, MagnData.z);

}

}

void I2C_Init(void)

{

CLOCK_SYS_EnableI2cClock(BOARD_FXOS8700_I2C_INSTANCE);

I2C_HAL_Init(I2C0_BASE);

I2C_HAL_SetAddress7bit(I2C0_BASE, 0x3A);

I2C_HAL_SetBaudRate(I2C0_BASE, CLOCK_SYS_GetBusClockFreq(), 90, NULL);

I2C_HAL_Enable(I2C0_BASE);

}

void FXOS8700_Init(void)

{

uint8_t deviceWhoAmI = 0;

I2C_Init();

// Verify device is there

Hal_Dev_FXOS8700_Read_Reg(WHO_AM_I_REG, &deviceWhoAmI, 1);

if (deviceWhoAmI != WHO_AM_I_MASK)

{

PRINTF(“The Initialization Error!\n\r”);

}

Hal_Dev_FXOS8700_Write_Reg(CTRL_REG1, 0);

Hal_Dev_FXOS8700_Write_Reg(M_CTRL_REG1, 0x1F);

Hal_Dev_FXOS8700_Write_Reg(M_CTRL_REG2, 0x20);

Hal_Dev_FXOS8700_Write_Reg(XYZ_DATA_CFG, 0x01);

Hal_Dev_FXOS8700_Write_Reg(CTRL_REG1, 0x0D);

}

i2c_status_t Hal_Dev_FXOS8700_Read_Reg(uint8_t addr, uint8_t *Buff, uint8_t len)

{

return(I2C_HAL_MasterReceiveDataPolling(I2C0_BASE, BOARD_FXOS8700_I2C_ADDR, &addr, 1, Buff, len));

}

i2c_status_t Hal_Dev_FXOS8700_Write_Reg(uint8_t addr, uint8_t data)

{

return(I2C_HAL_MasterSendDataPolling(I2C0_BASE, BOARD_FXOS8700_I2C_ADDR, &addr, 1, &data, 1));

}

I2C Communication HAL Example Based on Kinetis SDK 1.1 for FRDM-K22F

Leave a Comment