OK, starting to get the idea now, I am still not completely familiar with the opcodes but enough to see the idea. You have packed duty and dither into the same 32bit variable just by bit shifting and adding, then bit shift them out again. Not sure what 9b.Reg Base is ?
In the smallest lines possible code, the MOVD opcode needs a opcpode memory address, which is 9 bits. This is is the base into either of the two table of 32 entries of pattern, it can be added locally, with 1 opcode, in which case just 5 bits are needed from Host, and host no longer needs to care where the arrays are.
Basically, you can save 8 cy, if the host passes a pre-added number - the down side is more house-keeping, and slightly more host code.
An idea of my own,,,, as the update of my PWM duty does not need to be every cycle things could be eased by alternating the between RDLONGing new Ch1 and Ch2 values, you think ? Although somewhat complicated by the dithering, but even then we could only refresh every 16th time.
Yes, if you want to trade off update rate with loop-time, that could be done.
The Period is also updated every loop as well.
Note that the code above dither-conditionally adds 1 to the PWMvalue register, which is safe only if it is reloaded every pass.
So you need to add a save line, and a branch choice for which to load, plus some variable to define branch...
Unless power matters, the time budget is only an issue if you run out of it..
My back-of-envelope calcs show a time of 97, so it should be comfortable @ 128 and work down close to 100 periods. (~800Khz)
For your new info of the option of 22-25Khz PWM, then dither could be set at 00, (one pattern is no adders) and period of ~12 bits used.
Period is 1cy granular, so your choices are
22.002200 KHz, 22.008253 KHz etc
Because you can vary both Period and Hi-Time, you can gain some more precision by allowing 10/128 10/129 10/130 etc (but note that period is COG shared, so this has caveats )
The XOR gate is necessary in order to achieve full 0--100% coverage, with a switchover at the 50% point. The XOR is not necessary if you can get by with 50% coverage, or if you can spare a 3rd counter to use as an inverter. The code is all Spin, no pasm, but it achieves a PWM frequency of CLKFREQ/resolution/2, or 400 kHz with 80MHz clock and 100 steps.
The idea of expanding something like that to use a master clock (or pair) is intriguing, but will take some ad-hoc tricks to implement if the other cogs have to be executing other spin and pasm tasks.
The XOR gate is necessary in order to achieve full 0--100% coverage...
I think that is also possible with original AN001, as values well away from a count boundary, will never give a pin change.
I've realised that the packed option above lost the wide dynamic range, so adding a SAR (sign extends) is a better way to allow params to pass MSB to the pin, and so get DC control, for 0% and 100% cases.
Code above edited to sar from ror.
Comments
In the smallest lines possible code, the MOVD opcode needs a opcpode memory address, which is 9 bits. This is is the base into either of the two table of 32 entries of pattern, it can be added locally, with 1 opcode, in which case just 5 bits are needed from Host, and host no longer needs to care where the arrays are.
Basically, you can save 8 cy, if the host passes a pre-added number - the down side is more house-keeping, and slightly more host code.
Yes, if you want to trade off update rate with loop-time, that could be done.
The Period is also updated every loop as well.
Note that the code above dither-conditionally adds 1 to the PWMvalue register, which is safe only if it is reloaded every pass.
So you need to add a save line, and a branch choice for which to load, plus some variable to define branch...
Unless power matters, the time budget is only an issue if you run out of it..
My back-of-envelope calcs show a time of 97, so it should be comfortable @ 128 and work down close to 100 periods. (~800Khz)
For your new info of the option of 22-25Khz PWM, then dither could be set at 00, (one pattern is no adders) and period of ~12 bits used.
Period is 1cy granular, so your choices are
22.002200 KHz, 22.008253 KHz etc
Because you can vary both Period and Hi-Time, you can gain some more precision by allowing 10/128 10/129 10/130 etc (but note that period is COG shared, so this has caveats )
http://obex.parallax.com/objects/668/
The XOR gate is necessary in order to achieve full 0--100% coverage, with a switchover at the 50% point. The XOR is not necessary if you can get by with 50% coverage, or if you can spare a 3rd counter to use as an inverter. The code is all Spin, no pasm, but it achieves a PWM frequency of CLKFREQ/resolution/2, or 400 kHz with 80MHz clock and 100 steps.
The idea of expanding something like that to use a master clock (or pair) is intriguing, but will take some ad-hoc tricks to implement if the other cogs have to be executing other spin and pasm tasks.
I think that is also possible with original AN001, as values well away from a count boundary, will never give a pin change.
I've realised that the packed option above lost the wide dynamic range, so adding a SAR (sign extends) is a better way to allow params to pass MSB to the pin, and so get DC control, for 0% and 100% cases.
Code above edited to sar from ror.