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

PWM issue with TIMER2 #178

Closed
hathach opened this issue May 17, 2016 · 5 comments · Fixed by #181
Closed

PWM issue with TIMER2 #178

hathach opened this issue May 17, 2016 · 5 comments · Fixed by #181

Comments

@hathach
Copy link

hathach commented May 17, 2016

Board: Adafruit WICED Feather https://www.adafruit.com/product/3056
Issue: PWM with PA15 (Timer2 CH1) only start to work after 3-5 minutes.
Solution:
I have spent a few days to follow all the registers and dive into ST manuals to troubleshoot the issue. It turns out to be a very easy fix. As far as I know the EGR_UG bit must be set after setting the Preload to have preload value taking effect immediately. Otherwise, we will need to wait for 2-3 minutes before it starts to work !!!!!!!

Code : Moving Line 161 regs->EGR = TIMER_EGR_UG to right above the timer resume L178.
https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/STM32F4/cores/maple/boards.cpp#L161

static void timerDefaultConfig(timer_dev *dev) {
    timer_adv_reg_map *regs = (dev->regs).adv;
    const uint16 full_overflow = 0xFFFF;
    const uint16 half_duty = 0x8FFF;

    timer_init(dev);
    timer_pause(dev);

    regs->CR1 = TIMER_CR1_ARPE;
    regs->PSC = 1;
    regs->SR = 0;
    regs->DIER = 0;
//    regs->EGR = TIMER_EGR_UG; // MOVE FROM HERE

    switch (dev->type) {
    case TIMER_ADVANCED:
        regs->BDTR = TIMER_BDTR_MOE | TIMER_BDTR_LOCK_OFF;
        // fall-through
    case TIMER_GENERAL:
        timer_set_reload(dev, full_overflow);
        for (int channel = 1; channel <= 4; channel++) {
            timer_set_compare(dev, channel, half_duty);
            timer_oc_set_mode(dev, channel, TIMER_OC_MODE_PWM_1, TIMER_OC_PE);
        }
        // fall-through
    case TIMER_BASIC:
        break;
    }

    // UG must be placed after reload to take affect
    regs->EGR = TIMER_EGR_UG; // TO THIS LINE
    timer_resume(dev);
}
@rogerclarkmelbourne
Copy link
Owner

Thanks

I will see is @martinayotte has time to test for me on his F4 hardware

@ddrown
Copy link
Contributor

ddrown commented May 18, 2016

I tried this on my STM32F4 discovery board and can confirm the fix.

Test code:

int led = PA15;
int signalpin = PC11;
int brightness = 0;

void setup() {
  pinMode(led, PWM);
  gpio_set_af_mode(GPIOA,  15, 1); // we should probably do this in the pinMode code
  pinMode(signalpin, OUTPUT);
}

void loop() {
  digitalWrite(signalpin, HIGH);
  analogWrite(led, brightness);
  if(brightness == 0) {
    brightness = 32768;
  } else {
    brightness = 0;
  }

  delay(1);
  digitalWrite(signalpin, LOW);
  delay(29);
}

Before CH1/Yellow = PA15, CH2/Blue = PC11:

sds00002

After:

sds00001

The PWM output does eventually show up without the change.

@rogerclarkmelbourne
Copy link
Owner

rogerclarkmelbourne commented May 18, 2016

Thanks Dan

I'll do a merge straight on Github

Edit

Oops

I've realized this is not a PR.

Can you or the OP do this as a PR ?

@rogerclarkmelbourne
Copy link
Owner

Any chance of a PR for this ?

ddrown added a commit to ddrown/Arduino_STM32 that referenced this issue Jun 8, 2016
ddrown added a commit to ddrown/Arduino_STM32 that referenced this issue Jun 8, 2016
@martinayotte
Copy link
Contributor

Hi Roger,
Since I've never tried any PWM on F4, if it is working for @ddrown, I will agree that your can merge almost blindly, I will give it a try later when the "famous time ingredient" is coming back in stock :-)

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 a pull request may close this issue.

4 participants