2727/* ---- serial flash command ---- */
2828#if (FLASH_SIZE > 0x1000000 )
2929#define SPIBSC_OUTPUT_ADDR SPIBSC_OUTPUT_ADDR_32
30- #define SFLASHCMD_SECTOR_ERASE (0x21u) /* SE4B 4-byte address(1bit) */
31- #define SFLASHCMD_PAGE_PROGRAM (0x12u) /* PP4B 4-byte address(1bit), data(1bit) */
30+ #if DEVICE_QSPIx2
31+ #define SFLASHCMD_SECTOR_ERASE (0xDCu) /* SE4B 4-byte address(1bit) */
32+ #define SFLASHCMD_PAGE_PROGRAM (0x34u) /* QPP4B 4-byte address(1bit), data(4bit) */
33+ #else
34+ #define SFLASHCMD_SECTOR_ERASE (0x21u) /* SE4B 4-byte address(1bit) */
35+ #define SFLASHCMD_PAGE_PROGRAM (0x12u) /* PP4B 4-byte address(1bit), data(1bit) */
36+ #endif
3237#else
3338#define SPIBSC_OUTPUT_ADDR SPIBSC_OUTPUT_ADDR_24
34- #define SFLASHCMD_SECTOR_ERASE (0x20u) /* SE 3-byte address(1bit) */
35- #define SFLASHCMD_PAGE_PROGRAM (0x02u) /* PP 3-byte address(1bit), data(1bit) */
39+ #if DEVICE_QSPIx2
40+ #define SFLASHCMD_SECTOR_ERASE (0xD8u) /* SE 3-byte address(1bit) */
41+ #define SFLASHCMD_PAGE_PROGRAM (0x32u) /* PP 3-byte address(1bit), data(4bit) */
42+ #else
43+ #define SFLASHCMD_SECTOR_ERASE (0x20u) /* SE 3-byte address(1bit) */
44+ #define SFLASHCMD_PAGE_PROGRAM (0x02u) /* PP 3-byte address(1bit), data(1bit) */
45+ #endif
3646#endif
3747#define SFLASHCMD_READ_STATUS_REG (0x05u) /* RDSR data(1bit) */
3848#define SFLASHCMD_WRITE_ENABLE (0x06u) /* WREN */
3949/* ---- serial flash register definitions ---- */
50+ #if DEVICE_QSPIx2
51+ #define STREG_BUSY_BIT (0x0101u) /* SR.[0]BUSY Erase/Write In Progress (RO) */
52+ #define SPIBSC_BUS_MODE SPIBSC_CMNCR_BSZ_DUAL
53+ #define CHIP_SIZE (FLASH_SIZE + FLASH_SECTOR_SIZE)
54+ #define CHIP_BASE (FLASH_BASE - FLASH_SECTOR_SIZE)
55+ #else
4056#define STREG_BUSY_BIT (0x01u) /* SR.[0]BUSY Erase/Write In Progress (RO) */
57+ #define SPIBSC_BUS_MODE SPIBSC_CMNCR_BSZ_SINGLE
58+ #define CHIP_SIZE FLASH_SIZE
59+ #define CHIP_BASE FLASH_BASE
60+ #endif
4161
4262/* Definition of the base address for the MMU translation table */
4363#if defined(__CC_ARM ) || defined(__ARMCC_VERSION ) || defined(__GNUC__ )
@@ -100,7 +120,7 @@ typedef struct {
100120 uint32_t base_addr : 12 ; /* bit 31-20 : PA[31:20] PA(physical address) bits:bit31-20 */
101121} mmu_ttbl_desc_section_t ;
102122
103- static mmu_ttbl_desc_section_t desc_tbl [(FLASH_SIZE >> 20 )];
123+ static mmu_ttbl_desc_section_t desc_tbl [(CHIP_SIZE >> 20 )];
104124static volatile struct st_spibsc * SPIBSC = & SPIBSC0 ;
105125static st_spibsc_spimd_reg_t spimd_reg ;
106126static uint8_t write_tmp_buf [FLASH_PAGE_SIZE ];
@@ -117,7 +137,7 @@ RAM_CODE_SEC int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t s
117137
118138static RAM_CODE_SEC int32_t write_enable (void );
119139static RAM_CODE_SEC int32_t busy_wait (void );
120- static RAM_CODE_SEC int32_t read_register (uint8_t cmd , uint8_t * status );
140+ static RAM_CODE_SEC int32_t read_register (uint8_t cmd , uint16_t * status );
121141static RAM_CODE_SEC int32_t data_send (uint32_t bit_width , uint32_t spbssl_level , const uint8_t * buf , int32_t size );
122142static RAM_CODE_SEC void spi_mode (void );
123143static RAM_CODE_SEC void ex_mode (void );
@@ -141,12 +161,12 @@ int32_t flash_free(flash_t *obj)
141161
142162int32_t flash_erase_sector (flash_t * obj , uint32_t address )
143163{
144- return _sector_erase (address - FLASH_BASE );
164+ return _sector_erase (address - CHIP_BASE );
145165}
146166
147167int32_t flash_program_page (flash_t * obj , uint32_t address , const uint8_t * data , uint32_t size )
148168{
149- return _page_program (address - FLASH_BASE , data , size );
169+ return _page_program (address - CHIP_BASE , data , size );
150170}
151171
152172uint32_t flash_get_sector_size (const flash_t * obj , uint32_t address )
@@ -160,7 +180,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
160180
161181uint32_t flash_get_page_size (const flash_t * obj )
162182{
163- return 8 ;
183+ return ( SPIBSC_BUS_MODE == SPIBSC_CMNCR_BSZ_DUAL )? 32 : 8 ;
164184}
165185
166186uint32_t flash_get_start_address (const flash_t * obj )
@@ -177,6 +197,11 @@ int32_t _sector_erase(uint32_t addr)
177197{
178198 int32_t ret ;
179199
200+ #if DEVICE_QSPIx2
201+ if (addr < FLASH_SECTOR_SIZE )
202+ return -1 ; /* Do not mess around with the 1-st sector (Bootloader) */
203+ #endif
204+
180205 core_util_critical_section_enter ();
181206 spi_mode ();
182207
@@ -200,7 +225,7 @@ int32_t _sector_erase(uint32_t addr)
200225 spimd_reg .ade = SPIBSC_OUTPUT_ADDR ;
201226 spimd_reg .addre = SPIBSC_SDR_TRANS ; /* SDR */
202227 spimd_reg .adb = SPIBSC_1BIT ;
203- spimd_reg .addr = addr ;
228+ spimd_reg .addr = ( SPIBSC_BUS_MODE == SPIBSC_CMNCR_BSZ_DUAL )? addr >> 1 : addr ;
204229
205230 ret = spibsc_transfer (& spimd_reg );
206231 if (ret != 0 ) {
@@ -223,6 +248,11 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
223248 int32_t remainder ;
224249 int32_t idx = 0 ;
225250
251+ #if DEVICE_QSPIx2
252+ if (addr < FLASH_SECTOR_SIZE )
253+ return -1 ; /* Do not mess around with the 1-st sector (Bootloader) */
254+ #endif
255+
226256 while (size > 0 ) {
227257 if (size > FLASH_PAGE_SIZE ) {
228258 program_size = FLASH_PAGE_SIZE ;
@@ -259,7 +289,7 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
259289 spimd_reg .ade = SPIBSC_OUTPUT_ADDR ;
260290 spimd_reg .addre = SPIBSC_SDR_TRANS ; /* SDR */
261291 spimd_reg .adb = SPIBSC_1BIT ;
262- spimd_reg .addr = addr ;
292+ spimd_reg .addr = ( SPIBSC_BUS_MODE == SPIBSC_CMNCR_BSZ_DUAL )? addr >> 1 : addr ;
263293
264294 /* ---- Others ---- */
265295 spimd_reg .sslkp = SPIBSC_SPISSL_KEEP ; /* SPBSSL level */
@@ -272,7 +302,7 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
272302 }
273303
274304 /* ----------- 2. Data ---------------*/
275- ret = data_send (SPIBSC_1BIT , SPIBSC_SPISSL_NEGATE , write_tmp_buf , program_size );
305+ ret = data_send (( SPIBSC_BUS_MODE == SPIBSC_CMNCR_BSZ_DUAL )? SPIBSC_4BIT : SPIBSC_1BIT , SPIBSC_SPISSL_NEGATE , write_tmp_buf , program_size );
276306 if (ret != 0 ) {
277307 ex_mode ();
278308 core_util_critical_section_exit ();
@@ -317,7 +347,7 @@ static int32_t write_enable(void)
317347static int32_t busy_wait (void )
318348{
319349 int32_t ret ;
320- uint8_t st_reg ;
350+ uint16_t st_reg ;
321351
322352 while (1 ) {
323353 ret = read_register (SFLASHCMD_READ_STATUS_REG , & st_reg );
@@ -332,7 +362,7 @@ static int32_t busy_wait(void)
332362 return ret ;
333363}
334364
335- static int32_t read_register (uint8_t cmd , uint8_t * status )
365+ static int32_t read_register (uint8_t cmd , uint16_t * status )
336366{
337367 int32_t ret ;
338368
@@ -358,7 +388,7 @@ static int32_t read_register(uint8_t cmd, uint8_t * status)
358388
359389 ret = spibsc_transfer (& spimd_reg );
360390 if (ret == 0 ) {
361- * status = (uint8_t )(spimd_reg .smrdr [0 ]); /* Data[7:0] */
391+ * status = (SPIBSC_BUS_MODE == SPIBSC_CMNCR_BSZ_DUAL )? ( uint16_t )( spimd_reg . smrdr [ 0 ]) : ( uint8_t )(spimd_reg .smrdr [0 ]); /* Data[15:8] / Data[ 7:0] */
362392 }
363393
364394 return ret ;
@@ -383,6 +413,19 @@ static int32_t data_send(uint32_t bit_width, uint32_t spbssl_level, const uint8_
383413 spimd_reg .spidb = bit_width ;
384414 spimd_reg .spidre = SPIBSC_SDR_TRANS ; /* SDR */
385415
416+ #if (SPIBSC_BUS_MODE == SPIBSC_CMNCR_BSZ_DUAL )
417+ if (((uint32_t )size & 0x7 ) == 0 ) {
418+ spimd_reg .spide = SPIBSC_OUTPUT_SPID_32 ; /* Enable(64bit) */
419+ unit = 8 ;
420+ } else if (((uint32_t )size & 0x3 ) == 0 ) {
421+ spimd_reg .spide = SPIBSC_OUTPUT_SPID_32 ; /* Enable(32bit) */
422+ unit = 4 ;
423+ } else if (((uint32_t )size & 0x1 ) == 0 ) {
424+ spimd_reg .spide = SPIBSC_OUTPUT_SPID_16 ; /* Enable(16bit) */
425+ unit = 2 ;
426+ } else
427+ return -1 ;
428+ #else
386429 if (((uint32_t )size & 0x3 ) == 0 ) {
387430 spimd_reg .spide = SPIBSC_OUTPUT_SPID_32 ; /* Enable(32bit) */
388431 unit = 4 ;
@@ -393,6 +436,7 @@ static int32_t data_send(uint32_t bit_width, uint32_t spbssl_level, const uint8_
393436 spimd_reg .spide = SPIBSC_OUTPUT_SPID_8 ; /* Enable(8bit) */
394437 unit = 1 ;
395438 }
439+ #endif
396440
397441 while (size > 0 ) {
398442 if (unit == 1 ) {
@@ -404,6 +448,11 @@ static int32_t data_send(uint32_t bit_width, uint32_t spbssl_level, const uint8_
404448 } else if (unit == 4 ) {
405449 buf_l = (uint32_t * )buf ;
406450 spimd_reg .smwdr [0 ] = (uint32_t )(((uint32_t )(* buf_l )) & 0xfffffffful );
451+ } else if (unit == 8 ) {
452+ buf_l = (uint32_t * )buf ;
453+ spimd_reg .smwdr [1 ] = (uint32_t )(((uint32_t )(* buf_l )) & 0xfffffffful );
454+ buf_l ++ ;
455+ spimd_reg .smwdr [0 ] = (uint32_t )(((uint32_t )(* buf_l )) & 0xfffffffful );
407456 } else {
408457 /* Do Nothing */
409458 }
@@ -701,6 +750,9 @@ static void change_mmu_ttbl_spibsc(uint32_t type)
701750 desc .XN = 0x1u ; /* XN = 1 (Execute never) */
702751 } else { /* Xip */
703752 desc = desc_tbl [index - (FLASH_BASE >> 20 )];
753+ #if (FLASH_SIZE > 0x01000000 )
754+ __NOP (); /* prevents '__aeabi_memcpy4' function insertion by the ARM compiler, which sabotages the RAM_CODE execution and respectively rises the DAbt_Handler exeption */
755+ #endif
704756 }
705757 /* Write descriptor back to translation table */
706758 table [index ] = desc ;
0 commit comments