Adicionar primeiro
This commit is contained in:
245
components/peripherals/src/led.c
Executable file
245
components/peripherals/src/led.c
Executable file
@@ -0,0 +1,245 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "led.h"
|
||||
#include "board_config.h"
|
||||
#include "evse_error.h"
|
||||
#include "evse_api.h"
|
||||
|
||||
#define LED_UPDATE_INTERVAL_MS 100
|
||||
#define BLOCK_TIME pdMS_TO_TICKS(10)
|
||||
|
||||
static const char *TAG = "led";
|
||||
|
||||
typedef struct {
|
||||
gpio_num_t gpio;
|
||||
bool on : 1;
|
||||
uint16_t ontime;
|
||||
uint16_t offtime;
|
||||
TimerHandle_t timer;
|
||||
led_pattern_t pattern;
|
||||
uint8_t blink_count;
|
||||
} led_t;
|
||||
|
||||
static led_t leds[LED_ID_MAX] = {0};
|
||||
static TimerHandle_t led_update_timer = NULL;
|
||||
static evse_state_t led_state = -1;
|
||||
|
||||
// ----------------------------
|
||||
// Funções Internas
|
||||
// ----------------------------
|
||||
|
||||
static void led_update_timer_callback(TimerHandle_t xTimer);
|
||||
static void led_update(void);
|
||||
static void led_apply_by_state(evse_state_t state);
|
||||
|
||||
static inline void led_gpio_write(gpio_num_t gpio, bool level) {
|
||||
if (gpio != GPIO_NUM_NC)
|
||||
gpio_set_level(gpio, level);
|
||||
}
|
||||
|
||||
static void led_timer_callback(TimerHandle_t xTimer)
|
||||
{
|
||||
led_t *led = (led_t *)pvTimerGetTimerID(xTimer);
|
||||
led->on = !led->on;
|
||||
led_gpio_write(led->gpio, led->on);
|
||||
uint32_t next_time = led->on ? led->ontime : led->offtime;
|
||||
|
||||
xTimerChangePeriod(led->timer, pdMS_TO_TICKS(next_time), BLOCK_TIME);
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Inicialização
|
||||
// ----------------------------
|
||||
|
||||
void led_init(void)
|
||||
{
|
||||
gpio_config_t io_conf = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_ENABLE,
|
||||
.pin_bit_mask = 0
|
||||
};
|
||||
|
||||
for (int i = 0; i < LED_ID_MAX; i++) {
|
||||
leds[i].gpio = GPIO_NUM_NC;
|
||||
}
|
||||
|
||||
if (board_config.led_stop) {
|
||||
leds[LED_ID_STOP].gpio = board_config.led_stop_gpio;
|
||||
io_conf.pin_bit_mask |= BIT64(board_config.led_stop_gpio);
|
||||
}
|
||||
|
||||
if (board_config.led_charging) {
|
||||
leds[LED_ID_CHARGING].gpio = board_config.led_charging_gpio;
|
||||
io_conf.pin_bit_mask |= BIT64(board_config.led_charging_gpio);
|
||||
}
|
||||
|
||||
if (board_config.led_error) {
|
||||
leds[LED_ID_ERROR].gpio = board_config.led_error_gpio;
|
||||
io_conf.pin_bit_mask |= BIT64(board_config.led_error_gpio);
|
||||
}
|
||||
|
||||
if (io_conf.pin_bit_mask != 0) {
|
||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||
}
|
||||
|
||||
if (!led_update_timer) {
|
||||
led_update_timer = xTimerCreate("led_update_timer",
|
||||
pdMS_TO_TICKS(LED_UPDATE_INTERVAL_MS),
|
||||
pdTRUE, NULL,
|
||||
led_update_timer_callback);
|
||||
if (led_update_timer) {
|
||||
xTimerStart(led_update_timer, BLOCK_TIME);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to create LED update timer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// API Pública
|
||||
// ----------------------------
|
||||
|
||||
void led_set_state(led_id_t led_id, uint16_t ontime, uint16_t offtime)
|
||||
{
|
||||
if (led_id >= LED_ID_MAX) return;
|
||||
|
||||
led_t *led = &leds[led_id];
|
||||
if (led->gpio == GPIO_NUM_NC) return;
|
||||
|
||||
// Evita reconfiguração idêntica
|
||||
if (led->ontime == ontime && led->offtime == offtime)
|
||||
return;
|
||||
|
||||
if (led->timer) {
|
||||
xTimerStop(led->timer, BLOCK_TIME);
|
||||
}
|
||||
|
||||
led->ontime = ontime;
|
||||
led->offtime = offtime;
|
||||
|
||||
if (ontime == 0) {
|
||||
led->on = false;
|
||||
led_gpio_write(led->gpio, 0);
|
||||
} else if (offtime == 0) {
|
||||
led->on = true;
|
||||
led_gpio_write(led->gpio, 1);
|
||||
} else {
|
||||
led->on = true;
|
||||
led_gpio_write(led->gpio, 1);
|
||||
|
||||
if (!led->timer) {
|
||||
led->timer = xTimerCreate("led_timer", pdMS_TO_TICKS(ontime),
|
||||
pdFALSE, (void *)led, led_timer_callback);
|
||||
}
|
||||
|
||||
if (led->timer) {
|
||||
xTimerStart(led->timer, BLOCK_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void led_apply_pattern(led_id_t id, led_pattern_t pattern)
|
||||
{
|
||||
if (id >= LED_ID_MAX) return;
|
||||
|
||||
led_t *led = &leds[id];
|
||||
if (led->gpio == GPIO_NUM_NC) return;
|
||||
|
||||
if (led->pattern == pattern) return;
|
||||
|
||||
if (led->timer) {
|
||||
xTimerStop(led->timer, BLOCK_TIME);
|
||||
}
|
||||
|
||||
led->pattern = pattern;
|
||||
led->blink_count = 0;
|
||||
|
||||
switch (pattern) {
|
||||
case LED_PATTERN_OFF:
|
||||
led_set_state(id, 0, 0);
|
||||
break;
|
||||
case LED_PATTERN_ON:
|
||||
led_set_state(id, 1, 0);
|
||||
break;
|
||||
case LED_PATTERN_BLINK:
|
||||
led_set_state(id, 500, 500);
|
||||
break;
|
||||
case LED_PATTERN_BLINK_FAST:
|
||||
led_set_state(id, 200, 200);
|
||||
break;
|
||||
case LED_PATTERN_BLINK_SLOW:
|
||||
led_set_state(id, 300, 1700);
|
||||
break;
|
||||
case LED_PATTERN_CHARGING_EFFECT:
|
||||
led_set_state(id, 2000, 1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Controle por Estado
|
||||
// ----------------------------
|
||||
|
||||
static void led_apply_by_state(evse_state_t state)
|
||||
{
|
||||
// Reset todos
|
||||
led_apply_pattern(LED_ID_STOP, LED_PATTERN_OFF);
|
||||
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_OFF);
|
||||
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_OFF);
|
||||
|
||||
switch (state) {
|
||||
case EVSE_STATE_A:
|
||||
led_apply_pattern(LED_ID_STOP, LED_PATTERN_ON);
|
||||
break;
|
||||
case EVSE_STATE_B1:
|
||||
case EVSE_STATE_B2:
|
||||
case EVSE_STATE_C1:
|
||||
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_ON);
|
||||
break;
|
||||
case EVSE_STATE_C2:
|
||||
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_CHARGING_EFFECT);
|
||||
break;
|
||||
case EVSE_STATE_D1:
|
||||
case EVSE_STATE_D2:
|
||||
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_BLINK_FAST);
|
||||
break;
|
||||
case EVSE_STATE_E:
|
||||
case EVSE_STATE_F:
|
||||
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_BLINK_FAST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// Timer Update
|
||||
// ----------------------------
|
||||
|
||||
static void led_update(void)
|
||||
{
|
||||
if (evse_error_is_active()) {
|
||||
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_BLINK_FAST);
|
||||
led_apply_pattern(LED_ID_STOP, LED_PATTERN_OFF);
|
||||
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_OFF);
|
||||
return;
|
||||
}
|
||||
|
||||
evse_state_t current = evse_get_state();
|
||||
|
||||
if (current != led_state) {
|
||||
led_state = current;
|
||||
led_apply_by_state(current);
|
||||
}
|
||||
}
|
||||
|
||||
static void led_update_timer_callback(TimerHandle_t xTimer)
|
||||
{
|
||||
(void)xTimer;
|
||||
led_update();
|
||||
}
|
||||
Reference in New Issue
Block a user