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);
Pause(0x631);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, F_SETUP_REG, 0xA0);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG4, 0x40);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG5, 0x40);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG2, 0x00);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG3, 0x00);
I2C_WriteRegister(MPL3115A2_I2C_ADDRESS, CTRL_REG1, 0x39);
}
In the ISR, only the interrupt flag is cleared and the FIFO_DataReady variable is set to indicate that the FIFO is full.
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);
I2C_ReadMultiRegisters(MPL3115A2_I2C_ADDRESS, OUT_P_MSB_REG, 5*Watermark_Val, RawData);
for (i = 0; i < Watermark_Val; i++)
{
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;
Temperature[i] = (float) ((short)((RawData[3 + i*5] << 8) | (RawData[4 + i*5] & 0xF0)) >> 4) * 0.0625;
}
}
Deassertion of the INT1 pin after reading the STATUS register (0x00).

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

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

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