Conversation
wiring_analog_* : fallback to digitalWrite if no available PWM channel (copied from AVR core) wiring_analog_nRF52.c : convert pwmChannelPins & pwmChannelSequence -> pwmContext to semi-standardise pwm pin allocation and pwm status between nRF51 and nRF52 wiring_private.h : Move pwm structures defines out of wiring_analog_* into wiring_private and make the instantiation of these structure externs instead of statics wiring_digital.c : disable the appropriate pwm timer when a digitalWrite is sent to an allocated (from analogWrite) pwm pin, and free up the pwm channel for re-allocation
|
Tidy-up of #193 |
sandeepmistry
left a comment
There was a problem hiding this comment.
@micooke Thanks for submitting!
| } | ||
|
|
||
| // fallback to digitalWrite if no available PWM channel | ||
| if (ulValue < 128) |
There was a problem hiding this comment.
Can the write resolution be higher than 8-bits? If so, we need to adjust this.
There was a problem hiding this comment.
Yes, and on it!
One thing i noticed is that the read and write resolution isnt bounded and for the NRF52 they are stored as signed integers so you could set the read or write resolution to +/-2e9!
If its alright ill add a static int with the half max value and a switch statement to set it in writeResolution so that valid values are used (and so they arent re-calculated on each analogWrite)
There was a problem hiding this comment.
For reference;
- nRF51 TIMER1 (the only timer currently used for PWM) is either 8b or 16b write resolution
- nRF52 is up to 32b write resolution for all 12 PWM channels
|
|
||
| ulPin = g_ADigitalPinMap[ulPin]; | ||
|
|
||
| for (uint8_t i = 0; i < PWM_COUNT; i++) |
There was a problem hiding this comment.
What do you think about moving this to a private analogWriteOff (or something with a better name) function in cores/nRF5/wiring_analog_nRF5x.c?
There was a problem hiding this comment.
Rather than creating another function I could change analogWrite so that it turns off PWM when a duty cycle of zero is passed?
Its up to what you prefer as you are the owner and this affects the API. Either implementation is easy to implement.
|
Ok, can of worms officially opened 💥 |
|
Sorry i should have asked, @sandeepmistry , @dlabun - do you want me to fix the nRF52 PWM channel issue here or in a separate PR? The two issues are somewhat linked in that to enable the extra pwm i need to add another parameter in the PWMContext structure, which will then require me to update how the TIMER/PWM modules are turned off. |
|
Sure, go for it. |
| } | ||
| else | ||
| { | ||
| digitalWrite(ulPin, LOW); |
There was a problem hiding this comment.
Should be HIGH - copy/paste error
| } | ||
| else | ||
| { | ||
| digitalWrite(ulPin, LOW); |
There was a problem hiding this comment.
The same copy/paste error again
…s with M channels each) * replace static 8b resolution for nRF51 and nRF52 with user-defined up to 16b resolution * enable 6x PWM signals for nRF51 (up from 3) * enable 12x PWM signals for nRF52 (up from 3) * disable / free-up PWM signals when ZERO is written as the analog value analogWrite(PIN, 0)
|
Update :
The nRF51 now uses TIMER2 as well as TIMER1. As i have said before, the softdevice uses TIMER0 so i didn't touch that. The nRF5x documentation is lacking pretty severely compared to the AVR chips I have dealt with. Im very surprised but the implementation for the nRF51 uses software to set/clear the hardware pins. It also uses the first channel as the period interrupt, rather than having a separate overflow interrupt (which can be seen in the RBL core and several Nordic source code). It basically looks like PWM is implemented rather poorly in the nRF51, and i guess that is the reason that the nRF52 has dedicated PWM channels. |
|
@micooke Any issues with merging this fix? |
|
Let’s hold off on this one for a bit ... |
|
Hi @sandeepmistry, is there an issue with this PR I haven't addressed or does it just need more testing? |
|
The idea for that was actually copied from the Arduino AVR core Which uses |
wiring_analog_* : fallback to digitalWrite if no available PWM channel (copied from AVR core)
wiring_analog_nRF52.c : convert pwmChannelPins & pwmChannelSequence -> pwmContext to semi-standardise pwm pin allocation and pwm status between nRF51 and nRF52
wiring_private.h : Move pwm structures defines out of wiring_analog_* into wiring_private and make the instantiation of these structure externs instead of statics
wiring_digital.c : disable the appropriate pwm timer when a digitalWrite is sent to an allocated (from analogWrite) pwm pin, and free up the pwm channel for re-allocation