SpenceKonde / megaTinyCore

Arduino core for the tinyAVR 0/1/2-series - Ones's digit 2,4,5,7 (pincount, 8,14,20,24), tens digit 0, 1, or 2 (featureset), preceded by flash in kb. Library maintainers: porting help available!
Other
551 stars 142 forks source link

PWM trace difference between setting analogWrite ("0" and "0+N") on 412 #271

Closed ldalep closed 3 years ago

ldalep commented 3 years ago

This is a follow on to issue #261 I set up the following sketch using PIN_PA3 as a PWM pin with a trigger/marker digital pin PIN_PA1. I ran the sketch twice changing the the PWM pin sequence from 0,1,200 to 1,2,200 with delays of 25ms, 5msec, 5msec. This was done at 20Mhz and Default timer, Code 2.1.5. In both cases I ran a trace (Sampled at 12Mhz.... kinda slow) which are shown below

0,1,200 - Note that extra Pulse width on the transition from 0-1. Also there is an immediate transition to 0 level when going from 200 to 0.

0,1,200

1,2,200 - Note the difference from 200 -1

1,2,200 PWm

unsigned long t = 0; byte output_pwm_pin = PIN_PA3;

void setup() { pinMode(output_pwm_pin, OUTPUT); pinMode(PIN_PA1,OUTPUT); }

void loop() { // put your main code here, to run repeatedly:

PORTA.OUT |= PIN1_bm; // High Marker and Trigger analogWrite(output_pwm_pin,0); // Change here for "0 to 1" t=micros(); while ((micros() - t) < 25000) ;

PORTA.OUT &=~PIN1_bm; // Low analogWrite(output_pwm_pin,1); // Change here for "1 -2" t=micros(); while ((micros() - t) < 5000) ;

PORTA.OUT |= PIN1_bm; // High Marker PORTA.OUT &=~PIN1_bm; // Low

analogWrite(output_pwm_pin,200); ///blink at about 200 pwm t=micros(); while ((micros() - t) < 5000) ;

}

SpenceKonde commented 3 years ago

Second trace is correct behavior, when reducing the duty cycle, changes will never take effect until the start of the next pwm cycle.

First trace is the sort of glitch I thought might occur in one of the other threads, but he specifically never went all the way to 0, so that particular situation (non-pwm to pwm) was excluded. While there may be some simple half-measure mitigations to make the 0-to-non-0 case non-perverse. possible in time for next release, any sort of serious mitigation will need to wait until the one after that - lot of demand for fixes in current release to be rolled out to board manager, and cannot justify such a delay.

SpenceKonde commented 3 years ago

Immediate transition to 0 is also expected on analogWrite(pin,0) as that straight up turns off PWM entirely.

SpenceKonde commented 3 years ago

Oh, and don't get in the habit of PORTA.OUT|= or &= - use VPORTA.OUT|= or &= to get single cycle writes that are interrupt safe (works only when value written has a single 1 or single 0 and is compiletime known, otherwise it's a multicycle non-interrupt-safe R/M/W), or if setting more than 1 bit or value isn't compiletime known, use PORTA.OUTSET= / PORTA.OUTCLR= / PORTA.OUTTGL= (not |= or &= - those read as PORTA.OUT!) for an interrupt safe multicycle (3 clocks if value compiletime known - LDI put value in working register, STS to write to the relevant PORTx.OUTyyy register... or 2 + calculation time of value to write if it's not) write. PORTA.OUT|= is 6 cycles (LDS, ORI, STS) if compiletime known, or 6+calculation time if not, but not interrupt safe against ISR modifying different pin on same port (you could revert the interrupt's change).

ldalep commented 3 years ago

Thank you for the heads up on my habit ..... As for the "make the 0-to-non-0 case non-perverse" this would be great considering this is done a lot in LED land

SpenceKonde commented 3 years ago

Want to check if what's in github now works and hasn't introduced new bugs? I don't have time to actually test it on hardware, and I may also have broken other things with recent changes, but have a huuuuge to-do list right now.

ldalep commented 3 years ago

Well I get a totally different wave - missing everything before the imposing of 0

Screen Shot 2020-12-03 at 12 19 42 PM
SpenceKonde commented 3 years ago

Is this with the latest version of the core? Because this morning I put in a fix for analogWrite because the initial attempt to fix this didn't work.

On Thu, Dec 3, 2020 at 2:22 PM ldalep notifications@github.com wrote:

Well I get a totally different wave - missing everything before the imposing of 0 [image: Screen Shot 2020-12-03 at 12 19 42 PM] https://user-images.githubusercontent.com/24977246/101077323-ebda8a80-3561-11eb-9c89-e32c2814ea75.png

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/megaTinyCore/issues/271#issuecomment-738239941, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABTXEWYS5S5XCR35ANPYLHDSS7QPTANCNFSM4UJMMUUA .

--


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore https://github.com/SpenceKonde/ATTinyCore: Arduino support for all pre-2016 tinyAVR with >2k flash! megaTinyCore https://github.com/SpenceKonde/megaTinyCore: Arduino support for all post-2016 tinyAVR parts! DxCore https://github.com/SpenceKonde/DxCore: Arduino support for the AVR Dx-series parts, the latest and greatest from Microchip! Contact: spencekonde@gmail.com

ldalep commented 3 years ago

I downloaded the latest about 3 hours ago ... manually installed it - then reinstalled 2.1.5 with the board loader and verified I could reproduce what I had before. I would be the first to say I could have screwed something up

SpenceKonde commented 3 years ago

Uggghhhhh

Okay, this should work now... Earlier problem was that I'd duplicated the turn on pwm code into turnoffpwm, having forgotten to invert the bits.... and thento "fix" it I changed it... in the wrong place.

ldalep commented 3 years ago

Bingo- You got it

Screen Shot 2020-12-04 at 8 06 21 AM