MMA8451Q I2C questions

Showing results for 
Search instead for 
Did you mean: 

MMA8451Q I2C questions

Contributor II


I am running FIFO in "stop when full mode" at 400KHz I2C clock.

The sample rate is 800Hz and 400Hz.... switching over to 400Hz after 24 hours.

Due to the microprocessor MSP430  issues I have very few options to complete the FIFO transfer.

Question 1:

      In the I2C specification (Notes on page 14 of the Rev6 version) the following is stated:

      "5. A START condition immediately followed by a STOP condition (void message) is an illegal format. Many devices          however are designed to operate properly under this condition."

Q1:  Will the MMA8451Q operate correctly if the last byte of a FIFO transfer is completed by this I2C sequence.

(Start immediately followed by Stop with no other clocks in between)

Depending on your answer I may need to ask further questions to achieve a work around.

regards John Campbell

Labels (1)
2 Replies

NXP Employee
NXP Employee

Hello John,

Thank you for writing.

Unfortunately, it is not possible to read the FIFO of the MMA8451Q the way that you want. It is needed to read all the FIFO using the repeat start condition. If you could not fill the FIFO in the correct way, you could try to disable the FIFO and read the data one by one.

Furthermore, I am going to copy a code that I made. What the code does is fill and read the full FIFO from the MMA8451Q.

uint8_t FIFO_DataReady=0;
uint8_t FIFO_Status;
unsigned char AccelData[6*Watermark_Val];
short Xout_Accel_14_bit[Watermark_Val], Yout_Accel_14_bit[Watermark_Val], Zout_Accel_14_bit[Watermark_Val];
float Xout_g[Watermark_Val], Yout_g[Watermark_Val], Zout_g[Watermark_Val];

void MMA8451_init();
void MCU_init();

int main(void){    
  int counter = 0;    
  uint8_t i=0;    
  for(;;) {             
    if (FIFO_DataReady)                  
      FIFO_DataReady = 0;                      
      FIFO_Status = I2C_ReadRegister(MMA845x_I2C_ADDRESS, STATUS_REG);        // Read the Status register to clear the FIFO interrupt status bit                                   
      I2C_ReadMultiRegisters(MMA845x_I2C_ADDRESS, OUT_X_MSB_REG, 6*Watermark_Val, AccelData);        // Read the FIFO using a burst read                                             
      for (i = 0; i < Watermark_Val; i++)                      
        // 14-bit accelerometer data               
        Xout_Accel_14_bit[i] = ((short) (AccelData[0 + i*6]<<8 | AccelData[1 + i*6])) >> 2;            // Compute 14-bit X-axis acceleration output value          
        Yout_Accel_14_bit[i] = ((short) (AccelData[2 + i*6]<<8 | AccelData[3 + i*6])) >> 2;            // Compute 14-bit Y-axis acceleration output value                
        Zout_Accel_14_bit[i] = ((short) (AccelData[4 + i*6]<<8 | AccelData[5 + i*6])) >> 2;            // Compute 14-bit Z-axis acceleration output value                                                       

        // Accelerometer data converted to g's                
        Xout_g[i] = ((float) Xout_Accel_14_bit[i]) / SENSITIVITY_2G;        // Compute X-axis output value in g's           
        Yout_g[i] = ((float) Yout_Accel_14_bit[i]) / SENSITIVITY_2G;        // Compute Y-axis output value in g's             
        Zout_g[i] = ((float) Zout_Accel_14_bit[i]) / SENSITIVITY_2G;        // Compute Z-axis output value in g's          

return 0;

void MCU_init()
  //I2C0 module initialization  
  SIM_SCGC4 |= SIM_SCGC4_I2C0_MASK;        // Turn on clock to I2C0 module   
  SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;        // Turn on clock to Port E module   
  PORTE_PCR24 = PORT_PCR_MUX(5);            // PTE24 pin is I2C0 SCL line   
  PORTE_PCR25 = PORT_PCR_MUX(5);            // PTE25 pin is I2C0 SDA line   
  I2C0_F  = 0x14;                         // SDA hold time = 2.125us, SCL start hold time = 4.25us, SCL stop hold time = 5.125us *  
  I2C0_C1 = I2C_C1_IICEN_MASK;            // Enable I2C0 module            

  //Configure the PTA14 pin (connected to the INT1 of the MMA8451Q) for falling edge interrupts   
  SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;        // Turn on clock to Port A module    
  PORTA_PCR14 |= (0|PORT_PCR_ISF_MASK|    // Clear the interrupt flag             
                       PORT_PCR_MUX(0x1)|    // PTA14 is configured as GPIO                
                       PORT_PCR_IRQC(0xA));    // PTA14 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); }

void MMA8451_init()
  unsigned char reg_val = 0;          
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG2, 0x40);        // Reset all registers to POR values          
  do        // Wait for the RST bit to clear    
      reg_val = I2C_ReadRegister(MMA845x_I2C_ADDRESS, CTRL_REG2) & 0x40;     
  }     while (reg_val);  
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, 0x00);     // Standby mode    
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, F_SETUP_REG, 0xA0);    // FIFO Fill mode, 32 samples    
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG4, 0x40);    // Enable FIFO interrupt, push-pull, active low     
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG5, 0x40);    // Route the FIFO interrupt to INT1 - PTA5    
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, XYZ_DATA_CFG_REG, 0x00);        // +/-2g range -> 1g = 16384/4 = 4096 counts   
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG2, 0x02);        // High Resolution mode  
  I2C_WriteRegister(MMA845x_I2C_ADDRESS, CTRL_REG1, 0x3D);    // ODR = 1.56Hz, Reduced noise, Active mode    

void PORTA_IRQHandler()
  PORTA_PCR14 |= PORT_PCR_ISF_MASK;                    // Clear the interrupt flag   
  FIFO_DataReady = 1;

P.S. I am using the FRDM-KL25Z microcontroller.

Contributor I

Thank you so much for your code. It helps me a lot.

0 Kudos