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

Some pins interfers with timer interrupts? #82

Closed
Gregwar opened this issue Nov 26, 2013 · 5 comments
Closed

Some pins interfers with timer interrupts? #82

Gregwar opened this issue Nov 26, 2013 · 5 comments

Comments

@Gregwar
Copy link
Contributor

Gregwar commented Nov 26, 2013

Hi, after investigations I figured out that using some pins seems to interfer with timer interrupts. Here is my example:

#include <wirish/wirish.h>

#define TIMER   1
#define CHANNEL TIMER_CH1

static void timer_interrupt()
{
    digitalWrite(BOARD_LED_PIN, HIGH);
}

__attribute__((constructor)) void premain()
{
    init();
}

int main(void)
{
    pinMode(BOARD_LED_PIN, OUTPUT);

    HardwareTimer timer(TIMER);
    timer.pause();
    timer.setPeriod(50000);
    timer.setMode(CHANNEL, TIMER_OUTPUT_COMPARE);
    timer.setCompare(CHANNEL, 1);
    timer.attachInterrupt(CHANNEL, timer_interrupt);
    timer.refresh();
    timer.resume();

    pinMode(27, OUTPUT);
    digitalWrite(27, LOW);
    digitalWrite(BOARD_LED_PIN, LOW);

    while (1);
}

In the example above, the led will never be turned on if you use CHANNEL=TIMER_CH1, and it will be turned on if you use CHANNEL=TIMER_CH2

It look like that pin 27 is indeed the timer pin 1_CH1, but why setting just it as OUTPUT would interfer with it?

Best regards

@Gregwar
Copy link
Contributor Author

Gregwar commented Nov 26, 2013

Initializing the timer after the pinMode seems to be a solution, but I think something should be explained in the documentation about that

@mbolivar
Copy link
Contributor

Ah, OK. Yes, that's a bug. Thanks for the example! It helped me understand what you meant.

The problem is that in pinMode(), if the pin is capable of PWM, we disable the corresponding timer channel when going to OUTPUT mode.

https://github.com/leaflabs/libmaple/blob/master/wirish/stm32f1/wirish_digital.cpp#L82

The reason why is because the timer channel's capture/compare functionality is also what drives PWM, so disabling the channel is meant to also disable PWM on that pin. That does break your use case, though, and honestly, I've never liked that code, so I think we should just remove it (so users would have to disable the timer channels themselves instead). Most programs should be using pins for one thing only, so this shouldn't affect too many people.

Seem reasonable to you?

@Gregwar
Copy link
Contributor Author

Gregwar commented Nov 26, 2013

I agree, this is really odd

The problem of this code with my use case is that my pinMode was not defined before, so there is indeed no reason to disable the timer

What you suggest is replacing this code block by something like this?:

    if (PIN_MAP[pin].timer_device != NULL && pwm) {
        /* Enable timer channels if we're switching into PWM */
        timer_set_mode(PIN_MAP[pin].timer_device,
                       PIN_MAP[pin].timer_channel, TIMER_PWM);
    }

So I guess the only side-effect would be letting the timer running when switching from PWM to OUTPUT for instance, right?

@mbolivar
Copy link
Contributor

That's right -- the side effect would be to leave the timer running. The timers are all running from board initialization time, anyway, so that doesn't seem like a problem to me:

https://github.com/leaflabs/libmaple/blob/master/wirish/boards.cpp#L178

@Gregwar
Copy link
Contributor Author

Gregwar commented Nov 26, 2013

Hm, indeed, it's better like this then

@Gregwar Gregwar closed this as completed Nov 26, 2013
@Gregwar Gregwar reopened this Nov 26, 2013
@Gregwar Gregwar closed this as completed Sep 1, 2014
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

No branches or pull requests

2 participants