You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: megaavr/libraries/Event/README.md
+13-3Lines changed: 13 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -170,12 +170,16 @@ Below is a table with all of the event users for the tinyAVR 0/1/2-series parts
170
170
pinless: The parts potentially (per pinout) have this many event channels that can't be connected to any port's event generator
171
171
172
172
173
+
`*` Likely AB-CD-EF
173
174
174
175
The tinyAVR 0/1-series layouts are really weird. See the documentation included with megaTinyCore for the table; 0-series don't have any RTC-PIT options, and 1-series has them all crowded onto one channel; both of them have two kinds of channels, and are generally a lot less flexible. The tinyAVR 2-series, on the other hand, is almost normal - except they have a better layout - (channels 0/1 get PA, PB, 2/3 get PC, PA and the last 2 get PB, PC. It's unclear how EA will be handled, Taken at face value the EA's product brief implies 6 channels in the standard layout, for 2 channels per port. 14-pin AVR-DD will have only 2 pins in PORTA (and with no portB, those 2 pins have channels 0 and 1 to themselves), and with no port E either, the 14 and 20pin parts will have only the two pins on PORTF, which are not going to be everyone's first choice for I/O (PF6 and PF7 are Reset and UPDI), so channels 4 and 5 are nearly pinless - assuming that what's in the headers pre-release is what they will ship. There is room for improvement, though it's really not bad.
175
176
176
177
177
178
## Okay, so how do I read the state of these event channels?
178
-
All you can do is use it for something that you can detect the response of. Yes, this is bizarre. They're already syncingh it for the sync subchannel! Use that to feed a register
179
+
You don't? Even though each channel on the 2-series supposedly has a synchronizer on it, they for some reason didn't pipe those synchronized bits to a register that we could read from software, that would seem to be the natural thing to do. I'm not sure why, or whether there was a well-reasoned decision making process around this, or it was simply an oversight. An argument can certainly be made "what are you doing reading it from software?" (to which the obvious answer is "Because it's not working and I'm trying to figure out why").
180
+
181
+
The best you can do is pipe the outputs to a pin and read the pin....
182
+
179
183
180
184
## The Event class
181
185
Class for interfacing with the Event system (`EVSYS`). Each event channel has its own object.
@@ -207,6 +211,7 @@ These class methods return a reference to an event channel (an Event&), or Event
207
211
| Event::assign_generator() | gen::generator_| return channel that has that generator,<br/> pick one and set if none currently set |
208
212
| Event::assign_generator_pin() | uint8_t | return channel that has that pin as generator,<br/> pick one and set if none currently set |
209
213
214
+
210
215
Class methods for working with users or looking up generator or user numbers
@@ -345,7 +350,7 @@ Event0.soft_event(); // Create a single software event on Event0
345
350
### long_soft_event()
346
351
soft_event() is only one system clock long. Often you need something a little longer. 2 clocks? 4 clocks maybe? Maybe it needs to get past the 'filter' on a CCL... Or you've got 2 things that need to happen a fraction of a microsecond apart; you've tried triggering one on the rising edge of a soft_event and the other on the falling edge, but it's just a hair too fast, and the other obvious solutions aren't viable due to the specifics of your scheme. The only way that a soft-event can last multiple system clocks is if the register is written every clock cycle. There is no time for a loop; only brute force (ie, a contiguous block of 'ST'ore instructions) will do the trick. Now in many ways this defeats the point of the event system; however, there are times when it is not entirely unreasonable to do this (as noted above), particularly if doing weird things with the CCLs, event system, and other peripherals.
347
352
348
-
The lengths that are available are 2, 4, 6, 10 and 16 (any number less than 4 will give 2 clock-long pulse, only 4 will give a 4 clock long one. Anything between 4 and 10 will give 6, exactly 10 will give 10, and anything larger will give 16). Those numbers were chosen based on perceived usefulness while staying within reason. The wacky rounding is a function of the way I cut clock cycles. [It's a block of 16 consecutive st instructions, prior to that, the code (in asm) checks the argument against 4. I then use a breq and a brmi. If you need longer, you shouold definitely use a different approach.
353
+
The lengths that are available are 2, 4, 6, 10 and 16 (any number less than 4 will give 2 clock-long pulse, only 4 will give a 4 clock long one. Anything between 4 and 10 will give 6, exactly 10 will give 10, and anything larger will give 16). Those numbers were chosen arbitrarily to keep the size small, and give a selection that covered the reasonable use cases I could think of. If you need longer, you shouold definitely use a different approach.
349
354
350
355
#### Usage
351
356
```c++
@@ -355,6 +360,11 @@ Event0.long_soft_event(10); // will invert the state of the event channel for 10
355
360
```
356
361
Don't forget that this is an invert, not a "high" or "low". It should be entirely possible for the event that normally drives it to occur resulting in the state changing during that pulse, depending on it's configuration. Note also that the overhead of long_soft_event is typically several times the length of the pulse due to calculating the bitmask to write; it's longer with higher numbered channels. if that is a problem, whatever your use case is, it is not one of the ones this was intended for...
357
362
363
+
#### Usage
364
+
```c++
365
+
Event0.soft_event(); // Create a single software event on Event0
366
+
```
367
+
358
368
### start()
359
369
Starts an event generator channel by writing the generator selected by `set_generator()` method to the `EVSYS.CHANNELn` register.
360
370
@@ -400,7 +410,7 @@ Shown below, generators/user per instance (second argument should be less than
400
410
401
411
`*` - the tiny1 parts with 1 AC work normally. This is unfortunately not supported for tiny1 parts with the triple-AC configuration:
402
412
`**` - There is only one CCL peripheral, with multiple logic blocks. Each logic block has 1 event generator and 2 event users. If using the logic library, get the Logic instance number. The output generator is that number. The input is twice that number, and twice that number + 1.
403
-
`***` - This peripheral is not supported by t6his function, as the the generator numbers are channel dependent. Only effects aging parts anyway (though not that they do;t have some worthy features)
413
+
`***` - This peripheral is not supported because the generator numbers are channel dependent.
404
414
405
415
`!` - These parts do have an option, but we didn't bother to implement it because it isn't particularly useful. But the Event RX mode combined with the TX input to the CCL permit arbitrary remapping of RX and very flexible remapping of TX.
/* Woah, we were missing a huge optimization opportunity here....
836
+
/* Woah, we were missing a huge optimization opportunity here.... but only for DA/DB-series parts
838
837
- The users are numbered in the same orderas the ports.
839
838
- PA is #defined as 0, PB as 2, etc.
840
839
- there are no parts for which a port exists that has a pin 2 or 7, but which does not allow that pin to be used as an event output, except for tiny 0/1, where only pin 2 is an option...
841
840
We basically **don't have to test the port** as long as it's a valid port as we just tested. This is probably like 6-8 instructions instead of several dozen */
0 commit comments