1 /*
2 * Copyright (c) 2013-2022 ARM Limited. All rights reserved.
3 * Copyright 2019-2020 NXP. All rights reserved.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the License); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
20 * Copyright 2016-2019 NXP
21 * All rights reserved.
22 *
23 * SPDX-License-Identifier: BSD-3-Clause
24 */
25
26 #include "Driver_Flash.h"
27 #include "platform_base_address.h"
28 #include "flash_layout.h"
29 #include "fsl_iap.h"
30
31 #ifndef ARG_UNUSED
32 #define ARG_UNUSED(arg) ((void)arg)
33 #endif
34
35 /* Below CMDs apply to both C040HDATFC and C040HDFC flash */
36 #define FLASH_CMD_INIT 0
37 #define FLASH_CMD_READ_SINGLE_WORD 3
38
39 /* INT_STATUS - Interrupt status bits - taken from LPC5588_cm33_core0.h */
40
41 #define FLASH_INT_STATUS_OVL_MASK (0x10U)
42
43 /* Alignment macros - taken from bootloader_common.h */
44 #ifndef ALIGN_DOWN
45 #define ALIGN_DOWN(x, a) ((x) & -(a))
46 #endif
47
48 /* Flash property defines */
49
50 /* Mask the number of bits required to select the 32-bit data word (DATAW) from the flash line */
51 #define FLASH_DATAW_IDX_MAX 3 /* Max DATAW index, 3 for a 128-bit flash line, 7 for 256-bit. */
52
53 #define FLASH_READMODE_REG (FLASH->DATAW[0])
54 #define FLASH_READMODE_ECC_MASK (0x4U)
55 #define FLASH_READMODE_ECC_SHIFT (2U)
56 #define FLASH_READMODE_ECC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_ECC_SHIFT)) & FLASH_READMODE_ECC_MASK)
57 #define FLASH_READMODE_MARGIN_MASK (0xC00U)
58 #define FLASH_READMODE_MARGIN_SHIFT (10U)
59 #define FLASH_READMODE_MARGIN(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_MARGIN_SHIFT)) & FLASH_READMODE_MARGIN_MASK)
60 #define FLASH_READMODE_DMACC_MASK (0x8000U)
61 #define FLASH_READMODE_DMACC_SHIFT (15U)
62 #define FLASH_READMODE_DMACC(x) (((uint32_t)(((uint32_t)(x)) << FLASH_READMODE_DMACC_SHIFT)) & FLASH_READMODE_DMACC_MASK)
63
64 /* Driver version */
65 #define ARM_FLASH_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
66
67 /**
68 * Data width values for ARM_FLASH_CAPABILITIES::data_width
69 * \ref ARM_FLASH_CAPABILITIES
70 */
71 enum {
72 DATA_WIDTH_8BIT = 0u,
73 DATA_WIDTH_16BIT,
74 DATA_WIDTH_32BIT,
75 DATA_WIDTH_ENUM_SIZE
76 };
77
78 static const uint32_t data_width_byte[DATA_WIDTH_ENUM_SIZE] = {
79 sizeof(uint8_t),
80 sizeof(uint16_t),
81 sizeof(uint32_t),
82 };
83
84 /* ARM FLASH device structure */
85 struct arm_flash_dev_t {
86 const uint32_t memory_base; /*!< FLASH memory base address */
87 ARM_FLASH_INFO *data; /*!< FLASH data */
88 flash_config_t flashInstance; /*!< FLASH config*/
89 };
90
91 /* Flash Status */
92 static ARM_FLASH_STATUS FlashStatus = {0, 0, 0};
93
94 /* Driver Version */
95 static const ARM_DRIVER_VERSION DriverVersion = {
96 ARM_FLASH_API_VERSION,
97 ARM_FLASH_DRV_VERSION
98 };
99
100 /* Driver Capabilities */
101 static const ARM_FLASH_CAPABILITIES DriverCapabilities = {
102 0, /* event_ready */
103 2, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */
104 1 /* erase_chip */
105 };
106
107 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA = {
108 .sector_info = NULL, /* Uniform sector layout */
109 .sector_count = FLASH0_SIZE / FLASH0_PAGE_SIZE,
110 .sector_size = FLASH0_PAGE_SIZE,
111 .page_size = FLASH0_PAGE_SIZE,
112 .program_unit = FLASH0_PAGE_SIZE,
113 .erased_value = 0x00};
114
115 static struct arm_flash_dev_t ARM_FLASH0_DEV = {
116 #if (__DOMAIN_NS == 1)
117 .memory_base = FLASH0_BASE_NS,
118 #else
119 .memory_base = FLASH0_BASE_S,
120 #endif /* __DOMAIN_NS == 1 */
121 .data = &(ARM_FLASH0_DEV_DATA)};
122
123 struct arm_flash_dev_t *FLASH0_DEV = &ARM_FLASH0_DEV;
124
125 /* Prototypes */
126
127 /* Internal function Flash command sequence. Called by driver APIs only*/
128 static status_t flash_command_sequence(flash_config_t *config);
129
130 //static status_t FLASH_ReadInit(flash_config_t *config);
131 static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes);
132 static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData);
133
134 static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
135 uint32_t offset);
136 static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
137 uint32_t param);
138
139 /* Functions */
140
ARM_Flash_GetVersion(void)141 static ARM_DRIVER_VERSION ARM_Flash_GetVersion(void)
142 {
143 return DriverVersion;
144 }
145
ARM_Flash_GetCapabilities(void)146 static ARM_FLASH_CAPABILITIES ARM_Flash_GetCapabilities(void)
147 {
148 return DriverCapabilities;
149 }
150
ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)151 static int32_t ARM_Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
152 {
153 ARG_UNUSED(cb_event);
154 status_t status = kStatus_Success;
155
156 if (DriverCapabilities.data_width >= DATA_WIDTH_ENUM_SIZE) {
157 return ARM_DRIVER_ERROR;
158 }
159
160 /* Call initialization from Flash API */
161 status = FLASH_Init(&FLASH0_DEV->flashInstance);
162
163 if(status != kStatus_Success){
164 return ARM_DRIVER_ERROR;
165 }
166
167
168 /* Disable Error Detection functionality */
169 FLASH0_DEV->flashInstance.modeConfig.readSingleWord.readWithEccOff = 0x1;
170
171 #if 0
172 /* Initialization of Flash by means of its registers to be able read data*/
173 if(FLASH_ReadInit(&FLASH0_DEV->flashInstance) != kStatus_Success){
174 return ARM_DRIVER_ERROR;
175 }
176 #endif
177
178 return ARM_DRIVER_OK;
179 }
180
ARM_Flash_Uninitialize(void)181 static int32_t ARM_Flash_Uninitialize(void)
182 {
183 /* Nothing to be done */
184 return ARM_DRIVER_OK;
185 }
186
ARM_Flash_PowerControl(ARM_POWER_STATE state)187 static int32_t ARM_Flash_PowerControl(ARM_POWER_STATE state)
188 {
189 switch (state) {
190 case ARM_POWER_FULL:
191 /* Nothing to be done */
192 return ARM_DRIVER_OK;
193
194 case ARM_POWER_OFF:
195 case ARM_POWER_LOW:
196 default:
197 return ARM_DRIVER_ERROR_UNSUPPORTED;
198 }
199 }
200
ARM_Flash_ReadData(uint32_t addr,void * data,uint32_t cnt)201 static int32_t ARM_Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
202 {
203 static uint32_t status;
204
205 /* Conversion between data items and bytes */
206 cnt *= data_width_byte[DriverCapabilities.data_width];
207
208 /* Check Flash memory boundaries */
209 status = is_range_valid(FLASH0_DEV, addr + cnt);
210 if(status != kStatus_Success) {
211 return ARM_DRIVER_ERROR_PARAMETER;
212 }
213
214 /* Read Data */
215 #if 1
216 if(cnt) {
217 status = FLASH_ReadData(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
218 if(status != kStatus_Success) {
219 return ARM_DRIVER_ERROR;
220 }
221 }
222 #else /* Bus fault when reading erased memory */
223 (void)memcpy(data, (uint8_t *)addr, cnt);
224 #endif
225 cnt /= data_width_byte[DriverCapabilities.data_width];
226 return cnt;
227 }
228
ARM_Flash_ProgramData(uint32_t addr,const void * data,uint32_t cnt)229 static int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt)
230 {
231 static uint32_t status;
232 uint32_t failedAddress, failedData;
233 /* Conversion between data items and bytes */
234 cnt *= data_width_byte[DriverCapabilities.data_width];
235
236 /* Check Flash memory boundaries */
237 status = is_range_valid(FLASH0_DEV, addr);
238 status |= is_write_aligned(FLASH0_DEV, addr);
239 status |= is_write_aligned(FLASH0_DEV, cnt);
240 if(status != kStatus_Success) {
241 return ARM_DRIVER_ERROR_PARAMETER;
242 }
243
244 status = FLASH_Program(&FLASH0_DEV->flashInstance, addr, (uint8_t *)data, cnt);
245 if (status != kStatus_Success) {
246 return ARM_DRIVER_ERROR;
247 }
248
249 status = FLASH_VerifyProgram(&FLASH0_DEV->flashInstance, addr, cnt, (const uint8_t *)data,
250 &failedAddress, &failedData);
251 if (status != kStatus_Success) {
252 return ARM_DRIVER_ERROR;
253 }
254
255 cnt /= data_width_byte[DriverCapabilities.data_width];
256 return cnt;
257 }
258
ARM_Flash_EraseSector(uint32_t addr)259 static int32_t ARM_Flash_EraseSector(uint32_t addr)
260 {
261 static uint32_t status;
262
263 status = is_range_valid(FLASH0_DEV, addr);
264 status |= is_write_aligned(FLASH0_DEV, addr);
265 if(status != kStatus_Success) {
266 return ARM_DRIVER_ERROR_PARAMETER;
267 }
268
269 status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH0_DEV->data->sector_size, kFLASH_ApiEraseKey);
270 if (status != kStatus_Success) {
271 return ARM_DRIVER_ERROR;
272 }
273
274 return ARM_DRIVER_OK;
275 }
276
ARM_Flash_EraseChip(void)277 static int32_t ARM_Flash_EraseChip(void)
278 {
279 static uint32_t status;
280 uint32_t addr = FLASH0_DEV->memory_base;
281
282 status = FLASH_Erase(&FLASH0_DEV->flashInstance, addr, FLASH_TOTAL_SIZE, kFLASH_ApiEraseKey);
283 if (status != kStatus_Success)
284 return ARM_DRIVER_ERROR;
285
286 return ARM_DRIVER_OK;
287 }
288
ARM_Flash_GetStatus(void)289 static ARM_FLASH_STATUS ARM_Flash_GetStatus(void)
290 {
291 return FlashStatus;
292 }
293
ARM_Flash_GetInfo(void)294 static ARM_FLASH_INFO * ARM_Flash_GetInfo(void)
295 {
296 return FLASH0_DEV->data;
297 }
298
299 ARM_DRIVER_FLASH Driver_FLASH0 = {
300 ARM_Flash_GetVersion,
301 ARM_Flash_GetCapabilities,
302 ARM_Flash_Initialize,
303 ARM_Flash_Uninitialize,
304 ARM_Flash_PowerControl,
305 ARM_Flash_ReadData,
306 ARM_Flash_ProgramData,
307 ARM_Flash_EraseSector,
308 ARM_Flash_EraseChip,
309 ARM_Flash_GetStatus,
310 ARM_Flash_GetInfo
311 };
312
313 #if 0
314 static status_t FLASH_ReadInit(flash_config_t *config)
315 {
316 status_t status = kStatus_Fail;
317
318 if (config == NULL)
319 {
320 return kStatus_FLASH_InvalidArgument;
321 }
322
323 /* config->PFlashTotalSize was initialized to 0xA0000 (640kB) by FLASH API.
324 This value needs to be changed to 0x98000 (608kB)*/
325 config->PFlashTotalSize = FLASH_TOTAL_SIZE;
326
327 /* Immediately after leaving reset mode, an initialization phase takes place,
328 where some memory locations are read, and corresponding volatile locations
329 are initialized depending on the value just read. */
330 FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
331 FLASH->CMD = FLASH_CMD_INIT;
332 status = flash_command_sequence(config);
333
334 if (kStatus_FLASH_Success != status)
335 {
336 return status;
337 }
338
339 return kStatus_FLASH_Success;
340 }
341 #endif
342
FLASH_ReadData(flash_config_t * config,uint32_t start,uint8_t * dest,uint32_t lengthInBytes)343 static status_t FLASH_ReadData(flash_config_t *config, uint32_t start, uint8_t *dest, uint32_t lengthInBytes)
344 {
345 status_t status = kStatus_Fail;
346
347 uint32_t readbackData[FLASH_DATAW_IDX_MAX + 1];
348 while (lengthInBytes)
349 {
350 uint32_t alignedStart = ALIGN_DOWN(start, (uint32_t)kFLASH_AlignementUnitSingleWordRead);
351 status = FLASH_ReadSingleWord(config, alignedStart, readbackData);
352 if (status != kStatus_FLASH_Success)
353 {
354 break;
355 }
356 for (uint32_t i = 0; i < sizeof(readbackData); i++)
357 {
358 if ((alignedStart == start) && lengthInBytes)
359 {
360 *dest = *((uint8_t *)readbackData + i);
361 dest++;
362 start++;
363 lengthInBytes--;
364 }
365 alignedStart++;
366 }
367 }
368
369 return status;
370 }
371
FLASH_ReadSingleWord(flash_config_t * config,uint32_t start,uint32_t * readbackData)372 static status_t FLASH_ReadSingleWord(flash_config_t *config, uint32_t start, uint32_t *readbackData)
373 {
374 status_t status = kStatus_Fail;
375
376 if (readbackData == NULL)
377 {
378 return kStatus_FLASH_InvalidArgument;
379 }
380
381 FLASH->INT_CLR_STATUS = FLASH_INT_CLR_STATUS_FAIL_MASK | FLASH_INT_CLR_STATUS_ERR_MASK |
382 FLASH_INT_CLR_STATUS_DONE_MASK | FLASH_INT_CLR_STATUS_ECC_ERR_MASK;
383
384 /* Set start address */
385 FLASH->STARTA = start >> 4;
386
387 /* ReadSingleWord notes:
388 Flash contains one DMACC word per page. Such words are not readable through
389 the read interface. DMACC words are managed internally by the controller in
390 order to store a flag (all1), which can be used to verify whether a programming
391 operation was prematurely terminated.
392 DMACC words are all_0 for an erased page, all_1 for a programmed page */
393
394 /* Set read modes */
395 FLASH_READMODE_REG = FLASH_READMODE_ECC(config->modeConfig.readSingleWord.readWithEccOff) |
396 FLASH_READMODE_MARGIN(config->modeConfig.readSingleWord.readMarginLevel) |
397 FLASH_READMODE_DMACC(config->modeConfig.readSingleWord.readDmaccWord);
398
399 /* Calling flash command sequence function to execute the command */
400 FLASH->CMD = FLASH_CMD_READ_SINGLE_WORD;
401 status = flash_command_sequence(config);
402
403 if (kStatus_FLASH_Success == status)
404 {
405 for (uint32_t datawIndex = 0; datawIndex <= FLASH_DATAW_IDX_MAX; datawIndex++)
406 {
407 *readbackData++ = FLASH->DATAW[datawIndex];
408 }
409 }
410
411 return status;
412 }
413
414 /* This function is used to perform the command write sequence to the flash. */
flash_command_sequence(flash_config_t * config)415 static status_t flash_command_sequence(flash_config_t *config)
416 {
417 status_t status = kStatus_Fail;
418 uint32_t registerValue;
419
420 while (!(FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK))
421 ;
422
423 /* Check error bits */
424 /* Get flash status register value */
425 registerValue = FLASH->INT_STATUS;
426
427 /* Checking access error */
428 if (registerValue & FLASH_INT_STATUS_FAIL_MASK)
429 {
430 status = kStatus_FLASH_CommandFailure;
431 }
432 else if (registerValue & FLASH_INT_STATUS_ERR_MASK)
433 {
434 status = kStatus_FLASH_CommandNotSupported;
435 }
436 else if (registerValue & FLASH_INT_STATUS_ECC_ERR_MASK)
437 {
438 status = kStatus_FLASH_EccError;
439 }
440 else if (registerValue & FLASH_INT_STATUS_OVL_MASK)
441 {
442 status = kStatus_FLASH_RegulationLoss;
443 }
444 else
445 {
446 status = kStatus_FLASH_Success;
447 }
448
449 return status;
450 }
451
452 /* Check if the Flash memory boundaries are not violated. */
is_range_valid(struct arm_flash_dev_t * flash_dev,uint32_t offset)453 static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
454 uint32_t offset)
455 {
456
457 uint32_t flash_limit = FLASH_TOTAL_SIZE - 1;
458
459 return (offset > flash_limit) ? (kStatus_Fail) : (kStatus_Success) ;
460 }
461
462 /* Check if the parameter is aligned to program_unit. */
is_write_aligned(struct arm_flash_dev_t * flash_dev,uint32_t param)463 static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
464 uint32_t param)
465 {
466 return ((param % flash_dev->data->program_unit) != 0) ? (kStatus_Fail) : (kStatus_Success);
467 }