Universal Interfaces

Die neuen Atxmega-Controller besitzen eine Vielzahl an Hardwarefunktionen und -Komponenten.

Im Gegensatz zu den „älteren“ Attiny- und Atmega-Controllern, wurde die Konfigurationsstruktur („Defines“) von Atmel grundlegend überarbeitet. Beim Atxmega sind alle Register gleichbleibend und sauber durch entsprechende Namensräume getrennt und nutzen alle dieselbe Art und Weise der Bennennung von z.B. Bitnamen, Bitgruppen und Konfigurationsregistern.

Hiermit lassen sich diese vom Hersteller vorbelegten „Defines“ sauber in Gruppen unterteilen und sind entsprechend übersichtlicher. In der Luna-IDE wurde die Defines-Übersicht auch um eine entsprechende Gruppenansicht erweitert (siehe Bild).

Im Defines-Browser/Editor Ist bei Atxmega-Controllern eine hirarchische Übersicht vorhanden. Diese Übersicht enthält sämtliche für den ausgewählten Controller verfügbaren Hardware-Module, Register, Bitfelder und Konfigurationskonstanten.

Ein Klick auf ein Element zeigt automatisch im unteren Bereich ein Syntaxbeispiel zur Verwendung im Luna-Quelltext an. Ein Doppelklick auf ein Element fügt es in den Quelltext an der aktuellen Cursorposition, inklusive Kommentar mit einer Kurzbeschreibung ein.

Das Universalinterface stellt eine vereinfachte Möglichkeit zur direkten Konfiguration der Atxmega-Komponenten bereit. Dies bedeutet, dass sämtliche Gruppennamen die eine Hardwarekomponente darstellen, im Sourcecode mit der üblichen Punktnotation angesprochen werden können.

Grundsätzlich unterscheidet sich dies nur geringfügig von der Konfiguration über die Avr-Klasse mittels Avr.<Registername>.<Registerbit>, nur mit dem Unterschied, dass:

  • weniger Schreibarbeit notwendig ist,
  • Zugriffe auf Bits und Bitgruppen automatisch erfolgen,
  • Zugriffe auf Register automatisch mit dem richtigen Datentyp erfolgen und
  • in der IDE das Autovervollständigen für das verwendete Register vorsortiert ist.

Gleichnamige Luna-Interfaces, beispielsweise bei USARTC0 sind kombiniert. D.h. beide Varianten der Verwendung sind möglich. Die verfügbaren Funktionen sind Luna-Interface-Erweiterungen, die auf diese Komponente angewendet werden können (z.B. „usartc0.ReadByte“ u.A.).

Das Ansprechen einer Komponente erfolgt durch:

Komponente.Register[.Bit/Bitgruppe] bzw.
Komponente.Vektor

Hierbei sind lesende und auch schreibende Zugriffe möglich. Inwieweit das bei jeder einzelnen Komponente Sinn ergibt, verrät das Datenblatt des Controllers.

  • Komponentenname ist der Name der Komponente die angesprochen werden soll, beispielsweise RTC
  • Register ist das Register der Komponente das angesprochen werden soll, beispielsweise CTRL. Die führende Angabe des Komponentennamens, z.B. „RTC_“ (siehe Bild), wird weggelassen. Der Compiler weiß anhand der Definition wie groß die Datenbreite des Registers ist (siehe Bild, Spalte „Größe“). Das Lesen oder Schreiben erfolgt also automatisch in der vom Hersteller definierten Datenbreite.
  • Bit/Bitgruppe (optional) ist das Bit oder die Bitgruppe die im Register angesprochen werden soll. Die führende Angabe des Komponentennamens, z.B. „RTC_“ (siehe Bild), wird weggelassen. Der Zugriff auf ein einzelnes Bit erfolgt boolean (0 oder 1), einer Bitgruppe kann ein entsprechender Wert zugewiesen werden, je nach Anzahl der Bits in der Gruppe. Der Compiler liest oder setzt den Wert korrekt vom Register, ohne das umliegende Bits verändert werden. Die verfügbaren Bits die ansprechbar sind, sind alle mit der Endung _BP, Gruppen mit der Endung _GM in der Definesübersicht zu finden. Aus dem Datenblatt des Atxmega können die Namen 1:1 übernommen werden.
  • Vektor ist ein Interruptvektor der Komponente, dem man einen Namen einer Interrupt-Serviceroutine zuweisen kann (nur Zuweisung möglich).

Der Zugriff auf das einzelne Bit SYNCBUSY im Register STATUS der Komponente RTC wäre:

bit = RTC.STATUS.SYNCBUSY  //lesend
RTC.STATUS.SYNCBUSY = bit  //schreibend (macht bei diesem Bit keinen Sinn, nur als Beispiel)

Der Zugriff auf die Bitgruppe PRESCALER (3 Bits) im Register CTRL der Komponente RTC wäre:

value = RTC.CTRL.PRESCALER  //lesend
RTC.CTRL.PRESCALER = value  //schreibend

Das Register kann auch ohne Zuweisung direkt konfiguriert werden, das Auto-Vervollständigen bietet alle zugehörigen und möglichen Konfigurationen auch hier an:

RTC.CTRL.PRESCALER.DIV1024  //Konfiguration setzen
'Dasselbe per Schreibzugriff wäre:
RTC.CTRL.PRESCALER = RTC_PRESCALER_DIV1024_gc

Der Zugriff auf das gesamte Register PER (hier: word) der Komponente RTC wäre:

value = RTC.PER  //lesend
RTC.PER = value  //schreibend

Dem Interruptvektor OVF_VECT der Komponente RTC eine Interruptfunktion zuweisen wäre:

RTC.OVF_VECT = name
 
isr name
 ..
endisr