// === Início de: components/peripherals/src/ds18x20.c === /* * Copyright (c) 2016 Grzegorz Hetman * Copyright (c) 2016 Alex Stewart * Copyright (c) 2018 Ruslan V. Uss * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of itscontributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "ds18x20.h" #define ds18x20_WRITE_SCRATCHPAD 0x4E #define ds18x20_READ_SCRATCHPAD 0xBE #define ds18x20_COPY_SCRATCHPAD 0x48 #define ds18x20_READ_EEPROM 0xB8 #define ds18x20_READ_PWRSUPPLY 0xB4 #define ds18x20_SEARCHROM 0xF0 #define ds18x20_SKIP_ROM 0xCC #define ds18x20_READROM 0x33 #define ds18x20_MATCHROM 0x55 #define ds18x20_ALARMSEARCH 0xEC #define ds18x20_CONVERT_T 0x44 #define CHECK(x) do { esp_err_t __; if ((__ = x) != ESP_OK) return __; } while (0) #define CHECK_ARG(VAL) do { if (!(VAL)) return ESP_ERR_INVALID_ARG; } while (0) static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; static const char* TAG = "ds18x20"; esp_err_t ds18x20_measure(gpio_num_t pin, ds18x20_addr_t addr, bool wait) { if (!onewire_reset(pin)) return ESP_ERR_INVALID_RESPONSE; if (addr == DS18X20_ANY) onewire_skip_rom(pin); else onewire_select(pin, addr); portENTER_CRITICAL(&mux); onewire_write(pin, ds18x20_CONVERT_T); // For parasitic devices, power must be applied within 10us after issuing // the convert command. onewire_power(pin); portEXIT_CRITICAL(&mux); if (wait){ vTaskDelay(pdMS_TO_TICKS(750)); onewire_depower(pin); } return ESP_OK; } esp_err_t ds18x20_read_scratchpad(gpio_num_t pin, ds18x20_addr_t addr, uint8_t* buffer) { CHECK_ARG(buffer); uint8_t crc; uint8_t expected_crc; if (!onewire_reset(pin)) return ESP_ERR_INVALID_RESPONSE; if (addr == DS18X20_ANY) onewire_skip_rom(pin); else onewire_select(pin, addr); onewire_write(pin, ds18x20_READ_SCRATCHPAD); for (int i = 0; i < 8; i++) buffer[i] = onewire_read(pin); crc = onewire_read(pin); expected_crc = onewire_crc8(buffer, 8); if (crc != expected_crc) { ESP_LOGE(TAG, "CRC check failed reading scratchpad: %02x %02x %02x %02x %02x %02x %02x %02x : %02x (expected %02x)", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], crc, expected_crc); return ESP_ERR_INVALID_CRC; } return ESP_OK; } esp_err_t ds18x20_write_scratchpad(gpio_num_t pin, ds18x20_addr_t addr, uint8_t* buffer) { CHECK_ARG(buffer); if (!onewire_reset(pin)) return ESP_ERR_INVALID_RESPONSE; if (addr == DS18X20_ANY) onewire_skip_rom(pin); else onewire_select(pin, addr); onewire_write(pin, ds18x20_WRITE_SCRATCHPAD); for (int i = 0; i < 3; i++) onewire_write(pin, buffer[i]); return ESP_OK; } esp_err_t ds18x20_copy_scratchpad(gpio_num_t pin, ds18x20_addr_t addr) { if (!onewire_reset(pin)) return ESP_ERR_INVALID_RESPONSE; if (addr == DS18X20_ANY) onewire_skip_rom(pin); else onewire_select(pin, addr); portENTER_CRITICAL(&mux); onewire_write(pin, ds18x20_COPY_SCRATCHPAD); // For parasitic devices, power must be applied within 10us after issuing // the convert command. onewire_power(pin); portEXIT_CRITICAL(&mux); // And then it needs to keep that power up for 10ms. vTaskDelay(pdMS_TO_TICKS(10)); onewire_depower(pin); return ESP_OK; } esp_err_t ds18b20_read_temperature(gpio_num_t pin, ds18x20_addr_t addr, int16_t* temperature) { CHECK_ARG(temperature); uint8_t scratchpad[8]; int16_t temp; CHECK(ds18x20_read_scratchpad(pin, addr, scratchpad)); temp = scratchpad[1] << 8 | scratchpad[0]; *temperature = ((int16_t)temp * 625.0) / 100; return ESP_OK; } esp_err_t ds18s20_read_temperature(gpio_num_t pin, ds18x20_addr_t addr, int16_t* temperature) { CHECK_ARG(temperature); uint8_t scratchpad[8]; int16_t temp; CHECK(ds18x20_read_scratchpad(pin, addr, scratchpad)); temp = scratchpad[1] << 8 | scratchpad[0]; temp = ((temp & 0xfffe) << 3) + (16 - scratchpad[6]) - 4; *temperature = (temp * 625) / 100 - 25; return ESP_OK; } esp_err_t ds18x20_read_temperature(gpio_num_t pin, ds18x20_addr_t addr, int16_t* temperature) { if ((uint8_t)addr == DS18B20_FAMILY_ID) { return ds18b20_read_temperature(pin, addr, temperature); } else { return ds18s20_read_temperature(pin, addr, temperature); } } esp_err_t ds18b20_measure_and_read(gpio_num_t pin, ds18x20_addr_t addr, int16_t* temperature) { CHECK_ARG(temperature); CHECK(ds18x20_measure(pin, addr, true)); return ds18b20_read_temperature(pin, addr, temperature); } esp_err_t ds18s20_measure_and_read(gpio_num_t pin, ds18x20_addr_t addr, int16_t* temperature) { CHECK_ARG(temperature); CHECK(ds18x20_measure(pin, addr, true)); return ds18s20_read_temperature(pin, addr, temperature); } esp_err_t ds18x20_measure_and_read(gpio_num_t pin, ds18x20_addr_t addr, int16_t* temperature) { CHECK_ARG(temperature); CHECK(ds18x20_measure(pin, addr, true)); return ds18x20_read_temperature(pin, addr, temperature); } esp_err_t ds18x20_measure_and_read_multi(gpio_num_t pin, ds18x20_addr_t* addr_list, size_t addr_count, int16_t* result_list) { CHECK_ARG(result_list && addr_count); CHECK(ds18x20_measure(pin, DS18X20_ANY, true)); return ds18x20_read_temp_multi(pin, addr_list, addr_count, result_list); } esp_err_t ds18x20_scan_devices(gpio_num_t pin, ds18x20_addr_t* addr_list, size_t addr_count, size_t* found) { CHECK_ARG(addr_list && addr_count); onewire_search_t search; onewire_addr_t addr; *found = 0; onewire_search_start(&search); while ((addr = onewire_search_next(&search, pin)) != ONEWIRE_NONE) { uint8_t family_id = (uint8_t)addr; if (family_id == DS18B20_FAMILY_ID || family_id == DS18S20_FAMILY_ID) { if (*found < addr_count) addr_list[*found] = addr; *found += 1; } } return ESP_OK; } esp_err_t ds18x20_read_temp_multi(gpio_num_t pin, ds18x20_addr_t* addr_list, size_t addr_count, int16_t* result_list) { CHECK_ARG(result_list); esp_err_t res = ESP_OK; for (size_t i = 0; i < addr_count; i++) { esp_err_t tmp = ds18x20_read_temperature(pin, addr_list[i], &result_list[i]); if (tmp != ESP_OK) res = tmp; } return res; } // === Fim de: components/peripherals/src/ds18x20.c === // === Início de: components/peripherals/src/led.c === #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(); } // === Fim de: components/peripherals/src/led.c === // === Início de: components/peripherals/src/rcm.c === #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "esp_log.h" #include "rcm.h" #include "board_config.h" #include "evse_api.h" // static bool do_test = false; // static bool triggered = false; // static bool test_triggered = false; // static void IRAM_ATTR rcm_isr_handler(void* arg) // { // if (!do_test) { // triggered = true; // } else { // test_triggered = true; // } // } void rcm_init(void) { if (board_config.rcm) { gpio_config_t io_conf = {}; io_conf.mode = GPIO_MODE_OUTPUT; io_conf.pin_bit_mask = BIT64(board_config.rcm_test_gpio); ESP_ERROR_CHECK(gpio_config(&io_conf)); io_conf.mode = GPIO_MODE_INPUT; // io_conf.intr_type = GPIO_INTR_POSEDGE; io_conf.pin_bit_mask = BIT64(board_config.rcm_gpio); ESP_ERROR_CHECK(gpio_config(&io_conf)); //ESP_ERROR_CHECK(gpio_isr_handler_add(board_config.rcm_gpio, rcm_isr_handler, NULL)); } } bool rcm_test(void) { // do_test = true; // test_triggered = false; // gpio_set_level(board_config.rcm_test_gpio, 1); // vTaskDelay(pdMS_TO_TICKS(100)); // gpio_set_level(board_config.rcm_test_gpio, 0); // do_test = false; // return test_triggered; gpio_set_level(board_config.rcm_test_gpio, 1); vTaskDelay(pdMS_TO_TICKS(100)); bool success = gpio_get_level(board_config.rcm_gpio) == 1; gpio_set_level(board_config.rcm_test_gpio, 0); return success; } bool rcm_is_triggered(void) { // bool _triggered = triggered; // if (gpio_get_level(board_config.rcm_gpio) == 0) { // triggered = false; // } // return _triggered; if (gpio_get_level(board_config.rcm_gpio) == 1) { vTaskDelay(pdMS_TO_TICKS(1)); return gpio_get_level(board_config.rcm_gpio) == 1; } return false; } // === Fim de: components/peripherals/src/rcm.c === // === Início de: components/peripherals/src/adc.c === #include "adc.h" #include "esp_log.h" const static char* TAG = "adc"; adc_oneshot_unit_handle_t adc_handle; adc_cali_handle_t adc_cali_handle; void adc_init(void) { adc_oneshot_unit_init_cfg_t conf = { .unit_id = ADC_UNIT_1 }; ESP_ERROR_CHECK(adc_oneshot_new_unit(&conf, &adc_handle)); bool calibrated = false; #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED if (!calibrated) { ESP_LOGI(TAG, "Calibration scheme version is %s", "Curve Fitting"); adc_cali_curve_fitting_config_t cali_config = { .unit_id = ADC_UNIT_1, .atten = ADC_ATTEN_DB_12, .bitwidth = ADC_BITWIDTH_DEFAULT, }; if (adc_cali_create_scheme_curve_fitting(&cali_config, &adc_cali_handle) == ESP_OK) { calibrated = true; } } #endif #if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED if (!calibrated) { ESP_LOGI(TAG, "Calibration scheme version is %s", "Line Fitting"); adc_cali_line_fitting_config_t cali_config = { .unit_id = ADC_UNIT_1, .atten = ADC_ATTEN_DB_12, .bitwidth = ADC_BITWIDTH_DEFAULT, #if CONFIG_IDF_TARGET_ESP32 .default_vref = 1100 #endif }; if (adc_cali_create_scheme_line_fitting(&cali_config, &adc_cali_handle) == ESP_OK) { calibrated = true; } } #endif if (!calibrated) { ESP_LOGE(TAG, "No calibration scheme"); ESP_ERROR_CHECK(ESP_FAIL); } } // === Fim de: components/peripherals/src/adc.c === // === Início de: components/peripherals/src/adc121s021_dma.c === #include "driver/spi_master.h" #include "driver/gpio.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "adc121s021_dma.h" #define TAG "adc_dma" #define PIN_NUM_MOSI 23 #define PIN_NUM_MISO 19 #define PIN_NUM_CLK 18 #define PIN_NUM_CS 5 #define SPI_HOST_USED SPI2_HOST #define SAMPLE_SIZE_BYTES 2 #define ADC_BITS 12 static spi_device_handle_t adc_spi; void adc121s021_dma_init(void) { spi_bus_config_t buscfg = { .mosi_io_num = PIN_NUM_MOSI, .miso_io_num = PIN_NUM_MISO, .sclk_io_num = PIN_NUM_CLK, .quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = SAMPLE_SIZE_BYTES, }; spi_device_interface_config_t devcfg = { .clock_speed_hz = 6000000, // 6 MHz .mode = 0, .spics_io_num = PIN_NUM_CS, .queue_size = 2, .flags = SPI_DEVICE_NO_DUMMY, }; ESP_ERROR_CHECK(spi_bus_initialize(SPI_HOST_USED, &buscfg, SPI_DMA_CH_AUTO)); ESP_ERROR_CHECK(spi_bus_add_device(SPI_HOST_USED, &devcfg, &adc_spi)); } bool adc121s021_dma_get_sample(uint16_t *sample) { uint8_t tx_buffer[2] = {0x00, 0x00}; // Dummy TX uint8_t rx_buffer[2] = {0}; spi_transaction_t t = { .length = 16, // 16 bits .tx_buffer = tx_buffer, .rx_buffer = rx_buffer, .flags = 0 }; esp_err_t err = spi_device_transmit(adc_spi, &t); if (err != ESP_OK) { ESP_LOGE(TAG, "SPI transmit error: %s", esp_err_to_name(err)); return false; } // Extrai os 12 bits significativos da resposta do ADC121S021 *sample = ((rx_buffer[0] << 8) | rx_buffer[1]) & 0x0FFF; return true; } // === Fim de: components/peripherals/src/adc121s021_dma.c === // === Início de: components/peripherals/src/peripherals.c === #include "peripherals.h" #include "adc.h" #include "led.h" #include "buzzer.h" #include "proximity.h" #include "ac_relay.h" #include "socket_lock.h" #include "rcm.h" #include "aux_io.h" #include "ntc_sensor.h" void peripherals_init(void) { ac_relay_init(); led_init(); buzzer_init(); adc_init(); proximity_init(); // socket_lock_init(); // rcm_init(); //energy_meter_init(); // aux_init(); ntc_sensor_init(); } // === Fim de: components/peripherals/src/peripherals.c === // === Início de: components/peripherals/include/adc121s021_dma.h === #ifndef ADC_DMA_H_ #define ADC_DMA_H_ #include #include void adc121s021_dma_init(void); bool adc121s021_dma_get_sample(uint16_t *sample); #endif /* ADC_DMA_h_ */ // === Fim de: components/peripherals/include/adc121s021_dma.h === // === Início de: components/peripherals/include/peripherals.h === #ifndef PERIPHERALS_H #define PERIPHERALS_H void peripherals_init(void); #endif /* PERIPHERALS_H */ // === Fim de: components/peripherals/include/peripherals.h === // === Início de: components/peripherals/include/rcm.h === #ifndef RCM_H_ #define RCM_H_ #include /** * @brief Initialize residual current monitor * */ void rcm_init(void); /** * @brief Test residual current monitor * * @return true * @return false */ bool rcm_test(void); /** * @brief Residual current monitor was detected leakage * * @return true * @return false */ bool rcm_is_triggered(void); #endif /* RCM_H_ */ // === Fim de: components/peripherals/include/rcm.h === // === Início de: components/peripherals/include/aux_io.h === #ifndef AUX_IO_H_ #define AUX_IO_H_ #include "esp_err.h" /** * @brief Initialize aux * */ void aux_init(void); /** * @brief Read digital input * * @param name * @param value * @return esp_err_t */ esp_err_t aux_read(const char *name, bool *value); /** * @brief Write digial output * * @param name * @param value * @return esp_err_t */ esp_err_t aux_write(const char *name, bool value); /** * @brief Read analog input * * @param name * @param value * @return esp_err_t */ esp_err_t aux_analog_read(const char *name, int *value); #endif /* AUX_IO_H_ */ // === Fim de: components/peripherals/include/aux_io.h === // === Início de: components/peripherals/include/led.h === #ifndef LED_H_ #define LED_H_ #include #include /** * @brief Identificadores dos LEDs disponíveis no hardware */ typedef enum { LED_ID_STOP, LED_ID_CHARGING, LED_ID_ERROR, LED_ID_MAX } led_id_t; /** * @brief Padrões de comportamento possíveis para os LEDs */ typedef enum { LED_PATTERN_OFF, ///< LED sempre desligado LED_PATTERN_ON, ///< LED sempre ligado LED_PATTERN_BLINK, ///< Pisca com ciclo padrão (500ms on / 500ms off) LED_PATTERN_BLINK_FAST, ///< Pisca rápido (200ms / 200ms) LED_PATTERN_BLINK_SLOW, ///< Pisca lento (300ms / 1700ms) LED_PATTERN_CHARGING_EFFECT ///< Efeito visual para carregamento (2s on / 1s off) } led_pattern_t; /** * @brief Inicializa os LEDs com base na configuração da placa * Deve ser chamada uma única vez na inicialização do sistema. */ void led_init(void); /** * @brief Define diretamente o tempo ligado/desligado de um LED. * Pode ser usado para padrões personalizados. * * @param led_id Identificador do LED (ver enum led_id_t) * @param ontime Tempo ligado em milissegundos * @param offtime Tempo desligado em milissegundos */ void led_set_state(led_id_t led_id, uint16_t ontime, uint16_t offtime); /** * @brief Aplica um dos padrões de piscar definidos ao LED * * @param led_id Identificador do LED (ver enum led_id_t) * @param pattern Padrão desejado (ver enum led_pattern_t) */ void led_apply_pattern(led_id_t led_id, led_pattern_t pattern); #endif /* LED_H_ */ // === Fim de: components/peripherals/include/led.h === // === Início de: components/peripherals/include/buzzer.h === #ifndef BUZZER_H_ #define BUZZER_H_ #include /** * @brief Inicializa o buzzer e inicia monitoramento automático do estado EVSE. */ void buzzer_init(void); /** * @brief Liga e desliga o buzzer manualmente (uso interno ou testes). */ void buzzer_on(void); void buzzer_off(void); /** * @brief Ativa o buzzer por um período fixo (em milissegundos). */ void buzzer_beep_ms(uint16_t ms); #endif /* BUZZER_H_ */ // === Fim de: components/peripherals/include/buzzer.h === // === Início de: components/peripherals/include/ac_relay.h === #ifndef AC_RELAY_H_ #define AC_RELAY_H_ #include /** * @brief Inicializa o relé de corrente alternada. */ void ac_relay_init(void); /** * @brief Define o estado do relé de corrente alternada. * * @param state true para ligar, false para desligar. */ void ac_relay_set_state(bool state); /** * @brief Retorna o estado atual do relé de corrente alternada. * * @return true se estiver ligado, false se desligado. */ bool ac_relay_get_state(void); #endif /* AC_RELAY_H_ */ // === Fim de: components/peripherals/include/ac_relay.h === // === Início de: components/peripherals/include/lm75a.h === #ifndef LM75A_H #define LM75A_H #include "esp_err.h" // Para o uso de tipos de erro do ESP-IDF, caso esteja utilizando. #ifdef __cplusplus extern "C" { #endif /** * @brief Inicializa o sensor LM75A. * * Configura o sensor para leitura e define os pinos de comunicação. */ esp_err_t lm75a_init(void); /** * @brief Desinicializa o sensor LM75A. * * Libera os recursos usados pelo sensor. */ esp_err_t lm75a_deinit(void); /** * @brief Lê a temperatura do LM75A. * * @param show Se for 1, a temperatura será exibida em algum tipo de log ou interface. * Se for 0, o valor é apenas retornado sem exibição. * @return A temperatura lida em graus Celsius. */ float lm75a_read_temperature(int show); /** * @brief Define o valor do limite de temperatura (T_OS) para o sensor LM75A. * * @param tos O limite de temperatura de sobrecarga (T_OS) em graus Celsius. * @return ESP_OK em caso de sucesso ou código de erro se falhar. */ esp_err_t lm75a_set_tos(int tos); /** * @brief Define o valor do limite de temperatura de histerese (T_HYS) para o sensor LM75A. * * @param thys O limite de histerese de temperatura (T_HYS) em graus Celsius. * @return ESP_OK em caso de sucesso ou código de erro se falhar. */ esp_err_t lm75a_set_thys(int thys); /** * @brief Obtém o limite de temperatura de sobrecarga (T_OS) do sensor LM75A. * * @return O valor atual de T_OS em graus Celsius. */ int lm75a_get_tos(void); /** * @brief Obtém o limite de temperatura de histerese (T_HYS) do sensor LM75A. * * @return O valor atual de T_HYS em graus Celsius. */ int lm75a_get_thys(void); /** * @brief Habilita ou desabilita a interrupção do LM75A. * * @param en 1 para habilitar a interrupção, 0 para desabilitar. * @return ESP_OK em caso de sucesso ou código de erro se falhar. */ esp_err_t lm75a_set_int(int en); /** * @brief Obtém o estado do pino OS (Overtemperature Shutdown) do LM75A. * * @return 1 se o pino OS estiver ativo (indica que a temperatura de sobrecarga foi atingida), * 0 caso contrário. */ int lm75a_get_osio(void); #ifdef __cplusplus } #endif #endif /* LM75A_H */ // === Fim de: components/peripherals/include/lm75a.h === // === Início de: components/peripherals/include/ntc_sensor.h === #ifndef NTC_SENSOR_H_ #define NTC_SENSOR_H_ /** * @brief Initialize ntc senso * */ void ntc_sensor_init(void); /** * @brief Return temperature after temp_sensor_measure * * @return float */ float ntc_temp_sensor(void); #endif /* NTC_SENSOR_H_ */ // === Fim de: components/peripherals/include/ntc_sensor.h === // === Início de: components/peripherals/include/proximity.h === #ifndef PROXIMITY_H_ #define PROXIMITY_H_ #include /** * @brief Initialize proximity check * */ void proximity_init(void); /** * @brief Return measured value of max current on PP * * @return current in A */ uint8_t proximity_get_max_current(void); #endif /* PROXIMITY_H_ */ // === Fim de: components/peripherals/include/proximity.h === // === Início de: components/peripherals/include/socket_lock.h === #ifndef SOCKED_LOCK_H_ #define SOCKED_LOCK_H_ #include "esp_err.h" typedef enum { SOCKED_LOCK_STATUS_IDLE, SOCKED_LOCK_STATUS_OPERATING, SOCKED_LOCK_STATUS_LOCKING_FAIL, SOCKED_LOCK_STATUS_UNLOCKING_FAIL } socket_lock_status_t; /** * @brief Initialize socket lock * */ void socket_lock_init(void); /** * @brief Get socket lock detection on high, stored in NVS * * @return true when locked has zero resistance * @return false when unlocked has zero resistance */ bool socket_lock_is_detection_high(void); /** * @brief Set socket lock detection on high, stored in NVS * * @param detection_high */ void socket_lock_set_detection_high(bool detection_high); /** * @brief Get socket lock operating time * * @return time in ms */ uint16_t socket_lock_get_operating_time(void); /** * @brief Set socket lock operating time * * @param operating_time - time in ms * @return esp_err_t */ esp_err_t socket_lock_set_operating_time(uint16_t operating_time); /** * @brief Get socket lock retry count * * @return retry count */ uint8_t socket_lock_get_retry_count(void); /** * @brief Set socket lock retry count * * @param retry_count */ void socket_lock_set_retry_count(uint8_t retry_count); /** * @brief Get socket lock break time * * @return time in ms */ uint16_t socket_lock_get_break_time(void); /** * @brief Set socket lock break time * * @param break_time * @return esp_err_t */ esp_err_t socket_lock_set_break_time(uint16_t break_time); /** * @brief Set socke lock to locked / unlocked state * * @param locked */ void socket_lock_set_locked(bool locked); /** * @brief Get socket lock status * * @return socket_lock_status_t */ socket_lock_status_t socket_lock_get_status(void); /** * @brief Read the current physical lock state using the detection pin. */ bool socket_lock_is_locked_state(void); #endif /* SOCKED_LOCK_H_ */ // === Fim de: components/peripherals/include/socket_lock.h === // === Início de: components/peripherals/include/adc.h === #ifndef ADC_H_ #define ADC_H_ #include "esp_adc/adc_oneshot.h" #include "esp_adc/adc_cali.h" #include "esp_adc/adc_cali_scheme.h" extern adc_oneshot_unit_handle_t adc_handle; extern adc_cali_handle_t adc_cali_handle; void adc_init(void); #endif /* ADC_H_ */ // === Fim de: components/peripherals/include/adc.h ===