diff --git a/drivers/i2c/target/eeprom_target.c b/drivers/i2c/target/eeprom_target.c index 69ae35cfcd8d0..114623517ce04 100644 --- a/drivers/i2c/target/eeprom_target.c +++ b/drivers/i2c/target/eeprom_target.c @@ -18,12 +18,15 @@ LOG_MODULE_REGISTER(i2c_target); struct i2c_eeprom_target_data { + const struct device *dev; struct i2c_target_config config; uint32_t buffer_size; uint8_t *buffer; uint32_t buffer_idx; uint32_t idx_write_cnt; uint8_t address_width; + eeprom_target_changed_handler_t changed_handler; + bool changed; }; struct i2c_eeprom_target_config { @@ -32,6 +35,28 @@ struct i2c_eeprom_target_config { uint8_t *buffer; }; +void eeprom_target_set_changed_callback(const struct device *dev, + eeprom_target_changed_handler_t handler) +{ + struct i2c_eeprom_target_data *data = dev->data; + + data->changed_handler = handler; +} + +unsigned int eeprom_target_get_size(const struct device *dev) +{ + struct i2c_eeprom_target_data *data = dev->data; + + return data->buffer_size; +} + +uint8_t *eeprom_target_get_data(const struct device *dev) +{ + struct i2c_eeprom_target_data *data = dev->data; + + return data->buffer; +} + int eeprom_target_program(const struct device *dev, const uint8_t *eeprom_data, unsigned int length) { @@ -131,6 +156,7 @@ static int eeprom_target_write_received(struct i2c_target_config *config, data->idx_write_cnt++; } else { data->buffer[data->buffer_idx++] = val; + data->changed = true; } data->buffer_idx = data->buffer_idx % data->buffer_size; @@ -169,6 +195,11 @@ static int eeprom_target_stop(struct i2c_target_config *config) data->idx_write_cnt = 0; + if (data->changed && data->changed_handler) { + data->changed_handler(data->dev); + } + data->changed = false; + return 0; } @@ -191,6 +222,7 @@ static void eeprom_target_buf_write_received(struct i2c_target_config *config, if (len > 0) { memcpy(&data->buffer[data->buffer_idx], ptr, len); + data->changed = true; } } @@ -251,6 +283,7 @@ static int i2c_eeprom_target_init(const struct device *dev) return -ENODEV; } + data->dev = dev; data->buffer_size = cfg->buffer_size; data->buffer = cfg->buffer; data->config.address = cfg->bus.addr; diff --git a/include/zephyr/drivers/i2c/target/eeprom.h b/include/zephyr/drivers/i2c/target/eeprom.h index 3146c8b29b942..185718e046cc4 100644 --- a/include/zephyr/drivers/i2c/target/eeprom.h +++ b/include/zephyr/drivers/i2c/target/eeprom.h @@ -21,6 +21,41 @@ * @{ */ +/** + * @typedef eeprom_target_changed_handler_t + * @brief Define the application callback handler function signature + * + * @param dev Pointer to the device structure for the driver instance. + */ +typedef void (*eeprom_target_changed_handler_t)(const struct device *dev); + +/** + * @brief Set the EEPROM changed callback handler + * + * @param dev Pointer to the device structure for the driver instance. + * @param handler Handler to call on EEPROM changes + */ +void eeprom_target_set_changed_callback(const struct device *dev, + eeprom_target_changed_handler_t handler); + +/** + * @brief Get size of the virtual EEPROM + * + * @param dev Pointer to the device structure for the driver instance. + * + * @retval Size of EEPROM in bytes + */ +unsigned int eeprom_target_get_size(const struct device *dev); + +/** + * @brief Get a pointer to the data of the virtual EEPROM + * + * @param dev Pointer to the device structure for the driver instance. + * + * @retval Pointer to EEPROM data + */ +uint8_t *eeprom_target_get_data(const struct device *dev); + /** * @brief Program memory of the virtual EEPROM * diff --git a/samples/drivers/i2c/target_eeprom/src/main.c b/samples/drivers/i2c/target_eeprom/src/main.c index d1c42f9a40164..75c424bb9f9f9 100644 --- a/samples/drivers/i2c/target_eeprom/src/main.c +++ b/samples/drivers/i2c/target_eeprom/src/main.c @@ -11,6 +11,23 @@ static const struct device *eeprom = DEVICE_DT_GET(DT_NODELABEL(eeprom0)); +static void on_changed(const struct device *dev) +{ + unsigned int size, i; + uint8_t *data; + + size = eeprom_target_get_size(dev); + data = eeprom_target_get_data(dev); + + printk("Eeprom changed, now contains:\n"); + for (i = 0; i < size; i++) { + char sep = i % 16 == 15 ? '\n' : ' '; + + printk("%02x%c", data[i], sep); + } + printk("\n"); +} + int main(void) { printk("i2c target sample\n"); @@ -20,6 +37,8 @@ int main(void) return 0; } + eeprom_target_set_changed_callback(eeprom, on_changed); + if (i2c_target_driver_register(eeprom) < 0) { printk("Failed to register i2c target driver\n"); return 0; @@ -27,14 +46,5 @@ int main(void) printk("i2c target driver registered\n"); - k_msleep(1000); - - if (i2c_target_driver_unregister(eeprom) < 0) { - printk("Failed to unregister i2c target driver\n"); - return 0; - } - - printk("i2c target driver unregistered\n"); - return 0; }