Forum: Mikrocontroller und Digitale Elektronik SD Card mit RL-FlashFS über SPI ansprechen (STM32F2)


von Mathias S. (stucmath)


Lesenswert?

Hallo zusammen

Ich möchte momentan mit einem STM32F207IG Board 
(http://www.keil.com/mcbstm32f200/) über das RL-FlashFS eine SD-Card 
ansprechen.
Mit dem Beispielprojekt funktioniert dies wunderbar.
Jedoch muss bei meinem Projekt die SD Card mittels SPI angesteuert 
werden.
Deshalb musste ich den SPI Treiber (SPI_STM32F1xx) auf den F2 anpassen.
Und genau dieses Vorhaben klappt momentan nicht.

Ich hoffe jemand von euch hat genau dies bereits realisiert und kann mir 
ein wenig Unterstützung liefern.

Danke im voraus.

Hier der angepasste SPI Treiber:
1
/*----------------------------------------------------------------------------
2
 *      RL-ARM - FlashFS
3
 *----------------------------------------------------------------------------
4
 *      Name:    SPI_STM32F107.c
5
 *      Purpose: Serial Peripheral Interface Driver for ST STM32F105/7
6
 *      Rev.:    V4.20
7
 *----------------------------------------------------------------------------
8
 *      This code is part of the RealView Run-Time Library.
9
 *      Copyright (c) 2004-2011 KEIL - An ARM Company. All rights reserved.
10
 *---------------------------------------------------------------------------*/
11
 
12
#include <stdio.h>
13
#include <File_Config.h>
14
#include "stm32f2xx.h"                /* STM32F2 Library Definitions */
15
16
17
/*----------------------------------------------------------------------------
18
  SPI Driver instance definition
19
   spi0_drv: First SPI driver
20
   spi1_drv: Second SPI driver
21
 *---------------------------------------------------------------------------*/
22
23
#define __DRV_ID  spi0_drv
24
#define __FPCLK    72000000  
25
26
/* SPI Driver Interface functions */
27
static BOOL Init (void);
28
static BOOL UnInit (void);
29
static U8   Send (U8 outb);
30
static BOOL SendBuf (U8 *buf, U32 sz);
31
static BOOL RecBuf (U8 *buf, U32 sz);
32
static BOOL BusSpeed (U32 kbaud);
33
static BOOL SetSS (U32 ss);
34
static U32  CheckMedia (void);        /* Optional function for SD card check */
35
36
/* SPI Device Driver Control Block */
37
SPI_DRV __DRV_ID = {
38
  Init,
39
  UnInit,
40
  Send,
41
  SendBuf,
42
  RecBuf,
43
  BusSpeed,
44
  SetSS,
45
  CheckMedia                          /* Can be NULL if not existing         */
46
};
47
48
49
#define SPIx   SPI1
50
51
52
/* SPI_SR - bit definitions. */
53
#define RXNE    0x01
54
#define TXE     0x02
55
#define BSY     0x80
56
#define FPCLK   __FPCLK/1000
57
58
59
/*--------------------------- spi_init --------------------------------------*/
60
61
static BOOL Init (void) 
62
{
63
    GPIO_InitTypeDef GPIO_InitStructure;
64
  SPI_InitTypeDef SPI_InitStructure;
65
  
66
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
67
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 
68
69
  // Card Sensor PA.8 input 
70
    // 1 = NO Card, 0 = Card plugged.
71
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
72
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
73
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
74
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
75
  GPIO_Init(GPIOA, &GPIO_InitStructure);
76
77
  // Card Locked PB.0 input 
78
    // 1 = Card locked, 0 = Card unlocked.
79
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
80
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
81
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
82
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
83
  GPIO_Init(GPIOB, &GPIO_InitStructure);
84
85
86
  // Configure SPI as alternate function     
87
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;          
88
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
89
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
90
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;          
91
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
92
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
93
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;          
94
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    
95
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
96
97
  // Map the USART1 alternate function
98
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
99
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
100
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
101
102
  // Configure PA4 (/CS) as output
103
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
104
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
105
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
106
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
107
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
108
  GPIO_Init(GPIOA, &GPIO_InitStructure);    
109
110
111
112
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
113
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
114
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
115
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
116
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
117
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
118
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
119
  SPI_Init(SPI1,&SPI_InitStructure);
120
  SPI_Cmd(SPI1, ENABLE);  
121
  return (__TRUE);  
122
}
123
124
125
/*--------------------------- UnInit ----------------------------------------*/
126
127
static BOOL UnInit (void) 
128
{
129
  /* Return SSP interface to default state. */
130
  /*
131
  GPIOA->CRL = (GPIOA->CRL & 0x0000FFFF) | 0x44440000;
132
133
  
134
  GPIOE->ODR &= ~0x01; 
135
  GPIOE->CRL  = (GPIOE->CRL & 0xFFFFFFF0) | 0x00000004;
136
  
137
  SPIx->CR1  = 0x0000;
138
  SPIx->CR2  = 0x0000;    
139
    */
140
  return (__TRUE);  
141
}  
142
143
144
145
/*--------------------------- Send ------------------------------------------*/
146
147
static U8 Send (U8 outb) {
148
  /* Write and Read a byte on SPI interface. */
149
150
  SPIx->DR = outb;   
151
  /* Wait if RNE cleared, Rx FIFO is empty. */
152
  while (!(SPIx->SR & RXNE));
153
  return (SPIx->DR);
154
}
155
156
157
/*--------------------------- SendBuf ---------------------------------------*/
158
159
static BOOL SendBuf (U8 *buf, U32 sz) {
160
  /* Send buffer to SPI interface. */
161
  U32 i;                       
162
163
  for (i = 0; i < sz; i++) {    
164
    SPIx->DR = buf[i];
165
  /* Wait if TXE cleared, Tx FIFO is full. */
166
    while (!(SPIx->SR & TXE));
167
    
168
    SPIx->DR;
169
  }
170
  /* Wait until Tx finished, drain Rx FIFO. */
171
  while (SPIx->SR & (BSY | RXNE)) {
172
    SPIx->DR;
173
  }
174
  return (__TRUE);               
175
}
176
177
178
/*--------------------------- RecBuf ----------------------------------------*/
179
180
static BOOL RecBuf (U8 *buf, U32 sz) {
181
  /* Receive SPI data to buffer. */
182
  U32 i;
183
184
  for (i = 0; i < sz; i++) {
185
    SPIx->DR = 0xFF;
186
    /* Wait if RNE cleared, Rx FIFO is empty. */
187
    while (!(SPIx->SR & RXNE));
188
    buf[i] = SPIx->DR;
189
  }
190
  return (__TRUE);
191
}
192
193
194
/*--------------------------- BusSpeed --------------------------------------*/
195
196
static BOOL BusSpeed (U32 kbaud) {
197
  /* Set an SPI clock to required baud rate. */
198
  U8  br;
199
200
  if      (kbaud >= FPCLK / 2)   br = 0;                       /* FPCLK/2    */
201
  else if (kbaud >= FPCLK / 4)   br = 1;                       /* FPCLK/4    */
202
  else if (kbaud >= FPCLK / 8)   br = 2;                       /* FPCLK/8    */
203
  else if (kbaud >= FPCLK / 16)  br = 3;                       /* FPCLK/16   */
204
  else if (kbaud >= FPCLK / 32)  br = 4;                       /* FPCLK/32   */
205
  else if (kbaud >= FPCLK / 64)  br = 5;                       /* FPCLK/64   */
206
  else if (kbaud >= FPCLK / 128) br = 6;                       /* FPCLK/128  */
207
  else                           br = 7;                       /* FPCLK/256  */
208
209
  SPIx->CR1 = (SPIx->CR1 & ~(7 << 3)) | (br << 3); 
210
  
211
  return (__TRUE);
212
}
213
214
215
/*--------------------------- SetSS -----------------------------------------*/
216
217
static BOOL SetSS (U32 ss) {
218
  /* Enable/Disable SPI Chip Select (drive it high or low). */
219
  if (ss) 
220
  {
221
    printf ("High\n");
222
    GPIO_SetBits (GPIOA, GPIO_Pin_4);             /* SSEL is GPIO, output set to high. */
223
  }
224
  else 
225
  {
226
    printf ("Low\n");
227
    GPIO_ResetBits (GPIOA, GPIO_Pin_4);           /* SSEL is GPIO, output set to low. */
228
  }
229
  return (__TRUE);
230
}
231
232
233
/*--------------------------- CheckMedia ------------------------------------*/
234
235
static U32 CheckMedia (void) {
236
  /* Read CardDetect and WriteProtect SD card socket pins. */
237
  U32 stat = 0;
238
 
239
  if (!GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)) 
240
  {
241
    printf("Card inserted\n");
242
    /* Card is inserted (CD=0). */
243
    stat |= M_INSERTED;
244
  }
245
#if 0
246
  if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)) 
247
  {
248
    printf("Card locked\n");
249
    /* Write Protect switch is active (WP=1). */
250
    stat |= M_PROTECTED;
251
  }
252
#endif
253
  return (stat);
254
}
255
256
/*----------------------------------------------------------------------------
257
 * end of file
258
 *---------------------------------------------------------------------------*/

von holger (Gast)


Lesenswert?

Probier das mal so:
1
/*--------------------------- SendBuf ---------------------------------------*/
2
3
static BOOL SendBuf (U8 *buf, U32 sz) {
4
  /* Send buffer to SPI interface. */
5
  U32 i;                       
6
7
  for (i = 0; i < sz; i++) {    
8
    SPIx->DR = buf[i];
9
    while (!(SPIx->SR & RXNE));
10
    SPIx->DR;
11
  }
12
 
13
 return (__TRUE);               
14
}

von Mathias S. (stucmath)


Lesenswert?

Danke für die schnelle Antwort.

Dies hat leider mein Problem nicht gelöst.
Ist das SPI Init in meinem Code korrekt?
Hat vielleicht sonst noch jemand eine Idee
Bin dankbar für jede Hilfestellung.

Gruss

von Archie F. (archie)


Lesenswert?

Schaue dir die SPI Ansteuerung von der F1 Serie an, dürfte sich nicht 
viel geändert haben.
http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html#chanfat_stm32

von holger (Gast)


Lesenswert?

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);


Wo wird RCC für GPIOA freigeschaltet?

von Mathias S. (stucmath)


Lesenswert?

Vielen Dank für die Unterstützung.

GPIOA wurde immer hier freigeschaltet:
1
void RCC_Configuration(void)
2
{  
3
    /* Enable clocks */      
4
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
5
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
6
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 
7
}

Habe nun alles wieder dort hinein gepackt.

Ohne Erfolg.

von Mathias S. (stucmath)


Lesenswert?

1
#define __FPCLK    72000000

Müsste das nicht
1
 #define __FPCLK    120000000
 sein?

Aber somit wäre der Clock beim SD Init über 400khz oder nicht?

Was meint ihr dazu?

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.