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 <tykwon@m2i.co.kr>
This commit is contained in:
parent
a6f5c1bbf6
commit
69924b19c8
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -54,4 +54,6 @@ config EEPROM_AT25
|
|||
help
|
||||
Enable support for Atmel AT25 (and compatible) SPI EEPROMs.
|
||||
|
||||
source "drivers/eeprom/Kconfig.stm32"
|
||||
|
||||
endif # EEPROM
|
||||
|
|
10
drivers/eeprom/Kconfig.stm32
Normal file
10
drivers/eeprom/Kconfig.stm32
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2019 Kwon Tae-young <tykwon@m2i.co.kr>
|
||||
# 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.
|
125
drivers/eeprom/eeprom_stm32.c
Normal file
125
drivers/eeprom/eeprom_stm32.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Kwon Tae-young <tykwon@m2i.co.kr>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/eeprom.h>
|
||||
#include <soc.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
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);
|
|
@ -115,4 +115,11 @@ config DMA_STM32
|
|||
|
||||
endif # DMA
|
||||
|
||||
if EEPROM
|
||||
|
||||
config EEPROM_STM32
|
||||
default y
|
||||
|
||||
endif # EEPROM
|
||||
|
||||
endif # SOC_FAMILY_STM32
|
||||
|
|
Loading…
Reference in a new issue