FastPWM #513
Replies: 8 comments 5 replies
-
Yeah, it should be no problem, neopixels don't need any timers and servo needs only a type B timer. You didn't specify what part you're using so it's hard for me to give exact advice (anything except a 0-series will work great, 0-series you'll have to sacrifice millis/micros). All parts could do it by reconfiguring TCA0 to not prescale the system clock and set LPER or HPER to 99 (so 100 system clock ticks per cycle), and write the duty cycle in percent to the LCMP0/1/2 or HCMP0/1/2 register. Resolution would be limited to 100ths, like it would always be with a system clock of 10 MHz. Change to frequency would impact all 6 pins that TCA0 provides waveform output to; whichever half you changed the period for would run at the same frequency, while the other would run at 100/255ths of that (around 40kHz). 1-series parts could double the resolution by setting the core to use either TCB1 (if 16k+ of flash) or TCA0 (if 8k flash or less - within the 1-series, only parts with at least 16k of flash have the second type B timer, and you need the first for the servo) for millis timekeeping, and then run the TCD gauntlet. TCD0 is one of the most challenging peripherals to work with in all of the AVR product line - this is a requirement for the functionality it provides: most of the pain comes from the fact that it's not synchronous with the system clock, which is it's headline feature. Where this was sort of wallpapered over on classic AVRs that had an async timer, here there are too many reasons that wouldn't result in a satisfying product; they instead handle it correctly on the modern AVRs, at the expense of ease of use), and the rest of it is from the counter-intuitive manner in which the more sophisticated PWM is implemented. Since you haven't specifically requested it and I'd need to reread parts of the datasheet, I'm not going to go into any more depth on it. Possibly worth noting that the specs on all the modern AVRs are incredibly conservative, because the top end of the temperature range for the F-spec version exceeds the boiling point of water by a healthy margin, and they're rated for use in life safety critical applications like automotive stuff, where a system crash could lead to, well, a system crash... They will probably do 20@3V3 when T is around room temperature. Whether you'd want to take the risk of malfunction would of course depend on the power and value of the laser. And the value of anything downrange, for a sufficiently powerful laser.... |
Beta Was this translation helpful? Give feedback.
-
The FastPWM library probably only supports classic (aka legacy) AVRs. |
Beta Was this translation helpful? Give feedback.
-
Hello Spence,
Not sure Im qualified to answer that!!
Using a 1614 I just want something that will work without interfering with
the UART/WS2812/Servo/I2C
I dont intend doing anything else on this board.
Many thanks
Steve
…On Mon, 13 Sept 2021 at 02:46, Spence Konde (aka Dr. Azzy) < ***@***.***> wrote:
Using which timer?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#513 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJ5FYLQVRBENVNIQN2SCJJLUBVJWZANCNFSM5DFDMCRQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
Hi Spence, |
Beta Was this translation helpful? Give feedback.
-
Is your requirement 100 khz or 300 kHz? Seems to have jumped threefold? .. The key thing to recognize is, that you are up against the limits tfo the part in this regime - yoou'd have th timer runnning at the fastest clock it can (either system clock, opr TCD running from internal 20 MHz before it's divided in half. To set upcustom PWM, you can tell itr what period (integer values, units of ticks) how many ticks into the cycle before it turns offf ior turus off the output (I can't remember off hand whiche ones it which way aroun, I know in some cases I invert the values passed to analogWrite because they'r "backwards" (compssred to the arduino conventions. And you need to keep a timer for millis, one of the 2 type B timers for Servo and one to do the highspeed PWM. Are you doing any other sort of pwm, or just that one output (if you do need normal PWM, that means the type A imer is o a no-go because on the 1614, analogWrite() only uses the type A timer, the type B timers suck for making PWM anyway (though they are no worse) and megaTinyCore never uses them for that. Only the 20 and 24 pin parts have the analogWrite enabled for TCD0, because you don't get any pins that don't already have pwm on the 14-pin ones) |
Beta Was this translation helpful? Give feedback.
-
Hi Spence,
thanks for getting back. Firstly regarding spec. My laser controller will
be using an ICHAUS chip capable of running at 300KHz, naturally I wanted to
see what the effect of higher frequency would be. As the current solution
is usable at 20KHz ( limit of current laser PWM ), though I believe I can
see less noise compared to 5KHz, was curious to see effect at limit of the
new controller.
However in light of your comments, I guess that I could settle for a lower
frequency!
I would really like 8 bit resolution, so if I dont overclock then would I
be correct in saying the maximum frequency would be 20Mhz/256 or 78KHz?
Thats assuming I dont overclock, thats pretty incredible, but I dont think
I'll chance it.
So thats the laser taken care of.
As I said earlier the other peripherals I need to use are WS2812 LED, Servo
Library and UART, and of course your right, millis would be good!
I dont know what timers are required for these peripheral, but I dont need
additional pwm.
Based on this info i would really appreciate your suggestion for the best
fit soluion.
THanks
Steve
…On Fri, 15 Oct 2021 at 15:38, Spence Konde (aka Dr. Azzy) < ***@***.***> wrote:
Is your requirement 100 khz or 300 kHz? Seems to have jumped threefold? ..
The key thing to recognize is, that you are up against the limits tfo the
part in this regime - yoou'd have th timer runnning at the fastest clock it
can (either system clock, opr TCD running from internal 20 MHz before it's
divided in half. To set upcustom PWM, you can tell itr what period (integer
values, units of ticks) how many ticks into the cycle before it turns offf
ior turus off the output (I can't remember off hand whiche ones it which
way aroun, I know in some cases I invert the values passed to analogWrite
because they'r "backwards" (compssred to the arduino conventions.
at 10 MHz system clock, pwm at 100kHz is 1/100th system clock so you would
be able to adjust duty cycle vy 1/100ths (ie, 0-99 compared to 0 - 255 for
analogWrite). But uf you need 300 kHz, that's only 1/33rd of the system
clock, so you'd be able to adjust i units of 1/33rds ( ie, it's about 5 bis
of resolution. - you could get 1/33 or 2/33duty cycle, but never anything
between those. The type D would help, but it would only get you a factor of
2 (it can run from the internal oscillator without prescaling) TCD is an
incredibly powerful timer/ Unfortunately it's also nearly impossible to use
- and it's way more interesting on the Dx-series (which I think the
1-series was a testbed for) where even the incredibly conservative specs
say 48 MHz on the otherwise identical TCD is okay, and it's got an on-chip
pll to generate it. (I had it working fine at 128 MHz (yes you read that
right - 32 MHz (max rated speed is 24) with undocumented 4x PLL option
instead of the 2x and 3x options they advertise. It started glitching when
I tried 160 (40x4. The 40 MHz system clock worked though.))
And you need to keep a timer for millis, one of the 2 type B timers for
Servo and one to do the highspeed PWM.
Are you doing any other sort of pwm, or just that one output (if you do
need normal PWM, that means the type A imer is o a no-go because on the
1614, analogWrite() only uses the type A timer, the type B timers suck for
making PWM anyway (though they are no worse) and megaTinyCore never uses
them for that.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#513 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJ5FYLQQUEBUQM3HIVOJWFLUHA4F3ANCNFSM5DFDMCRQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
On TCA0, if you were running at 20 yeah, 78kHz soundsin the right area With no other PWM, getting much faster 8-bit PWM is easy, up until 1/256th of the system clock beyond which it's impossible. For TCA, you should be able keep using plain analog write it the precise speed is not critical and get much faster PWM
That one liner will drastically increase PWM frequency by changing prescaler of TCA from the default of 64 to 1. low bit of CTRLA is enable, rest of low nybble (bits 1-3) select the prescaler from 1, 2, 4, 8, 16, 64, 256, 1024 This will impact all PWM that relies on TCA0 (PB0, PB1, PB2, PA3 PA4 PA5 - everything you have on 14-pin parts), PWM still controlled by standard analogWrite() Now if you're actually running at 10 MHz not 20 that would be halved on TCA, (note: I would be surprised if it didn't actually run at 20 and 3.3 at room temp, I tried a few just now and the only thing that changed when I switched from 5v to 3.3 was that the power LED wasn't quite as bright. And I was doing it live, with a 1.5 cent switch controlling a pair of 1.5 cent highly suspicious mosfets (marketed as SI2301/2302 If you are in fact running at 10, the TCD can still generate PWM at the higher frequency, but it's a godawful thing to work with in that case, you'd need to pick either TCA or a TCB as millis (whichever TCB says it doesn't break servo, or the TCA is fine if you're not doing any direct register writes to and you can only use PA4 or PA5. (this uses PA4) nor can you use analogWrite() to control it.
You can't turn a channel on and off without disabling the timer so you can make the protected write to FAULTCTRL (the TCD is meant for driving things like the gates ofthe FETs in an H-bridge for motors or sync. rectified DC-DC converters, so they are terrified of a user accidentally causing shoot-through, an extremely destructive phenomenon. I actually realized that actually on DxCore, this is not that much harder the, because it supports frequency adjustment within it;'s analogWrite implementation (too too much flash to drag in here - people already give me shit about flash usage so I'm not going to pull in bulky code that 99% of people won't touch here). But on DxCore, though you still have to bounce the timer to change the prescaler, you can then set CMPBCLR to one of the magic values listed inthe docs, and then call analogWrite() on it as described in the TCD document linked off the readme, so all you'd need to in order to get fast PWM on the DX is to disable TCD0 wait for enabler eady, set CMPBCLR to 254 (only 254 and a few other (254)*(2^n)-1 values work correctly, and it's documented what they are). and then reenable it with the faster prescale (ie, no prescaling). and it would work with plain old analogWrite() :-P |
Beta Was this translation helpful? Give feedback.
-
Hi Spence,
Thanks for that information. Sorry its taken so long to get back,
everything got silly, but I now have a working prototype ( currently with
fastpwmpin and a 328) using a stepper rather than a servo ( using stepper.h
so probably need millis and micros).
I am running at 5V with an external supply for peripherals, so 20MHz no
problem.
TCA modification as specified works, and gives a FIXED 80KHz output. This
is not what fastpwmpin does
https://github.com/maxint-rd/FastPwmPin
enables you to set an individual pin to a range of frequencies. I guess
this really involves getting Maxint to port to your library.
Thanks
Steve
…On Mon, 18 Oct 2021 at 19:34, Spence Konde (aka Dr. Azzy) < ***@***.***> wrote:
On TCA0, *if you were running at 20* yeah, 78kHz soundsin the right area
With no other PWM, getting much faster 8-bit PWM is easy, up until 1/256th
of the system clock beyond which it's impossible.
For TCA, you should be able keep using plain analog write it the precise
speed is not critical and get much faster PWM
#if defined(MILLIS_USE_TIMERD0)
#error "Millis timer must not be the same as the timer used for HS PWM"
#endif
// in setup
TCA0.SPLIT.CTRLA = 1; // Only prescaler is changed, (it is originally set to 0x0B as I recall.
// the core configured it in split mode for 2 banks of 3x 8bit downcounting fast PWM
// channels (in single mode, you get 1 bank of 3 16-bit pwm channels which can count up or down, or up-and-down (dual slope)
That one liner will drastically increase PWM frequency by changing
prescaler of TCA from the default of 64 to 1. low bit of CTRLA is enable,
rest of low nybble (bits 1-3) select the prescaler from 1, 2, 4, 8, 16, 64,
256, 1024
This will impact all PWM that relies on TCA0 (PB0, PB1, PB2, PA3 PA4 PA5 -
everything you have on 14-pin parts), PWM still controlled by standard
analogWrite()
Now if you're actually running at 10 MHz not 20 that would be halved on
TCA, (note: I would be surprised if it didn't actually run at 20 and 3.3 at
room temp, I tried a few just now and the only thing that changed when I
switched from 5v to 3.3 was that the power LED wasn't quite as bright. And
I was doing it live, with a 1.5 cent switch controlling a pair of 1.5 cent
highly suspicious mosfets (marketed as SI2301/2302
If you are in fact running at 10, the TCD can still generate PWM at the
higher frequency, but it's a godawful thing to work with
in that case, you'd need to pick either TCA or a TCB as millis (whichever
TCB says it doesn't break servo, or the TCA is fine if you're not doing any
direct register writes to and you can only use PA4 or PA5. (this uses PA4)
nor can you use analogWrite() to control it.
#if defined(MILLIS_USE_TIMERD0)
#error "Millis timer must not be the same as the timer used for HS PWM"
#endif
void init_TCD0() { // override initialization with empty function ti disable it
}
void setup() {
//takeOverTCD0(); // (on 20 and 24 pin parts this is needed, on 14 pin, no difference in outcome.
pinMode(PIN_PA4,OUTPUT);
TCD0.CMPBCLR = 254; //(counts from 0 to 254, in 255 ticks. meaning that writing 255 will ourtput a constant value
//TCD0.CTRLB =0; //unneeded. this is default setting One Ramp mode..
_PROTECTED_WRITE(TCD0_FAULTCTRL,TCD_CMPAEN_bm); // enable locked AND under CCP!
TCD0,CMPASET = (255-InitialDutyCycle);
while (!(TCD0.STATUS & TCD_ENRDY_bm)) {
; poll until enable ready
}
TCD0.CTRLA = 1; // the enable flag only will stqart it /1 sync, /1 count prescaler from internal HF oscillator- -0 is the fastest option for all prescalers
/ * rest of setup */
}
void setTCD_duty_A(uint8_t dutycycle) {
TCD0.CMPASET=255-dutycycle;
while (!(TCD0.STATUS& TCD_CMDRDY_bm)) {
;
}
TCD0.CTRLE = TCD_SYNCEOC_bm; //tell it to sync this at the end of the current tcd cycle
}
You can't turn a channel on and off without disabling the timer so you can
make the protected write to FAULTCTRL (the TCD is meant for driving things
like the gates ofthe FETs in an H-bridge for motors or sync. rectified
DC-DC converters, so they are terrified of a user accidentally causing
shoot-through, an extremely destructive phenomenon.
I actually realized that actually on DxCore, this is not that much harder
the, because it supports frequency adjustment within it;'s analogWrite
implementation (too too much flash to drag in here - people already give me
shit about flash usage so I'm not going to pull in bulky code that 99% of
people won't touch here). But on DxCore, though you still have to bounce
the timer to change the prescaler, you can then set CMPBCLR to one of the
magic values listed inthe docs, and then call analogWrite() on it as
described in the TCD document linked off the readme, so all you'd need to
in order to get fast PWM on the DX is to disable TCD0 wait for enabler
eady, set CMPBCLR to 254 (only 254 and a few other (254)*(2^n)-1 values
work correctly, and it's documented what they are). and then reenable it
with the faster prescale (ie, no prescaling). and it would work with plain
old analogWrite() :-P
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#513 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJ5FYLQTW4J5PAOMJMGCABDUHRSBVANCNFSM5DFDMCRQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
I really love these parts,
but I am struggling on how to get PWM running at 100khz+( driving a laser), exacerbated by needing to run at 3.3V so max clock 10Mhz. I only need one pin, BUT I also need to run neopixel and one servo. I have this running on a Nano at 5v using FastPWM library, not tested with Neopixel yet.
Is this doable, and any guidance please?
Thanks
Steve
Beta Was this translation helpful? Give feedback.
All reactions