Hallihallo, vielleicht weiß ja jemand Rat: Habe einen W25Q80BV Flash IC (DIP, SPI ~25MHz) in einer aufgelöteten IC-Fassung auf einer kleinen Platine. Von dort aus geht es direkt über Jumperkabel ohne irgendwelches Hühnerfutter an den STM32. Das ganze hat auch bis vor einigen Tagen ein paar Monate lang ohne zu Murren funktioniert. Jetzt passiert es allerdings manchmal, dass mein System nicht hochfährt, da anscheinend Lesefehler auftreten. Zumindest stimmt die ausgelesene JEDEC-ID nicht. Ändern der SPI-Frequenz ändert an dem Verhalten nichts. Zu Anfang dachte ich der Speicher wäre defekt, also IC ausgetauscht, programmiert und alles wieder OK. Nach einiger Zeit wieder das selbe beim Systemstart: Falsche JEDEC-ID. Erst vor kurzem ist mir aufgefallen, dass die JEDEC-ID stimmt, sobald ich das System kurz vom Strom trenne. Hat jemand einen Tipp, fehlt mir hier vllt. etwas Hühnerfutter? Google konnte mir hier nicht wirklich helfen bzw. war ich zu blöd um die richtigen Suchbegriffe einzugeben. Danke schonmal! Grüße Reggie
Reginald L. schrieb: > Hat jemand einen Tipp, Glaskugel sagt: SPI Timing falsch. Alles andere wäre ohne Schaltplan und Code geraten :) rgds
6a66 schrieb: > Reginald L. schrieb: >> Hat jemand einen Tipp, > > Glaskugel sagt: SPI Timing falsch. Alles andere wäre ohne Schaltplan und > Code geraten :) Darum nicht raten oder Glaskugeln befragen, sondern Logic Analyzer ran und sich das ganze angucken.
Nee, Timings passen, es werden bei jedem Systemstart etwa ein halbes MB in den STM-internen Flash geladen und da passt alles. Beschreiben des Chips funktioniert auch wunderbar. Bei jedem Systemstart frage ich aber erst die ID ab, wenn die nicht passt, lasse ich erst gar nicht weiter booten. Und hier bekomme ich eben (selten) nicht die richtige ID. Schaltplan gibts nicht. MOSI, MISO, CLK wie gehabt, CS dauerhaft auf low und die restlichen Pins nach Datenblatt entweder high oder low. Der Fehler tritt ja sporadisch auf und zwar relativ selten. Und falls er dann auftritt: Strom aus, Strom wieder ran und es geht. Deshalb vermute ich, dass da irgendwie vielleicht noch Hühnerfutter dran muss. Da es bisher aber funktioniert hat, wundert mich das jetzt. Gibt es für die JEDEC-Spezi irgendwelche Design-Rules bezüglich der Beschaltung mit Hühnerfutter? Den Code habe ich mal rangehangen. Zeile 326 ist der "Übeltäter".
>>CS dauerhaft auf low
Laut Programm ist CS nicht dauerhaft low. Wieso schreibst du sowas?
Upsa, Tatsache. War grad ganz woanders -.- Vermutlich also doch Timing zwischen CS und Senden, richtig? EDIT: Laut Datenblatt braucht er nur einen Stups von high nach low nach dem PowerUp. Ich schau mal ob ich den dann dauerhaft auf low lassen kann. Vielen Dank erstmal für den Stups in die richtige Richtung!
:
Bearbeitet durch User
Bin jetzt endlich dazu gekommen, nach dem SPI zu schauen. Beim Timing und dem IC ist alles wunderbar, habe mal den LogicAnalyzer angesteckt. Also muss der Fehler an meinem Code liegen und zwar in Richtung "ReadBytes()". Hier sind die Schnipsel, vielleicht sieht ja jemand auf den ersten Blick, dass da was verquer ist.
1 | void ExternFlash::SendCommand(CMD cmd) |
2 | {
|
3 | while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); |
4 | SPI_I2S_SendData(SPI2, cmd); |
5 | while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); |
6 | SPI_I2S_ReceiveData(SPI2); |
7 | }
|
8 | void ExternFlash::ReadBytes(uint8_t * byte_arr, uint32_t amount) |
9 | {
|
10 | for (int i = 0; i < amount; i++) |
11 | {
|
12 | while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); |
13 | SPI_I2S_SendData(SPI2, 0x00); |
14 | while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET); |
15 | byte_arr[amount - i] = SPI_I2S_ReceiveData(SPI2); |
16 | }
|
17 | }
|
18 | bool ExternFlash::CheckID(uint8_t jedecid, uint32_t uniqueid) |
19 | {
|
20 | uint8_t jdid; |
21 | uint32_t uid; |
22 | SetCSLow(); // static void SetCSLow() { GPIOB->BSRRH = GPIO_Pin_12; }; |
23 | |
24 | SendCommand(JEDECID); |
25 | ReadBytes((uint8_t*)&jdid, 1); |
26 | SetCSHigh(); // static void SetCSHigh() { GPIOB->BSRRL = GPIO_Pin_12; }; |
27 | |
28 | if (jdid != jedecid) |
29 | return false; |
30 | return true; |
31 | }
|
:
Bearbeitet durch User
byte_arr[amount - 1 - i] = SPI_I2S_ReceiveData(SPI2); Es ist schon spät :) Das ganze hätte böse enden können :>
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.