Forum: Mikrocontroller und Digitale Elektronik GPIO und SPI bei ATSAM2D asynchron?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Sortland (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuche mit folgendem Code 24 Datenbits per SPI auszugeben, wobei 
sich die beiden SPI-Geräte ein gemeinsames CS-Signal teilen:
1
    gpio_set_pin_level(DAC_CS,false); // CS auf LOW ziehen
2
3
    // 3x 8 bit per SPI ausgeben und jeweils darauf warten, dass SERCOM damit fertig wird:
4
    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[3]); //SPI2
5
    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[3]); //SPI4
6
    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_RXC))
7
8
    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[2]); //SPI2
9
    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[2]); //SPI4
10
    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_RXC))
11
12
    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[1]); //SPI2
13
    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[1]); //SPI4
14
    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_RXC))
15
16
    gpio_set_pin_level(DAC_CS,true); // CS wieder auf HIGH setzen

Was ich erwarten würde, was passiert:

- CS-Leitung geht auf LOW
- ich sehe 24 Clock-Pulse auf der SPI-Taktleitung
- CS-Leitung geht auf HIGH

Was statt dessen passiert:

- CS-Leitung geht auf LOW
- für ca 220 nsec passiert nichts
- ich sehe 17 Clock-Pulse auf SCLK
- CS geht auf HIGH
- es kommen die fehlenden 7 Clock-Pulse

Also scheint da mit meiner Synchronisation was nicht zu stimmen? Mit 
welchem Registerbit überwache ich denn wirklich, ob alle Datenbits 
gesendet wurden? RXC scheint es ja nicht zu sein...

Danke!

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


Bewertung
0 lesenswert
nicht lesenswert
TXC sollte das sein (im Unterschied zu DRE, welches nur besagt, dass du 
weitere Daten ins Ausgaberegister schreiben kannst).

von Sortland (Gast)


Bewertung
0 lesenswert
nicht lesenswert
TXC macht es nur anders aber nicht besser. Dann ist das Ergebnis

- CS geht auf LOW
- ca 22 nsec nichts
- 8x SCLK
- ca. 550 nsec nichts
- 8x SCLK
- ca 550 nsec nichts
- 6x SCLK
- CS geht auf HIGH
- 2x SCLK

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


Bewertung
0 lesenswert
nicht lesenswert
Zwischen den Bytes brauchst du kein TXC benutzen, da genügt DRE.

Ansonsten hat TXC für uns seinerzeit funktioniert (auf einem SAMR21, 
aber das ist letztlich ein modifizierter SAMD21 mit einem AT86RF233 
drüber gestapelt).

von Sortland (Gast)


Bewertung
0 lesenswert
nicht lesenswert
OK, das Problem scheint auch wo anders zu liegen. Wenn ich folgende 
Funktion habe:
1
static void SPI_ExchangeBuffer(const uint8_t pSendX[4],const uint8_t pSendY[4])
2
{
3
    gpio_set_pin_level(DAC_CS,false); // CS auf LOW ziehen
4
5
    // 3x 8 bit per SPI ausgeben und jeweils darauf warten, dass SERCOM damit fertig wird:
6
    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[3]); //SPI2
7
    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[3]); //SPI4
8
    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_DRE))
9
10
    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[2]); //SPI2
11
    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[2]); //SPI4
12
    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_DRE))
13
14
    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[1]); //SPI2
15
    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[1]); //SPI4
16
    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_TXC))
17
18
    gpio_set_pin_level(DAC_CS,true); // CS wieder auf HIGH setzen
19
}

dann wird das Setzen von DAC_CS am Ende nicht ausgeführt. Rufe ich 
gpio_set_pin_level(DAC_CS,true) vor dem Verlassen der Funktion aber zwei 
mal auf, dann funktioniert es und ich sehe, dass CS auf HIGH geht.

Ähnliches passiert beim Beschreiben der DATA-Register: nur einer der 
beiden SERCOMs zeigt mir 24 Clock-Bits, beim anderen werden nur 8 
ausgegeben. Verdopple ich die Aufrufe von 
hri_sercomspi_write_DATA_reg(), dann sendet auch der andere SPI 24 Bits.

Wenn das Lesen der Statusbits genau so zuverlässig funktioniert, ist es 
klar, dass das Timing nicht stimmt.

Erzeugt habe ich den Code mit Atmel START, bauen tue ich im AtmelStudio 
unter Windows. Ist das ein Compilerproblem oder habe ich irgend was 
anderes blödes übersehen, was dieses Verhalten verursachen könnte?

Danke!

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


Bewertung
0 lesenswert
nicht lesenswert
Vielleicht solltest du ja auch, wenn du auf zwei SERCOMs arbeitest, auf 
jeder von beiden das DRE-Bit testen?

START / FSF haben wir nie benutzt, irgendwie zu aufgebläht und 
obfuscated. Wir haben uns lowlevel-Routinen selbst geschrieben (hat auch 
den Vorteil, dass sich bspw. auch ein STM32Fxxx da parallel ganz gut 
einbinden lässt).

Keine Ahnung, ob da noch was vergurkt sein könnte – eigentlich haben 
sich die Jungs und Mädels da Mühe gegeben, jeden auch noch so obskuren 
Fall abzudecken, aber ich habe (als ich mir das mal für irgendeinen 
eigenen Code als Vorlage genommen habe) da auch schon Bugs entdeckt. War 
allerdings nicht SAMD/SAMR, sondern SAM4E/SAME70.

: Bearbeitet durch Moderator
von foobar (Gast)


Bewertung
1 lesenswert
nicht lesenswert
>
1
>    hri_sercomspi_write_DATA_reg(SERCOM2,pSendX[1]); //SPI2
2
>    hri_sercomspi_write_DATA_reg(SERCOM1,pSendY[1]); //SPI4
3
>    while (!(hri_sercomspi_read_INTFLAG_reg(SERCOM1) & SERCOM_SPI_INTFLAG_TXC))
4
         ;
5
>    gpio_set_pin_level(DAC_CS,true); // CS wieder auf HIGH setzen
6
>

Dürfte an den fehlenden Semikola liegen.

Davon abgesehen: ich würde mich nicht darauf verlassen, dass die beiden 
SERCOMs gleichzeitig fertig sind - besser beide testen.

von Sortland (Gast)


Bewertung
0 lesenswert
nicht lesenswert
foobar schrieb:
> Dürfte an den fehlenden Semikola liegen.

Oh F***, na klar, Danke!!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.