Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 29

Thread: Another PSRAM option - Lyontek LY68L6400S

Hybrid View

  1. #1

    Another PSRAM option - Lyontek LY68L6400S

    I have seen the LY68L6400S mentioned before, but found no confirmation if they were in fact a valid alternate so I brought some in to test since chip shortages are going to be around for awhile.

    These appear to be the exact same as the ESP PSRAM64H and have the same chip ID.

    You do want the 'S' version for the SOIC. The 'B' version is the WSON package. Here is the Datasheet

    Tested 5 chips on 5 Teensy 4.1 using the standard PJRC teensy41_psram_memtest and they work fine.

    Available from LCSC, Aliexpress and ProtoSupplies.com will be adding them to our mix of products as well.

    Click image for larger version. 

Name:	Lyontek Ly68L6400S Test on Teensy 4.1.jpg 
Views:	27 
Size:	155.5 KB 
ID:	25060

    --- Ken

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    @KenHahn > Good news for an available and alternate chip!

    That chip is not an alternative mentioned here :: https://www.pjrc.com/store/psram.html

    Paul made a note somewhere recently about the PSRAM ++cost and --availability change to PJRC.

  3. #3
    I'd be happy to send some to Paul if he would like to test them himself and add them to his approved alternate list. Not sure if there is a more strenuous test than the standard memtest that can be run to better test performance boundaries.

    Regarding chip shortages, my wife is an executive with a fairly large EMS that that specializes in aerospace, medical and military type applications. Chip shortages are causing havoc across the board and prices are going up. I have even seen some crazy price increases lately on some of the standard stuff coming out of China that you wouldn't think would be affected much.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,244
    Quote Originally Posted by KenHahn View Post
    I'd be happy to send some to Paul if he would like to test them himself and add them to his approved alternate list.
    Sure. Send me just 2 chips. I'll solder one to a Teensy 4.1 and run the memory test. Assuming it passes, I'll use the other for a photo to add to the PSRAM page. The 3 photos on the page today are the 3 chips I have personally tested. PJRC is currently shipping the Espressif chip, but we've purchased Ap Memory parts and will switch to those when the Espressif parts run out.

    I'm pretty sure all of these various 8 MB QSPI PSRAM chips are really the same chip made by Ap Memory and then printed with different part numbers for different buyers.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Hi Ken - Had to look up 'Electronic Manufacturing Services for Defense & Military' ... Ambulances and Firetrucks for E.M.S. didn't match with Space and Military

    This chip drought is really widespread - like lots of other markets demand/supply imbalance - only different reasons and challenges to just make more.

    If you wanted to test PSRAM on your end and have installed TD 1.54 Beta 9 - running {arduino_install}\hardware\teensy\avr\libraries\Li ttleFS\examples\LFSintegrity\LFSintegrity.ino

    Here is a T_4.1 with twin 8MB 'IPUS' PSRAMS giving these results. Running this will repeatedly cycle across all of the PSRAM address space with writes and reads and some degree of verification that would be caught as FS failing to track files or file content, and below some idea of the expected throughput rates Read and Write.

    Testing with 1 chip installed would be:
    Code:
    //#include <LittleFS.h>
    #include <LittleFS_NAND.h>
    
    #define HALFCUT  // HALFCUT defined to fill half the disk
    //#define ROOTONLY // NORMAL is NOT DEFINED!
    #define NUMDIRS 32  // When not ROOTONLY must be 1 or more
    #define MYPSRAM 8	// compile time PSRAM size
    #define MYBLKSIZE 2048 // 2048
    //#define SHOW_YIELD_CNT  1 // uncommented shows calls to Yield per second
    
    #define TEST_RAM
    //#define TEST_SPI
    //#define TEST_QSPI
    //#define TEST_SPI_NAND
    //#define TEST_QSPI_NAND
    //#define TEST_PROG
    //#define TEST_MRAM
    ...
    > 8MB will run out of room and halt with out of space
    Change : #define MAXNUM 26 // ALPHA A-Z is 26, less for fewer files
    to perhaps : #define MAXNUM 18 // ALPHA A-Z is 26, less for fewer files


    or with two soldered:
    Code:
    //#include <LittleFS.h>
    #include <LittleFS_NAND.h>
    
    #define HALFCUT  // HALFCUT defined to fill half the disk
    //#define ROOTONLY // NORMAL is NOT DEFINED!
    #define NUMDIRS 32  // When not ROOTONLY must be 1 or more
    #define MYPSRAM 16	// compile time PSRAM size
    #define MYBLKSIZE 2048 // 2048
    //#define SHOW_YIELD_CNT  1 // uncommented shows calls to Yield per second
    
    #define TEST_RAM
    //#define TEST_SPI
    //#define TEST_QSPI
    //#define TEST_SPI_NAND
    //#define TEST_QSPI_NAND
    //#define TEST_PROG
    //#define TEST_MRAM
    ...
    When it starts in SerMon hit Enter to create folders and start.
    'k' : run 1,000 loop iterations of file create, extend, delete
    '0' : Zero the loops to run and stop ongoing iterations
    'd' : dir of image
    'B' : one or more times to fill half of remaining disk space
    Big write /0_bigfile.txt took 0.97 Sec for 4169728 Bytes : file3.size()=4169728
    Big write KBytes per second 4289.39

    Bytes Used: 4190208, Bytes Total:8388608
    'b' : Remove those 'B'ig files
    Delete with read verify all #bigfile's
    Verify /0_bigfile.txt bytes 4169728 : .................................................. GOOD! >> bytes 4169728
    Big read&compare KBytes per second 2317.94
    'S' : one or more times to alloc 2MB files
    's' : Remove any 'S' files
    'g' : run speedBench() - output on chips here:
    RAM_DISK Benchmark:
    FILE_SIZE = 16384
    BUF_SIZE = 2048 bytes
    Starting write test, please wait.

    write speed and latency
    speed,max,min,avg
    KB/Sec,usec,usec,usec
    4096.00,553,477,488
    4096.00,553,437,473
    4096.00,522,440,459
    5461.33,541,446,470
    4096.00,545,460,484

    Starting sequential read test, please wait.

    read speed and latency
    speed,max,min,avg
    KB/Sec,usec,usec,usec
    83167.52,65,6,24
    178086.95,30,5,11
    260063.48,16,5,7
    315076.94,13,5,6
    334367.34,10,5,6

  6. #6
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,699
    the one difference I see in the from looking at the datasheets is the max clock speed. It looks like for the Lyontek LY68L6400S the clock is maxed at 100Mhz while for the ESP its at 133 Mhz. This shouldn't be a problem as the default clock is set at 88Mhz. We have tested the ESP chips up to pretty close to the max and it worked. Only warning would be not to exceed 100Mhz in your apps.

  7. #7
    mjs513, the datasheet I linked to from LCSC site is Rev 0.7 and shows 144MHz max data rate. There is an older datasheet I have come across that showed 100MHz, so I think they updated it at some point. The actual Lyontek website doesn't currently show a datasheet I could find and they list the part as sampling, though they are clearly shipping.

    Paul, chips are in the mail. Should have them tomorrow.

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    @mjs513 - I see above code does duplicate Mount as written ... but it works ... and gives the Idea
    Code:
    		if (lfs_mount(&lfs, &config) < 0) {
    			memset(ptr, 0xFF, size); // always start with blank slate
    			if (lfs_format(&lfs, &config) < 0) return false;
    			if (lfs_mount(&lfs, &config) < 0) return false;
    		}
    Does this seem like a good change to make? Seems to me it could add value to a running system that might encounter an intermittent error or Warm Restart and not present total data loss.

    Repeating the test in p#4 it 'generally' works after "R"estart Teensy. But there is something in the LittleFS not surviving?
    Code:
    printDirectory RAM_DISK
    --------------
    FILE	0_2MBfile.txt		2048000
    FILE	0_bigfile.txt		4169728
    
     0 dirs with 2 files of Size 6217728 Bytes
     Total 2 files of Size 6217728 Bytes
    Bytes Used: 6246400, Bytes Total:8388608
    
    
    	 Loop Count: 7 (#fileCycle=0), Bytes read 1763328, written 0, #Files=2
    	dirV...113_us	[  1.21 M](0.00024 M elap) Awaiting input 0123456789RdwcghkFqvplmusSBbyYxfan+-? loops left 0 >
    
    [  1.21 M](0.00024 M elap) Awaiting input 0123456789RdwcghkFqvplmusSBbyYxfan+-? loops left 0 > RESTART Teensy ...
    T:\arduino-1.8.15\hardware\teensy\avr\libraries\LittleFS\examples\LFSintegrity\LFSintegrity.ino Jun 17 2021 11:34:43
    LittleFS Test : File Integrity
    printDirectory RAM_DISK
    --------------
    FILE	0_2MBfile.txt		0
    FILE	0_bigfile.txt		4169728
    Maybe there is LittleFS data in the Cache not yet pushed to the PSRAM?

    YES :: Putting this in "R" for software Restart fixes the issue :: arm_dcache_flush_delete(buf, MYPSRAM * 1024 * 1024 );

    .flush() is a LittleFS virtual function.
    The User Sketch would need to call this to allow TyComm/Reset or other WarmRestart to assure data integrity

    @mjs513 - can you see how to add that .flush() function to class LittleFS_RAM : public LittleFS, where it adds the arm_dcache_flush_delete()?
    Last edited by defragster; 06-17-2021 at 07:54 PM. Reason: add to final line

  9. #9
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,699
    Quote Originally Posted by KenHahn View Post
    mjs513, the datasheet I linked to from LCSC site is Rev 0.7 and shows 144MHz max data rate. There is an older datasheet I have come across that showed 100MHz, so I think they updated it at some point. The actual Lyontek website doesn't currently show a datasheet I could find and they list the part as sampling, though they are clearly shipping.

    Paul, chips are in the mail. Should have them tomorrow.
    Thanks for the clarification will have pick up a few

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    @mjs513 - running test noted p#4 - when a 'R'estart the myfs fails to survive?

    Across a warm restart the EXTMEM/PSRAM image will be present ...

    It seems - IIRC - SPIFFS on PSRAM would survive warm restart.

    Making these changes allows PSRAM Warm Restart to survive data.

    This will never happen on RAM1 - though it would also work on RAM2 with DMAMEM as 'static' on Warm Restart.

    If a USER Sketch does not want this behavior - then setup() could add ::
    Code:
    	if (!myfs.begin(buf, sizeof(buf))) {
    	  ...
    	}
    	myfs.quickFormat();
    T:\arduino-1.8.15\hardware\teensy\avr\libraries\LittleFS\src\ LittleFS.h
    Code:
    class LittleFS_RAM : public LittleFS
    {
    public:
    	LittleFS_RAM() { }
    	bool begin(uint32_t size) {
    #if defined(__IMXRT1062__)
    		return begin(extmem_malloc(size), size);
    #else
    		return begin(malloc(size), size);
    #endif
    	}
    	bool begin(void *ptr, uint32_t size) {
    		//Serial.println("configure "); delay(5);
    		configured = false;
    		if (!ptr) return false;
    //		memset(ptr, 0xFF, size); // always start with blank slate
    		size = size & 0xFFFFFF00;
    		memset(&lfs, 0, sizeof(lfs));
    		memset(&config, 0, sizeof(config));
    		config.context = ptr;
    		config.read = &static_read;
    		config.prog = &static_prog;
    		config.erase = &static_erase;
    		config.sync = &static_sync;
    		if ( size > 1024 * 1024 ) {
    			config.read_size = 256; // Must set cache_size. If read_buffer or prog_buffer are provided manually, these must be cache_size.
    			config.prog_size = 256;
    			config.block_size = 2048;
    			config.block_count = size / config.block_size;
    			config.block_cycles = 900;
    			config.cache_size = 256;
    			config.lookahead_size = 512; // (config.block_count / 8 + 7) & 0xFFFFFFF8;
    		}
    		else {
    			config.read_size = 64;
    			config.prog_size = 64;
    			config.block_size = 256;
    			config.block_count = size / 256;
    			config.block_cycles = 50;
    			config.cache_size = 64;
    			config.lookahead_size = 64;
    		}
    		config.name_max = LFS_NAME_MAX;
    		config.file_max = 0;
    		config.attr_max = 0;
    		configured = true;
    		if (lfs_mount(&lfs, &config) < 0) {
    			memset(ptr, 0xFF, size); // always start with blank slate
    			if (lfs_format(&lfs, &config) < 0) return false;
    		}
    		//Serial.println("formatted");
    		if (lfs_mount(&lfs, &config) < 0) return false;
    		//Serial.println("mounted atfer format");
    		mounted = true;
    		return true;
    	}
    ...

  11. #11
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,699
    @defragster
    Will take a look at that. Didnít do much with the psram. That chuck was Paul. Canít remember about spiffs Ö was way too long ago now.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Oh yeah - That was Paul on Release Day ...

    Yes, SPIFFS is a forgotten memory ... but I do recall ... IIRC ... it survived warm restarts as written.

    @Paul this could improve the usability or debugability when a user uses RAM2 or PSRAM for fast 'temp' storage. Is it worth working through this?

    @mjs513 - this seems to be working:
    Code:
    class LittleFS_RAM : public LittleFS
    {
    public:
    	LittleFS_RAM() { }
    	bool begin(uint32_t size) {
    #if defined(__IMXRT1062__)
    		return begin(extmem_malloc(size), size);
    #else
    		return begin(malloc(size), size);
    #endif
    	}
    ...	FLASHMEM
    	uint32_t formatUnused(uint32_t blockCnt, uint32_t blockStart) {
    		return 0;
    	}
    	void flush() {
    		Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", config.context, config.block_count * config.block_size);
    		arm_dcache_flush_delete(config.context, config.block_count * config.block_size );
    	}
    
    But this "FILE" got lost as I did it moving from the virtual function:
    Code:
    class LittleFSFile : public File
    ...
    	virtual void flush() {
    		if (file) lfs_file_sync(lfs, file);
    	}
    LFSIntegrity was HANDY to find the Error - it was showing '0xFF' found for file data not expected - which showed the formatted block not written because the data cache was not Flushed.

    This data cache flush - when called - would prevent that to allow warm restart to survive with FS intact.

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,244
    Quote Originally Posted by defragster View Post
    @Paul this could improve the usability or debugability when a user uses RAM2 or PSRAM for fast 'temp' storage. Is it worth working through this?
    Flushing the CPU cache does make sense for the ramdisk. But it should be done from the static_sync() function, not with an API addition at the filesystem level.

    Code:
            static int static_sync(const struct lfs_config *c) {
                    // flush cache here
                    return 0;
            }

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Quote Originally Posted by PaulStoffregen View Post
    Flushing the CPU cache does make sense for the ramdisk. But it should be done from the static_sync() function, not with an API addition at the filesystem level.

    Code:
            static int static_sync(const struct lfs_config *c) {
                    // flush cache here
                    return 0;
            }
    Thanks Paul - You are correct!

    ... an hour later I just now see your post and see I went the right direction ... and have it working.

    The other half of the change is to not assume the RAM disk always needs to be started with a fresh format. In the case of RAM1 that still happens as Zeroed Ram1 will never mount. But for RAM2 and PSRAM they have some static properties across reset, restart and reprogram when those areas stay powered.

  15. #15
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,699
    Quote Originally Posted by defragster
    @mjs513 - if you are bored and want to have some fun - let me know if you can give this a try.
    Usually not bored, only sometimes.

    Definitely think its worth trying and adding if it works. I will download and give the new LittleFS.h a try that you posted in #16

  16. #16
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Quote Originally Posted by mjs513 View Post
    Usually not bored, only sometimes.

    Definitely think its worth trying and adding if it works. I will download and give the new LittleFS.h a try that you posted in #16
    bored ... i KNEW that wasn't the case

    Code:
    I see it as viewed now but here is the current version with the no flush on RAM1 : LittleFS.h
    Tested here with LFSIntegrity.ino - not sure if there were any other real world like examples to play with?

    But as noted that sketch did good telling me when I had issues and allows for lots of File I/O in some fashion : # loop iterations and the B and S file creation.

    BTW - tried the B on the RAM1 drive and that was a FAIL because of the small 256 Byte alloc units at 390KB of RAM1. I see it does use 2048 over 1MB in use.

    Of course my github is a mess ... not sure if we had any other pending changes ....

  17. #17
    Administrator Paul's Avatar
    Join Date
    Oct 2012
    Posts
    418
    Reopening this thread. Not sure why it got closed. Maybe a mistake?

  18. #18
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Quote Originally Posted by Paul View Post
    Reopening this thread. Not sure why it got closed. Maybe a mistake?
    Thanks, Might have been browser spasm here - was typing a reply and 'focus' was not in the post area ... may have tabbed back and had focus on that check box ... opps.


    Tested against RAM2 :: DMAMEM char buf[490000];

    Again generally works - except without 'file *' flush the lfs core hasn't updated the DIR entry it seems and file size on 'B'igfile write is not correct and LFSIntegrity catches an error.

    LFSIntegrity was not doing ANY FLUSH( file ) - perhaps it should have been - though it is clear when data is not flushed errors are detected.

    Using the obvious seeming FLUSH() was a fail ...


    >> FIXED ?????
    Making a change like this seems to be working with no added code on user part as this is called by the lfs core code as needed, even across a 'Hardware' driven reset with TyComm/Reset:
    Code:
    class LittleFS_RAM : public LittleFS
    {
    ...
    private:
    ...
    	static int static_sync(const struct lfs_config *c) {
    		Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
    		arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
    		return 0;
    	}
    Here is above code showing the PRINT on creating a BigFile - tested an DMAMEM and here on PSRAM:
    Code:
     RAM_DISK +++ Add [sz 0 add 5120] @KB/sec 800.38 {524.81}  ++ I   Verify /I_file.txt 5120B  @KB/sec 2348.62 
    :: /J_file.txt     arm_dcache_flush_delete: ptr=0x70000000, size=8388608
        arm_dcache_flush_delete: ptr=0x70000000, size=8388608
     RAM_DISK +++ Add [sz 0 add 5632] @KB/sec 920.86 {595.41}  ++ J   Verify /J_file.txt 5632B  @KB/sec 2321.52 
    :: /A_file.txt     arm_dcache_flush_delete: ptr=0x70000000, size=8388608
        arm_dcache_flush_delete: ptr=0x70000000, size=8388608
     RAM_DISK +++ Add [sz 0 add 6144] @KB/sec 954.48 {624.77}  ++ A   Verify /A_file.txt 6144B  @KB/sec 2308.04 
    [  0.10 M](0.01127 M elap) Awaiting input 0123456789RdwcghkFqvplmusSBbyYxfan+-? loops left 0 >
    Start Big write of 4147200 Bytes    arm_dcache_flush_delete: ptr=0x70000000, size=8388608
    ..................................................    arm_dcache_flush_delete: ptr=0x70000000, size=8388608
    
    Big write /0_bigfile.txt took  0.97 Sec for 4145152 Bytes : file3.size()=4145152
    	Big write KBytes per second 4267.55 
    
    Bytes Used: 4214784, Bytes Total:8388608

  19. #19
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Below should be the extent of the changes for 'static' RAM ( PSRAM and DMAMEM/RAM2 ) LittleFS to survive device Warm Restart/Reset

    I can make a PULL REQUEST : Here is the edited file :: LittleFS.h

    Only edits to LFSIntegrity are to make the FS use PSRAM/EXTMEM or RAM2/DMAMEM > start of file replacement below.

    Code:
    @@ -298,7 +298,7 @@ public:
    		//Serial.println("configure "); delay(5);
    		configured = false;
    		if (!ptr) return false;
    		memset(ptr, 0xFF, size); // always start with blank slate
    		// memset(ptr, 0xFF, size); // always start with blank slate
    		size = size & 0xFFFFFF00;
    		memset(&lfs, 0, sizeof(lfs));
    		memset(&config, 0, sizeof(config));
    @ -329,9 +329,12 @@ public:
    		config.file_max = 0;
    		config.attr_max = 0;
    		configured = true;
    		if (lfs_format(&lfs, &config) < 0) return false;
    		//Serial.println("formatted");
    		if (lfs_mount(&lfs, &config) < 0) return false;
    		if (lfs_mount(&lfs, &config) < 0) {
    			memset(ptr, 0xFF, size); // always start with blank slate
    			if (lfs_format(&lfs, &config) < 0) return false;
    			//Serial.println("formatted");
    			if (lfs_mount(&lfs, &config) < 0) return false;
    		}
    		//Serial.println("mounted atfer format");
    		mounted = true;
    		return true;
    @ -361,6 +364,8 @@ private:
    		return 0;
    	}
    	static int static_sync(const struct lfs_config *c) {
    		// Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
    		arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
    		return 0;
    	}
    };
    @ @@
    Code:
    //#include <LittleFS.h>
    #include <LittleFS_NAND.h>
    
    #define HALFCUT  // HALFCUT defined to fill half the disk
    #define ROOTONLY // NORMAL is NOT DEFINED!
    #define NUMDIRS 32  // When not ROOTONLY must be 1 or more
    #define MYPSRAM 8	// compile time PSRAM size
    #define MYBLKSIZE 2048 // 2048
    //#define SHOW_YIELD_CNT  1 // uncommented shows calls to Yield per second
    
    #define TEST_RAM
    //#define TEST_SPI
    //#define TEST_QSPI
    //#define TEST_SPI_NAND
    //#define TEST_QSPI_NAND
    //#define TEST_PROG
    //#define TEST_MRAM
    
    IntervalTimer clocked10ms;
    uint32_t yCalls = 0;
    uint32_t yCallsMax = 0;
    uint32_t yCallsLast = 0;
    uint32_t yCallsIdx = 0;
    uint32_t yCallsSum = 0;
    #ifdef SHOW_YIELD_CNT
    void yield() {
    	yCalls++;
    }
    #endif
    void clock_isr() {
    	yCallsIdx++;
    	if ( yCallsIdx >= 100 ) {
    		if (yCallsSum > 0 )
    			Serial.printf( "\n yps=%lu [mx=%lu]\t", yCallsSum, yCallsMax * 100);
    		yCallsIdx = 0;
    		yCallsSum = 0;
    		yCallsMax = 0;
    	}
    	yCallsSum += yCalls - yCallsLast;
    	if ( yCalls - yCallsLast > yCallsMax ) yCallsMax = yCalls - yCallsLast;
    	yCallsLast = yCalls;
    }
    
    // Set for SPI usage
    //const int FlashChipSelect = 10; // AUDIO BOARD
    const int FlashChipSelect = 4; // PJRC Mem board 64MB on #5, #6 : NAND 1Gb on #3, 2GB on #4
    //const int FlashChipSelect = 5; // PJRC Mem board 64MB on #5, #6 : NAND 1Gb on #3, 2GB on #4
    //const int FlashChipSelect = 6; // digital pin for flash chip CS pin
    
    
    #ifdef TEST_RAM
    LittleFS_RAM myfs;
    // RUNTIME :: extern "C" uint8_t external_psram_size;
    EXTMEM char buf[MYPSRAM * 1024 * 1024];	// USE DMAMEM for more memory than ITCM allows - or remove
    //DMAMEM char buf[490000];	// USE DMAMEM for more memory than ITCM allows - or remove
    char szDiskMem[] = "RAM_DISK";
    #elif defined(TEST_SPI)
    //const int FlashChipSelect = 10; // Arduino 101 built-in SPI Flash
    #define FORMATSPI
    //#define FORMATSPI2
    LittleFS_SPIFlash myfs;
    char szDiskMem[] = "SPI_DISK";
    #elif defined(TEST_MRAM)
    //const int FlashChipSelect = 10; // Arduino 101 built-in SPI Flash
    LittleFS_SPIFram myfs;
    char szDiskMem[] = "FRAM_DISK";
    #elif defined(TEST_PROG)
    LittleFS_Program myfs;
    char szDiskMem[] = "PRO_DISK";
    #elif defined(TEST_QSPI_NAND)
    char szDiskMem[] = "QSPI_NAND";
    LittleFS_QPINAND myfs;
    #elif defined(TEST_SPI_NAND)
    char szDiskMem[] = "SPI_NAND";
    LittleFS_SPINAND myfs;
    #else // TEST_QSPI
    LittleFS_QSPIFlash myfs;
    char szDiskMem[] = "QSPI_DISK";
    
    #endif
    
    File file3;
    
    uint32_t DELSTART = 3; // originally was 3 + higher bias more to writes and larger files - lower odd
    #define SUBADD 512	// bytes added each pass (*times file number)
    #define BIGADD 1024	// bytes added each pass - bigger will quickly consume more space
    #define MAXNUM 10	// ALPHA A-Z is 26, less for fewer files
    #define MAXFILL 2048 // 66000	// ZERO to disable :: Prevent iterations from over filling - require this much free
    #define DELDELAY 0 	// delay before DEL files : delayMicroseconds
    #define ADDDELAY 0 	// delay on ADD FILE : delayMicroseconds
    ...

  20. #20
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    @mjs513 - if you are bored and want to have some fun - let me know if you can give this a try.

    With p#16 code the drive FS appears to survive to LFSIntegrity standards where lfs core code does all the work as it had the static sync() callback for a reason.
    > survival tested with:
    -> 'R' command in LFSIntegrity
    -> TyCommander issues Host side Teensy 'Reset'
    -> TeensyLoader Reprogram
    -> Teensy Button press and Reset

    opps ... in typing that I wonder what happens when the arm_dcache_flush_delete() is done with a RAM1 address ???
    >> Maybe it need to verify the Memory area of "c->context" is not an address in RAM1 ???
    -> make the _flush_ conditional on address >= :: ptr=0x20200000
    Code:
    // EXTMEM char buf[MYPSRAM * 1024 * 1024];
    arm_dcache_flush_delete: ptr=0x70000000, size=8388608
    Code:
    // DMAMEM char buf[490000];
     arm_dcache_flush_delete: ptr=0x20200000, size=489984
    Code:
    // char buf[400000]; // RAM1
    arm_dcache_flush_delete: ptr=0x200023c8, size=399872
    Edited code:
    Code:
    	static int static_sync(const struct lfs_config *c) {
    		if ( c->context >= (void *)0x20200000 ) {
    			Serial.printf("    arm_dcache_flush_delete: ptr=0x%x, size=%d\n", c->context, c->block_count * c->block_size);
    			arm_dcache_flush_delete(c->context, c->block_count * c->block_size );
    		}
    		return 0;
    That stops _dcache_flush_ on RAM1 - though it didn't seem to have any trouble.

  21. #21
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    @KenHahn - sorry for polluting your thread ... Though it does IMHO greatly increase the value/utility of popping PSRAM chips onto T_4.1's knowing that when possible data is preserved.

    Paul - Mike ... Kurt/Frank :: if seen as WORTHY and Working I'll move this to LittleFS thread ...

  22. #22
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,699
    @defragster.

    First your modified LittleFS.h is throwing errors on lowlevelFormat. So I used codecompare and updated the one the is bundled with Teensyduino1.54b9. See attached.

    I took a slightly different approach than you did. Instead of using LFSIntegrity I used a modifed LittleFS_teensy_test1a sketch see attached zip.

    On first pass it will print the directory on start and then add files or append if they already exist. So pass 1:
    Code:
    LittleFS Test
    TotalSize (Bytes): 8388608
    started
    printDirectory
    --------------
    
     0 dirs with 0 files of Size 0 Bytes
    
    MAKE files
    printDirectory
    --------------
    DIR	structureData1 / 
    
     0 dirs with 0 files of Size 0 Bytes
    
     1 dirs with 0 files of Size 0 Bytes
    
    --------------
    printDirectory
    --------------
    DIR	structureData1 / 
    	FILE	temp_test.txt		19
    
     0 dirs with 1 files of Size 19 Bytes
    FILE	temp_test1.txt		19
    FILE	temp_test2.txt		19
    FILE	temp_test3.txt		1024
    
     1 dirs with 3 files of Size 1062 Bytes
    
    Disk Usuage:
    Bytes Used: 10240, Bytes Total:8388608
    Test for SOME DATA TO TEST
    Note No files on start. Doing a Restart with the 'R' command that I added to the original sketch. The first pass shows that it retained the files and appended new data:
    Code:
    LittleFS Test
    TotalSize (Bytes): 8388608
    started
    printDirectory
    --------------
    FILE	bigfile.txt  		616448
    DIR	structureData1 / 
    	FILE	temp_test.txt		19
    
     0 dirs with 1 files of Size 19 Bytes
    FILE	temp_test1.txt		19
    FILE	temp_test2.txt		19
    FILE	temp_test3.txt		1024
    
     1 dirs with 4 files of Size 617510 Bytes
    
    MAKE files
    printDirectory
    --------------
    FILE	bigfile.txt  		616448
    DIR	structureData1 / 
    	FILE	temp_test.txt		19
    
     0 dirs with 1 files of Size 19 Bytes
    FILE	temp_test1.txt		19
    FILE	temp_test2.txt		19
    FILE	temp_test3.txt		1024
    
     1 dirs with 4 files of Size 617510 Bytes
    
    --------------
    printDirectory
    --------------
    FILE	bigfile.txt  		616448
    DIR	structureData1 / 
    	FILE	temp_test.txt		38
    
     0 dirs with 1 files of Size 38 Bytes
    FILE	temp_test1.txt		38
    FILE	temp_test2.txt		38
    FILE	temp_test3.txt		2048
    
     1 dirs with 4 files of Size 618572 Bytes
    
    Disk Usuage:
    Bytes Used: 630784, Bytes Total:8388608
    Test for SOME DATA TO TEST
    So I would say it looks like its working if you do a warm restart.
    Attached Files Attached Files

  23. #23
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Quote Originally Posted by mjs513 View Post
    @defragster.

    First your modified LittleFS.h is throwing errors on lowlevelFormat. So I used codecompare and updated the one the is bundled with Teensyduino1.54b9. See attached.

    I took a slightly different approach than you did. Instead of using LFSIntegrity I used a modifed LittleFS_teensy_test1a sketch see attached zip.

    On first pass it will print the directory on start and then add files or append if they already exist. So pass 1:
    ...

    Just noted my github is a mess ... I seem to have some included KurtE change to pass in *Serial? for output redirect?

    That had nothing to do with the change at hand though ... going to look at your code now ???

  24. #24
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    7,699
    Quote Originally Posted by defragster View Post
    Just noted my github is a mess ... I seem to have some included KurtE change to pass in *Serial? for output redirect?

    That had nothing to do with the change at hand though ... going to look at your code now ???
    Well, looks like the option to pass in *Serial has been incorporated:
    Code:
    bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
    This is what is up at: https://github.com/PaulStoffregen/Li...src/LittleFS.h. Think you may need a refresh Me too most of the time. I forgot to remove @KurtE's date modifications from my local directory first pass through

    I saw what you did when I updated using CodeCompare.

  25. #25
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,277
    Quote Originally Posted by mjs513 View Post
    Well, looks like the option to pass in *Serial has been incorporated:
    Code:
    bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
    This is what is up at: https://github.com/PaulStoffregen/Li...src/LittleFS.h. Think you may need a refresh Me too most of the time. I forgot to remove @KurtE's date modifications from my local directory first pass through

    I saw what you did when I updated using CodeCompare.
    Left me confused ... too long since touching LittleFS - I did a sync from github and I have this :: bool lowLevelFormat(char progressChar=0, Print* pr=&Serial);
    Seemed to match with td1.54 b9 as I did code compares to make sure I had no other needed changes.

    Paul liked the sync() idea - that is probably needed on any FLASH using data_cache as well, or pending changes would be lost on Power Loss on what should be 'permanent' media?

    I'll go back to doing a PR with your confirmation that it is at least sane and seemingly safe and complete.

    This will require any 'Warm Start' user on RAM2 or PSRAM Media to do some format if they expect to start with a fresh drive on any entry to setup() - but that is easier to explain than 'Lost Data' because they found a bug and edited code to new code, or touched the Button, or had a code Fault after some hours or days of trusting the data to be there.

    Looking at the .ld files I don't see any easy way to avoid using this hardcoded value to skip RAM1 flush? :: if ( c->context >= (void *)0x20200000 ) {
    > Not sure this is a usable 'named item' :: RAM (rwx): ORIGIN = 0x20200000

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •