implemented EEPROM write operation with data overlapped page size margin
This commit is contained in:
parent
6cb5bc0e9c
commit
9276d4a6c1
58
src/EEPROM.c
58
src/EEPROM.c
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright 2024 Bogdan Pilyugin
|
/* Copyright 2024 Bogdan Pilyugin
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
|
|
||||||
#define TAG "EEPROMDriver"
|
#define TAG "EEPROMDriver"
|
||||||
|
|
||||||
|
|
||||||
#define I2C_MASTER_TIMEOUT_MS 1000
|
#define I2C_MASTER_TIMEOUT_MS 1000
|
||||||
#define I2C_MASTER_NUM CONFIG_I2C_HOST /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
|
#define I2C_MASTER_NUM CONFIG_I2C_HOST /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
|
||||||
#define I2C_MASTER_SDA_GPIO CONFIG_I2C_SDA_GPIO /*!< I2C master i2c SDA pin*/
|
#define I2C_MASTER_SDA_GPIO CONFIG_I2C_SDA_GPIO /*!< I2C master i2c SDA pin*/
|
||||||
|
|
@ -41,23 +40,24 @@ typedef struct
|
||||||
uint32_t clk_speed; // I2C clock frequency for master mode
|
uint32_t clk_speed; // I2C clock frequency for master mode
|
||||||
} i2c_dev_t;
|
} i2c_dev_t;
|
||||||
|
|
||||||
|
|
||||||
i2c_dev_t eepr_24c32 = {
|
i2c_dev_t eepr_24c32 = {
|
||||||
.port = I2C_MASTER_NUM,
|
.port = I2C_MASTER_NUM,
|
||||||
.addr = EEPR24CXX_ADDR >> 1,
|
.addr = EEPR24CXX_ADDR >> 1,
|
||||||
.clk_speed = CONFIG_I2C_CLOCK
|
.clk_speed = CONFIG_I2C_CLOCK
|
||||||
};
|
};
|
||||||
|
|
||||||
static esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size)
|
static esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data,
|
||||||
|
size_t in_size)
|
||||||
{
|
{
|
||||||
if (!dev || !in_data || !in_size) return ESP_ERR_INVALID_ARG;
|
if (!dev || !in_data || !in_size)
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
|
||||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
if (out_data && out_size)
|
if (out_data && out_size)
|
||||||
{
|
{
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true);
|
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true);
|
||||||
i2c_master_write(cmd, (void *)out_data, out_size, true);
|
i2c_master_write(cmd, (void*) out_data, out_size, true);
|
||||||
}
|
}
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
i2c_master_write_byte(cmd, (dev->addr << 1) | 1, true);
|
i2c_master_write_byte(cmd, (dev->addr << 1) | 1, true);
|
||||||
|
|
@ -66,30 +66,32 @@ static esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t
|
||||||
|
|
||||||
esp_err_t res = i2c_master_cmd_begin(dev->port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
|
esp_err_t res = i2c_master_cmd_begin(dev->port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
|
||||||
/*
|
/*
|
||||||
if (res != ESP_OK)
|
if (res != ESP_OK)
|
||||||
ESP_LOGE(TAG, "Could not read from device [0x%02x at %d]: %d", dev->addr, dev->port, res);
|
ESP_LOGE(TAG, "Could not read from device [0x%02x at %d]: %d", dev->addr, dev->port, res);
|
||||||
*/
|
*/
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size)
|
static esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data,
|
||||||
|
size_t out_size)
|
||||||
{
|
{
|
||||||
if (!dev || !out_data || !out_size) return ESP_ERR_INVALID_ARG;
|
if (!dev || !out_data || !out_size)
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
|
||||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
i2c_master_start(cmd);
|
i2c_master_start(cmd);
|
||||||
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true);
|
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true);
|
||||||
if (out_reg && out_reg_size)
|
if (out_reg && out_reg_size)
|
||||||
i2c_master_write(cmd, (void *)out_reg, out_reg_size, true);
|
i2c_master_write(cmd, (void*) out_reg, out_reg_size, true);
|
||||||
i2c_master_write(cmd, (void *)out_data, out_size, true);
|
i2c_master_write(cmd, (void*) out_data, out_size, true);
|
||||||
i2c_master_stop(cmd);
|
i2c_master_stop(cmd);
|
||||||
|
|
||||||
esp_err_t res = i2c_master_cmd_begin(dev->port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
|
esp_err_t res = i2c_master_cmd_begin(dev->port, cmd, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
|
||||||
/*
|
/*
|
||||||
if (res != ESP_OK)
|
if (res != ESP_OK)
|
||||||
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d", dev->addr, dev->port, res);
|
ESP_LOGE(TAG, "Could not write to device [0x%02x at %d]: %d", dev->addr, dev->port, res);
|
||||||
*/
|
*/
|
||||||
i2c_cmd_link_delete(cmd);
|
i2c_cmd_link_delete(cmd);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -97,13 +99,29 @@ static esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t
|
||||||
esp_err_t eepr_i2c_read(uint16_t addr, uint8_t *data, int length)
|
esp_err_t eepr_i2c_read(uint16_t addr, uint8_t *data, int length)
|
||||||
{
|
{
|
||||||
uint8_t adr[] = { (uint8_t)(addr >> 8), (uint8_t)(addr & 0xff) };
|
uint8_t adr[] = { (uint8_t)(addr >> 8), (uint8_t)(addr & 0xff) };
|
||||||
return i2c_dev_read(&eepr_24c32 , adr, 2, data, length);
|
return i2c_dev_read(&eepr_24c32, adr, 2, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define EEPROM_WRITE_PAGE_SIZE 32
|
||||||
|
#define EEPROM_WRITE_MAX_ATTEMPTS 5
|
||||||
esp_err_t eepr_i2c_write(uint16_t addr, uint8_t *data, int length)
|
esp_err_t eepr_i2c_write(uint16_t addr, uint8_t *data, int length)
|
||||||
{
|
{
|
||||||
uint8_t adr[] = { (uint8_t)(addr >> 8), (uint8_t)(addr & 0xff) };
|
int written = 0, attempts = 0;
|
||||||
return i2c_dev_write(&eepr_24c32 , adr, 2, data, length);
|
uint16_t block_addr = addr;
|
||||||
|
esp_err_t err;
|
||||||
|
while ((length - written) > 0)
|
||||||
|
{
|
||||||
|
int block_len = MIN(length - written, EEPROM_WRITE_PAGE_SIZE);
|
||||||
|
uint8_t adr[] = { (uint8_t)(block_addr >> 8), (uint8_t)(block_addr & 0xff) };
|
||||||
|
while ((err = i2c_dev_write(&eepr_24c32, adr, 2, data + written, block_len)) != ESP_OK)
|
||||||
|
{
|
||||||
|
if (++attempts >= EEPROM_WRITE_MAX_ATTEMPTS) //Critical error
|
||||||
|
return err;
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(5));
|
||||||
|
}
|
||||||
|
written += block_len;
|
||||||
|
block_addr += EEPROM_WRITE_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user