This commit is contained in:
2025-08-24 11:17:48 +01:00
parent 0d0dc5b129
commit 96b2ab1f57
31 changed files with 2883 additions and 4054 deletions

View File

@@ -6,10 +6,42 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/ledc.h" // Para buzzer passivo
#define BUZZER_GPIO GPIO_NUM_27
static const char *TAG = "Buzzer";
// --- Configuração de modo ---
typedef enum {
BUZZER_MODE_ACTIVE = 0,
BUZZER_MODE_PASSIVE
} buzzer_mode_t;
typedef struct {
buzzer_mode_t mode;
gpio_num_t gpio;
// Apenas para PASSIVE
uint32_t freq_hz; // ex: 4000
uint8_t duty_percent; // 0100
ledc_mode_t ledc_speed_mode; // LEDC_LOW_SPEED_MODE
ledc_timer_t ledc_timer; // LEDC_TIMER_1
ledc_channel_t ledc_channel; // LEDC_CHANNEL_1
ledc_timer_bit_t duty_resolution; // LEDC_TIMER_10_BIT
} buzzer_config_t;
static buzzer_config_t s_buzzer_cfg = {
.mode = BUZZER_MODE_PASSIVE, // Mude para PASSIVE se for buzzer passivo
.gpio = BUZZER_GPIO,
.freq_hz = 4000,
.duty_percent = 50,
.ledc_speed_mode = LEDC_LOW_SPEED_MODE,
.ledc_timer = LEDC_TIMER_1,
.ledc_channel = LEDC_CHANNEL_1,
.duty_resolution = LEDC_TIMER_10_BIT
};
// --- Estrutura de passos ---
typedef struct {
uint16_t on_ms;
uint16_t off_ms;
@@ -39,9 +71,37 @@ static const buzzer_pattern_t buzzer_patterns[] = {
[BUZZER_PATTERN_CARD_DENIED] = {pattern_card_denied, sizeof(pattern_card_denied) / sizeof(buzzer_step_t)},
};
static void buzzer_on(void) { gpio_set_level(BUZZER_GPIO, 1); }
static void buzzer_off(void) { gpio_set_level(BUZZER_GPIO, 0); }
// --- Funções de controle ---
static inline uint32_t duty_from_percent(uint8_t pct, ledc_timer_bit_t res) {
if (pct == 0) return 0;
uint32_t max = (1U << res) - 1U;
return (uint32_t)((pct * max) / 100U);
}
static void buzzer_on(void) {
if (s_buzzer_cfg.mode == BUZZER_MODE_PASSIVE) {
ledc_set_freq(s_buzzer_cfg.ledc_speed_mode,
s_buzzer_cfg.ledc_timer,
s_buzzer_cfg.freq_hz);
ledc_set_duty(s_buzzer_cfg.ledc_speed_mode,
s_buzzer_cfg.ledc_channel,
duty_from_percent(s_buzzer_cfg.duty_percent, s_buzzer_cfg.duty_resolution));
ledc_update_duty(s_buzzer_cfg.ledc_speed_mode, s_buzzer_cfg.ledc_channel);
} else {
gpio_set_level(s_buzzer_cfg.gpio, 1);
}
}
static void buzzer_off(void) {
if (s_buzzer_cfg.mode == BUZZER_MODE_PASSIVE) {
ledc_set_duty(s_buzzer_cfg.ledc_speed_mode, s_buzzer_cfg.ledc_channel, 0);
ledc_update_duty(s_buzzer_cfg.ledc_speed_mode, s_buzzer_cfg.ledc_channel);
} else {
gpio_set_level(s_buzzer_cfg.gpio, 0);
}
}
// --- Execução de padrões ---
static void buzzer_execute(buzzer_pattern_id_t pattern_id) {
if ((int)pattern_id <= BUZZER_PATTERN_NONE || pattern_id >= BUZZER_PATTERN_MAX) {
ESP_LOGW(TAG, "Invalid buzzer pattern id: %d", pattern_id);
@@ -60,6 +120,7 @@ static void buzzer_execute(buzzer_pattern_id_t pattern_id) {
}
}
// --- Event Handlers ---
static void buzzer_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) {
if (base != BUZZER_EVENTS || id != BUZZER_EVENT_PLAY_PATTERN || data == NULL) return;
@@ -107,7 +168,6 @@ static void network_event_handler(void *handler_args, esp_event_base_t base, int
}
}
static void auth_event_handler(void *arg, esp_event_base_t base, int32_t id, void *event_data) {
if (base != AUTH_EVENTS || event_data == NULL) return;
@@ -117,7 +177,6 @@ static void auth_event_handler(void *arg, esp_event_base_t base, int32_t id, voi
const auth_tag_event_data_t *evt = (const auth_tag_event_data_t *)event_data;
ESP_LOGI(TAG, "AUTH processed: tag=%s authorized=%d", evt->tag, evt->authorized);
buzzer_evt.pattern = evt->authorized ? BUZZER_PATTERN_CARD_READ : BUZZER_PATTERN_CARD_DENIED;
} else if (id == AUTH_EVENT_TAG_SAVED) {
buzzer_evt.pattern = BUZZER_PATTERN_CARD_ADD;
} else {
@@ -127,15 +186,41 @@ static void auth_event_handler(void *arg, esp_event_base_t base, int32_t id, voi
esp_event_post(BUZZER_EVENTS, BUZZER_EVENT_PLAY_PATTERN, &buzzer_evt, sizeof(buzzer_evt), portMAX_DELAY);
}
// --- Inicialização ---
void buzzer_init(void) {
gpio_config_t io = {
.pin_bit_mask = BIT64(BUZZER_GPIO),
.mode = GPIO_MODE_OUTPUT,
.pull_down_en = 0,
.pull_up_en = 0,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io);
if (s_buzzer_cfg.mode == BUZZER_MODE_PASSIVE) {
// Configura temporizador do PWM
ledc_timer_config_t tcfg = {
.speed_mode = s_buzzer_cfg.ledc_speed_mode,
.duty_resolution = s_buzzer_cfg.duty_resolution,
.timer_num = s_buzzer_cfg.ledc_timer,
.freq_hz = s_buzzer_cfg.freq_hz,
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&tcfg));
// Configura canal PWM
ledc_channel_config_t ccfg = {
.gpio_num = s_buzzer_cfg.gpio,
.speed_mode = s_buzzer_cfg.ledc_speed_mode,
.channel = s_buzzer_cfg.ledc_channel,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = s_buzzer_cfg.ledc_timer,
.duty = 0,
.hpoint = 0
};
ESP_ERROR_CHECK(ledc_channel_config(&ccfg));
} else {
gpio_config_t io = {
.pin_bit_mask = (1ULL << s_buzzer_cfg.gpio),
.mode = GPIO_MODE_OUTPUT,
.pull_down_en = 0,
.pull_up_en = 0,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io);
}
buzzer_off();
// Registro de handlers
@@ -155,14 +240,12 @@ void buzzer_init(void) {
AUTH_EVENT_TAG_SAVED,
auth_event_handler,
NULL));
ESP_ERROR_CHECK(esp_event_handler_register(NETWORK_EVENTS,
NETWORK_EVENT_AP_STARTED,
network_event_handler,
NULL));
ESP_ERROR_CHECK(esp_event_handler_register(
NETWORK_EVENTS,
NETWORK_EVENT_AP_STARTED,
network_event_handler,
NULL
));
ESP_LOGI(TAG, "Buzzer initialized on GPIO %d", BUZZER_GPIO);
ESP_LOGI(TAG, "Buzzer initialized on GPIO %d (%s)",
s_buzzer_cfg.gpio,
s_buzzer_cfg.mode == BUZZER_MODE_PASSIVE ? "passive/PWM" : "active/ON-OFF");
}