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