This repository was archived by the owner on Oct 18, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 26
Adding support for the SPI stack chips #10
Open
hargoniX
wants to merge
25
commits into
jonas-schievink:master
Choose a base branch
from
hargoniX:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
06d9b55
adding the FlashWrite, EepromWrite and Read traits
hargoniX 08197ad
reworking the new traits
hargoniX cbd5159
adding erase_all and write_bytes implementations
hargoniX 233effe
finalizing the trait impl on series25 chips, adding a prelude file wh…
hargoniX e28690d
finalizing the trait impl on series25 chips, adding a prelude file wh…
hargoniX e07ac1d
Merge branch 'master' of github.com:hargoniX/spi-memory
hargoniX ceda1d6
addressing review points
hargoniX 4bfdf97
Update comment on erase times
hargoniX a3422c2
Update src/lib.rs
hargoniX 7a4755a
more review points addressed
hargoniX 7e41934
Merge branch 'master' of github.com:hargoniX/spi-memory
hargoniX 8a518a0
commented the wrong addr
hargoniX e82af20
Nit 1
hargoniX a2e816e
Nit 2
hargoniX fd9b3bc
adding an (undocumented) implementation of the w25m concept
hargoniX fa2488a
merged conflicts
hargoniX a6d2db2
adding BlockDevice and Read impls for w25m
hargoniX 816d9f1
read, write and reset working roughly for w25n, more testing to be d…
hargoniX 8127c02
working API for the w25n series, everything tested
hargoniX 33834ca
adding support for spi stack chips
hargoniX 4e3b729
Resolve merge conflicts
hargoniX e72f625
Update src/lib.rs
hargoniX eebfde2
increasing code reusage by only having one central spi_command function
hargoniX a446e71
formatting and a bit of docs
hargoniX 1474850
Merge branch 'master' of github.com:hargoniX/spi-memory
hargoniX File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| //! Provides an implementation for switching between the two dies stacked upon each other inside the W25M series | ||
| use crate::utils::spi_command; | ||
| use crate::{BlockDevice, Error, Read}; | ||
| use core::marker::PhantomData; | ||
| use core::mem; | ||
| use embedded_hal::blocking::spi::Transfer; | ||
| use embedded_hal::digital::v2::OutputPin; | ||
|
|
||
| #[allow(missing_debug_implementations)] | ||
| pub struct Die0; | ||
| #[allow(missing_debug_implementations)] | ||
| pub struct Die1; | ||
|
|
||
| /// All dies which are supposed to be supported by the W25M struct have to implement this trait | ||
| pub trait Stackable<SPI: Transfer<u8>, CS: OutputPin>: | ||
| BlockDevice<SPI, CS> + Read<SPI, CS> + Sized | ||
| { | ||
| fn new(spi: SPI, cs: CS) -> Result<Self, Error<SPI, CS>>; | ||
| /// Returns the SPI and chip select objects so they can be used elsewhere | ||
| fn free(self) -> (SPI, CS); | ||
| } | ||
|
|
||
| /// Driver for W25M SPI Flash chips. | ||
| /// | ||
| /// # Type Parameters | ||
| /// | ||
| /// * **`DIE0`**: The type of one of the two dies inside the W25M package | ||
| /// * **`DIE0`**: The type of the other of the two dies inside the W25M package | ||
| /// * **`DIE`**: A type state, used to indicate which of the two die's is the currently active one | ||
| #[derive(Debug)] | ||
| pub struct Flash<DIE0, DIE1, DIE> { | ||
| inner: Inner<DIE0, DIE1>, | ||
| _die: PhantomData<DIE>, | ||
| } | ||
|
|
||
| #[derive(Debug)] | ||
| enum Inner<DIE0, DIE1> { | ||
| Die0(DIE0), | ||
| Die1(DIE1), | ||
| Dummy, | ||
| } | ||
|
|
||
| impl<DIE0, DIE1> Flash<DIE0, DIE1, Die0> { | ||
| /// Creates a new W25M device | ||
| /// | ||
| /// At | ||
| /// the moment the only way to call this function is sadly | ||
| /// ``` | ||
| /// let mut flash: Flash<W25N<_, _>, W25N<_, _>, _> = Flash::init(spi, cs).unwrap(); | ||
| /// ``` | ||
| /// TODO: Improve this API, its not very convenient | ||
| pub fn init<SPI, CS>(spi: SPI, cs: CS) -> Result<Flash<DIE0, DIE1, Die0>, Error<SPI, CS>> | ||
| where | ||
| SPI: Transfer<u8>, | ||
| CS: OutputPin, | ||
| DIE0: Stackable<SPI, CS>, | ||
| DIE1: Stackable<SPI, CS>, | ||
| { | ||
| Ok(Flash { | ||
| inner: Inner::Die0(DIE0::new(spi, cs)?), | ||
| _die: PhantomData, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| impl<DIE0, DIE1> Flash<DIE0, DIE1, Die0> { | ||
| pub fn switch_die<SPI, CS>(mut self) -> Result<Flash<DIE0, DIE1, Die1>, Error<SPI, CS>> | ||
| where | ||
| DIE0: Stackable<SPI, CS>, | ||
| DIE1: Stackable<SPI, CS>, | ||
| SPI: Transfer<u8>, | ||
| CS: OutputPin, | ||
| { | ||
| let (mut spi, mut cs) = match mem::replace(&mut self.inner, Inner::Dummy) { | ||
| Inner::Die0(die) => die.free(), | ||
| _ => unreachable!(), | ||
| }; | ||
| let mut command = [0xC2, 0x01]; | ||
| spi_command(&mut spi, &mut cs, &mut command)?; | ||
|
|
||
| Ok(Flash { | ||
| inner: Inner::Die1(DIE1::new(spi, cs)?), | ||
| _die: PhantomData, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| impl<DIE0, DIE1> Flash<DIE0, DIE1, Die1> { | ||
| pub fn switch_die<SPI, CS>(mut self) -> Result<Flash<DIE0, DIE1, Die0>, Error<SPI, CS>> | ||
| where | ||
| DIE0: Stackable<SPI, CS>, | ||
| DIE1: Stackable<SPI, CS>, | ||
| SPI: Transfer<u8>, | ||
| CS: OutputPin, | ||
| { | ||
| let (mut spi, mut cs) = match mem::replace(&mut self.inner, Inner::Dummy) { | ||
| Inner::Die1(die) => die.free(), | ||
| _ => unreachable!(), | ||
| }; | ||
|
|
||
| let mut command = [0xC2, 0x00]; | ||
| spi_command(&mut spi, &mut cs, &mut command)?; | ||
|
|
||
| Ok(Flash { | ||
| inner: Inner::Die0(DIE0::new(spi, cs)?), | ||
| _die: PhantomData, | ||
| }) | ||
| } | ||
| } | ||
hargoniX marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| impl<DIE0, DIE1, SPI, CS, DIE> BlockDevice<SPI, CS> for Flash<DIE0, DIE1, DIE> | ||
| where | ||
| DIE0: Stackable<SPI, CS>, | ||
| DIE1: Stackable<SPI, CS>, | ||
| SPI: Transfer<u8>, | ||
| CS: OutputPin, | ||
| { | ||
| fn erase(&mut self, addr: u32, amount: usize) -> Result<(), Error<SPI, CS>> { | ||
| match &mut self.inner { | ||
| Inner::Die0(die) => die.erase(addr, amount), | ||
| Inner::Die1(die) => die.erase(addr, amount), | ||
| _ => unreachable!(), | ||
| } | ||
| } | ||
|
|
||
| fn erase_all(&mut self) -> Result<(), Error<SPI, CS>> { | ||
| match &mut self.inner { | ||
| Inner::Die0(die) => die.erase_all(), | ||
| Inner::Die1(die) => die.erase_all(), | ||
| _ => unreachable!(), | ||
| } | ||
| } | ||
|
|
||
| fn write_bytes(&mut self, addr: u32, data: &mut [u8]) -> Result<(), Error<SPI, CS>> { | ||
| match &mut self.inner { | ||
| Inner::Die0(die) => die.write_bytes(addr, data), | ||
| Inner::Die1(die) => die.write_bytes(addr, data), | ||
| _ => unreachable!(), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl<DIE0, DIE1, SPI, CS, DIE> Read<SPI, CS> for Flash<DIE0, DIE1, DIE> | ||
| where | ||
| DIE0: Stackable<SPI, CS>, | ||
| DIE1: Stackable<SPI, CS>, | ||
| SPI: Transfer<u8>, | ||
| CS: OutputPin, | ||
| { | ||
| fn read(&mut self, addr: u32, buf: &mut [u8]) -> Result<(), Error<SPI, CS>> { | ||
| match &mut self.inner { | ||
| Inner::Die0(die) => die.read(addr, buf), | ||
| Inner::Die1(die) => die.read(addr, buf), | ||
| _ => unreachable!(), | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These can just
#[derive(Debug)], there shouldn't be any harm in thatThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also make them
enums instead ofstructs since they're just used as type markers