@@ -2546,6 +2546,7 @@ void jshFlashRead(void * buf, uint32_t addr, uint32_t len) {
2546
2546
* Writes an array of bytes to memory. Addr must be word aligned and len must be a multiple of 4.
2547
2547
*/
2548
2548
void jshFlashWrite (void * buf , uint32_t addr , uint32_t len ) {
2549
+ assert ((len & 3 )== 0 ); // ensure we're always a multiple of 4 long
2549
2550
//jsiConsolePrintf("\njshFlashWrite 0x%x addr 0x%x -> 0x%x, len %d\n", *(uint32_t*)buf, (uint32_t)buf, addr, len);
2550
2551
#ifdef SPIFLASH_BASE
2551
2552
if ((addr >= SPIFLASH_BASE ) && (addr < (SPIFLASH_BASE + SPIFLASH_LENGTH ))) {
@@ -2639,40 +2640,42 @@ void jshFlashWrite(void * buf, uint32_t addr, uint32_t len) {
2639
2640
if (jshFlashWriteProtect (addr )) return ;
2640
2641
uint32_t err = 0 ;
2641
2642
2642
- if (((size_t )(char * )buf )& 3 ) {
2643
- /* Unaligned *SOURCE* is a problem on nRF5x,
2644
- * so if so we are unaligned, do a whole bunch
2645
- * of tiny writes via a buffer */
2646
- while (len >=4 && !err ) {
2647
- flashIsBusy = true;
2648
- uint32_t alignedBuf ;
2649
- memcpy (& alignedBuf , buf , 4 );
2650
- while ((err = sd_flash_write ((uint32_t * )addr , & alignedBuf , 1 )) == NRF_ERROR_BUSY );
2651
- if (err != NRF_SUCCESS ) flashIsBusy = false;
2652
- WAIT_UNTIL (!flashIsBusy , "jshFlashWrite" );
2653
- len -= 4 ;
2654
- addr += 4 ;
2655
- buf = (void * )(4 + (char * )buf );
2656
- }
2657
- } else {
2658
- flashIsBusy = true;
2659
- uint32_t wordOffset = 0 ;
2660
- while (len > 0 && !jspIsInterrupted ()) {
2661
- uint32_t l = len ;
2643
+ uint32_t wraddr = addr , wrlen = len ; // destination + length, we increment these as we write
2644
+ uint8_t * wrbuf = (uint8_t * )buf ; // source, we increment this as we write
2645
+ uint8_t alignedBuf [32 ]; // aligned buffer if writes need it (misaligned source)
2646
+
2647
+ while (wrlen > 0 && !jspIsInterrupted ()) {
2648
+ uint32_t l = wrlen ;
2649
+ uint8_t * awrbuf = wrbuf ; // write buffer pointer (always updated to be aligned)
2662
2650
#ifdef NRF51_SERIES
2663
- if (l > 1024 ) l = 1024 ; // max write size
2651
+ if (l > 1024 ) l = 1024 ; // max write size
2664
2652
#else // SD 6.1.1 doesn't like flash ops that take too long so we must not write the full 4096 (probably a good plan on older SD too)
2665
- if (l > 2048 ) l = 2048 ; // max write size
2653
+ if (l > 2048 ) l = 2048 ; // max write size
2666
2654
#endif
2667
- len -= l ;
2668
- while ((err = sd_flash_write (((uint32_t * )addr )+ wordOffset , ((uint32_t * )buf )+ wordOffset , l >>2 )) == NRF_ERROR_BUSY && !jspIsInterrupted ());
2669
- wordOffset += l >>2 ;
2655
+ if ((size_t )wrbuf & 3 ) {
2656
+ // Unaligned *SOURCE* is a problem on nRF5x, so if so we are unaligned, do a whole bunch of tiny writes via a buffer
2657
+ if (l > sizeof (alignedBuf )) l = sizeof (alignedBuf ); // max write size
2658
+ memcpy (alignedBuf , wrbuf , l );
2659
+ awrbuf = wrbuf ;
2670
2660
}
2661
+
2662
+ flashIsBusy = true;
2663
+ while ((err = sd_flash_write (wraddr , awrbuf , l >>2 )) == NRF_ERROR_BUSY && !jspIsInterrupted ());
2671
2664
if (err != NRF_SUCCESS ) flashIsBusy = false;
2672
2665
WAIT_UNTIL (!flashIsBusy , "jshFlashWrite" );
2666
+ wrlen -= l ;
2667
+ wraddr += l ;
2668
+ wrbuf += l ;
2673
2669
}
2674
2670
if (err != NRF_SUCCESS )
2675
2671
jsExceptionHere (JSET_INTERNALERROR ,"NRF ERROR 0x%x" , err );
2672
+ /* // (slow!) sanity check to ensure that all data is written correctly:
2673
+ for (int i=0;i<len;i++) {
2674
+ uint8_t a = ((uint8_t*)addr)[i];
2675
+ uint8_t b = ((uint8_t*)buf)[i];
2676
+ if (a!=b)
2677
+ jsiConsolePrintf("Write failed at 0x%08x+%d %d!=%d\n", addr,i, a,b);
2678
+ }*/
2676
2679
}
2677
2680
2678
2681
// Just pass data through, since we can access flash at the same address we wrote it
0 commit comments