2017-12-03 11:07 PM
Good day all
My LIS2DH12 seems to lock up or stops responding, it is connected to STM32L152 which is set to go into STOPMODE and wakes on interrupt. An I/O pin is configured as an external interrupt and connected to INT1 of the LIS2DH12. When the LIS2DH12 is Tilted the interrupt wakes up the processor and a buzzer sounds.
I have build 15 units and they all seem to randomly stop working.
Some of the units run 1-5minutes before it locks up and the interrupt pin stops toggling when moved, a few units will run a few hours, others may run 2-3 days. but eventually they all lock up. At this stage i am uncertain if its hardware or software.
My setup code is as follows (included are also other setups I have tried while i was experimenting ). To my understanding, once the LIS2DH12 is setup it should toggle the interrupt as long as power is applied to the chip irrespective of the processor it is connected to.
CODE :// setup lis2dh12 //TEMPe_en1|TEMP_en2 = 0x00 00000000 // disable temperature I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_TEMP_CFG_REG, 0x00, 1); // nothing to change here //REG 1: ODR3|ODR2|ODR1|ODR0|LPen|Zen|Yen|Xen //* 0x77 (1hz) normal power 10 bit mode normal mode //** 0x5F 01011111 (100hz) low power 8 bit mode normal mode also set CNRL_REG4[3] to 0 //*** 0x7F 01011111 (400hz) low power 8 bit mode normal mode also set CNRL_REG4[3] to 07 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG1, 0x7F, 1); // low power 400hz //REG 2: HPM1|HPM0|HPCF2|HPCF1|FDS|HPCLICK|HP_IA2|HP_IA1 //* 0x00 bypass all filters set to normal mode //** 0x04 00000100 HP Click only //*** 0x06 00000110 HP click and IA2 //**** 0x09 00001001 high pass filter enabled on interrupt activity 1 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG2, 0x00, 1); //all High pass filter setup //REG 3: I1_CLICK|I1_IA1|I1_IA2|I1_ZYXDA|0|I1_WMT|I1_OVERUN |-- //* 0x00 00000000 disable all no click,no ai1/2 interrupt no XYZDA int, no watermark, no overun int. //** 0x80 10000000 only click Int1 enable rest all disable //*** 0x40 01000000 I1_IA1 interrupt enabled I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG3, 0x40,1); //REG 4: BDU|BLE|FS1|FS0|HR|ST1|ST0|SIM //* 0x00 00000000 diable all 2G enabled //** 0x80 100000000 BDU set as we dont use sync,2G, High resolution, rest is all default 0 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG4, 0x80, 1); // nothing to change here //REG 5: BOOT|FIFO_EN|--|--|LIR_INT1|D4D_INT1|LIR_INT2|D4D_INT2 //* 0x00 00000000 no reboot, no FIFO, NO latch of INT1/INT2, 4D only X/Y //** 0x05 0000101 no reboot, no FIFO, NO latch of INT1/INT2 enable 6D for INT1/2 (include Z) //*** 0x0F 00001111 no reboot no FIFO, latch of INT1/INT2 enable 6D for INT1/2 (include Z) //****0x08 00001000 lir int1 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG5, 0x08, 1); //REG 6: I2_CLICK|I2_IA1|I2_IA2|I2_BOOT|I2_ACT|--|INT_POLARITY|-- // click, boot, interrupts disabled. 0x00 00000000 //* 0x22 00100010 polarity invert I2IA2 interrupt //** 0x82 10000010 click int2 no IA1/2 int, no boot on Int2, no activity int, poarity invert I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG6, 0x00, 1); //FIFO CTRL REG: FM1|FM0|TR|FTH4|FTH3|FTH2|FTH1|FTH0 //* bypass mode, trigger diabled 0x00 00000000 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_FIFO_CTRL_REG, 0x00, 1); //Reference for interrupt Ref7|Ref6|Ref5|Ref4|Ref3|Ref2|Ref1|Ref0 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_REFERENCE, 0x0A, 1); // accel value i.e set reference accel/tilt value // INT 1 Threshold 0|THS6|THS5|THS4|THS3|THS2|THS1|THS0 // interrupt threshold value all 0 //* 0x55 trigger threshhold 01010101 //** 0xA5 10100101 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_INT1_THS, 0x10, 1); // INT1 Duration 0|D6|D5|D4|D3|D2|D1|D0 // interrupt duration disabled //*int1 duration 0x05 10100101 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_INT1_DURATION, 0x00,1);I2C_Master_Read(SLAVE_ADDRESS, ACCELReg_REFERENCE , 0, 1); // do a dummy read to force HP filter to current
// INT1_CFG AOI|6D|ZHIE|ZLIE|YHIE|YLIE|XHIE|XLIE // ZH,ZL,YH,YL,XH,XL interrupt disabled //* 0x08 Y trigger //** 0x02 X trigger //*** 0x0A 00001010 both X and y trigger //****0x2A 00101010 XYZ High //*****0x15 00010101 XYZ LOW I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_INT1_CFG, 0x0A, 1); // INT 2 Threshold 0|THS6||THS5|THS4|THS3|THS2|THS1|THS0 // interrupt threshold value all 0 //* 0x10 threshold I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_INT2_THS, 0x00, 1); // INT2 Duration 0|D6|D5|D4|D3|D2|D1|D0 // interrupt duration disabled // duration 0x01 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_INT2_DURATION, 0x00, 1); // INT2_CFG AOI|6D|ZHIE|ZLIE|YHIE|YLIE|XHIE|XLIE // ZH,ZL,YH,YL,XH,XL interrupt disabled //* 0x08 Y trigger //** 0x02 X trigger //*** 0x0A both X and y trigger //**** 0x7F 011111111 all enabled except AOI I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_INT2_CFG, 0x00, 1); // CLICK_CFG --|--|ZD|ZS|YD|YS|XD|XS // disable click configuration //* 0x08 00001000 double click on Y //** 0x2A 00101010 Double click on XYZ //*** 0x02 0000010 double click on X //**** 0x04 000100 single click on Y //***** 0x15 00010101 single click on XYZ I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CLICK_CFG, 0x00, 1); // how hard you must double click // CLICK_THS |LIR_click|Ths6|Ths5|Ths4|Ths3|Ths2|Ths1|Ths0 // disable click thresholds //* 0x7F hardest setting, 0x0A softer setting I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CLICK_THS, 0x00, 1); // Time Limit --|TLI6|TLI5|TLI4|TLI3|TLI2|TLI1|TLI0 // Max time interval that can elapse when XYZ goes out of Threshold to detect click //* click time limit set 0x04 00000100 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_TIME_LIMIT, 0x00, 1); // Time Latency TLA7|TLA6|TLA5|TLA4|TLA3|TLA2|TLA1|TLA0| // time interval that starts after first click detection where the click detection // procedure is disabled, ifor double click // click time latency 0x24 00100100 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_TIME_LATENCY, 0x00, 1); // Time Window TW7|TW6|TW5|TW4|TW3|TW2|TW1|TW0| // max time interval that can elapse after end of latency interval in which click detection can start // click time window I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_TIME_WINDOW, 0x00, 1); // sleep to wake return to sleep Threshold --|Acth6|Acth5|Acth4|Acth3|Acth2|Acth1|Acth0 // 1LSB=16mG@2g // 1LSB=32mG@4g // 1LSB=64mG@8g // 1LSB=186mG@16g I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_ACT_THS, 0x00, 1); // // sleep to wake return to sleep duration ActD7|ActD6|ActD7|ActD4|ActD3|ActD2|ActD1|ActD0| // sleep to wake return to sleep 1LSB=(8*[LSB+1])/ODR // 0x00 00000000 I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_ACT_DUR, 0x00, 1); // calibrateAccel(); // calibrate accel#stm32l152 #spirit1-sp1ml #lis2dh122017-12-05 10:56 PM
Good day. I have manage to solve this issue. For completeness this was the problem :
I2C_Master_Write(SLAVE_ADDRESS, ACCELReg_CTRL_REG5, 0x08, sets the interrupt to latching and I presume a bug in the code or return function where I need to read INT1_SRC to clear it was not always working.
Setting it to 0x00, (no latching function) and by disabling the internal weak pull-up on the processor pin the system seems to have resolved my problem.
I will probably also add a 100k pull-down resistor.
I am using a active LOW to put the processor to sleep. which is setup in Register 6 (Polarity).
2023-10-07 09:22 AM
This is the exact issue I had and all the fix required was not latching in the REG5. Thanks for sharing your solution