Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blocking/spi: Don't return the same buffer back. #286

Merged
merged 1 commit into from
Aug 3, 2021

Conversation

Dirbaio
Copy link
Member

@Dirbaio Dirbaio commented Jun 22, 2021

This is a rather minor improvement to the blocking SPI Transfer trait, but that IMO is still worth it.

Old: fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<&'w [W], Self::Error>
New: fn transfer(&mut self, words: &mut [W]) -> Result<(), Self::Error>

It is redundant (and confusing IMO) to return back the same buffer the user has passed in. It allows for 2 ways of writing the same thing: use the returned buffer, or ignore it and use the buffer that was passed in. It's not obvious which is better, and from the docs it's not obvious that both are really the same either.

Also, with the old signature, it is possible for implementors to return a subslice of the buffer instead of the whole buffer. This would be arguably wrong and would break user code that assumes the entire buffer is returned. Not re-returning the buffer makes this mistake impossible.

@Dirbaio Dirbaio requested a review from a team as a code owner June 22, 2021 15:20
@rust-highfive
Copy link

r? @ryankurte

(rust-highfive has picked a reviewer for you, use r? to override)

@lachlansneff
Copy link
Contributor

One thing that I just thought of here. If the read buffers get switched over to MaybeUninit, then returning the buffer as a slice of words lets people use the api without unsafe. There is the issue of returning a subslice though.

@Dirbaio
Copy link
Member Author

Dirbaio commented Jun 22, 2021

True!

The propsed change is what I feel makes most sense given the current convention of not using MaybeUninit or similar.

Maybe you could open an issue on "add a way to read into uninitialized buffers" and we can discuss there :)

@David-OConnor
Copy link

David-OConnor commented Jun 24, 2021

Agreed. I noticed this recently as well, and was surprised. Eg this instead:

    /// Read multiple bytes to a buffer, blocking.
   fn transfer<'w>(&mut self, words: &'w mut [W]) -> Result<(), Error> {
        for word in words.iter_mut() {
            nb::block!(self.write_one(word.clone()))?;
            *word = nb::block!(self.read())?;
        }

        Ok(())
    }

@Dirbaio
Copy link
Member Author

Dirbaio commented Jul 13, 2021

ping @eldruin @ryankurte @therealprof

I believe this should be fairly uncontroversial. The question of "what about MaybeUninit" is better debated in its own issue, and the verdict from that applied to all traits. I don't think it justifies keeping the returned slice here "just in case": no other trait does this, and we can always add it back if we do MaybeUninit.

eldruin
eldruin previously approved these changes Jul 13, 2021
Copy link
Member

@eldruin eldruin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks!

@therealprof
Copy link
Contributor

@japaric Since you added the API way back when, did you have any intentions with regards to this particular interface? Any objections to removing it?

@ryankurte
Copy link
Contributor

i guess without the returned subslice (or an n) you can't easily signal partial-success (eg, tried to transfer four bytes, only achieved three), but, it'd probably be less surprising to signal that as an error (especially with the new error types) than to require people to -also- check n on success. pending any thoughts by @japaric, sgtm.

@therealprof
Copy link
Contributor

As discussed last week we're going to merge this pending objections. @Dirbaio Would you mind fixing the conflicts?

@Dirbaio
Copy link
Member Author

Dirbaio commented Aug 3, 2021

@therealprof rebased

@eldruin
Copy link
Member

eldruin commented Aug 3, 2021

uh, CI is broken due to the stm32f1 dev dependency. Updating it does not help: #304

@eldruin
Copy link
Member

eldruin commented Aug 3, 2021

Alright, #305 should fix CI, then we can merge this.

Copy link
Contributor

@therealprof therealprof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bors try

bors bot added a commit that referenced this pull request Aug 3, 2021
Copy link
Contributor

@therealprof therealprof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

bors r+

@bors bors bot merged commit 306c3d8 into rust-embedded:master Aug 3, 2021
bors bot added a commit that referenced this pull request Nov 4, 2021
287: spi: add Read and separate-buffers Transfer r=eldruin a=Dirbaio

~~Depends on #286~~

- Added spi::Read for only reading
- Renamed Transfer to TransferInplace
- Added a new Transfer, for reading+writing simultaneously with different buffers.

Open question
- ~~Should Transactional gain Read, Transfer (not-inplace) support?~~ yes, done


Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Review is incomplete T-hal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants