Pogrammierung SAM D21 mit Atmega ICE und SWD

Hallo Dirk
habe die meisten Fehler weg bekommen. Es kam meistens aus vert^steckten Leerzeichen oder gross/klein Schreibbung. Kann jetzt ohne Probleme mehrere GPIOs angeben. Es bleibt aber eib Fehler den ich nicht verstehe.


CodeBox C
// Gruppe LED
   port_get_config_defaults(&config_port_pin);           // ok LED G
   config_port_pin.direction = PORT_PIN_DIR_OUTPUT;   // ok LED G
   port_group_set_config(&PORTB, PORT_PB08|PORT_PB09, &config_port_pin);       // geht

und


CodeBox C
if (port_pin_get_input_level(Button2))           // Taste 4
         {
           port_pin_toggle_output_level(&PORTB);       // 30
           delay_ms(500);
           port_pin_toggle_output_level(&PORTB);       // 30
           delay_ms(500);
         }

Das ergibt diesen Fehler


CodeBox C

expected 'uint8_t {aka const unsigned char}' but argument is of type 'PortGroup * {aka struct <anonymous> *}'  
expected 'uint8_t {aka const unsigned char}' but argument is of type 'PortGroup * {aka struct <anonymous> *}'   
passing argument 1 of 'port_pin_toggle_output_level' makes integer from pointer without a cast [-Wint-conversion]   
passing argument 1 of 'port_pin_toggle_output_level' makes integer from pointer without a cast [-Wint-conversion]   

Die beiden aufgeführten LEDs leuchten. Es erfolgt keine Umschaltung bzw. blinken. Soweit ich es verstanden habe, liegt der Fehler


CodeBox C
port_pin_toggle_output_level(&PORTB);

besonders in (&PORTB). Leider verstehe ich nicht warum. In der ASF Doku steht drin, was es sein soll, leider weiss ich nicht wie.
achim
 
In der ASF Doku habe ich das gefunden


CodeBox C
port_group_toggle_output_level(&PORTB);

habe es eingesetzt und bekomme wieder Fehlermeldung. Soweit ist das klar. Möchte eine Gruppe umschalten und nicht eine einzelne LED. Ist unklar
achim
 
Einzelnen Pin toggeln
port_pin_toggle_output_level(&PORTB);
Dies wirkt nur auf einen einzelnen Pin. Die Funktion erwartet als Parameter den Index des Pins (uint8_t), nicht die Basisadresse des Ports. Der Compiler zeigt hier einen Fehler.

Ein Index wäre zum Beispiel PIN_PB30.

Mehrere Pins toggeln (Gruppe)
In der ASF Doku habe ich das gefunden
port_group_toggle_output_level(&PORTB);
Das kann nicht sein. Hier fehlt der zweite Parameter, die Maske.

static void port_group_toggle_output_level ( PortGroup *const port,
const uint32_t mask
)
port Base of the PORT module to write to
mask Mask of the port pin(s) to toggle

In der Maske sind die Bitpositionen 1 bei denen der GPIO Pin getoggelt werden soll. Ist ein Portpin nicht Output, wird dieser nicht getoggelt.
Sollen alle outputs des Ports getoggelt werden ist die Maske 0x0000FFFF (Bit 0..31 sind "1")
 
Danke Dirk
habe den zweiten Parameter vollkommen übersehen. Jetzt geht es und kann weitermachen. Mal sehen was ich nicht begreiffe.
achim
 
Hallo
habe die ersten Programme für den SAMD21 fertig und stelle sie allen zur Verfügung. Falls ich was übersehen habe oder nicht klar ist, bitte eine mail an mich.
Möchte mich nochmal ausdrücklich bei Dirk für seine Hilfe bedanken.
achim
 

Anhänge

  • ATB SAM D21 Software 2 Das erste Programm.pdf
    740,6 KB · Aufrufe: 14
Hallo Dirk
bin dabei den I2C Bus zu arbeiten. Bei der Eingabe des Programmes bekomme ich eine Fehlermeldung die ich nicht verstehe.


CodeBox C
packet.address

Dieses Stück wird mir als Quelle angezeigt.


CodeBox C
#define LED1  PIN_PB05               // PA03 / PB30 - 1. Zahl LED+Taster auf P110
#define Button1   PIN_PB23               // PB23 / PA13 - 2. Zahl LED+Taster auf Nano SAM
#define DATA_LENGTH 32
#define packet.address

void configure_i2c(void);       // Angabe Prototype
void touch_write_data(void);
void configure_port_pins(void);   

struct i2c_master_module i2c_master_instance; //generate the instance-struct for I2C-Master
struct i2c_master_packet packet;

static uint8_t i2c_write_buffer[DATA_LENGTH];

Es steht hier drin


CodeBox C
void configure_i2c(void)  // ok configuraton SERCOM 2 als I2C-Master
  {
   struct i2c_master_config config_i2c_master;                   // ok generate the configure-struct
   i2c_master_get_config_defaults(&config_i2c_master);           // ok get the defaults
   config_i2c_master.pinmux_pad0 = PINMUX_PA08C_SERCOM0_PAD0;   // ok PA08 SDA
   config_i2c_master.pinmux_pad1 = PINMUX_PA09C_SERCOM0_PAD1;   // ok PA09 SCL
   config_i2c_master.baud_rate = 100;                           // ok Setzt Baudrate auf 100kHz
   while(i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master) != STATUS_OK);  //initialization
   i2c_master_enable(&i2c_master_instance);                   // ok I2C interface einschalten
  }

Damit konfiguirie ich den Bus
Habe es mit deiner Angabe und dem Datenblatt verglichen. Leider keine Idee dazu.
achim
 
Schreibe ich diese Teil des Codes so erscheint alles in der richtigen Farbe.


CodeBox C
#define LED1  PIN_PB05               // PA03 / PB30 - 1. Zahl LED+Taster auf P110
#define Button1   PIN_PB23               // PB23 / PA13 - 2. Zahl LED+Taster auf Nano SAM
#define DATA_LENGTH 32
#define packet_address
#define packet_data_length
#define packet_data
 
Habe die Fehler auf die folgenden Zeilen eingegrenzt.


CodeBox C
uint16_t packet.address;
uint16_t packet.data_length;
uint16_t packet.data;

Es ergibt diese Fehlermeldungen.
expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
Diese Fehlermeldung erscheint 3x jeweils für jede Zeile. Den oberen Code konnte ich teilweise bereits korrigieren. Die Verbindung zum Slave, einem PCF8574 geht auch nicht. Brauchte drindend ein bischen Hilfe.
achim
 
Brauchte drindend ein bischen Hilfe
Hallo Achim,

deine Deklarationen und defines verstehe ich nicht. Ich hatte hier irgendwo schon mal ein komplettes Beispiel gepostet.
Du gehst erst mal folgendermaßen vor ...


Driver SERCOM I2C aus dem ASF einbinden.

Dann unter anderem ein packet definieren:

struct i2c_master_packet packet; // Beispiel


Die Elemente der struct packet definieren:
(alles Beispiele)
packet.address = 0x32;
packet.data_length = 1; // ein Byte wird gesendet
packet.data = i2c_write_buffer; // das ist ein uint8_t Array, muss deklariert sein

Das was du senden möchtest im buffer definieren:
i2c_write_buffer[0] = 0; // es wird nach der I2C Adresse eine "0" gesendet

Nun das packet senden:
(Beispiel)

while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
{
if (timeout++ == TIMEOUT)
{
LED_PB30_ON // weiter auf Fehler reagieren
break;
}
};
 
Du weißt, daß der Punkt der Strukturverweisoperator ist?
Wenn nicht, empfehle ich das Kapitel Strukturen in Deinem C-Buch nochmal durchzuarbeiten.

packet ist der Name einer Struktur, die irgendwo anders deklariert wurde
und address ist ein Member dieser Struktur, dessen Typ schon in der Struktur festgelegt wurde.


CodeBox C
uint16_t packet.address;

ist somit der Versuch, ein Member einer schon bestehenden Struktur zu verändern
 
Hallo Dirk
habe mich an deinen Ciôde gehalten. Die Abfrage Taster und Ansteuerung LED habe ich zusätzlich drin.


CodeBox C
#include <asf.h>               // Einbinden Bibliothek

#define SLAVE_ADDRESS 40       // Angabe Slave Adresse

#define LED1  PIN_PB05               // PA03 / PB30 - 1. Zahl LED+Taster auf P110
#define Button1   PIN_PB23               // PB23 / PA13 - 2. Zahl LED+Taster auf Nano SAM
#define DATA_LENGTH

void configure_i2c(void);       // Angabe Prototype
void touch_write_data(void);
void configure_port_pins(void);   

struct i2c_master_module i2c_master_instance; //generate the instance-struct for I2C-Master
struct i2c_master_packet packet;

static uint8_t i2c_write_buffer[DATA_LENGTH];

void configure_i2c(void)  // ok configuraton SERCOM 2 als I2C-Master
  {
   struct i2c_master_config config_i2c_master;                   // ok generate the configure-struct
   i2c_master_get_config_defaults(&config_i2c_master);           // ok get the defaults
   config_i2c_master.pinmux_pad0 = PINMUX_PA08C_SERCOM0_PAD0;   // ok PA08 SDA
   config_i2c_master.pinmux_pad1 = PINMUX_PA09C_SERCOM0_PAD1;   // ok PA09 SCL
   config_i2c_master.baud_rate = 100;                           // ok Setzt Baudrate auf 100kHz
   while(i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master) != STATUS_OK);  //initialization
   i2c_master_enable(&i2c_master_instance);                   // ok I2C interface einschalten
  }

void touch_write_data(void)           // Bus schreiben
  {
   uint16_t timeout;
   timeout = 100;
   
   i2c_write_buffer[0] = 0x34;
   
   packet.address = SLAVE_ADDRESS;
   packet.data_length = DATA_LENGTH;
   packet.data = i2c_write_buffer;
   
   i2c_master_write_packet_wait(&i2c_master_instance, &packet);
   
   while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
    {
       if (timeout ++ == timeout)
         {
           // Error LED_PB30_ON
           break;
         }
     /
  }
 
 void configure_port_pins(void)                           // konfiguration der Ports/Pins
   { // Angabe LED
    struct port_config config_port_pin;
    port_get_config_defaults(&config_port_pin);
    config_port_pin.direction = PORT_PIN_DIR_OUTPUT;
    port_pin_set_config(LED1, &config_port_pin);        // Angabe LED1
    // Angabe Taster
    port_get_config_defaults(&config_port_pin);
    config_port_pin.direction = PORT_PIN_DIR_INPUT;
    config_port_pin.input_pull = PORT_PIN_PULL_UP;
    port_pin_set_config(Button1, &config_port_pin);   // Angabe Button1 (Taster1)
   }
 
int main(void)
  {
   system_init();    //initialize and configure the MCU and I2C
   configure_i2c();
   configure_port_pins();   
   delay_init();
   
   while (1)
     {
       // Abfrage Taster
       //if (port_pin_get_input_level(Button1))   // Taster nicht gedrückt
       if (!port_pin_get_input_level(Button1))       // Taster gedrückt
         {                                           // Schaltet LED       
           touch_write_data();                       // Aufruf Bus
           
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
         }
       }
      }

Die entsprechenden ASF, delay und GPIO habe ich angegeben. Vielleicht könntest du mir helfen.
achim
 
Hallo Achim,
#define DATA_LENGTH
... da fehlt ein Wert, wahrsheinlich "1"

Zeile 40 entfernen, nur die Funktion in der folgenden while Schleife verwenden.

Zeile 49 entfernen "/"

Fehlerbehandlung nach dem _write_packet_wait könntest du noch machen.
 
Hallo Dirk
Ausser diesen Sachen hast du nichts gesehen? Ist komisch. Immer wenn ich eines ändee bekomme ich wieder eine andere Fehlermeldung. Zum Beispiel:


CodeBox C
uint16_t timeout;
   timeout = 100;
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
    {
       if (timeout++ == Timeout)
         {
           // Error LED_PB30_ON
           break;
         }
   
  }

Er sagt das das Timeout, gross geschrieben, verkehrt ist. Schreibe ich es klein, ist es gut. Dafür wird die ganze while bemängelt.


CodeBox C
//packet.address = SLAVE_ADDRESS;
   packet.address = 40;
   packet.data_length = DATA_LENGTH;
   packet.data = i2c_write_buffer;

Schreibe ich SLAVE_ADRESS gibt es eine Fehlermeldung, bei angabe 40 nicht.
Noch ein Beispiel:


CodeBox C
#define DATA_LENGTH

void configure_i2c(void);       // Angabe Prototype
void touch_write_data(void);
void configure_port_pins(void);   

uint8_t DATA_LENGTH = 1;

Er fordert eine Klammer vor der 1. Dafür wird mir #define DATA_LENGTH als Fehler angezeigt wenn ich eine =1 schreibe.
Bei jeder Korrekrur bekomme ich die alten Fehler und neue dazu oder ganz andere. Bin langsam am verzweifeln.
achim
 
Er sagt das das Timeout, gross geschrieben, verkehrt ist. Schreibe ich es klein, ist es gut. Dafür wird die ganze while bemängelt.
In C ist Groß/Klein-Schreiben wichtig.

Timeout (groß geschrieben) ist eine Konstante, die du nicht definiert hast.

definiere zum Beispiel
#define Timeout 100

Schreibe ich SLAVE_ADRESS gibt es eine Fehlermeldung, bei angabe 40 nicht.
Eventuell hast du noch etwas falsch geschrieben oder ein Fehler zuvor wirkt sich hier aus.

#define DATA_LENGTH als Fehler angezeigt wenn ich eine =1 schreibe.
Schau dir in der unteren Codebox Zeile 1 und Zeile 7 an.
 
Hallo Dirk
habe wieder einen Fehler gefunden. Der Fehler mit Timeout bleibt. Egal ob ich es gross oder kleinschreibe oder es definiere.


CodeBox C
uint16_t Timeout;
   Timeout = 100;

i2c_master_write_packet_wait(&i2c_master_instance, &packet);
   while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
    {
       if (Timeout ++ == Timeout )
         {
           // Error LED_PB30_ON
           break;
         }
    }

Wenn ich ab if alles auskommentiere bringt die Zeile mit while auch einen Fehler.
Mir was anderes aufgefallen. Habe für den PCF8574 die Adresse 0x40 eingestellt. Habe es auf dem IC alles richtig adressiert. Das Modul mit dem PCF ist ok, habe es in anderen Schaltungen mehrfach getestet.


CodeBox C
packet.address = SLAVE_ADDRESS;

Bei allen anderen Angaben erscheint bei einer korrekten Eingabe die Wörter in Farbe. Bei nicht korrekt sind sie schwarz. Damit könnte die korrekte Adresse nicht übermittelt werden und es kommt kein ACK zurück. packet ist in Farbe und adress ist schwarz
Die Adresse ist korrekt. Habe sie vorher überprüft.
achim
 
Beim timeout schau dir die if-Anweisung an und überlege was hier falsch ist.

Du kannst auch wegen den anderen Fehlern den ganzen Code Posten. Ich kompiliere es bei mir, komme heute aber nicht mehr dazu.
 
Hallo Dirk
hast Recht, mache heute auch Scluss. Werde mir morgen den Pegelwandler ansehen und ausmessen. Bekomme keine Spannung (Mist) sorry
achim
 
Hallo Dirk
habe den Pegelwandler noch mal ausgemessen und die Platine mit der Schaltung verglichen. Scheint alles zu stimmen. Spannungen liegen korrekt an. Habe alle fehler wegbekommen. Euîn Teil kamm durch eine falsche Reihenfolge. Das Programm lässt sich ohne Fehler kompilieren, läuft aber nicht. Wenn ich richtig gemessen habe wird der Slave nicht erkannt und das Programm geht in break. Habe jetzt bereits das zweite Modul angeschlossen und die Adressen geändert. Habe die Adressen vom PCF 8574 mit einem anderen Teil und Programm ausgelesen. Scheint alles korrekt zu sein.
Anbei das komplette Programm


CodeBox C
#include <asf.h>               // Einbinden Bibliothek

#define CONF_I2C_MASTER_MODULE SERCOM1
#define SLAVE_ADDRESS 42       // Angabe Slave Adresse 0x42

#define LED1  PIN_PB05               // PA03 / PB30 - 1. Zahl LED+Taster auf P110
#define Button1   PIN_PB23               // PB23 / PA13 - 2. Zahl LED+Taster auf Nano SAM
#define DATA_LENGTH 4
#define Timeout 1000

void configure_i2c(void);       // Angabe Prototype
void touch_write_data(void);
void configure_port_pins(void);   

struct i2c_master_module i2c_master_instance; //generate the instance-struct for I2C-Master
struct i2c_master_packet packet;

static uint8_t i2c_write_buffer[DATA_LENGTH];

void configure_i2c(void)  // ok configuraton SERCOM 2 als I2C-Master
  {
   struct i2c_master_config config_i2c_master;                   // ok generate the configure-struct
   i2c_master_get_config_defaults(&config_i2c_master);           // ok get the defaults
   config_i2c_master.pinmux_pad0 = PINMUX_PA08C_SERCOM0_PAD0;   // ok PA08 SDA
   config_i2c_master.pinmux_pad1 = PINMUX_PA09C_SERCOM0_PAD1;   // ok PA09 SCL
   config_i2c_master.baud_rate = 100;                           // ok Setzt Baudrate auf 100kHz
   while(i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master) != STATUS_OK);  //initialization
   i2c_master_enable(&i2c_master_instance);                   // ok I2C interface einschalten
  }

void touch_write_data(void)           // Bus schreiben
  {
   uint16_t timeout;
   timeout = 100;
   while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
   {
       if (timeout ++ == Timeout )
         {
           // Error LED_PB30_ON
           break;
         }
    }
  }
 
 void configure_port_pins(void)                           // konfiguration der Ports/Pins
   { // Angabe LED
    struct port_config config_port_pin;
    port_get_config_defaults(&config_port_pin);
    config_port_pin.direction = PORT_PIN_DIR_OUTPUT;
    port_pin_set_config(LED1, &config_port_pin);        // Angabe LED1
    // Angabe Taster
    port_get_config_defaults(&config_port_pin);
    config_port_pin.direction = PORT_PIN_DIR_INPUT;
    config_port_pin.input_pull = PORT_PIN_PULL_UP;
    port_pin_set_config(Button1, &config_port_pin);   // Angabe Button1 (Taster1)
   }
 
int main(void)
  {
   system_init();    //initialize and configure the MCU and I2C
   configure_i2c();
   configure_port_pins();   
   delay_init();
   
   i2c_write_buffer[0] = 44;
   
   packet.address = SLAVE_ADDRESS;
   packet.data_length = DATA_LENGTH;
   packet.data = i2c_write_buffer;
   
   while (1)
     {
       // Abfrage Taster
       //if (port_pin_get_input_level(Button1))   // Taster nicht gedrückt
       if (!port_pin_get_input_level(Button1))       // Taster gedrückt
         {                                           // Schaltet LED       
           touch_write_data();                       // Aufruf Bus
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
           port_pin_toggle_output_level(LED1);       // Toggelt LED1
           delay_ms(500);                           // Zeit 500ms
         }
       }
      }

Vielleicht siehst du noch was.
achim
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)