ESR-2025/src/door_sensor.c
2025-07-03 08:37:46 +02:00

94 lines
3.0 KiB
C

/**
* \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 <stdint.h>
#include <msp430.h>
#include <driverlib.h>
#include <stdbool.h>
#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;
}