Forum: Mikrocontroller und Digitale Elektronik STM32 ISP Flash S25FL256S Problem


von Berger (Gast)


Lesenswert?

Hallo,

ich habe ein Problem mit dem Flash Speicher von Spansion und versuche 
schon seit Tagen das Problen zu lösen, komme aber irgendwie nicht 
weiter.
Der Befehl read ID (90h) wird hier mit der Funktion 
S25FL256S_ReadID(void) ausgeführt und sollte 01 18 hex liefert. dieser 
liefert aber Werte wie 01 FF oder 18 FF. Wenn ich einfach mal 4 statt 2 
Bytes lese, dann haben die letzten beiden Bytes die richtigen Werte.
Aufgefallen ist mir das wenn ich die zweite Funktion read Status 
Register-1 aufrufe, hatte diese dann den Wert 01 18 geliefert, also die 
Werte vom ersten Befehl. Im Datenblatt steht das der Befehl zwei bytes 
liefern sollte.

Ich sehe wahrscheinlich den Walt vor lauter Bäume nicht.
Hat jemand einen Tip wie das Problem gelöst bekomme?
1
// Chip Select für externen Speicher
2
#define S25FL256S_ChipSelect()        GPIO_ResetBits(S25FL_PORT, S25FL_CS_PIN)
3
// Chip Deselect für externen Speicher
4
#define S25FL256S_ChipDeselect()      GPIO_SetBits(S25FL_PORT, S25FL_CS_PIN) 
5
6
void S25FL_Configuration()
7
{
8
9
  GPIO_InitTypeDef GPIO_InitStructure;
10
  SPI_InitTypeDef SPI_InitStructure;
11
12
  // RCC Konfiguration
13
  //------------------------------------------------------------------------------------
14
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1, ENABLE);
15
16
  // Konfiguriert den Not CS Pin als Ausgang
17
  //------------------------------------------------------------------------------------
18
  GPIO_InitStructure.GPIO_Pin   = S25FL_CS_PIN;
19
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
20
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
21
  GPIO_Init(S25FL_PORT, &GPIO_InitStructure);
22
  
23
  // Konfiguriert die SPI Pins
24
  //------------------------------------------------------------------------------------
25
  GPIO_InitStructure.GPIO_Pin = S25FL_SCK_PIN | S25FL_SO_PIN | S25FL_SI_PIN;
26
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
27
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
28
  GPIO_Init(S25FL_PORT, &GPIO_InitStructure);
29
30
  // SPI Master Konfiguration
31
  //------------------------------------------------------------------------------------
32
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
33
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
34
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
35
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI_CPOL_High, SPI_CPOL_Low
36
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // SPI_CPHA_1Edge, SPI_CPHA_2Edge
37
  SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft; // SPI_NSS_Soft, SPI_NSS_Hard
38
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;//SPI_BaudRatePrescaler_128;//SPI_BaudRatePrescaler_16;// 72M / 64 = 1.125M 
39
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
40
  SPI_InitStructure.SPI_CRCPolynomial = 7;
41
42
  SPI_I2S_DeInit(S25FL_SPI);
43
  SPI_Init(S25FL_SPI, &SPI_InitStructure);
44
45
  // Enable SPI_MASTER 
46
  SPI_Cmd(S25FL_SPI, ENABLE);
47
  SPI_CalculateCRC(S25FL_SPI, DISABLE);
48
}
49
50
51
u8 S25FL256S_FlashRead(u8 command, u32 address, u8* buffer, int number_Of_Read_Bytes)
52
{
53
  u8 status = TRUE;
54
  int data_cycle;
55
  
56
  // Sendet den Befehl
57
  while(SPI_I2S_GetFlagStatus(S25FL_SPI, SPI_I2S_FLAG_TXE) == RESET); // Wartet bis der TX-Puffer leer ist.  
58
  SPI_I2S_SendData(S25FL_SPI, command); // Sendet das Byte.
59
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
60
61
  // Sendet die Adresse
62
  if(address != ADDRESS_NOT_USED)
63
  {    
64
    while(SPI_I2S_GetFlagStatus(S25FL_SPI, SPI_I2S_FLAG_TXE) == RESET); // Wartet bis der TX-Puffer leer ist.  
65
    SPI_I2S_SendData(S25FL_SPI, (u8)((address >> 16) & 0x000000FF)); // Sendet das Byte.     
66
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
67
    
68
    while(SPI_I2S_GetFlagStatus(S25FL_SPI, SPI_I2S_FLAG_TXE) == RESET); // Wartet bis der TX-Puffer leer ist.  
69
    SPI_I2S_SendData(S25FL_SPI, (u8)((address >> 8) & 0x000000FF)); // Sendet das Byte.
70
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
71
72
    while(SPI_I2S_GetFlagStatus(S25FL_SPI, SPI_I2S_FLAG_TXE) == RESET); // Wartet bis der TX-Puffer leer ist.  
73
    SPI_I2S_SendData(S25FL_SPI, (u8)(address & 0x000000FF)); // Sendet das Byte.
74
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
75
  }
76
77
  if(number_Of_Read_Bytes != 0)
78
  {         
79
    for(data_cycle = 0; data_cycle < number_Of_Read_Bytes; data_cycle++)
80
    {     
81
      while( (S25FL_SPI->SR & SPI_I2S_FLAG_TXE) == RESET); // Wartet bis der TX-Puffer leer ist.  
82
      SPI_I2S_SendData(S25FL_SPI, 0);
83
             
84
      while(SPI_I2S_GetFlagStatus(S25FL_SPI, SPI_I2S_FLAG_RXNE) == RESET);
85
      *(buffer + data_cycle) = (u8)SPI_I2S_ReceiveData(S25FL_SPI);
86
    }
87
  }
88
89
  return status;
90
}
91
92
void S25FL256S_Wait(u32 ticks)
93
{
94
  while(ticks)
95
  {
96
    ticks--;
97
    __NOP();
98
  }
99
}
100
101
u16 S25FL256S_ReadID(void)
102
{
103
  u32 returnValue;
104
105
  S25FL256S_ChipSelect();
106
107
  // Wenn ich hier vier Bytes lade, liefert ist returnValue 0 x 01 18 18 FF
108
  // die zuletzt gelesenen Bytes 01 18 haben die richtigen Werte.
109
  // S25FL256S_FlashRead(S25FL256S_CMD_READ_ID, 0x000000, (u8*)&returnValue, 4);    
110
111
  // Read Identification - REMS (Read_ID or REMS 90h)
112
  S25FL256S_FlashRead(S25FL256S_CMD_READ_ID, 0x000000, (u8*)&returnValue, 2); // Soll 0x 01 18 liefert
113
114
  S25FL256S_Wait(0x0F);  
115
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
116
  S25FL256S_ChipDeselect();  
117
118
  return (u16)(returnValue & 0x0000ffff);
119
}
120
121
u16 S25FL256S_ReadStatusReg1(void)
122
{
123
  u16 returnValue;
124
125
  S25FL256S_ChipSelect();
126
  S25FL256S_Wait(0x0F);
127
128
  S25FL256S_FlashRead(S25FL256S_CMD_READ_STATUS_REG1, ADDRESS_NOT_USED, (u8*)&returnValue, 2);  
129
130
  S25FL256S_Wait(0x0F);  
131
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
132
  S25FL256S_ChipDeselect();  
133
134
  return returnValue;
135
}
136
137
// ---------------------------------------
138
139
int main(void)
140
{ 
141
  u16 a, b;
142
143
  InitializeProgram();
144
  S25FL_Configuration();
145
146
  while(1)
147
  {
148
    a = S25FL256S_ReadID();    
149
    b = S25FL256S_ReadStatusReg1();
150
151
    S25FL256S_Wait(0xffff);
152
  }
153
}

von Berger (Gast)


Lesenswert?

Noch eine Anmerkung, in der Funktion S25FL256S_ReadStatusReg1(void) wird 
normalerweise nur ein Byte gelesen.

von Berger (Gast)


Lesenswert?

Kleiner Tippfehler es ist natürlich die SPI-Schnittstelle.

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

Hast Du schon mal versucht, den "S25FL_SI_PIN" als Eingang zu 
konfigurieren? Ich könnte auch den Pin "S25FL_SO_PIN" meinen, keine 
Ahnung, wie die definiert sind. Oder habe ich was übersehen?
1
  // Konfiguriert die SPI Pins
2
  //------------------------------------------------------------------------------------
3
  GPIO_InitStructure.GPIO_Pin = S25FL_SCK_PIN | S25FL_SO_PIN/* | S25FL_SI_PIN*/;
4
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
5
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
6
  GPIO_Init(S25FL_PORT, &GPIO_InitStructure);
7
8
  GPIO_InitStructure.GPIO_Pin = S25FL_SI_PIN;
9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // oder meinetwegen GPIO_Mode_IPU, GPIO_Mode_IPD
11
  GPIO_Init(S25FL_PORT, &GPIO_InitStructure);

mfg

von Berger (Gast)


Lesenswert?

@ ** Lötlackl (pappnase)
Nein, das wäre nur nötig wenn man ein Software SPI machen würde. Ich 
benutze den Hardware gesteuerten SPI. Bei der Hardware Variante muß man 
die Pins mit GPIO_Mode_AF_PP konfigurieren, der Mikrokontroller steuert 
dann die PIN automatisch.
1
GPIO_InitStructure.GPIO_Pin = S25FL_SCK_PIN | S25FL_SO_PIN | S25FL_SI_PIN;
2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
4
GPIO_Init(S25FL_PORT, &GPIO_InitStructure);

Ich habe aber mitlerweile das Problem lösen können. immer wenn Ich Daten 
sende, empfängt der MC Datenschrott, also die unerwünschten FF Bytes.
Gelöst habe Ich das in dem Ich für RX den Interrupt benutze, dieser 
filtert dann den Datenschrott raus.

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.