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

Pico - only one PWM pin is set #287

Merged
merged 4 commits into from
Nov 30, 2023
Merged

Conversation

elral
Copy link
Collaborator

@elral elral commented Nov 27, 2023

Description of changes

Further evaluation of issue #283 showed that PR #285 didn't solve the issue.
Pico is limited to one bank of 16 PWM timer starting at Pin 0. If using a pin > 15 also as PWM output, these pins get doubled.
E.g. using pin 2 as PWM output and unsing pin 18 as PWM output each change on pin 2 or pin 18 will also set the other one.
If one of these pins are used as a digital output everything is fine.

Within the code for the outputs analogWrite() is always used toset an output. Doing it this way each pin is used as PWM output for the Pico and the above problem occurs. The only way to solve it is to use only the first 16 pins as PWM output. This change will be done in a separate PR to adapt the raspberrypi_pico.board.json by setting "isPWM": false for pins > 15. So for pins > 15 the value for setting the pin will either be 0 or 255.
Within the FW it has to check if the value for each pin is 0 or 255. In this case digitalWrite() is used instead of analogWrite() which avoids setting the output as PWM.
This change is only done for the Pico, for AVR's it is kept as it is to not raise another potential problem (which I can not see, just to be absolutely sure).

Fixes #283

@elral elral requested a review from DocMoebiuz as a code owner November 27, 2023 07:37
Copy link
Collaborator

@DocMoebiuz DocMoebiuz left a comment

Choose a reason for hiding this comment

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

see my comments - have you thought about it?

#endif
}

void MFOutput::set(uint8_t value)
{
_value = value;
#if defined(ARDUINO_ARCH_RP2040)
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think it would be easier to read if we introduce a deviated method like

setRp2040 and then put the custom logic there instead of having everything inline

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmhm, in this case the CommandMessenger.cpp must also be changed:

#if defined(ARDUINO_ARCH_RP2040)
    cmdMessenger.attach(kSetPin, Output::OnSetRP2040);
#else
    cmdMessenger.attach(kSetPin, Output::OnSet);
#endif

Due to the differnet pinMode initialization MFOutput.cpp would look like:

void MFOutput::attach(uint8_t pin)
{
    _pin   = pin;
    pinMode(_pin, OUTPUT);
    analogWrite(pin, LOW);
}

#if defined(ARDUINO_ARCH_RP2040)
void MFOutput::attachRP2040(uint8_t pin)
{
    _pin   = pin;
    pinMode(_pin, OUTPUT_12MA);
    digitalWrite(_pin, LOW);
}
#endif

And Output.cpp must be as:

#if defined(ARDUINO_ARCH_RP2040)
        outputs[outputsRegistered].attachRP2040(pin);
#else
        outputs[outputsRegistered].attach(pin);
#endif

Not sure if this increases readability, also as the CommandMessegner.cpp must also be changed (changes not as much bundled as before).

Copy link
Collaborator

Choose a reason for hiding this comment

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

i was thinking of a private local method only - nothing fancy

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

After some more testing the logic from Pico to set outputs can also be used for AVR's.
So I wouldn't differ anymore between both. Just for setting pinMode() it has to be differ betwenn AVR and Pico.

The class MFOutput() is "only" needed for setting the pinMode and setting the powersave Mode.
I am wondering if we still need this class, both could also be done within Output.cpp like setting the output.

// Set led
analogWrite(pin, state); // why does the UI sends the pin number and not the x.th output number like other devices?
// output[pin].set(state); // once this is changed uncomment this
#if defined(ARDUINO_ARCH_RP2040)
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here

Copy link

Firmware for this pull request:
Firmware.zip

Copy link

Firmware for this pull request:
Firmware.zip

@DocMoebiuz DocMoebiuz merged commit ff05429 into MobiFlight:main Nov 30, 2023
@DocMoebiuz DocMoebiuz added the bug Something isn't working label Dec 2, 2023
@DocMoebiuz DocMoebiuz changed the title Double set pin Pico - two PWM pins are set at the same time Dec 2, 2023
@DocMoebiuz DocMoebiuz changed the title Pico - two PWM pins are set at the same time Pico - only one PWM pins are set at the same time Dec 2, 2023
@DocMoebiuz DocMoebiuz changed the title Pico - only one PWM pins are set at the same time Pico - only one PWM pin is set Dec 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Two Pins get set at the same time on Pico
2 participants