Hi i encounter an odd response when trying to use the A_VECM feature in FXOS8700.
i have the following piece of code:
MMA865x_Standby();
IIC_RegWrite(CTRL_REG4,0x02); //Disable Data Ready interrupts, enable A_VECM interrupts
IIC_RegWrite(A_VECM_THS_MSB,0x80); //update MSB THS, reset when condition fails
print_string("A_VECM_THS_MSB= ",16); print_hex(IIC_RegRead(A_VECM_THS_MSB)); WaitPrintBuffer();
IIC_RegWrite(A_VECM_THS_LSB,Acc_THS); //update LSB THS
print_string("A_VECM_THS_LSB= ",16); print_hex(IIC_RegRead(A_VECM_THS_LSB)); WaitPrintBuffer();
IIC_RegWrite(A_VECM_CNT,Acc_COUNT); //update counter
print_string("A_VECM_CNT= ",13); print_hex(IIC_RegRead(A_VECM_CNT)); printENTER; WaitPrintBuffer();
IIC_RegWrite(A_VECM_CFG,0x78); //0111 1000 Latch enable, A_VECM_INIT, don't update reference when event
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03))); //Enable Accelerometer_Only
Data_Mode= Accelerometer_Only; //notify EX0 interrupt to read Accelerometer data
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20))); //Disable autoincrement mode
// IntSource=IIC_RegRead(TRANSIENT_SRC); //Read 0x1E TRANSIENT_SRC register to clear the interrupt
MMA865x_Active(); //ACTIVATE THE SENSOR
with this code the program works fine and every time i move the device A_VECM is asserted.
in this stage i decided to delete the print_string() lines.
after i did that the A_VECM is asserted once and not asserted anymore.
i tried to replace the print_string() lines with simple delay: for(i=0; i<60000; i++);
with this line, again A_VECM is asserted with no problems.
i can read CNTR_REG4 and it is set to 0x02. nevertheless the A_VECM is not asserted.
any idea what is the reason for that?
thanks
Hi Meir,
Please look at my example code. You need to read the INT_SOURCE register (0x0C) to clear the the SRC_A_VECM status bit and deassert the INTx pin.
Hope it helps.
Regards,
Tomas
PS: If my answer helps to solve your question, please mark it as "Correct". Thank you.
Hi Tomas
thanks for your prompt response.
Unfortunately I can’t open the link you sent for your example code.
Indeed I copied paste a previous piece of code from a program deal with Transient interrupt so I read the transient source instead of INT_Source.
The piece of code I attached in my question is the last part of handling the A_VECM interrupt.
Immediately after the interrupt is asserted I do read INT_SOURCE register.
Finally, I changed the line as you suggested
// IntSource=IIC_RegRead(TRANSIENT_SRC); //Read 0x1E TRANSIENT_SRC register to clear the interrupt
and replaced it with
IntSource=IIC_RegRead(INT_SOURCE); //Read 0x0C INT_SOURCE register to clear the interrupt
The problem still exist.
The point in my case is a beat different.
It looks like if I have a delay after the line:
IIC_RegWrite(CTRL_REG4,0x02); //Disable Data Ready interrupts, enable A_VECM interrupts
I do get interrupts.
The delay is either by setting and printing several registers (see the code I sent in my question),
or even by simple for(i=0; i<60000; i++); to implement the delay.
In these cases I do get A_VECM interrupts after the first one, which is always asserted as expected.
If the delay is not implemented I don't get interrupts after the 1st that was asserted.
thanks
Meir SUDRY
Hi Meir,
Sorry, the correct link is: https://community.freescale.com/docs/DOC-106050
Please try to reproduce my settings and let me know if the problem persists.
Regards,
Tomas
Hi Tomas
thanks for the correct link.
the problem still exist.
see below more details (code) of my project
Sensor initialization:
MMA865x_Standby();
IIC_RegWrite(CTRL_REG4,0x02);
IIC_RegWrite(A_VECM_THS_MSB,0x80);
IIC_RegWrite(A_VECM_THS_LSB,Acc_THS);
IIC_RegWrite(A_VECM_CNT,Acc_COUNT);
IIC_RegWrite(A_VECM_INITX_MSB, 0x00);
IIC_RegWrite(A_VECM_INITX_LSB, 0x00);
IIC_RegWrite(A_VECM_INITY_MSB, 0x00);
IIC_RegWrite(A_VECM_INITY_LSB, 0x00);
IIC_RegWrite(A_VECM_INITZ_MSB, 0x00);
IIC_RegWrite(A_VECM_INITZ_LSB, 0x00);
IIC_RegWrite(A_VECM_CFG,0x78);
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03)));
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20)));
MMA865x_Active();
IntSource=IIC_RegRead(INT_SOURCE);
now I'm polling for A_VECM event
General_IntSource= IIC_RegRead(INT_SOURCE);
if (General_IntSource&0x02) readdata();
and finally the function readdata()
void readdata(void) //
{
IntSource=IIC_RegRead(INT_SOURCE);
MMA865x_Standby();
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))|0x03)); //hybrid mode
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))|0x20)); //enable magnetic auto increment
IIC_RegWrite(CTRL_REG4,0x01); //enable data ready interrupts and disable A_VECM interrupts
MMA865x_Active(); //ACTIVATE THE SENSOR
here I read several times the accelerometer and magnetic data using data ready interrupt to retrieve new data
after finalizing reading data I set the parameters to re-accept A_VECM interrupts
MMA865x_Standby();
IIC_RegWrite(CTRL_REG4,0x02); //Disable Data Ready interrupts, enable A_VECM interrupts
for (i=0; i<60000; i++); - if this line is removed the A_VECM interrupt is not asserted anymore unless I restart the system
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03))); //Enable Accelerometer_Only
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20))); //Disable autoincrement mode
MMA865x_Active(); //ACTIVATE THE SENSOR
IntSource=IIC_RegRead(INT_SOURCE); //Read 0x0C INT_SOURCE register to clear the interrupt
}
the first interrupt is always asserted and the system works as expected. i get all data readings.
when the delay line is placed also the system is working fine. the question is why is it needed at all.
i got the idea that the delay is needed because i had there several lines of printing for the debugging. once i removed those lines i stopped getting interrupts after the first A_VECM.
after an investigation i made i realized that a delay after setting CTRL_ REG4 is required in order to get the successive interrupts.
i positively know the interrupt in no asserted because in debug mode i can see the General_IntSource variable get the value of 0x00.
I would appreciate if you can look into this case and come with your insights.
thanks
Meir
MMA865x_Standby(); IIC_RegWrite(CTRL_REG4,0x02); IIC_RegWrite(A_VECM_THS_MSB,0x80); IIC_RegWrite(A_VECM_THS_LSB,Acc_THS); IIC_RegWrite(A_VECM_CNT,Acc_COUNT); IIC_RegWrite(A_VECM_INITX_MSB, 0x00); IIC_RegWrite(A_VECM_INITX_LSB, 0x00); IIC_RegWrite(A_VECM_INITY_MSB, 0x00); IIC_RegWrite(A_VECM_INITY_LSB, 0x00); IIC_RegWrite(A_VECM_INITZ_MSB, 0x00); IIC_RegWrite(A_VECM_INITZ_LSB, 0x00); IIC_RegWrite(A_VECM_CFG,0x78);
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03))); IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20))); MMA865x_Active(); IntSource=IIC_RegRead(INT_SOURCE);