Datum:
Angehängte Dateien: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 :)
Datum:
Angehängte Dateien: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.
Datum:
Angehängte Dateien: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
Datum:
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.
Datum:
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 :)

