icm 20948 wake on motion interrupt
NIIHARIKARAVIPROLU opened this issue · 1 comments
Hi,
I am facing a problem in icm 20948 with msp430fr5994 by using int .i set a threshold values so that onece when my threshold values is cross i should get int but here it is not happening like that without crossing also i am getting int .I was suspecting that setting of threshold value in register is not proper .
the following is my code
//macros used
//interrupts
const uint8_t REG_ACCEL_INTEL_CTRL =0x12;//userbank2
const uint8_t BIT_ACCEL_INTEL_EN =0x02;//Wake-up On Motion enable bit
const uint8_t BIT_ACCEL_INTEL_MODE =0x01;//WOM algorithm selection bit
const uint8_t REG_ACCEL_WOM_THR = 0x13; //_BANK_2 // Wake-up On Motion Threshold register
const uint8_t BIT_SLEEP =0x40; //bank0 reg 0x06 /< Sleep mode enable bit
const uint8_t BIT_SLEEP_CLEAR=0x00;//clear bit sleepin ub0,reg6
const uint8_t REG_PWR_MGMT_1 =0x06;//bank0 /< Power Management 1 register
const uint8_t REG_LP_CONFIG = 0x05;// bnk0,reg,5 //Low Power mode config register
const uint8_t BIT_ACCEL_CYCLE= 0x20;////bank0,reg,5writhe this value /< Accelerometer cycle mode enable
const uint8_t BIT_GYRO_CYCLE = 0x10;//bank0,reg5,write this value /< Gyroscope cycle mode enable
const uint8_t REG_GYRO_SMPLRT_DIV =0x00;//bank2,reg0 /< Gyroscope Sample Rate Divider regiser
const uint8_t REG_ACCEL_SMPLRT_DIV_1 = 0x10;//bank2,reg 10 /< Acceleration Sensor Sample Rate Divider
const uint8_t REG_ACCEL_SMPLRT_DIV_2 = 0x11;//bank2,reg11 /< Acceleration Sensor Sample Rate Divider 2 register */
const uint8_t SHIFT_ACCEL_DLPCFG = 3; /< Accel DLPF Config bit shift */
const uint8_t BIT_PWR_ACCEL_STBY= 0x07; //bank0,reg7 /< Disable accelerometer */
const uint8_t BIT_WOM_INT_EN = 0x08;//bank0,reg10 /< Wake-up On Motion enable bit */
const uint8_t B0_REG10=0x10;
const uint8_t EN_GYRO=0x38;
const uint8_t REG_INT_STATUS= 0x19;//bnk0 /< Interrupt Status register */
const uint8_t BIT_WOM_INT = 0x08; /< Wake-up on motion interrupt occured bit */
const uint8_t BIT_PLL_RDY = 0x04; /**< PLL ready interrupt occured bit */
int Enable_WOM_Interrupt()
{
if (changeUserBank(USER_BANK_0,0) < 0)//selecting userbank0
{
return -1;
}
if (I2C_WRITE(UB0_INT_PIN_CFG, UB0_INT_PIN_CFG_HIGH_50US) < 0)
{
return -2;
}
enable_sleepmode(false);//chacking if//it is sleep mode or not
enable_cyclemode(false);//operating in duty cycle mode
enable_sensor(true,false);//enablling accelemeter
set_sample_rate(1100.0);
enable_irq(true);//ensbling wom int
if (configAccel(ACCEL_RANGE_16G, ACCEL_DLPF_BANDWIDTH_1209HZ) < 0)//scale range 16g
{
return -3;
}
enable_irq();
__delay_cycles(50);
if (changeUserBank(USER_BANK_2,0) < 0)
{
return -4;
}
if (I2C_WRITE(REG_ACCEL_INTEL_CTRL, BIT_ACCEL_INTEL_EN|BIT_ACCEL_INTEL_MODE) < 0)//enablewomlogic,comparingprevious with current sample
{
return -5;
}
if (changeUserBank( USER_BANK_0,0) < 0)
{
return -6;
}
readSensor();
if (changeUserBank(USER_BANK_2,0) < 0)
{
return -6;
}
if (I2C_WRITE(REG_ACCEL_WOM_THR,x_Threshold)<0)//setting_threshold_value
{
return -7;
}
enableInterrupt(GPIO_PORT_P4, GPIO_PIN4);
}
uint32_t enable_irq( )
{
if (changeUserBank( USER_BANK_0,0) < 0)
{
return -1;
}
else if( I2C_WRITE(B0_REG10,BIT_WOM_INT_EN)<0)
{
return -2;
}
return 1;
}
int enable_sleepmode(bool enable)
{
if (enable)
{
if (changeUserBank( USER_BANK_0,0) < 0)
{
return -1;
}
if( I2C_WRITE(REG_PWR_MGMT_1,BIT_SLEEP)<0)
{
return -2;
}
}
else
{
if (changeUserBank( USER_BANK_0,0) < 0)
{
return -1;
}
if( I2C_WRITE(REG_PWR_MGMT_1,BIT_SLEEP_CLEAR)<0)
{
return -2;
}
}
return 1;
}
int enable_cyclemode(bool enable)
{
if (enable)
{
if (changeUserBank( USER_BANK_0,0) < 0)
{
return -1;
}
if(I2C_WRITE(REG_LP_CONFIG,(BIT_ACCEL_CYCLE|BIT_GYRO_CYCLE))<0)
{
return -2;
}
}
else
{
if (changeUserBank( USER_BANK_0,0) < 0)
{
return -1;
}
if(I2C_WRITE(REG_LP_CONFIG,(BIT_ACCEL_CYCLE&BIT_GYRO_CYCLE))<0)
{
return -2;
}
}
return 1;
}
uint32_t set_sample_rate(float sampleRate)
{
set_gyro_sample_rate(sampleRate);
set_accel_sample_rate(sampleRate);
return 1;
}
float set_gyro_sample_rate(float sampleRate)
{
uint8_t gyroDiv;
float gyroSampleRate;
/* Calculate the sample rate divider */
gyroSampleRate = (1125.0 / sampleRate) - 1.0;
/* Check if it fits in the divider register */
if ( gyroSampleRate > 255.0 )
{
gyroSampleRate = 255.0;
}
if ( gyroSampleRate < 0 )
{
gyroSampleRate = 0.0;
}
/* Write the value to the register */
gyroDiv = (uint8_t) gyroSampleRate;
if(changeUserBank( USER_BANK_2,0) < 0)
{
return -1;
}
if(I2C_WRITE(REG_GYRO_SMPLRT_DIV, gyroDiv)<0)
{
return -2;
}
/* Calculate the actual sample rate from the divider value */
gyroSampleRate = 1125.0 / (gyroDiv + 1);
return gyroSampleRate;
}
float set_accel_sample_rate(float sampleRate)
{
uint16_t accelDiv;
float accelSampleRate;
/* Calculate the sample rate divider */
accelSampleRate = (1125.0 / sampleRate) - 1.0;
/* Check if it fits in the divider registers */
if ( accelSampleRate > 4095.0 ) {
accelSampleRate = 4095.0;
}
if ( accelSampleRate < 0 ) {
accelSampleRate = 0.0;
}
/* Write the value to the registers */
accelDiv = (uint16_t) accelSampleRate;
I2C_WRITE(REG_ACCEL_SMPLRT_DIV_1, (uint8_t) (accelDiv >> 8) );
I2C_WRITE(REG_ACCEL_SMPLRT_DIV_2, (uint8_t) (accelDiv & 0xFF) );
/* Calculate the actual sample rate from the divider value */
accelSampleRate = 1125.0 / (accelDiv + 1);
return accelSampleRate;
}
uint32_t enable_sensor(bool accel, bool gyro)
{
// uint8_t pwrManagement1;
// uint8_t pwrManagement2;
// pwrManagement2 = 0;
if ( accel )
{
if (changeUserBank(USER_BANK_0,0) < 0 )
{
I2C_WRITE(UB0_PWR_MGMNT_2, BIT_PWR_ACCEL_STBY);
return -1;
}
}
else if ( gyro )
{
if (changeUserBank(USER_BANK_0,0) < 0 )
{
I2C_WRITE(UB0_PWR_MGMNT_2, EN_GYRO);
return -2;
}
}
return 1;
}
this is when i get interuupt in took a pin
void int_pin()
{
GPIO_setAsInputPin(GPIO_PORT_P4,GPIO_PIN4);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4,GPIO_PIN4);
GPIO_selectInterruptEdge(GPIO_PORT_P4, GPIO_PIN4, GPIO_LOW_TO_HIGH_TRANSITION);
GPIO_clearInterrupt(GPIO_PORT_P4,GPIO_PIN4);
}
#pragma vector=PORT4_VECTOR
__interrupt void Port_4(void) //ISR
{
Tx_Uart0_String("\nharsh_braking");///when my threshold values crosses it should here but if axis
value is less than threshold value then also it is in isr and not clearing
GPIO_clearInterrupt(GPIO_PORT_P4, GPIO_PIN4);
}
so is there any thing i need to add or change should be done mail me naga.niharika09@gmail.com as early as possible
so i haave codded in such a format that i keep on reading accelerometer axis values but once threshold values crosses reaches ISR
Thanks in advance
Have you figured it out already?