/** * \file door_sensor.c * \brief Implementation of the door sensor driver using MSP430 GPIO interrupts. * * This module configures a GPIO pin to detect door open/close events and invokes * user-provided callbacks on confirmed state changes. */ #include #include #include #include #include "door_sensor.h" #include "constants.h" /**\brief GPIO port used for the door sensor. */ #define SENSOR_PORT GPIO_PORT_P2 /**\brief GPIO pin used for the door sensor. */ #define SENSOR_PIN GPIO_PIN0 /**\brief Interrupt vector associated with the sensor port. */ #define SENSOR_VECTOR PORT2_VECTOR /** * \brief Callback invoked when the door is detected as opened. * * User must supply a function matching this type to be notified of an open event. */ static DoorOpenedCallback_t doorOpenedCallback = NULL; /** * \brief Callback invoked when the door is detected as closed. * * User must supply a function matching this type to be notified of a close event. */ static DoorClosedCallback_t doorClosedCallback = NULL; /** * \brief Initialize the door sensor driver. * * Configures the GPIO pin for input with pull-up resistor and enables * interrupts on the specified edge. Also stores the user-provided callbacks. * * \param ocb Function to call when the door opens (rising edge). * \param ccb Function to call when the door closes (falling edge). */ void door_init(DoorOpenedCallback_t ocb, DoorClosedCallback_t ccb) { doorOpenedCallback = ocb; doorClosedCallback = ccb; /* Configure port as pull up with interrupt */ GPIO_setAsInputPinWithPullUpResistor(SENSOR_PORT, SENSOR_PIN); GPIO_clearInterrupt(SENSOR_PORT, SENSOR_PIN); GPIO_selectInterruptEdge(SENSOR_PORT, SENSOR_PIN, GPIO_LOW_TO_HIGH_TRANSITION); GPIO_enableInterrupt(SENSOR_PORT, SENSOR_PIN); /* Enable global interrupts */ __enable_interrupt(); } /** * \brief Tracks the last known door state (open = true, closed = false). */ volatile bool door_last_open = false; /** * \brief ISR for PORT2 interrupt handling door sensor events. * * Detects whether the door is opening or closing based on interrupt edge, * invokes the corresponding callback, and reconfigures the interrupt edge * for the next transition. */ #pragma vector=SENSOR_VECTOR __interrupt void SENSOR_ISR(void) { uint16_t status = GPIO_getInterruptStatus(SENSOR_PORT, SENSOR_PIN); if (status) { if (door_last_open) { /* Door was open, now closed */ if (doorClosedCallback) doorClosedCallback(); GPIO_selectInterruptEdge(SENSOR_PORT, SENSOR_PIN, GPIO_LOW_TO_HIGH_TRANSITION); } else { /* Door was closed, now opened */ if (doorOpenedCallback) doorOpenedCallback(); GPIO_selectInterruptEdge(SENSOR_PORT, SENSOR_PIN, GPIO_HIGH_TO_LOW_TRANSITION); } } /* Clear the interrupt flag and toggle stored state */ GPIO_clearInterrupt(SENSOR_PORT, SENSOR_PIN); door_last_open = !door_last_open; }