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

Added two new constructors to ExclusiveDevice to allow for SPI devices that don't require a CS pin #650

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

uliano
Copy link

@uliano uliano commented Feb 15, 2025

Summary

  • Introduced NoPin (in embedded-hal::digital) as a dummy pin for hardware-managed CS scenarios.
  • Added two new constructors to ExclusiveDevice, namely new_no_cs and new_no_cs_no_delay (could't figure out any better) to allow for SPI devices that don't require a CS pin.

Why?

The existing implementation required an OutputPin, which for some chips can be unnecessary and effectively wasted.

Edited

I refactoerd this PR along the lines hinted by @Rahix below.

@uliano uliano requested a review from a team as a code owner February 15, 2025 15:54
@uliano uliano force-pushed the exclusive_device_no_cs branch from 33a7a6e to c209484 Compare February 15, 2025 16:01
Copy link

@Rahix Rahix left a comment

Choose a reason for hiding this comment

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

Can we be sure there are no use-cases for an exclusive device which still expects a proper chip-select signal? I vaguely remember having seen such things before...

Beyond that, removing the CS from ExclusiveDevice now is a breaking change. I think it's a better option to leave it in and give users the option to opt-out by providing a second constructor:

impl<BUS, D> ExclusiveDevice<BUS, NoPin, D> {
    pub fn without_cs(bus: BUS, delay: D) -> Self {
        ExclusiveDevice::new(bus, NoPin, delay).unwrap_infallible()
    }
}

@uliano
Copy link
Author

uliano commented Feb 16, 2025

About the use case if there is such a thing as an exclusive device that needs to control its CS for some reason (can't figure out any) it can be done with an additional OutputPin to be contolled as required.

But then it should be proved that such a case exists.

To me this has been oversighted.

To be follwing to the letter the naming found here

Module spi

It should have been named ExclusiveBus from the beginning (but then all the Buses are Exclusive so still redundant)

About the breaking change, I normally quite agree with you. Here my reason for that is that the name of this SpiDevice implementation is contradictory and misleading. Is it better to have users correct their code (just remove the pin) or to keep a misnomer in the Interface?

Convenience (your proposal) but still one should take the fuss of making its own NoPin

or Correctness (my PR)

I sincerely can't decide

@Dirbaio
Copy link
Member

Dirbaio commented Feb 16, 2025

there's many SPI chips that need CS toggles for each transaction, so they know where a command begins/ends, and they don't work if you tie CS permanently low.

@uliano
Copy link
Author

uliano commented Feb 17, 2025

there's many SPI chips that need CS toggles for each transaction, so they know where a command begins/ends, and they don't work if you tie CS permanently low.

I see, then @Rahix is the only choice.

I see what I can do along that approach

…wing to have devices without chip select namely new_no_cs and new_no_cs_no_delay
@uliano uliano force-pushed the exclusive_device_no_cs branch from c209484 to 3450491 Compare February 17, 2025 10:12
@uliano
Copy link
Author

uliano commented Feb 17, 2025

@Rahix @Dirbaio. I refactored the PR along the lines of @Rahix suggestions above. Now the NoPin behavior is opt-in.

@uliano uliano changed the title removed chip select pin from ExclusiveDevice in embedded-hal-bus Added two new constructors to ExclusiveDevice to allow for SPI devices that don't require a CS pin Feb 17, 2025
impl<BUS, D> ExclusiveDevice<BUS, NoPin, D> {
/// Create a new [`ExclusiveDevice`] without a Chip Select (CS) pin.
pub fn new_no_cs(bus: BUS, delay: D) -> Self {
ExclusiveDevice::new(bus, NoPin, delay).unwrap_infallible()
Copy link

Choose a reason for hiding this comment

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

To not pull another dependency, you can also do

pub fn new_no_cs(bus: BUS, delay: D) -> Self {
    match ExclusiveDevice::new(bus, NoPin, delay) {
        Ok(this) => this,
        // no Err() branch
    }
}

Less readable, but avoids dependency-bloat... Not sure what the official stance of e-h on that topic is...

Copy link
Member

Choose a reason for hiding this comment

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

yeah avoiding deps is always nice.

Comment on lines +239 to +248
// Implement `OutputPin`
impl OutputPin for NoPin {
fn set_low(&mut self) -> Result<(), Infallible> {
Ok(())
}

fn set_high(&mut self) -> Result<(), Infallible> {
Ok(())
}
}
Copy link

Choose a reason for hiding this comment

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

I guess also implement all the other digital traits for this type?

Copy link
Author

@uliano uliano Feb 17, 2025

Choose a reason for hiding this comment

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

@Rahix what's the use case for a non existent InputPin? what is the value is supposed to return?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants