From 69924b19c8a684e3824a870f4f2440c6f472cd24 Mon Sep 17 00:00:00 2001 From: Kwon Tae-young Date: Tue, 10 Dec 2019 11:44:44 +0900 Subject: [PATCH] drivers: eeprom: add driver support for EEPROM of STM32L1 Could not find a supported LL with EEPROM. So I used HAL. Tested with: 96b_wistrio Signed-off-by: Kwon Tae-young --- CODEOWNERS | 1 + drivers/eeprom/CMakeLists.txt | 1 + drivers/eeprom/Kconfig | 2 + drivers/eeprom/Kconfig.stm32 | 10 ++ drivers/eeprom/eeprom_stm32.c | 125 ++++++++++++++++++ .../st_stm32/common/Kconfig.defconfig.series | 7 + 6 files changed, 146 insertions(+) create mode 100644 drivers/eeprom/Kconfig.stm32 create mode 100644 drivers/eeprom/eeprom_stm32.c diff --git a/CODEOWNERS b/CODEOWNERS index ffd36477f0..86e27da92d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -121,6 +121,7 @@ /drivers/dma/*sam0* @Sizurka /drivers/dma/dma_stm32* @cybertale /drivers/eeprom/ @henrikbrixandersen +/drivers/eeprom/eeprom_stm32.c @KwonTae-young /drivers/entropy/*rv32m1* @MaureenHelm /drivers/espi/ @albertofloyd @franciscomunoz @scottwcpg /drivers/ps2/ @albertofloyd @franciscomunoz @scottwcpg diff --git a/drivers/eeprom/CMakeLists.txt b/drivers/eeprom/CMakeLists.txt index 53f2abafa2..90e683a891 100644 --- a/drivers/eeprom/CMakeLists.txt +++ b/drivers/eeprom/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_sources_ifdef(CONFIG_EEPROM_SHELL eeprom_shell.c) zephyr_library_sources_ifdef(CONFIG_EEPROM_NATIVE_POSIX eeprom_native_posix.c) zephyr_library_sources_ifdef(CONFIG_EEPROM_AT2X eeprom_at2x.c) +zephyr_library_sources_ifdef(CONFIG_EEPROM_STM32 eeprom_stm32.c) diff --git a/drivers/eeprom/Kconfig b/drivers/eeprom/Kconfig index 325be9ca62..4c862df209 100644 --- a/drivers/eeprom/Kconfig +++ b/drivers/eeprom/Kconfig @@ -54,4 +54,6 @@ config EEPROM_AT25 help Enable support for Atmel AT25 (and compatible) SPI EEPROMs. +source "drivers/eeprom/Kconfig.stm32" + endif # EEPROM diff --git a/drivers/eeprom/Kconfig.stm32 b/drivers/eeprom/Kconfig.stm32 new file mode 100644 index 0000000000..a9b7cd9caf --- /dev/null +++ b/drivers/eeprom/Kconfig.stm32 @@ -0,0 +1,10 @@ +# Copyright (c) 2019 Kwon Tae-young +# SPDX-License-Identifier: Apache-2.0 + +config EEPROM_STM32 + bool "STM32 EEPROM driver" + depends on SOC_SERIES_STM32L1X + select USE_STM32_HAL_FLASH + select USE_STM32_HAL_FLASH_EX + help + Enable EEPROM support on the STM32 L1 family of processors. diff --git a/drivers/eeprom/eeprom_stm32.c b/drivers/eeprom/eeprom_stm32.c new file mode 100644 index 0000000000..85ea517b8d --- /dev/null +++ b/drivers/eeprom/eeprom_stm32.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019 Kwon Tae-young + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL +#include +LOG_MODULE_REGISTER(eeprom_stm32); + +K_MUTEX_DEFINE(lock); + +struct eeprom_stm32_config { + u32_t addr; + size_t size; +}; + +static int eeprom_stm32_read(struct device *dev, off_t offset, void *buf, + size_t len) +{ + const struct eeprom_stm32_config *config = dev->config->config_info; + u8_t *pbuf = buf; + + if (!len) { + return 0; + } + + if ((offset + len) > config->size) { + LOG_WRN("attempt to read past device boundary"); + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + + while (len) { + *pbuf = *(__IO u8_t*)(config->addr + offset); + + pbuf++; + offset++; + len--; + } + + k_mutex_unlock(&lock); + + return 0; +} + +static int eeprom_stm32_write(struct device *dev, off_t offset, + const void *buf, size_t len) +{ + const struct eeprom_stm32_config *config = dev->config->config_info; + const u8_t *pbuf = buf; + HAL_StatusTypeDef ret = HAL_OK; + + if (!len) { + return 0; + } + + if ((offset + len) > config->size) { + LOG_WRN("attempt to write past device boundary"); + return -EINVAL; + } + + k_mutex_lock(&lock, K_FOREVER); + + HAL_FLASHEx_DATAEEPROM_Unlock(); + + while (len) { + ret = HAL_FLASHEx_DATAEEPROM_Program( + FLASH_TYPEPROGRAMDATA_BYTE, + config->addr + offset, *pbuf); + if (ret) { + LOG_ERR("failed to write to EEPROM (err %d)", ret); + HAL_FLASHEx_DATAEEPROM_Lock(); + k_mutex_unlock(&lock); + return ret; + } + + pbuf++; + offset++; + len--; + } + + ret = HAL_FLASHEx_DATAEEPROM_Lock(); + if (ret) { + LOG_ERR("failed to lock EEPROM (err %d)", ret); + k_mutex_unlock(&lock); + return ret; + } + + k_mutex_unlock(&lock); + + return ret; +} + +static size_t eeprom_stm32_size(struct device *dev) +{ + const struct eeprom_stm32_config *config = dev->config->config_info; + + return config->size; +} + +static int eeprom_stm32_init(struct device *dev) +{ + return 0; +} + +static const struct eeprom_driver_api eeprom_stm32_api = { + .read = eeprom_stm32_read, + .write = eeprom_stm32_write, + .size = eeprom_stm32_size, +}; + +static const struct eeprom_stm32_config eeprom_config = { + .addr = DT_INST_0_ST_STM32_EEPROM_BASE_ADDRESS, + .size = DT_INST_0_ST_STM32_EEPROM_SIZE, +}; + +DEVICE_AND_API_INIT(eeprom_stm32, DT_INST_0_ST_STM32_EEPROM_LABEL, + &eeprom_stm32_init, NULL, + &eeprom_config, POST_KERNEL, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &eeprom_stm32_api); diff --git a/soc/arm/st_stm32/common/Kconfig.defconfig.series b/soc/arm/st_stm32/common/Kconfig.defconfig.series index 1116c86d8e..bfa6c0d854 100644 --- a/soc/arm/st_stm32/common/Kconfig.defconfig.series +++ b/soc/arm/st_stm32/common/Kconfig.defconfig.series @@ -115,4 +115,11 @@ config DMA_STM32 endif # DMA +if EEPROM + +config EEPROM_STM32 + default y + +endif # EEPROM + endif # SOC_FAMILY_STM32