Skip to content

Commit 5b791eb

Browse files
committed
targets:MIMXRT1050: Add QSPI Flash FLASHIAP support
Update the flash driver to support both Hyper Flash and QSPI Flash. Signed-off-by: Gavin Liu <[email protected]>
1 parent e22ea3c commit 5b791eb

File tree

3 files changed

+356
-5
lines changed

3 files changed

+356
-5
lines changed

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/flash_api.c

+238-3
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,16 @@ AT_QUICKACCESS_SECTION_CODE(void flexspi_update_lut_ram(void));
2929
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_write_enable_ram(uint32_t baseAddr));
3030
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_wait_bus_busy_ram(void));
3131
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_flash_erase_sector_ram(uint32_t address));
32-
AT_QUICKACCESS_SECTION_CODE(static void flexspi_lower_clock_ram(void));
33-
AT_QUICKACCESS_SECTION_CODE(static void flexspi_clock_update_ram(void));
3432
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_flash_page_program_ram(uint32_t address,
3533
const uint32_t *src,
3634
uint32_t size));
3735
AT_QUICKACCESS_SECTION_CODE(void flexspi_nor_flash_read_data_ram(uint32_t addr,
3836
uint32_t *buffer,
3937
uint32_t size));
4038

39+
#ifdef HYPERFLASH_BOOT
40+
AT_QUICKACCESS_SECTION_CODE(static void flexspi_lower_clock_ram(void));
41+
AT_QUICKACCESS_SECTION_CODE(static void flexspi_clock_update_ram(void));
4142
void flexspi_update_lut_ram(void)
4243
{
4344
flexspi_config_t config;
@@ -271,11 +272,245 @@ status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *sr
271272
return status;
272273
}
273274

275+
#else
276+
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_enable_quad_mode_ram(void));
277+
status_t flexspi_nor_enable_quad_mode_ram(void)
278+
{
279+
flexspi_transfer_t flashXfer;
280+
uint32_t writeValue = FLASH_QUAD_ENABLE;
281+
status_t status = kStatus_Success;
282+
283+
memset(&flashXfer, 0, sizeof(flashXfer));
284+
/* Write enable */
285+
status = flexspi_nor_write_enable_ram(0);
286+
287+
if (status != kStatus_Success)
288+
{
289+
return status;
290+
}
291+
292+
/* Enable quad mode. */
293+
flashXfer.deviceAddress = 0;
294+
flashXfer.port = kFLEXSPI_PortA1;
295+
flashXfer.cmdType = kFLEXSPI_Write;
296+
flashXfer.SeqNumber = 1;
297+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
298+
flashXfer.data = &writeValue;
299+
flashXfer.dataSize = 1;
300+
301+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
302+
if (status != kStatus_Success)
303+
{
304+
return status;
305+
}
306+
307+
status = flexspi_nor_wait_bus_busy_ram();
308+
309+
/* Do software reset. */
310+
FLEXSPI_SoftwareReset(FLEXSPI);
311+
312+
return status;
313+
}
314+
315+
void flexspi_update_lut_ram(void)
316+
{
317+
#ifndef XIP_EXTERNAL_FLASH
318+
flexspi_config_t config;
319+
320+
memset(&config, 0, sizeof(config));
321+
322+
/*Get FLEXSPI default settings and configure the flexspi. */
323+
FLEXSPI_GetDefaultConfig(&config);
324+
325+
/*Set AHB buffer size for reading data through AHB bus. */
326+
config.ahbConfig.enableAHBPrefetch = true;
327+
config.ahbConfig.enableAHBBufferable = true;
328+
config.ahbConfig.enableReadAddressOpt = true;
329+
config.ahbConfig.enableAHBCachable = true;
330+
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
331+
FLEXSPI_Init(FLEXSPI, &config);
332+
333+
/* Configure flash settings according to serial flash feature. */
334+
FLEXSPI_SetFlashConfig(FLEXSPI, &deviceconfig, kFLEXSPI_PortA1);
335+
336+
/* Update LUT table. */
337+
FLEXSPI_UpdateLUT(FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH);
338+
339+
flexspi_nor_enable_quad_mode_ram();
340+
/* Do software reset. */
341+
FLEXSPI_SoftwareReset(FLEXSPI);
342+
/* Wait for bus idle. */
343+
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
344+
}
345+
#endif
346+
}
347+
348+
status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
349+
{
350+
flexspi_transfer_t flashXfer;
351+
status_t status = kStatus_Success;
352+
353+
memset(&flashXfer, 0, sizeof(flashXfer));
354+
/* Write enable */
355+
flashXfer.deviceAddress = baseAddr;
356+
flashXfer.port = kFLEXSPI_PortA1;
357+
flashXfer.cmdType = kFLEXSPI_Command;
358+
flashXfer.SeqNumber = 1;
359+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
360+
361+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
362+
363+
return status;
364+
}
365+
366+
status_t flexspi_nor_wait_bus_busy_ram(void)
367+
{
368+
/* Wait status ready. */
369+
bool isBusy;
370+
uint32_t readValue;
371+
status_t status = kStatus_Success;
372+
flexspi_transfer_t flashXfer;
373+
374+
memset(&flashXfer, 0, sizeof(flashXfer));
375+
376+
flashXfer.deviceAddress = 0;
377+
flashXfer.port = kFLEXSPI_PortA1;
378+
flashXfer.cmdType = kFLEXSPI_Read;
379+
flashXfer.SeqNumber = 1;
380+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG;
381+
flashXfer.data = &readValue;
382+
flashXfer.dataSize = 1;
383+
384+
do
385+
{
386+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
387+
388+
if (status != kStatus_Success)
389+
{
390+
return status;
391+
}
392+
if (FLASH_BUSY_STATUS_POL)
393+
{
394+
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
395+
{
396+
isBusy = true;
397+
}
398+
else
399+
{
400+
isBusy = false;
401+
}
402+
}
403+
else
404+
{
405+
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
406+
{
407+
isBusy = false;
408+
}
409+
else
410+
{
411+
isBusy = true;
412+
}
413+
}
414+
415+
} while (isBusy);
416+
417+
return status;
418+
}
419+
420+
421+
status_t flexspi_nor_flash_erase_sector_ram(uint32_t address)
422+
{
423+
flexspi_transfer_t flashXfer;
424+
status_t status = kStatus_Success;
425+
426+
memset(&flashXfer, 0, sizeof(flashXfer));
427+
428+
/* Write enable */
429+
flashXfer.deviceAddress = address;
430+
flashXfer.port = kFLEXSPI_PortA1;
431+
flashXfer.cmdType = kFLEXSPI_Command;
432+
flashXfer.SeqNumber = 1;
433+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
434+
435+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
436+
437+
if (status != kStatus_Success)
438+
{
439+
return status;
440+
}
441+
442+
flashXfer.deviceAddress = address;
443+
flashXfer.port = kFLEXSPI_PortA1;
444+
flashXfer.cmdType = kFLEXSPI_Command;
445+
flashXfer.SeqNumber = 1;
446+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;
447+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
448+
449+
if (status != kStatus_Success)
450+
{
451+
return status;
452+
}
453+
454+
status = flexspi_nor_wait_bus_busy_ram();
455+
456+
/* Do software reset. */
457+
FLEXSPI_SoftwareReset(FLEXSPI);
458+
459+
return status;
460+
}
461+
462+
status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *src, uint32_t size)
463+
{
464+
flexspi_transfer_t flashXfer;
465+
status_t status = kStatus_Success;
466+
uint32_t offset = 0;
467+
468+
memset(&flashXfer, 0, sizeof(flashXfer));
469+
470+
while (size > 0) {
471+
/* Write enable */
472+
status = flexspi_nor_write_enable_ram(address + offset);
473+
474+
if (status != kStatus_Success) {
475+
return status;
476+
}
477+
478+
/* Prepare page program command */
479+
flashXfer.deviceAddress = address + offset;
480+
flashXfer.port = kFLEXSPI_PortA1;
481+
flashXfer.cmdType = kFLEXSPI_Write;
482+
flashXfer.SeqNumber = 1;
483+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD;
484+
flashXfer.data = (uint32_t *)(src + offset);
485+
flashXfer.dataSize = BOARD_FLASH_PAGE_SIZE;
486+
487+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
488+
489+
if (status != kStatus_Success) {
490+
return status;
491+
}
492+
493+
status = flexspi_nor_wait_bus_busy_ram();
494+
495+
if (status != kStatus_Success) {
496+
return status;
497+
}
498+
499+
size -= BOARD_FLASH_PAGE_SIZE;
500+
offset += BOARD_FLASH_PAGE_SIZE;
501+
}
502+
503+
/* Do software reset. */
504+
FLEXSPI_SoftwareReset(FLEXSPI);
505+
506+
return status;
507+
}
508+
509+
#endif
274510
void flexspi_nor_flash_read_data_ram(uint32_t addr, uint32_t *buffer, uint32_t size)
275511
{
276512
memcpy(buffer, (void *)addr, size);
277513
}
278-
279514
int32_t flash_init(flash_t *obj)
280515
{
281516
flexspi_update_lut_ram();

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/device.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,20 @@
1919
#define MBED_DEVICE_H
2020

2121
#define DEVICE_ID_LENGTH 24
22-
/* 4MB reserved for mbed-os */
22+
23+
#ifdef HYPERFLASH_BOOT
24+
/* 64MB HyperFlash, 4MB reserved for mbed-os */
2325
#define BOARD_FLASH_SIZE (0x3C00000U)
2426
#define BOARD_FLASH_START_ADDR (0x60400000U)
25-
2627
#define BOARD_FLASH_PAGE_SIZE (512)
2728
#define BOARD_FLASH_SECTOR_SIZE (262144)
29+
#else
30+
/* 8MB QSPI Flash, 64KB reserved for mbed_bootloader */
31+
#define BOARD_FLASH_SIZE (0x7F0000U)
32+
#define BOARD_FLASH_START_ADDR (0x60010000U)
33+
#define BOARD_FLASH_PAGE_SIZE (256)
34+
#define BOARD_FLASH_SECTOR_SIZE (4096)
35+
#endif
2836

2937
#define BOARD_ENET_PHY_ADDR (2)
3038

0 commit comments

Comments
 (0)