Skip to content

Latest commit

 

History

History
60 lines (54 loc) · 17 KB

LibraryCompatibility.md

File metadata and controls

60 lines (54 loc) · 17 KB

Library Compatibility for megaTinyCore and DxCore

Please include information that uniquely identifies the library, as popular libraries have dozens of forks all over the internet, and it is often difficult to identify which is the "right one". Bonus points if you include a version number too - but I've given up on that.

Library Version Library URL or reference Status Included w/ Notes
~FAST LED ~ All https://github.com/FastLED/FastLED Does not compile, appears little if any work done to support modern AVRs This library is not being particularly well managed right now. The code incomprehensible. Supposedly one of the original authors passed away in an accident, which is a pretty good excuse for not maintaining a library.
tinyGPS++ https://github.com/mikalhart/TinyGPSPlus Compiles and works
NeoGPS Architecture warning, doesn't work There are many other GPS libraries that do work.
VEML6070 Adafruit Compiles and works
MLX90614 https://github.com/adafruit/Adafruit-MLX90614-Library Compiles and works
BMP180 Adafruit Compiles and works
BME280 Adafruit Compiles and works
OneWireNg https://github.com/pstolarz/OneWireNg Compiles and works
OneWire Original https://github.com/PaulStoffregen/OneWire Does not compile Not compatible with modern AVRs other than the ATmega4809
OneWire Forked https://github.com/SpenceKonde/OneWire full "megaavr" support added, works Works on all currently available "modern AVRs" and is expected to work on any future such parts with not more than 56 I/O pins (which will require a fundamental change in behavior of the hardware wrt. pin control). Tested PR submitted August 2020. No response from Paul.
Neopixel Adafruit Does not compile Use included tinyNeoPixel - Same API, adapted for these devices...
LED Backpack 1.1.8 https://github.com/adafruit/Adafruit_LED_Backpack Compiles and works
Tiny4kOLED 1.5.4 https://github.com/datacute/Tiny4kOLED Compiles and works SSD1306, not just for tinyAVR - anything with Wire.h! Documentation is v. poor.
Adafruit GFX 1.10.12 https://github.com/adafruit/Adafruit-GFX-Library/ Fixed in 2.5.5 Was broken in megaTinyCore 2.5.0-2.5.4, but not DxCore; cause was I2C buffer size being effectively 31 bytes rather than the required 32.
U8x8 and U8g2 2.28.10 https://github.com/olikraus/u8g2 Fixed in 2.5.5 Was a manifestation of buffer size issue on megaTinyCore
rc-switch https://github.com/sui77/rc-switch (TX mode) Compiles and works(?) A surprise. I don't expect RX will work
FAB-LED Original https://github.com/sonyhome/FAB_LED Supported as of 9/8/2021 FAB-LED is a WS2812 w/out buffer library; impressive
FAB-LED Forked https://github.com/SpenceKonde/FAB_LED No longer needed Fix has been merged, original should be used, not the fork
Servo From library manager (the one included w/core works) Compile error Core Use Servo_megaTinyCore if installed Servo via lib. mgr.
TLC5947 https://github.com/adafruit/Adafruit_TLC5947 Compiles and works TLC5947 is a rather fancy LED driver.
MFRC522 Frozen https://github.com/miguelbalboa/rfid Compiles and works Lib. Mgr. Long ago had issue relating to F(). This is the F()ing library that forced the return of the F() macro!
CAP1296 https://github.com/mattThurstan/CAP1296 Compiles and works Library needs cleanup - may not use correct ID by default, and prints stuff to Serial
Crypto https://github.com/rweather/arduinolibs/tree/master/libraries/Crypto Compiles and works We need entropy for crypto. ADC is not good for this. On classic AVRs they beat async WDT against system clock as source of noise. Modern AVRs can do it much better with a CCL inverting it's own output.
MCP4725 2.0.0 https://github.com/adafruit/Adafruit_MCP4725 Compiles and works I2C 12-bit DAC. Less exciting with the ADC on the 2-series, and the EA-series coming
MCP23017 2.0.0 https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library Compiles and works Also supports the MCP23008, which has half as many pins
VL53L0X Pololu Compiles and works This and the one below are drastically different
VL53L1X_ULD 1.2.2 https://github.com/rneurink/VL53L1X_ULD Compiles and works Lib. Mgr.
Radiohead 1.119 https://www.airspayce.com/mikem/arduino/RadioHead/ Compile error Working on PR to make thing at least compile. Library produces excessively large binaries and does not make efficient use of flash.
RFM69 Compiles and works Makes much more efficient use of flash than RH
ADCTouch Compiles, but doesn't work well This depends on poorly specified, usually unwanted behavior of the ADC. This behavior has been made far less prominent on the modern AVRs. These libraries would need to be rewritten for the specific generation of hardware - a generic implementation is impossible I think. Sorry :-(

DxCore vs megaTinyCore

This page is linked to from the DxCore documentation as well, for the simple reason that the similarity of the underlying hardware is such that something that works with one will work with the other unless it's using specific features that are only present on one of the two (that is, it is a library for making use of a specific peripheral which was changed between those processors, which will always require library adjustment). It also, among other things, means that it is a recently written library with an author to complain to), or if it is very poorly written and checks for specific parts, rather than peripheral types or things that are true for a whole host of parts (ie, testing for #if defined(__ATtiny3216__) || defined(__ATtiny1614__) - the two things the author tested on - when the exact same code might work on any modern AVR if they had instead tested __AVR_ARCH__ - which picks up all modern AVRs with 64k of flash (102), 128k of flash (104) or 48k-or-less of flash (103 - the condition of __AVR_ARCH__ == 103 is notable in that the flash is fully memory-mapped in these parts, and is not fully mapped for any other Arduino-compatible AVRs; Now that we have reverted the changes to the F() macro, I don't think there are any issues specific those. Particularly common is "special-casing" the ATmega4809 to pick up the Nano Every, and while the same code could have worked on every modern AVR (or was only a few trivial modifications away from that)

A few plausible fault lines within the modern AVRs

Within the realm of modern AVRs (tinyAVR 0/1/2, megaAVR 0-series. Dx-series and Ex-series), there are only a limited number of plausible dividing lines. Almost all of these only ever apply to stuff that interacts directly with a peripheral:

  • Cases where a library's function is to interact with a specific peripheral not present on all parts will never work on parts without that peripheral.
  • Things that directly manipulate the event system will have trouble on either tinyAVR 0/1-series or everything else. The event system on 0/1-series is different (and significantly worse) than that on all other modern AVRs (which differ from each other only in numbers of channels and the quantity of peripherals to act as users and generators). Hence, directly interacting with the event system and making it work everywhere core can be quite challenging. With 2.5.0 megaTinyCore and 1.4.0 DxCore we introduce a number of improvements to Event.h which make it much better as a basis for interacting with the event system in a device-independent way, though it still is far from perfect. In addition to all the wackiness of of the 0/1-series with two types of channels and generators having inconsistent numeric values on different channels, which isn't handled well, there are a few specific differences
    • tinyAVR 0/1-series and megaAVR 0-series only had 1 event input for TCA0. More recent parts have 2. Event.h has both user::tca0_cnt_a and user::tca0 as synonyms to help paper over this, and the EVENT is an alias for EVENTA on parts that have both events, and EVENTA names alias for EVENT on mTC. Use the new names when you have the option.
    • On tinyAVR 0/1-series and megaAVR 0-series, only TCA0 can count on event. On more recent parts, the TCBs can as well.
    • The EA series will break EVSYS things again as they rework how pin and RTC PIT timer events are treated (but the benefit is that all event channels are equal).
    • This was the impetus for the Event.h library, and some of it's features: it was realized that a library for something as simple as input capture would have to be implemented once per part family! But at least with the EA (and presumably beyond) we'll finally have the EVSYS we always wanted.
  • Things that manipulate the inner workings of the ADC will trip up, as each generation got subtle changes to the ADC. tinyAVR 0/1 and megaAVR 0 are almost identical, Dx-series has 2 extra bits of resolution, and the option for (kind of) differential measurements, but it otherwise is similar. The 2-series and Ex-series have an all new much more capable ADC, which behaves quite differently. Any library is likely to require a totally separate implementation for the two sets of hardware - unless they stick to using analogRead(), analogReadResolution(), and on mTC/DxC, analogReadEnh(), in which case any issues would be easily solved.
  • The tinyAVR 0/1-series PORTMUX registers are packed tighter (more peripherals per register in some cases) than elsewhere, and the names are different (and worse). The tinyAVR 2-series is Dx-like.
  • The DD/EA-series have more options in their PORTMUX registers. I expect this pattern to be continued moving forward, with each generation gaining, but only rarely losing, a mapping option.
  • Code written to interact with the RTC and developed on Dx-series or tinyAVR 2-series may not work on older parts other than the 32k 1-series parts (which have the fix). There are a number of serious silicon bugs relating to the RTC. Even basic operation requires use of (thankfully simple) workarounds. Those workarounds are nearly harmless if used the parts without the bug, so moving forward isn't generally a problem.
  • Code that manipulates the system clock controller may pose challenges. As far as I can tell, it looks like the tinyAVR 0/1/2-series and megaAVR 0-series got one version of CLKCTRL, The AVR DA-series got another, the DB and DD got a third, and the EA-series is going to get a mashup of the tinyAVR and Dx-series ones.
  • Direct port manipulation counts as working with a peripheral (the PORT peripheral has it's own chapter, doesn't it?). All Dx-series parts get the multipin configuration for for setting PINnCTRL on masse and the DB, DD, and EA series have a TTL input level option, so you can tell them to have definitions of HIGH and LOW that don't depend on supply voltage with per-pin granularity. Library authors who attempt to use those features should respectively, check for PORTA_PINCONTROL or PORT_INLVL_bm being defined and provide an implementation that does not make use of it and optionally add a #warning to inform the user if this degrades functionality, or #error if the library is not viable without it.

Pre-compiled libraries

As of megaTinyCore 2.4.0/DxCore 1.3.x, pre-compiled libraries (ie, those distributed as .a files instead of source) can be used. These sort of libraries have several significant disadvantages. First and foremost, the library must include a compiled .a file for the specific part being used. The libraries are typically distributed without source code, so you cannot generate those files for the device you want to use if not included. . This is also the primary motivation for such libraries - to allow authors to distribute a library without letting anyone see their code, which may be licensed under proprietary terms. The libraries also trade off compile speed for binary size - but in the wrong direction: Compile speed increases because the library doesn't need to be compiled, but lacking the symbols normally left for the link-time optimizer, the linker cannot make it as small as it could if compiling from source. Finally, because the code is not available, you must rely upon the documentation provided by the library creator(s) - you don't have the source code as documentation of last resort; the commercial entities who adore proprietary licenses are far from immune to bad documentation. In fact, there is no clear association between the two - while putting a skilled technical writer between the library author and the library user can result in much better documentation - but an unskilled one can turn the developers' poorly written but accurate notes (which likely also make optimistic assumptions about the background of the reader) into a mass of impenetrable yet grammatically correct verbiage lacking in clarity, relevance and accuracy. Often the technical writer falls short on the technical background, is unclear on the motivation or use case for a feature, and .

For these reasons, although they are supported, pre-compiled libraries are not recommended where alternatives are available. Often, when all you can get are precompiled libraries you will discover that they won't be compiled for the parts you want them for, or were built with AVR as an afterthought, having been ported by someone who was inexperienced with the architecture and who looks down upon people are unaware of it's limitations or of relevant market trends and generally ill-prepared to meet the challenge. A great example of dreams crushed by pre-compiled proprietary libraries is the BME680 library. Anyone can get the raw readings out no problem. But you wanted the IAQ number? Oh, you need their library for that. Supplied pre-compiled, mind-blowingly bloated, and only supporting the ATmega2560 on AVR (they think you should be using an ARM, I guess). So nobody can use it with any recent part, even though Dx-series could fit it, much less figure out how they managed to make it generate a binary larger than the side of a house when it is taking a handful of numbers and turning them into a single calculated values. (my impression looking through the disassembly listings, is that they defaulted floating point values for everything, and are unfamiliar with AVR as a platform and it's limitations. It was clear that it would be a major undertaking to reverse engineer the IAQ calculation (though the code isn't obfuscated as far as I could tell, it was just assembly provided without comments or context. , reading unadorned assembly is very difficult and time consuming).