drivers: eeprom: add driver for NXP LPC11U6X
This patch adds adds an EEPROM driver supporting the on-chip EEPROM found on NXP LPC11U6X MCUs. Note that this driver is only a wrapper relying entirely on the IAP (In-Application Programming) EEPROM commands. Signed-off-by: Simon Guinot <simon.guinot@seagate.com>
This commit is contained in:
parent
75a2f3e484
commit
319d9d94a8
4 changed files with 132 additions and 0 deletions
|
@ -6,5 +6,6 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE eeprom_handlers.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_EEPROM_SHELL eeprom_shell.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_AT2X eeprom_at2x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_LPC11U6X eeprom_lpc11u6x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_STM32 eeprom_stm32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_EEPROM_SIMULATOR eeprom_simulator.c)
|
||||
|
|
|
@ -49,6 +49,7 @@ config EEPROM_AT25
|
|||
help
|
||||
Enable support for Atmel AT25 (and compatible) SPI EEPROMs.
|
||||
|
||||
source "drivers/eeprom/Kconfig.lpc11u6x"
|
||||
source "drivers/eeprom/Kconfig.stm32"
|
||||
|
||||
config EEPROM_SIMULATOR
|
||||
|
|
9
drivers/eeprom/Kconfig.lpc11u6x
Normal file
9
drivers/eeprom/Kconfig.lpc11u6x
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2020 Seagate Technology LLC
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config EEPROM_LPC11U6X
|
||||
bool "LPC11U6x EEPROM driver"
|
||||
depends on SOC_SERIES_LPC11U6X
|
||||
default y
|
||||
help
|
||||
Enable support for the on-chip EEPROM found on NXP LPC11U6x MCUs.
|
121
drivers/eeprom/eeprom_lpc11u6x.c
Normal file
121
drivers/eeprom/eeprom_lpc11u6x.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* 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)
|
||||
* EEPROM funcions.
|
||||
*/
|
||||
|
||||
#include <drivers/eeprom.h>
|
||||
#include <iap.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(eeprom_lpc11u6x);
|
||||
|
||||
struct eeprom_lpc11u6x_config {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static int eeprom_lpc11u6x_read(struct device *dev,
|
||||
off_t offset, void *data, size_t len)
|
||||
{
|
||||
const struct eeprom_lpc11u6x_config *config = dev->config_info;
|
||||
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;
|
||||
}
|
||||
|
||||
static int eeprom_lpc11u6x_write(struct device *dev,
|
||||
off_t offset, const void *data, size_t len)
|
||||
{
|
||||
const struct eeprom_lpc11u6x_config *config = dev->config_info;
|
||||
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;
|
||||
}
|
||||
|
||||
static size_t eeprom_lpc11u6x_size(struct device *dev)
|
||||
{
|
||||
const struct eeprom_lpc11u6x_config *config = dev->config_info;
|
||||
|
||||
return config->size;
|
||||
}
|
||||
|
||||
static int eeprom_lpc11u6x_init(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(eeprom_lpc11u6x, DT_INST_LABEL(0),
|
||||
&eeprom_lpc11u6x_init, NULL,
|
||||
&eeprom_config, POST_KERNEL,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &eeprom_lpc11u6x_api);
|
Loading…
Add table
Add a link
Reference in a new issue