Nous avons maintenant une section Discussions Github. Lorsqu'un problème est définitivement un défaut central, vous réduirez le temps nécessaire pour le résoudre si vous créez un problème, car je donne la priorité aux problèmes plutôt qu'au rattrapage des discussions.
Cela corrige de nombreux bugs présents dans la version 2.6.x
2.6.x introduit une empreinte Flash améliorée de manière significative tout en ajoutant des fonctionnalités, le fil peut sortir l'esclave du mode veille sans corrompre les données, et bien plus encore, voir le journal des modifications.
Seules les versions de l'IDE Arduino téléchargées depuis arduino.cc doivent être utilisées, JAMAIS depuis un gestionnaire de paquets Linux. Les gestionnaires de paquets disposent souvent de l'IDE Arduino, mais l'ont modifié . Et ce, même s'ils ne savent rien de l'Arduino ou du développement embarqué en général, et encore moins de ce dont ils auraient besoin pour le modifier avec succès. Ces versions sont connues pour des problèmes subtils mais sérieux causés par ces modifications imprudentes. Ce noyau ne devrait pas fonctionner sur de telles versions, et aucune modification ne sera apportée dans le but de corriger les versions de l'EDI provenant des gestionnaires de packages pour cette raison.
Il s'agit d'un bug du client Arduino.
Les versions IDE entre 1.8.13 et 2.x ont développé de nouveaux défauts importants. Les versions IDE 1.8.2 et antérieures possèdent cependant des défauts rédhibitoires non corrigés. Je pense qu'ils disposent enfin d'une version fonctionnelle de l'EDI, et je pense que cette dernière est capable d'installer mon noyau correctement.
Avant megaTinyCore 2.6.0, l'installation manuelle de megaTinyCore provoquait le crash de la V1.8.14 de l'IDE à cause de ce bug lorsque vous installiez le noyau manuellement dans votre dossier Arduino. Les utilisateurs de 1.8.14 et versions ultérieures doivent utiliser la version 2.6.0 de megaTinyCore.
J'achète beaucoup de produits électroniques sur AliExpress. C'est un excellent marché pour les produits fabriqués par des entreprises chinoises et qui sont pour la plupart génériques, y compris de nombreux composants qui ne sont pas disponibles autrement pour les particuliers en Occident (par exemple, la commande minimum est une bobine ou quelque chose comme ça - si vous pouvez même trouver un fournisseur de composants qui travaille avec le fabricant de puces chinois sans nom). Ce n’est pas un endroit idéal pour les dernières gammes de produits semi-conducteurs des principaux fabricants occidentaux, surtout au milieu d’une pénurie historique de ces puces. Les appareils AVR modernes, lorsqu'ils sont disponibles via ces canaux, sont fréquemment signalés comme étant faux ou défectueux (comme les ATtiny412 qui pensent qu'ils sont des 416 et peuvent ne pas exécuter correctement la réinitialisation de la mise sous tension). D'ailleurs, vous ne voulez probablement pas acheter de microcontrôleurs AVR sur AliExpress ... Les cartes assemblées, comme les clones Arduino Nano, fonctionnent généralement si vous évitez celles avec les puces LGT8 tierces et faites attention à celles avec l'ATmega168p. au lieu du '328p - mais il y a beaucoup de rapports faisant état de faux microcontrôleurs lorsqu'ils sont vendus sous forme de puces nues (j'ai entendu parler de faux ATtiny85 qui ont en fait été remarqués) ATtiny13 ; il n’y a pas que les AVR modernes qui sont falsifiés). Il existe de nombreuses théories intéressantes sur l’origine de ces fausses puces, et Microchip est resté totalement silencieux sur la question.
Il est préférable de visualiser ce document en ligne (plutôt que d'ouvrir le fichier de démarque dans votre éditeur de texte préféré), afin que les liens soient cliquables et que les images en ligne soient affichées, et probablement plus important encore, pour que les tableaux s'affichent parfois correctement. Encore une fois, ce [document peut être trouvé sur github](https://github.com/SpenceKonde/megaTinyCore](https://github.com/SpenceKonde/megaTinyCore)
Les anciennes versions ne gèrent pas correctement les programmeurs dans le menu Outils -> Programmeurs, ce qui dégrade rapidement l'UX à mesure que le nombre de cœurs installés augmente. Ils ne conviennent pas. Les versions les plus récentes commençant par 1.8.14 (y compris 1.8.17, 1.8.18 et 1.8.19) peuvent générer une erreur « panique : aucune version majeure trouvée » car elles ne parviennent pas à analyser correctement platform.txt. Depuis la version 2.6.0, nous modifions manuellement le fichier platform.txt juste avant la sortie, ce qui pose donc moins de problèmes.
Lorsque megaTinyCore est installé via le gestionnaire de cartes, la version requise de la chaîne d'outils est installée automatiquement. Toutes les pièces de la série 0/1/2 sont prises en charge sans étapes supplémentaires. Jusqu'à la version 2.2.7, nous utilisions la version Arduino7 d'avr-gcc (gcc 7.3.0 et avrlibc 3.6.1) avec les derniers ATpacks en juin 2020. À partir de la version 2.2.7, nous avons commencé à utiliser ma version Azduino de la chaîne d'outils, qui a mis à jour les ATpacks pour toutes les pièces nouvellement prises en charge. La version 2.2.7 utilisait Azduino3, la version 2.3.0+ utilisait Azduino4 et, à partir de la version 2.6.0, nous utilisons Azduino5 (bien que cela ne nous offre aucun avantage, si ce n'est d'économiser un quart de Go d'espace disque dur et 40 Mo de bande passante de téléchargement si vous installez les deux). megaTinyCore et DxCore via le gestionnaire de forum.
L'installation manuelle est plus compliquée, en particulier si vous souhaitez prendre en charge la série 2 ; consultez le guide d'installation pour plus d'informations.
Un noyau Arduino pour les tinyAVR série 0, série 1 et maintenant série 2. Ces pièces ont une architecture améliorée par rapport aux pièces tinyAVR "classiques" (qui sont prises en charge par ATTinyCore), avec des périphériques améliorés et un temps d'exécution amélioré pour certaines instructions (elles sont similaires en ce qui concerne la série AVR Dx avancée, ainsi que puces megaAVR série 0 comme l'ATmega4809 utilisée sur les versions officielles Nano Every et Uno Wifi Rev. 2 - bien que l'équipe Arduino ait fait de son mieux pour les mettre à genoux) dans un petit format à faible coût. packages typiques de la ligne ATtiny. Toutes ces pièces comportent au moins un UART matériel et une interface SPI et TWI (aucune de ces ordures USI comme, par exemple, l'ATtiny85 n'en a), un système d'événements puissant, une logique personnalisée configurable, au moins un comparateur analogique sur puce. , un oscillateur interne étonnamment précis, et dans le cas de la série 1, un véritable canal de sortie DAC, et dans le cas de la série 2, un CAN différentiel sophistiqué.
De plus, les pièces minuscules de la série AVR 0/1/2 sont bon marché - les pièces les plus haut de gamme, les 3226 et 3227, avec 32 Ko de flash et 3 Ko de SRAM (contre la SRAM 2k comme l'ATmega328p utilisé dans Uno/Nano/ProMini) fonctionnent un peu plus de 1 $ USD en quantité - moins que de nombreuses pièces AVR ATtiny classiques de 8 000 pièces ("jeu d'instructions AVR, à un prix PIC"). Tous ces composants sont conçus pour fonctionner à 16 MHz ou 20 MHz (à 4,5-5,5 V) sans cristal externe, et l'oscillateur interne est suffisamment précis pour la communication UART.
Ceux-ci utilisent la programmation UPDI, et non un FAI traditionnel comme le faisaient les parties ATtiny classiques. Voir ci-dessous pour plus d'informations. Obtenir un programmeur UPDI est simple - vous pouvez utiliser un Arduino classique basé sur 328p comme programmeur en utilisant jtag2updi - ou pour de meilleurs résultats avec du matériel moins cher, vous pouvez utiliser n'importe quel adaptateur USB-série et une résistance (et de préférence une diode) en utilisant le SerialUPDI inclus. outil, ou vous pouvez utiliser AVRdude avec l'un des programmeurs Microchip (les programmeurs basés sur mEDBG/nEDBG/EDBG sur leur carte de développement, Atmel-ICE ou SNAP) ou toute programmation UPDI outil qui émule l'un d'entre eux (ce qui, à ma connaissance, le font tous - s'il y en a un qu'avrdude prend en charge et que mon noyau ne prend pas en charge, veuillez ouvrir un numéro pour me le faire savoir !).
Un chargeur de démarrage série, Optiboot_x (basé sur la même base de code que le chargeur de démarrage Arduino Uno classique, bien que considérablement modifié depuis) est pris en charge sur ces pièces (le support de la série 0/1 est actuellement en ligne, la série 2 est attendue d'ici la première semaine de mai. ; les ajustements pour les nouvelles pièces sont triviaux), ce qui permet de les programmer via un port série traditionnel. Consultez la section Optiboot ci-dessous pour plus d'informations à ce sujet et les options pertinentes. L'installation du chargeur de démarrage nécessite un programmeur UPDI. Les breakout boards assemblées que je vends sur Tindie sont disponibles pré-démarrées (elles sont démarrées à la demande). Cela étant dit, l'expérience utilisateur avec Optiboot est un peu décevante sur les pièces de la série 0/1 ainsi que sur les pièces de la série 2 à 14 broches, en raison de l'absence de broche de réinitialisation matérielle qui pourrait être utilisée avec le circuit de réinitialisation automatique habituel. pour se réinitialiser automatiquement dans le chargeur de démarrage lorsque le port série est ouvert. Vous devez soit désactiver complètement la programmation UPDI (nécessitant un programmateur HT si les paramètres des fusibles ou du chargeur de démarrage doivent être modifiés après le démarrage initial), soit laisser UPDI activé, mais démarrer tout téléchargement dans les 8 secondes suivant la mise sous tension. Les pièces de la série 2 à 20 et 24 broches prennent en charge une « broche de réinitialisation alternative » leur permettant d'agir davantage comme un Arduino traditionnel.
L'interface de programmation UPDI est une interface monofilaire pour la programmation (et le débogage - Interface universelle de programmation et de débogage), qui est utilisée sur la série tinyAVR 0/1/2, ainsi que sur tous les autres microcontrôleurs AVR modernes. . Bien que l'on puisse toujours acheter un programmeur UPDI spécialement conçu auprès de Microchip, cela n'est pas recommandé lorsque vous utilisez l'IDE Arduino plutôt que l'IDE (terriblement compliqué) de Microchip. De nombreux rapports font état de problèmes sous Linux pour les programmeurs officiels de Microchip. Il existe deux approches alternatives très peu coûteuses pour créer un programmeur UPDI, avec lesquelles la communauté Arduino a plus d'expérience que les programmeurs officiels.
Avant que megaTinyCore n'existe, il existait un outil appelé pyupdi - un simple programme Python permettant de télécharger sur des microcontrôleurs équipés d'UPDI à l'aide d'un adaptateur série modifié par l'ajout d'une seule résistance. Mais pyupdi n’était pas facilement utilisable depuis l’IDE Arduino, et ce n’était donc pas une option. Depuis la version 2.2.0, megaTinyCore introduit une implémentation Python portable, qui ouvre de nombreuses portes ; A l'origine, nous avions prévu d'adapter pyupdi, mais à la demande de son auteur et de plusieurs employés de Microchip, nous avons plutôt basé cette fonctionnalité sur pymcuprog, un outil "plus robuste" développé et "maintenu par Microchip" qui inclut le même téléchargement de port série. fonctionnalité, uniquement sans les optimisations de performances. Si vous effectuez une installation manuelle, vous devez ajouter le package Python approprié à votre système d'exploitation afin d'utiliser cette méthode de téléchargement (une installation du système Python n'est pas suffisante, ni nécessaire).
Lisez la documentation SerialUPDI pour plus d'informations sur le câblage.
Depuis la version 2.3.2, avec les améliorations spectaculaires des performances et la fiabilité éprouvée du schéma de câblage utilisant une diode au lieu d'une résistance, et à la lumière du caractère instable du micrologiciel jtag2updi, il s'agit désormais de la méthode de programmation recommandée. À partir de cette version, la vitesse de programmation a été multipliée par 20 et dépasse désormais de loin ce qui était possible avec jtag2updi (la programmation via jtag2updi est à peu près comparable en vitesse à la programmation via SerialUPDI sur l'option de vitesse "SLOW", 57600 bauds ; la version normale à 230 400 bauds programme environ trois fois plus rapidement que la version SLOW ou jtag2updi, tandis que l'option "TURBO" (fonctionne à 460 800 bauds et augmente la vitesse de téléchargement d'environ 50 % par rapport à la vitesse normale. La version à vitesse TURBO ne doit être utilisée qu'avec des appareils fonctionnant à 4,5 V ou plus, car nous devons exécuter l'horloge UPDI plus rapidement pour suivre le rythme (ce n'est pas non plus prévu). pour être compatible avec tous les adaptateurs série (il s'agit d'un compromis intentionnel pour des performances améliorées), mais il permet le téléchargement et la vérification d'un croquis de 32 Ko en 4 secondes.
Trois conceptions sont en cours d'itération : un adaptateur série à double port où les deux sont des ports série, un adaptateur série à double port où un port est toujours UPDI, et un port unique avec un commutateur pour sélectionner le mode, et une carte d'extension en option pour donner LED indiquant l'état des lignes de contrôle du modem.
Ceux-ci permettront d'utiliser soit un connecteur SMT JST-XH, soit un connecteur Dupont - dans les deux sens avec 6 broches pour la série (brochage FTDI comme indiqué) et 3 broches (pour UPDI).
Tous les trois pourront fournir 3,3 ou Vusb (nom. 5 V), ou déconnecter à la fois Vusb et 3V3 de l'alimentation, et s'attendre à ce que l'appareil cible soit alimenté avec 5,5 V > Vdd > 1,8 V. Les niveaux logiques utilisés dans ce cas seront la tension de tout ce qui est appliqué. Soyez averti que sur les appareils double série, le rail d'alimentation VccIO est partagé ! Ils doivent tous deux fonctionner à la même tension, être le même appareil, ou l'adaptateur doit être réglé pour les alimenter et leur alimentation doit être déconnectée.
Selon le modèle d'adaptateur et le système d'exploitation, il a été constaté que différents paramètres de synchronisation sont requis ; cependant, les paramètres nécessaires pour empêcher même 230 400 bauds d'échouer sous Linux/Mac avec la plupart des adaptateurs imposent une pénalité de temps beaucoup plus importante sous Windows, où la gestion série du système d'exploitation est suffisamment lente pour que rien n'ait besoin de ce délai...
Le « délai d'écriture » mentionné ici est destiné à permettre à la commande d'effacement-écriture de page de terminer son exécution ; cela prend un temps non nul. En fonction de l'adaptateur, la latence USB et le tampon implicite de 2 ou 3 octets (c'est comme un USART, et probablement implémenté comme un seul en interne. Le troisième octet qui arrive n'a nulle part où aller, car le tampon matériel n'a que 2 octets de profondeur) peuvent être suffisant pour lui permettre de fonctionner sans délai explicite. Ou bien, il peut échouer à mi-chemin et signaler une « Erreur avec st ». Plus le délai d'attente de latence de l'adaptateur et plus la gestion série du système d'exploitation est rapide, plus le risque que cela pose problème est grand. Ceci est contrôlé par le paramètre de ligne de commande -wd
si vous exécutez prog.py manuellement. Depuis la version 2.5.6, ce délai d'écriture est plus proche du temps réel demandé (en ms), auparavant il avait une granularité de plusieurs ms, alors que 1 suffisait, et par conséquent, la pénalité qu'il imposait était brutale , en particulier sur Fenêtres.
Guide de sélection :
Les adaptateurs FTDI (FT232, FT2232 et FT4232, etc.), y compris les faux qui sont disponibles sur eBay/AliExpress pour environ 2 $, sous Windows ont par défaut une période de latence atrocement longue de 16 ms. Même avec tous les efforts déployés pour limiter le nombre de périodes de latence que nous devons attendre, cela prolongera un téléchargement de 2,2 secondes à plus de 15 secondes. Vous devez modifier cela afin d'obtenir des vitesses de téléchargement tolérables :
L’un peut être fabriqué à partir d’un AVR Uno/Nano/Pro Mini classique ; Les clones Nano bon marché sont le choix habituel, étant suffisamment bon marché pour pouvoir être câblés puis laissés comme ça. Nous ne fournissons plus de documentation détaillée pour ces processus ; jtag2updi est obsolète. Si vous l'utilisez toujours, vous devez sélectionner jtag2updi dans le menu outils->programmeur. C’était auparavant notre option recommandée. En raison des bogues persistants de jtag2updi et de sa dépendance à l'égard de l'outil 'avrdude' en grande partie non maintenu (qui, entre autres, insère un faux message d'erreur dans tous les téléchargements UPDI effectués avec lui), cela n'est plus recommandé.
Apparemment, Arduino ne propose pas de versions 32 bits du dernier avrdude. J'ai défini une nouvelle définition d'outil qui est une copie d'arduino18 (la dernière) sauf qu'elle utilise plutôt la version 17 sur Linux 32 bits, car c'est la meilleure disponible pour cette plate-forme. La version arduino17 ne prend pas correctement en charge le téléchargement avec certains outils de programmation Microchip.
Ceci n'est actuellement utilisé que pour les dernières versions et devrait corriger l'erreur avrdude non disponible pour cette plate-forme.
Voir ce document couvrant tous les AVR modernes
Fonctionnalité | série 0 | 1-série | 1+série | 2 séries |
---|---|---|---|---|
Éclair | 2k-16k | 2k-8k | 16k/32k | 4k-32k |
Pincount | 8-24 | 8-24 | 14-24 | 14-24 |
SRAM | 128b-1k | 128b-512b | 2k | 512b-3k |
TCD | Non | Oui | Oui | Non |
TCB | 1 | 1 | 2 | 2 |
CDA | 1x10 bits | 1x10 bits | 2x10 bits | 1x12 bits avec PGA |
Broche VREF | Non | Non | Oui | Oui |
CA | 1 | 1 | 3 | 1 |
Événement * | 3 canaux | 6 canaux | 6 canaux | 6 canaux |
CCL** | 2 LUT | 2 LUT | 2LUT | 4LUT |
*
Les canaux d'événements, à l'exception des tinyAVR de la série 2 (et de tous les AVR modernes non minuscules), sont subdivisés en deux types : synchrone (par rapport à l'horloge système) et asynchrone. Tous les générateurs ne peuvent pas être utilisés avec un canal synchrone, et certains utilisateurs d'événements ne peuvent utiliser que les canaux synchrones, et les listes de canaux sont moins cohérentes et plus nombreuses. Cette folie a été abandonnée à la première occasion – même le méga0 avait supprimé cette distinction.
**
Seules les séries 2 et les pièces non minuscules peuvent déclencher une interruption basée sur l'état CCL.
Toutes les pièces ont une entrée analogique disponible sur la plupart des broches (toutes les broches sur PORTA et PORTB 0-1 et 4-5). Le deuxième ADC de la série 1+ peut également utiliser les broches du PORTC comme entrées (voir la référence analogique pour plus d'informations sur leur utilisation).
Ce sont les options budgétaires. Bien qu’ils soient pris en charge, ils ne sont pas recommandés. Ceux-ci n'obtiennent jamais le "boost" que la série tinyAVR 1 obtient à 16k, n'ont pas de deuxième TCB dans aucune configuration, pas de TCD, seulement 3 canaux d'événements, dont aucun ne peut transporter de sortie d'événement RTC. Ces pièces disposent de 2 LUT CCL comme la série 1 et sont disponibles avec jusqu'à 16 Ko de flash dans des configurations à 14, 20 et 24 broches (seulement 4 Ko pour les pièces à 8 broches) et jusqu'à 1 Ko de SRAM.
Ceux-ci ont 2k, 4k ou 8k de flash et 128, 256 ou 512b de RAM, tout comme la série 0. Ils n'ont pas le deuxième ADC, la configuration triple AC ou le deuxième TCB, bien qu'ils aient le TCD.
Tout d'un coup, à 16k, les pièces de la série 1 deviennent bien plus intéressantes. Le flash plus grand est accompagné d'un arsenal de périphériques qui semblent adaptés à une puce beaucoup plus grande, et qu'ils soient 16k ou 32k, ils reçoivent tous 2k de SRAM. Le deuxième ADC est unique parmi les AVR. Il semble avoir été le terrain de test de nombreuses fonctionnalités apparues sous une forme raffinée sur la série AVR Dx. Le prix ne semble pas tenir compte des périphériques largement supérieurs de la série 16k 1,
Comme vous pouvez le voir dans le tableau ci-dessus, la série 2 est presque plus une mise à niveau qu’une mise à niveau. Ils ont un ADC bien meilleur, le système d'évènements et les CCL sont "normaux", et ils ont plus de RAM, la partie 14 broches est disponible avec 32k de flash (un 3214 était apparemment prévu, mais ensuite annulé ; il est allé assez loin pour rester dans l'ATPACK pendant un certain temps avant d'être retiré)
J'ai rédigé un bref résumé indiquant quand vous souhaitez utiliser quelle série, si le bon choix n'est pas évident à ce stade.
Dans la définition officielle de la carte Arduino pour leur package matériel "megaavr", ils impliquent que la nouvelle architecture des pièces megaAVR de la série 0 (qui est presque la même que celle utilisée sur les tinyAVR séries 0 et 1) est appelée "megaavr". " - ce n'est pas un terme officiel. Microchip utilise le terme « megaAVR » pour désigner n'importe quelle pièce « ATmega », qu'elle soit dotée d'un style ancien ou de périphériques modernes. Il n'existe pas de terme officiel pour désigner toutes les parties AVR d'une famille ou d'une autre, et un employé de Microchip a même nié l'existence d'un tel terme en interne. Je ne sais pas comment vous pouvez fabriquer deux ensembles de pièces, les pièces de chaque ensemble ayant tant de points communs les unes avec les autres et si peu de points communs avec l'autre ensemble, sans que personne n'invente une expression pour faire référence à l'un ou l'autre.
Dans ce document, avant la version 2.0.2, nous utilisions la convention Arduino, et bien que plus d'un an se soit écoulé depuis, je continue de trouver des endroits où je les appelle mégaAVR. Veuillez signaler cela en utilisant un problème github si vous en voyez. Notez que les termes avr
et megaavr
sont toujours utilisés en interne (par exemple, dans les bibliothèques, pour marquer les parties avec lesquelles une bibliothèque donnée est compatible, ou pour séparer les différentes versions d'un fichier en fonction de ce sur quoi elles seront exécutées). Cela va continuer - nous devons nous en tenir à cela pour des raisons de compatibilité avec ce que l'équipe Arduino a commencé avec le noyau de l'Uno WiFi Rev. 2 et du Nano Every.
Quoi qu'il en soit, il faut un mot pour désigner les deux groupes et Microchip n'en a pas fourni. En l'absence de terme officiel, j'ai fait référence aux appareils AVR d'avant 2016 (avec registres PORTx, DDRx, etc. pour les broches) comme " AVR classique " et ceux qu'Arduino appelle megaavr comme " AVR moderne ". Il existe également des pièces dont les modules d'E/S ressemblent largement davantage aux AVR classiques, mais qui ont également une version nettement pire du jeu d'instructions et des tailles de flash typiques de 1k ou moins. Ceux-ci utilisent la variante AVRrc (pour noyau réduit) d'AVR, alors que la plupart des AVR classiques utilisent AVRe ou AVRe+, et que les AVR modernes utilisent AVRxt. Les pièces AVRrc ne sont pas supportées par ce noyau, et à la malheureuse occasion où j'aurai besoin de discuter de ces pièces profondément décevantes, je les appellerai pièces " Réduire Core AVR ", car c'est leur nom officiel, même si j'ai beaucoup des phrases plus colorées pour eux. Il est recommandé qu'aucune conception n'utilise un AVR à noyau réduit , point final. Non pas qu’ils soient obsolètes, ils sont juste moche. Il est recommandé d'utiliser les " AVR modernes " (ceux dotés des nouveaux périphériques et du jeu d'instructions AVRxt ) - soit la série Ex, la série Dx, tinyAVR 0/1/2 ou mega0 pour toutes les nouvelles conceptions.
Fiche technique de la nouvelle série tinyAVR 2 - Bien que la fiche technique ne « couvre » que les 16 000 pièces, elle indique clairement qu'il n'y a aucune différence de fonctionnalités entre les pièces ayant le même nombre de broches (c'est-à-dire qu'il n'y a pas de pièces « dorées » comme la 16k/32k 1-Series), uniquement entre les pièces avec un nombre de broches différent, et uniquement comme dicté par le nombre de broches (c'est-à-dire qu'une fonctionnalité sur la partie à 24 broches sera sur celle à 14 broches, à moins que celui à 14 broches n'ait pas les broches dont il a besoin, et c'est quelque chose qui ne peut pas être utilisé sans broches). Les pièces à 14, 20 et 24 broches sont toutes répertoriées avec flash 4k, 8k, 16k et 32k ; ces options de taille de flash, respectivement, sont livrées avec 512, 1024, 2048 et 3072 octets de SRAM (c'est-à-dire que les parties 4k et 8k ont le double de la SRAM), les parties 4/8k reçoivent 128 octets d'EEPROM, les plus grandes en reçoivent 256. Les pièces à 14 broches sont disponibles en SOIC et TSSOP, à 20 broches en SOIC (large), SSOP, et ainsi de suite. un tout petit QFN comme le 1616 (cette fois, ils nous ont également donné la partie 32k dans ce package, mais bonne chance pour en obtenir un, il est en rupture de stock partout - je n'ai pas pu en marquer un seul) et 24 broches dans le même VQFN que le 3217.
TWI, SPI, USART0, AC0 sont inchangés, tout comme NVMCTRL (les modifications requises sur le chargeur de démarrage concernaient uniquement la prise en charge du deuxième USART). Options d'horloge inchangées. TCB0 et TCB1 ont été mis à niveau vers la version de la série Dx : option d'événement d'horloge, cascade et bits INTCTRL séparés pour OVF et CAPT - ajouts intéressants, mais rien de pertinent pour le noyau lui-même), et toutes les parties ont les deux TCB. Nous obtenons maintenant 4 LUT CCL et 2 séquenceurs, au lieu de 2 et 1 - et ils peuvent déclencher des interruptions comme les autres parties avec CCL (et contrairement à la série tinyAVR 0/1). L'une des caractéristiques les plus intéressantes est que, comme prévu, ils disposent d'un deuxième USART (le bruit que vous entendez est celui de l'ATtiny841 et de l'ATtiny1634 qui sanglotent dans le coin). Les registres PORTMUX sont désormais nommés comme le reste des AVR modernes - mais nous n'avons pas perdu le contrôle individuel sur les broches de chaque canal TCA WO. EVSYS fonctionne désormais comme il le fait sur les pièces non minuscules de la série AVR-0/1 (ce qui est un changement bienvenu - la série 0/1 était l'intrus, et certaines des façons dont leur EVSYS était différent étaient nuls ). Les fonctionnalités de la série 1 de TCD0, AC1/2, DAC0 et ADC1 ont disparu . À leur place, l'ADC0 est beaucoup plus sophistiqué et presque méconnaissable, le premier nouvel AVR sorti depuis le rachat et doté d'un véritable ADC différentiel. (faites la queue, un autre gémissement d'agonie du pauvre '841, qui possède également un ADC incroyablement sophistiqué avec d'excellentes options différentielles, mais qui semble complètement daté à côté des nouveaux)... à en juger par le volume de messages sur différents sujets que j'ai Il semble que j'ai le sentiment que l'ADC différentiel n'était pas en tête de la plupart de vos listes de souhaits - mais il figurait en tête des listes des principaux clients de puces, et c'est donc ce que nous obtenons. Et il était presque temps que nous ayons un CAN différentiel approprié au lieu de celui de la série Dx. Et c'est vraiment très chic. Voir ci-dessous.
megaTinyCore fournit une implémentation analogRead() et des fonctions plus puissantes pour utiliser le suréchantillonnage et le PGA (voir la section sur les fonctionnalités analogiques ci-dessous).
Oh, et encore une chose... la configuration des broches UPDI a les anciennes options - UPDI, I/O ou Reset... et une nouvelle : UPDI sur PA0, avec broche matérielle RESET sur PB4 ! Optiboot sera enfin une option viable et confortable au moins sur les pièces dotées d'un PB4, c'est à dire pas sur les pièces à 14 broches. Ce qui se trouve également être (si les ventes de mon magasin Tindie sont une indication) le type le plus populaire.
Pensez-vous qu'il y aura une série 3 ? Non. DD et les EA les poursuivent clairement et prennent des positions stratégiques autour du petit territoire d'AVR. Je pense que ce n'est qu'une question de temps avant que la marque soit éliminée comme ils l'ont fait megaAVR après la série megaAVR 0. Ce n'est pas nécessairement une mauvaise chose : toutes les pièces des séries Dx et EA sont très similaires en termes de mappage de broches et de comportement, ce qui est très agréable. Les Tinies sont moins systématiques, même s'ils distribuent les broches à davantage de périphériques. Le principe directeur semble avoir été "aucun périphérique laissé pour compte". Contraste avec les mappages de broches des séries Dx et EA où tout suit un plan directeur fixe. Les pièces ont ou non une broche donnée, et si ce n'est pas le cas, cette fonction n'est pas disponible. Dans les deux grands groupes, je pense qu'il y a un chef de produit dont le travail consiste à fouetter les ingénieurs qui envisagent de faire une "exception" au Holy Pinout (puisque ces exceptions prolifèrent inévitablement et c'est ainsi que nous nous sommes retrouvés avec les affectations de broches de cible aux yeux bandés sur tinyAVR classique)
La numérotation des broches est étrange sur les tinyAVR, et c'est la faute de Microchip - ils ont étrangement numéroté les broches dans les ports : cela commence dans l'ordre, sauf que PA0 est UPDI et généralement inutilisable, puis les broches de PORTB sont numérotées dans l'ordre inverse, puis PORTC revient à la même numérotation dans le sens inverse des aiguilles d'une montre que PORTA. Donnez-moi une pause ! Puisque la tradition est d'utiliser la broche 0 pour la première broche et que le dernier numéro soit la broche que vous ne pouvez pas utiliser sans définir un fusible qui rend la puce difficile à programmer. J'aurais de loin préféré pouvoir les numéroter dans le sens inverse des aiguilles d'une montre en commençant par A0 sans enfreindre les conventions non écrites du code Arduino. On peut affirmer que j'ai pris une mauvaise décision concernant les mappages de broches - ils auraient peut-être dû commencer par PA0 (inutilisable à moins que le fusible ne soit activé, auquel cas la puce est difficile à programmer) comme broche 0, puis numéroter les broches dans le sens inverse des aiguilles d'une montre. Mais vous ne pourriez toujours pas faire le genre de trucs que vous pourriez faire si tous les ports étaient en ordre, à moins de numéroter les broches PORTB à l'envers. Si vous pouviez vous débarrasser de l'attente selon laquelle toutes les broches soient numérotées dans l'ordre (et utiliser uniquement la notation PIN_Pxn), des économies significatives pourraient être réalisées.
Je prédis que dans 2 à 4 ans, il y aura un AVR DA, DB, DD. Pièces DU (celle USB), EA et D/E/F jusqu'à un nombre de broches de 8 (ou au moins 14) et pièces à 64 broches avec flash 128k et le nouvel ADC. Et rien d'autre de marque ATtiny. La plus grande question qui reste est peut-être de savoir s'ils vont un jour remplacer l'ATmega2560 par un AVR moderne avec 100 broches au total (dont probablement 80 à 88 sont des E/S) et des options de flash jusqu'à 256 Ko ; Cela poserait trois problèmes : premièrement, au-delà de 56 broches d'E/S, il n'y a plus de registres VPORT - l'espace d'E/S faible est plein de 28 VPORT et 4 GPIOR. Comment vont-ils gérer les 4 ports supplémentaires ? (sur le 2560, il s'agissait simplement de ports de seconde classe auxquels on accédait plus lentement et qui n'avaient pas d'accès en un seul cycle. J'ai quelques réflexions à ce sujet et sur la faisabilité du peu d'opcodes disponibles dans l'annexe A ici. et deuxièmement, pour violer La barrière 128K en Flash, vous devez aller à un comptoir de programme 17 bits. "D x Part à 256k de Flash aurait 32k de RAM. Maintenant, rappelez-vous comment progmem fonctionne sur DX - ils ne pourraient pas aller jusqu'à 32. 24k RAM est certainement possible, peut-être même 28, mais à 32k, plus 32k pour Flash mappé, ne laisse aucune place pour les SFR, qui sont dans le même espace d'adressage.
Je vends des planches à cassoires avec le régulateur, l'en-tête Updi et l'en-tête série dans ma boutique Tindie, ainsi que les planches nus. L'achat dans mon magasin aide à soutenir le développement ultérieur au cœur et est un excellent moyen de commencer à utiliser ces nouvelles pièces passionnantes avec Arduino. Les conseils d'attiny1624 sont actuellement disponibles, mais les pièces de 20 et 24 broches ne seront pas vendues en tant que carte assemblée jusqu'à ce qu'une conception de PCB nouvellement révisée ne soit pas de retour de la maison de la carte pour permettre l'autoréglage sur la broche alt-réinitialisation. Il y a aussi une révision du conseil d'administration à 14 broches - pensant que c'était largement cosmétique. Le masque de soudure jaune doit aller, car la lisibilité semblait empirer dans les derniers lots. Les nouvelles panneaux standardisent également un espacement de 0,6 "entre les rangées d'épingles, au lieu de l'espacement actuel de 0,7", vous pourrez donc, par exemple, de mettre en tête de broche usin Utilisez-les avec notre carte de prototypage optimisée pour cet espacement des lignes. Les tableaux de la série 0 assemblés sont interrompus et ne seront pas réapprovisionnés une fois qu'ils se vendent. La même chose se produira pour les pièces de la série 16k 2 une fois les 32k disponibles.
L'ADC sur la série 2 et la série EA est le meilleur ADC qui a été publié sur un AVR dans l'ère AVR moderne. Outre ces deux-là. Les comparaisons les plus proches sont les AVR classiques qui ont obtenu des ADC différentielles avec des fonctionnalités de premier ordre (les T841, MEGA2560 et (étonnamment), le T861 étant les concurrents les plus forts). Bien qu'il ne soit pas capable du gain de 100x et 200x fou dont certaines pièces se sont vantées dans les jours AVR classiques, il ne m'a jamais été clair à quel point ce qui était amplifié était simplement du bruit (compte tenu de mon expérience certes limitée à jouer avec des ADC différentiels Je vais dire "probablement la plupart, et certainement la plupart si vous me permettez de concevoir le matériel, je ne connais pas analogique!"). Ce nouvel ADC est certainement très capable, avec une véritable capacité différentielle (contrairement à la série DA et DB), et qui augmente la tête et les épaules au-dessus de tout ce qui est disponible sur tout autre AVR moderne à ce jour. L'amplificateur de gain programmable est une nouvelle capacité, et il reste à voir quel type d'exploitations de mesures analogiques que les gens sont capables d'en sortir; Il semble certainement prometteur. Il sera particulièrement intéressant de comprendre les différences entre l'utilisation du PGA à 1x gain, vs non utiliser le PGA, et les avantages et les inconvénients de le faire. (Microchip serait bien servi par un document qui a expliqué comment choisir la bonne configuration ADC pour une tâche dans le cas général; j'ai soulevé cette préoccupation avec Microchip et la personne à qui j'ai parlé indiqué que c'était une priorité élevée; pendant que La situation a été considérablement améliorée, il semble toujours que le groupe DOC ait été spécifiquement invité à ne pas faire de recommandations concrètes de toute sorte.
L'ajout d'accumulation de 1024 échantillons à des fins de suréchantillonnage et de décimation est un ajout bienvenu, bien que celle qui risque également sous-estimant l'ampleur et la pertinence de l'erreur de décalage. (Prendre 1024 échantillons (qui ont tous une erreur de décalage donnée), puis décimer la somme pour donner une mesure ADC 17 bits permet d'imaginer facilement que toute erreur serait limitée aux deux bits les plus bas. Mais si l'erreur Était, disons 5 LSB sur une seule mesure, lorsque vous accumulez 1024 échantillons et décime, vous avez une erreur de décalage de 160, il est extrêmement facile de voir cela et de penser qu'il n'est pas du bruit.
La première puce pleine grandeur (non-minuscule) avec le nouvel ADC est disponible dans des packages de 28-48 broches avec jusqu'à 64k flash. Il y avait la spéculation habituelle sur ce qui allait si quelque chose passait de la série 2 à la série EA: il semble que la réponse soit, l'un des boutons confus a été supprimé et le hachage automatique des signes pour les mesures accumulées (
La minuterie de type D est uniquement utilisée pour PWM sur les pièces de la série 1 Pin 124 sur les paramètres PWM par défaut. Sur les pièces plus petites, cela ne nous laisserait pas augmenter le nombre total de broches PWM. Seules les broches WOC et WOD (sur PC0 et PC1 respectivement) n'ont pas déjà de PWM dirigée par TCA. En tant que tel, puisque AnalogWrite () ne prend en charge aucune fonctionnalité qui serait activée en désactivant le mode Split (comme PWM 16 bits) ou amélioré en utilisant la minuterie de type D (comme l'ajustement de la fréquence), ce serait juste pire, car Il faudrait un espace supplémentaire pour stocker la routine pour activer et éteindre PWM à partir de deux types de minuterie, au lieu d'un. Ce n'est pas négligeable sur les plus petites pièces flash; Il est de l'ordre de 600 octets. 150 pour DigitalWrite () et 450 pour analogwrite () Si ceux-ci sont appelés sur une broche PWM TCD. L'optimiseur devrait être en mesure d'optimiser cette partie de ces fonctions dans ce cas, tant que les broches utilisées avec ces fonctions n'incluent aucune broche PWM TCD. Remarque L'optimiseur les considérera indépendamment, c'est-à-dire que DigitalWrite () inclura le code pour désactiver TCD PWM s'il est utilisé avec une broche qui utilise TCD pour PWM, que vous appeliez ou non AnalogWrite () sur cette broche.
Contrairement à presque tous les autres AVR (je peux penser à peut-être 3 exemples, et un seul d'entre eux est un "bonus" pas un "non de channeau"), il existe des fonctionnalités "bonus" supplémentaires basées sur la taille de la taille d'une famille au sein d'une famille . Les versions 16K et 32K (uniquement) ont quelques fonctionnalités supplémentaires (qui ne semblent pas non plus avoir été considérées pour les prix) - ils ont tous 2k de RAM, qu'ils soient 16k ou 32k, ils ont 3 comparateurs analogiques (y compris un mode de fenêtre Option), une seconde - désespérément nécessaire - Tipe de type B - et le plus étrange de tout ce dont ils ont un deuxième ADC, ne différant que dans lesquels les épingles correspondent aux canaux!
Contrairement aux AVR classiques, sur ces parties, le flash est mappé au même espace d'adressage que le reste de la mémoire . Cela signifie que pgm_read_*_near()
n'est pas nécessaire pour lire directement à partir de Flash. Pour cette raison, le compilateur met automatiquement toute variable déclarée const
dans le progmem et y accéde de manière appropriée - vous n'avez plus besoin de les déclarer explicitement en tant que progmem. Cela inclut les littéraux de cordes cités, de sorte que la macro f () n'est plus nécessaire non plus, mais pour maintenir la compatibilité avec certaines bibliothèques tierces, F () déclare toujours son argument progmem.
Cependant, notez que si vous déclarez explicitement un progmem variable, vous devez toujours utiliser les fonctions pgm_read
pour la lire, tout comme sur les AVR classiques. Lorsqu'une variable est déclarée progmem sur des pièces avec un flash mappé de mémoire, le pointeur est décalé (l'adresse est relative au démarrage du flash, pas au début de l'espace d'adressage); Ce même décalage est appliqué lors de l'utilisation des macros pgm_read_*_near()
. Notez que déclarer les choses progressives et accéder à pgm_read_*_near
des fonctions, bien qu'elle fonctionne bien, est plus lente et gaspille une petite quantité de flash (par rapport à la déclaration simplement des variables const); Il en va de même pour la macro f () avec des chaînes constantes en 2.1.0 et plus tard (pendant une période avant 2.1.0, F()
n'a rien fait - mais cela a causé des problèmes pour les bibliothèques tierces). Les auteurs ont soutenu que le problème était avec le noyau, pas la bibliothèque, et mon choix était d'accepter moins d'efficacité ou de refuser à mes utilisateurs l'accès aux bibliothèques populaires). L'utilisation de la macro F()
peut être nécessaire pour la compatibilité avec certaines bibliothèques tierces (les cas spécifiques qui ont forcé le retour de F()
sur nous n'étaient pas de ce genre - nous avons réellement pu faire de ceux que je connaissais avec le travail avec le F () - Code en ce qui concerne le NOOP, et ils ont pris quelques octets en moins Flash en conséquence).
Les versions automobiles devraient également fonctionner. Vous devez toujours sélectionner les vitesses d'horloge dérivées de 16 MHz sur ces pièces. Ils ne prennent pas en charge le fonctionnement de 20 MHz et les options d'horloge réglées ne doivent pas être utilisées.
Passons maintenant à la bonne partie, où nous pouvons parler de la façon dont tout cela est exposé par le mégatinycore. Nous allons commencer par la façon dont vous devez vous référer aux broches pour de meilleurs résultats, puis passer aux fonctionnalités principales, options de menu, avant de se terminer par une série de liens vers des documents avec plus de détails sur divers sous-systèmes.
La simple question de savoir comment se référer à une broche pour analograread () et digitalread (), en particulier sur le matériel non standard, a été une source persistante de confusion chez les utilisateurs d'Arduino. Je suis à mon avis qu'une grande partie du blâme repose sur les décisions prises par l'équipe Arduino (et auteur de Wiring avant eux) concernant la façon dont les épingles devaient être mentionnées; La désignation de certaines broches en tant que «broches analogiques» amène les gens à penser que ces broches ne peuvent pas être utilisées pour les opérations numériques (elles sont mieux considérées comme des «broches avec entrée analogique» - comme la façon dont il y a des «broches qui peuvent sortir PWM»). Le fait que les épingles aient été traditionnellement renumérotées a encore brouillé l'eau. Pour les pièces AVR classiques non standard, les choses sont souvent encore aggravées par de multiples "mappages de broches" incompatibles créés par divers auteurs au fil des ans pour que la pièce agisse "plus comme une uno" ou à d'autres fins (Atttinyccore est un particulier Match de cette manière, avec certaines pièces ayant trois mappages de broches entièrement différents, dans au moins un cas, l'une des mappages alternatifs est une œuvre d'inspiration diable de Pure Evil, ne nécessitant rien de moins qu'une table de recherche supplémentaire pour convertir les broches analogiques en numérique broches).
Ce noyau utilise un schéma simple pour attribuer les numéros de broches Arduino: les broches sont numérotées à partir de la broche d'E / S la plus proche de VCC en tant que broche 0 et procédant dans le sens antihoraire, en sautant la broche Updi (principalement) non utilisable. La broche UPDI est ensuite attribuée au dernier numéro de broche (comme indiqué ci-dessus, il est possible de lire la broche UPDI (les lectures analogiques et numériques fonctionnent) même si elle n'est pas définie comme GPIO). Nous recommandons cela en dernier recours: la broche UPDI a toujours son pullup activé lorsqu'il n'est pas défini comme une broche GPIO, et un signal qui ressemble trop à la séquence d'activation Updi provoquera un fonctionnement indésirable.
Afin d'éviter toute confusion sur les identités de broches et d'éliminer l'ambiguïté, nous vous recommandons d'utiliser la notation PIN_PXN pour se référer aux épingles, sauf si vous utilisez une carte de développement avec différents nombres ou noms pour les épingles imprimées dessus. Cela maximisera la portabilité de votre code à un autre matériel similaire et facilitera la recherche d'informations sur les épingles que vous utilisez dans les fiches techniques pertinentes, si cela est nécessaire.
Il s'agit du moyen recommandé de se référer aux broches #defines
sont également fournies par le formulaire PIN_Pxn
, où x
est A, B ou C, et n
est un nombre 0-7 - (à ne pas confondre avec le Pin_an définit ci-dessous). Ceux-ci se résolvent simplement au numéro de broche numérique de la broche en question - ils ne passent pas par un chemin de code différent ou quoi que ce soit. Cependant, ils ont une utilité particulière dans l'écriture de code qui fonctionne à travers la gamme de produits avec des périphériques liés à certaines épingles (par port), comme la plupart des périphériques. Plusieurs éléments de code de démonstration dans la documentation en profitent. La manipulation directe du port est également possible - et en fait, plusieurs options supplémentaires puissantes sont disponibles pour elle - voir la manipulation directe du port .
PIN_Pxn
- pas Pxn
, et non PIN_xn
- ceux-ci signifient différentes choses!
Lorsqu'un seul numéro est utilisé pour se référer à une broche - dans la documentation ou dans votre code - c'est toujours le "numéro de broche Arduino". Ce sont les nombres de broches indiqués en orange (pour les broches capables d'Analogread ()) et du bleu (pour les broches qui ne le sont pas) sur les graphiques d'épingle. Toutes les autres façons de se référer aux broches sont #définies au numéro de broche Arduino correspondant.
Le noyau fournit également An
constantes et PIN_An
(où n
est un nombre de 0 à 11). Comme pour le noyau officiel, PIN_An
est défini comme le numéro de broche numérique de la broche partagée avec le canal analogique n celles-ci se réfèrent aux numéros de canal ADC0. Ce système de dénomination est similaire à ce qui a été utilisé sur de nombreux noyaux AVR classiques , mais ici, ils sont simplement défini comme le numéro de broche Arduino correspondant . Si vous avez besoin d'obtenir le numéro de canal analogique sur une broche numérique, utilisez la macro digitalPinToAnalogInput(pin)
- mais vous n'en avez besoin que si vous écrivez une bibliothèque ADC avancée.
Ces pièces (enfin, la série 1/2 au moins - la série 0 était conçue comme une option de budget, sauf qu'elles n'ont pas réussi à réduire le budget, et ce sont seulement quelques cents moins chers) fournissent une excellente boîte à outils de polyvalence et des périphériques puissants; Les haut-parleurs sont à égalité avec ou mieux que les pièces MEGAAVR classiques - à un prix minuscule. L'un des principes directeurs de la conception du mégatinyccore, comme avec mes autres noyaux, est de permettre aux pièces prises en charge d'atteindre leur plein potentiel - ou aussi près que possible dans les limites d'Arduino. Cette section (très grande) couvre les caractéristiques de ces pièces et comment elles sont exposées par le mégatinyccore, ainsi que les caractéristiques du noyau lui-même. Cette (très grande) section tente de couvrir chacune des zones de caractéristiques. Essayez de trouver la fonctionnalité avec laquelle vous travaillez si vous essayez d'utiliser une fonctionnalité de puce et d'avoir des problèmes!
Nous ne faisons aucune affirmation sur les gammes de tension ou de température pour les pièces overclockées - tout ce que nous prétendons, c'est qu'au moins un des puces que nous avons travaillé à cette vitesse à température ambiante, exécutant un croquis spécifique, à 5V. Votre kilométrage devrait varier, mais être généralement meilleur avec une pièce F Spec par rapport à une partie N ou U Spec.
IMPORTANT - En savoir sur le réglage avant de sélectionner une option réglée!
Plus d'informations sur ces vitesses d'horloge peuvent être trouvées dans la référence de l'horloge
Les tensions indiquées sont celles garanties pour fonctionner par les spécifications du fabricant ( / La série 1 fonctionnera également généralement à 32 MHz avec une horloge externe à condition que l'alimentation soit un 5,0 à 5,5 V) stable.
Aucune action n'est requise pour définir le fusible OSCCFG
lorsque l'esquisse est téléchargée via Updi. Lorsqu'il est téléchargé via Optiboot, le fusible ne peut pas être modifié, donc tout ce qui a été choisi lorsque le chargeur de démarrage a été brûlé est ce qui est utilisé, et seul "Burn Bootloader" ou le téléchargement d'un croquis via Updi changera cela.
Toutes les options de vitesse d'horloge de l'oscillateur interne utilisent l'étalonnage par défaut d'usine, sauf si une option "réglée" est sélectionnée, auquel cas l'étalonnage est ajusté comme documenté dans la référence de réglage . Cela peut être utilisé pour obtenir une opération de 16 MHz sur une puce Optiboot fusionnée pour 20 MHz et vice versa.
Voir la référence de grade de vitesse pour plus d'informations sur les notes de vitesse du fabricant. Notez que ce sont les tensions et les vitesses d'horloge auxquelles il est garanti de fonctionner. Ces pièces sont destinées à être utilisées pour une utilisation dans des applications où un problème inattendu d'une description pourrait poser un danger pour les personnes ou les biens (réflexion, équipement industriel, avions, réacteurs nucléaires - endroits où les gens pourraient mourir si la pièce a mal fonctionné) et I Croyez également pour les applications militaires, qui ont des exigences de fiabilité similaires, juste pour la raison inverse. Les utilisateurs de passe-temps typiques seront beaucoup plus détendus quant au potentiel de problèmes de stabilité, les accidents étant un peu plus qu'une nuisance, et les extrêmes des pièces de la plage de température prolongées dépassant ce dont nous aurions besoin. En supposant que la planche avait un revêtement imperméable, thermiquement, une partie N de grade N devrait pouvoir fonctionner selon le grade de vitesse dans un pot d'eau bouillante. Et c'est juste le n-spécial. Le F-Spec devrait être bon à 125!
Il a été établi que les pièces de température étendues overclockent mieux, ce qui a du sens. Une partie qui est spécifique pour fonctionner à 20 MHz à 125C devrait avoir une meilleure chance de fonctionner à 32 MHz à température ambiante qu'un spécifique pour fonctionner à 20 MHz uniquement à 105C
À partir de la version 2.4.0, nous fournissons désormais une option de "carte microchip officielle". Cela ne fait rien de spécial autre que la définition LED_BUILTIN
comme la broche qui a la LED sur cette carte, au lieu de A7, et de définir une macro PIN_BUTTON_BUILTIN
définie comme la broche avec le bouton utilisateur dessus et en faisant "télécharger" avec le non -prrogrammer / débogueur à bord utilisez toujours le programmeur / débogueur embarqué; Outils -> Le programmeur sera utilisé uniquement pour "Burn Bootloader" et "Télécharger à l'aide du programmeur". Dans le cas du nano ATtiny416 Xplagé, il sélectionne également la version du chargeur de démarrage qui utilise les broches alternatives pour le port série - il n'utilise pas automatiquement les épingles alternatives pour USART0 comme si vous aviez fait Serial.Swap (1) pourtant pourtant encore - La fonctionnalité pour prendre en charge l'échange par défaut des broches en série sera disponible dans une future mise à jour, parallèlement à d'autres modifications dans la machine sous-jacente au mécanisme PINSWAP qui, espérons-le, réduira également l'utilisation du flash.
Comme indiqué ci-dessus, ceux-ci peuvent ne pas fonctionner correctement sur les plates-formes Linux 32 bits. Ceci est hors de ma volonté; Je ne construit pas de binaires Avrdude AMD Je n'assume pas non plus cette tâche. J'en ai déjà trop.
blink()
prend-il plus de flash sur le Mini Xplagé VS le XPlated Pro?Les deux ont le même atttiny817! Comment peuvent-ils être différents?
Pour la même raison que Blink prendra plus de flash si vous le modifiez pour utiliser PIN_PC0
par opposition à PIN_PB4
: PC0, utilisé sur le Mini Xplagé est une broche PWM, tandis que PB4, utilisé par le XPlated Pro ne l'est pas. Puisque c'est la seule broche sur laquelle DigitalWrite () est utilisée, le compilateur est libre d'optimiser tout ce qui n'est pas nécessaire pour DigitalWrite () sur cette broche, y compris la fonctionnalité pour désactiver la sortie PWM sur une broche qui prend en charge PWM . La différence disparaît si DigitalWrite () est également utilisée sur une broche qui prend en charge PWM sur les deux appareils (résultant en le résultat d'utilisation du flash plus élevé) ou si DigitalWrite () est remplacé par DigitalWriteFast (), qui utilisera moins de flash (mais suppose que vous avez gagné 't appelle-t-on sur une broche en sortie PWM).
Chaque fois qu'un programmeur Updi est utilisé pour télécharger du code, toutes les fusibles qui peuvent être définies "en toute sécurité" (comme dans, sans risque de briquement de la carte, ou de briquement si l'on n'a pas accès à un programmeur HV), et qui ont des Les options de configuration intégrées seront définies. Ainsi, sauf lorsqu'il est noté, le comportement correspondra toujours au menu des outils sélectionnés. En résumé, ceux-ci sont gérés comme suit:
WDTCFG will not be changed - it is not configured by megaTinyCore except to reset it to the factory default when doing "burn bootloader".
BODCFG will not be changed - not safe, you could set the BOD level to 4.3 on a 3.3v system, and then it would need to get > 4.3v applied to reprogram it. If it is on the same circuit board as parts that would be damaged, this is a difficult situation to recover from.
OSCCFG will be set
TCD0CFG will not be changed - it is not configured by megaTinyCore except to reset it to the factory default when doing "burn bootloader".
SYSCFG0 will not be changed - not safe
SYSCFG1 will be set
APPEND will not be changed - it is not configured by megaTinyCore. There is insufficient demand to justify the development effort.to make use of this as DxCore does
BOOTEND will be set
LOCKBIT will not be changed - it is not configured by megaTinyCore; supporting the lockbits presents several additional complications, and commercial users with need of this facility are unlikely to be using the Arduino IDE to program production units.
BODCFG
n'est pas sûr, car le régler sur une tension plus élevée que la carte fonctionne et l'activera "brique" la carte jusqu'à ce qu'une tension de fonctionnement plus élevée puisse être fournie; Cela pourrait être particulièrement gênant s'il est soudé aux mêmes PCB que les appareils qui ne toléreront pas ces tensions.
SYSCFG0
n'est pas sûr car c'est là que la vie RSTPINCFG
; Changer cela peut laisser la carte non programmable, sauf via la programmation HV UPDI, et tout le monde n'a pas de programmeur HV Updi. Dans le futur si / quand un programmeur qui garantit la capacité HV UPDI qui peut être sélectionnée comme programmeur (c'est-à-dire, il devient possible de créer une option d'outils -> programme ce programmeur.
En conséquence en 2.2.0 et ultérieurement, vous n'avez plus besoin de «brûler le chargeur de démarrage» pour basculer entre les vitesses dérivées de 16 MHz et des vitesses dérivées de 20 MHz lors du téléchargement à l'aide de UPDI
Ce noyau utilise toujours l'optimisation du temps de liaison pour réduire l'utilisation du flash - toutes les versions du compilateur qui prennent en charge les pièces TinyAVR 0/1/2 de la série prennent également en charge le LTO, il n'est donc pas nécessaire de le rendre facultatif, comme cela a été fait avec Attinyccore. Ce fut une énorme amélioration de la codédimension lors de l'introduction, généralement de l'ordre de 5 à 20%!
Ces pièces ont toutes un grand nombre d'entrées analogiques - les séries DA et DB ont jusqu'à 22 entrées analogiques, tandis que la série DD a une entrée analogique sur chaque broche qui n'est pas utilisée pour conduire le cristal HF (bien que les broches sur Portc soient Seule pris en charge lorsque MVIO est éteint). Ils peuvent être lus avec analogRead()
comme sur un AVR normal, et nous avons par défaut une résolution 10 bits; Vous pouvez passer au 12 bits complet avec analogReadResolution()
, et utiliser les fonctions analogiques améliorées pour prendre automatiquement des lectures déciméées sur la résolution plus élevée et pour prendre des mesures différentielles. Il y a 4 références de tension interne dans 1.024, 2.048, 4.096 et 2,5 V, plus la prise en charge de la tension de référence externe (et du VDD bien sûr). Les lectures ADC sont prises 3 fois plus rapidement qu'un AVR classique, et cette vitesse peut être doublée à nouveau si ce que vous mesurez est une faible impédance ou prolongez le temps d'échantillonnage d'un facteur considérablement pour lire des sources d'impédance très élevées. Ceci est détaillé dans la référence analogique.
Les pièces de la série DX ont un DAC 10 bits qui peut générer une tension analogique réelle (notez que cela fournit un courant faible et ne peut être utilisé que comme une tension de référence ou une tension de contrôle, il ne peut pas être utilisé pour alimenter d'autres appareils). Cela génère des tensions entre 0 et le VREF
sélectionné (contrairement à la série TinyAVR 1, cela peut être VCC!). Définissez la tension de référence DAC via la fonction DACR reference()
- passez-la l'une des options de référence ADC répertoriées dans la section ADC ci-dessus (y compris VDD!). Appelez analogWrite()
sur la broche DAC (PD6) pour définir la tension pour être sortie par le DAC (cela l'utilise en mode 8 bits). Pour désactiver la sortie DAC, appelez digitalWrite()
ou turnOffPWM()
sur cette broche.
Il peut y avoir des options supplémentaires pour configurer le DAC dans la série EA.
Voir la référence ADC et DAC pour tous les détails.
L'utilisation des constantes An
pour les broches analogiques est obsolète - la pratique recommandée consiste à utiliser simplement le numéro de broche numérique, ou mieux encore, à utiliser la notation PIN_Pxn
lors de l'appel analogRead()
.
Il y a plus d'options que sur AVR classique pour la réinitialisation, y compris si le code est suspendu d'une manière ou d'une autre. Le temporisateur de garde ne peut se réinitialiser (utiliser le RTC et la pit pour les interruptions chronométrées).
Voir la réinitialisation et la référence de Watchdog (WDT) et la bibliothèque de base-aéliaire Megatinycore
Ce noyau ajoute un certain nombre de nouvelles fonctionnalités incluent des E / S numériques rapides (1-14 horloges selon ce qui est connu au moment de la compilation, et 2-28 octets de flash (le numéro de broche doit être connu au moment de la compilation pour les fonctions ________Fast()
, et pour configurer tous les paramètres par broches que le matériel a avec pinConfigure()
.
Voir la référence des E / S numérique améliorée .
Toutes les pièces de série 0/1 ont un seul port série matériel (UART ou USART); Les pièces de la série 2 en ont deux. Il fonctionne exactement comme celui des tableaux Arduino officiels, sauf qu'il n'y a pas de réinitialisation automatique, sauf si vous l'avez câblé en fusionnant la broche UPDI comme réinitialisant (nécessitant HV-Updi ou le Optiboot Bootloader pour télécharger du code), ou défini sur une "broche de réinitialisation ersatz" comme décrit ailleurs dans ce document. Voir les graphiques d'épingle pour les emplacements des broches en série.
Avant de mettre la pièce en mode de sommeil, ou de désactiver sa capacité à transmettre, assurez-vous qu'il a fini d'envoyer les données dans le tampon en appelant Serial.flush()
, sinon le port série émettra des caractères corrompus et / ou échoue Pour terminer la transmission d'un message.
Voir la référence série pour une liste complète des options. À partir de 2.5.0, presque tous les types de fonctionnalités que le matériel en série peut faire est prise en charge, y compris le mode RS485, le demi-duplex (via LBME et ODME), et même le mode SPI synchrone et maître, et 2.6.0 ajoutera Autobaud, Même si ce n'est pas très utile.
Toutes ces pièces ont une seule périphérique SPI matérielle. Il fonctionne comme celui des tableaux officiels Arduino en utilisant la bibliothèque SPI.H. Voir les graphiques d'épingle pour l'emplacement de ces épingles. Sur les pièces à 8 broches, la seule option pour la broche SS est PA0 (la broche Updi / Réinitialisation); Cependant, cela n'a pas d'importance aux fins de ce noyau, car, comme la bibliothèque officielle, cela ne fonctionne que comme maître, et la broche SS n'est utilisée que lorsque vous agissez potentiellement comme esclave.
Sur toutes les pièces à l'exception des pièces à 14 broches, les broches SPI peuvent être déplacées vers un autre emplacement (Remarque: Sur les pièces à 8 broches, la broche SCK ne peut pas être déplacée). Ceci est configuré à l'aide des méthodes SPI.swap()
ou SPI.pins()
. Les deux réalisent la même chose, mais diffèrent dans la façon dont vous spécifiez l'ensemble des broches à utiliser. Cela doit être appelé avant d'appeler SPI.begin()
.
SPI.swap(1)
ou SPI.swap(0)
définira le mappage sur les broches alternatives ( 1
) ou par défaut ( 0
). Il reviendra vrai s'il s'agit d'une option valide, et faux si ce n'est pas le cas (vous n'avez pas besoin de vérifier cela, mais cela peut être utile pendant le développement). Si une option non valide est spécifiée, elle sera définie sur la par défaut.
SPI.pins(MOSI pin, MISO pin, SCK pin, SS pin);
- Cela définira le mappage à ce que le mappage a les broches spécifiées. S'il ne s'agit pas d'une option de mappage valide, il renvoie False et définira le mappage par défaut. Cela utilise plus de flash que SPI.swap()
afin que la méthode soit préférée. L'argument SS pin
est facultatif, car la broche n'est pas utilisée lors du jeu de maître SPI, et ni cette bibliothèque ni la prise en charge officielle de la bibliothèque SPI.H agissant en tant qu'esclave.
Lorsqu'il peut être déterminé que les arguments transmis à SPI.swap()
ou SPI.pins()
ne sont pas valides au moment de la compilation (le plus souvent lorsque les arguments sont des constantes, ce qu'ils sont presque toujours), le noyau générera une compilation erreur à cet effet. Ceci est destiné à aider à empêcher ces problèmes détectables de nécessiter du temps de débogage sur le matériel.
Ce noyau désactive la broche SS, ce qui signifie que la broche "SS" peut être utilisée à quel point vous voulez, et la broche n'est pertinente que lorsque vous faites un esclave SPI (ce qui vous oblige à mettre en œuvre l'interaction avec le périphérique SPI vous-même - bien qu'il ne soit pas Science des fusées ou quoi que ce soit). Sur les AVR classiques, si SS était une entrée et que SPI était activée, elle agissait comme la broche SS, et si elle allait bas, elle changeait l'appareil en mode esclave (et Spi.h ne fonctionnerait pas avant de remettre dans le maître mode, ce qui n'a pas été fait automatiquement).
Toutes ces pièces ont un seul périphérique matériel I2C (TWI). Il présente une API compatible avec l'implémentation standard d'Arduino, mais avec une prise en charge supplémentaire pour plusieurs adresses esclaves, en répondant aux adresses d'appel générales et - le plus excitant - le fonctionnement simultané et le fonctionnement des esclaves! (Nouveau en 2.5.0).
Voir la documentation Wire.H pour la description complète et les détails. Le matériel I2C est l'un des périphériques les plus compliqués. Wire a eu beaucoup de nouvelles améliorations chaudes récemment le vérifier.
Le noyau fournit du matériel PWM via la fonction analogWrite()
standard. Sur les pièces à 8 broches (412, 212, 402, 204), 4 épingles PWM sont disponibles. Sur toutes les autres pièces, à l'exception des pièces de la série 1 ou 24 broches, 6 broches PWM sont disponibles, toutes entraînées par la minuterie A (TCA0). Les pièces de la série 1 et 24 broches 1 ont deux épingles supplémentaires, entraînées par TCD0. La série 2 a apparemment échangé TCD0 pour un deuxième port série et un ADC super-fréquentant - ces pièces ont également toutes 6 broches PWM. Les minuteries de type B (TCBN) ne peuvent pas être utilisées pour des broches PWM supplémentaires - leurs broches de sortie sont les mêmes que celles disponibles avec la minuterie A et ils sont souvent trop utiles pour justifier l'utilisation d'un TCB entier pour. Cependant, vous pouvez les reprendre si vous avez besoin de générer des PWM à différentes fréquences, bien que le fait que le Prescaler ne puisse pas différer du type de minuterie limite également. Voir les graphiques Pinout pour une liste dont les broches prennent en charge PWM.
À partir de 2.6.8, un sous-menu d'outils a été ajouté pour vous permettre de choisir parmi les mappages PWM utiles plausibles, et (en série 1) pour désactiver le PWM TCD pour enregistrer Flash.
Notez que TCA0 (la minuterie de type A) sur toutes les pièces est configurée par le noyau au démarrage pour fonctionner en mode Split afin de prendre en charge les broches les plus PWM possibles avec analogWrite()
. En ce qui concerne les versions 2.2.x, une fonction takeOverTCA0()
a été ajoutée, qui peut être appelée pour instruire le noyau qui ne pas écrire aux régistes TCA0 ni supposer un mode ou un comportement particulier pour TCA0. analogWrite()
ne générera pas de PWM sauf sur les broches entraînées par TCD0 sur les pièces 20/24 broches et digitalWrite()
ne le désactivera pas si vous souhaitez reconfigurer TCA0 à d'autres fins, veuillez vous référer au guide ci-dessous et "réinitialisation dure" La minuterie revient à la configuration des stocks.
Les 3216, 1616, 816, 416 et les 3217, 1617 et 817 ont deux broches PWM supplémentaires entraînées par la minuterie D (PC0 et PC1 - broches 10 et 11 sur x16, 12 et 13 sur x17). La minuterie D est une minuterie asynchrone (async), et les sorties ne peuvent pas être activées ou désactivées sans arrêter brièvement la minuterie. This results in a brief glitch on the other PWM pin (if it is currently outputting PWM) and doing so requires slightly longer - though the duration of this glitch is under 1 us. If TCD is used as the millis timer - which is the default on any part that has a type D timer (in order to keep the timers that are more readily repurposed available - TCD0 is not an easy peripheral to work with), this will result in millis()
losing a very small amount of time (under 1 us) every time PWM is turned on or off on a TCD pin.
As of 2.2.0, analogWrite()
of 0 or 255 on a TCD-driven PWM pin does not disconnect the pin from the timer - instead it results in a constant HIGH
or LOW
output without disconnecting the timer (use digitalWrite()
for that ). This means that analogWrite(PIN_PC0, 0)
or analogWrite(PIN_PC1, 0)
can be used to connect the timer to the pin without outputting PWM (yet) - doing this on both pins prior to setting any other duty cycles would allow one to ensure that no glitch of any sort occurs on the other TCD0 pin when the second pin is connected to it. Only digitalWrite()
or turnOffPWM()
will disconnect the timer from the pin . When outputting a HIGH
in this way, the pin is "inverted"; this means that digitalRead()
on it will return 0, not 1 (if you're digitalRead()
'ing a pin, which you have set to output a constant HIGH
, using analogWrite()
, and it's one of those two pins, it will read LOW
. However, if you are using digitalRead()
on a pin that you've set to output a constant value, you may be doing something wrong in general.
Because TCD is async, and can run from the unprescaled internal oscillator, that means you can lower the system clock frequency without affecting the speed of the PWM. While there is a difference in PWM frequency between 16-MHz derived and 20-MHz derived clocks, there is no change in frequency for different system clock speeds for the TCD-controlled pins (the TCA-controlled pins will vary by a factor of two) The exception to this is when TCD0 is used as the millis/micros timing source at 1 MHz - running at full speed there resulted in spending an unreasonable fraction of runtime in the millis()
ISR (tens of percent of the time).
TCD0 is used for millis()
/ micros()
by default on parts that have it. Be aware that this does have a small flash penalty, so you can save flash by switching to use TCA or a TCB as the timer. That will also make micros()
return faster. There is a shortage of timers on most of these parts, and I have not seen anyone talking about or posting code that reconfigures the TCD. Meanwhile everyone seems to be reconfiguring the TCA and many libraries need a TCB. These factors have been the impetus for making TCD0 the default for millis()
/ micros()
: it is least likely to directly interfere.
On some versions of megaTinyCore prior to 2.2.0, PWM on the TCD0 pins was entirely broken.
For general information on the available timers and how they are used PWM and other functions, consult the guide: This also covers the PWM frequencies that these timers will give you at various system clocks. Timers and megaTinyCore
Support for tone()
is provided on all parts using TCB0, unless TCB1 is present and TCB0 is set as millis()
source. This is like the standard tone()
function. Unlike on some classic AVRs, it does not support use of the hardware 'output compare' to generate tones; due to the very limited PWM capabilities and restricted prescaler selection for the TCB timers, this is not practical. See caveats below if using TCB0 or TCB1 for millis()
/ micros()
settings. See the timer reference for more information
tone()
can only play a tone on one pin at a time. In theory you can play one tone per Type B timer, simultaneously, without anything more exotic than what tone()
does now other than adding a capability to manage the multiple pins. It is my opinion that those belong in a library, not the core. See comments in tone.cpp
for some thoughts if you want to implement something like that - I'd be happy to give more thoughts if you have questions.
megaTinyCore provides the option to use any available timer on a part for the millis()
/ micros()
timekeeping, controlled by a Tools submenu. It can be disabled entirely if needed to save flash, allow use of all timer interrupts or eliminate the periodic background interrupt. By default, TCD0 will be used by on parts that have one - otherwise TCA0 will be used (in versions prior to 1.1.9, TCA0 was used by default on parts that could output PWM with TCD0 on pins not available for TCA0 PWM). All timers available on the parts can be used: TCA0, TCD0 (on parts that have it), TCB0, TCB1 (where present) and the RTC. Many of these - particularly the non-default options, involve tradeoffs. In brief, TCA0 is a very versatile timer that users often want to reconfigure, TCD0 loses a small amount of time when PWM is turned on or off on the two TCD0 PWM pins (10,11 on 20-pin parts, 12,13 on 24-pin parts), TCB0 conflicts with Servo
and tone()
on parts that don't have TCB1, and when the RTC is used micros()
is not available at all because the clock isn't fast enough. With these limitations in mind, the timer selection menu provides a way to move millis()
/ micros()
to the timer most appropriate for your needs.
For more information, on the hardware timers of the supported parts, and how they are used by megaTinyCore's built-in functionality, see the Timers and megaTinyCore Reference .
2.3.0 fixed a long-standing (though surprisingly low impact) "time travel" bug.
millis()
If the RTC is selected as the timer for millis()
timekeeping, micros()
will not be available. Additionally, this timer will be configured to run while in STANDBY sleep mode. This has two important consequences: First, it will keep time while in sleep. Secondly, every 64 seconds, the RTC overflow interrupt will fire, waking the chip - thus, if you are using the RTC for millis()
and putting the part into sleep, you should declare a volatile global variable that you set in the ISR that is supposed to wake the part, eg volatile boolean ShouldWakeUp=0;
, set it to 1 in the ISR, and when you put the ATtiny to sleep, have it check this immediately after waking, going back to sleep if it's not set, and clearing it if it is set, eg:
void GoToSleep () {
do {
sleep_cpu ();
} while (!ShouldWakeUp)
ShouldWakeUp= 0 ;
}
This functionality will be made easier to use via ModernSleep when that library is available.
This board package also supports using an external 32.768khz crystal as the clock source for the RTC (not supported on 0-Series or 8-pin parts - not our fault, the hardware doesn't support it). If this is used, make sure that the crystal is connected between the TOSC1 and TOSC2 pins (these are the same as the TX and RX pins with the default pin mapping - very convenient right?), that nothing else is, that no excessively long wires or traces are connected to these pins, and that appropriate loading capacitors per crystal manufacturer datasheet are connected (and that it's not a full moon - I found the 32k crystal to be extremely uncooperative. To reduce power usage, they try to drive the crystal as weakly as they can get away with, which in turn makes it more susceptible to interference.
Yes, you can use an external oscillator for the RTC, at least on 1 and 2 series parts. When it's an oscillator not a crystal, it can be fed to either TOSC0 or EXTCLK; better support for this will come in the future. Note that while TOSC0 won't let you run the RTC at widlly faster speeds. EXTCLK will.
printf()
Support for "printable" Class Unlike the official board packages, but like many third party board packages, megaTinyCore includes the printf()
method for the printable class (used for UART serial ports and most everything else with print()
methods); this works like sprintf()
, except that it outputs to the device in question; Par exemple:
Serial.printf( " Milliseconds since start: %ld n " , millis());
Note that using this method will pull in just as much bloat as sprintf()
and is subject to the same limitations as printf - by default, floating point values aren't printed. You can use this with all serial ports You can choose to have a full printf()
implementation from a Tools submenu if you want to print floating point numbers, at a cost of some additional flash.
printf()
and Variants Thereof Have Many Pitfalls There are a considerable number of ways to screw up with printf()
. Some of the recent issues that have come up:
printf()
- printf()
bugs are a common cause of software bugs in the real world. Be aware that while you can use F() on the format string, there are no warnings for invalid format strings in that case ; a conservative programmer would first make the app work without F() around the format string, and only switch to F() once the format string was known working.From cplusplus.com:
The length sub-specifier modifies the length of the data type. This is a chart showing the types used to interpret the corresponding arguments with and without length specifier
(if a different type is used, the proper type promotion or conversion is performed, if allowed): Strikethrough mine 'cause that don't work here (and it's not my fault nor under my control - it's supplied with avrlibc, and I suspect that it's because the overhead of implementing it on an 8-bit AVR is too large). When incorrect length specifiers are given (including none when one should be used) surprising things happen. It looks to me like all the arguments get smushed together into a group of bytes. Then it reads the format string, and when it gets to a format specifier for an N byte datatype, it grabs N bytes from the argument array, formats them and prints them to whatever you're printing to, proceeding until the end of the format chaîne. Thus, failing to match the format specifiers' length modifiers with the arguments will result in printing wrong data, for that substitution and all subsequent ones in that call toprintf()
.
The table below comprises the relevant lines from that table - many standard types are not a thing in Arduino (their original was several times longer, but including that mess would just complicate this discussion.
longueur | di | uox X | f F e E g G a A | c | s | p | n |
---|---|---|---|---|---|---|---|
(aucun) | int16 | uint16 | flotter | int | carboniser* | vide* | int* |
hh | int8 | uint8 | carboniser* | ||||
je | int32 | uint32 | int32_t* |
Notice that there is no line for 64 bit types in the table above; these are not supported (support for 64-bit types is pretty spotty, which is not surprising. Variables of that size are hard to work with on an 8-bit microcontroller with just 32 working registers), and using uint64's is something you should try to avoid, similar to driving on the wrong side of the road, flying kites during thunder storms, or drinking bleach. While all have been suggested (Europe is really persistent about the side of the road; As far as I'm concerned, it comes down to physics; mirror image symmetry i. This applies to all versions of printf()
- the capability is not supplied by avr-libc.
There are reports of memory corruption with printf, I suspect it is misunderstanding of above that is actually at hand here.
printf()
Implementation A Tools submenu lets you choose from three levels of printf()
: full printf()
with all features, the default one that drops float support to save 1k of flash, and the minimal one drops almost everything and for another 450 bytes flash saving (will be a big deal on the 16k and 8k parts. Less so on 128k ones). Note that selecting any non-default option here will cause it to be included in the binary even if it's never called - and if it's never called, it normally wouldn't be included. So an empty sketch will take more space with minimal printf()
selected than with the default, while a sketch that uses printf()
will take less space with minimal printf()
vs default.
Donc:
Sélection des menus | printf() or similar used? | Aérien |
---|---|---|
Défaut | Non | 0 by definition |
Défaut | Oui | apx 1500 |
Minimal | Non | apx 1000 |
Minimal | Oui | apx 1100 |
Complet | Non | apx 2800 |
Complet | Oui | apx 3000 |
Notice how when not using printf or similar functions, you are far better off leaving it on the default, as opposed to switching to minimal thinking you'll save flash, because you you'll use more flash not less.
All pins can be used with attachInterrupt()
and detachInterrupt()
, on RISING
, FALLING
, CHANGE
, or LOW
. All pins can wake the chip from sleep on CHANGE
or LOW
. Pins marked as Async Interrupt pins on the megaTinyCore pinout charts (pins 2 and 6 within each port) can be used to wake from sleep on RISING
and FALLING
edges as well. Those pins are termed "fully asynchronous pins" in the datasheet.
Advanced users can instead set up interrupts manually, ignoring attachInterrupt()
, manipulating the relevant port registers appropriately and defining the ISR with the ISR()
macro - this will produce smaller code (using less flash and RAM) and the ISRs will run faster as they don't have to check whether an interrupt is enabled for every pin on the port.
For full information and example, see the Interrupt Reference.
Like my other cores, Sketch -> Export compiled binary will generate an assembly listing in the sketch folder. A memory map is also created. The formatting of the memory map leaves something to be desired, and I've written a crude script to try to improve it, see the Export reference for more information. see Exported Files documentation
The EESAVE fuse can be controlled via the Tools -> Save EEPROM menu. If this is set to "EEPROM retained", when the board is erased during programming, the EEPROM will not be erased. If this is set to "EEPROM not retained", uploading a new sketch will clear out the EEPROM memory. Note that this only applies when programming via UPDI - programming through the bootloader never touches the EEPROM.
You must do "burn bootloader" in order to apply changes after modifying this setting, as EESAVE is on the same fuse as one the one that can be used to disable UPDI, making it an "unsafe" fuse (one that if written with the wrong options, can make the device difficult to reprogram). We don't write "unsafe" fuses like that when uploading sketches, because it should never be possible to brick your board just by uploading, which you can do without opening the tools menu and seeing that you forgot to change the options back to the intended ones for the current project.
These parts officially support BOD trigger levels of 1.8V, 2.6V, and 4.2V, with Disabled, Active, and Sampled operation options for when the chip is in ACTIVE and SLEEP modes - Disabled uses no extra power, Active uses the most, and Sampled is in the middle. As of 2.1.0, the ACTIVE/SLEEP modes have been combined into a single menu, the nonsensical options (such as using more aggressive BOD while sleeping than while awake) were removed, and the previously unexposed options were added. Sampled mode is now available with two sample rates (the faster one uses ever so slightly more power, as you would expect) and "Enabled hold wake": in that mode, BOD is disabled in sleep, enabled when not sleeping, and when waking up, code execution does not begin until the BOD is ready. See the datasheet for details on power consumption and the meaning of these options.
You must do Burn Bootloader to apply this setting. This fuse is considered "unsafe" as you can set the BOD level to a voltage higher than the highest voltage tolerated by other chips soldered to the same pcb and sharing a power rail with the AVR, and this will then prevent reprogramming without desoldering things (because you'll either be unable to program the AVR because it's in brownout reset, or if you power it at a high enough voltage to leave BOR, you would damage the afore-mentioned low voltage parts).
Between the initial header file and preliminary datasheet release, and the more recent versions of each, several BOD settings were removed from the tinyAVR 0/1-Series datasheets, and the atpack release notes described them as "unqualified" - (I understand that this has something to do with the factory testing process and possibly the vetting process for the safety critical applications these parts are certified for. ). The three official BOD levels are the voltages that the chip is guaranteed (Yup, they use that word in the datasheet!) to work at, within the manufacturer specified temperature range and running at a system clock frequency no higher than specified at that voltage. Nevertheless, the other 5 BOD levels are believed to work as one would expect (I have used them successfully), but Microchip does not provide any guarantee that they'll work, even if all other operating requirements are met, and I do not believe they are tested in production. These "not guaranteed" voltages are still supported by the megaTinyCore BOD dropdown menu, but (as of 2.0.4 - the first version that has the new headers) are marked as "(Unofficial)" in the submenu. Note that the new headers no longer provide the *_gc
enum entries for these BOD level.
| BOD level
0/1-series| BOD level
2-series | Guaranteed speed
Normal temp. range | Guaranteed speed
Elevated temp. range) |-----------|------------------|------------------| | 1.8V | 1.8V | 5 MHz | 4 MHz | | 2.1V | 2.15V | unofficial | unofficial | | 2.6V | 2.6V | 10 MHz | 8 MHz | | 2.9V | 2.95V | unofficial | unofficial | | 3.3V | 3.3V | unofficial | unofficial | | 3.7V | 3.7V | unofficial | unofficial | | 4.0V | 4.0V | unofficial | unofficial | | 4.2V | 4.3V | 20 MHz | 16 MHz |
Normal temperature range is -40-105C on 0/1-series parts and -40-85C on 2-series parts. These parts have a letter N (0/1-series) or U (2-series) at the end of the part number; this is marked on the physical chip as well on 0/1-series, but not on 2-series.
Extended temperature range is -40-125C, and these parts are denoted with the F temperature spec. The extended temperature range column applies when the temperature range is above the normal range and below 125C on F-spec parts. The normal temperature range column still applies to F-spec parts if they are running in the normal temperature range.
Most existing Arduino libraries work. See the Supported Libraries List for a more complete list and discussion of what kinds of libraries might have issues. Of the few libraries that don't work, a handful happened to also be extremely popular and heavily used, such that it was felt necessary to include a compatible version with megaTinyCore. In addition to these, libraries which expose hardware that is only present on the modern AVRs, are also included. These libraries are listed below.
This library supplies two functions to check tuning status of the chip it's running on, and now adds two software reset functions (via WDT or via software reset). It also holds the massive keywords.txt file that highlights register names and core-specific functions.
megaTinyCore helper library docs
The usual NeoPixel (WS2812) libraries, including the popular FastLED as well as AdafruitNeoPixel, have problems on these parts - they depend on hand-tuned assembly, but the execution time of several key instructions has been improved. The improvements enable significant simplification of the code for driving these LEDs. This core includes a compatible version of the tinyNeoPixel library for interfacing with these ubiquitous addressable LEDs. There are two versions, both tightly based on the Adafruit_NeoPixel library. One implements a truly identical API, differing only in name (and obviously the fact that it works on tinyAVR and Dx-Series and megaAVR 0-Series parts at clock speeds from 8 MHz to 48 MHz, instead of on most classic AVRs at 8, 12, and 16 MHz). The other version makes a slight change to the constructor and drops support for changing length at runtime, in order to realize significant flash savings (around 1k). See the tinyNeoPixel documentation and included examples for more information.
The standard EEPROM.h is available here - it works like it does on any AVR. USERSIG.h
(from "User Signature" which the datasheet has sometimes called the USERROW
) it has the same API as EEPROM, though there may be future additions to harmonize with Dx-friendly functions for updating multiple bytes. The Dx-Series parts can only erase the whole USERROW, so potentially each byte written could involve erasing and rewriting it all - the question of how to deal with that is why DxCore doesn't have a USERSIG library yet). The name "USERSIG" refers to the alternate name of the USERROW, the "User Signature" space - the name USERROW could not be used because it is defined by the io headers (it's the struct
of type USERROW_t
, made up of USERROW.USERROW0
through USERROW.USERROW31
. Not the most useful thing, but we never override the io header file definitions unless working around a bug.
Note: Prior to 2.1.0, we tried to get clever with supporting the USERROW
through the EEPROM library; that not only was shortsighted (as it's logically inconsistent on anything with more than 256b of EEPROM), it also introduced some serious bugs. Use the USERSIG.h
library for that instead.
The usual Servo library from library manager is incompatible with these parts (minor changes could make it "work", but with glaring issues and a dependence on the configuration of TCA0). This core provides a version of the Servo library which will select an appropriate timer (TCB0 is the only option on most parts, on parts with a TCB1 (2-Series and 3216, 3217, 1617, 1616 and 1614), TCB1 will be used instead, provided it's not being used for millis()
). Except on parts with a TCB1, Tone cannot be used at the same time as the Servo library. Servo output is better at higher clock speed; when using servos, it is recommended to run at the highest frequency permitted by the operating voltage, to minimize jitter.
Warning If you have installed a version of the Servo library to your /libraries folder (including via library manager), the IDE will use that version of the library (which is not compatible with these parts) instead of the one supplied with megaTinyCore (which est). As a workaround, a duplicate of the Servo library is included with a different name - to use it, just #include
instead of #include
- no other code changes are necessary.
Note that the Servo libraries were only fixed in version 2.2.0 - prior to that we had a Servo library, but it didn't work due to an astonishingly large number of bugs (I swear I tested it - apparently not well enough).
Written by @MCUDude, this provides a more accessible (much more accessible!) wrapper around the optiboot.h library (which was written by the famous @westfw) . This supports writing to the flash of any device using Optiboot, by having the application code call routines in the bootloader to write to the flash. All modern AVRs have built-in flash protection mechanisms that permit only code executing from the bootloader section ( BOOTCODE
, in their terminology) to write to the application section ( APPCODE
). While the hardware does support a third flash section ( APPDATA
) which can be written by code running in APPCODE
this is only usable if there is also a BOOTCODE
section defined (otherwise the entire flash is treated as BOOTCODE
which can never be self-programmed), and would require a separate implementation of this library to use. It would also be possible to get flash-write-from-app without use of an actual bootloader through an analog of the trick used by the DxCore Flash.h for this. Since there appears to be little demand for such a thing, that functionality is not currently implemented (they were implemented on DxCore's flash writing library because the additional effort was virtually nil, and because there was a user with a particular interest in that feature). If someone wants this, and will adapt the library, I can add the entry point to the core and give you little chunks of inline assembly that will call it. Note on terminology: on AVR Dx-Series, the fuses are called BOOTSIZE
and CODESIZE
whereas on 0/1-Series tinyAVRs they're called BOOTEND
and APPEND
. I'm not quite sure how they didn't foresee customer confusion when they called the "APPlication END" that... Regardless of the names they do the same thing, although the granularity on tinyAVRs is finer, as you would expect.
Optiboot_flasher documentation
Warning As noted above, there is a library for DxCore that is also named Flash.h
. Both allow an application to write to the flash using Optiboot if present. That is the only similarity they have . The API, NVM hardware, method used to call the bootloader, and basically everything about these libraries is different . Be sure you write code for the one that matches the hardware you're using. While I (Spence Konde) wrote the DxCore one, I don't have a particularly strong opinion about which way is "right". We made them independently, but not because we each thought the other one's idea of how it should be done was wrong. They largely reflect the way the hardware interacts with its flash. For example, the one for megaTinyCore is page-oriented with its own page buffer, and these parts write in a page-oriented manner, while the DxCore library only cares about pages when erasing - on those parts, the flash is written with word or even byte granularity!
All of these parts have at least a pair of Configurable Custom Logic (CCL) blocks; official Microchip terminology calls them "LUTs" in reference to the LookUp Table (aka truth table). We use the term "logic block" instead, to avoid confusion with other kinds of lookup table (the "lookup table" in a logic block is very different from most lookup tables; containing 8 entries, each of which is a 0 or a 1, it is a single byte, which isn't much of a table), and to prevent users who missed this paragraph from being confused by the terminology. Each block allows you to supply an arbitrary 3-input truth table, as well as configuring additional options like a synchronizer, filter, or edge detector. The CCL operates asynchronously (unless you using the synchronizer) - meaning that things can happen faster than the clock speed. Thesynchronizer that will synchronize the CCL output to one of several clock sources (probably the system clock will be what you would synchronize with). The inputs can come from pins, events, or other peripherals. There's a feedback input as well, which allows a great many exciting possibilities, and a "sequencer" that can act like a latch or flip-flop using the outputs of a pair of logic blocks as its inputs. This is an incredibly powerful peripheral - especially on the 2-Series parts, which have a second pair of logic blocks, as well as the capability to trigger an interrupt when the state of one changes.
The Logic ( #include Logic.h
) library provides a simple wrapper around the CCL hardware in the tinyAVR 0/1/2-Series devices. This library is also included in DxCore and MegaCoreX, covering all AVRs with CCL hardware. Written by @MCUDude.
Logic library documentation
These parts have either 1 (everything else) or 3 (1614, 1616, 1617, 3216, and 3217) on-chip analog comparators which can be used to compare two analog voltages, and, depending on which is larger, do one or more of the following: generate an event output, control an output pin, or fire an interrupt. One of the voltages can be the internal reference (0-Series) or an internal reference scaled by an 8-bit DAC (everything else). This library, written by @MCUDude, provides a simple wrapper around the analog comparator(s) which makes their configuration easier and resulting code more readable (also easier on the wrists - less stuff to type in all caps) than manually configuring registers, while exposing nearly the full featureset of the analog comparators on these parts. Do note does not support the Window Comparator option for the parts with 3 comparators; There doesn't exactly seem to be a lot of demand for that one, though!
The Comparator library ( #include Comparator.h
) is also included in DxCore and MegaCoreX, covering all modern AVRs with comparator hardware. Written by @MCUDude.
Comparator library documentation
In general you should expect the following about library compatibility:
__AVR_ARCH__ >= 102
.architectures=*
would suggest that it would work anywhere - all this means is that there are not separate folders with implementations for different architectures. It does not mean that the library does not make assumptions about architecture, test against architecture specific stuff with #ifdef
s and so on. Unfortunately, library authors often use this when they know it works with a couple of architectures, shrug their shoulders and assume it'll work anywhere and put down a * in that field.The amount of effort required to port a given library will vary widely depending on the library. Some are straightforward for anyone reasonably familiar with these parts and what to generally expect and approach it. Any library associated with some peripheral that both classic and modern had, it's probably going to be a straightforward change if you just need to swap out the classic peripheral for the modern one - Yes, every bitfield will be named differently, but only rarely did a modern AVR's peripheral lack a feature the classic version had. The USART on classic AVR has whack stuff like MPCM, and the 9 bit mode - sorry, modes. Even the layout of some of the registers is similar - the parts aren't as different as they appear at first. Another type is the "bitbanger", where they're using direct port writes; the solution to this is cookbook - switch to using the relevant PORT or VPORT registers. Input capture is a little more complicated because you have to set up the event channel, and figure out how to offer that in a library (that is the hard part). But the consistent factor is that generally, none of these things are long slow painful slogs. And as noted above, many libraries will work out of the box, or have already been adapted.
The fact that many libraries can be ported no or little underlines the need for reports from users about incompatible libraries as well as compatible ones not listed on the table linked below. Usually reports of non-working libraries to add to the table result in the library getting fixed , and the fixed library being added to the table; Almost all of the fruit here low hanging. So when you come upon incompatible libraries report it to me! Many libraries that were initially incompatible were fixed up in under 10 minutes. Porting typical libraries from classic AVRs requires a fraction of the effort that the "tar pit" libraries included with this core take to port to new modern AVR families (these are Comparator, Logic, Event: Logic and Event are both, on their own, large, complicated, "system-like" peripherals. The CCL is just complex in general, and has seen relatively modest changest between families, except for the t0/1. Event is simple in theory and much more complicated in practice, in no small part because the implementation on the 0-series, 1-series, mega0, 2-series/DA/DB/DD, EA and the EB are each different. And a single library has to support all of them with a consistent interface and paper over all the differences.
I know lots of people use libraries that aren't on that list, and I fully expect that there is a great number of libraries that work and are not listed, and I'd love to hear about them. Use the "discussions" or email me, or even submit a PR to add a line to the table. I want to hear about working libraries so others will know they work and not hesitate, and I'm even more interested in ones that don't work so they can be fixed - or determined to be unfixable)
For more information on resetting from software, using the Watchdog Timer, the causes of unexpected resets and how to prevent them, and generally all things reset-related, see the Reset Guide.
It is often useful to identify what options are selected on the menus from within the sketch; this is particularly useful for verifying that you have selected the options you wrote the sketch for when opened later by yourself or someone who you shared it with. Or, you can use such in-sketch identification, combined with preprocessor #if
macros, to select the appropriate code depending on the part or options at hand.
There are a great number of #define
s provided to get information about the hardware in-use, in order to write portable and flexible code in your sketch or, especially, library code.
Note : You cannot distinguish an extended temperature range part from a normal one from software. For 0/1-series, most packages mark the temperature grade. this is no longer true on the 2-series, nor on any part released after the 1-series - So better make sure you mark those parts if you unpack them, because the only alternative is to give the lot number to Microchip support, and they'll tell you if it's an F, a U, or an N (FUN letters - but notice that you can't turn any letter into any other letter without both erasing and adding lines. The same is true of the different set of letters they used on automotive parts - BMZ or something - less FUN, but they had the same "modification resistance" (hey, on at least one occasion, a quantity of t13'd had the markings polished off and were remarked as tiny85's and sold as such on aliexpress and ebay - that was worth doing to some criminal in China! Unethical behavior is of course the norm for companies everywhere, but in the US, criminality of the company (as opposed to rogue employees) is not pervasive. When it rises above that, low end of chinese industry - ex, virtually all PVC wire is 2-8 AWG smaller than what is printed on the wire; same with silicone wire (but FEP insulated wire is always spot on, cause it's not at the low end ya see), one has to assume that (well, if they still marked the parts) someone has taken a bunch of parts marked I (vertical line), added 3 horizontal lines to each one (One imagines, with the same sort of automated chip marking method that would be used for putting any other pattern, except here it would just be the missing parts of an E. The consistency of the location of markings on packages is remarkably consistent specimen to specimen, such that you might be able to target by position and get it close enough to be convincing, and with just 3 small marks and no grinding, and significant price difference between I and E spec parts for certain parts (oddly, not for most tinies). Of course when they adopted the I and E when they stopped marking parts at all, so this is academic. But can you seriously imagine anyone inspecting 200 boards and writing down every lot number he saw, and emailing the list to Microchip and asking for confirmation that they're all E's as he ordered?).
A new version of Optiboot (Optiboot_x) now runs on the tinyAVR 0-Series, 1-Series and 2-Series chips. It's under 512 bytes, and works on all parts supported by this core, allowing for a convenient workflow with the same serial connections used for both uploading code and debugging (like a normal Arduino Pro Mini). Note the exception about not having autoreset unless you disable UPDI (except for the 20 and 24-pin 2-Series parts which can put reset on PB4 instead), which is a bit of a bummer.
To use the serial bootloader, select a board definition with (optiboot) after it. Note - the optiboot suffix might be visually cut off due to the width of the menu; the second / lower set of board definitions in the board menu are the optiboot ones). The 2-Series Optiboot definitions and the 0/1-Series Optiboot definitions are separate entries in the board menu.
See the Optiboot referencefor more information.
These guides cover subsystems of the core in much greater detail (some of it extraneous or excessive).
Covering top-level functions and macros that are non-standard, or are standard but poorly documented, and which aren't covered anywhere else.
The API reference for the analog-related functionality that is included in this core beyond the standard Arduino API.
The API reference for the digital I/O-related functionality that is included in this core, beyond the standard Arduino API, as well as a few digital I/O-related features that exist in the hardware which we provide no wrapper around.
Documents the (largely intended for internal use) dirty inline assembly macros that are used by the core to improve performance or reduce code size.
Includes a list of all interrupt vectors that can be used, how the flags are cleared (not a substitute for the datasheet - just a very quick reminder), which parts each vector exists on, and and what parts of the core, if any, make use of a vector. It also has general guidance and warnings relating to interrupts their handling, including estimates of real-world interrupt response times.
The USARTs (Serial) have some greatly enhanced functionality compared to the stock core.
Serial UPDI is our recommended tool for UPDI programming.
Supported clock sources and considerations for the use thereof.
Manufacturer specs for speed at various voltages, and some discussion of BOD thresholds - this is written largely from a very conservative perspective, in contrast to most of the documentation.
These are provided by the core and can be overridden with code to run in the event of certain conditions, or at certain times in the startup process.
The core feature #define
s are used by megaTinyCore and other cores I maintain as well. This also documents what constant values are defined by the core for version identification, testing for features, and dealing with compatibility problems.
Export compiled binary generates both assembly listings and memory maps, in addition to the hex file. The options selected are encoded in the name of the file to help prevent confusion and make it easy to compare two configurations when you are surprised by the differences between them. Also provides links to a script I wrote to reformate memory maps so you can read the damned things.
The sources of reset, and how to handle reset cause flags to ensure clean resets and proper functioning in adverse events. Must read for production systems
The installation and operation of the Optiboot bootloader (for uploading over straight serial (not SerialUPDI)) is described here. Not recommended except on the 20/24-pin 2-Series (since they have the alt reset pin) or for special use cases that demand it.
This contains detailed information on how the timers are used in megaTinyCore, and some background on their capabilities.
These guides are older; some are still relevant.
This has been recently updated and will likely be turned into a Ref_TCA0.
This document describes how (on the 0 and 1 Series only) the ADC can be taken over and reconfigured, with particular attention to free running mode. The 2-Series ADC is different, and it would require changes to reflect those differences.
A delightful, though unfortunately short, document on bare metal programming in C.
The bible of the AVR instruction set. Like any such tome, it is a lengthy document which contains timeless wisdom from the creator(s), written in obtuse and challenging language and a confusing syntax (though you won't go to hell if you don't read it, if you're writing assembly without it, you might not be able to tell the difference).
As promised, a bunch of additional information was released; Unfortunately it leaves some of the key questions unanswered.
printf()
implementation - The default option can be swapped for a lighter weight version that omits most functionality to save a tiny amount of flash, or for a full implementation (which allows printing floats with it) at the cost of about 1k extra flash. Note that if non-default options are selected, the implementation is always included in the binary, and will take space even if not called. This applies everywhere that format strings are used, including Serial.printf()
.attachPortAEnable()
and replace A
with the letter of the port) before attaching the interrupt. This allows attachInterrupt()
to be used without precluding any use of a manually defined interrupt (which is always much faster to respond). Basically any time you "attach" an interrupt, the performance is much worse.millis()
, micros()
and pulseInLong()
will be available. If set to disable, these will not be available, Serial methods which take a timeout as an argument will not have an accurate timeout (though the actual time will be proportional to the timeout supplied); delay()
will still work. Disabling millis()
and micros()
saves flash, and eliminates the millis()
interrupt every 1-2 ms; this is especially useful on the 8-pin parts which are extremely limited in flash. Depending on the part, options to force millis()
/ micros()
onto specific timers are available. A #error
will be shown upon compile if a specific timer is chosen but that timer does not exist on the part in question (as the 0-Series parts have fewer timers, but run from the same variant). If RTC is selected, micros()
and pulseInLong()
will not be available - only millis()
will be.There are however a few cautions warranted regarding megaTinyCore - either areas where the core is different from official cores, or where the behavior is the same, but not as well known.
If you are manually manipulating registers controlling a peripheral, except as specifically noted in relevant reference pages, the stated behavior of API functions can no longer be assured. It may work like you hope, it may not, and it is not a bug if it does not, and you should not assume that calling said API functions will not adversely impact the rest of your application. For example, if you "take over" TCA0, you should not expect that using analogWrite()
- except on the two pins on the 20/24-pin parts controlled by TCD0 - will work for generating PWM. If you reconfigure TCA0 except as noted in Ref_Timers, without calling takeOverTCA0
, both analogWrite()
and digitalWrite()
on a PWM pin may disrupt your changed configuration.
While we generally make an effort to emulate the official Arduino core, there are a few cases where the decision was made to have different behavior to avoid compromising the overall functionality; the official core is disappointing on many levels. The following is a (hopefully nearly complete) list of these cases.
Earlier versions of megaTinyCore, and possibly very early versions of DxCore enabled the internal pullup resistors on the I2C pins. This is no longer done automatically - they are not strong enough to meet the I2C specifications, and it is preferable for it to fail consistently without external ones than to work under simple conditions with the internal ones, yet fail under more demanding ones (more devices, longer wires, etc). However, as a testing aid, we supply Wire. usePullups()
to turn on the weak internal pullups. If usePullups()
ever fixes anything, you should install external pullups straight away. Our position is that whenever external pullups are not present, I2C is not expected to work. Remember that many modules include their own on-board pullups. For more information, including on the appropriate values for pullups, see the Wire library documentation
The official core for the (similar) megaAVR 0-Series parts, which megaTinyCore was based on, fiddles with the interrupt priority (bet you didn't know that!) in methods that are of dubious wisdoom. megaTinyCore does not do this, saving several hundred bytes of flash in the process, and fixing at least one serious bug which could result in the microcontroller hanging if Serial was used in ways that everyone tells you not to use it, but which frequently work anyway . Writing to Serial when its buffer is full, or calling Serial.flush()
with interrupts disabled, or during another ISR (which you really shouldn't do ) will behave as it does on classic AVRs and simply block, manually calling the transmit handlers, until there is space in the buffer for all of the data waiting to be written or the buffer is empty (for flush()
). On th stock megaAVR core, this could hang forever.
This is deprecated on the official core and is, and always has been, a dreadful misfeature. Dropped as of 2.3.0.
digitalRead()
Does Not Turn Off PWM On official cores, and most third party ones, the digitalRead()
function turns off PWM when called on a pin. This behavior is not documented by the Arduino reference. This interferes with certain optimizations, makes digitalRead()
take at least twice as long (likely much longer) as it needs to and generally makes little sense. Why should a "read" operation change the thing it's called on? We have a function that alters the pin it's called on: digitalWrite()
. There does not seem to be a logically coherent reason for this and, insofar as Arduino is supposed to be an educational platform it makes simple demonstrations of what PWM is non-trivial (imagine setting a pin to output PWM, and then looking at the output by repeatedly reading the pin).
digitalWrite()
and INPUT
Pins Like the official "megaavr" core, calling digitalWrite()
on a pin currently set INPUT
will enable or disable the pullups as appropriate. digitalWrite()
also supports "CHANGE" as an option; on the official core, this will turn the pullup on, regardless of which state the pin was previously in, instead of toggling the state of it. The state of the pullup is now set to match the value that the port output register was just set to.
This was done because of the huge volume of code that makes use of this behavior. We experimented with making pinMode() do the inverse for INPUT and INPUT_PULLUP, but this was removed by unanimous agreement by everyone in the discussion thread.
analogWrite()
and TCD0 Pins Please see the above PWM feature description if using PWM on those pins and also using digitalRead()
or direct port writes on the same pins (PIN_PC0, and PIN_PC1).
On the official "megaavr" board package, TCA0 is configured for "single mode" as a three-channel 16-bit timer (used to output 8-bit PWM). megaTinyCore always configures it for "Split mode" to get additional PWM outputs. See the datasheets for more information on the capabilities of TCA0. See Taking over TCA0 for information on reconfiguring it. One downside to this is that the compare channels do not support buffering, so changing the duty cycle can cause a glitch lasting up to one PWM cycle (generally under 1 ms).
0 is a count, so at 255, there are 256 steps, and 255 of those will generate PWM output - but since Arduino defines 0 as always off and 255 as always on, there are only 254 possible values that it will use. The result of this is that (I don't remember which) either analogWrite(pin,254)
results in it being LOW
2/256's of the time, or analogWrite(pin,1)
results in it being HIGH
2/256's of the temps. On megaTinyCore, with 255 steps, 254 of which generate PWM, the hardware is configured to match the API, and this does not occur. As it happens, 255 also (mathematically) works out such that integer math gets exact results for millis()
timing with both 16-MHz-derived and 20-MHz-derived clock speeds, which is relevant when TCA0 is used for millis()
timing. The same thing is done for TCD0, though to 509, giving 510 steps. analogWrite()
accounts for this, so that we can get the same output frequency while keeping the fastest synchronization prescaler for fastest synchronization between TCD0 and system clock domains.
On the official "megaavr" board package, as well as DxCore, the Type B timers are used to generate 8-bit PWM (one pin per timer). There are very few circumstances where this could increase the number of usable PWM pins. These timers are just too scarce and valuable on these parts. Being minimally useful for PWM, in short supply, and highly desirable for other purposes, support for using Type B timers for PWM was removed in order to save space that would otherwise be used initializing these timers for PWM and handling them in analogWrite()
et . al. If a Type B timer is used for millis()
, it is configured in a radically different way than the official core does it.
They return and expect uint8_t
(byte) values, not enum
s like the official megaavr board package does. Like classic AVR cores, constants like LOW
, HIGH
, etc are simply #define
d to appropriate values. The use of enum
s unfortunately broke many common Arduino programming idioms and existing code (granted, these idioms were poor programming practice - they're also incredibly widespread and convenient), increased flash usage, lowered performance and made optimization more challenging. The enum
implementation made language design purists comfortable and provided error checking for newbies, because you couldn't pass anything that wasn't a PinState to a digital I/O function and would see that error if you accidentally got careless. Nevertheless, due to all the complaints, a compatibility layer was added to the official core, so all the old tricks would work again, it was just less performant. However, that got rid of what was probably the most compelling benefit by allowing the workarounds: the fact that it did generate an error for new users to train them away from common Arduino practices like passing 1 or 0 to digitalWrite()
, if(digitalRead(pin))
and the like. The choice of names of the enum
s also had the perverse effect of making PinMode(pin,OUTPUT)
(an obvious typo of pinMode(pin,OUTPUT)
) into valid syntax (comma operator turns pin,OUTPUT
into OUTPUT
, and it returns a new PinMode
of value OUTPUT
...) and does nothing with it, instead of a syntax error (It took me over an hour to find the erroneous capitalization. That evening, I converted the digital I/O functions to the old signatures and removed the enum
s). Anyway - the enum
s are not present here, and they never will be; this is the case with MegaCoreX and DxCore as well.
There are two classes of significant low level architectural differences (aside from the vastly improved peripherals): the improved instruction set and the unified memory address space.
The classic AVR devices all use the venerable AVRe
(ATtiny) or AVRe+
(ATmega) instruction set ( AVRe+
differs from AVRe
in that it has hardware multiplication and supports devices with more than 64k of flash). Modern AVR devices (with the exception of ones with minuscule flash and memory, such as the ATtiny10, which use the reduced core AVRrc
) all use the latest iteration of the AVR instruction set, AVRxt
. AVRxt
has much in common with AVRxm
(used in XMega parts) in terms of instruction timing - and in the few places where they differ, AVRxt
is faster (SBIC, as well as LDD, and LD with pre-decrement, are all 1 clock slower on AVRxm
vs AVRxt
or AVRe
), however AVRxt
doesn't have the single-instruction-two-clock read-and-write instructions for memory access LAT
, LAC
, LAS
, and XCH
. The difference between subspecies of the AVR instruction set is unimportant for 99.9% of users - but if you happen to be working with hand-tuned assembly (or are using a library that does so, and are wondering why the timing is messed up), the changes are:
As you can see, everything that involves writing to the SRAM is faster now; it would appear that any time it is writing to a location based on one of the pointer registers or the stack pointer, it's a single cycle. All the other improvements except CBI
and SBI
can be viewed as a consequence of that. Of course, the variants of CALL
are faster; they have to put the return address into the stack. I can't say I've ever felt like LAT
, LAC
, or LAS
would be terribly useful as they are described in the instruction set manual - those take a register and the address pointed to by the Z register, load the contents of the specified address and toggle, set or clear in that memory address the bits that were set to begin with in the register. If that worked on special function registers, it would be a very useful instruction, taking PERIPHERAL.REGISTER |= SOME_BIT_bm;
from a 5 clock, non-atomic operation to a 2 clock atomic one! But it says they only work on SRAM... so not as much of a loss. XCH
is more obviously useful than the others, but all 4 of them come with the need to set up the Z register... which in many cases would take long enough that it wouldn't be a notable improvement.
Note that the improvement to PUSH
can make interrupts respond significantly faster (since they have to push the contents of registers onto the stack at the beginning of the ISR), though the corresponding POP
s at the end aren't any faster. The change with ST
impacted tinyNeoPixel. Prior to my realizing this, the library worked on SK6812 LEDs (which happened to be what I tested with) at 16/20 MHz, but not real WS2812's. However, once I discovered this, I was able to leverage it to use a single tinyNeoPixel library instead of a different one for each port like was needed with ATTinyCore (for 8 MHz, they need to use the single cycle OUT
on classic AVRs to meet timing requirements, the two cycle ST
was just too slow; hence the port had to be known at compile time, or there must be one copy of the routine for each port, an extravagance that the ATtiny parts cannot afford. But with single cycle ST
, that issue vanished).
Oh, and one other instruction it doesn't have that (some) AVRxm parts have: The hardware DES
encryption instruction - an instruction which is most effective at marking AVRxm as, ah, back from the time when DES
was a big deal.
On all modern AVRs with up to 48k of flash, both the flash and ram reside in the same address space - On tinyAVRs, the program memory starts at 0x8000, while on megaAVR 0-Series, it starts at 0x4000 to leave room for the 48k of flash that they can have, and on the Dx-Series parts with up to 32k of flash, they have the same layout as the tinyAVRs, while Dx-Series parts with 64k or 128k of flash have a 32k section of flash mapped at any given time (how to make sure variables go into this memory mapped flash has been described elsewhere in this document). There is another big and fundamental change to the layout of the address space as well: the registers are organized by peripheral. PORTA is assigned 0x400 to 0x41F. PORTB is the next 32 bytes, and so on - and the address space is far sparser - all the peripherals have multiple "reserved" registers that may or may not get functions added in the future. And each instance of a peripheral on a part that has multiple of them has the same layout. You can, say, pass a pointer to a TCB around without the functions that get it knowing which TCB they'll get, and then access the TCB registers through it. On classic AVRs the names of the registers were consistent, but their locations were all over the place, packed much more tightly, so that sort of trick isn't possible. This also means that the EEPROM (and USERROW) are part of this unified address space (on classic AVRs, reading was accomplished through special function registers, and was far more awkward).
The lowest 64 registers are special - you can read or write them with the IN
or OUT
instructions (hence, "I/O space") in a single clock cycle, without setting up a pointer to them as you would need to with ST
or LD
. The 32 "Low I/O registers" additionally have bit-level access instructions CBI
and SBI
to clear and set bits, and SBIC
/ SBIS
to skip the next instruction if a certain bit is set or cleared. On all AVRxt parts released so far, the low I/O registers are used only for the VPORTs, up to VPORTG or the last port on the part, whichever comes first. This means VPORTG.OUT |= 1 << n
, where n is known at compile-time and constant , is a 1 clock cycle atomic operation , while VPORTG.OUT = 1 << n
(note the =
in lieu of |=
) takes two clock cycles. For the latter, the first cycle is to put the value to be stored into a register, and the second is to write it with an OUT
instruction. The GPIOR0-3 registers occupying the last 4 bytes in the low I/O space (those are user-defined registers to use as you choose. We use GPIOR0 internally during startup to record reset cause, and store two types of warnings applicable to tuning ). The reset flag register is always cleared very early in startup to prevent dirty resets, and when using a bootloader, so that it can honor bootloader entry conditions on next reset). No other part of this core touches those registers, and we only set GPIOR0; we never read it. So all can be used freely, as long as you remember that GPIOR0 is not empty when you enter setup, and contains the reset cause flags. Other Low I/O registers are not used by the hardware.
The 32 "high I/O registers" are used even less - they only contain the the stack pointer, RAMPZ
on the 128k DA/DB parts, SREG
, and CCP
(Configuration Change Protection - where _PROTECTED_WRITE()
does it's magic to let you write to protected registers. That's all - 5 out of 32 registers are used, the rest are "reserved". On classic AVRs, registers for assorted peripherals that the designers thought would be accessed often were put into the I/O space, so it was a disappointment that they didn't put an alias of any other registers there. I'd vote for the intflags registers to be aliased there
megaTinyCore itself is released under the LGPL 2.1. It may be used, modified, and distributed freely, and it may be used as part of an application which, itself, is not open source (though any modifications to these libraries must be released under the LGPL as well). Unlike LGPLv3, if this is used in a commercial product, you are not required to provide means for users to update it.
The DxCore hardware package (and by extension this repository) contains DxCore as well as libraries, bootloaders, and tools. These are released under the same license, unless specified otherwise . For example, tinyNeoPixel and tinyNeoPixel_Static, being based on Adafruit's library, are released under GPLv3, as described in the LICENSE.md in those subfolders and within the body of the library files themselves.
The pyupdi-style serial uploader in megaavr/tools is a substantially renovated version of pymcuprog from Microchip, which is not open source has now been released under the open source MIT license! .
Any third party tools or libraries installed on behalf of megaTinyCoreCore when installed via board manager (including but not limited to, for example, avr-gcc and avrdude) are covered by different licenses as described in their respective license files.