-
-
Notifications
You must be signed in to change notification settings - Fork 345
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
Initial functioning version of ESP32 HardwarePWM. #2599
Conversation
|
I've added a number of toughts as a comment to the cpp file but don't want to open a new PR for just that, so I post it here for discussion
Not sure what a good implementation for a more abstract interface is. Maybe a baseclass / SoC specific implementation class scheme to implement generic functions in software and provide SoC specific capabilities plus extensions where available? That's how the adafruit gfx library builds it for specific hardware. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start, thank you! In general just a little tidying.
(sorry for takign some more time, I was travelling and then sick for two weeks - will get to this soon) |
ok, I'm sorry if this is now very muddled, but I believe I got lost in git here - for reasons I don't understand, both, the .h as well as the .cpp file were repeatedly lost by git and no longer tracked. I think, now it's all there |
…e ESP32C3 with up to 5kHz pwm frequency.
This reverts commit 7279c66.
…ter goofing up with git Sigh)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've rebased and done some tidying but code functionality hasn't been changed.
Couple of points to consider regarding return values for invalid period/frequency and how update() works.
what's that remaining change request? I can't seem to see it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, just remove those unused variables
uint32_t io_info[SOC_LEDC_CHANNEL_NUM][3]; // pin information | ||
uint32_t pwm_duty_init[SOC_LEDC_CHANNEL_NUM]; // pwm duty | ||
for(uint8_t i = 0; i < no_of_pins; i++) { | ||
pwm_duty_init[i] = 0; // Start with zero output |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
io_info
and pwm_duty_init
aren't used, please remove
@pljakobs Please run the coding style fixer. The following file has an issue:
|
@pljakobs Also fix the typos reported here: https://github.com/SmingHub/Sming/pull/2599/files#diff-647d65279a6f999683c4cd320288f28dd4f901ca8a4eba5a75f1c9e2ad4ff451 |
@@ -122,6 +122,11 @@ class HardwarePWM | |||
*/ | |||
void update(); | |||
|
|||
/** @brief Get PWM Frequency |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add also
@param pin GPIO to get frequency for
you guys are thorrough! hope I caught it all by now. Also - can I get some feedback on the other implementation that I've started (#2624)? |
…t iteraton as they are already underway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good to me. There are still few coding style and return value issues that have to be fixed before merging this PR.
|
||
uint32_t periodToFrequency(uint32_t period) | ||
{ | ||
return (period == 0) ? -1 : (1000000 / period); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, change the return value to be a valid uint32_t. -1 is not a valid unsigned int.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
uint32_t frequencyToPeriod(uint32_t freq) | ||
{ | ||
return (freq == 0) ? -1 : (1000000 / freq); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, change the return value to be a valid uint32_t. -1 is not a valid unsigned int.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
{ | ||
for(uint8_t i = 0; i < channel_count; i++) { | ||
if(channels[i] == pin) { | ||
// debug_d("getChannel %d is %d", pin, i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either remove the commented line or uncomment it. I would prefer to have it removed if it is not improving the debug output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
#include <Clock.h> | ||
#include "ESP8266EX.h" | ||
#include <debug_progmem.h> | ||
|
||
#include <HardwarePWM.h> | ||
|
||
#define PERIOD_TO_MAX_DUTY(x) (x * 25) | ||
|
||
HardwarePWM::HardwarePWM(uint8_t* pins, uint8_t no_of_pins) : channel_count(no_of_pins) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, keep close to Sming's coding style: https://sming.readthedocs.io/en/latest/information/develop/coding-style.html?highlight=Variables#naming.
Local variables, instance variables, and class variables must also be written in lowerCamelCase. Variable names must not start with, end with or contain underscore (_) or dollar sign ($) characters.
For example in the code here uint8_t no_of_pins
should be renamed to uint8_t numberOfPins
, uint32_t io_info[PWM_CHANNEL_NUM_MAX][3];
-> uint32_t ioInfo[PWM_CHANNEL_NUM_MAX][3];
, uint32_t pwm_duty_init[PWM_CHANNEL_NUM_MAX]
-> uint32_t pwmDutyInit[PWM_CHANNEL_NUM_MAX]
and so on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so no_of_pins is part of the core interface definition, if I rename that, I should probably also rename it for the other architectures - should this be part of this PR or may be a PR of it's own?
I believe, all other occurences of underscored names are defined in the esp32 ledc interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be part of this PR or may be a PR of it's own
Leave it for another PR. This one waited already for too long to be merged.
I believe, all other occurences of underscored names are defined in the esp32 ledc interface.
Please, rename all local variables in the code that you have introduced to use lowerCamelCase . Example:
uint32_t io_info[PWM_CHANNEL_NUM_MAX][3]; // pin information
uint32_t pwm_duty_init[PWM_CHANNEL_NUM_MAX]; // pwm duty
// ...
const int initial_period = 1000;
and so on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't use those, they are part of the original ESP8266 version and are used both there and in the RP2040 implementation. I'll go ahead and rename them all and send a separate PR.
uint8_t HardwarePWM::getChannel(uint8_t pin) | ||
{ | ||
for(uint8_t i = 0; i < channel_count; i++) { | ||
if(channels[i] == pin) { | ||
//debugf("getChannel %d is %d", pin, i); | ||
// debug_d("getChannel %d is %d", pin, i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented debug statements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this really part of my PR? I have not touched the 8266 code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was me! See commit eaf77f9 - there's a new getFrequency
method which is required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I was really confused for a moment now. I have renamed the local vars to comply with camelCase now, not yet removed the debug calls. I think some of them are worthy of being there and functional, so I will uncomment them
return i; | ||
} | ||
} | ||
//debugf("getChannel: can't find pin %d", pin); | ||
|
||
// debug_d("getChannel: can't find pin %d", pin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove commented debug statements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} | ||
|
||
debugf("Duty cycle value too high for current period."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace debugf
with debug_w
. And include also the duty cycle value to make the debug statement more useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
sice I've deleted my earlier, confused comment, I'll say it again: |
@pljakobs Thank you for your contribution and congratulations for your first merged PR :) |
a few weeks ago I said I would take a swing at implementing HardwarePWM for the ESP32 Platform and here it is.
This is very preliminary and does not extend the api a lot (in fact, the only public function is curently HardwarePWM::getFrequency(uint8_t pin) which I used in debugging).
I would go ahead and extend the interface to expose the more advanced functions of ledc_ bt would appreciate your input on how to do so. My current thinking is that I put conditionals into the master HardwarePWM.h - but conditionals can make code very hard to read if the number of platforms gets too large.