jonas-schievink / spi-memory Goto Github PK
View Code? Open in Web Editor NEWAn embedded-hal driver for various SPI Flash and EEPROM chips
License: BSD Zero Clause License
An embedded-hal driver for various SPI Flash and EEPROM chips
License: BSD Zero Clause License
This series is almost compatible with the 25x chips, but uses only 8-bit addresses, with an optional 9th bit encoded in the instruction byte. Seems like only ST manufactures these as their M950x0 series.
currently the sector size using in erase_sectors
is implicit, this makes it hard to write generic code that uses the flash traits since it can't know how many sectors it needs to erase for a given write.
Adding the sector size as an associated constant to the BlockDevice
trait would allow writing proper generic code that uses the flash traits.
Currently there's only a Debug
impl.
Ideally we'd also implement Error
, but that doesn't exist in libcore, and I'm not sure adding a std
feature is worth it.
Manufacturers tend to implement this differently, and the command can return a variable amount of data (I've seen 3 to 20 Bytes). Even when only considering the first 3 Bytes it isn't clear how they are split up (some chips return a 2 Byte manufacturer ID and a 1 Byte device ID, others do it the other way around). It's better to remove this functionality, it's not terribly useful in any case.
I have some W25N01GV chips that I've been playing with. These are still 25-series, but they're NAND flash and have a slightly different instruction set.
This crate provides an excellent starting point for those chips, but doesn't work without tweaking. For example, initialization returns an error because of an invalid status register (the command buffer needs to be changed to [0x05, 0xC0, 0x00]
instead of [0x05, 0x00]
, and the result is read from the 3rd bit), and the JEDEC id response is offset by one byte as well.
I'm happy to make a PR with whatever I get working, although it looks like there's no support for different protocols at the moment. #4 and #8 touch on this, and #10 and #25 propose two different approaches, but neither is merged, so it's unclear how to best proceed.
The crate doesn't do much atm, but it's still useful, so it should be added to https://github.com/rust-embedded/awesome-embedded-rust
Currently RN1 is a 4x0603 10k resistor array, which is apparently not easy to get (I substituted discrete 0603 resistors because Digikey didn't have a fitting resistor array). It should be replaced by 4 discrete 10k 0805 resistors, which would mean that the board has a total of 10 of these resistors, which can lower cost a little bit.
(this is currently being worked on on the (merged into master)dev-board
branch)
I no longer have a way to test this crate, so I want to build a development PCB with a bunch of SPI Flash and EEPROM chips on it that can also be used for hardware-in-the-loop testing. The PCB should have the following features:
#![no_std]
requirement since everything runs on a normal PC).This sort of setup is perhaps a bit overkill for a crate like this, but it seems like a very good starting point regarding HIL-testing that I can hopefully later transfer to Rubble, which is way more complex to test.
Current progress and notes:
Work left to do:
\HOLD
pin that just pauses transfers), need to switch off their power supply I guess.embedded-hal
s SPI traits of course)
linux-embedded-hal
or rppal
write_bytes
does not appear to manage non-sector aligned memory accesses. This may not be a constraint on all devices, but is definitely the case for some
To mitigate this writing 256-bytes at address 128 should result in two transactions, one to write to each sector, or the constraint could be documented and managed externally.
For a flash chip I'm using, the time to do a 64KB block erase is significantly faster than a whole series of sector erase commands. For 1MB, this is about 800ms vs 7500ms.
I'd be happy to send a PR to add support for erasing blocks, but wanted to first check your thoughts on API.
One option would be to add a new method that just erases a 64KB block. e.g.:
fn erase_64k_block(&mut self, addr: u32) -> Result<(), Error<SPI, CS>> {
self.write_enable()?;
let mut cmd_buf = [
Opcode::BlockErase as u8,
(addr >> 16) as u8,
(addr >> 8) as u8,
addr as u8,
];
self.command(&mut cmd_buf)?;
self.wait_done()
}
Another option would be to change erase_sectors
to check if you're erasing all the sectors in a block and if so, erase that block instead. This has the advantage that it doesn't add to the API, but it does make the implementation of erase_sectors more complex. Any preference?
AFAIK, you can't use this with any other SPI peripherals on the same SPI.
2 solns:
I think the first is the better approach. Thoughts?
Apparently also called DataFlash. Doesn't seem to have many manufacturers.
Example chips in the series:
This needs quite different algorithms, so we'll probably split up the types to have one for Flash and one for EEPROM. Perhaps there should be a third one that can only read, but doesn't care about Flash/EEPROM.
While waiting for the flash memory to complete its work, a lot of time can traverse.
In my case I have a radio IC on the same SPI as the flash memory that logging is happening on, and it would be awesome to be able to do the wait checks in a polling manner.
This would allow for the high priority SPI transactions with, in my case, the radio to happen in parallel with waiting for flash operations.
One way to do this is to use type states and have a Busy
state for polling.
It was extremely difficult soldering a AT45DB021E to it since its footprint is much wider. The Dev-Board should accommodate for this by having footprints that work with as many chips as possible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.