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

Make PIO IRQ IDs into ZSTs #723

Merged
merged 1 commit into from
Nov 23, 2023
Merged

Make PIO IRQ IDs into ZSTs #723

merged 1 commit into from
Nov 23, 2023

Conversation

9ary
Copy link
Contributor

@9ary 9ary commented Nov 19, 2023

This allows getting the IRQ with pio.irq::<IRQn>(), where IRQn is a type generic.

This is a minor breaking change. I struggled for a while trying to get something similar working with the existing const generic, without success.

@ithinuel
Copy link
Member

Hello, thank you for the contribution.
Could you elaborate on your usecase/motivation for this change?

@9ary
Copy link
Contributor Author

9ary commented Nov 19, 2023

This allows me to write a module which uses PIO while being generic over the IRQ it uses. See https://github.com/redolution/cubane/blob/e35d1be482b2e81d074fc699efcec44f840ab4f3/src/exi.rs, in particular these two lines:

I can't use a match block over the const generic here because the two IRQs have different type signatures, type-level selection is the only option as far as I can tell.
I've tried several approaches to make this work while retaining the const generic, but to no avail. I'm not sure it's actually possible without the ability to construct the object myself, so I fixed it at the root.

I admit the commit/PR message is a bit lacking, I was very frustrated about not getting this to work so I didn't really have the energy to write a better one.

@ithinuel
Copy link
Member

I see, thank you :)

Only adding fn irq<const IRQ: usize>(&self) -> Interrupt<'_, P, IRQ> wouldn't be good as it'd allow to create an Interrupt with any value of IRQ where only 0 and 1 are valid.

@9ary
Copy link
Contributor Author

9ary commented Nov 19, 2023

Yup, hence I implemented the same construct as is already used for things like state machine and DMA channel IDs.

@ithinuel ithinuel self-requested a review November 20, 2023 07:52
@ithinuel
Copy link
Member

ithinuel commented Nov 20, 2023

Actually I found a way to check for that that's transparent to the user:

pub fn irq<const IRQ: usize>(&self) -> Interrupt<'_, P, IRQ> {                                                                    
    struct IRQSanity<const X: usize>;                                                                                             
    impl<const IRQ: usize> IRQSanity<IRQ> {                                                                                       
        const CHECK: () = assert!(IRQ == 0 || IRQ == 1, "Irq Index must be either 0 or 1");                                       
    }                                                                                                                             

    let _test = IRQSanity::<IRQ>::CHECK;                                                                                          
    Interrupt {                                                                                                                   
        block: self.pio.deref(),                                                                                                  
        _phantom: core::marker::PhantomData,                                                                                      
    }                                                                                                                             
}

The error message looking like:

error[E0080]: evaluation of `rp2040_hal::pio::PIO::<P>::irq::IRQSanity::<3>::CHECK` failed
   --> /rp-hal/rp2040-hal/src/pio.rs:130:31
    |
130 |             const CHECK: () = assert!(IRQ == 0 || IRQ == 1, "Irq Index must be either 0 or 1");
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'Irq Index must be either 0 or 1', /rp-hal/rp2040-hal/src/pio.rs:130:31

@9ary
Copy link
Contributor Author

9ary commented Nov 20, 2023

Oh that's neat, although the error message is a bit weird.
Fwiw since it's a usize, IRQ <= 1 should be enough as the condition.

This allows writing modules that are generic over the IRQ.

Co-authored-by: Wilfried Chauveau <wilfried.chauveau@ithinuel.me>
@9ary
Copy link
Contributor Author

9ary commented Nov 20, 2023

Updated with your suggestion, so this is no longer a breaking change.

@jannic jannic merged commit cfd6c12 into rp-rs:main Nov 23, 2023
8 checks passed
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