Tool/software:
My circuit contains an H-bridge motor driver and 2 proximity sensors, The idea is to make the motor move in one direction until one sensor is triggered, then stop the motor, then move it in the other direction until the other sensor is triggered, in perpetuity. The sensors are active-low. The motor driver is on pins 2 & 3 and the proximity sensors are on pins 4 & 5, all on PORTA.
The proximity sensor pins are configured as low-level interrupts. The interrupt handler function is as follows:
void pos_sensor_int_handler() {
GPIOIntClear(GPIO_PORTA_BASE, GPIO_INT_PIN_4 | GPIO_INT_PIN_5); // clear the proximity sensor interrupts
static uint32_t state;
state = GPIOIntStatus(GPIO_PORTA_BASE, true); //get masked interrupt status
xQueueSendFromISR(pos_sensor_int_queue, &state, NULL); //send this to a task where the event is actually processed
}
I set up the GPIO as follows:
int main() {
ROM_FPULazyStackingEnable();
ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA)) {}
GPIOIntRegister(GPIO_PORTA_BASE, pos_sensor_int_handler);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, motor_control_pin_R | motor_control_pin_L); //GPIO pins 2 & 3 are to control the motor
ROM_GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, pos_sensor_pin_L | pos_sensor_pin_R); //GPIO pins 4 & 5 are the proximity sensors
GPIOIntTypeSet(GPIO_PORTA_BASE, pos_sensor_pin_L | pos_sensor_pin_R, GPIO_LOW_LEVEL);
GPIOIntEnable(GPIO_PORTA_BASE, GPIO_INT_PIN_4 | GPIO_INT_PIN_5);
}
(Code which I don't believe to be relevant is omitted)
The interrupts for pins 4 & 5 do work as expected, however the issue is that I'm also getting spurious interrupts. Using the debugger, I can see that the handler function pos_sensor_int_handler() is randomly (and usually very frequently) being entered even when there was no level change on these pins.
Using the Register view, I can see that the PORTA GPIO Interrupt Mask register (GPIO_IM) is set correctly at 0x00000030, which is the OR result of 16 (pin 5) and 32 (pin 4). When the erroneous interrupt occurs, the GPIO Raw Interrupt Status register (GPIO_RIS) reads 0x00000080, signifying an interrupt on pin 7, which I never enabled! So, I tried explicitly disabling the interrupt for the pin:
GPIOIntDisable(GPIO_PORTA_BASE, GPIO_INT_PIN_7);
Now when it happens, GPIO_RIS just reads all 0s. How is this possible? Shouldn't all interrupts on PORTA be reflected in GPIO_RIS? How could this interrupt handler be entered by any other means than a low level on the enabled pins?
Thank you