fix ade7758

This commit is contained in:
2025-06-25 06:34:03 +01:00
parent a0b2e048d4
commit 84f106eee5
53 changed files with 7079 additions and 18456 deletions

View File

@@ -1,186 +1,184 @@
#include <stdio.h>
#include <stdlib.h>
#include "driver/spi_master.h"
#include "sdkconfig.h"
#include "esp_log.h"
#include "ade7758.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_rom_sys.h"
spi_bus_config_t _spi_bus_cfg;
// spi_device_interface_config_t _spi_interface_cfg;
spi_device_handle_t _handle;
spi_host_device_t _spi_peripheral;
spi_transaction_t _spi_transaction;
esp_err_t transferByte(const uint8_t reg_addr, const uint8_t data, const uint8_t command)
{
_spi_transaction.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
_spi_transaction.length = 8;
//_spi_transaction.rxlength = 8;
_spi_transaction.cmd = command;
_spi_transaction.addr = reg_addr;
_spi_transaction.tx_data[0] = data;
#define PIN_ADUM_EN 4 // ou o pino real conectado ao VE1 do ADUM1401
return spi_device_transmit(_handle, &_spi_transaction);
static const char *TAG = "ade7758";
// --- SPI internals ---
static spi_device_handle_t ade7758_spi_handle = NULL;
static spi_host_device_t spi_host = SPI2_HOST; // default
static spi_transaction_t spi_transaction;
// --- Configuração SPI do dispositivo ---
static const uint8_t MODE = 2;
static const uint8_t ADDR_BITS = 7;
static const uint8_t CMD_BITS = 1;
static const uint8_t SPI_WRITE = 1;
static const uint8_t SPI_READ = 0;
static const int BUS_SPEED_HZ = 1000000;
static void adum1401_select(void) {
gpio_set_level(PIN_ADUM_EN, 1);
esp_rom_delay_us(2); // curto delay para estabilização
}
esp_err_t transferMultiplesBytes(const uint8_t reg_addr, uint8_t *tx_buf, uint8_t *rx_buf, size_t data_length, const uint8_t command)
{
spi_transaction_t spi_transaction_multibyte; // spi_transaction_t to use the tx and rx buffers
if (data_length < 1)
{
data_length = 1;
}
spi_transaction_multibyte.flags = 0; // SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
spi_transaction_multibyte.length = (8 * data_length);
spi_transaction_multibyte.rxlength = 0;
spi_transaction_multibyte.cmd = command;
spi_transaction_multibyte.addr = reg_addr;
spi_transaction_multibyte.tx_buffer = tx_buf;
spi_transaction_multibyte.rx_buffer = rx_buf;
return spi_device_transmit(_handle, &spi_transaction_multibyte);
static void adum1401_deselect(void) {
esp_rom_delay_us(2); // opcional: aguarde para evitar glitch
gpio_set_level(PIN_ADUM_EN, 0);
}
esp_err_t Init(const spi_host_device_t spi_peripheral, const int pin_miso, const int pin_mosi, const int pin_sclk)
{
esp_err_t status = ESP_OK;
// === Transações básicas ===
_spi_peripheral = spi_peripheral;
static esp_err_t transfer_byte(uint8_t reg_addr, uint8_t data, uint8_t command) {
adum1401_select();
_spi_transaction.tx_buffer = NULL;
_spi_transaction.rx_buffer = NULL;
spi_transaction.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA;
spi_transaction.length = 8;
spi_transaction.cmd = command;
spi_transaction.addr = reg_addr;
spi_transaction.tx_data[0] = data;
_spi_bus_cfg.mosi_io_num = pin_mosi;
_spi_bus_cfg.miso_io_num = pin_miso;
_spi_bus_cfg.sclk_io_num = pin_sclk;
_spi_bus_cfg.quadwp_io_num = -1;
_spi_bus_cfg.quadhd_io_num = -1;
esp_err_t err = spi_device_transmit(ade7758_spi_handle, &spi_transaction);
status |= spi_bus_initialize(spi_peripheral, &_spi_bus_cfg, SPI_DMA_CH_AUTO);
return status;
adum1401_deselect();
return err;
}
esp_err_t RegisterDevice(const uint8_t mode, const int ss, const int addr_length, const int command_length, const int bus_speed)
{
esp_err_t status = ESP_OK;
spi_device_interface_config_t _spi_interface_cfg = {
.command_bits = command_length,
.address_bits = addr_length,
.mode = mode,
.clock_speed_hz = bus_speed,
.spics_io_num = ss,
static esp_err_t transfer_bytes(uint8_t reg_addr, uint8_t *tx_buf, uint8_t *rx_buf, size_t len, uint8_t command) {
if (len < 1) len = 1;
spi_transaction_t t = {
.flags = 0,
.length = 8 * len,
.cmd = command,
.addr = reg_addr,
.tx_buffer = tx_buf,
.rx_buffer = rx_buf
};
adum1401_select();
esp_err_t err = spi_device_transmit(ade7758_spi_handle, &t);
adum1401_deselect();
return err;
}
// === Interface pública ===
esp_err_t Init(spi_host_device_t host, int pin_miso, int pin_mosi, int pin_sclk) {
// Essa função não inicializa o barramento SPI
// Apenas armazena os parâmetros
spi_host = host;
return ESP_OK;
}
esp_err_t InitSpi(int cs_gpio) {
spi_device_interface_config_t devcfg = {
.command_bits = CMD_BITS,
.address_bits = ADDR_BITS,
.mode = MODE,
.clock_speed_hz = BUS_SPEED_HZ,
.spics_io_num = cs_gpio,
.queue_size = 5,
};
status |= spi_bus_add_device(_spi_peripheral, &_spi_interface_cfg, &_handle);
gpio_config_t io_conf = {
.pin_bit_mask = BIT64(PIN_ADUM_EN),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io_conf);
gpio_set_level(PIN_ADUM_EN, 0); // inicialmente desativado
return status;
return spi_bus_add_device(spi_host, &devcfg, &ade7758_spi_handle);
}
uint8_t ReadRegister(const uint8_t reg_addr, const uint8_t command)
{
transferByte(reg_addr, 0, command);
return _spi_transaction.rx_data[0];
spi_device_handle_t GetHandle(void) {
return ade7758_spi_handle;
}
esp_err_t WriteRegister(const uint8_t reg_addr, const uint8_t reg_data, const uint8_t command)
{
esp_err_t status = ESP_OK;
// === Registro de acesso ===
status |= transferByte(reg_addr, reg_data, command);
return status;
uint8_t ReadRegister(uint8_t reg_addr, uint8_t command) {
transfer_byte(reg_addr, 0, command);
return spi_transaction.rx_data[0];
}
esp_err_t WriteRegisterMultipleBytes(const uint8_t reg_addr, uint8_t *reg_data_buffer, const uint8_t byte_count, const uint8_t command)
{
return transferMultiplesBytes(reg_addr, reg_data_buffer, NULL, byte_count, command);
esp_err_t WriteRegister(uint8_t reg_addr, uint8_t data, uint8_t command) {
return transfer_byte(reg_addr, data, command);
}
esp_err_t ReadRegisterMultipleBytes(const uint8_t reg_addr, uint8_t *reg_data_buffer, const uint8_t byte_count, const uint8_t command)
{
return transferMultiplesBytes(reg_addr, NULL, reg_data_buffer, byte_count, command);
esp_err_t WriteRegisterMultipleBytes(uint8_t reg, uint8_t *data, uint8_t count, uint8_t command) {
return transfer_bytes(reg, data, NULL, count, command);
}
spi_device_handle_t GetHandle(void)
{
return _handle;
esp_err_t ReadRegisterMultipleBytes(uint8_t reg, uint8_t *buf, uint8_t count, uint8_t command) {
return transfer_bytes(reg, NULL, buf, count, command);
}
static uint8_t MODE = 2;
static uint8_t ADDR_BITS = 7;
static uint8_t CMD_BITS = 1;
// === Leitura e escrita de tamanho fixo ===
static uint8_t SPI_WRITE = 1;
static uint8_t SPI_READ = 0;
static int BUSSPEED = 1000000;
// static const char TAG[] = "ade7758";
esp_err_t write8(uint8_t reg, uint8_t value)
{
esp_err_t write8(uint8_t reg, uint8_t value) {
return WriteRegister(reg, value, SPI_WRITE);
}
esp_err_t write16(uint8_t reg, uint32_t value)
{
uint8_t buff[2];
buff[0] = (value >> 8) & 0xFF;
buff[1] = (value >> 0) & 0xFF;
return WriteRegisterMultipleBytes(reg, buff, 3, SPI_WRITE);
esp_err_t write16(uint8_t reg, uint32_t value) {
uint8_t buf[2] = {
(value >> 8) & 0xFF,
(value >> 0) & 0xFF
};
return WriteRegisterMultipleBytes(reg, buf, 2, SPI_WRITE);
}
esp_err_t write24(uint8_t reg, uint32_t value)
{
uint8_t buff[2];
buff[0] = (value >> 16) & 0xFF;
buff[1] = (value >> 8) & 0xFF;
buff[2] = (value >> 0) & 0xFF;
return WriteRegisterMultipleBytes(reg, buff, 4, SPI_WRITE);
esp_err_t write24(uint8_t reg, uint32_t value) {
uint8_t buf[3] = {
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
(value >> 0) & 0xFF
};
return WriteRegisterMultipleBytes(reg, buf, 3, SPI_WRITE);
}
uint8_t read8(const uint8_t reg)
{
uint8_t buff[1];
ReadRegisterMultipleBytes(reg, buff, 2, SPI_READ);
return buff[0];
uint8_t read8(uint8_t reg) {
uint8_t buf[1];
ReadRegisterMultipleBytes(reg, buf, 1, SPI_READ);
return buf[0];
}
uint32_t read16(const uint8_t reg)
{
uint8_t buff[2];
ReadRegisterMultipleBytes(reg, buff, 3, SPI_READ);
return buff[0] << 8 | buff[1];
uint32_t read16(uint8_t reg) {
uint8_t buf[2];
ReadRegisterMultipleBytes(reg, buf, 2, SPI_READ);
return (buf[0] << 8) | buf[1];
}
uint32_t read24(const uint8_t reg)
{
uint8_t buff[3];
ReadRegisterMultipleBytes(reg, buff, 4, SPI_READ);
return buff[0] << 16 | buff[1] << 8 | buff[2];
uint32_t read24(uint8_t reg) {
uint8_t buf[3];
ReadRegisterMultipleBytes(reg, buf, 3, SPI_READ);
return (buf[0] << 16) | (buf[1] << 8) | buf[2];
}
esp_err_t readBlockData(const uint8_t reg, uint8_t *buf, const int length)
{
return ReadRegisterMultipleBytes(reg, buf, length, SPI_READ);
esp_err_t readBlockData(uint8_t reg, uint8_t *buf, int len) {
return ReadRegisterMultipleBytes(reg, buf, len, SPI_READ);
}
esp_err_t InitSpi(const int ss)
{
return RegisterDevice(MODE, ss, ADDR_BITS, CMD_BITS, BUSSPEED);
}
/*****************************
*

View File

@@ -1,4 +1,5 @@
#include "meter_ade7758.h"
#include "spi_bus_manager.h"
#include "ade7758.h"
#include "meter_events.h"
@@ -11,16 +12,13 @@
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#define TAG "meter_ade7758"
// === Configurações de hardware ===
#define PIN_NUM_CLK 15
#define PIN_NUM_MOSI 2
#define PIN_NUM_MISO 4
#define PIN_NUM_CS 23
#define EEPROM_HOST HSPI_HOST
// === Pinos ===
#define PIN_NUM_CS 15
#define PIN_ADUM_EN 4
// === Constantes de calibração ===
#define VRMS_CAL 4732.78f
@@ -28,13 +26,13 @@
#define METER_READ_INTERVAL_MS 5000
// === Dados internos ===
// === Estrutura interna ===
typedef struct {
float vrms[3];
float irms[3];
int watt[3];
int var[3]; // reservados
int va[3]; // reservados
int var[3]; // reservado
int va[3]; // reservado
} meter_ade7758_internal_data_t;
static meter_ade7758_internal_data_t meter_data;
@@ -42,7 +40,8 @@ static TaskHandle_t meter_task = NULL;
static SemaphoreHandle_t meter_mutex = NULL;
static uint32_t meter_watchdog_counter = 0;
// === Utilitários internos ===
// === Post de evento ===
static void meter_ade7758_post_event(const meter_ade7758_internal_data_t *data) {
meter_event_data_t evt = {
.frequency = 0,
@@ -54,22 +53,23 @@ static void meter_ade7758_post_event(const meter_ade7758_internal_data_t *data)
memcpy(evt.irms, data->irms, sizeof(evt.irms));
memcpy(evt.watt, data->watt, sizeof(evt.watt));
esp_err_t err = esp_event_post(METER_EVENT, METER_EVENT_DATA_READY,
&evt, sizeof(evt), pdMS_TO_TICKS(10));
esp_err_t err = esp_event_post(METER_EVENT, METER_EVENT_DATA_READY, &evt, sizeof(evt), pdMS_TO_TICKS(10));
if (err != ESP_OK) {
ESP_LOGW(TAG, "Falha ao emitir evento: %s", esp_err_to_name(err));
}
}
// === Task de leitura ===
static void meter_ade7758_task_func(void *param) {
ESP_LOGI(TAG, "Meter task started");
ESP_LOGI(TAG, "Tarefa de medição ADE7758 iniciada");
meter_ade7758_internal_data_t previous = {0};
while (true) {
meter_ade7758_internal_data_t meterData = {0};
//ESP_LOGI(TAG, "Tarefa de medição ADE7758 iniciada %d",getVersion());
meterData.vrms[0] = avrms() / VRMS_CAL;
meterData.vrms[1] = bvrms() / VRMS_CAL;
meterData.vrms[2] = cvrms() / VRMS_CAL;
@@ -97,10 +97,9 @@ static void meter_ade7758_task_func(void *param) {
}
}
// === Interface pública: controle ===
// === Inicialização ===
esp_err_t meter_ade7758_init(void) {
ESP_LOGI(TAG, "Inicializando medidor ADE7758...");
ESP_LOGI(TAG, "Inicializando ADE7758...");
if (!meter_mutex) {
meter_mutex = xSemaphoreCreateMutex();
@@ -110,21 +109,38 @@ esp_err_t meter_ade7758_init(void) {
}
}
esp_err_t err = Init(EEPROM_HOST, PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK);
if (!spi_bus_manager_is_initialized()) {
esp_err_t err = spi_bus_manager_init(); // usa pinos padrão
if (err != ESP_OK) {
ESP_LOGE(TAG, "Erro ao inicializar SPI: %s", esp_err_to_name(err));
return err;
}
}
vTaskDelay(pdMS_TO_TICKS(10)); // Delay de estabilização
esp_err_t err = Init(spi_bus_manager_get_host(), -1, -1, -1);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Erro ao inicializar SPI (%d)", err);
ESP_LOGE(TAG, "Erro Init SPI ADE7758: %s", esp_err_to_name(err));
return err;
}
err = InitSpi(PIN_NUM_CS);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Erro ao registrar dispositivo SPI: %s", esp_err_to_name(err));
return err;
}
InitSpi(PIN_NUM_CS);
gainSetup(INTEGRATOR_OFF, FULLSCALESELECT_0_5V, GAIN_1, GAIN_1);
setupDivs(1, 1, 1);
setLcycMode(0x00);
resetStatus();
ESP_LOGI(TAG, "ADE7758 inicializado com sucesso.");
return ESP_OK;
}
// === Execução ===
esp_err_t meter_ade7758_start(void) {
if (meter_task) return ESP_ERR_INVALID_STATE;