kopia lustrzana https://github.com/espressif/esp-idf
Merge 2fcb67cb0c
into d4cd437ede
commit
1daafbc479
|
@ -193,14 +193,30 @@ static bool s_i2c_write_command(i2c_master_bus_handle_t i2c_master, i2c_operatio
|
|||
i2c_master->async_break = true;
|
||||
}
|
||||
} else {
|
||||
i2c_master->cmd_idx++;
|
||||
i2c_master->trans_idx++;
|
||||
i2c_master->i2c_trans.cmd_count--;
|
||||
if (i2c_master->async_trans == false) {
|
||||
if (xPortInIsrContext()) {
|
||||
xSemaphoreGiveFromISR(i2c_master->cmd_semphr, do_yield);
|
||||
// Handle consecutive i2c write operations
|
||||
i2c_operation_t next_transaction = i2c_master->i2c_trans.ops[i2c_master->trans_idx + 1];
|
||||
if (next_transaction.hw_cmd.op_code == I2C_LL_CMD_WRITE) {
|
||||
portENTER_CRITICAL_SAFE(&handle->spinlock);
|
||||
i2c_ll_master_write_cmd_reg(hal->dev, hw_end_cmd, i2c_master->cmd_idx + 1);
|
||||
portEXIT_CRITICAL_SAFE(&handle->spinlock);
|
||||
i2c_master->cmd_idx = 0;
|
||||
i2c_master->trans_idx++;
|
||||
i2c_master->i2c_trans.cmd_count--;
|
||||
if (i2c_master->async_trans == false) {
|
||||
i2c_hal_master_trans_start(hal);
|
||||
} else {
|
||||
xSemaphoreGive(i2c_master->cmd_semphr);
|
||||
i2c_master->async_break = true;
|
||||
}
|
||||
} else {
|
||||
i2c_master->cmd_idx++;
|
||||
i2c_master->trans_idx++;
|
||||
i2c_master->i2c_trans.cmd_count--;
|
||||
if (i2c_master->async_trans == false) {
|
||||
if (xPortInIsrContext()) {
|
||||
xSemaphoreGiveFromISR(i2c_master->cmd_semphr, do_yield);
|
||||
} else {
|
||||
xSemaphoreGive(i2c_master->cmd_semphr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -524,7 +540,6 @@ static void s_i2c_send_command_async(i2c_master_bus_handle_t i2c_master, BaseTyp
|
|||
needs_start = s_i2c_read_command(i2c_master, i2c_operation, &fifo_fill, do_yield);
|
||||
} else {
|
||||
s_i2c_start_end_command(i2c_master, i2c_operation, &address_fill, do_yield);
|
||||
|
||||
}
|
||||
}
|
||||
i2c_hal_master_trans_start(hal);
|
||||
|
@ -1076,6 +1091,27 @@ esp_err_t i2c_master_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *wr
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_prefixed_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *reg_buffer, size_t reg_size, const uint8_t *write_buffer, size_t write_size, int xfer_timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_dev != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized");
|
||||
ESP_RETURN_ON_FALSE((reg_buffer != NULL) && (reg_size > 0), ESP_ERR_INVALID_ARG, TAG, "i2c register/command buffer or size invalid");
|
||||
ESP_RETURN_ON_FALSE((write_buffer != NULL) && (write_size > 0), ESP_ERR_INVALID_ARG, TAG, "i2c transmit buffer or size invalid");
|
||||
|
||||
i2c_operation_t i2c_ops[] = {
|
||||
{.hw_cmd = I2C_TRANS_START_COMMAND},
|
||||
{.hw_cmd = I2C_TRANS_WRITE_COMMAND(i2c_dev->ack_check_disable ? false : true), .data = (uint8_t *)reg_buffer, .total_bytes = reg_size},
|
||||
{.hw_cmd = I2C_TRANS_WRITE_COMMAND(i2c_dev->ack_check_disable ? false : true), .data = (uint8_t *)write_buffer, .total_bytes = write_size},
|
||||
{.hw_cmd = I2C_TRANS_STOP_COMMAND},
|
||||
};
|
||||
|
||||
if (i2c_dev->master_bus->async_trans == false) {
|
||||
ESP_RETURN_ON_ERROR(s_i2c_synchronous_transaction(i2c_dev, i2c_ops, DIM(i2c_ops), xfer_timeout_ms), TAG, "I2C transaction failed");
|
||||
} else {
|
||||
ESP_RETURN_ON_ERROR(s_i2c_asynchronous_transaction(i2c_dev, i2c_ops, DIM(i2c_ops), xfer_timeout_ms), TAG, "I2C transaction failed");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_dev != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized");
|
||||
|
|
|
@ -123,6 +123,27 @@ esp_err_t i2c_master_bus_rm_device(i2c_master_dev_handle_t handle);
|
|||
*/
|
||||
esp_err_t i2c_master_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, int xfer_timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Perform a write transaction with prefixed register/command bytes on the I2C bus.
|
||||
* The transaction will be undergoing until it finishes or it reaches
|
||||
* the timeout provided.
|
||||
*
|
||||
* @note If a callback was registered with `i2c_master_register_event_callbacks`, the transaction will be asynchronous, and thus, this function will return directly, without blocking.
|
||||
* You will get finish information from callback. Besides, data buffer should always be completely prepared when callback is registered, otherwise, the data will get corrupt.
|
||||
*
|
||||
* @param[in] i2c_dev I2C master device handle that created by `i2c_master_bus_add_device`.
|
||||
* @param[in] reg_buffer Register/command bytes to send on the I2C bus.
|
||||
* @param[in] reg_size Size, in bytes, of the register/command buffer.
|
||||
* @param[in] write_buffer Data bytes to send on the I2C bus.
|
||||
* @param[in] write_size Size, in bytes, of the write buffer.
|
||||
* @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever.
|
||||
* @return
|
||||
* - ESP_OK: I2C master transmit success
|
||||
* - ESP_ERR_INVALID_ARG: I2C master transmit parameter invalid.
|
||||
* - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash.
|
||||
*/
|
||||
esp_err_t i2c_master_prefixed_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *reg_buffer, size_t reg_size, const uint8_t *write_buffer, size_t write_size, int xfer_timeout_ms);
|
||||
|
||||
/**
|
||||
* @brief Perform a write-read transaction on the I2C bus.
|
||||
* The transaction will be undergoing until it finishes or it reaches
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#define I2C_EEPROM_MAX_TRANS_UNIT (48)
|
||||
// Different EEPROM device might share one I2C bus
|
||||
|
||||
static const char TAG[] = "i2c-eeprom";
|
||||
|
@ -25,8 +24,9 @@ esp_err_t i2c_eeprom_init(i2c_master_bus_handle_t bus_handle, const i2c_eeprom_c
|
|||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2c_eeprom_handle_t out_handle;
|
||||
out_handle = (i2c_eeprom_handle_t)calloc(1, sizeof(i2c_eeprom_handle_t));
|
||||
out_handle = (i2c_eeprom_handle_t)calloc(1, sizeof(i2c_eeprom_t));
|
||||
ESP_GOTO_ON_FALSE(out_handle, ESP_ERR_NO_MEM, err, TAG, "no memory for i2c eeprom device");
|
||||
ESP_GOTO_ON_FALSE(eeprom_config->addr_wordlen <= 4, ESP_ERR_NO_MEM, err, TAG, "max possible addr_wordlen is 4");
|
||||
|
||||
i2c_device_config_t i2c_dev_conf = {
|
||||
.scl_speed_hz = eeprom_config->eeprom_device.scl_speed_hz,
|
||||
|
@ -37,9 +37,6 @@ esp_err_t i2c_eeprom_init(i2c_master_bus_handle_t bus_handle, const i2c_eeprom_c
|
|||
ESP_GOTO_ON_ERROR(i2c_master_bus_add_device(bus_handle, &i2c_dev_conf, &out_handle->i2c_dev), err, TAG, "i2c new bus failed");
|
||||
}
|
||||
|
||||
out_handle->buffer = (uint8_t*)calloc(1, eeprom_config->addr_wordlen + I2C_EEPROM_MAX_TRANS_UNIT);
|
||||
ESP_GOTO_ON_FALSE(out_handle->buffer, ESP_ERR_NO_MEM, err, TAG, "no memory for i2c eeprom device buffer");
|
||||
|
||||
out_handle->addr_wordlen = eeprom_config->addr_wordlen;
|
||||
out_handle->write_time_ms = eeprom_config->write_time_ms;
|
||||
*eeprom_handle = out_handle;
|
||||
|
@ -58,21 +55,20 @@ esp_err_t i2c_eeprom_write(i2c_eeprom_handle_t eeprom_handle, uint32_t address,
|
|||
{
|
||||
ESP_RETURN_ON_FALSE(eeprom_handle, ESP_ERR_NO_MEM, TAG, "no mem for buffer");
|
||||
for (int i = 0; i < eeprom_handle->addr_wordlen; i++) {
|
||||
eeprom_handle->buffer[i] = (address & (0xff << ((eeprom_handle->addr_wordlen - 1 - i) * 8))) >> ((eeprom_handle->addr_wordlen - 1 - i) * 8);
|
||||
eeprom_handle->addr_buffer[i] = (address & (0xff << ((eeprom_handle->addr_wordlen - 1 - i) * 8))) >> ((eeprom_handle->addr_wordlen - 1 - i) * 8);
|
||||
}
|
||||
memcpy(eeprom_handle->buffer + eeprom_handle->addr_wordlen, data, size);
|
||||
|
||||
return i2c_master_transmit(eeprom_handle->i2c_dev, eeprom_handle->buffer, eeprom_handle->addr_wordlen + size, -1);
|
||||
return i2c_master_prefixed_transmit(eeprom_handle->i2c_dev, eeprom_handle->addr_buffer, eeprom_handle->addr_wordlen, data, size, -1);
|
||||
}
|
||||
|
||||
esp_err_t i2c_eeprom_read(i2c_eeprom_handle_t eeprom_handle, uint32_t address, uint8_t *data, uint32_t size)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(eeprom_handle, ESP_ERR_NO_MEM, TAG, "no mem for buffer");
|
||||
ESP_RETURN_ON_FALSE(eeprom_handle, ESP_ERR_NO_MEM, TAG, "no mem for address buffer");
|
||||
for (int i = 0; i < eeprom_handle->addr_wordlen; i++) {
|
||||
eeprom_handle->buffer[i] = (address & (0xff << ((eeprom_handle->addr_wordlen - 1 - i) * 8))) >> ((eeprom_handle->addr_wordlen - 1 - i) * 8);
|
||||
eeprom_handle->addr_buffer[i] = (address & (0xff << ((eeprom_handle->addr_wordlen - 1 - i) * 8))) >> ((eeprom_handle->addr_wordlen - 1 - i) * 8);
|
||||
}
|
||||
|
||||
return i2c_master_transmit_receive(eeprom_handle->i2c_dev, eeprom_handle->buffer, eeprom_handle->addr_wordlen, data, size, -1);
|
||||
return i2c_master_transmit_receive(eeprom_handle->i2c_dev, eeprom_handle->addr_buffer, eeprom_handle->addr_wordlen, data, size, -1);
|
||||
}
|
||||
|
||||
void i2c_eeprom_wait_idle(i2c_eeprom_handle_t eeprom_handle)
|
||||
|
|
|
@ -20,7 +20,7 @@ typedef struct {
|
|||
struct i2c_eeprom_t {
|
||||
i2c_master_dev_handle_t i2c_dev; /*!< I2C device handle */
|
||||
uint8_t addr_wordlen; /*!< block address wordlen */
|
||||
uint8_t *buffer; /*!< I2C transaction buffer */
|
||||
uint8_t addr_buffer[4]; /*!< I2C transaction address buffer */
|
||||
uint8_t write_time_ms; /*!< I2C eeprom write time(ms)*/
|
||||
};
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue