SPI Master mit Attiny1616

#7758147
Lesenswert?

Hallo zusammen, ich habe derzeit ein Projekt, bei dem ein Attin1616 über SPI mit einem SX1276 LoRa Modul reden soll. Leider bekomme ich die SPI Kommunikation nicht wirklich hin. Ich habe mir 3 Methoden geschrieben:

1
void init_spi() {
2
  PORTA_DIRSET = 0x02 | 0x04 | 0x10; //set clock, MOSI and NSS as output
3
  PORTC_DIRSET = 0x02; //set rst as output
4
  PORTC_OUTSET = 0x02; //set reset high
5
  SPI0_CTRLA = 0x23; 
6
  SPI0_CTRLB = 0x04;
7
}
1
void readReg(uint8_t reg, uint8_t *result, size_t length = 1) {
2
  uint8_t message[length + 1];
3
  PORTA_OUTCLR = 0x10;
4
  _delay_ms(2);
5
  for (int i = 0; i < length; i++) {
6
    message[i + 1] = 0;
7
  }
8
  message[0] = reg;
9
  for (int i = 0; i < length + 1; i++) {
10
    SPI0_DATA = message[i];
11
    //while (!SPI0_INTFLAGS & 0x80) ; // wait for transmission to be over
12
    _delay_ms(5);
13
    message[i] = SPI0_DATA;
14
    send_char(message[i]);
15
  }
16
  memcpy(result, &message[1], length);
17
  PORTA_OUTSET = 0x10;
18
}
1
void writeReg(uint8_t reg, uint8_t *data, size_t length = 1) {
2
  //pull cs low
3
  PORTA_OUTCLR = 0x10;
4
  _delay_ms(2);
5
  uint8_t message[length + 1];
6
  message[0] = reg | 0x80;
7
  memcpy(&message[1], data, length);
8
  for (int i = 0; i < length + 1; i++) {
9
    SPI0_DATA = message[i];
10
   //; while (!SPI0_INTFLAGS & 0x80) ; // wait for transmission to be over
11
    _delay_ms(5);
12
    send_char(SPI0_DATA);    
13
  }
14
  PORTA_OUTSET = 0x10;
15
}

Die Methode send_char() macht über UART eine Ausgabe zum debuggen. Leider bekomme ich immer nur 0x00 zurück. Sieht jemand auf Anhieb etwas das Falsch läuft? Falls nein, hat jemand evtl ein paar Code Fetzen, die ich mir anschauen kann? Microchip hat zwar ein Guide zu SPI an Attiny 0 und 1 serie, allerdings habe ich da nicht wirklich etwas finden können, was erklärt, warum das ganze hier nicht funktioniert. Ich habe leider kein Oszilloskop um mir die Leitungen anzuschauen. Die Pinbelegung ist MOSI PA1, MISO PA2, SPI_CLK PA3, CS PA4, also die Standartbelegung des Attiny1616, wenn ich das richtig aus dem Datenblatt gelesen habe.

Danke schon mal für Eure Hilfe und noch einen schönen Abend.

#7758165
Lesenswert?

Wastl schrieb:

Das wären meine Magic Numbers ..... wenn man den Clock auch als Output definieren müsste. MISO natürlich nicht ...

Ah da ist mir wohl ein Fehler unterlaufen. Geht aber leider immer noch nicht.

Die Einstellungen zu SPI sollten denke ich passen, Das sollte SPI Master Mode sein mit clockdiv 16 und SPI enable. Das zweite ist Nur Slave Select Disable, da ich kein multi Master mache.

Moderator (Firma: Titel) Persönliche Seite #7758232
Lesenswert?

David P. schrieb:

Sieht jemand auf Anhieb etwas das Falsch läuft?

Meine übliche Vorgehensweise wäre jetzt, ein/en Oszi/Logicanalyzer zu nehmen, und zu kontrollieren, ob sich auf dem SPI das tut, was ich erwarte. Und wenn nicht das passiert, was ich erwarte, dann sehe ich, wo ich noch korrigieren muss.

David P. schrieb:

Die Einstellungen zu SPI sollten denke ich passen

Da muss man dann gar nichts Denken, sondern einfach nur kontrollieren. Alles andere ist wie "Blindflug im Nebel" oder "Autofahren nach Gehör". Es ist mir ein völliges Rätsel, wie man serielle Busse ohne Speicheroszi bzw. LA in Betrieb nehmen kann.

#7758284
Lesenswert?

David P. schrieb:

Veit D. schrieb:

schau dir Kapitel 25.3.1 nochmal genauer an.

Hast du was gesehen, was ich falsch gemacht habe oder ist das mehr ein "hier sollte alles drin stehen"? Ich habe eigentlich beides gelesen, aber scheinbar dann wohl nicht richtig.

Eher da steht in Beiden alles drin. Dein Code Ausschnitt ist leider schwer bis kaum lesbar. Niemand übersetzt Hexcode in Binär und zurück nur zum vergleichen. Bekommst du eine Led zum blinken? Ansonsten, halte dich an die App Note und es wird funktionieren. Tue dir selbst auch einen Gefallen. Verwende Bitnummern oder noch besser Bitnamen bzw. Bitmasken (die mit _bm am Ende).

Deine:

1
PORTA_DIRSET = 0x02 | 0x04 | 0x10; //set clock, MOSI and NSS as output

übersetzt:

1
PORTA_DIRSET = _BV(1) | _BV(2) | _BV(4); //set clock, MOSI and NSS as output

Stellst du schon etwas fest? Wenn nicht, an welchen Portpins verwendest du SPI? Wie heißen die Portpins? Was sind deren Bitnummern? Gehe alles nochmal durch.

#7758290
Lesenswert?

Wenn ich einen zweiten Attiny1616 als Slave setze und etwas nicht geht, habe ich ja nichts gewonnen. Ich weiß dann ja nicht, ob es an der Master- oder Slave Seite liegt. Eine zweite Platine müsste ich erst bestücken; dafür, dass das Resultat nicht. Aber kann ich Testweise einfach MISO und MOSI verbinden? Dann sollte doch zumindest immer das ankommen, was ich sende, um zu schauen, ob das SPI an sich überhaupt funktioniert.

#7758299
Lesenswert?

Veit D. schrieb:

Deine:PORTA_DIRSET = 0x02 | 0x04 | 0x10; //set clock, MOSI and NSS as output übersetzt:PORTA_DIRSET = _BV(1) | _BV(2) | _BV(4); //set clock, MOSI and NSS as output

Den Fehler hatte schon dein Vorredner gesehen. Das ganze habe ich korrigiert auf

1
PORTA_DIRSET = 0x02 | 0x08 | 0x10;

daraus habe ich jetzt das hier gemacht

1
PORTA_DIRSET = PIN1_bm | PIN3_bm | PIN4_bm;

aber das ändert ja nichts an der Funktionalität.

#7758323
Lesenswert?

Ich habe den Fehler gefunden. Es war tatsächlich was ganz anderes und unglaublich dämliches. Anstatt in der main() spi_init(); aufzurufen, hatte ich stattdessen void spi_init(); da stehen, also eine lokale Redefinition(?) der Methode? Ohne das setzen aller PINS und Register geht natürlich gar nichts...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren