/** * @file led_indicator.h * @brief Неблокирующая индикация состояния устройства на одном или нескольких LED. */ #ifndef LED_INDICATOR_H #define LED_INDICATOR_H #include #include #ifdef __cplusplus extern "C" { #endif #define LED_INDICATOR_MAX_STEPS 8U typedef enum { LED_INDICATOR_MODE_OFF = 0, LED_INDICATOR_MODE_ON, LED_INDICATOR_MODE_STARTUP, LED_INDICATOR_MODE_WORK, LED_INDICATOR_MODE_ACTIVITY, LED_INDICATOR_MODE_WARNING, LED_INDICATOR_MODE_ERROR, LED_INDICATOR_MODE_CRITICAL, LED_INDICATOR_MODE_COUNT } LedIndicator_Mode; /** Один период сигнала. Бит N в levels задаёт уровень шага N. */ typedef struct { uint32_t duration_ms[LED_INDICATOR_MAX_STEPS]; uint8_t levels; uint8_t step_count; uint8_t repeat; uint8_t final_level; } LedIndicator_Pattern; /** * Аппаратный порт. write получает логический уровень, поэтому active-low, * GPIO, PWM и регистры расширителя обрабатываются за границей ядра. */ typedef struct { void (*write)(void *context, uint8_t channel, uint8_t on); uint32_t (*now_ms)(void *context); void *context; } LedIndicator_Port; typedef struct { LedIndicator_Mode mode; uint32_t started_ms; uint8_t output_level; uint8_t initialized; } LedIndicator_Channel; typedef struct { const LedIndicator_Pattern *patterns; size_t pattern_count; } LedIndicator_Config; typedef struct { LedIndicator_Port port; const LedIndicator_Pattern *patterns; LedIndicator_Channel *channels; size_t pattern_count; size_t channel_count; uint8_t initialized; } LedIndicator; /** Заполняет конфигурацию встроенными шаблонами режимов. */ void LedIndicator_ConfigDefault(LedIndicator_Config *config); /** Копирует встроенные шаблоны в изменяемую таблицу; возвращает число записей. */ size_t LedIndicator_CopyDefaultPatterns(LedIndicator_Pattern *patterns, size_t capacity); /** Проверяет таблицу шаблонов. */ uint8_t LedIndicator_ValidateConfig(const LedIndicator_Config *config); /** * Инициализирует экземпляр и немедленно выключает все его каналы. * Массив channels принадлежит приложению и должен жить столько же, сколько instance. */ uint8_t LedIndicator_Init(LedIndicator *instance, LedIndicator_Channel *channels, size_t channel_count, const LedIndicator_Port *port, const LedIndicator_Config *config); /** Назначает режим, используя время порта. Повтор того же режима не сбрасывает фазу. */ uint8_t LedIndicator_SetMode(LedIndicator *instance, size_t channel, LedIndicator_Mode mode); /** Назначает режим с явно переданной меткой времени. Повтор не сбрасывает фазу. */ uint8_t LedIndicator_SetModeAt(LedIndicator *instance, size_t channel, LedIndicator_Mode mode, uint32_t now_ms); /** Принудительно запускает режим с первого шага, используя время порта. */ uint8_t LedIndicator_RestartMode(LedIndicator *instance, size_t channel, LedIndicator_Mode mode); /** Принудительно запускает режим с первого шага в указанное время. */ uint8_t LedIndicator_RestartModeAt(LedIndicator *instance, size_t channel, LedIndicator_Mode mode, uint32_t now_ms); /** Обновляет выходы, используя время порта. Вызывать в главном цикле. */ void LedIndicator_Process(LedIndicator *instance); /** Обновляет выходы с явно переданной меткой времени. */ void LedIndicator_ProcessAt(LedIndicator *instance, uint32_t now_ms); LedIndicator_Mode LedIndicator_GetMode(const LedIndicator *instance, size_t channel); #ifdef __cplusplus } #endif #endif /* LED_INDICATOR_H */