Skip to content

Commit 92f5809

Browse files
authored
Merge pull request #12711 from liugang-gavin/master
targets:MIMXRT1050: Add QSPI flash support
2 parents 7151e1e + 288946a commit 92f5809

File tree

10 files changed

+548
-100
lines changed

10 files changed

+548
-100
lines changed

targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/flash_api.c

+277-11
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,66 @@ 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));
38+
AT_QUICKACCESS_SECTION_CODE(void *flexspi_memset(void *buf, int c, size_t n));
39+
/**
40+
* @brief Set bytes in memory. If put this code in SRAM, Make sure this code
41+
* does not call functions in Flash.
42+
*
43+
* @return pointer to start of buffer
44+
*/
45+
void *flexspi_memset(void *buf, int c, size_t n)
46+
{
47+
/* do byte-sized initialization until word-aligned or finished */
48+
unsigned char *d_byte = (unsigned char *)buf;
49+
unsigned char c_byte = (unsigned char)c;
50+
51+
while (((unsigned int)d_byte) & 0x3) {
52+
if (n == 0) {
53+
return buf;
54+
}
55+
*(d_byte++) = c_byte;
56+
n--;
57+
};
58+
59+
/* do word-sized initialization as long as possible */
60+
61+
unsigned int *d_word = (unsigned int *)d_byte;
62+
unsigned int c_word = (unsigned int)(unsigned char)c;
63+
64+
c_word |= c_word << 8;
65+
c_word |= c_word << 16;
66+
67+
while (n >= sizeof(unsigned int)) {
68+
*(d_word++) = c_word;
69+
n -= sizeof(unsigned int);
70+
}
71+
72+
/* do byte-sized initialization until finished */
73+
74+
d_byte = (unsigned char *)d_word;
4075

76+
while (n > 0) {
77+
*(d_byte++) = c_byte;
78+
n--;
79+
}
80+
81+
return buf;
82+
}
83+
84+
#ifdef HYPERFLASH_BOOT
85+
AT_QUICKACCESS_SECTION_CODE(void flexspi_lower_clock_ram(void));
86+
AT_QUICKACCESS_SECTION_CODE(void flexspi_clock_update_ram(void));
4187
void flexspi_update_lut_ram(void)
4288
{
4389
flexspi_config_t config;
4490

45-
memset(&config, 0, sizeof(config));
91+
flexspi_memset(&config, 0, sizeof(config));
4692

4793
/*Get FLEXSPI default settings and configure the flexspi. */
4894
FLEXSPI_GetDefaultConfig(&config);
@@ -77,7 +123,7 @@ status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
77123
flexspi_transfer_t flashXfer;
78124
status_t status = kStatus_Success;
79125

80-
memset(&flashXfer, 0, sizeof(flashXfer));
126+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
81127

82128
/* Write enable */
83129
flashXfer.deviceAddress = baseAddr;
@@ -99,7 +145,7 @@ status_t flexspi_nor_wait_bus_busy_ram(void)
99145
status_t status = kStatus_Success;
100146
flexspi_transfer_t flashXfer;
101147

102-
memset(&flashXfer, 0, sizeof(flashXfer));
148+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
103149

104150
flashXfer.deviceAddress = 0;
105151
flashXfer.port = kFLEXSPI_PortA1;
@@ -138,7 +184,7 @@ status_t flexspi_nor_flash_erase_sector_ram(uint32_t address)
138184
status_t status = kStatus_Success;
139185
flexspi_transfer_t flashXfer;
140186

141-
memset(&flashXfer, 0, sizeof(flashXfer));
187+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
142188

143189
/* Write enable */
144190
status = flexspi_nor_write_enable_ram(address);
@@ -165,7 +211,7 @@ status_t flexspi_nor_flash_erase_sector_ram(uint32_t address)
165211
return status;
166212
}
167213

168-
static void flexspi_lower_clock_ram(void)
214+
void flexspi_lower_clock_ram(void)
169215
{
170216
unsigned int reg = 0;
171217

@@ -197,7 +243,7 @@ static void flexspi_lower_clock_ram(void)
197243
}
198244
}
199245

200-
static void flexspi_clock_update_ram(void)
246+
void flexspi_clock_update_ram(void)
201247
{
202248
/* Program finished, speed the clock to 133M. */
203249
/* Wait for bus idle before change flash configuration. */
@@ -229,7 +275,7 @@ status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *sr
229275
flexspi_transfer_t flashXfer;
230276
uint32_t offset = 0;
231277

232-
memset(&flashXfer, 0, sizeof(flashXfer));
278+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
233279

234280
flexspi_lower_clock_ram();
235281

@@ -271,14 +317,234 @@ status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *sr
271317
return status;
272318
}
273319

320+
#else
321+
AT_QUICKACCESS_SECTION_CODE(status_t flexspi_nor_enable_quad_mode_ram(void));
322+
status_t flexspi_nor_enable_quad_mode_ram(void)
323+
{
324+
flexspi_transfer_t flashXfer;
325+
uint32_t writeValue = FLASH_QUAD_ENABLE;
326+
status_t status = kStatus_Success;
327+
328+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
329+
/* Write enable */
330+
status = flexspi_nor_write_enable_ram(0);
331+
332+
if (status != kStatus_Success) {
333+
return status;
334+
}
335+
336+
/* Enable quad mode. */
337+
flashXfer.deviceAddress = 0;
338+
flashXfer.port = kFLEXSPI_PortA1;
339+
flashXfer.cmdType = kFLEXSPI_Write;
340+
flashXfer.SeqNumber = 1;
341+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
342+
flashXfer.data = &writeValue;
343+
flashXfer.dataSize = 1;
344+
345+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
346+
if (status != kStatus_Success) {
347+
return status;
348+
}
349+
350+
status = flexspi_nor_wait_bus_busy_ram();
351+
352+
/* Do software reset. */
353+
FLEXSPI_SoftwareReset(FLEXSPI);
354+
355+
return status;
356+
}
357+
358+
void flexspi_update_lut_ram(void)
359+
{
360+
flexspi_config_t config;
361+
362+
flexspi_memset(&config, 0, sizeof(config));
363+
364+
/*Get FLEXSPI default settings and configure the flexspi. */
365+
FLEXSPI_GetDefaultConfig(&config);
366+
367+
/*Set AHB buffer size for reading data through AHB bus. */
368+
config.ahbConfig.enableAHBPrefetch = true;
369+
config.ahbConfig.enableAHBBufferable = true;
370+
config.ahbConfig.enableReadAddressOpt = true;
371+
config.ahbConfig.enableAHBCachable = true;
372+
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
373+
FLEXSPI_Init(FLEXSPI, &config);
374+
375+
/* Configure flash settings according to serial flash feature. */
376+
FLEXSPI_SetFlashConfig(FLEXSPI, &deviceconfig, kFLEXSPI_PortA1);
377+
378+
/* Update LUT table. */
379+
FLEXSPI_UpdateLUT(FLEXSPI, 0, customLUT, CUSTOM_LUT_LENGTH);
380+
381+
/* Do software reset. */
382+
FLEXSPI_SoftwareReset(FLEXSPI);
383+
/* Wait for bus idle. */
384+
while (!FLEXSPI_GetBusIdleStatus(FLEXSPI)) {
385+
}
386+
flexspi_nor_enable_quad_mode_ram();
387+
}
388+
389+
status_t flexspi_nor_write_enable_ram(uint32_t baseAddr)
390+
{
391+
flexspi_transfer_t flashXfer;
392+
status_t status = kStatus_Success;
393+
394+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
395+
/* Write enable */
396+
flashXfer.deviceAddress = baseAddr;
397+
flashXfer.port = kFLEXSPI_PortA1;
398+
flashXfer.cmdType = kFLEXSPI_Command;
399+
flashXfer.SeqNumber = 1;
400+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
401+
402+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
403+
404+
return status;
405+
}
406+
407+
status_t flexspi_nor_wait_bus_busy_ram(void)
408+
{
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));
416+
417+
flashXfer.deviceAddress = 0;
418+
flashXfer.port = kFLEXSPI_PortA1;
419+
flashXfer.cmdType = kFLEXSPI_Read;
420+
flashXfer.SeqNumber = 1;
421+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG;
422+
flashXfer.data = &readValue;
423+
flashXfer.dataSize = 1;
424+
425+
do {
426+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
427+
428+
if (status != kStatus_Success) {
429+
return status;
430+
}
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+
}
443+
}
444+
445+
} while (isBusy);
446+
447+
return status;
448+
}
449+
450+
451+
status_t flexspi_nor_flash_erase_sector_ram(uint32_t address)
452+
{
453+
flexspi_transfer_t flashXfer;
454+
status_t status = kStatus_Success;
455+
456+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
457+
458+
/* Write enable */
459+
flashXfer.deviceAddress = address;
460+
flashXfer.port = kFLEXSPI_PortA1;
461+
flashXfer.cmdType = kFLEXSPI_Command;
462+
flashXfer.SeqNumber = 1;
463+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
464+
465+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
466+
467+
if (status != kStatus_Success) {
468+
return status;
469+
}
470+
471+
flashXfer.deviceAddress = address;
472+
flashXfer.port = kFLEXSPI_PortA1;
473+
flashXfer.cmdType = kFLEXSPI_Command;
474+
flashXfer.SeqNumber = 1;
475+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;
476+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
477+
478+
if (status != kStatus_Success) {
479+
return status;
480+
}
481+
482+
status = flexspi_nor_wait_bus_busy_ram();
483+
484+
/* Do software reset. */
485+
FLEXSPI_SoftwareReset(FLEXSPI);
486+
487+
return status;
488+
}
489+
490+
status_t flexspi_nor_flash_page_program_ram(uint32_t address, const uint32_t *src, uint32_t size)
491+
{
492+
flexspi_transfer_t flashXfer;
493+
status_t status = kStatus_Success;
494+
uint32_t offset = 0;
495+
496+
flexspi_memset(&flashXfer, 0, sizeof(flashXfer));
497+
498+
while (size > 0) {
499+
/* Write enable */
500+
status = flexspi_nor_write_enable_ram(address + offset);
501+
502+
if (status != kStatus_Success) {
503+
return status;
504+
}
505+
506+
/* Prepare page program command */
507+
flashXfer.deviceAddress = address + offset;
508+
flashXfer.port = kFLEXSPI_PortA1;
509+
flashXfer.cmdType = kFLEXSPI_Write;
510+
flashXfer.SeqNumber = 1;
511+
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD;
512+
flashXfer.data = (uint32_t *)(src + offset);
513+
flashXfer.dataSize = BOARD_FLASH_PAGE_SIZE;
514+
515+
status = FLEXSPI_TransferBlocking(FLEXSPI, &flashXfer);
516+
517+
if (status != kStatus_Success) {
518+
return status;
519+
}
520+
521+
status = flexspi_nor_wait_bus_busy_ram();
522+
523+
if (status != kStatus_Success) {
524+
return status;
525+
}
526+
527+
size -= BOARD_FLASH_PAGE_SIZE;
528+
offset += BOARD_FLASH_PAGE_SIZE;
529+
}
530+
531+
/* Do software reset. */
532+
FLEXSPI_SoftwareReset(FLEXSPI);
533+
534+
return status;
535+
}
536+
537+
#endif
274538
void flexspi_nor_flash_read_data_ram(uint32_t addr, uint32_t *buffer, uint32_t size)
275539
{
276540
memcpy(buffer, (void *)addr, size);
277541
}
278542

279543
int32_t flash_init(flash_t *obj)
280544
{
545+
core_util_critical_section_enter();
281546
flexspi_update_lut_ram();
547+
core_util_critical_section_exit();
282548

283549
return 0;
284550
}
@@ -355,12 +621,12 @@ uint32_t flash_get_page_size(const flash_t *obj)
355621

356622
uint32_t flash_get_start_address(const flash_t *obj)
357623
{
358-
return BOARD_FLASH_START_ADDR;
624+
return BOARD_FLASHIAP_START_ADDR;
359625
}
360626

361627
uint32_t flash_get_size(const flash_t *obj)
362628
{
363-
return BOARD_FLASH_SIZE;
629+
return BOARD_FLASHIAP_SIZE;
364630
}
365631

366632
uint8_t flash_get_erase_value(const flash_t *obj)

0 commit comments

Comments
 (0)