1 /*
2 * Copyright (c) 2018-2022 Arm Limited. All rights reserved.
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 #include "Driver_Flash.h"
18 #include "gfc100_eflash_drv.h"
19 #include "RTE_Device.h"
20 #include "device_cfg.h"
21 #include "device_definition.h"
22 #include "system_core_init.h"
23 #include "cmsis_driver_config.h"
24
25 /**
26 * \file Driver_GFC100_EFlash.c
27 *
28 * \brief CMSIS Flash driver for GFC100 flash controller
29 */
30
31 #ifndef ARG_UNUSED
32 #define ARG_UNUSED(arg) (void)arg
33 #endif
34
35 #ifndef ARG_NOT_USED
36 #define ARG_NOT_USED 0U
37 #endif
38
39 /* Driver version */
40 #define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
41
42 const ARM_DRIVER_VERSION GFC100_EFlash_Driver_Version = {
43 ARM_FLASH_API_VERSION, /* Defined in the CMSIS Flash Driver header file */
44 ARM_FLASH_DRV_VERSION
45 };
46
47 /**
48 * Event ready values for ARM_FLASH_CAPABILITIES::event_ready
49 * \ref ARM_FLASH_CAPABILITIES
50 */
51 enum {
52 EVENT_READY_NOT_AVAILABLE = 0u,
53 EVENT_READY_AVAILABLE
54 };
55
56 /**
57 * Data width values for ARM_FLASH_CAPABILITIES::data_width
58 * \ref ARM_FLASH_CAPABILITIES
59 */
60 enum {
61 DATA_WIDTH_8BIT = 0u,
62 DATA_WIDTH_16BIT,
63 DATA_WIDTH_32BIT,
64 DATA_WIDTH_ENUM_SIZE
65 };
66
67 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
68 sizeof(uint8_t),
69 sizeof(uint16_t),
70 sizeof(uint32_t),
71 };
72
73 /**
74 * Erase chip values for ARM_FLASH_CAPABILITIES::erase_chip
75 * \ref ARM_FLASH_CAPABILITIES
76 */
77 enum {
78 CHIP_ERASE_NOT_SUPPORTED = 0u,
79 CHIP_ERASE_SUPPORTED
80 };
81
82 /** Driver Capabilities */
83 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
84 .event_ready = EVENT_READY_NOT_AVAILABLE,
85 .data_width = DATA_WIDTH_32BIT,
86 .erase_chip = CHIP_ERASE_SUPPORTED
87 };
88
89 /**
90 * \brief Flash busy values flash status \ref ARM_FLASH_STATUS
91 */
92 enum {
93 DRIVER_STATUS_IDLE = 0u,
94 DRIVER_STATUS_BUSY
95 };
96
97 /**
98 * \brief Flash error values flash status \ref ARM_FLASH_STATUS
99 */
100 enum {
101 DRIVER_STATUS_NO_ERROR = 0u,
102 DRIVER_STATUS_ERROR
103 };
104
105 /**
106 * \brief Arm Flash device structure.
107 */
108 typedef struct _FLASHx_Resources {
109 struct gfc100_eflash_dev_t* dev; /*!< FLASH memory device structure */
110 ARM_FLASH_INFO *data; /*!< FLASH memory device data */
111 ARM_FLASH_STATUS status;
112 } ARM_FLASHx_Resources;
113
ARM_Flash_GetVersion(void)114 static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
115 {
116 return GFC100_EFlash_Driver_Version;
117 }
118
ARM_Flash_GetCapabilities(void)119 static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
120 {
121 return DriverCapabilities;
122 }
123
ARM_Flashx_Initialize(ARM_FLASHx_Resources * ARM_FLASHx_DEV,ARM_Flash_SignalEvent_t cb_event)124 static int32_t ARM_Flashx_Initialize(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
125 ARM_Flash_SignalEvent_t cb_event)
126 {
127 ARG_UNUSED(cb_event);
128
129 uint32_t page_size = gfc100_get_eflash_page_size(ARM_FLASHx_DEV->dev);
130 uint32_t flash_size = gfc100_get_eflash_size(ARM_FLASHx_DEV->dev);
131
132 /* Validate hardcoded parameters of the flash */
133 if ((ARM_FLASHx_DEV->data->page_size != page_size) ||
134 (ARM_FLASHx_DEV->data->sector_size != page_size) ||
135 (ARM_FLASHx_DEV->data->sector_count != (flash_size / page_size))) {
136 return ARM_DRIVER_ERROR_PARAMETER;
137 }
138
139 gfc100_eflash_init(ARM_FLASHx_DEV->dev, SystemCoreClock);
140
141 return ARM_DRIVER_OK;
142 }
143
ARM_Flashx_Uninitialize(ARM_FLASHx_Resources * ARM_FLASHx_DEV)144 static int32_t ARM_Flashx_Uninitialize(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
145 {
146 ARG_UNUSED(ARM_FLASHx_DEV);
147
148 /* Nothing to do */
149 return ARM_DRIVER_OK;
150 }
151
ARM_Flashx_PowerControl(ARM_FLASHx_Resources * ARM_FLASHx_DEV,ARM_POWER_STATE state)152 static int32_t ARM_Flashx_PowerControl(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
153 ARM_POWER_STATE state)
154 {
155 ARG_UNUSED(ARM_FLASHx_DEV);
156
157 switch(state) {
158 case ARM_POWER_FULL:
159 /* Nothing to do */
160 return ARM_DRIVER_OK;
161 case ARM_POWER_OFF:
162 case ARM_POWER_LOW:
163 return ARM_DRIVER_ERROR_UNSUPPORTED;
164 default:
165 return ARM_DRIVER_ERROR_PARAMETER;
166 }
167 }
168
ARM_Flashx_ReadData(ARM_FLASHx_Resources * ARM_FLASHx_DEV,uint32_t addr,void * data,uint32_t cnt)169 static int32_t ARM_Flashx_ReadData(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
170 uint32_t addr, void *data, uint32_t cnt)
171 {
172 enum gfc100_error_t err = GFC100_ERROR_NONE;
173 uint32_t flash_size = gfc100_get_eflash_size(ARM_FLASHx_DEV->dev);
174
175 /* Conversion between data items and bytes */
176 cnt *= data_width_byte[DriverCapabilities.data_width];
177
178 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
179
180 /* Check if range is valid */
181 if ((addr + cnt) > flash_size) {
182 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
183 return ARM_DRIVER_ERROR_PARAMETER;
184 }
185
186 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
187
188 err = gfc100_eflash_read(ARM_FLASHx_DEV->dev, addr, data, &cnt);
189
190 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
191
192 if(err != GFC100_ERROR_NONE) {
193 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
194 return ARM_DRIVER_ERROR;
195 }
196
197 /* Conversion between bytes and data items */
198 cnt /= data_width_byte[DriverCapabilities.data_width];
199
200 return cnt;
201 }
202
ARM_Flashx_ProgramData(ARM_FLASHx_Resources * ARM_FLASHx_DEV,uint32_t addr,const void * data,uint32_t cnt)203 static int32_t ARM_Flashx_ProgramData(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
204 uint32_t addr, const void *data,
205 uint32_t cnt)
206 {
207 enum gfc100_error_t err = GFC100_ERROR_NONE;
208
209 /* Conversion between data items and bytes */
210 cnt *= data_width_byte[DriverCapabilities.data_width];
211
212 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
213 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
214
215 /* Note: There is a significantly faster way to write to the flash using
216 * gfc100_eflash_row_write. It has the disadvantage that all IRQs have
217 * to be disabled, because the implementation is sensitive to timing.
218 * For applications where timing can be guaranteed this can be replaced
219 * with gfc100_eflash_row_write. For generic use, simple write is used here.
220 */
221 err = gfc100_eflash_write(ARM_FLASHx_DEV->dev, addr, data, &cnt);
222
223 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
224
225 if(err != GFC100_ERROR_NONE) {
226 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
227 if ((err == GFC100_ERROR_OUT_OF_RANGE) ||
228 (err == GFC100_ERROR_UNALIGNED_PARAM)) {
229 /* The native driver checks aligment and range */
230 return ARM_DRIVER_ERROR_PARAMETER;
231 }
232 return ARM_DRIVER_ERROR;
233 }
234
235 /* Conversion between bytes and data items */
236 cnt /= data_width_byte[DriverCapabilities.data_width];
237
238 return cnt;
239 }
240
ARM_Flashx_EraseSector(ARM_FLASHx_Resources * ARM_FLASHx_DEV,uint32_t addr)241 static int32_t ARM_Flashx_EraseSector(ARM_FLASHx_Resources *ARM_FLASHx_DEV,
242 uint32_t addr)
243 {
244 enum gfc100_error_t err = GFC100_ERROR_NONE;
245
246 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
247 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
248
249 /* The erase function checks whether the address is within the valid flash
250 * address range, and the HW will align the address to page boundary if
251 * it is not aligned.
252 */
253 err = gfc100_eflash_erase(ARM_FLASHx_DEV->dev, addr, GFC100_ERASE_PAGE);
254
255 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
256
257 if (err != GFC100_ERROR_NONE) {
258 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
259 if (err == GFC100_ERROR_OUT_OF_RANGE) {
260 return ARM_DRIVER_ERROR_PARAMETER;
261 }
262 return ARM_DRIVER_ERROR;
263 }
264
265 return ARM_DRIVER_OK;
266 }
267
ARM_Flashx_EraseChip(ARM_FLASHx_Resources * ARM_FLASHx_DEV)268 static int32_t ARM_Flashx_EraseChip(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
269 {
270 enum gfc100_error_t err = GFC100_ERROR_NONE;
271
272 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_NO_ERROR;
273 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_BUSY;
274
275 /* The erase function checks whether the address is aligned with
276 * the sector or subsector and checks the Flash memory boundaries.
277 */
278 err = gfc100_eflash_erase(ARM_FLASHx_DEV->dev, ARG_NOT_USED,
279 GFC100_MASS_ERASE_MAIN_AREA);
280
281 ARM_FLASHx_DEV->status.busy = DRIVER_STATUS_IDLE;
282
283 if(err != GFC100_ERROR_NONE) {
284 ARM_FLASHx_DEV->status.error = DRIVER_STATUS_ERROR;
285 return ARM_DRIVER_ERROR;
286 }
287
288 return ARM_DRIVER_OK;
289 }
290
291 static ARM_FLASH_STATUS
ARM_Flashx_GetStatus(ARM_FLASHx_Resources * ARM_FLASHx_DEV)292 ARM_Flashx_GetStatus(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
293 {
294 return ARM_FLASHx_DEV->status;
295 }
296
ARM_Flashx_GetInfo(ARM_FLASHx_Resources * ARM_FLASHx_DEV)297 static ARM_FLASH_INFO * ARM_Flashx_GetInfo(ARM_FLASHx_Resources *ARM_FLASHx_DEV)
298 {
299 return ARM_FLASHx_DEV->data;
300 }
301
302 #if (RTE_EFLASH0)
303 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
304 .sector_info = NULL, /* Uniform sector layout */
305 .sector_count = (0x200000u / 0x4000u), /* 2MB (flash size) / 16kB */
306 .sector_size = 0x4000u, /* 16kB - as there are no sectors the page size
307 * size is used here
308 */
309 .page_size = 0x4000u, /* 16kB */
310 .program_unit = 4u, /* Minimum write size in bytes */
311 .erased_value = 0xFF
312 };
313
314 static ARM_FLASHx_Resources ARM_FLASH0_DEV = {
315 .dev = &EFLASH0_DEV,
316 .data = &(ARM_FLASH0_DEV_DATA),
317 .status = {
318 .busy = DRIVER_STATUS_IDLE,
319 .error = DRIVER_STATUS_NO_ERROR,
320 .reserved = 0,
321 },
322 };
323
ARM_Flash0_GetVersion(void)324 static ARM_DRIVER_VERSION ARM_Flash0_GetVersion(void)
325 {
326 return ARM_Flash_GetVersion();
327 }
328
ARM_Flash0_GetCapabilities(void)329 static ARM_FLASH_CAPABILITIES ARM_Flash0_GetCapabilities(void)
330 {
331 return ARM_Flash_GetCapabilities();
332 }
333
ARM_Flash0_Initialize(ARM_Flash_SignalEvent_t cb_event)334 static int32_t ARM_Flash0_Initialize(ARM_Flash_SignalEvent_t cb_event)
335 {
336 return ARM_Flashx_Initialize(&ARM_FLASH0_DEV, cb_event);
337 }
338
ARM_Flash0_Uninitialize(void)339 static int32_t ARM_Flash0_Uninitialize(void)
340 {
341 return ARM_Flashx_Uninitialize(&ARM_FLASH0_DEV);
342 }
343
ARM_Flash0_PowerControl(ARM_POWER_STATE state)344 static int32_t ARM_Flash0_PowerControl(ARM_POWER_STATE state)
345 {
346 return ARM_Flashx_PowerControl(&ARM_FLASH0_DEV, state);
347 }
348
ARM_Flash0_ReadData(uint32_t addr,void * data,uint32_t cnt)349 static int32_t ARM_Flash0_ReadData(uint32_t addr, void *data, uint32_t cnt)
350 {
351 return ARM_Flashx_ReadData(&ARM_FLASH0_DEV, addr, data, cnt);
352 }
353
ARM_Flash0_ProgramData(uint32_t addr,const void * data,uint32_t cnt)354 static int32_t ARM_Flash0_ProgramData(uint32_t addr, const void *data,
355 uint32_t cnt)
356 {
357 return ARM_Flashx_ProgramData(&ARM_FLASH0_DEV, addr, data, cnt);
358 }
359
ARM_Flash0_EraseSector(uint32_t addr)360 static int32_t ARM_Flash0_EraseSector(uint32_t addr)
361 {
362 return ARM_Flashx_EraseSector(&ARM_FLASH0_DEV, addr);
363 }
364
ARM_Flash0_EraseChip(void)365 static int32_t ARM_Flash0_EraseChip(void)
366 {
367 return ARM_Flashx_EraseChip(&ARM_FLASH0_DEV);
368 }
369
ARM_Flash0_GetStatus(void)370 static ARM_FLASH_STATUS ARM_Flash0_GetStatus(void)
371 {
372 return ARM_Flashx_GetStatus(&ARM_FLASH0_DEV);
373 }
374
ARM_Flash0_GetInfo(void)375 static ARM_FLASH_INFO * ARM_Flash0_GetInfo(void)
376 {
377 return ARM_Flashx_GetInfo(&ARM_FLASH0_DEV);
378 }
379
380 ARM_DRIVER_FLASH Driver_EFLASH0 = {
381 ARM_Flash0_GetVersion,
382 ARM_Flash0_GetCapabilities,
383 ARM_Flash0_Initialize,
384 ARM_Flash0_Uninitialize,
385 ARM_Flash0_PowerControl,
386 ARM_Flash0_ReadData,
387 ARM_Flash0_ProgramData,
388 ARM_Flash0_EraseSector,
389 ARM_Flash0_EraseChip,
390 ARM_Flash0_GetStatus,
391 ARM_Flash0_GetInfo
392 };
393 #endif /* RTE_EFLASH0 */
394
395 #if (RTE_EFLASH1)
396 static ARM_FLASH_INFO ARM_FLASH1_DEV_DATA = {
397 .sector_info = NULL, /* Uniform sector layout */
398 .sector_count = (0x200000u / 0x4000u), /* 2MB (flash size) / 16kB */
399 .sector_size = 0x4000u, /* 16kB - as there are no sectors the page size
400 * size is used here
401 */
402 .page_size = 0x4000u, /* 16kB */
403 .program_unit = 4u, /* Minimum write size in bytes */
404 .erased_value = 0xFF
405 };
406
407 static ARM_FLASHx_Resources ARM_FLASH1_DEV = {
408 .dev = &EFLASH1_DEV,
409 .data = &ARM_FLASH1_DEV_DATA,
410 .status = {
411 .busy = DRIVER_STATUS_IDLE,
412 .error = DRIVER_STATUS_NO_ERROR,
413 .reserved = 0,
414 },
415 };
416
ARM_Flash1_GetVersion(void)417 static ARM_DRIVER_VERSION ARM_Flash1_GetVersion(void)
418 {
419 return ARM_Flash_GetVersion();
420 }
421
ARM_Flash1_GetCapabilities(void)422 static ARM_FLASH_CAPABILITIES ARM_Flash1_GetCapabilities(void)
423 {
424 return ARM_Flash_GetCapabilities();
425 }
426
ARM_Flash1_Initialize(ARM_Flash_SignalEvent_t cb_event)427 static int32_t ARM_Flash1_Initialize(ARM_Flash_SignalEvent_t cb_event)
428 {
429 return ARM_Flashx_Initialize(&ARM_FLASH1_DEV, cb_event);
430 }
431
ARM_Flash1_Uninitialize(void)432 static int32_t ARM_Flash1_Uninitialize(void)
433 {
434 return ARM_Flashx_Uninitialize(&ARM_FLASH1_DEV);
435 }
436
ARM_Flash1_PowerControl(ARM_POWER_STATE state)437 static int32_t ARM_Flash1_PowerControl(ARM_POWER_STATE state)
438 {
439 return ARM_Flashx_PowerControl(&ARM_FLASH1_DEV, state);
440 }
441
ARM_Flash1_ReadData(uint32_t addr,void * data,uint32_t cnt)442 static int32_t ARM_Flash1_ReadData(uint32_t addr, void *data, uint32_t cnt)
443 {
444 return ARM_Flashx_ReadData(&ARM_FLASH1_DEV, addr, data, cnt);
445 }
446
ARM_Flash1_ProgramData(uint32_t addr,const void * data,uint32_t cnt)447 static int32_t ARM_Flash1_ProgramData(uint32_t addr, const void *data,
448 uint32_t cnt)
449 {
450 return ARM_Flashx_ProgramData(&ARM_FLASH1_DEV, addr, data, cnt);
451 }
452
ARM_Flash1_EraseSector(uint32_t addr)453 static int32_t ARM_Flash1_EraseSector(uint32_t addr)
454 {
455 return ARM_Flashx_EraseSector(&ARM_FLASH1_DEV, addr);
456 }
457
ARM_Flash1_EraseChip(void)458 static int32_t ARM_Flash1_EraseChip(void)
459 {
460 return ARM_Flashx_EraseChip(&ARM_FLASH1_DEV);
461 }
462
ARM_Flash1_GetStatus(void)463 static ARM_FLASH_STATUS ARM_Flash1_GetStatus(void)
464 {
465 return (ARM_Flashx_GetStatus(&ARM_FLASH1_DEV));
466 }
467
ARM_Flash1_GetInfo(void)468 static ARM_FLASH_INFO * ARM_Flash1_GetInfo(void)
469 {
470 return ARM_Flashx_GetInfo(&ARM_FLASH1_DEV);
471 }
472
473 ARM_DRIVER_FLASH Driver_EFLASH1 = {
474 ARM_Flash1_GetVersion,
475 ARM_Flash1_GetCapabilities,
476 ARM_Flash1_Initialize,
477 ARM_Flash1_Uninitialize,
478 ARM_Flash1_PowerControl,
479 ARM_Flash1_ReadData,
480 ARM_Flash1_ProgramData,
481 ARM_Flash1_EraseSector,
482 ARM_Flash1_EraseChip,
483 ARM_Flash1_GetStatus,
484 ARM_Flash1_GetInfo
485 };
486 #endif /* RTE_EFLASH1 */
487