Forum: Mikrocontroller und Digitale Elektronik Winbond Flash & STM32F4


von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

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

von 6a66 (Gast)


Lesenswert?

Reginald L. schrieb:
> Hat jemand einen Tipp,

Glaskugel sagt: SPI Timing falsch. Alles andere wäre ohne Schaltplan und 
Code geraten :)

rgds

von Cyblord -. (cyblord)


Lesenswert?

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.

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Angehängte Dateien:

Lesenswert?

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".

von holger (Gast)


Lesenswert?

>CS dauerhaft auf low

Da hast du deinen Fehler.

von holger (Gast)


Lesenswert?

>>CS dauerhaft auf low

Laut Programm ist CS nicht dauerhaft low. Wieso schreibst du sowas?

von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

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
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

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
von Reginald L. (Firma: HEGRO GmbH) (reggie)


Lesenswert?

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
Noch kein Account? Hier anmelden.