MMA8652FC - Auto-WAKE/SLEEP mode

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

MMA8652FC - Auto-WAKE/SLEEP mode

MMA8652FC - Auto-WAKE/SLEEP mode

Hello Community,

 

One of the main features of the NXP accelerometers is the Auto-WAKE/SLEEP mode.

 

I would like to share this project in order to demonstrate the feasibility of using the Low-power and auto-WAKE/SLEEP modes for reducing current consumption in the different NXP accelerometers such as the MMA845x and MMA865x series.

158750_158750.jpg8652.jpg

 

I created this project using the FRDM-KL25Z platform and the MMA8652FC accelerometer (You may find the breakout board files here). The complete source code is written in CodeWarrior v10.x IDE.

 

This document gives you an introduction of the MMA8652FC accelerometer as well as the different power consumptions and guides you through the initialization process and how to appreciate the demonstration:

 

  1. Initialization of the MKL25Z128 MCU.
  2. Initialization of the MMA8652FC.
  3. Auto-WAKE/SLEEP mode.
  4. MMA8652FC Embedded functions.
  5. Interrupt handlers.
  6. Evaluation of the interrupt source.
  7. Summarizing the application and Macros definition.
  8. Visualization of the current consumption.

 

1. As you can see in the FRDM-KL25Z schematic and the image below, the I2C signals are routed to the I2C1 module (PTC1 and PTC2 pins) of the KL25Z MCU and the INT1 and INT2 outputs are connected to the PTD5 and PTA5 pins. The INT1 and INT2 outputs of the MMA8652FC are configured as a push-pull active-low outputs, so the corresponding PTD5 and PTA5 pins configuration are GPIOs with an interrupt on falling edge.

158751_158751.jpgfrdm.jpg

 

The MCU is, therefore, configured as follows:

 

 

     /* I2C1 module initialization */

     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(0x2);         // PTC1 pin is I2C1 SCL line

     PORTC_PCR2 |= PORT_PCR_MUX(0x2);         // PTC2 pin is I2C1 SDA line

     I2C1_F  |= I2C_F_ICR(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 PTD5 and PTA5 pin (connected to the INT1 and INT2 of the MMA8652FC) for falling edge interrupts */

     SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;       // Turn on clock to Port D module

     PORTD_PCR5 |= (0|PORT_PCR_ISF_MASK|      // Clear the interrupt flag

                          PORT_PCR_MUX(0x1)|  // PTD5 is configured as GPIO

                          PORT_PCR_IRQC(0xA));// PTD5 is configured 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 PORTD interrupt on NVIC */

     NVIC_ICPR |= 1 << ((INT_PORTD - 16)%32);

     NVIC_ISER |= 1 << ((INT_PORTD - 16)%32);

     /* Enable PORTA interrupt on NVIC */

     NVIC_ICPR |= 1 << ((INT_PORTA - 16)%32);

     NVIC_ISER |= 1 << ((INT_PORTA - 16)%32);

 

 

2. The MMA8652FC is an intelligent, low-power, three-axis, capacitive micromachined accelerometer with 12 bits of resolution.

 

At the beginning of the initialization, all registers are reset to their default values by setting the RST bit of the CTRL_REG2 register. The Normal and Low Power modes are set in the same register. The MODS[1:0] bits select which Oversampling mode is to be used. The Oversampling modes are available in both WAKE Mode MOD[1:0] and also in the SLEEP Mode SMOD[1:0].

 

158752_158752.jpgmods.jpg

Then the MMA8652FC is initialized as shown below:

 

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG2, 0x40);        // Reset all registers to POR values

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

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, XYZ_DATA_CFG_REG, 0x00); // +/-2g range with ~0.977mg/LSB      

 

     /* Power Mode Configuration */

     If LOW power mode is selected:

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG2, 0x1B);        // Low Power mode

 

     If NORMAL power mode is selected:

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG2, 0x00);        // Normal mode

 

 

3. As I mentioned, one of the main features of the MMA8652FC is the Auto-WAKE/SLEEP mode.

 

The advantage of using the Auto-WAKE/SLEEP is that the system can automatically transition to a higher sample rate (higher current consumption) when needed, but spends the majority of the time in the SLEEP mode (lower current) when the device does not require higher sampling rates.

 

Auto-WAKE refers to the device being triggered by one of the interrupt functions to transition to a higher sample rate. This may also interrupt the processor to transition from a SLEEP mode to a higher power mode.

SLEEP mode occurs after the accelerometer has not detected an interrupt for longer than the user-definable timeout period.

 

 

159611_159611.jpgsleep.jpg

 

At the ASLP_COUNT register, you can set the minimum time period of inactivity required to switch the part between Wake and Sleep status, in this case, 5 seconds.

 

The Auto-WAKE/SLEEP mode, therefore, is configured as follow:

 

     read_reg = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG2);

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG2, read_reg|0x04);  // Auto-SLEEP enable

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, ASLP_COUNT_REG, 0x10);      // 5 seconds (16 * 320ms)

     read_reg = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG4);

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG4, read_reg|0x80);  // Enable AutoSleep interrupt, INT2 - PTD5

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG1, 0xC1);           // ODR=800Hz and Sleep mode ODR=1.56Hz, Active mode

 

 

4. The device can be configured to generate inertial wake-up interrupt signals from any combination of the configurable embedded functions, enabling the MMA8652FC to monitor inertial events while remaining in a low-power mode during periods of inactivity.

 

The Interrupts that can WAKE the device from SLEEP are:

Tap Detection, Orientation Detection, Motion/Freefall, and Transient Detection.

 

159612_159612.jpginterrupts.jpg

 

 

In this project, the TAP (Pulse) or Transient interrupts are used to wake up the device from the SLEEP. In order to get more information about the TAP detection, please click here.

 

The MMA8652FC is configured as below:

 

     If Transient interrupt is selected:

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, TRANSIENT_THS_REG, 0x84);         // Set threshold to 252mg (4 x 63mg )

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, TRANSIENT_COUNT_REG, 0x02);       // Set debounce timer period to 40ms (low power mode) / 2.5ms (normal mode)-Table 66

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, TRANSIENT_CFG_REG, 0x17);         // Enable transient detection for X and Y axis, latch enabled 

 

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG3, 0x40);                 // Wake from Transient interrupt, Push-pull, active low interrupt

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG4, 0x20);                 // Enable Transient detection interrupt

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG5, 0x20);                 // Transient interrupt routed to INT1 - PTA5

 

 

     If TAP interrupt is selected:

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, PULSE_CFG_REG, 0x15);             // Enable X, Y and Z Single Pulse

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, PULSE_THSX_REG, 0x20);            // Set X Threshold to 2.016g

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, PULSE_THSY_REG, 0x20);            // Set Y Threshold to 2.016g

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, PULSE_THSZ_REG, 0x2A);            // Set Z Threshold to 2.646g

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, PULSE_TMLT_REG, 0x28);            // Set Time Limit for Tap Detection to 25 ms

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, PULSE_LTCY_REG, 0x28);            // Set Latency Time to 50 ms. During this time interval, all pulses are ignored

   

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG3, 0x10);                 // Wake from Pulse interrupt, Push-pull, active low interrupt

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG4, 0x08);                 // Pulse detection interrupt enabled

     I2C_WriteRegister(MMA8652FC_I2C_ADDRESS, CTRL_REG5, 0x08);                 // Pulse interrupt routed to INT1 - PTA5

 

 

5. As I mentioned above, the TAP (Pulse) or Transient interrupts are used to wake up the device from the SLEEP. Besides, if Auto-SLEEP interrupt is enabled, then transitioning from ACTIVE mode to Auto-SLEEP mode (or vice versa) generates an interrupt.

 

In this project, the Auto-SLEEP, the TAP (Pulse) or the Transient interrupts are enable. The MKL25Z128 responds to these interrupts reading the INT_SOURCE (0x0C) register, in order to determine the appropriate sources of the interrupt.

 

Every source of interrupt has its own way to clear the interrupt flag. Please refer to the comments of each ISR:

 

     Transient interrupt handler

     void PORTA_IRQHandler()

     {

        PORTA_PCR5 |= PORT_PCR_ISF_MASK;                // Clear the PTC interrupt

        int_source = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, INT_SOURCE_REG); // Clear interrupt Source Register

          if(int_source&0x20)  // Transient interrupt ?

        {

           i = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, TRANSIENT_SRC_REG); // Read the TRANSIENT_SRC register to clear the SRC_TRANS flag in the INT_SOURCE register 

           transient_int = 1;

        }

     }

 

     TAP interrupt handler

     void PORTA_IRQHandler()

     {

        PORTA_PCR5 |= PORT_PCR_ISF_MASK;                // Clear the PTC interrupt flag

        int_source = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, INT_SOURCE_REG); // Clear interrupt Source Register

           if(int_source&0x08)  // Pulse interrupt ?

        {

           i = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, PULSE_SRC_REG); // Read the PULSE_SRC register to clear the SRC_TRANS flag in the INT_SOURCE register 

           pulse_int = 1;

        }

     }

 

     Auto WAKE/SLEEP interrupt handler

     void PORTD_IRQHandler()

     {

         PORTD_PCR5 |= PORT_PCR_ISF_MASK;                // Clear the PTD interrupt flag

            int_source = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, INT_SOURCE_REG); // Clear interrupt Source Register

            if (int_source&0x80) // Auto Sleep/Wake interrupt ?

         {

            i = I2C_ReadRegister(MMA8652FC_I2C_ADDRESS, SYSMOD_REG);      // Read the SYSMOD register to clear the SRC_ASLP flag in the INT_SOURCE register

            sleep_int = 1;

         }

     }

 

 

6. At this point, the configuration of the MCU and the accelerometer is done.

The RGB LED contained on the FRDM-KL25Z board is configured in order to help showing the behavior of the application. This behavior is configured as follow:

 

     #if TRANSIENT_DETECTION

                   if (transient_int){            

                transient_int = 0;

                TURN_BLUE_ON(); TURN_RED_OFF();}

     #elif TAP_DETECTION

                   if (pulse_int){

                pulse_int = 0;

                TURN_BLUE_ON(); TURN_RED_OFF();}

     #endif

                   if (sleep_int){

                 sleep_int = 0;

                 TURN_RED_ON(); TURN_BLUE_OFF();}

 

 

7. In summary, the FRDM-KL25Z will be interfacing with the MMA8652FC. The power mode will be set and the interrupts will be enabled.

The macros at the top of the source code will allow us to select between the different power modes, the different embedded functions and to select the Auto-WAKE/SLEEP function.

 

If the Auto-WAKE/SLEEP function is enabled, the MMA8652FC will go into the SLEEP mode (ODR=1.56Hz) after 5 seconds of inactivity. The RED LED will be set.

When an interrupt from the embedded functions is generated, the MMA8652FC will be awakened (ODR=800Hz) and so on. The BLUE LED will be set.

 

     /* Select the Power Mode - Table 101 from datasheet */

     #define NORMAL_MODE        1

     #define LOW_POWER_MODE     0

  

     /* Select the Embedded Function */

     #define TRANSIENT_DETECTION       1

     #define TAP_DETECTION             0

 

     /* Auto-WAKE/SLEEP Function */

     #define AUTO_SLEEP   1

 

 

8. The Table 5 from the datasheet shows the expected current consumption in regard with the power mode and ODR selected:

 

159613_159613.jpglowpowertable.jpg

As I mentioned before, the Sleep mode allow us to change between different Output Data Rates (ODR) dynamically so we can reduce the current consumption.

 

In order to verify if the accelerometer is consuming the current mentioned on the datasheet, I measured the MMA8652FC current consumption using the project mentioned.

 

Please refer to the results below:

 

159614_159614.jpgnormalmode.jpg

 

 

159615_159615.jpglowpowermode.jpg

 

 

9. The advantage of using the Auto-WAKE/SLEEP mode is that the system can automatically transition to a higher sample rate (higher current consumption) when needed, but spends the majority of the time in the SLEEP mode (lower current) when the device does not require higher sampling rates.

 

In the manner we have come to expect of the MMA8652FC, the current consumption decreases when the ODR is changed from 800Hz to 1.56Hz, in both normal and low power mode.

 

The information mentioned on the datasheet is now confirmed.

 

 

Please find attached the complete source code.

 

I hope you find useful and funny this sample project. Any suggestion will be appreciated.

 

You are invited to take part of the NXP community where you can post all your questions and you may find useful material for your projects.

 

Best Regards,

David

标签 (1)
附件
评论
iot

Helo! Can you help me with my issue, please!

We try to use MMA8652FC as a pulse counter. It works but not exactly as we expect. We can't get an interval when pulses are ignored.

We work with the next configuration:

XYZ_DATA_CFG  = 0x10;// 2g mode
HP_FILTER_CUTOFF
 = 0;// high-pass filter on, low-pass filter off

CTRL_REG1 = 0x69;//ASLP rate 12.5 Hz, data-rate - 12.5 Hz

CTRL_REG2 = 0x1F;//smod - low power, auto-sleep enable, mod - low-power

CTRL_REG3 = 0x11;//wake-pulse

CTRL_REG4 = 0x08;//pulse inrerrupt enabled

PULSE_CFG = 0x10;//single-pulse Z-zxis

PULSE_THSX = 0x20;//

PULSE_THSY = 0x20;//

PULSE_THSZ = 0x2A;//

PULSE_TMLT = 0x03;//3 * 40 = 120 ms (as we understant - this is the maximal pulse width)

PULSE_LTCY = 0xFF;//80 * 255 = 20.4 s

ASLP_COUNT = 0x01;//

We really get the pulse interrupts, but we don't have this 20.4-second inactivity between pulses.

What is wrong?

Thank you in advance for your help

iot

And an additional question. Can I get the INT1 interrupt in this configuration if there is no pulse detected? I see that I receive interrupts on the INT1 pin. And when I read registers INT_SOURCE and PULSE_SRC right after the received interrupt these registers are both empty from time to time. These interrupts I receive when I try to get PULSE. 

iot

I've found out the cause of these issues - it is an auto-sleep. When the accelerometer went to sleep the INT_SOURCE and PULSE_SRC are cleared and possibly the latency counter is turning off.

无评分
版本历史
最后更新:
‎08-18-2016 09:38 AM
更新人: