This is in continuation to my earlier blog i posted for interfacing Xtrinsic sensor.
Before we start this project below are the pre-requisites:
1) KDS software tool from Freescale
2) FRDM-kl46ZFRDM-kl46Z Freedom development board
3) e14 Xtrinsic Sensore14 Xtrinsic Sensor Development board
Brief Introduction:
This project introduces on interfacing e14 xtrinsic sensor board to Kinetis freedom board KL46Z. As we know xtrinsic sensor board is having pin compatible of arduino interface and KL46Z is also having arduino compatible interface so both the board are one-to-one pluggable. The interface looks like the picture shown below. This project polls data from accelerometer and displays in ‘g’s, polls data from magnetometer in ‘uT ‘, Getting pressure and temperature data in kPa and degrees Celsius.
This project operates in 4 modes or state machines Standby mode (e14), Accelerometer mode (A SE), Magnetometer mode (G SE), Pressure/Temp mode (P SE). All these modes can be transited through successive button press (SW3). And these modes can be seen or displayed on 4-digit segmented LCD panel present on KL46 board and the sensor data’s are been sent to UART port and can be seen on HyperTerminal.
It polls data from accelerometer and displays in ‘g’s
Little bit on Xtrinsic sensor board:
The sensor board comes equipped with three of Freescale's new-generation XTRINSIC MEMS sensors. The MPL3115 (U1) is designed for accurate measurement of temperature and pressure, the MAG3110 (U2) for detection of magnetic fields, and the MMA8491 (U3) for measurement of physical positions.
MPL3115
The MPL3115 is a high-precision sensor used to provide accurate pressure and altitude data. It features an adjustable sampling rate, ultra-low power consumption and intelligent functions, suitable for applications such as mobile, medical and security devices. MPL3115 is able to provide digitized output, two separated wake-up interrupts, minimum/maximum threshold mechanism, and autonomous data acquisition. The self data processing ability of the MPL3115 reduces the need for communication with MCUs, which reduces overall system power consumption.
MAG3110
The MAG3110 is a small, low-power, digital 3-axis magnetometer featuring a wide measurement range. It can measure magnetic fields (the overlapped fields consisting of the geomagnetic field and the fields created by components on PCB) on each of the 3 axes in the position where it is placed. The MAG3110 features an I2C serial interface, and is capable of measuring magnetic fields of up to 10 Gauss with an output data rate up to 80Hz. The output data rate can vary depending on the sampling intervals and may be adjusted from 12ms to several seconds.
MMA8491Q
The MMA8491Q is a low voltage, 3-axis low-g accelerometer housed in a 3 mm by 3 mm QFN package. The device can accommodate two accelerometer configurations, acting as either an easy to implement 45° Tilt Sensor or a digital (I2C) output accelerometer. In the 45° Tilt Sensor mode, it offers extremely easy board implementation by using a single line of output per axis. In the digital output mode, 14-bit ±8g raw data can be read from the device with high 1 mg/LSB sensitivity. The extreme low power capabilities of the MMA8491Q reduce the low data rate current consumption to less than 400 nA per Hz.
Before we proceed make sure you install/import the updated *.PEupd files available from Git HUB.
To install these file first download the contents from below link
http://sourceforge.net/projects/mcuoneclipse/files/PEx%20Components/
The downloaded folder is named as “Components 2014-10-17” which contains Part1_Beans_17.10.2014.PEupd and Part2_Beans_17.10.2014.PEupd bean files
Select the option Processor Expert> Import Component as shown below.
Next select the destination which you have downloaded and select Part1_Beans PEupd file and click on open as shown below.
Repeat the same procedure to import the Part2_Beans PEupd file
Now the KDS tool has been updated with all the Processor expert components.
(This project folder has been extracted from the Freescale community blog: https://community.freescale.com/docs/DOC-101370 )
Let’s start on creating a project to interface this sensor board using Kinetis Design studio on Processor Expert platform.
As per our stated requirement the modules that are been used in this project are:
1. Console IO: for UART communication
2. I2C_LDD: required for I2C communication
3. ExtInt_LDD: external interrupt signal required for MAG3110 sensor
4. ExtInt_LDD: external interrupt signal required for MPL3115 sensor
5. TimerInt_LDD: Timer interrupt for every 1 ms generated
6. TimerUnit_LDD: This is an referenced component required for timer interrupt generation
7. BitIO_LDD: Bit i/o signal required for enable pin of Accelerometer
8. SegLCD_LDD: 4 digit segment LCD module driver
9. ExtInt_LDD: external interrupt signal interfaced to switch SW3 for user interface
10. Init_GPIO: This module is required to add internal pull-up for SW3 switch interface
Open KDS tool and create a new project give your choice of name for it, i have given it as “Xtrinsic on KL46 with SW+LCD”
Refer to my earlier blog on how to create a project in KDS.
Clock settings:
From project explorer window select the cpu components as shown below:
Select clock source setting as shown below:
Under Clock source settings select MCG settings in that select FEI as MCG mode.
Next select clock configuration as per below snap shot
Next select the Core clock and Bus clock as shown below:
Now clock setting is done and let’s move further in selecting the required components.
ConsoleIO Module:
Click on components>Components Library>Alphabetical then select the component ‘ConsoleIO’ as shown below and right click and Add to Project or Double click on this.
Now select as shown below:
We need to configure the UART settings we have connected this ConsoleIO to UART0 of the KL46 MCU board.
ConsoleIO is connected to UART0_TX->PTA2 and UART0_RX->PTA1 port pins
I2C_LDD module (E14:I2C_LDD)
Since we are using three different devices on one I2C module, we need to change the slave addresses to talk to the different modules. You will notice in the properties tab in the components inspector window that in the Settings->MASTER mode, we left the Target Slave Address as 0. We could use any of the slave addresses of the sensors but since the function above ‘SelectSlaveDevice’ is always going to be called before using the I2C ports in our programme.
Similarly add I2C_LDD module from component library this I2C module is required for MMA8491Q magnetometer sensor.
Here we have I2C in Master mode with clock frequency to be 93.623 kHz and target slave address to be 0X55 which is the address of Xtrinsic sensor MMA8491 magnetometer device.
Next assign the concern I2C pins as shown below:
I2C SDA-> PTE0 port pin
I2C SCL-> PTE1 port pin
ExtInt_LDD module: (MAG3110_INT: ExtInt_LDD)
Similarly as we had done to earlier modules, add ExtInt_LDD module from Component library list and name this as MAG3110_INT. This module is assigned to the xtrinsic sensor MAG3110 device as external interrupt source.
Xtrinsic module is having an interrupt signal coming out from MAG3110 device to say the master that the sensor data is ready to read.
This interrupt pin is assigned to PTD5 port pin with rising edge as interrupt sensing signal. The above snap shot shows the setting of MAG_INT module.
ExtInt_LDD: MPL3115A2_INT Module
Similar to MAG3110 interrupt module add one more ExtInt_LDD module from component library and name this as MPL3115A2 which is interrupt module from MPL3115 sensor device.
This interrupt is assigned to PTD7 Port pin with rising edge triggered interrupt.
TI1:TimerInt_LDD module
Next we need a timer module which generates an interrupt for every 1ms. We are adding a TimerInt_LDD module from component library and naming it as TI1. After adding this component the tool will add its reference component TimerUnit_LDD also make the setting as shown below:
The reference component TimerUnit_LDD has below configuration:
The settings of TU1 are shown below which is taken care y tool itself:
ACC_EN: BitIO_LDD Module
There is an enable pin on xtrinsic sensor board which is an input signal. The controller should send high signal in order to select the sensor board, this enable pin in signal required for Accelerometer sensor MMA8491 device.
Select BitIO_LDD module from component library and add it to project name it as ACC_EN and do the settings as shown below
This enable pin is connected to port PTA13 pin which sends High signal to sensor board to enable Acc sensor
SegLCD1:SegLCD_LDD
Now we are adding segment lcd module to our project from component library and assigned as shown below.
Next select the Backplane pins as shown below:
Next select the Frontplane pins as shown below:
SW:ExtInt_LDD Module
Next we need to add one more external interrupt ExtInt_LDD module from component library for switch interrupt press and name it as SW and configure its port pin as shown below.
The Switch is connected to PTC12 port pin on KL46 freedom board with rising edge triggered interrupt.
PTC:Init_GPIO Module
As there is no pull-up exist on the freedom board on the Port pin PTC12 (see KL46Z board schematic) we need to add an internal pull-up in get an switch interrupt. The module Init_GPIO will initialise the pull-up at the start-up, Add this module from component library and name it as PTC and make the settings as shown below:
Now all our component modules have been added to our project folder to make sure it is error free click on generate icon as shown below:
it’s time to add software code along with driver. I have extracted the drivers available from Freescale community link below:
https://community.freescale.com/docs/DOC-101370
The project explorer folder is shown below, i have added sensor_headers folder which consist of drivers interface files like MAG3110.c, MMA8491Q.c, MPL3115A2.c these can be extracted from attached project folder.
As explained earlier in my blog add the segment LCD drivers to the project SLCD_header which consist of driver files as shown above in picture.
For more regarding driving segment LCD refer to my earlier blog Here
Here is the code written for this project:
#include"Cpu.h"
#include "Events.h"
#include "CsIO1.h"
#include "IO1.h"
#include "E14.h"
#include "MAG3110_INT.h"
#include "MPL3115A2_INT.h"
#include "TI1.h"
#include "ACC_EN.h"
#include "TU1.h"
#include "SegLCD1.h"
#include "SW.h"
#include "PTC.h"
/* Including shared modules, which are used for whole project */
#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
/* User includes (#include below this line is not maintained by Processor Expert) */
#include "stdio.h"
#include "board_serial.h"
#include "commons.h"
#include "LCD.h"
char Welcome[] = "Command Server Application";
char PROMPT[] = "\nE14>\n ";
bool g_initial_comp=FALSE; //This variable is set only when all module initialisation is complete to prevent
//overtaking by interrupts
const char prmt[]=("e14");
const char acc[]=("A se");
const char mag[]=("G se");
const char pres[]=("R se");
const char tilt[]=("tilt");
const char blank[]=(" ");
extern int sw_count;
int y;
/*lint -save -e970 Disable MISRA rule (6.3) checking. */
int main(void)
/*lint -restore Enable MISRA rule (6.3) checking. */
{
/* Write your local variable definition here */
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
deviceData.handle = E14_Init(&deviceData);
mag_setup();
MPL3115A2_setup();
//Interrupt event may occur before initialisation and so we disable reading data first.
//To re engage the interrupt we need to read from the sensors and this is what occurs below
E14_SelectSlaveDevice(deviceData.handle,LDD_I2C_ADDRTYPE_7BITS,MAG3110_SLAVE_AD);
do res=ReadReg(STATUS_REG,mag_data,2);
while(res!=0);
E14_SelectSlaveDevice(deviceData.handle,LDD_I2C_ADDRTYPE_7BITS,MPL3115A2_SLAVE_AD);
do res=ReadReg(STATUS_REG,mag_data,2);
while(res!=0);
g_initial_comp=TRUE
//printf("\nPlease Press SW3 button to start on the board and press again to change the sensor type\n");
vfnLCD_Write_Msg((uint8 *)prmt);
bool l_neg=0,flag=1;
bool is_g=1;
bool l_temp=0;
for(;;)
{
y=sw_count % 4;
if(flag){
printf("\nPlease Press SW3 button to start on the board and press again to change the sensor type\n");
flag=0;
}
if(y == 0){
vfnLCD_Write_Msg((uint8 *)prmt);
printf("\r");
printf("\nPlease Press SW3 button to start on the board and press again to change the sensor type\n");
}
if(y == 1){
l_temp= TRUE;
is_g=0;
vfnLCD_Write_Msg((uint8 *)acc);
printf("\r");
accel_interface_raw();
}
if(y==2){
vfnLCD_Write_Msg((uint8 *)mag);
bool is_t=TRUE, l_temp=0;
bool mag_samp_ready=0,pres_samp_ready=0;
unsigned int l_current_time=0;
l_current_time=t_count;
printf("\r");
mag_interface_bh();
}
if(y==3){
vfnLCD_Write_Msg((uint8 *)pres);
printf("\r");
pres_interface_bh();
}
vfnLCD_Write_Msg((uint8 *)prmt);
}
#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of RTOS startup code. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;){}
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
/* END main */
/*!
** @}
*/
Program Execution:
In this main program there is a variable ‘sw_count’ for interrupt generated when ever switch is pressed and the variable is incremented in interrupt handler Events.c
As we have 4 state machines we are checking the switch press corresponds to which mode by modulo operated on sw_count by 4 i.e
y=sw_count %4
- Standby mode (e14): corresponds to first switch press (y==0)
- Accelerometer mode (A SE): corresponds to second switch press (y==1)
- Magnetometer mode (G SE): corresponds to third switch press (y==2)
- Pressure/Temp mode (P SE): corresponds to fourth switch press (y==3)
Standby mode:
if(y == 0){
vfnLCD_Write_Msg((uint8 *)prmt);
printf("\r");
printf("\nPlease Press SW3 button to start on the board and press again to change the sensor type\n");
}
Here we are checking the switch press is for e14 mode and displays the status on LCD using vfnLCD_Write_Msg((uint8 *)prmt);
and also sends message on hyper terminal using printf().
Accelerometer mode (A SE):
if(y == 1){
l_temp= TRUE;
is_g=0;
vfnLCD_Write_Msg((uint8 *)acc);
printf("\r");
accel_interface_raw();
}
Here we are checking the switch press for two times. Then we are calling the below function to display the message “A SE” on LCD
vfnLCD_Write_Msg((uint8 *)acc);
And call the accelerometer function accel_interface_raw();to perform, here the system infinitely senses the accelerometer data and displays corresponding X-axis, Y-axis, Z-axis sensor data’s on hyper terminal until you press the next event of switch.
Magnetometer mode (G SE):
if(y==2){
vfnLCD_Write_Msg((uint8 *)mag);
bool is_t=TRUE, l_temp=0;
bool mag_samp_ready=0,pres_samp_ready=0;
unsigned int l_current_time=0;
l_current_time=t_count;
printf("\r");
mag_interface_bh();
}
Here we are checking the switch press is for the magnetometer event if true then display “G SE” on LCD display using the below function.
vfnLCD_Write_Msg((uint8 *)mag);
Further we are calling the magnetometer sensing function mag_interface_bh();which continuously senses the magnetometer present and displays its values on hyper terminal.
Pressure/Temp mode (P SE):
if(y==3){
vfnLCD_Write_Msg((uint8 *)pres);
printf("\r");
//printf("\nShowing Pressure and temperature data values\n");
pres_interface_bh();
}
Here we are checking the switch press is for the pressure mode, if true then display “P SE” on LCD display using the vfnLCD_Write_Msg((uint8 *)pres) function.
And proceed further calling the pres_interface_bh() function which executes the pressure sensor present on xtrinsic board. This function collects the sensor data and display it on the hyper terminal.
Build the project
First save the project selecting File > Save All
Now click on build the project as shown below
You will see the progress bar and console result as shown below
Debug configuration
Now we need to configure debug settings for the board.
To configure the board in KDS tool open Debug Configuration as shown below:
Debug configuration window opens select “GDB PEmicro interface debugging” right click and select option ‘New’ then automatically it get selected to your current running compiled project which is shown below:
Debug the project
First save the project selecting File > Save All and connect the board to your computer on SDA port.
Click on debug and select our target project
And click on Debug button. It takes few time to configure for the debug execution, after this process finishes click on resume button as shown
Now click on resume button to execute the program
Before that open a hyper terminal on your computer and set baud rate to 9600 8N1 parity: none, with flow control to be Xon/Xoff.
Below are the output snaps and video output of the execution.
Below is the video output execution of the project:
I have enclosed the project folder for quick reference.








































