Dabei besonders erst ein struct konfiguriert (korrekt?) und danach z.B. die Pins festgelegt an denen SCL und SDA anliegen sollen.
Ja das ist richtig. In anderen Bereichen des ASF wird das auch so gemacht.
Was ich dabei nicht verstehe ist das:
config_i2c_master.buffer_timeout = 10000;
Das ist ein Timeout Wert, welche die _wait Funktionen nutzen. Diese geben dann auch einen Status STATUS_ERR_TIMEOUT zurück, falls es zu einem Timeout gekommen ist.
Der Timeout Wert muss zuvor in der Struktur festgelegt oder angepasst werden.
Wie im ASF Beispiel habe ich zusätzlich nocht einen Timeout Zähler dieser ist innerhalb der while Schleife eingebaut. Hier kann man also wiederholt lesen/schreiben. Das ist etwas irritierend im ASF Beispiel.
CodeBox C
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
{
if (timeout++ == TIMEOUT)
{
LED_PB30_ON
break;
}
}
In den Doku habe ich es oft so gesehen:
while(i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master) != STATUS_OK);
Nein das kann eigentlich nicht sein, bei der _init Funktion nicht.
Einmal für schreiben und einmal für lesen? oder generell?
CodeBox C
i2c_master_write_packet_wait(&i2c_master_instance, &packet)
i2c_master_read_packet_wait(&i2c_master_instance, &packet)
Bei beiden Funktionen wird es geanuso gemacht. Zum Timeout kann es ja kommen, wenn der Slave nicht mit einem ACK antwortet, in beiden Fällen.
Zuvor definiertst du in der Package Struktur die Felder für Adresse, Datenlänge und Datenbuffer. Der Datenbuffer ist ein Array und kann für Schreiben und lesen unterschiedlich sein.
Die Slave Adress ist 12, diese übergabe ich an packet.adress und wie geht es weiter?
Beispiel:
Schreiben
CodeBox C
#define DATA_LENGTH 32
static uint8_t i2c_write_buffer[DATA_LENGTH];
static uint8_t i2c_read_buffer[DATA_LENGTH];
// ...
packet.address = SLAVE_ADDRESS; // 7bit Adresse
packet.data_length = 1; // ein Byte senden
packet.data = i2c_write_buffer; // dieser Buffer wird verwendet
i2c_write_buffer[0] = 0; // 0 wird gesendet
timeout = 0;
while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
{
if (timeout++ == TIMEOUT)
{
LED_PB30_ON
break;
}
}
Beispiel:
Lesen (äquivalent zu Schreiben)
CodeBox C
packet.address = SLAVE_ADDRESS;
packet.data_length = 32; // 32 Byte lesen
packet.data = i2c_read_buffer;
timeout = 0;
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK)
{
if (timeout++ == TIMEOUT)
{
LED_PB30_ON
break;
}
}
// Wenn es fehlerfrei abgelaufen ist, sind befinden sich die 32 Byte im Array i2c_read_buffer