24
24
#include "fsl_flexspi.h"
25
25
#include "fsl_cache.h"
26
26
#include "flash_defines.h"
27
+ #include "mimxrt_flash_api.h"
28
+
29
+ #include <inttypes.h>
30
+ #include <stdio.h>
27
31
28
32
AT_QUICKACCESS_SECTION_CODE (void flexspi_update_lut_ram (void ));
29
33
AT_QUICKACCESS_SECTION_CODE (status_t flexspi_nor_write_enable_ram (uint32_t baseAddr ));
@@ -103,6 +107,13 @@ void flexspi_update_lut_ram(void)
103
107
config .enableSckBDiffOpt = true;
104
108
config .rxSampleClock = kFLEXSPI_ReadSampleClkExternalInputFromDqsPad ;
105
109
config .enableCombination = true;
110
+
111
+ /* Wait for bus idle. It seems to be important to hold off on calling
112
+ * FLEXSPI_Init() until after the bus is idle; I was getting random crashes
113
+ * until I added this. */
114
+ while (!FLEXSPI_GetBusIdleStatus (FLEXSPI )) {
115
+ }
116
+
106
117
FLEXSPI_Init (FLEXSPI , & config );
107
118
108
119
/* Configure flash settings according to serial flash feature. */
@@ -116,6 +127,10 @@ void flexspi_update_lut_ram(void)
116
127
/* Wait for bus idle. */
117
128
while (!FLEXSPI_GetBusIdleStatus (FLEXSPI )) {
118
129
}
130
+
131
+ // Just in case any bad data got into the I-cache while we were reconfiguring
132
+ // the flash, wipe it.
133
+ SCB_InvalidateICache ();
119
134
}
120
135
121
136
status_t flexspi_nor_write_enable_ram (uint32_t baseAddr )
@@ -319,13 +334,31 @@ status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *sr
319
334
320
335
#else
321
336
AT_QUICKACCESS_SECTION_CODE (status_t flexspi_nor_enable_quad_mode_ram (void ));
337
+ AT_QUICKACCESS_SECTION_CODE (status_t flexspi_nor_read_status_register_ram (uint32_t * result ));
338
+
339
+ /*
340
+ * Check if quad SPI mode is enabled and, if not, enable it.
341
+ *
342
+ * Note that I'm not totally sure if this function is needed because I don't think
343
+ * that the application could boot without quad mode enabled, but this might be
344
+ * useful for programming non-boot-device flashes at a later date.
345
+ * Or, if you must run the application on a flash which does not have quad mode enabled,
346
+ * you could temporarily change the boot header read command to use 1-pad read,
347
+ * then rely on this function to update the setting.
348
+ */
322
349
status_t flexspi_nor_enable_quad_mode_ram (void )
323
350
{
324
- flexspi_transfer_t flashXfer ;
325
- uint32_t writeValue = FLASH_QUAD_ENABLE ;
326
- status_t status = kStatus_Success ;
351
+ uint32_t readResult = 0 ;
352
+ status_t status = flexspi_nor_read_status_register_ram (& readResult );
353
+ if (status != kStatus_Success ) {
354
+ return status ;
355
+ }
356
+
357
+ if (readResult & (1 << FLASH_QE_STATUS_OFFSET )) {
358
+ // QSPI mode already enabled, don't need to do anything
359
+ return kStatus_Success ;
360
+ }
327
361
328
- flexspi_memset (& flashXfer , 0 , sizeof (flashXfer ));
329
362
/* Write enable */
330
363
status = flexspi_nor_write_enable_ram (0 );
331
364
@@ -334,6 +367,8 @@ status_t flexspi_nor_enable_quad_mode_ram(void)
334
367
}
335
368
336
369
/* Enable quad mode. */
370
+ flexspi_transfer_t flashXfer = {};
371
+ uint32_t writeValue = (1 << FLASH_QE_STATUS_OFFSET );
337
372
flashXfer .deviceAddress = 0 ;
338
373
flashXfer .port = kFLEXSPI_PortA1 ;
339
374
flashXfer .cmdType = kFLEXSPI_Write ;
@@ -349,17 +384,12 @@ status_t flexspi_nor_enable_quad_mode_ram(void)
349
384
350
385
status = flexspi_nor_wait_bus_busy_ram ();
351
386
352
- /* Do software reset. */
353
- FLEXSPI_SoftwareReset (FLEXSPI );
354
-
355
387
return status ;
356
388
}
357
389
358
390
void flexspi_update_lut_ram (void )
359
391
{
360
- flexspi_config_t config ;
361
-
362
- flexspi_memset (& config , 0 , sizeof (config ));
392
+ flexspi_config_t config = {};
363
393
364
394
/*Get FLEXSPI default settings and configure the flexspi. */
365
395
FLEXSPI_GetDefaultConfig (& config );
@@ -370,6 +400,15 @@ void flexspi_update_lut_ram(void)
370
400
config .ahbConfig .enableReadAddressOpt = true;
371
401
config .ahbConfig .enableAHBCachable = true;
372
402
config .rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad ;
403
+ config .enableDoze = false; // matches boot rom setting
404
+ config .seqTimeoutCycle = 0xee6c ; // matches boot rom setting
405
+
406
+ /* Wait for bus idle. It seems to be important to hold off on calling
407
+ * FLEXSPI_Init() until after the bus is idle; I was getting random crashes
408
+ * until I added this. */
409
+ while (!FLEXSPI_GetBusIdleStatus (FLEXSPI )) {
410
+ }
411
+
373
412
FLEXSPI_Init (FLEXSPI , & config );
374
413
375
414
/* Configure flash settings according to serial flash feature. */
@@ -383,7 +422,12 @@ void flexspi_update_lut_ram(void)
383
422
/* Wait for bus idle. */
384
423
while (!FLEXSPI_GetBusIdleStatus (FLEXSPI )) {
385
424
}
425
+
386
426
flexspi_nor_enable_quad_mode_ram ();
427
+
428
+ // Just in case any bad data got into the I-cache while we were reconfiguring
429
+ // the flash, wipe it.
430
+ SCB_InvalidateICache ();
387
431
}
388
432
389
433
status_t flexspi_nor_write_enable_ram (uint32_t baseAddr )
@@ -404,47 +448,46 @@ status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
404
448
return status ;
405
449
}
406
450
407
- status_t flexspi_nor_wait_bus_busy_ram (void )
451
+ // Read the status register and save the result into the given pointer
452
+ status_t flexspi_nor_read_status_register_ram (uint32_t * result )
408
453
{
409
- /* Wait status ready. */
410
- bool isBusy ;
411
- uint32_t readValue ;
412
- status_t status = kStatus_Success ;
413
- flexspi_transfer_t flashXfer ;
414
-
415
- flexspi_memset (& flashXfer , 0 , sizeof (flashXfer ));
454
+ flexspi_transfer_t flashXfer = {};
416
455
417
456
flashXfer .deviceAddress = 0 ;
418
457
flashXfer .port = kFLEXSPI_PortA1 ;
419
458
flashXfer .cmdType = kFLEXSPI_Read ;
420
459
flashXfer .SeqNumber = 1 ;
421
460
flashXfer .seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG ;
422
- flashXfer .data = & readValue ;
461
+ flashXfer .data = result ;
423
462
flashXfer .dataSize = 1 ;
424
463
464
+ return FLEXSPI_TransferBlocking (FLEXSPI , & flashXfer );
465
+ }
466
+
467
+ status_t flexspi_nor_wait_bus_busy_ram (void )
468
+ {
469
+ /* Wait status ready. */
470
+ bool isBusy ;
471
+
425
472
do {
426
- status = FLEXSPI_TransferBlocking (FLEXSPI , & flashXfer );
473
+ uint32_t readResult ;
474
+ status_t status = flexspi_nor_read_status_register_ram (& readResult );
427
475
428
476
if (status != kStatus_Success ) {
429
477
return status ;
430
478
}
431
- if (FLASH_BUSY_STATUS_POL ) {
432
- if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET )) {
433
- isBusy = true;
434
- } else {
435
- isBusy = false;
436
- }
437
- } else {
438
- if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET )) {
439
- isBusy = false;
440
- } else {
441
- isBusy = true;
442
- }
479
+
480
+ if (readResult & (1U << FLASH_BUSY_STATUS_OFFSET )) {
481
+ isBusy = FLASH_BUSY_STATUS_POL ;
482
+ }
483
+ else
484
+ {
485
+ isBusy = !FLASH_BUSY_STATUS_POL ;
443
486
}
444
487
445
488
} while (isBusy );
446
489
447
- return status ;
490
+ return kStatus_Success ;
448
491
}
449
492
450
493
@@ -540,12 +583,18 @@ void flexspi_nor_flash_read_data_ram(uint32_t addr, uint32_t *buffer, uint32_t s
540
583
memcpy (buffer , (void * )addr , size );
541
584
}
542
585
543
- int32_t flash_init ( flash_t * obj )
586
+ void mimxrt_flash_setup ( void )
544
587
{
545
588
core_util_critical_section_enter ();
546
589
flexspi_update_lut_ram ();
547
590
core_util_critical_section_exit ();
591
+ }
548
592
593
+ int32_t flash_init (flash_t * obj )
594
+ {
595
+ // Setup is already done when the application boots by flash_setup().
596
+ // Nothing left to do.
597
+ (void )obj ;
549
598
return 0 ;
550
599
}
551
600
@@ -581,6 +630,8 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
581
630
if (status != kStatus_Success ) {
582
631
ret = -1 ;
583
632
} else {
633
+ SCB_InvalidateICache_by_Addr ((void * )address , (int32_t )size );
634
+ SCB_InvalidateDCache_by_Addr ((void * )address , (int32_t )size );
584
635
DCACHE_InvalidateByRange (address , size );
585
636
}
586
637
@@ -604,8 +655,8 @@ int32_t flash_free(flash_t *obj)
604
655
uint32_t flash_get_sector_size (const flash_t * obj , uint32_t address )
605
656
{
606
657
uint32_t sectorsize = MBED_FLASH_INVALID_SIZE ;
607
- uint32_t devicesize = BOARD_FLASHIAP_SIZE ;
608
- uint32_t startaddr = BOARD_FLASHIAP_START_ADDR ;
658
+ uint32_t devicesize = BOARD_FLASH_SIZE ;
659
+ uint32_t startaddr = BOARD_FLASH_START_ADDR ;
609
660
610
661
if ((address >= startaddr ) && (address < (startaddr + devicesize ))) {
611
662
sectorsize = BOARD_FLASH_SECTOR_SIZE ;
@@ -621,12 +672,12 @@ uint32_t flash_get_page_size(const flash_t *obj)
621
672
622
673
uint32_t flash_get_start_address (const flash_t * obj )
623
674
{
624
- return BOARD_FLASHIAP_START_ADDR ;
675
+ return BOARD_FLASH_START_ADDR ;
625
676
}
626
677
627
678
uint32_t flash_get_size (const flash_t * obj )
628
679
{
629
- return BOARD_FLASHIAP_SIZE ;
680
+ return BOARD_FLASH_SIZE ;
630
681
}
631
682
632
683
uint8_t flash_get_erase_value (const flash_t * obj )
0 commit comments