Forum: Mikrocontroller und Digitale Elektronik SAMD21 Xplained pro / Eingänge lesen


von U.G. L. (dlchnr)


Angehängte Dateien:

Lesenswert?

Hallo,
hat jemand von Euch schon Erfahrungen mit den GPIOs eines Atmel SAMD21 
sammeln können?
Ich habe ein seltsames Problem. Ich lese, wenn ich die für 
Datenleitungen (D7..D0) vorgesehenen Port Pins am EXT2-Header auf 
PULL_UP konfiguriere, den Wert 0xFF ein, konfiguriere ich auf PULL_DOWN 
lese ich entsprechen 0x00.
Ich kann auch den oberen Nibble auf PULL_UP, den unteren Nibble auf 
PULL_DOWN konfigurieren, so dass ich 0xF0 lese - wenn ich dann aber D7 
mit GND verbinde oder D0 mit VCC (dass läßt sich einfach mittels Jumper 
machen), lese ich nicht etwa 0x70 oder 0xF1, sondern nach wie vor 
0xF0!!!
Hat jemand eine Idee, was ich da falsch mache?
1
// Initialisierung
2
  // D7 ==> PIN_PA11
3
  // D6 ==> PIN_PA21
4
  // D5 ==> PIN_PB13
5
  // D4 ==> PIN_PB15
6
  // D3 ==> PIN_PA09
7
  // D2 ==> PIN_PB10
8
  // D1 ==> PIN_PA18
9
  // D0 ==> PIN_PA19
10
  // CK ==> PIN_PA10
11
  // /R ==> PIN_PA20
12
  // /E ==> PIN_PA16
13
  system_pinmux_get_config_defaults(&pinmux);
14
  pinmux.direction    = SYSTEM_PINMUX_PIN_DIR_INPUT;
15
  //pinmux.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
16
  pinmux.mux_position = SYSTEM_PINMUX_GPIO;
17
  pinmux.input_pull   = SYSTEM_PINMUX_PIN_PULL_UP;
18
  system_pinmux_pin_set_config(PIN_PA11, &pinmux);  // D7
19
  system_pinmux_pin_set_config(PIN_PA21, &pinmux);  // D6
20
  system_pinmux_pin_set_config(PIN_PB13, &pinmux);  // D5
21
  system_pinmux_pin_set_config(PIN_PB15, &pinmux);  // D4
22
  pinmux.input_pull   = SYSTEM_PINMUX_PIN_PULL_DOWN;
23
  system_pinmux_pin_set_config(PIN_PA09, &pinmux);  // D3
24
  system_pinmux_pin_set_config(PIN_PB10, &pinmux);  // D2
25
  system_pinmux_pin_set_config(PIN_PA18, &pinmux);  // D1
26
  system_pinmux_pin_set_config(PIN_PA19, &pinmux);  // D0
27
  pinmux.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
28
  system_pinmux_pin_set_config(PIN_PA10, &pinmux);  // CK
29
  system_pinmux_pin_set_config(PIN_PA20, &pinmux);  // /R
30
  system_pinmux_pin_set_config(PIN_PA16, &pinmux);  // /E
31
  port_pin_set_output_level(PIN_PA10, 1);  // CK
32
  port_pin_set_output_level(PIN_PA20, 1);  // /R
33
  port_pin_set_output_level(PIN_PA16, 1);  // /E
34
35
//Einlesen
36
      //Test with SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK
37
      //port_pin_set_output_level(PIN_PA11, (p->addr & 0x80) ? 1 : 0);
38
      //port_pin_set_output_level(PIN_PA21, (p->addr & 0x40) ? 1 : 0);
39
      //port_pin_set_output_level(PIN_PB13, (p->addr & 0x20) ? 1 : 0);
40
      //port_pin_set_output_level(PIN_PB15, (p->addr & 0x10) ? 1 : 0);
41
      //port_pin_set_output_level(PIN_PA09, (p->addr & 0x08) ? 1 : 0);
42
      //port_pin_set_output_level(PIN_PB10, (p->addr & 0x04) ? 1 : 0);
43
      //port_pin_set_output_level(PIN_PA18, (p->addr & 0x02) ? 1 : 0);
44
      //port_pin_set_output_level(PIN_PA19, (p->addr & 0x01) ? 1 : 0);
45
    data  = port_pin_get_output_level(PIN_PA11) ? 0x80 : 0x00;
46
    data |= port_pin_get_output_level(PIN_PA21) ? 0x40 : 0x00;
47
    data |= port_pin_get_output_level(PIN_PB13) ? 0x20 : 0x00;
48
    data |= port_pin_get_output_level(PIN_PB15) ? 0x10 : 0x00;
49
    data |= port_pin_get_output_level(PIN_PA09) ? 0x08 : 0x00;
50
    data |= port_pin_get_output_level(PIN_PB10) ? 0x04 : 0x00;
51
    data |= port_pin_get_output_level(PIN_PA18) ? 0x02 : 0x00;
52
    data |= port_pin_get_output_level(PIN_PA19) ? 0x01 : 0x00;

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

So, hab' mir jetzt mal so ein SAMD21 XplainedPro an Land gezogen,
wollte demnächst sowieso mal was mit einem SAMD20 selbst machen.

Das ganze ASF-Geraffel ist mir suspekt.  Eine Funktion, die ein Bit
in einem Steuerregister setzt oder löscht, brauch ich nicht, ich kann
mit dem |= und &=-Operator ganz gut umgehen. ;-)

Ich habe daher mal eine Minimal-App gezimmert, die je nachdem, ob man
einen Jumper bei PA16 oder PA19 reinsteckt, die LED0 an- oder
ausschaltet.  Funktioniert.
1
#include "sam.h"
2
3
void _init(void)
4
{
5
}
6
7
int
8
main(void)
9
{
10
  // unusable, since PORT is a macro
11
  // PM->APBBMASK.bit.PORT = 1;
12
  PM->APBBMASK.reg = 8;
13
14
  /* PA19: input with pulldown */
15
  PORT->Group[0].PINCFG[19].bit.INEN = 1;
16
  PORT->Group[0].PINCFG[19].bit.PULLEN = 1;
17
  PORT->Group[0].OUTCLR.bit.OUTCLR = (1 << 19);
18
19
  /* PA16: input with pullup */
20
  PORT->Group[0].PINCFG[16].bit.INEN = 1;
21
  PORT->Group[0].PINCFG[16].bit.PULLEN = 1;
22
  PORT->Group[0].OUTSET.bit.OUTSET = (1 << 16);
23
24
  /* LED0 on XPlainedPro: PB30, active low */
25
  PORT->Group[1].DIRSET.bit.DIRSET = (1 << 30);
26
  PORT->Group[1].OUTSET.bit.OUTSET = (1 << 30);
27
28
  for (;;)
29
    {
30
      if ((PORT->Group[0].IN.bit.IN & (1 << 19)) != 0)
31
      {
32
        /* PA19 pulled high */
33
        /* turn on LED */
34
        PORT->Group[1].OUTCLR.bit.OUTCLR = (1 << 30);
35
        /* wait for button release */
36
        while ((PORT->Group[0].IN.bit.IN & (1 << 19)) != 0)
37
          {
38
          }
39
      }
40
41
      if ((PORT->Group[0].IN.bit.IN & (1 << 16)) == 0)
42
      {
43
         /* PA16 pulled low */
44
         /* turn off LED */
45
         PORT->Group[1].OUTSET.bit.OUTSET = (1 << 30);
46
         /* wait for button release */
47
         while ((PORT->Group[0].IN.bit.IN & (1 << 16)) == 0)
48
           {
49
           }
50
      }
51
    }
52
53
  return 0;
54
}

(Die leere _init() wollte er bei mir unbedingt haben, sonst gibt's
einen Linkerfehler.  Eventuell brauchst du die ja nicht.)

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Jumper bei PA16 oder PA19 reinsteckt,

Das sind übrigens, im Gegensatz zu deinem Bild, die Pins links an
der Steckerleiste.  Nur dort gibt's sowohl Vcc als auch GND, auf
der rechten Seite ist statt Vcc die Leitung zur Identifikation des
angesteckten Moduls.

von U.G. L. (dlchnr)


Lesenswert?

Jörg Wunsch schrieb:
> Nur dort gibt's sowohl Vcc als auch GND, auf
> der rechten Seite ist statt Vcc die Leitung zur Identifikation des
> angesteckten Moduls.

Das stimmt so, wenn ich in links/rechts unterscheide - unterscheide ich 
es in oben/unten gibt es VCC und GND nur unten :-).

von U.G. L. (dlchnr)


Lesenswert?

Jörg Wunsch schrieb:
> Das ganze ASF-Geraffel ist mir suspekt.

Sicher bringt so eine Lib 'ne Menge Overhead mit, wenn sie aber gut 
gemacht ist, läßt sich eine nicht zeitkritische Applikation auch mal 
lösen, ohne das Datenblatt studieren zu müssen. Ich benutze bei meiner 
Applikation den virtuellen ComPort (mit Callbackfunktionen), 'nen 
Timerinterrupt und ettliche GPIOs des EXT2-Steckers. Dazu habe ich die 
"getting-started" Applikation etwas abgeändert und das Programm um 
insgesamt drei Module/Klassen erweitert. Mittlerweile funktioniert das 
Programm auch, hab' mir wieder eine ordentlichen "Schnitzer" erlaubt.

Ich hatte zunächst die Ausgänge mittels port_pin_set_output_level(pin, 
val) getestet und dabei auch die Wiederholrate des Timer-Interrupts 
justiert.
Für das Lesen eines GPIO-Pins habe ich dann eine 
port_pin_set_output_level(pin, val)-Zeile kopiert, den zweiten Parameter 
rausgeschmissen und das set in get geändert - und übersehen, dass ich 
auch output in input hätte ändern müässen! :-)

Mit port_pin_get_input_level(pin) funktioniert das Programm wie 
gewünscht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

U.G. L. schrieb:
>> Das ganze ASF-Geraffel ist mir suspekt.
>
> Sicher bringt so eine Lib 'ne Menge Overhead mit, wenn sie aber gut
> gemacht ist, läßt sich eine nicht zeitkritische Applikation auch mal
> lösen, ohne das Datenblatt studieren zu müssen.

Ist nicht so mein Ding; ich möchte gern selbst in der Hand haben, was
auf meinen Controllern passiert und was nicht.

Und „gut gemacht“, hmm, naja, hüstel, „gut gemeint“ ist meist das
Gegenteil davon … ;-)

Wenn man sowas konsequent durchzieht, ist man bei Konzepten à la
Arduino oder Bascom, aber die sind dann wenigstens in sich stimmig.
ASF ist meiner Meinung nach an vielen Stellen einfach nur Overhead
ohne Konzept dahinter.

von U.G. L. (dlchnr)


Lesenswert?

Jörg Wunsch schrieb:
> Und „gut gemacht“, hmm, naja, hüstel, „gut gemeint“ ist meist das
> Gegenteil davon … ;-)

Das bezog sich jetzt nicht speziell auf die ASF - da ich die jetzt nur 
für dieses eine Projekt eingesetzt habe, will ich mir da kein Urteil 
anmaßen - da sie für lau zu haben ist, würd' ich ein "gut gemacht" aber 
schon vergeben, wenn sie einen nicht mit Fehlern ärgert. Ich meine klar 
- ich hätte schon jetzt, wie auf der PC-Seite, gerne etwas wie 
usart_read_buffer_job_until(...) gehabt, dem ich einen Delimiter 
Character mitgeben kann - gab's nicht und ich musste die Zeichen einzeln 
reinlutschen, aber es hat auch so auf Anhieb funktioniert.

Und bei etwas zeitkritischem würd' ich von vorn herein nicht auf eine 
Lib bauen - die unterschiedlichen Anforderungen, die Libraries 
typischerweise erfüllen müssen, sind eben mit einem gewissen Overhead 
verbunden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.