@@ -52,7 +52,16 @@ using namespace mbed;
52
52
#define OSPIF_NO_QUAD_ENABLE (-1 )
53
53
54
54
// Configuration Register2 address
55
- #define OSPIF_CR2_OPI_EN_ADDR 0x00000000
55
+ #define OSPIF_CR2_OPI_EN_ADDR 0x00000000
56
+ #define OSPIF_CR2_BANK_STATUS_ADDR 0xc0000000
57
+ #define OSPIF_CR2_RWWDI ((uint8_t )0x00 ) /* !< No active program or erase operation */
58
+ #define OSPIF_CR2_RWWDS ((uint8_t )0x01 ) /* !< Program/erase in other bank */
59
+ #define OSPIF_CR2_RWWBS ((uint8_t )0x03 ) /* !< program/erase operation in addressed bank */
60
+
61
+ #ifdef MX_FLASH_SUPPORT_RWW
62
+ #define MX25LM51245G_BANK_SIZE 0x01000000 /* 16 MBytes */
63
+ #define MX25LM51245G_BANK_SIZE_MASK ~(MX25LM51245G_BANK_SIZE - 1 ) /* 0xFF000000 */
64
+ #endif
56
65
57
66
/* SFDP Header Parsing */
58
67
/* **********************/
@@ -232,6 +241,11 @@ OSPIFBlockDevice::OSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
232
241
_attempt_4_byte_addressing = true ;
233
242
_4byte_msb_reg_write_inst = OSPIF_INST_4BYTE_REG_WRITE_DEFAULT;
234
243
_support_4_byte_inst = false ;
244
+
245
+ #ifdef MX_FLASH_SUPPORT_RWW
246
+ _wait_flag = NOT_STARTED;
247
+ _busy_bank = 0xffffffff ;
248
+ #endif
235
249
}
236
250
237
251
int OSPIFBlockDevice::init ()
@@ -358,6 +372,17 @@ int OSPIFBlockDevice::deinit()
358
372
return result;
359
373
}
360
374
375
+ if (false == _is_mem_ready ()) {
376
+ tr_error (" Device not ready after write, failed" );
377
+ /* program_failed = true;
378
+ status = OSPIF_BD_ERROR_READY_FAILED;
379
+ goto exit_point;*/
380
+ }
381
+
382
+ #ifdef MX_FLASH_SUPPORT_RWW
383
+ _wait_flag = NOT_STARTED;
384
+ #endif
385
+
361
386
change_mode (SPI);
362
387
363
388
// Disable Device for Writing
@@ -383,6 +408,29 @@ int OSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
383
408
int status = OSPIF_BD_ERROR_OK;
384
409
tr_debug (" Read Inst: 0x%xh" , _read_instruction);
385
410
411
+ #ifdef MX_FLASH_SUPPORT_RWW
412
+ bool need_wait;
413
+ need_wait = (_wait_flag != NOT_STARTED) && ((addr & MX25LM51245G_BANK_SIZE_MASK) == _busy_bank);
414
+
415
+ // Wait for ready
416
+ if (need_wait) {
417
+
418
+ _busy_mutex.lock ();
419
+
420
+ if (_is_mem_ready_rww (addr, false ) == false ) {
421
+ return OSPIF_BD_ERROR_OK;
422
+ }
423
+
424
+ } else {
425
+ if (_wait_flag == WRITE_WAIT_STARTED) {
426
+ tr_debug (" \r\n RWW1 CNT" );
427
+ } else if (_wait_flag == ERASE_WAIT_STARTED) {
428
+ tr_debug (" \r\n RWE2 CNT" );
429
+ }
430
+ }
431
+
432
+ #endif
433
+
386
434
_mutex.lock ();
387
435
388
436
// In DOPI mode, the number of read data should be even
@@ -397,8 +445,13 @@ int OSPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
397
445
398
446
_mutex.unlock ();
399
447
400
- return status;
448
+ #ifdef MX_FLASH_SUPPORT_RWW
449
+ if (need_wait) {
450
+ _busy_mutex.unlock ();
451
+ }
452
+ #endif
401
453
454
+ return status;
402
455
}
403
456
404
457
int OSPIFBlockDevice::program (const void *buffer, bd_addr_t addr, bd_size_t size)
@@ -418,6 +471,16 @@ int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
418
471
chunk = (offset + size < _page_size_bytes) ? size : (_page_size_bytes - offset);
419
472
written_bytes = chunk;
420
473
474
+ #ifdef MX_FLASH_SUPPORT_RWW
475
+ _busy_mutex.lock ();
476
+
477
+ // Wait for ready
478
+ if (_is_mem_ready_rww (addr, true ) == false ) {
479
+ return OSPIF_BD_ERROR_OK;
480
+ }
481
+
482
+ #endif
483
+
421
484
_mutex.lock ();
422
485
423
486
// Send WREN
@@ -437,17 +500,26 @@ int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
437
500
goto exit_point;
438
501
}
439
502
440
- buffer = static_cast <const uint8_t *>(buffer) + chunk;
441
- addr += chunk;
442
- size -= chunk;
503
+ #ifdef MX_FLASH_SUPPORT_RWW
504
+ _wait_flag = WRITE_WAIT_STARTED;
505
+ _busy_bank = addr & MX25LM51245G_BANK_SIZE_MASK;
506
+
507
+ _mutex.unlock ();
443
508
509
+ _busy_mutex.unlock ();
510
+ #else
444
511
if (false == _is_mem_ready ()) {
445
512
tr_error (" Device not ready after write, failed" );
446
513
program_failed = true ;
447
514
status = OSPIF_BD_ERROR_READY_FAILED;
448
515
goto exit_point;
449
516
}
450
517
_mutex.unlock ();
518
+ #endif
519
+
520
+ buffer = static_cast <const uint8_t *>(buffer) + chunk;
521
+ addr += chunk;
522
+ size -= chunk;
451
523
}
452
524
453
525
exit_point:
@@ -511,6 +583,15 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
511
583
tr_debug (" Erase - Region: %d, Type:%d " ,
512
584
region, type);
513
585
586
+ #ifdef MX_FLASH_SUPPORT_RWW
587
+ _busy_mutex.lock ();
588
+
589
+ // Wait for ready
590
+ if (_is_mem_ready_rww (addr, true ) == false ) {
591
+ return OSPIF_BD_ERROR_OK;
592
+ }
593
+ #endif
594
+
514
595
_mutex.lock ();
515
596
516
597
if (_set_write_enable () != 0 ) {
@@ -527,15 +608,14 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
527
608
goto exit_point;
528
609
}
529
610
530
- addr += eu_size;
531
- size -= eu_size;
611
+ #ifdef MX_FLASH_SUPPORT_RWW
612
+ _wait_flag = ERASE_WAIT_STARTED;
613
+ _busy_bank = addr & MX25LM51245G_BANK_SIZE_MASK;
532
614
533
- if ((size > 0 ) && (addr > _sfdp_info.smptbl .region_high_boundary [region])) {
534
- // erase crossed to next region
535
- region++;
536
- bitfield = _sfdp_info.smptbl .region_erase_types_bitfld [region];
537
- }
615
+ _mutex.unlock ();
538
616
617
+ _busy_mutex.unlock ();
618
+ #else
539
619
if (false == _is_mem_ready ()) {
540
620
tr_error (" OSPI After Erase Device not ready - failed" );
541
621
erase_failed = true ;
@@ -544,6 +624,16 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
544
624
}
545
625
546
626
_mutex.unlock ();
627
+ #endif
628
+
629
+ addr += eu_size;
630
+ size -= eu_size;
631
+
632
+ if ((size > 0 ) && (addr > _sfdp_info.smptbl .region_high_boundary [region])) {
633
+ // erase crossed to next region
634
+ region++;
635
+ bitfield = _sfdp_info.smptbl .region_erase_types_bitfld [region];
636
+ }
547
637
}
548
638
549
639
exit_point:
@@ -1537,6 +1627,51 @@ bool OSPIFBlockDevice::_is_mem_ready()
1537
1627
return mem_ready;
1538
1628
}
1539
1629
1630
+ #ifdef MX_FLASH_SUPPORT_RWW
1631
+ bool OSPIFBlockDevice::_is_mem_ready_rww (bd_addr_t addr, uint8_t rw)
1632
+ {
1633
+ uint16_t cr2_value = 0 ;
1634
+ bool mem_ready = true ;
1635
+ static uint32_t rww_cnt = 0 ; // For testing
1636
+ static uint32_t rwe_cnt = 0 ; // For testing
1637
+
1638
+ bd_addr_t bank_addr = addr & MX25LM51245G_BANK_SIZE_MASK;
1639
+
1640
+ if ((_wait_flag == NOT_STARTED) || (!rw && bank_addr != _busy_bank)) {
1641
+ return mem_ready;
1642
+ }
1643
+ // Read CR2 Register 1 from device, the number of read byte need to be even in octa flash DOPI mode
1644
+ if (OSPI_STATUS_OK != _ospi_send_general_command (OSPIF_INST_RDCR2, bank_addr + OSPIF_CR2_BANK_STATUS_ADDR,
1645
+ NULL , 0 ,
1646
+ (char *) &cr2_value, OSPI_DEFAULT_STATUS_REGISTERS)) { // store received value in cr2_value
1647
+ tr_error (" Reading CR2 Register failed" );
1648
+ }
1649
+
1650
+ cr2_value &= OSPIF_CR2_RWWBS;
1651
+
1652
+ if ((cr2_value == OSPIF_CR2_RWWBS) || (rw && (cr2_value == OSPIF_CR2_RWWDS))) {
1653
+
1654
+ // Wait until device ready
1655
+ if (false == _is_mem_ready ()) {
1656
+ tr_error (" _is_mem_ready Failed" );
1657
+ mem_ready = false ;
1658
+ }
1659
+ _wait_flag = NOT_STARTED;
1660
+ } else if (!rw && (cr2_value == OSPIF_CR2_RWWDS)) {
1661
+ // For testing
1662
+ if (_wait_flag == WRITE_WAIT_STARTED) {
1663
+ rww_cnt++;
1664
+ tr_debug (" rww_cnt = 0x%x " , rww_cnt);
1665
+ } else {
1666
+ rwe_cnt++;
1667
+ tr_debug (" rwe_cnt = 0x%x " , rwe_cnt);
1668
+ }
1669
+ }
1670
+
1671
+ return mem_ready;
1672
+ }
1673
+ #endif
1674
+
1540
1675
/* **************************************************/
1541
1676
/* ********** OSPI Driver API Functions *************/
1542
1677
/* **************************************************/
@@ -1665,9 +1800,12 @@ ospi_status_t OSPIFBlockDevice::_ospi_send_general_command(ospi_inst_t instructi
1665
1800
if ((_inst_width == OSPI_CFG_BUS_OCTA) || (_inst_width == OSPI_CFG_BUS_OCTA_DTR)) {
1666
1801
if ((instruction == OSPIF_INST_RSR1) || (instruction == OSPIF_INST_RDID) ||
1667
1802
(instruction == OSPIF_INST_RDCR2) || (instruction == OSPIF_INST_RDCR)) {
1668
- _ospi.configure_format (_inst_width, _inst_size, _address_width, _address_size, OSPI_CFG_BUS_SINGLE, 0 , _data_width, _dummy_cycles);
1669
- addr = 0 ;
1670
- } else if (instruction == OSPIF_INST_WSR1) {
1803
+ _ospi.configure_format (_inst_width, _inst_size, _address_width, _address_size, OSPI_CFG_BUS_SINGLE,
1804
+ 0 , _data_width, 4 );
1805
+ if (instruction != OSPIF_INST_RDCR2) {
1806
+ addr = 0 ;
1807
+ }
1808
+ } else if ((instruction == OSPIF_INST_WSR1)) {
1671
1809
addr = 0 ;
1672
1810
}
1673
1811
}
0 commit comments