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

Feature: Hardware PWM #568

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft

Feature: Hardware PWM #568

wants to merge 11 commits into from

Conversation

stephenhensley
Copy link
Collaborator

summary

This PR introduces methods of controlling the TIM Channels to do hardware PWM via libDaisy.

This provides typical usage for pins exposed via Daisy Seed, and other official SOMs, as well as DMA control for driving things like Neopixels.

The current API (which I'd like to change) involves:

  1. Configure the TimerHandle
  2. Initialize the TimerHandle
  3. Configure a TimChannel object with the Channel, mode, polarity, and pin.
  4. Initialize the TimChannel
  5. Start with TimChannel::StartPwm, the start the timer with TimerHandle::Start.

For normal PWM, you can use the TimChannel::SetPwm function to set the value in real time.

For controlling things (like Neopixel LEDs) via DMA it gets a little more complicated.


There are some general improvements to initialization/starting that I feel like could be built into the TimerHandle object instead of being an entire new class.

In addition there's a bit of leftover work to make a more user-friendly driver for neopixels.
This also has the current limitation of only being able to run a single LED strip at a time, without doing some unique sequencing, or making some changes to the implementation.

@stephenhensley stephenhensley marked this pull request as draft February 13, 2023 17:44
@github-actions
Copy link

Unit Test Results

150 tests   150 ✔️  0s ⏱️
  16 suites      0 💤
    1 files        0

Results for commit 1bcfbfe.

// const int kZeroTime = kTickPeriod - 8;
const size_t kTickPeriod = 29;
// const size_t kTickPeriod = 59;
const int kOneTime = 20;
Copy link

Choose a reason for hiding this comment

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

It might make sense here to provide a number of examples alongside different LED controllers. I know there are minor differences between vendors (though mostly it comes out in the wash).

For my example with one of either the WS2812B or SK6812 (unknown which I have on these "neopixel" items), I had MUCH higher reliability with many neopixels (28) setting kOneTime to 14 and kZeroTime to 9, while changing line 114 to chn_cfg.polarity = TimChannel::Config::Polarity::HIGH; (from ::LOW).

I haven't analyzed the waveform yet to determine exactly how the polarity affects things, but my results were VERY unreliable before I set polarity ::HIGH.

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.

None yet

2 participants