Skip to content

Conversation

sethp
Copy link
Contributor

@sethp sethp commented Jun 14, 2021

I wired up a button I had on a little breadboard from sparkfun so that it's sitting between GND and pin 9 (gpio1). Pressing the button shorts pin9 to ground, which we can detect reliably by configuring the pin in "pull up input" mode (so the pin's internally connected to a pull-up resistor) to avoid "floating."

This all works fine for polling (see: examples/gpio_button.rs), but the PLIC isn't behaving as I expect for examples/gpio_button_interrupt.rs. Most recently I've tried to set it up so that it's always got an interrupt to trigger until I acknowledge it (beyond claiming the interrupt from the PLIC, the GPIO something requires writing a 1 back to a particular device to say "yup, saw that falling edge/rising edge/low level/high level" (see manual section 17.4: Interrupts). But, even when I crank all the priorities up on every interrupt, I only see the watchdog and "interrupt 46" (PWM1CMP2, apparently), not the expected GPIO1.

@sethp sethp requested a review from dougli1sqrd June 14, 2021 15:17
Copy link
Contributor

@dougli1sqrd dougli1sqrd left a comment

Choose a reason for hiding this comment

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

This is interesting! The polling version works though?

let rplic = &*hifive1::hal::e310x::PLIC::ptr();
for p in rplic.priority.iter() {
// p.write(|w| w.bits(0));
p.write(|w| w.bits(Priority::P7.into()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Kind of hilarious to set priority for all PLIC sources to 7

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Heh, yeah: that was my attempt to answer "well, am I even getting interrupts at ALL? Which ones?"

p.write(|w| w.bits(Priority::P7.into()));
}
rplic.priority[1].write(|w| w.bits(Priority::P0.into()));
rplic.priority[46].write(|w| w.bits(Priority::P0.into())); // TODO: vas ist das?
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh but you're setting 46 (which is a PWM pin I guess?) and the watchdog to 0, so it'll never interrupt.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are the answers to the "which ones" question: At first all I saw was a wall of watchdog interrupts as fast as the serial line could print, and when I turned those off then it was all interrupt no. 46. With that disabled, though, I get nothin', despite having set the GPIO to interrupt on every logically coherent state.


sprint!("hello world {:?}\n", button.is_low());

unsafe {
Copy link
Contributor

Choose a reason for hiding this comment

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

Surely your gpio into_pull_up_input() should have configured the GPIO memory correctly like you're doing in this block here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would think so. It looks like it sets pullup and input_en (and disables iof_en):

/// Configures the pin to operate as a pulled down input pin
pub fn into_pull_up_input(self) -> $PXi<Input<PullUp>> {
    $GPIOX::set_pullup(Self::INDEX, true);
    $GPIOX::set_input_en(Self::INDEX, true);
    $GPIOX::set_iof_en(Self::INDEX, false);
    $PXi { _mode: PhantomData }
}

but I'd still need to configure the "*_ie" (interrupt enable) stuff here. In order to toggle the state of the LED while the button is pressed, I was thinking I could trigger on rising and falling signal edges and just check the value of the input when interrupted, but I've currently got it set up to interrupt when the pin is high or low, thinking that would be "always."

However, I'm beginning to suspect my problem is electrical: I'm not sure I'm reading the diagram correctly, but I think the internal pull-up resistor isn't "part of" (whatever the appropriate term is) the interrupt circuit. So even though when I read the button's input I get a coherent value, the interrupt state is actually floating.

I think this means I need my own pull-up resistor attached to the pin and to not use the internal pull-up?

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.

2 participants