MPL3115A2 - FIFO Fill mode example code

cancel
Showing results for 
Search instead for 
Did you mean: 

MPL3115A2 - FIFO Fill mode example code

MPL3115A2 - FIFO Fill mode example code

Hi Everyone,

I would like to share here one of my examples I created for the MPL3115A2 while working with the NXP FRDM-KL25Z platform and FRDMSTBC-P3115 shield board. It illustrates the use of the embedded FIFO buffer to collect either pressure/temperature or altitude/temperature data that are read from the FIFO using an interrupt technique through the I2C interface. The FIFO is set to store the maximum number of samples (32). Each sample consists of 3 bytes of pressure (or altitude) data and 2 bytes of temperature data. Therefore 160 bytes (32 x (3 + 2)) in total are read from the FIFO when the FIFO is full and the FIFO interrupt is asserted.

The MPL3115A2 is initialized as follows.

/******************************************************************************
* MPL3115A2 initialization function
******************************************************************************

void MPL3115A2_Init (void)
{
 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1, 0x04); // Reset all registers to POR values

 Pause(0x631); // ~1ms delay

 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, F_SETUP_REG, 0xA0); // FIFO Fill mode, 32 samples
 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG4, 0x40); // Enable FIFO interrupt
 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG5, 0x40); // Route the FIFO interrupt to INT1 - PTA5
 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG2, 0x00); // Time step = ~1s
 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG3, 0x00); // Push-pull, active low interrupt
 I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1, 0x39); // Active barometer mode, OSR = 128
 //I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1, 0xB9); // Active altimeter mode, OSR = 128
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In the ISR, only the interrupt flag is cleared and the FIFO_DataReady variable is set to indicate that the FIFO is full.

/******************************************************************************
* PORT A Interrupt handler
******************************************************************************/

void PORTA_IRQHandler()
{
 PORTA_PCR5 |= PORT_PCR_ISF_MASK;
 FIFO_DataReady = 1;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Once the FIFO_DataReady variable is set, the STATUS register (0x00) is read to clear the FIFO interrupt status bit and deassert the INT1 pin. Afterwars the FIFO is read using a 160-byte (5 x 32 bytes) burst read starting from the OUT_P_MSB register (0x01). Then the raw pressure (or altitude) and temperature data are converted to real values.

if (FIFO_DataReady)
{
 FIFO_DataReady = 0;
 FIFO_Status = I2C_ReadRegister(MPL3115A2_I2C_ADDRESS, STATUS_REG); // Read the Status register to clear the FIFO interrupt status bit

 I2C_ReadMultiRegisters(MPL3115A2_I2C_ADDRESS, OUT_P_MSB_REG, 5*Watermark_Val, RawData); // Read the FIFO using a burst read

 for (i = 0; i < Watermark_Val; i++)
 {
 /* Get pressure, the 20-bit measurement in Pascals is comprised of an unsigned integer component and a fractional component.
 The unsigned 18-bit integer component is located in OUT_P_MSB, OUT_P_CSB and bits 7-6 of OUT_P_LSB.
 The fractional component is located in bits 5-4 of OUT_P_LSB. Bits 3-0 of OUT_P_LSB are not used. */

 Pressure[i] = (float) (((RawData[0 + i*5] << 16) | (RawData[1 + i*5] << 8) | (RawData[2 + i*5] & 0xC0)) >> 6) + (float) ((RawData[2 + i*5] & 0x30) >> 4) * 0.25;

 /* Get temperature, the 12-bit temperature measurement in °C is comprised of a signed integer component and a fractional component.
 The signed 8-bit integer component is located in OUT_T_MSB. The fractional component is located in bits 7-4 of OUT_T_LSB.
 Bits 3-0 of OUT_T_LSB are not used. */

 Temperature[i] = (float) ((short)((RawData[3 + i*5] << 8) | (RawData[4 + i*5] & 0xF0)) >> 4) * 0.0625;

 /* Get altitude, the 20-bit measurement in meters is comprised of a signed integer component and a fractional component.
 The signed 16-bit integer component is located in OUT_P_MSB and OUT_P_CSB.
 The fraction component is located in bits 7-4 of OUT_P_LSB. Bits 3-0 of OUT_P_LSB are not used */

 //Altitude[i] = (float) ((short) ((RawData[0 + i*5] << 8) | RawData[1 + i*5])) + (float) (RawData[2 + i*5] >> 4) * 0.0625;
 }
} ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Deassertion of the INT1 pin after reading the STATUS register (0x00).

Interrupt.JPG

The auto acquisition time step is set in this example to the lowest possible value (1s), so the FIFO is read every ~32s.

FIFO Flush.JPG

The calculated values can be watched in the "Variables" window on the top right of the Debug perspective.

Values.JPG

Attached you can find the complete source code. If there are any questions regarding this simple example project, please feel free to ask below. Your feedback or suggestions are also welcome.

 

Regards,

Tomas

Labels (1)
Attachments
Version history
Revision #:
2 of 2
Last update:
‎09-10-2020 02:47 AM
Updated by:
 
Contributors