Hallo,
ich habe mir gerade folgendes Beispiel zum Atmel SAM D10 angeschaut:
1
#include"sam.h"
2
3
intmain(void)
4
{
5
SystemInit();
6
7
PORT->Group[0].DIRSET.reg=PORT_PA09;
8
9
while(1)
10
{
11
if(PORT->Group[0].IN.reg&PORT_PA25;
12
{
13
PORT->Group[0].OUTSET.reg=PORT_PA09;
14
}
15
else
16
{
17
PORT->Group[0].OUTCLR.reg=PORT_PA09;
18
}
19
}
20
}
Was ich hier nicht verstehe, ist das setzen der Ausgangsregister(PA09)
sowie das auslesen des Tasters (PA25). Was bedeutet dieses "Group[0]"?
Gibt es noch eine andere Schreibweise?
Gruß
Felix
Felix L. schrieb:> Was bedeutet dieses "Group[0]"?
Der PIO-Modul der neuen SAMs hat nur noch eine Instanz, und die
einzelnen Ports (A, B, C) sind dann in dieser Gruppe vertreten.
> Gibt es noch eine andere Schreibweise?
Zuweilen habe ich schon sowas im Code gesehen:
Felix L. schrieb:> Also bleibt es mir überlassen, ob ich Group[1],[2],[...] verwende?
Mit den Standard-Headerdateien hast du keine andere Wahl, als sie zu
verwenden. ;-)
Die gezeigten Definitionen für PORTA etc. müsstest du dir selbst
irgendwo hinlegen.
p.s.: Natürlich fängt die Zählung bei 0 an, also PORT A ist
PORT->Group[0] (du hast bei 1 angefangen).
Ich habe vorhin mal damit auf meinem SAMD20 Board gespielt, einfach nur
mal um direkten Register-Zugriff zu testen.
Und spielt soweit, also nicht das Beispiel, sondern blinken lassen der
LED auf dem SAMD20 xplained.
Nun mal eine Frage, woher kommt so ein Konstrukt wie
"PORT->Group[0].DIRSET.reg" - ist das CMSIS?
Oder ist das was eigenes von Atmel?
Ist das auch irgendwo dokumentiert?
Zumindest im Datenblatt vom SAMD20 taucht sowas wie "port->group" oder
"port->" überhaupt nicht auf.
Wenn man nach dem Datenblatt geht und das so machen würde wie bei den
AVRs dann müsste das Register einfach nur DIRSET heissen.
Also "DIRSET = 0x00000000" oder so sollte nach Datenblatt funktionieren
- was es aber natürlich nicht tut.
Und es gibt davon ja auch noch mehrere.
Wie soll man auf sowas kommen wenn das nichtmal im Datenblatt steht?
Rudolph schrieb:> Felix L. schrieb:>> Atmel hat vor einigen Tagen Tutorials in YouTube hochgeladen:>> Das hilft, YouTube ist bei mir auf der Arbeit gesperrt. :-)
Das ist dann natürlich schlecht. Ich finde Atmel macht gute Dev Boards
und viel Werbung aber Informationen zur Programmierung (von SAM) findet
man so gut wie gar nicht. Oder kennt jemand ein Tutorial?
Gruß
Nachtrag:
Habe hier ein PDF Dokument gefunden indem die Funktionen des D20 sowie
Codebeispiele gezeigt werden:
http://www.atmel.com/images/atmel-42139-asf-manual-sam-d20_application-note_at03665.pdf
Rudolph schrieb:> Nun mal eine Frage, woher kommt so ein Konstrukt wie> "PORT->Group[0].DIRSET.reg" - ist das CMSIS?
Nö, die Peripherals (bis auf ein paar zentrale Dinge wie NVIC, SysTick
und so) werden von ARM nicht koordiniert. Da kocht jeder Hersteller
sein eigenes Süppchen. Auf den älteren Atmel-ARMs sahen die ja auch
noch anders aus (aber meiner Meinung nach viel angestaubter).
> Wenn man nach dem Datenblatt geht und das so machen würde wie bei den> AVRs dann müsste das Register einfach nur DIRSET heissen.
Nein, selbst bei Xmega gab es da schon immer den Namen des Moduls
und die Instanznummer davor. Die Register im Datenblatt beschreiben
dann nur noch den Offset innerhalb der Instanz. Beispiel:
1
/* PF3 is output for VLCD charge pump (PWM on OC0D) */
2
PORTF.DIRSET=_BV(3);
3
TCF0.CTRLA=TC_CLKSEL_DIV1_gc;/* TCF0 @ 16 MHz */
4
TCF0.CTRLB=TC0_CCDEN_bm|TC_WGMODE_SS_gc;
5
TCF0.PER=256;/* 62.5 kHz PWM frequency */
6
TCF0.CCD=4;/* -> VLCD abt. -1.3 V */
Allerdings heißt PORTF eben dort noch PORTF und nicht PORT->Group[5].
> Wie soll man auf sowas kommen wenn das nichtmal im Datenblatt steht?
Steht schon, aber bei den Ports zugegebenermaßen ziemlich
verklausuliert:
1
The I/O pins are organized in groups with up to 32 pins. Group 0 consists
2
of the PA pins, group 1 the PB pins, etc. Each group has its own set of
3
registers. For example, the register address offset for the Data Direction
4
(DIR) register for group 0 (PA00 to PA31) is 0x00, while the register
5
address offset for the DIR register for group 1 (PB00 to PB31) is 0x80.
Verwunderlich ist eigentlich nur das System PORT->Group, während bei
allen anderen Peripherals (auch im SAMDxx) die Instanzen jeweils eine
eigene Basisadresse bilden, also TC0->xxx oder SERCOM5->xxx.
Es gibt auch unterhalb von PORT nichts außer den Gruppen selbst, aber
es gibt eben nur eine einzige Instanz von PORT.
Wie ich schon schrieb, wenn es dir logischer erscheint, dann verziere
deine Projekte global mit sowas:
1
#define PORTA PORT->Group[0]
2
#define PORTB PORT->Group[1]
3
#define PORTB PORT->Group[2]
und benutze PORT.DIRSET etc. Dann hast du so ziemlich das gleiche,
wie es bspw. auch bei den Xmegas war.
Neu ist für jedes Register die Union, die einerseits einen direkten
Zugriff auf alle Bits gestattet (über .reg), andererseits einzelne
Bits registersicher per Namen ansprechen lässt (.bit.xxx). Für
die Parallelports ist das egal, aber für die Registerbits in den
diversen Steuerregistern ist es ein Segen, weil man jetzt einen
Compilerfehler bekommt, wenn man versucht, ein namentlich benanntes
Bit in einem falschen Register zu behandeln. Das hatten wir beim
ATmega128RFA1 auch versucht einzuführen, aber hatte sich damals nicht
ernsthaft durchgesetzt (und beim ATmega256RFR2 wurde das Feature
in der Atmel-eigenen Toolchain demoliert, obwohl es in der avr-libc
noch drin ist).
Jörg Wunsch schrieb:>> Wenn man nach dem Datenblatt geht und das so machen würde wie bei den>> AVRs dann müsste das Register einfach nur DIRSET heissen.>> Nein, selbst bei Xmega gab es da schon immer den Namen des Moduls> und die Instanznummer davor.
Die XMega habe ich mir nie ernsthaft angesehen weil es da bis heute
keinen mit CAN gibt.
Ist das im Datenblatt der XMega wenigstens beschrieben wie man den
Register-Zugriff machen soll?
> Allerdings heißt PORTF eben dort noch PORTF und nicht PORT->Group[5].>>> Wie soll man auf sowas kommen wenn das nichtmal im Datenblatt steht?>> Steht schon, aber bei den Ports zugegebenermaßen ziemlich> verklausuliert:
Das nützt ja garnichts, was fehlt ist jeder Hinweis auf die zu
benutzende Syntax.
Ein paar einsame Zeilen Code-Beispiele ich C würden das Datenblatt nicht
schlechter machen.
Auf der Embedded World habe ich am Atmel Stand jemanden dazu
angesprochen wie man denn mit dem SAMD20 Register-Zugriffe machen soll.
Der war ziemlich überrascht und hat mir das kurz gezeigt, Dokumentation
konnte er aber auch keine aus dem Hut ziehen.
Und Beispiel-Programme für das SAMD20 Xplained hatte ich nur mit dem AFS
gesehen - die Arduino-Abstraktion finde ich aber grausam.
Rudolph schrieb:> Das nützt ja garnichts, was fehlt ist jeder Hinweis auf die zu> benutzende Syntax.
Die Syntax ist C.
Die obigen Strukturen und Konstanten sind in den Headerfiles deklariert
(wirf da mal einen Blick rein, dann wird vieles klarer), die eigentliche
Funktion der Register, also welche Bits du wo setzen musst um was zu
bewirken findest Du alles im Datenblatt bzw. Reference manual.
Sobald Du das System einmal durchschaut hast hilft auch schon das
Autocomplete Deiner IDE die genauen Namen der Register zu finden und die
Namen der benötigten Bitmasken auch wenn Du als Ausgangspunkt nur die
Bezeichnungen aus dem Datenblatt hast.
Rudolph schrieb:> Ist das im Datenblatt der XMega wenigstens beschrieben wie man den> Register-Zugriff machen soll?
Nö, allerdings gab's da wohl noch eine Appnote "Getting started
writing C code".
> Ein paar einsame Zeilen Code-Beispiele ich C würden das Datenblatt nicht> schlechter machen.
Ja.
> Und Beispiel-Programme für das SAMD20 Xplained hatte ich nur mit dem AFS> gesehen - die Arduino-Abstraktion finde ich aber grausam.
Wenn's denn wenigstens eine Abstraktion wäre, die genauso gut wie
Arduino ist. Kannste aber vergessen, dass du vielleicht einen SAM3S
(für das es gerade mal ein Beispiel gab) schnell durch einen SAM4E
ersetzen kannst – so weit geht die Abstraktion nicht.
Was übrig bleibt bei ASF ist ein nutzlos aufgeblähtes API, bei dem
man zum Setzen eines Bits in einem Register einen kompletten
Funktionsaufruf verplempert, aber dennoch keine weitere Erläuterung,
welche Bits man denn für einen bestimmten Zweck nun setzen muss.
Diese Art von „Abstraktion“ ist bestimmt nicht das, was der Welt noch
gefehlt hätte … ganz davon abgesehen, dass der Salat sowieso bloß unter
Windows zu haben ist.
Bernd K. schrieb:> Die obigen Strukturen und Konstanten sind in den Headerfiles deklariert> (wirf da mal einen Blick rein, dann wird vieles klarer), die eigentliche> Funktion der Register, also welche Bits du wo setzen musst um was zu> bewirken findest Du alles im Datenblatt bzw. Reference manual.
Ja nee, eben nicht.
Was fehlt ist jeglicher Hinweis, dass man sich das
zu "PORT->Group[0].DIRSET.reg" zusammen puzzeln soll wenn man das nur
als DIRSET im Datenblatt beschriebene Register von PORTA beschreiben
möchte.
Es ist völlig egal wie einfach und offensichtlich das ist wenn man das
erstmal verstanden hat, wenn es keine Grundlage gibt auf der man das
verstehen kann.
Rudolph schrieb:> Es ist völlig egal wie einfach und offensichtlich das ist wenn man das> erstmal verstanden hat, wenn es keine Grundlage gibt auf der man das> verstehen kann.
Dann schau doch mal in die header files, oder stochere einfach mal mit
dem Autocomplete drin rum, da siehst du doch dann wie es aufgebaut ist,
das Datenblatt legst Du daneben und vergleichst, solange bis Du den
Zusammenhang und die Logik hinter den Strukturen siehst.
Bernd K. schrieb:> Dann schau doch mal in die header files, oder stochere einfach mal mit> dem Autocomplete drin rum, da siehst du doch dann wie es aufgebaut ist
Kann man machen, aber wie ich oben schon schrieb, die Philosophie
mit den "Gruppen" unterhalb von PORT ist nun nicht wirklich allzu
offensichtlich, und sie entspricht auch nicht so recht dem, wie der
Rest dieser Controller aufgebaut ist. Man hätte da eher sowas wie
PORT0->DIRSET erwartet.
Selbst bei der derzeitigen Implementierung hätte es wohl deutlich
weniger Verwunderung bewirkt, wenn Atmel die #defines für PORTA,
PORTB etc. gleich mitgeliefert hätte, denn im Rest des Datenblatts
werden die Portpins eben auch als PB25 bezeichnet, und nicht etwa als
PORT[1].25 oder sowas.
Aber wenn man das einmal weiß, und sich das Wissen durchs Netz
hinreichend breitstreut, ist es am Ende auch kein großes Thema mehr.
Im Moment sind diese Teile einfach noch ziemlich neu „in freier
Wildbahn“.
Jörg Wunsch schrieb:> ganz davon abgesehen, dass der Salat sowieso bloß unter Windows zu.> haben ist.
Noe, die Atmel-Toolchain gibt es direkt fuer Linux x86_64 bei Atmel als
Download, incl. dem ganzen cmsis-zeug, compiler pipapo als archiv.
Runterladen, entpacken, fertig.
Oder meinst du was anderes?
Kaj schrieb:> Jörg Wunsch schrieb:>> ganz davon abgesehen, dass der Salat sowieso bloß unter Windows zu.>> haben ist.> Noe, die Atmel-Toolchain gibt es direkt fuer Linux x86_64 bei Atmel als> Download, incl. dem ganzen cmsis-zeug, compiler pipapo als archiv.
Wo eigentlich? Ich habe da immer nur eine für den AVR gefunden,
keine für ARM.
> Oder meinst du was anderes?
Ich meinte das ASF. Aber ok, das scheint es auch so zum Download zu
geben, ohne das Studio-Gedöns.
Jörg Wunsch schrieb:> Kaj schrieb:>> Jörg Wunsch schrieb:>>> ganz davon abgesehen, dass der Salat sowieso bloß unter Windows zu.>>> haben ist.>> Noe, die Atmel-Toolchain gibt es direkt fuer Linux x86_64 bei Atmel als>> Download, incl. dem ganzen cmsis-zeug, compiler pipapo als archiv.>> Wo eigentlich? Ich habe da immer nur eine für den AVR gefunden,> keine für ARM.http://distribute.atmel.no/tools/opensource/Atmel-ARM-GNU-Toolchain/4.8.4
Diese Info findet man versteckt in einem PDF von Atmel, habs mal
angehangen :) Seite 4, Abschnitt 2.2
Funktioniert bei mir unter Arch Linux einwandfrei :)
Danke, dann habe ich zumindest mal eine „offizielle“ Toolchain zum
Vergleich, auch wenn es natürlich ansonsten die generische völlig für
meinen Zweck tut. (Wirklich ernsthafte Patches haben sie ja auch
nicht drin, anders als bei der AVR-Toolchain.)
Hallo,
ich würde gerne einen Artikel anlegen in dem es um das konfigurieren des
Atmel Studios geht sowie die Programmierung von SAM D20/D21. Es soll
besonders für die Umsteiger von AVR auf ARM sein, die sich vom Atmel
Studio nicht trennen können (manchen mögen es andere nicht). Es soll wie
ein Tutorial aufgebaut sein, also von Grund auf. Ich würde mich über
Unterstützung freuen da ich sehr wenig Erfahrung mit den SAM habe.
Gruß
Hallo,
beschäftige mich ebenfalls mit dem SAM D10D14AM und habe Probleme bei
der Programmierung.
Ich möchte als Übung nur die interne LED zum blinken bekommen und suche
nun den richtigen BEfehl für die Delay-Time. Bei dem ATMEga hat ja
delay_ms ausgereicht, jedoch wird er bei diesem COntroller nicht
anerkannt. Kann mir jemand weiterhelfen.
Ich nutze die #include "sam.h" Datei.
MfG
CHristian
Naja, die _delay_us/_delay_ms-Routinen sind doch weiter nichts als
(in Inline-Assembler) gehackte Zählschleifen.
Du kannst genauso gut auf einem ARM eine Zählschleife bauen, zumal
diese Cortex-M0+ keinen Cache haben, die Ausführungszeit also recht
gut vorhersagbar ist.
Wenn ich das hier:
1
voiddelay(intcount){
2
registervolatileintc=count;
3
while(--c>0){/* delay */}
4
}
compiliere (arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Os -S
delay.c), bekomme ich
1
.thumb_func
2
.type delay, %function
3
delay:
4
sub sp, sp, #8
5
str r0, [sp, #4]
6
.L3:
7
ldr r3, [sp, #4]
8
sub r3, r3, #1
9
str r3, [sp, #4]
10
cmp r3, #0
11
bgt .L3
12
add sp, sp, #8
13
@ sp needed
14
bx lr
Du müsstest mithin mal zählen, wie lange die drei Befehle von LDR
bis BGT dauern, dann hast du die Zeit für einen Durchlauf.
Dass man natürlich in der Praxis einen Timer benutzen wird, dürfte
selbstverständlich sein …
Hallo an alle,
ich habe jetzt die Atmegas, Xmegas (ohne ASF, anfangs gab es ja noch
einzelne Treiber ohne gleich das ganze ASF verwenden zu müssen) und
einge alte Infineon Controller hinter mir. In den nächsten Wochen will
ich mich in die SAM4 einarbeiten.
Nutzt ihr die SAM4 nur mit dem ASF oder soll man das lieber ohne machen?
Mein erster Eindruck...
- Durch die ganze Flexibilität des ASF für die verschiednen Controller,
scheint es teilweise sehr ineffizient zu sein.
- Sehr unübersichtlich
- Will ich die Hardwaremodule wirklich gut ausnutzen, muss ich sicher
wieder vieles selber initialisieren, da einige Funktionen nicht alle
Konfigurationen zulassen. Diese Erfahrung habe ich bei den Xmegas
gemacht, weshalb ich dann doch nicht das ASF zur programmierung
verwendet habe.
+ fertige treiber für USB und Co
Was empfehlt ihr?
Martin J. schrieb:> Welcher SAM ist mir eigentlich egal.
Trotzdem kaperst du einen fremden Thread. Das ist unhöflich. Auch
wenn sich der TE nicht mehr gemeldet hat bislang, könnte es ja sein,
dass er nach ein wenig Bedenkzeit sein Thema doch noch gern
weiterführen möchte.