wokwi / avr8js

Arduino (8-bit AVR) simulator, written in JavaScript and runs in the browser / Node.js
https://blog.wokwi.com/avr8js-simulate-arduino-in-javascript/
MIT License
462 stars 73 forks source link

External clock for timers #97

Closed urish closed 2 years ago

urish commented 2 years ago

The timers can be clocked by an external clock through the Tn pin. For instance, for the ATmega328p:

image

This feature is currently missing from the Timer implementation.

alto777 commented 2 years ago

Just found this out the long way!

No trouble without it, just good to have my observations confirmed.

Finally just ran the code on the UNO and it is doing what I need, I can still do most of the work for my "bounce laboratory" under simulation. Messing with the timers is fraught, easier on the desktop than the upload.

a7

urish commented 2 years ago

Oh, sorry you had to find it out the long way.

It shouldn't be too hard to implement. If you have a link to a demo project (+ expected output on a physical uno), that'd be helpful for the implementation.

alto777 commented 2 years ago

Here is the reduced demonstration. That external clock input is not implemented is exactly explains the behaviour. I am developing a bounce analyzer to evaluate real switches and a bounce simulator (hardware) for exploring and validating different debouncing methods.

I want to use the timer counter as it is the fastest way to count the bounces.

https://wokwi.com/arduino/projects/307002012913893952

I can't give this any truly high priority, as I have most of the analyzer working OK. I just want to see every corner of the WAS covered, so there aren't any "except it doesn't" things.

a7

urish commented 2 years ago

That's a good test case. Thanks!

urish commented 2 years ago

And... it's live on wokwi.com!

alto777 commented 2 years ago

Nice work!

Observed on the desktop, works as expected.

On two iPads (Safari browser), one small enough to be considered a mobile device, one large enough to be considered a desktop device, the timer counter marches out ahead of the true (software) counter in the case of making the switch bounceless…

unless you are very slow to press and release the button.

My suspicion is this has more to do with the UI and the implementation of pushbuttons than it does with the (newly!) externally clocked timer counter.

Add: Before I ran it on the desktop machine, I thought you might be counting both edges, as the timer counter seemed to go ahead 2 for every press. Sometimes, however, on the iPads the timer counter got ahead by more than 2. Just throwing this at you incase something sticks.

a7

alto777 commented 2 years ago

Okay, I thought it was implausible (my own theory) and poking away I find that in the simulation, the externally clocked timer one counter pulls ahead on the desktop as well…

` Hello Counter One World!

0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 21 20 22 21 23 22 25 23 26 24 27 25 28 26 29 27 30 28 32 29 33 30 34 `

The software counter misses no counts, this validates the switching logic (I set bounce to 0, so we have a bounceless switch counting loops correctly).

The timer/counter sometimes registers multiple counts per loop.

With the real UNO and an external debounced signal, the loop count and the timer counter count accumulate the same number of transitions.

a7

urish commented 2 years ago

Interesting - I'm investigating.

urish commented 2 years ago

I think I found the culprit: https://github.com/wokwi/avr8js/blob/60d024ff4168751aa60b0f54b434bf2f138efd7d/src/peripherals/timer.ts#L312

urish commented 2 years ago

Actually, on a deeper look, it doesn't seem like there's a problem them.

Are you still using https://wokwi.com/arduino/projects/307002012913893952 for testing? Or do you use different code?

From what I can see, the code in loop() is waiting for a rising edge, so I would expect the count to start at 1. Or am I missing something?

alto7 commented 2 years ago

I used the link you just posted. I then edit the jason for a bounceless pushbutton. I see misbehaviour, viz:

28 58 29 60 30 61 31 64

the loop counter is correct, the timer counter counter advances, as seen in the fragment of output copied from the serial monitor area of the sim, by 1, 2 or 3 where we would expect only by 1.

2 is the most common incremental jump - you see the bad count is about twice the good count, but not exactly.

I have been as careful as possible, but I am still with only one cup of coffee this morning…

I did the above on an iPad mobile device, I repeated the experiment on the desktop where it still misbehaves, but way less frequently. In 500 button presses (mouse clicks) only once did the timer counter jump by 2 rather than 1.

I shouldn’t speculate out of my box, but I wonder if something about the processor speeds or number of processors / processes is different between the two environments, iPad and desktop (relatively modern iMac 3.6 GHz Core i9).

Honestly I’d be happy to see you drop this matter but leave a note about it clearly pointing to this thread and example.

HTH

a7

urish commented 2 years ago

Interestingly, it didn't reproduce on my laptop - went up to 300.

Honestly I’d be happy to see you drop this matter but leave a note about it clearly pointing to this thread and example.

Where would you suggest to leave the note?

If you wish, you can try to record your session with the logic analyzer (both pins 1 and 5 of the Arduino, so we also capture the serial output), perhaps looking at the signals will provide some better insights why this happens...

alto7 commented 2 years ago

I would expect your laptop to be a desktop device and perhaps enjoy the reduced probability of catching the error. If mobile vs. desktop is significant.

I don’t know if the browser brand or OS/Machine type enters into it. From my miles high perspective, it should not. Seems like you should be above that fray.

Maybe there is a section of the documentation that addresses known gaps and idiosyncrasies in the simulation, anything that would make simulation be at all different from real life. The first place to look when something doesn’t do both places the same thing.

I found the external counter gap after some mild googling. This issue, referred to on discord. I expect most of your audience are still people who are going to meet you more than halfway, and the discord has solved my problems with rapidity and kindness. BTW you guys ever try sleeping?

I’ll try with the logic analyzer mostly because I’d like to gather some real experience with a simulated logic analyzer… I know my real one, usually I think my way out of needing it but it can be indispensable.

Ironically it turns out that the timer counter samples the external clock, so there is a limit to how fast it can count. I think it is fast enough for my bounce lab, some pencil work will tell.

Anyway THX for looking into this.

alto777

alto777 commented 2 years ago

OH DEAR!

I have destroyed been modifying the sim in the above link. This happened to me before, thought it was something I did wrong but now:

  1. Get out project oldProject.ino

  2. Rename project newProjectBasedOnOld.ino

See the new name in the tab, but curiously see the old name (somewhere)

  1. Save, oldProject GONE. Only project with the new name exists.

This may be how it is supposed to work, but old habits run cross-wise to this: if I rename something, I expect the thing I saved with the old name to continue to exist…

So how do you keep an existing project, and clone/rename it to a new project to continue working on it?

a7

urish commented 2 years ago

Renaming a project indeed does not create a copy.

To create a copy, click on the arrow next to the "Save" button and choose: "Save a copy":

image

Is there any way I can make this more intuitive?

alto777 commented 2 years ago

Haha, no, I will always find a way to lose work. I've just noticed the Arduino IDE does the same thing - rename the main *.ino tab, and save, poof! your original named folder and contents are gone (just renamed that is). The IDE will also happily delete files when you remove them from a sketch by deleting the tab… a little too much power for an application but perhaps appropriate for those that manage projects that directly exploit the file system. I guess I would prefer a container of some kind, but never mind, it's getting more intuitive the longer I use it (!).

I did put instruments into the bounce timer counter problem project and added to the sketch a bit to make it easier to use.

https://wokwi.com/arduino/projects/307002012913893952

I examined the *.vcd with PulseView. There is absolutely nothing remarkable to see monitoring the switch, the serial output line and the ALARM I added. All is exactly what you would expect. The sketch now freezes when it detects the counts going out of sync. After that, the logic analyser records another button press or two before I realized it had tripped and hung itself. All like I say and what you would expect.

I am talented (and humble) but I don't think there is something I am doing (or not doing) that makes this a problem for me that anyone couldn't see - I can't explain why you are unable to reproduce the same error.

I repeat that the matter can be, as far as I am concerned, dropped. If you want the *.vcd to rummage through, just say how I should transmit it.

a7

urish commented 2 years ago

Yes, I'd love to take a look at that VCD file...

alto777 commented 2 years ago

OK. I won't mess with the sketch. I locked it but I'll pretend I don't know the implications of having done, as I do not.

wokwi-logic-8.vcd.zip

What I just dragged and dropped here, tell me if it doesn't get there intact.

The error is around 15.23 seconds in. And that's at the far end. UART Ascii protocol decoder very cool!

a7

urish commented 2 years ago

Thank you!

I locked it but I'll pretend I don't know the implications of having done, as I do not.

Locked basically means it won't allow you to save any changes unless you unlock first. It's a simple mechanism to protect against accidentally overriding it in the future.

The error is around 15.23 seconds in. And that's at the far end.

I can see it, very strange. Seems like this is something internal to the AVR - at least the Logic Analyzer and your code seem to be in agreement.

UART Ascii protocol decoder very cool!

Agreed!

alto777 commented 2 years ago

TBC you mean internal to avr8js - real hardware does not trip the ALARM, that is to say it counts the same number of presses in hardware as there are in software as there are IRL.

If anything, I would expect a simulation to fix weird flaws in the hardware, what might not get implemented "correctly" if the design was informed by the datasheet rather the a logic diagram or other specification.

a7

urish commented 2 years ago

TBC you mean internal to avr8js

Yes :)

urish commented 2 years ago

Quick update - I managed to narrow it down to a minimal VCD file that reproduces the issue:

$version Generated by Wokwi.com $end
$date Mon Aug 16 2021 12:11:33 GMT-0400 (EDT) $end
$timescale 1ns $end
$scope module logic $end
$var wire 1 " D1 $end
$upscope $end
$enddefinitions $end
#0
0"
#15231063187
1"

So we have a consistent reproduction!

Edit: seems like it surfaces another issue (your code counting rising edges, while the interrupt counts falling edges). So still no minimal VCD that reproduces the issue correctly

alto7 commented 2 years ago

The edge which either counts can be changed. I suggest changing the interrupt to count the falling edges, to leave my logic intact.

bitwise or (1 << CS10) into TCCR1B

How do you apply/what project does the VCD go with? Is that like an arbitrary signal generator? Just say I’ll find it learning more about VCD and Pusleview or fix my (mis)understanding.

TIA

a7

alto777 commented 2 years ago

So I modified the example in a new project

https://wokwi.com/arduino/projects/307382307237397056

uses the other edge for incrementing the timer counter counter. If the logic was counting a different edge, they are now counting the same edge. I didn't think it was important.

And the error still occurs.

Now I have to figure out GitHub and why I have a split in my personality, no idea who this alto7 guy is. :-|

a7

urish commented 2 years ago

Now I have to figure out GitHub and why I have a split in my personality, no idea who this alto7 guy is. :-|

Funny, I haven't even noticed until you mentioned it!

urish commented 2 years ago

I repeat that the matter can be, as far as I am concerned, dropped

Is that still the case?

alto777 commented 2 years ago

Sorry to not get to your question sooner, and answering it when I had a chance on the discord. I was hoping to be a bit more thorough and review the matter and then life.

So, I think the matter can be dropped. However, my understanding is that there is an existing fault in the emulation, that is to say the emulation does not agree with reality.

It appears that the real processor performs according to the document(s). If the real processor had the flaw, then the emulation could be excused for adhering to the document. Nevertheless it might be adjusted to agree: a moving target, no doubt, as it might be the kind of flaw that would be corrected and noted as such at some point by Microchip or whomever.

Since the emulation does the "wrong" thing, it would be more important to fix. I still say it doesn't rise very high on any priority list, it's just the kind of thing that might be a slight unsettling mystery - why would this happen, ever.

I know nothing about how the emulator does its thing (yet?) but it seems like something that just shouldn't happen.

As I said on the discourse, I would way prefer that you spend no more time on this. Wherever such tiny discrepancies are noted, be they faults in the AVR emulation or in the larger wokwi sim world, this odd thing should be on the list, along perhaps with a pointer to a minimal example that shows it up.

a7