Code: Select all
#include <string.h>
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "spi_flash_mmap.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "freertos/timers.h"
#include "soc/rtc.h"
#include "esp_timer.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_random.h"
#include "rom/gpio.h"
#include "esp_task_wdt.h"
#include "soc/timer_group_struct.h"
#include "soc/timer_group_reg.h"
#include "driver/i2c.h"
#include <rom/ets_sys.h>
#define ADS1115_REG_POINTER_CONVERT (0x00)
#define ADS1115_REG_POINTER_CONFIG (0x01)
#define ADS1115_REG_CONFIG_MUX_SINGLE_0 (0x4000)
#define ADS1115_REG_CONFIG_MUX_SINGLE_1 (0x5000)
#define ADS1115_REG_CONFIG_MUX_SINGLE_2 (0x6000)
#define ADS1115_REG_CONFIG_MUX_SINGLE_3 (0x7000)
#define ADS1115_REG_CONFIG_CQUE_NONE (0x0003)
#define ADS1115_REG_CONFIG_CLAT_NONLAT (0x0000)
#define ADS1115_REG_CONFIG_CPOL_ACTVLOW (0x0000)
#define ADS1115_REG_CONFIG_CMODE_TRAD (0x0000)
#define ADS1115_REG_CONFIG_MODE_SINGLE (0x0100)
#define ADS1115_REG_CONFIG_PGA_6_144V (0x0000)
#define ADS1115_REG_CONFIG_DR_860SPS (0x00E0)
#define ADS1115_REG_CONFIG_OS_SINGLE (0x8000)
#define ADS_I2C_FREQ_HZ 1000000
#define FRAM_I2C_FREQ_HZ 1000000
#define ADS_I2C_NUM I2C_NUM_0
#define FRAM_I2C_NUM I2C_NUM_1
#define ADS_SCL GPIO_NUM_22
#define ADS_SDA GPIO_NUM_21
#define FRAM_SCL GPIO_NUM_18
#define FRAM_SDA GPIO_NUM_19
#define ADS1115_I2C_ADDRESS_1 0b1001000 // ADDR = GND
#define ADS1115_I2C_ADDRESS_2 0b1001001 // ADDR = VDD
#define FRAM_I2C_ADDRESS 0b1010 // base part - Slave ID
static const char *TAG = "main";
static i2c_config_t conf0 = {
.mode = I2C_MODE_MASTER,
.sda_io_num = ADS_SDA,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_io_num = ADS_SCL,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = ADS_I2C_FREQ_HZ,
.clk_flags = 0,
};
static i2c_config_t conf1 = {
.mode = I2C_MODE_MASTER,
.sda_io_num = FRAM_SDA,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_io_num = FRAM_SCL,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = FRAM_I2C_FREQ_HZ,
.clk_flags = 0,
};
static void i2c_init()
{
ESP_LOGI(TAG, "i2c_init");
i2c_param_config(ADS_I2C_NUM, &conf0);
i2c_driver_install(ADS_I2C_NUM, conf0.mode, 0, 0, 0);
i2c_param_config(FRAM_I2C_NUM, &conf1);
i2c_driver_install(FRAM_I2C_NUM, conf1.mode, 0, 0, 0);
}
static void feed_the_dog()
{
// feed dog 0
TIMERG0.wdtwprotect.val = TIMG_WDT_WKEY_VALUE; // write enable
TIMERG0.wdtfeed.val = 1; // feed dog
TIMERG0.wdtwprotect.val = 0; // write protect
// feed dog 1
TIMERG1.wdtwprotect.val = TIMG_WDT_WKEY_VALUE; // write enable
TIMERG1.wdtfeed.val = 1; // feed dog
TIMERG1.wdtwprotect.val = 0; // write protect
}
static uint16_t ads1115_get_raw_value(uint8_t address, uint16_t channel)
{
uint16_t config = ADS1115_REG_CONFIG_CQUE_NONE |
ADS1115_REG_CONFIG_CLAT_NONLAT |
ADS1115_REG_CONFIG_CPOL_ACTVLOW |
ADS1115_REG_CONFIG_CMODE_TRAD |
ADS1115_REG_CONFIG_MODE_SINGLE;
config |= ADS1115_REG_CONFIG_PGA_6_144V;
config |= ADS1115_REG_CONFIG_DR_860SPS;
config |= ADS1115_REG_CONFIG_OS_SINGLE;
config |= channel;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, ADS1115_REG_POINTER_CONFIG, true);
i2c_master_write_byte(cmd, (uint8_t)(config >> 8), true);
i2c_master_write_byte(cmd, (uint8_t)config, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(ADS_I2C_NUM, cmd, pdMS_TO_TICKS(1000));
i2c_cmd_link_delete(cmd);
ets_delay_us(1170);
uint8_t data_h = 0, data_l = 0;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, &data_h, false);
i2c_master_read_byte(cmd, &data_l, false);
i2c_master_stop(cmd);
i2c_master_cmd_begin(ADS_I2C_NUM, cmd, pdMS_TO_TICKS(1000));
i2c_cmd_link_delete(cmd);
if (data_h >> 7 != 1)
{
ESP_LOGE(TAG, "Данные еще не готовы");
}
i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, ADS1115_REG_POINTER_CONVERT, true);
i2c_master_stop(cmd);
i2c_master_cmd_begin(ADS_I2C_NUM, cmd, pdMS_TO_TICKS(1000));
i2c_cmd_link_delete(cmd);
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_READ, true);
i2c_master_read_byte(cmd, &data_h, false);
i2c_master_read_byte(cmd, &data_l, false);
i2c_master_stop(cmd);
i2c_master_cmd_begin(ADS_I2C_NUM, cmd, pdMS_TO_TICKS(1000));
i2c_cmd_link_delete(cmd);
uint16_t raw_measurement = (data_h << 8 | data_l);
int raw_measurement_as_signed_int = (INT16_MAX + 1) & raw_measurement ? 0 : raw_measurement;
return raw_measurement_as_signed_int;
}
void ads1115_get_data(uint16_t *data_p)
{
data_p[0] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_1, ADS1115_REG_CONFIG_MUX_SINGLE_0);
data_p[1] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_1, ADS1115_REG_CONFIG_MUX_SINGLE_1);
data_p[2] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_1, ADS1115_REG_CONFIG_MUX_SINGLE_2);
data_p[3] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_1, ADS1115_REG_CONFIG_MUX_SINGLE_3);
data_p[4] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_2, ADS1115_REG_CONFIG_MUX_SINGLE_2);
data_p[5] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_2, ADS1115_REG_CONFIG_MUX_SINGLE_3);
data_p[6] = ads1115_get_raw_value(ADS1115_I2C_ADDRESS_2, ADS1115_REG_CONFIG_MUX_SINGLE_0);
}
static void get_data_task(void *const pvParameters)
{
ESP_LOGI(TAG, "get_data_task start, CoreId %d", xPortGetCoreID());
uint8_t channels_count = 7;
uint8_t measure_count = 20;
uint16_t buffer[channels_count];
uint16_t raw_data[channels_count][measure_count];
float results[channels_count];
while (true)
{
for (int m = 0; m < measure_count; m++)
{
ads1115_get_data(buffer);
for (int c = 0; c < channels_count; c++)
{
raw_data[c][m] = buffer[c];
}
}
feed_the_dog();
}
ESP_LOGI(TAG, "get_data_task end");
vTaskDelete(NULL);
}
static void storage_write_uint32_internal(uint32_t value, uint8_t slave_address, uint8_t word_address)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, FRAM_I2C_ADDRESS << 4 | (slave_address << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, word_address, true);
for (int i = 0; i < sizeof(uint32_t); i++)
{
i2c_master_write_byte(cmd, (value >> (8 * i)) & 0xFF, true);
}
i2c_master_stop(cmd);
i2c_master_cmd_begin(FRAM_I2C_NUM, cmd, pdMS_TO_TICKS(1000));
i2c_cmd_link_delete(cmd);
}
static void storage_task(void *const pvParameters)
{
ESP_LOGI(TAG, "storage_task start, CoreId %d", xPortGetCoreID());
while (true)
{
storage_write_uint32_internal(42, 0, 0);
vTaskDelay(pdMS_TO_TICKS(100));
}
ESP_LOGI(TAG, "storage_task end");
vTaskDelete(NULL);
}
void app_main()
{
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
uint32_t size_flash_chip;
esp_flash_get_size(NULL, &size_flash_chip);
rtc_cpu_freq_config_t c;
rtc_clk_cpu_freq_get_config(&c);
ESP_LOGI(TAG, "CPU clock frequency: %ld MHz", c.freq_mhz);
ESP_LOGI(TAG, "This is %s chip with %d CPU cores, WiFi%s%s, ", CONFIG_IDF_TARGET, chip_info.cores, (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
ESP_LOGI(TAG, "Silicon revision %d, ", chip_info.revision);
ESP_LOGI(TAG, "%ldMB %s flash", size_flash_chip / (1024 * 1024), (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
ESP_LOGI(TAG, "configMINIMAL_STACK_SIZE=%d", configMINIMAL_STACK_SIZE);
ESP_LOGI(TAG, "Free memory: %ld bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "IDF version: %s", esp_get_idf_version());
i2c_init();
xTaskCreatePinnedToCore(&storage_task, "storage_task", 3000, NULL, 5, NULL, 0);
xTaskCreatePinnedToCore(&get_data_task, "get_data_task", 8000, NULL, 5, NULL, 1);
}