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