SPI flash support (was: current limit)

Uhm, okay, playing with the supply voltages…

I cannot get responses at anything higher than 2.2V now!
Then I took my Fluke 179 DMM and measured 2.02V when 2.0V was requested and 3.365V when 3.3V was requested, so the VCC voltages are close enough.

My flash chip is a weirdo, or more probably the 20cm probe cables are a problem here.

Wow, thank you again for pointing out the current limit bug. I finally solved it. It was a really nasty bit of concurrency with both cores grabbing the ADC at the same time after the PSU is enabled.

We have an atomic lock for the shared SPI interface, what RP2040 calls a spinlock. In the past the SPI spinlock also covered access to ADC (because we use SPI shift registers to set the channel of the analog mux). However, when I “cleaned up the code” into nice reusable discrete functions the spin lock only covered SPI. I added a new ADC spinlock and things seem back to normal. That was a real challenge :slight_smile:

ImportedPhoto_1711013341086

I’ve made up several boards for testing flash chips. These are early boards and don’t work well, but I should have the final boards in a few days. Can I send you some PCBs? I’m not sure how many socket samples I’m going to receive, I think I got several of the WSON, but I’ll send those too if I can.

1 Like

Just curious: what speed are you using? I had success with the probe cable up to 12.5MHz(? I believe, it’s in another thread), which really really surprised me.

Yes, I would happily receive some test gear and also happy to test them out and give feedback.

I was using 100 kHz speed, not anything higher any time. Perhaps I actually should try out higher speed, 1MHz for starters. Maybe the SPI chips just gets bored. :laughing:

1 Like

You will probably hate me for saying this, but that kind of locking/concurrency problems would have been “easy” to avoid with Rust. :upside_down_face:

I have been making my own (small) embedded stuff with Rust for Cortex-M (including RP2040/pico) and ESP32 and still love it. Their slogan fearless concurrency is not just empty words.

Having said that, I understand that it would be truly insane to rewrite everything now that there is quite a lot of codebase already made. :crazy_face:

1 Like

I’m really interested in the higher level languages for uCs that are around now. I have a hard time trusting something that’s not C though :slight_smile: It feels too much like programming in PHP :rofl:

I looked at a logic analyzer written in rust for rp2040 and it was impressive in its compactness.

The main reason I stuck with C instead of CircuitPython/rust/etc is there’s so much great open source stuff in C (like the flash library) that we can use to expand the features quickly.

2 Likes

Well, you mean it’s too easy with other than C? :laughing:

Also, mentioning PHP in this context, and on consecutive lines with Rust makes you an infidel and Karma will punish you! :grimacing: (now I myself mentioned them on the same sentence, oh well)

It is very true that there is a vast collection of ready made libraries written in C for embedded development. There is no denying that. Anyway, also Rust has been gaining traction lately and there is impressive amount of drivers already available in crates.io, for example. It’s a pity that embedded-hal only got to version 1.0 quite lately, but probably it was better to do it right the first time. Version 1.0 is meaningful because it is supposed to be stable.

Anyway, I would say about Rust, give it a try one day. It’s a thing.

There are at least two very good books from O’Reilly that I would recommend, in addition to the “official” free book.

My fun project involving LED matrix displays and ESP32… I have several of these around the house.

BR, -sjm

2 Likes

Very cool! I love the json backend!

Speaking of json and C libraries, I need to find a new JSON parser for the firmware. I didn’t have much luck feeding the current one from flash instead of an array. I’d like to have a set of data sources that can be accessed from the internal flash drive. For example a full list of JEDEC manufacturer names for v1.5 SFDP parameter tables, a big I2C device list with datasheet links, etc, etc.

2 Likes

I just tidied up the spi mode. I found a chip in my junk box with no flash parameters table: Renesis (née Adesto) AT25SF321.

   {"AT25SF321", SFUD_MF_ID_ADESTO, 0x87, 0x01, 4L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_PAGE_256B, 4096, 0x20},      \

It shares the JEDEC manufacturer code 0x1f with existing manufacturer Atmel, but the codes don’t seem to overlap so it still works.

ImportedPhoto_1711200326508

I tried using my handy flash socket adapter, but there’s no positioning pegs to hold the sockets in place and they’re really tough to solder without shorts. I’m planning to use the larger SOP spring loaded sockets, they’re actually much cheaper and we can have low volumes hand assembled.

Now I’ll try to get it dumping properly.

3 Likes

I found the proper capacity variable and it seems to work with chips identified through the table now.

flash read -f test.bin -s 0x00 -e 0xffffff -a 3

It would be useful to try to dump chips, even if they are not IDed. How about something like this: -s is the start address (default 0x00), -e is the end address, -a specifies how many bytes the address uses (default 3). Then we attempt to read with the most common 0x03 read command? Does that make sense? Any suggestions/requests?

2 Likes

Well that would make lots of sense.

Also, when IDing chips, if a complete match is not found, we can still suggest a size based on the last byte of id…

    {"W25Q40BV", SFUD_MF_ID_WINBOND, 0x50, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                        \
    {"W25Q80BV", SFUD_MF_ID_WINBOND, 0x50, 0x14, 1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                       \
    {"W25Q16BV", SFUD_MF_ID_WINBOND, 0x50, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                    \
    {"W25Q32BV", SFUD_MF_ID_WINBOND, 0x50, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                    \
    {"W25Q64BV", SFUD_MF_ID_WINBOND, 0x50, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                    \
    {"W25Q128BV", SFUD_MF_ID_WINBOND, 0x50, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                  \
    {"W25Q256BV", SFUD_MF_ID_WINBOND, 0x50, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20},                  \

I mean, 0x13 is 512KiB, 0x14 is 1 MiB and so on, regardless of the manufacturer.
So, this byte can be used as a fallback “guess” of the size, and also having
the option to just force blind reading as you suggested would be of course useful
and sometimes very much necessary, I guess.

I’ll give the newly fixed flash read command a try.

BR, -sjm

3 Likes

You’re right, I think a good guess can be made from the third byte. It seems to be somewhat manufacturer dependent though.

This is the chip I tested, it has the density in the second byte.

This is the Puya chip I’ve been using for SFPD tables, it follows convention.

    {"P25D20H", SFUD_MF_ID_PUYA, 0x60, 0x11, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, 

This Puya chip from the source doesn’t though.

I think it’s helpful to give the user this information, maybe pair it with an extended list of known flash IDs. This is an impressive list, but it doesn’t seem to be RDIDs. The comment at link pretty much sums up our discussion here :slight_smile:

2 Likes

Yeah, I was able to dump my spi chip now, it seems to contain the firmware of a ZyXEL ADSL modem and strings reveals that most probably it was read correctly…

SPI> flash read -f flash1.bin
Flash device manufacturer ID 0xC2, type ID 0x20, capacity ID 0x15
SFDP V1.0, 2 parameter headers
Error: Parameter table length (2) error
Warning: Read SFDP parameter header information failed.
Warning: The chip does not support JEDEC SFDP.
Searching flash chip database for 0xC2 0x20 0x15
Found a Macronix MX25L1606E flash chip (2097152 bytes)
Flash device reset success
Dumping to flash1.bin...
[-------------------C]
Dump OK

SPI> 
SPI> ls
        82 bpspi.bp
   2097152 flash1.bin
        35 bpi2c.bp
       333 bpconfig.bp
0 dirs, 4 files

Nice!

1 Like

Very cool! Thank you for the update and test, I’m glad it worked.

1 Like

media_20240329_131852_5909893694895615847

I put together a kit for you. I don’t have enough right angle 10P female connectors. If you happen to have some, I will mail it as is. I should receive more connectors early next week.

I, uh, tried to pull some off old prototypes. It was not super successful :rofl:

2 Likes

Uh oh well, thanks a lot. I will order more of those angled connectors from Aliexpress… they might prove useful for other projects and cost a few euros max.

1 Like

Whee-o, I received the adapter kits today and assembled them.
Luckily I had suitable 470nF smd caps to use. :slight_smile:

1 Like

Glad it arrived. Sorry for the time frame. The RA 10P connectors never arrived and I eventually ordered them locally. Most schematics and PCBs should be in git. Let me know if you need anything !

1 Like

Another useful thing would be a way to extend the FlashDB with a file on the flash instead of patching the code. had to do that twice recently to wiggle some data onto a flash for testing a theory

1 Like

Good suggestion. There’s a few other places I’d like to include databases on flash (I2C device IDs, etc). The block on implementing it is incorporating a better JSON parser that doesn’t need to hold everything in ram at once.

The flash command should also probably have some sane defaults to use for write if no chip is IDed, the way we added a common 0x03 read to end option.