[Libmaple] pinMode() disables timer even if no PWM mode involved

LibMaple (The core that Roger's repo uses)
rmdMoba
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: pinMode() disables timer even if no PWM mode involved

Post by rmdMoba » Fri May 19, 2017 9:36 pm

victor_pv wrote: or you were using the normal ones, then if you switch to the alternate ones for SPI1 then PWM works again?
That's it

victor_pv
Posts: 1681
Joined: Mon Apr 27, 2015 12:12 pm

Re: pinMode() disables timer even if no PWM mode involved

Post by victor_pv » Fri May 19, 2017 9:38 pm

rmdMoba wrote:
victor_pv wrote: or you were using the normal ones, then if you switch to the alternate ones for SPI1 then PWM works again?
That's it
So it is something related to the original pins still being linked to the SPI and possible hold in a certain state.
Did you check if the end() method for the SPI port disables the SPI peripheral? perhaps that's all that's needed and for some reason is not yet in the spi code.

rmdMoba
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: pinMode() disables timer even if no PWM mode involved

Post by rmdMoba » Fri May 19, 2017 9:42 pm

victor_pv wrote: Did you check if the end() method for the SPI port disables the SPI peripheral?
It seems to do so ...

Code: Select all

void SPIClass::end(void) {
    if (!spi_is_enabled(_currentSetting->spi_d)) {
        return;
    }

    // Follows RM0008's sequence for disabling a SPI in master/slave
    // full duplex mode.
    while (spi_is_rx_nonempty(_currentSetting->spi_d)) {
        // FIXME [0.1.0] remove this once you have an interrupt based driver
        volatile uint16 rx __attribute__((unused)) = spi_rx_reg(_currentSetting->spi_d);
    }
    while (!spi_is_tx_empty(_currentSetting->spi_d))
        ;
    while (spi_is_busy(_currentSetting->spi_d))
        ;
    spi_peripheral_disable(_currentSetting->spi_d);
}

rmdMoba
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: pinMode() disables timer even if no PWM mode involved

Post by rmdMoba » Sat May 20, 2017 2:39 pm

After several tests I did not find a reason why pwm doesn't work again after SPI has been active. The only solution I found is to remap the SPI pins ( or execute a hardware reset ). It seems that SPI blocks the AF on this pin if it once has been activated. Even setting all SPI registers back to '0' (the state after reset ) does not help. The same seems to be true on pins that share UART and PWM as AF.

Because PWM works after remapping SPI this is obviously not a problem of PWM/timer channel configuration.

The changes to pinMode() now don't stop attached IRQ's when setting non PWM modes. The latest version of the fix is like this:

Code: Select all

    if (PIN_MAP[pin].timer_device != NULL) {
        if ( pwm ) { // we're switching into PWM, enable timer channels
        timer_set_mode(PIN_MAP[pin].timer_device,
                       PIN_MAP[pin].timer_channel,
                       TIMER_PWM );
        } else {  // disable channel output in non pwm-Mode             
            timer_cc_disable(PIN_MAP[pin].timer_device, 
                            PIN_MAP[pin].timer_channel); 
        }
    }
In non PWM mode the timer channel is disconnected from the pin, but nothing else is changed in timer/channel configuration. This worked fine in all my tests, and so I will create a pull request on Github soon.

User avatar
RogerClark
Posts: 7158
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: pinMode() disables timer even if no PWM mode involved

Post by RogerClark » Fri May 26, 2017 7:04 am

Can we change this one step at a time.

I think we've established that pinMode does not need to disable the whole timer

Can a PR be generated for just the pinMode change

The SPI issue looks more complicated and can be applied separately to the pinMode change

edogaldo
Posts: 281
Joined: Fri Jun 03, 2016 8:19 am

Re: pinMode() disables timer even if no PWM mode involved

Post by edogaldo » Fri May 26, 2017 7:27 am

RogerClark wrote:Can a PR be generated for just the pinMode change
Hi Roger, there is PR #288 which addresses it but I don't understand why the guy added a second commit which, on my opinion, breaks things again..
I think the 1st commit only is ok (there's just the need to also modify the commit which still talks about disabling the timer..).
Add my comments also in the PR.

Best, E.

stevestrong
Posts: 1747
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: pinMode() disables timer even if no PWM mode involved

Post by stevestrong » Fri May 26, 2017 7:33 am

edogaldo wrote: Hi Roger, there is PR #288 which addresses it but I don't understand why the guy added a second commit which, on my opinion, breaks things again..
edogaldo, can you please detail which things exactly get broken with this PR?

edogaldo
Posts: 281
Joined: Fri Jun 03, 2016 8:19 am

Re: pinMode() disables timer even if no PWM mode involved

Post by edogaldo » Fri May 26, 2017 7:41 am

stevestrong wrote:edogaldo, can you please detail which things exactly get broken with this PR?
Hi Steve, I'm in doubt with this part:

Code: Select all

        } else {  // disable channel output in non pwm-Mode             
            timer_cc_disable(PIN_MAP[pin].timer_device,
                            PIN_MAP[pin].timer_channel);
        }
A question as I'm not that expert with timers: can't we have any valid combination (also in a possible future variant) in which 2 pins can map to the same couple {timer, channel}?

User avatar
RogerClark
Posts: 7158
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: pinMode() disables timer even if no PWM mode involved

Post by RogerClark » Fri May 26, 2017 7:42 am


rmdMoba
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: pinMode() disables timer even if no PWM mode involved

Post by rmdMoba » Fri May 26, 2017 12:26 pm

edogaldo wrote:A question as I'm not that expert with timers: can't we have any valid combination (also in a possible future variant) in which 2 pins can map to the same couple {timer, channel}?
No, that's not possible.

Post Reply