1 /*
2 * Copyright (c) 2019 Kwon Tae-young <tykwon@m2i.co.kr>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT st_stm32_eeprom
8
9 #include <zephyr/drivers/eeprom.h>
10 #include <soc.h>
11 #include <zephyr/kernel.h>
12
13 #define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(eeprom_stm32);
16
17 K_MUTEX_DEFINE(lock);
18
19 struct eeprom_stm32_config {
20 uint32_t addr;
21 size_t size;
22 };
23
eeprom_stm32_read(const struct device * dev,off_t offset,void * buf,size_t len)24 static int eeprom_stm32_read(const struct device *dev, off_t offset,
25 void *buf,
26 size_t len)
27 {
28 const struct eeprom_stm32_config *config = dev->config;
29 uint8_t *pbuf = buf;
30
31 if (!len) {
32 return 0;
33 }
34
35 if ((offset + len) > config->size) {
36 LOG_WRN("attempt to read past device boundary");
37 return -EINVAL;
38 }
39
40 k_mutex_lock(&lock, K_FOREVER);
41
42 while (len) {
43 *pbuf = *(__IO uint8_t*)(config->addr + offset);
44
45 pbuf++;
46 offset++;
47 len--;
48 }
49
50 k_mutex_unlock(&lock);
51
52 return 0;
53 }
54
eeprom_stm32_write(const struct device * dev,off_t offset,const void * buf,size_t len)55 static int eeprom_stm32_write(const struct device *dev, off_t offset,
56 const void *buf, size_t len)
57 {
58 const struct eeprom_stm32_config *config = dev->config;
59 const uint8_t *pbuf = buf;
60 HAL_StatusTypeDef ret = HAL_OK;
61
62 if (!len) {
63 return 0;
64 }
65
66 if ((offset + len) > config->size) {
67 LOG_WRN("attempt to write past device boundary");
68 return -EINVAL;
69 }
70
71 k_mutex_lock(&lock, K_FOREVER);
72
73 HAL_FLASHEx_DATAEEPROM_Unlock();
74
75 while (len) {
76 ret = HAL_FLASHEx_DATAEEPROM_Program(
77 FLASH_TYPEPROGRAMDATA_BYTE,
78 config->addr + offset, *pbuf);
79 if (ret) {
80 LOG_ERR("failed to write to EEPROM (err %d)", ret);
81 HAL_FLASHEx_DATAEEPROM_Lock();
82 k_mutex_unlock(&lock);
83 return ret;
84 }
85
86 pbuf++;
87 offset++;
88 len--;
89 }
90
91 ret = HAL_FLASHEx_DATAEEPROM_Lock();
92 if (ret) {
93 LOG_ERR("failed to lock EEPROM (err %d)", ret);
94 k_mutex_unlock(&lock);
95 return ret;
96 }
97
98 k_mutex_unlock(&lock);
99
100 return ret;
101 }
102
eeprom_stm32_size(const struct device * dev)103 static size_t eeprom_stm32_size(const struct device *dev)
104 {
105 const struct eeprom_stm32_config *config = dev->config;
106
107 return config->size;
108 }
109
110 static const struct eeprom_driver_api eeprom_stm32_api = {
111 .read = eeprom_stm32_read,
112 .write = eeprom_stm32_write,
113 .size = eeprom_stm32_size,
114 };
115
116 static const struct eeprom_stm32_config eeprom_config = {
117 .addr = DT_INST_REG_ADDR(0),
118 .size = DT_INST_REG_SIZE(0),
119 };
120
121 DEVICE_DT_INST_DEFINE(0, NULL, NULL, NULL, &eeprom_config, POST_KERNEL,
122 CONFIG_EEPROM_INIT_PRIORITY, &eeprom_stm32_api);
123