94 lines
3.0 KiB
C
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;
|
|
}
|