8888
8989//#define SPI_QUAD_MODE
9090/* SPI Flash Commands */
91- #define FESPI_READ_ID 0x9F /* Read Flash Identification */
91+ #define FESPI_READ_ID 0xAB /* Read Flash Identification */
9292#define FESPI_READ_MID 0xAF /* Read Flash Identification, multi-io */
9393#define FESPI_READ_STATUS 0x05 /* Read Status Register */
9494#define FESPI_WRITE_ENABLE 0x06 /* Write Enable */
177177#define CPU_FREQ 320000000
178178#endif
179179#define MAX_CPU_FREQ 320000000
180- #define MAX_FLASH_FREQ 50000000
180+ #define MAX_FLASH_FREQ 5000000
181181
182182/* PLL Configuration */
183183/* R and Q are fixed values for this PLL code */
@@ -291,12 +291,14 @@ static RAMFUNCTION void fespi_csmode_auto(void)
291291
292292static RAMFUNCTION void fespi_wait_txwm (void )
293293{
294- while ((FESPI_REG_IP & FESPI_IP_TXWM ) == 0 );
294+ while ((FESPI_REG_IP & FESPI_IP_TXWM ) == 0 )
295+ ;
295296}
296297
297298static RAMFUNCTION void fespi_sw_tx (uint8_t b )
298299{
299- while ((FESPI_REG_TXDATA & FESPI_TXDATA_FIFO_FULL ) != 0 );
300+ while ((FESPI_REG_TXDATA & FESPI_TXDATA_FIFO_FULL ) != 0 )
301+ ;
300302 FESPI_REG_TXDATA = b ;
301303}
302304
@@ -322,38 +324,71 @@ static RAMFUNCTION void fespi_write_address(uint32_t address)
322324 fespi_sw_tx ((address & 0xFF0000 ) >> 16 );
323325 fespi_sw_tx ((address & 0xFF00 ) >> 8 );
324326 fespi_sw_tx ((address & 0xFF ));
327+ fespi_wait_txwm ();
325328}
326329
327- static RAMFUNCTION void fespi_wait_flash_busy (void )
330+ static RAMFUNCTION void fespi_wait_write_disabled (void )
328331{
329332 uint8_t rx ;
333+ fespi_sw_setdir (FESPI_DIR_RX );
330334 fespi_csmode_hold ();
331335 fespi_sw_tx (FESPI_READ_STATUS );
332336 rx = fespi_sw_rx ();
333337 while (1 ) {
334338 fespi_sw_tx (0 );
335339 rx = fespi_sw_rx ();
336- if ((rx & FESPI_RX_BSY ) == 0 ) {
337- fespi_csmode_auto ();
338- return ;
340+ if ((rx & FESPI_RX_WE ) == 0 ) {
341+ break ;
342+ }
343+ }
344+ fespi_csmode_auto ();
345+ fespi_sw_setdir (FESPI_DIR_TX );
346+ }
347+
348+ static RAMFUNCTION void fespi_write_enable (void )
349+ {
350+ uint8_t rx ;
351+ int i ;
352+ while (1 ) {
353+ fespi_sw_tx (FESPI_WRITE_ENABLE );
354+ fespi_wait_txwm ();
355+ fespi_sw_setdir (FESPI_DIR_RX );
356+ fespi_csmode_hold ();
357+ fespi_sw_tx (FESPI_READ_STATUS );
358+ rx = fespi_sw_rx ();
359+ for (i = 0 ; i < 3 ; i ++ ) {
360+ fespi_sw_tx (0 );
361+ rx = fespi_sw_rx ();
362+ if ((rx & FESPI_RX_WE ) == FESPI_RX_WE ) {
363+ fespi_csmode_auto ();
364+ fespi_sw_setdir (FESPI_DIR_TX );
365+ return ;
366+ }
339367 }
368+ fespi_csmode_auto ();
369+ fespi_sw_setdir (FESPI_DIR_TX );
340370 }
341371}
342372
343- static RAMFUNCTION void fespi_wait_flash_writing (void )
373+ static RAMFUNCTION void fespi_wait_flash_busy (void )
344374{
345375 uint8_t rx ;
376+ fespi_sw_setdir (FESPI_DIR_RX );
377+ fespi_csmode_hold ();
346378 fespi_sw_tx (FESPI_READ_STATUS );
347379 rx = fespi_sw_rx ();
348380 while (1 ) {
349381 fespi_sw_tx (0 );
350382 rx = fespi_sw_rx ();
351- if ((rx & FESPI_RX_WE ) == 0 ) {
352- return ;
383+ if ((rx & FESPI_RX_BSY ) == 0 ) {
384+ break ;
353385 }
354386 }
387+ fespi_csmode_auto ();
388+ fespi_sw_setdir (FESPI_DIR_TX );
355389}
356390
391+ static uint32_t fespi_flash_probe (void );
357392
358393void hifive1_init (uint32_t cpu_clock , uint32_t uart_baud )
359394{
@@ -410,6 +445,9 @@ void hifive1_init(uint32_t cpu_clock, uint32_t uart_baud)
410445
411446 /* Reconfigure the SPI to maximum frequency */
412447 fespi_init (cpu_clock , MAX_FLASH_FREQ );
448+
449+ /* Probe the FESPI flash */
450+ (void )fespi_flash_probe ();
413451
414452 /* Reconfigure the UART */
415453 uart_init (cpu_clock , uart_baud );
@@ -434,30 +472,26 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
434472 int i ;
435473 uint32_t off = address & 0xFF ;
436474 uint32_t page = address >> 8 ;
437- fespi_wait_txwm () ;
475+ FESPI_REG_TXMARK = 1 ;
438476 fespi_swmode ();
477+ fespi_wait_flash_busy ();
439478
440479 while ((page * FLASH_PAGE_SIZE ) < (address + len )) {
441- fespi_wait_flash_busy ();
442- fespi_wait_txwm ();
443- fespi_sw_setdir (FESPI_DIR_TX );
480+ fespi_write_enable ();
444481 fespi_csmode_hold ();
445- fespi_sw_tx (FESPI_WRITE_ENABLE );
446482 fespi_sw_tx (FESPI_PAGE_PROGRAM );
483+ fespi_wait_txwm ();
447484 fespi_write_address ((page << 8 ) + off );
448485 for (i = off ; i < FLASH_PAGE_SIZE ; i ++ ) {
449486 fespi_sw_tx (data [i ]);
450487 }
451488 fespi_csmode_auto ();
452- fespi_sw_setdir (FESPI_DIR_RX );
453- fespi_wait_txwm ();
489+ fespi_wait_write_disabled ();
454490 page ++ ;
455491 data += FLASH_PAGE_SIZE ;
456492 off = 0 ;
457493 }
458- fespi_wait_flash_writing ();
459494 fespi_hwmode ();
460-
461495 return 0 ;
462496}
463497
@@ -469,23 +503,46 @@ void RAMFUNCTION hal_flash_lock(void)
469503{
470504}
471505
506+ static uint32_t RAMFUNCTION fespi_flash_probe (void )
507+ {
508+ uint32_t rx ;
509+
510+ FESPI_REG_TXMARK = 1 ;
511+ fespi_sw_setdir (FESPI_DIR_RX );
512+ fespi_swmode ();
513+
514+ fespi_wait_txwm ();
515+ fespi_wait_flash_busy ();
516+ fespi_sw_setdir (FESPI_DIR_RX );
517+ fespi_csmode_hold ();
518+ fespi_sw_tx (FESPI_READ_ID );
519+ fespi_sw_tx (0 );
520+ fespi_sw_tx (0 );
521+ fespi_sw_tx (0 );
522+ rx = fespi_sw_rx ();
523+ rx |= fespi_sw_rx () << 8 ;
524+ rx |= fespi_sw_rx () << 16 ;
525+ fespi_csmode_auto ();
526+ fespi_sw_setdir (FESPI_DIR_TX );
527+ return rx ;
528+ }
529+
472530int RAMFUNCTION hal_flash_erase (uint32_t address , int len )
473531{
474532 uint32_t end = address + len - 1 ;
475533 uint32_t p ;
476- FESPI_REG_TXMARK = 1 ;
534+
477535 fespi_wait_txwm ();
536+ FESPI_REG_TXMARK = 1 ;
478537 fespi_swmode ();
479538 fespi_wait_flash_busy ();
480539
540+
481541 for (p = address ; p <= end ; p += FESPI_FLASH_SECTOR_SIZE ) {
482- fespi_sw_tx (FESPI_WRITE_ENABLE );
483- fespi_wait_txwm ();
542+ fespi_write_enable ();
484543 fespi_csmode_hold ();
485- fespi_sw_setdir (FESPI_DIR_TX );
486544 fespi_sw_tx (FESPI_ERASE_SECTOR );
487545 fespi_write_address (p );
488- fespi_sw_setdir (FESPI_DIR_RX );
489546 fespi_wait_txwm ();
490547 fespi_csmode_auto ();
491548 fespi_wait_flash_busy ();
0 commit comments