The Freescale Freedom KL26Z hardware (FRDM-KL26Z) is a capable and cost-effective design featuring a Kinetis L series microcontroller, the industry’s first microcontroller built on the ARM® Cortex™-M0+ core. It features a KL26Z128VLH4 (KL26Z), a device boasting a maximum operating frequency of 48MHz, 128KB of flash. The FRDM-KL26Z features the Freescale open standard embedded serial and debug adapter known as OpenSDA. You can find more information at following link: FRDM-KL26Z: Freescale Freedom Development Platform for Kinetis KL16 and KL26 MCUs (up to 128 KB Flas...
The second required board for this example is the Freescale's Freedom Development Platform for Multiple Xtrinsic Sensors, the FRDM-FXS-MULTI. It is a sensor expansion board that contains 7 sensors among which is the FXAS21000 Xtrinsic 3-axis gyroscopic sensors.
This example is using above mentioned tools to create data acquisition system (DAQ) for acquiring angular rate data measured in deg/s from the FXAS21000 Xtrinsic 3-axis gyroscopic sensors (Gyro). For data logging and visualization of acquired data FreeMASTER tool is used. The output is in 3 directions of rotation. Around X direction is for the Roll (around longitudinal axis), around Y direction is for the Pitch (around the lateral axis) and around Z direction for the Yaw (around the vertical axis).
The Gyro embedded registers are accessed through an I2C serial interface and routed to KL26Z I2C 1 module with following pin association.
Precisely the 7-bit I2C slave address is 0x20 (SA0=0) and SCL1, SDA1 lines are routed to port C of the I2C 1 module at KL26Z board pins PTC1 and PTC2:
Proper interrupt INT1_GYRO at J1-6 needs to be routed via jumper on J6 to INT_GYRO as shown in following block diagram since the interrupts are shared with other sensors:
This is then handled as GPIO port A: PTA at the KL26Z board and configured for the falling edge interrupts.
For more details see the schematics of the FRDM-FXS-MULTI block diagram.
This example illustrates:
1. Initialization of the KL26Z MCU (I2C and PORT modules).
2. Initialization of the Gyro to achieve the resolution 0.025 dsp/LSB with +/-200 dps range and a high-pass filter on.
3. Output data reading using an interrupt technique.
4. Conversion of the output values from registers 0x01 – 0x06 to real values in deg/s.
5. Visualization of the output values in the FreeMASTER tool.
1. According to the schematic, the INT1_GYRO output of the FXAS21000 is connected to the PTA5 pin of the KL26Z MCU and both SCL and SDA lines are connected to the I2C1 module (PTC1 and PTC2 pins). The MCU is, therefore, configured as follows:
void MCU_Init(void){
//I2C1 module initialisation
SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK; // Turn on clock to I2C1 module
SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; // Turn on clock to Port C module
PORTC_PCR1 = PORT_PCR_MUX(2); // PTC1 pin is I2C1 SCL1 line pin alternative
PORTC_PCR2 = PORT_PCR_MUX(2); // PTC2 pin is I2C1 SDA1 line pin alternative
I2C1_F = 0x14; // SDA hold time = 2.125us, SCL start hold time = 4.25us, SCL stop hold time = 5.125us
I2C1_C1 = I2C_C1_IICEN_MASK; // Enable I2C1 module
//Configure the PTA5 pin (connected to the INT_GYRO of the FXAS21000) for falling edge interrupts
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; // Turn on clock to Port A module
PORTA_PCR5 |= (0|PORT_PCR_ISF_MASK| // Clear the interrupt flag
PORT_PCR_MUX(0x1)| // PTA5 is configured as GPIO
PORT_PCR_IRQC(0xA)); // PTA5 is configured for falling edge interrupts
//Enable PORTA interrupt on NVIC
NVIC_ICPR |= 1 << ((INT_PORTA - 16)%32);
NVIC_ISER |= 1 << ((INT_PORTA - 16)%32);
}
2. At the beginning of the initialization, all Gyro registers are reset to their default values by setting the RST bit of the CTRL_REG1 register. Also the ZR_cond in CTRL_REG1 to trigger the offset compensation is enabled and hold till ZR_cond offset compensation is accomplished. This is meant to be used only when the IC is in zero rate condition on all axes. Writing a '1' to this bit initiates the internal zero-rate offset calibration. The ZR_cond bit self-clears after the zero-rate offset calculation, and it can only be used once after a hard or soft reset has occurred. The measuring range of Gyro is set to ±200 dps and to achieve the highest resolution the ODR = 1.5625Hz (640ms) and the High-pass filter is enabled with H-P filter cutoff frq.:0.047 Hz.
void Gyro_Init (void){
unsigned char reg_val = 0;
I2C_WriteRegister(FXAS21_I2C_ADDRESS, CTRL_REG1, 0x40); // Reset all registers to POR values
do // Wait for the RST bit to clear
{
reg_val = I2C_ReadRegister(FXAS21_I2C_ADDRESS, CTRL_REG1) & 0x40;
} while (reg_val);
// Zero values initialisation ------------------------------------------------------------
// I2C_WriteRegister(FXAS21_I2C_ADDRESS, CTRL_REG1, 0x80); // ZR_cond to trigger offset compensation
do // wait till ZR_cond to trigger offset compensation accomplished
{
reg_val = I2C_ReadRegister(FXAS21_I2C_ADDRESS, CTRL_REG1) & 0x80;
} while (reg_val);
//----------------------------------------------------------------------------------------
I2C_WriteRegister(FXAS21_I2C_ADDRESS, CTRL_REG2, 0x0C); // Enable DRDY interrupt, DRDY interrupt routed to INT1 - PTA5, Push-pull, active low interrupt
I2C_WriteRegister(FXAS21_I2C_ADDRESS, CTRL_REG0, 0x17); // High-pass filter enabled, H-P filter cutoff frq.:0.047 Hz, +/-200 dps range -> 0.025 dsp/LSB = 40 LSB/dps
I2C_WriteRegister(FXAS21_I2C_ADDRESS, CTRL_REG1, 0x1E); // ODR = 1.5625Hz(640ms), Active mode
}
Below are the snap shots of write and read section of the registers from the instructions above.
3. In the ISR, only the interrupt flag is cleared and the DataReady variable is set to indicate the arrival of new data.
void PORTA_IRQHandler(){
PORTA_PCR5 |= PORT_PCR_ISF_MASK; // Clear the interrupt flag
DataReady = 1;
}
4. The output values from Gyro registers 0x01 – 0x06 are first converted to signed 14-bit values and afterwards to real values in deg/s.
while(1){
if (DataReady){ // Is a new set of data ready?
DataReady = 0;
I2C_ReadMultiRegisters(FXAS21_I2C_ADDRESS, OUT_X_MSB_REG, 6, GyrData); // Read data output registers 0x01-0x06
Xout_14_bit = ((short) (GyrData[0]<<8 | GyrData[1])) >> 2;// Compute 14-bit X-axis output value
Yout_14_bit = ((short) (GyrData[2]<<8 | GyrData[3])) >> 2;// Compute 14-bit Y-axis output value
Zout_14_bit = ((short) (GyrData[4]<<8 | GyrData[5])) >> 2;// Compute 14-bit Z-axis output value
Roll = ((float) (Xout_14_bit)) / SENGYR_025D; // Compute X-axis output value in dps
Pitch = ((float) (Yout_14_bit)) / SENGYR_025D; // Compute Y-axis output value in dps
Yaw = ((float) (Zout_14_bit)) / SENGYR_025D; // Compute Z-axis output value in dps
Temperature on the Gyro is also read out from the TEMP register of the Gyro
Temp = (signed char) I2C_ReadRegister(FXAS21_I2C_ADDRESS, TEMP_REG); // temperature on Gyro
5. The calculated values can be watched in the "(x)= Variables" window on the top right of the Debug perspective of the CodeWarrior IDE or in the FreeMASTER application.
To open and run the FreeMASTER project, install the FreeMASTER 1.4 application and FreeMASTER Communication Driver that can be downloaded from following link:
FREEMASTER: FreeMASTER Run-Time Debugging Tool
User Guide for FreeMASTER is available within the installation.
For board communication in FreeMASTER following Options of Plug-in Module needs to be selected and configured for the BDM P&E Kinetis cable settings:
FreeMASTER in action screenshot:
Enjoy the Freescale Gyro.