#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;
}
