1 /*
2 * Copyright (c) 2023 Arm Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef __DRIVER_FLASH_SST26VF064B_H__
18 #define __DRIVER_FLASH_SST26VF064B_H__
19
20 #include "cmsis_compiler.h"
21 #include "Driver_Flash_Common.h"
22 #include "spi_sst26vf064b_flash_lib.h"
23
24 /*
25 * ARM FLASH device structure
26 */
27 struct arm_flash_sst26vf064b_flash_dev_t {
28 struct spi_sst26vf064b_dev_t* dev; /*!< FLASH memory device structure */
29 ARM_FLASH_INFO* data; /*!< FLASH data */
30 int8_t (*setup_qspi)(struct arm_flash_sst26vf064b_flash_dev_t* dev);
31 /*!< Setup flash for QSPI access */
32 int8_t (*release_qspi)(struct arm_flash_sst26vf064b_flash_dev_t* dev);
33 /*!< Setup flash for XIP access */
34 const uint32_t memory_base_s; /*!< FLASH memory base address in
35 * XIP mode, secure alias */
36 const uint32_t memory_base_ns; /*!< FLASH memory base address in
37 * XIP mode, non-secure alias */
38 };
39 /* Driver Capabilities */
40 static const ARM_FLASH_CAPABILITIES SST26VF064BDriverCapabilities = {
41 0, /* event_ready */
42 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
43 1, /* erase_chip */
44 0, /* reserved */
45 };
46
47 static ARM_FLASH_INFO SST26VF064B_DEV_DATA = {
48 .sector_info = NULL, /* Uniform sector layout */
49 .sector_count = SST26VF064B_FLASH_TOTAL_SIZE /
50 SST26VF064B_FLASH_SECTOR_SIZE,
51 .sector_size = SST26VF064B_FLASH_SECTOR_SIZE,
52 .page_size = SST26VF064B_FLASH_PAGE_SIZE,
53 .program_unit = SST26VF064B_FLASH_PROGRAM_UNIT,
54 .erased_value = ARM_FLASH_DRV_ERASE_VALUE
55 };
56
SST26VF064B_Driver_GetCapabilities(void)57 __STATIC_INLINE ARM_FLASH_CAPABILITIES SST26VF064B_Driver_GetCapabilities(void)
58 {
59 return SST26VF064BDriverCapabilities;
60 }
61
62 #define SETUP_QSPI(flash_dev) \
63 do { \
64 if(flash_dev.setup_qspi != NULL) { \
65 if(flash_dev.setup_qspi(&flash_dev) != 0) { \
66 ret = SST26VF064B_ERR_QSPI_SETUP; \
67 goto cleanup; \
68 } \
69 } \
70 } while(0)
71
72 #define RELEASE_QSPI(flash_dev) \
73 do { \
74 if(flash_dev.release_qspi != NULL) { \
75 if(flash_dev.release_qspi(&flash_dev) != 0) { \
76 /* Should never get there */ \
77 __ASM("B ."); \
78 } \
79 } \
80 } while(0)
81
82 /*
83 * \brief Macro for SST26VF064B Flash Driver
84 *
85 * \param[in] FLASH_DEV Native driver device
86 * \ref arm_flash_sst26vf064b_flash_dev_t
87 * \param[out] FLASH_DRIVER_NAME Resulting Driver name
88 */
89 #define ARM_FLASH_SST26VF064B(FLASH_DEV, FLASH_DRIVER_NAME) \
90 static int32_t FLASH_DRIVER_NAME##_Initialize( \
91 ARM_Flash_SignalEvent_t cb_event) \
92 { \
93 ARG_UNUSED(cb_event); \
94 enum sst26vf064b_error_t ret = ARM_DRIVER_OK; \
95 struct spi_sst26vf064b_dev_t* dev = FLASH_DEV.dev; \
96 ARM_FLASH_INFO* data = FLASH_DEV.data; \
97 \
98 dev->total_sector_cnt = data->sector_count; \
99 dev->page_size = data->page_size; \
100 dev->sector_size = data->sector_size; \
101 dev->program_unit = data->program_unit; \
102 \
103 SETUP_QSPI(FLASH_DEV); \
104 ret = spi_sst26vf064b_initialize(FLASH_DEV.dev); \
105 if (ret != SST26VF064B_ERR_NONE) { \
106 SPI_FLASH_LOG_MSG("%s: Initialization failed.\n\r", __func__); \
107 goto cleanup; \
108 } \
109 \
110 cleanup: \
111 RELEASE_QSPI(FLASH_DEV); \
112 if (ret != SST26VF064B_ERR_NONE) { \
113 return ARM_DRIVER_ERROR; \
114 } \
115 return ARM_DRIVER_OK; \
116 } \
117 \
118 static int32_t FLASH_DRIVER_NAME##_ReadData(uint32_t addr, \
119 void *data, \
120 uint32_t cnt) \
121 { \
122 enum sst26vf064b_error_t ret; \
123 \
124 if (SST26VF064BDriverCapabilities.data_width > 2 || \
125 SST26VF064BDriverCapabilities.data_width < 0) \
126 { \
127 SPI_FLASH_LOG_MSG("%s: Incorrect data width selected: addr=0x%x\n\r", \
128 __func__, addr); \
129 ret = SST26VF064B_ERR_WRONG_ARGUMENT; \
130 goto cleanup; \
131 } \
132 \
133 cnt *= data_width_byte[SST26VF064BDriverCapabilities.data_width]; \
134 \
135 SETUP_QSPI(FLASH_DEV); \
136 ret = spi_sst26vf064b_read(FLASH_DEV.dev, addr, (uint8_t*) data, cnt); \
137 if (ret != SST26VF064B_ERR_NONE) { \
138 SPI_FLASH_LOG_MSG("%s: read failed: addr=0x%x, cnt=%u\n\r", \
139 __func__, addr, cnt); \
140 goto cleanup; \
141 } \
142 \
143 cnt /= data_width_byte[SST26VF064BDriverCapabilities.data_width]; \
144 \
145 cleanup: \
146 RELEASE_QSPI(FLASH_DEV); \
147 if (ret != SST26VF064B_ERR_NONE) { \
148 return ARM_DRIVER_ERROR; \
149 } \
150 return cnt; \
151 } \
152 \
153 static int32_t FLASH_DRIVER_NAME##_ProgramData(uint32_t addr, \
154 const void *data, \
155 uint32_t cnt) \
156 { \
157 enum sst26vf064b_error_t ret; \
158 \
159 if (SST26VF064BDriverCapabilities.data_width > 2 || \
160 SST26VF064BDriverCapabilities.data_width < 0) \
161 { \
162 SPI_FLASH_LOG_MSG("%s: Incorrect data width selected: addr=0x%x\n\r", \
163 __func__, addr); \
164 ret = SST26VF064B_ERR_WRONG_ARGUMENT; \
165 goto cleanup; \
166 } \
167 \
168 cnt *= data_width_byte[SST26VF064BDriverCapabilities.data_width]; \
169 \
170 SETUP_QSPI(FLASH_DEV); \
171 ret = spi_sst26vf064b_program(FLASH_DEV.dev, addr, (uint8_t*) data, cnt); \
172 if (ret != SST26VF064B_ERR_NONE) { \
173 SPI_FLASH_LOG_MSG("%s: program failed: addr=0x%x, cnt=%u\n\r", \
174 __func__, addr, cnt); \
175 goto cleanup; \
176 } \
177 \
178 cnt /= data_width_byte[SST26VF064BDriverCapabilities.data_width]; \
179 \
180 cleanup: \
181 RELEASE_QSPI(FLASH_DEV); \
182 if (ret != SST26VF064B_ERR_NONE) { \
183 return ARM_DRIVER_ERROR; \
184 } \
185 return cnt; \
186 } \
187 \
188 static int32_t FLASH_DRIVER_NAME##_EraseSector(uint32_t addr) \
189 { \
190 enum sst26vf064b_error_t ret; \
191 \
192 SETUP_QSPI(FLASH_DEV); \
193 ret = spi_sst26vf064b_erase_sector(FLASH_DEV.dev, addr); \
194 if (ret != SST26VF064B_ERR_NONE) { \
195 SPI_FLASH_LOG_MSG("%s: erase failed: addr=0x%x\n\r", __func__, addr); \
196 goto cleanup; \
197 } \
198 \
199 cleanup: \
200 RELEASE_QSPI(FLASH_DEV); \
201 if (ret != SST26VF064B_ERR_NONE) { \
202 return ARM_DRIVER_ERROR; \
203 } \
204 return ARM_DRIVER_OK; \
205 } \
206 \
207 static int32_t FLASH_DRIVER_NAME##_EraseChip(void) \
208 { \
209 enum sst26vf064b_error_t ret; \
210 \
211 SETUP_QSPI(FLASH_DEV); \
212 ret = spi_sst26vf064b_erase_chip(FLASH_DEV.dev); \
213 if (ret != SST26VF064B_ERR_NONE) { \
214 SPI_FLASH_LOG_MSG("%s: erase chip failed\n\r", __func__); \
215 goto cleanup; \
216 } \
217 \
218 cleanup: \
219 RELEASE_QSPI(FLASH_DEV); \
220 if (ret != SST26VF064B_ERR_NONE) { \
221 return ARM_DRIVER_ERROR; \
222 } \
223 return ARM_DRIVER_OK; \
224 } \
225 \
226 static ARM_FLASH_INFO * FLASH_DRIVER_NAME##_GetInfo(void) \
227 { \
228 return FLASH_DEV.data; \
229 } \
230 \
231 ARM_DRIVER_FLASH FLASH_DRIVER_NAME = { \
232 ARM_Flash_GetVersion, \
233 SST26VF064B_Driver_GetCapabilities, \
234 FLASH_DRIVER_NAME##_Initialize, \
235 ARM_Flash_Uninitialize, \
236 ARM_Flash_PowerControl, \
237 FLASH_DRIVER_NAME##_ReadData, \
238 FLASH_DRIVER_NAME##_ProgramData, \
239 FLASH_DRIVER_NAME##_EraseSector, \
240 FLASH_DRIVER_NAME##_EraseChip, \
241 ARM_Flash_GetStatus, \
242 FLASH_DRIVER_NAME##_GetInfo \
243 }
244
245 #endif /* __DRIVER_FLASH_SST26VF064B_H__ */
246