#ifndef ULTRASONIC_H #define ULTRASONIC_H #include #include /* * ultrasonic.h — HC-SR04 ultrasonic distance sensor driver (Issue #243) * * STM32F722 driver for HC-SR04 ultrasonic ranger with TIM1 input capture. * Trigger: PA0 (GPIO output, active high pulse 10µs) * Echo: PA1 (TIM1_CH2, input capture on rising/falling edges) * * Non-blocking operation: trigger measurement, get result via callback. * Distance calculated from echo pulse width: distance_mm = (pulse_us / 2) / 29.1 * Typical range: 20-4000mm (accuracy ±3mm above 30mm) */ /* Ultrasonic sensor states */ typedef enum { ULTRASONIC_IDLE, /* Ready for new measurement */ ULTRASONIC_TRIGGERED, /* Trigger pulse sent, waiting for echo */ ULTRASONIC_MEASURING, /* Echo rising edge detected, measuring */ ULTRASONIC_COMPLETE, /* Measurement complete */ ULTRASONIC_ERROR /* Timeout or out-of-range */ } UltrasonicState; /* Measurement result callback: called when measurement completes * Arguments: * - distance_mm: measured distance in mm (0 if error/timeout) * - is_valid: true if measurement valid, false if timeout/error */ typedef void (*ultrasonic_callback_t)(uint16_t distance_mm, bool is_valid); /* * ultrasonic_init() * * Initialize HC-SR04 driver: * - PA0 as GPIO output (trigger pin) * - PA1 as TIM1_CH2 input capture (echo pin) * - Configure TIM1 for input capture on both edges (rising/falling) * - Enable timer interrupt for echo measurement */ void ultrasonic_init(void); /* * ultrasonic_trigger() * * Start a non-blocking distance measurement. * Sends 10µs trigger pulse on PA0, sets up echo measurement. * Measurement completes asynchronously (typically 25-300ms depending on distance). * Call ultrasonic_get_state() to check status or wait for callback. * * Returns: true if triggered successfully, false if still measuring previous result */ bool ultrasonic_trigger(void); /* * ultrasonic_set_callback(callback) * * Register callback to be called when measurement completes. * Callback receives: distance_mm (0 if error), is_valid (true if successful) * Callback is optional; can poll with ultrasonic_get_result() instead. */ void ultrasonic_set_callback(ultrasonic_callback_t callback); /* * ultrasonic_get_state() * * Returns current measurement state (IDLE, TRIGGERED, MEASURING, COMPLETE, ERROR). * Useful for non-blocking polling. */ UltrasonicState ultrasonic_get_state(void); /* * ultrasonic_get_result(distance_mm, is_valid) * * Retrieve result of last measurement (only valid when state == ULTRASONIC_COMPLETE). * Resets state to IDLE after reading. * * Arguments: * - distance_mm: pointer to store distance in mm * - is_valid: pointer to store validity flag * * Returns: true if result retrieved, false if no measurement available */ bool ultrasonic_get_result(uint16_t *distance_mm, bool *is_valid); /* * ultrasonic_tick(now_ms) * * Update function called periodically (recommended: every 1-10ms in main loop). * Handles timeout detection for echo measurement. * Must be called regularly for non-blocking operation. * * Arguments: * - now_ms: current time in milliseconds (from HAL_GetTick() or similar) */ void ultrasonic_tick(uint32_t now_ms); #endif /* ULTRASONIC_H */