Hello,
I am trying to get the FXOS8700 accelmag and FXAS21002 gyro to work with the TM4C123 mcu. So far, I wrote the i2c driver, made the sensor initialize generating interrupts, and handle those interrupts and read data from i2c. What happens is, if I configure the code to work with only one sensor, it works, but if I have two interrupts, after a while (like 30-60seconds) one of the interrupt handling mechanisms fail.
Here are the relevant parts of the code:
// gyro interrupt pin setup SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_4); GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); GPIOIntDisable(GPIO_PORTC_BASE, GPIO_PIN_4); GPIOIntClear(GPIO_PORTC_BASE, GPIO_PIN_4); GPIOIntRegister(GPIO_PORTC_BASE, gyro_isr); GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_FALLING_EDGE); GPIOIntEnable(GPIO_PORTC_BASE, GPIO_PIN_4); // accelmag interrupt pin setup SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_2); GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); GPIOIntDisable(GPIO_PORTE_BASE, GPIO_PIN_2); GPIOIntClear(GPIO_PORTE_BASE, GPIO_PIN_2); GPIOIntRegister(GPIO_PORTE_BASE, accelmag_isr); GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_2, GPIO_RISING_EDGE); GPIOIntEnable(GPIO_PORTE_BASE, GPIO_PIN_2);
PC4 is configured for a falling edge, and PE2 is configured for rising edge, which are connected to the sensor board, and gyro is configured to generate active 0 output (for falling edge) and accelmag board is configured to generate active 1 output.
// gyro interrupt service routine void gyro_isr(void) { if(GPIOIntStatus(GPIO_PORTC_BASE, false) & GPIO_PIN_4) { GPIOIntClear(GPIO_PORTC_BASE, GPIO_PIN_4); gyro_data_ready = true; } } // accelmag interrupt service routine void accelmag_isr(void) { if(GPIOIntStatus(GPIO_PORTE_BASE, false) & GPIO_PIN_2) { GPIOIntClear(GPIO_PORTE_BASE, GPIO_PIN_2); accelmag_data_ready = true; } }
Here are the interrupt handlers. They just mark a volatile boolean so that I can read the sensor from the main loop.
In my main loop, I check for these booleans anrd read data:
while(1) { //current_time = nh.now(); if(gyro_data_ready) { GyroGetData(FXAS21002C_ADDRESS, &gyroRD); gyro_data_ready = false; } if(accelmag_data_ready) { AGGetData(FXOS8700_ADDRESS, &accelRD, &magRD); accelmag_data_ready = false; } }
No matter what I tried, I could not get rid of this bug. The active high interrupt for the accelmag, gets stuck at 1, meaning that the sensor was not read (which would have cleared the interrupt on the sensor)
At the beginning I was thinking this was related to the FXOS8700 accelmag orFXAS21002 gyro sensor, but at this point I believe this is interrupt related. Somehow, the sensor rises interrupt line, but the interrupt does not trigger, because other interrupt is happening. To support this theory:
A. By examining the both interrupt lines with scope carefuly, (by videotaping it) I have evidence out that misfunction happens when two interrupts are triggered at the same time.
B. I replaced the failing accelmag interrupt from PE2 to PB4. This time the other interrupt line at PC4 fails (from the gyro)
Here is the link to the video: twitter.com/altineller/status/1170381044115283973 (I had to put it on twitter because appearently vimeo does not like scope shoots)
Any ideas, help and recommendation on the problem greatly appreciated.
Best Regards,
Can