#include #include #include "driver/gpio.h" #include "driver/i2c.h" #include "esp_err.h" #include "esp_log.h" #include "freertos/portmacro.h" #include "hal/i2c_types.h" /* DAC Peripheral Config */ #define DAC_SCL_PIN 12 #define DAC_SDA_PIN 13 #define DAC_LDAC_PIN 14 #define DAC_ADDR 0x64 /* I2C Address of DAC */ #define DAC_VREF 0x00 /* Use Vdd as reference voltage */ #define DAC_PD 0x00 /* Full power mode */ #define DAC_GAIN 0x00 /* Since we use external Vref, this doesn't matter */ #define ACK_EN 0x1 /* Enable i2c acknowledgment check */ #define ACK_DIS 0x0 /* Disable i2c acknowledgment check */ #define ACK_VAL 0x0 /* i2c acknowledgment value */ #define NACK_VAL 0x1 /* i2c negative-acknowledgment value */ static const i2c_port_t I2C_MASTER_PORT = 0; static const char *TAG = "EERG"; /* Initialize and configure I2C DAC */ static void dac_init(void) { ESP_LOGI(TAG, "Initializing DAC I2C connection"); /* Configure µC as I2C master */ i2c_config_t i2c_conf = { .mode = I2C_MODE_MASTER, .scl_io_num = DAC_SCL_PIN, .sda_io_num = DAC_SDA_PIN, .master.clk_speed = 400000 /* 400kHz for i2c fast mode */ }; i2c_param_config(I2C_MASTER_PORT, &i2c_conf); /* Install i2c driver */ ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_PORT, i2c_conf.mode, 0, 0, 0)); /* Setup LDAC pin with GPIO. Tied low */ gpio_reset_pin(DAC_LDAC_PIN); gpio_set_direction(DAC_LDAC_PIN, GPIO_MODE_OUTPUT); gpio_set_level(DAC_LDAC_PIN, 0); } /* Tests for acknowledgment of i2c DAC. Return ESP_OK if so */ static esp_err_t dac_ack_test(void) { ESP_LOGI(TAG, "Testing I2C DAC"); /* Create i2c command handle */ i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (DAC_ADDR << 1) | I2C_MASTER_READ, ACK_EN); /* R/W byte is LSB of DAC address */ i2c_master_stop(cmd); esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_PORT, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); return ret; } static esp_err_t dac_out_test(void) { esp_err_t ret; uint16_t test_value = 0; /* The value sent to DAC input registers */ i2c_cmd_handle_t cmd; for (uint16_t i = 0; i < 4096; i++){ test_value = i; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (DAC_ADDR << 1) | I2C_MASTER_WRITE, ACK_EN); /* R/W byte is LSB of DAC address */ i2c_master_write_byte(cmd, 0x50, ACK_EN); /* Multi-write to all channels */ /* For each channel [A-D] write 2 bytes to input register */ /* V_ref + PD1 + PD0 + Gx + D11-D8 | D7-D0 */ for (uint8_t i = 0; i < 4; i++) { uint8_t bytes[2]; bytes[0] = ((uint8_t) DAC_VREF << 7) | ((uint8_t) DAC_PD << 5) | ((uint8_t) DAC_GAIN << 4) | (test_value >> 8); bytes[1] = test_value; i2c_master_write_byte(cmd, bytes[0], ACK_EN); i2c_master_write_byte(cmd, bytes[1], ACK_EN); } i2c_master_stop(cmd); /* Issue the multi-write command */ /* TODO need to create array of returns and check them for error */ ret = i2c_master_cmd_begin(I2C_MASTER_PORT, cmd, 1000 / portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); } return ret; } /* Main application entrance */ void app_main(void) { /* Initialize and configure I2C DAC */ dac_init(); /* Test DAC */ esp_err_t ret = dac_ack_test(); if (ret != ESP_OK){ ESP_LOGE(TAG, "Failed to initialize DAC"); } else { ESP_LOGI(TAG, "Sucessfully initialized DAC"); } /* Loop to test DAC output */ while (1) { dac_out_test(); } }