www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 - SPI Schnittstelle empfängt mal korrekt und dann wieder nicht


Important 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.
Autor: Claudio Hediger (hedie)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Guten Abend zusammen


Ich habe hier ein merkwürdiges Problem.

An meinem STM32F105RB hängt eine SD-Card am SPI1
Ich verwende den Code von elm-chan.

Nun habe ich ein Problem mit der SPI kommunikation...
Für das Mounten des Volume wird im MBR der Kate nach dem Pattern 0xAA55 
gesucht.

Dazu wird die karte an entsprechender Stelle ausgelesen.
Nun das Problem, mit dem LA überprüft sendet die Karte beim ersten 
Empfang 0x55, der STM empfängt jedoch 0xEB
bei der zweiten Übertragnung zeigt der LA 0xAA, der STM32 ebenfalls 
0xAA.
Dies ist permanent reproduzierbar.

Die kommunikation an anderen Codestellen klappt meines wissens 
eigentlich.

Hier meine SPI Read routine:

unsigned char read_spi (SPI_TypeDef* SPIx)
{       //msb first
  write_spi(SPIx,0xFF);
  while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET);
  while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  return SPI_I2S_ReceiveData(SPIx);
}


static
BYTE rcvr_mmc (void)
{
  BYTE r;

  r = read_spi(SPI1);

  return r;
}


aufgerufen wird rcvr_mmc.
Bereits dort hat die Variable r den flaschen Wert.

Anbei noch die 2 logs des LA's

Ich erkenne dort keinen unterschied was das Timing anbelangt. Der LA 
erkennt die gesendeten Bytes ja auch korrekt.

Meine SPI Einstellungen:
230Khz CLK
CPOL = low
CPHA = erste Flanke

Hat jemand eine Idee woran das liegen könnte?

Danke schonmal :)

Autor: Matthias K. (matthiask)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Schwierig, ohne Dein Programm genau zu kennen.

Ich häng Dir mal funtionsfähigen Low-Level Code für SPI SDCARD an. 
Vielleicht eine Hilfe.

Autor: Claudio Hediger (hedie)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Matthias K. schrieb:
> Schwierig, ohne Dein Programm genau zu kennen.
>
> Ich häng Dir mal funtionsfähigen Low-Level Code für SPI SDCARD an.
> Vielleicht eine Hilfe.

Hallo Matthias
Vielen Dank für deine Antwort....

Was mir auffält, ist dass du nicht bis zum ende des Transmit wartest.
/*-----------------------------------------------------------------------*/
/* Transmit/Receive a byte to MMC via SPI  (Platform dependent)          */
/*-----------------------------------------------------------------------*/
static BYTE stm32_spi_rw( BYTE out )
{
  /* Loop while DR register in not empty */
  /// not needed: while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_TXE) == RESET) { ; }

  /* Send byte through the SPI peripheral */
  SPI_I2S_SendData(SPI_SD, out);

  /* Wait to receive a byte */
  while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_RXNE) == RESET) { ; }

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI_SD);
}


Ich habe nach meindem SendData ja noch dies hier drinn

while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET);

Du schreibst ja in deinem Kommentar, dass das Warten auf das ende des 
Sendens nicht nötig ist also auf das flag TXE. Weshalb nicht?
Ich hatte ohne das Warten Probleme.

Der STM hatte dann nämlich sein TX Buffer wieder gefüllt obwohl der alte 
noch nicht gesendet war. Mit dem flag TXE konnte ich dies leider nicht 
korrekt erkennen ob er leer war oder nicht.
Nach einigem Googlen hab ich herausgefunden dass anscheinend auch andere 
dieses Problem haben.

Lösen konnte ich es mit der obigen Codezeile. Das Warten auf das BSY 
Flag

Bevor ich jetzt meinen gesamten Code umkremple und mit deinem vereine,
habe ich dir im Anhang noch mein komplettes Projekt angehängt...

Vielleicht siehst du da etwas verdächtiges....

Danke schonmal

Autor: Matthias K. (matthiask)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Claudio Hediger schrieb:
> /* Wait to receive a byte */
>   while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_RXNE) == RESET) { ; }

Wenn das Byte empfangen wurde, ist zwangsläufig auch ein Byte gesendet 
wurden. (immer so im SPI Master Betrieb). Deshalb kann man sich das 
zusätzliche warten beim senden sparen.

Autor: Claudio Hediger (hedie)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
So ich konnte das Problem dank Matthias lösen :)
Also an dieser Stelle, Danke Matthias.

Folgendes ist geschehen,

in meiner spi_write funktion lese ich den empfangs puffer nicht ein.
somit bleit nach dem senden eines bytes das RXNE Flag gesetzt.
Dies bedeutet, der Controller bzw. die Software meint es hat etwas im 
empfangs buffer.

Wenn nun nach einem byte Senden ein empfangen kommt, wird zuerst 0xFF 
gesendet und gleich danach überprüft ob etwas empfangen wurde (mit dem 
RXNE Flag).

Da dieses nun ja schon von der vorherrigen write operation gesetzt ist, 
wird der Buffer sofort ausgelesen. Dies noch bevor das neue Byte 
überhaupt eingelesen wurde.

Deshalb war mein Byte welches ich empfangen habe, jenes von einer 
vorherigen transaktion.

Die Lösung:

Wie Matthias in seinem code auch, wird bei mir nach jedem byte senden 
auch eines empfangen.

Dadurch wird das Flag RXNE gelöscht. und alles klappt einwandfrei :)

hier der Code:
unsigned char rw_spi (SPI_TypeDef* SPIx, unsigned char data_out)
{       //msb first
  SPI_I2S_SendData(SPIx,data_out);
  while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET);
  while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  return SPI_I2S_ReceiveData(SPIx);
}

Danke euch allen :)

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net