2020-05-14 18:22:06 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020 Seagate Technology LLC
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define DT_DRV_COMPAT nxp_lpc11u6x_eeprom
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* @brief EEPROM driver for NXP LPC11U6X MCUs
|
|
|
|
*
|
|
|
|
* This driver supports the on-chip EEPROM found on NXP LPC11U6x MCUs.
|
|
|
|
*
|
|
|
|
* @note This driver is only a wrapper for the IAP (In-Application Programming)
|
2022-02-24 20:00:55 +08:00
|
|
|
* EEPROM functions.
|
2020-05-14 18:22:06 +08:00
|
|
|
*/
|
|
|
|
|
2022-10-14 14:46:29 +08:00
|
|
|
#include <zephyr/kernel.h>
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/drivers/eeprom.h>
|
2020-05-14 18:22:06 +08:00
|
|
|
#include <iap.h>
|
|
|
|
|
|
|
|
#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
|
2022-05-06 16:25:46 +08:00
|
|
|
#include <zephyr/logging/log.h>
|
2020-05-14 18:22:06 +08:00
|
|
|
LOG_MODULE_REGISTER(eeprom_lpc11u6x);
|
|
|
|
|
|
|
|
struct eeprom_lpc11u6x_config {
|
|
|
|
size_t size;
|
|
|
|
};
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int eeprom_lpc11u6x_read(const struct device *dev,
|
2020-05-14 18:22:06 +08:00
|
|
|
off_t offset, void *data, size_t len)
|
|
|
|
{
|
2020-05-29 02:44:16 +08:00
|
|
|
const struct eeprom_lpc11u6x_config *config = dev->config;
|
2020-05-14 18:22:06 +08:00
|
|
|
uint32_t cmd[5];
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!len) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((offset + len) > config->size) {
|
|
|
|
LOG_WRN("attempt to read past device boundary");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd[0] = IAP_CMD_EEPROM_READ;
|
|
|
|
cmd[1] = offset;
|
|
|
|
cmd[2] = (uint32_t) data;
|
|
|
|
cmd[3] = len;
|
|
|
|
cmd[4] = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000;
|
|
|
|
|
|
|
|
ret = iap_cmd(cmd);
|
|
|
|
|
|
|
|
if (ret != IAP_STATUS_CMD_SUCCESS) {
|
|
|
|
LOG_ERR("failed to read EEPROM (offset=%08x len=%d err=%d)",
|
|
|
|
(unsigned int) offset, len, ret);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static int eeprom_lpc11u6x_write(const struct device *dev,
|
2020-05-14 18:22:06 +08:00
|
|
|
off_t offset, const void *data, size_t len)
|
|
|
|
{
|
2020-05-29 02:44:16 +08:00
|
|
|
const struct eeprom_lpc11u6x_config *config = dev->config;
|
2020-05-14 18:22:06 +08:00
|
|
|
uint32_t cmd[5];
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!len) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((offset + len) > config->size) {
|
|
|
|
LOG_WRN("attempt to write past device boundary");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd[0] = IAP_CMD_EEPROM_WRITE;
|
|
|
|
cmd[1] = offset;
|
|
|
|
cmd[2] = (uint32_t) data;
|
|
|
|
cmd[3] = len;
|
|
|
|
cmd[4] = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000;
|
|
|
|
|
|
|
|
ret = iap_cmd(cmd);
|
|
|
|
|
|
|
|
if (ret != IAP_STATUS_CMD_SUCCESS) {
|
|
|
|
LOG_ERR("failed to write EEPROM (offset=%08x len=%d err=%d)",
|
|
|
|
(unsigned int) offset, len, ret);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-05-01 02:33:38 +08:00
|
|
|
static size_t eeprom_lpc11u6x_size(const struct device *dev)
|
2020-05-14 18:22:06 +08:00
|
|
|
{
|
2020-05-29 02:44:16 +08:00
|
|
|
const struct eeprom_lpc11u6x_config *config = dev->config;
|
2020-05-14 18:22:06 +08:00
|
|
|
|
|
|
|
return config->size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct eeprom_driver_api eeprom_lpc11u6x_api = {
|
|
|
|
.read = eeprom_lpc11u6x_read,
|
|
|
|
.write = eeprom_lpc11u6x_write,
|
|
|
|
.size = eeprom_lpc11u6x_size,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct eeprom_lpc11u6x_config eeprom_config = {
|
|
|
|
.size = DT_INST_PROP(0, size),
|
|
|
|
};
|
|
|
|
|
2023-04-18 18:25:15 +08:00
|
|
|
DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &eeprom_config, POST_KERNEL,
|
|
|
|
CONFIG_EEPROM_INIT_PRIORITY, &eeprom_lpc11u6x_api);
|