Forum: Mikrocontroller und Digitale Elektronik SD Karte via SPI. Komisches Verhalten.


von Franz (Gast)


Lesenswert?

Hallo!

Ich weiß es gibt schon genug Threads bzgl. SD Karten, nur habe ich 
nichts gefunden was mir bei meinem Problem helfen würde: Ich habe an 
mein STM32F4 Discovery Board ein SD-Karten Breakout Board via SPI nach 
der allgemein Bekannten Vorgangsweise angeschlossen: 
[[http://elm-chan.org/docs/mmc/mmc_e.html]]

Dazu habe ich eines der Beispiele hergenommen und auf den STM32 
portiert. Im Prinzip funktioniert das auch wunderbar. Ich kann Daten von 
der SD-Karte einlesen und daten darauf schreiben. Jetzt zum eigentlichen 
Problem: Ich habe das ganze mit 5 Karten verschiedener Größe (256Mb - 
4Gb) getestet. Es funktioniert mit allen karten wunderbar, nur bei der 
Karte mit 256Mb zeigt sich folgendes Verhalten: Die Karte wird 
prinzipiell erkannt, also disk_initialize() gibt keinen Fehler zurück, 
nur kann ich weder Daten von der Karte lesen noch Daten darauf 
schreiben. Beim Schreiben kommt nicht mal ein Fehler zurück, jedoch 
werden die Daten nicht geschrieben. Die Karte funktioniert sonst 
einwandfrei, mit dem USB-Kartenleser funktionierts.

Eigentlich hätte ich mir beim disk_initialize() einen Fehler erwartet, 
so wies bei den meisten der Fall ist, wenn die Karte nicht funktioniert.

Hat vlt. irgendwer eine Idee was hier das Problem sein könnte?

Lg,
Franz

von asdf (Gast)


Lesenswert?

Zum Debuggen könntest du einen Logic Analyzer ans SPI hängen und genauer 
schauen was da passiert.

von Jim M. (turboj)


Lesenswert?

Franz schrieb:
> Beim Schreiben kommt nicht mal ein Fehler zurück, jedoch
> werden die Daten nicht geschrieben. Die Karte funktioniert sonst
> einwandfrei, mit dem USB-Kartenleser funktionierts.

Sind die Daten auch noch da, wenn Du die Karte aus dem Lesegerät 
entnommen und wieder eingesteckt hast?

von holger (Gast)


Lesenswert?

SPI zu schnell?

von Franz (Gast)


Lesenswert?

Hallo!

Danke erstmal für die Antworten!

@asdf:
Logicanalyzer hab ich leider keinen, nur ein Oszi und damit ist es 
leider nicht so leicht die gesamte Kommunikation zu analysieren.

Jim Meba schrieb:
> Franz schrieb:
>> Beim Schreiben kommt nicht mal ein Fehler zurück, jedoch
>> werden die Daten nicht geschrieben. Die Karte funktioniert sonst
>> einwandfrei, mit dem USB-Kartenleser funktionierts.
>
> Sind die Daten auch noch da, wenn Du die Karte aus dem Lesegerät
> entnommen und wieder eingesteckt hast?

Ja die Daten sind dann auch noch da. Das habe ich natürlich getestet. 
Ich habe die Karte auch nicht anders formatiert. Alle sind FAT16 
formatiert.

holger schrieb:
> SPI zu schnell?
Die Baudrate ist auf ca. 164Khz eingestellt, diese wird in meinem Code 
auch nicht erhöht nach der Initialisierung. SD Karten sollten ja mehrere 
MHz vertragen, das sollte also nicht das Problem sein.

Im Prinzip wäre es mir ja egal, da ich ja des öfteren davon gehört habe, 
dass manche SD-Karten einfach nicht funktionieren. Nur lässt sich bei 
diesen Fällen die Karte erst gar nicht initialisieren, was bei mir aber 
einwandfrei funktioniert.

Sonst noch ideen?

Lg,
Franz


PS: Werde euch später noch den Code hochladen, vlt sieht ja da gleich 
jmd einen Fehler.

von Franz (Gast)


Lesenswert?

Hallo!

Hier die SPI-initialisierung
1
void SPI_Configuration(void)
2
{
3
  SPI_InitTypeDef  SPI_InitStructure;
4
5
  /* SPI configuration -------------------------------------------------------*/
6
  SPI_I2S_DeInit(SPI2);
7
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
8
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
9
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
10
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
11
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
12
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
13
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
14
  SPI_InitStructure.SPI_CRCPolynomial = 7;
15
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
16
17
  SPI_Init(SPI2, &SPI_InitStructure);
18
  SPI_CalculateCRC(SPI2, DISABLE);
19
  /* Enable the SPI peripheral */
20
  SPI_Cmd(SPI2, ENABLE);
21
}


Und hier die funktionen in diskio.c:
1
/*
2
 * low_level_functions.c
3
 *
4
 *  Created on: Jul 12, 2013
5
 *      Author: franz
6
 */
7
8
#include <stm32f4xx.h>
9
#include <stm32_configuration.h>
10
#include <diskio.h>
11
#include <helperFunctions.h>
12
13
/*-----------------------------------------------------------------------*/
14
/* MMCv3/SDv1/SDv2 (in SPI mode) control module  (C)ChaN, 2010           */
15
/*-----------------------------------------------------------------------*/
16
17
18
#define CS_HIGH()  {GPIO_SetBits(GPIOB, GPIO_Pin_12); Delay(10);}
19
#define CS_LOW()  {GPIO_ResetBits(GPIOB, GPIO_Pin_12);Delay(10);}
20
21
#define FCLK_SLOW() ;
22
#define FCLK_FAST() ;
23
24
25
/**
26
 * @brief  Detect if SD card is correctly plugged in the memory slot.
27
 * @param  None
28
 * @retval Return if SD is detected or not
29
 */
30
uint8_t SD_Detect(void)
31
{
32
  __IO uint8_t status = SD_PRESENT;
33
34
  /*!< Check GPIO to detect SD */
35
  if (GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != Bit_RESET)
36
  {
37
    status = SD_NOT_PRESENT;
38
  }
39
  return status;
40
}
41
42
43
/*--------------------------------------------------------------------------
44
45
   Module Private Functions
46
47
---------------------------------------------------------------------------*/
48
49
/* Definitions for MMC/SDC command */
50
#define CMD0  (0)      /* GO_IDLE_STATE */
51
#define CMD1  (1)      /* SEND_OP_COND (MMC) */
52
#define  ACMD41  (0x80+41)  /* SEND_OP_COND (SDC) */
53
#define CMD8  (8)      /* SEND_IF_COND */
54
#define CMD9  (9)      /* SEND_CSD */
55
#define CMD10  (10)    /* SEND_CID */
56
#define CMD12  (12)    /* STOP_TRANSMISSION */
57
#define ACMD13  (0x80+13)  /* SD_STATUS (SDC) */
58
#define CMD16  (16)    /* SET_BLOCKLEN */
59
#define CMD17  (17)    /* READ_SINGLE_BLOCK */
60
#define CMD18  (18)    /* READ_MULTIPLE_BLOCK */
61
#define CMD23  (23)    /* SET_BLOCK_COUNT (MMC) */
62
#define  ACMD23  (0x80+23)  /* SET_WR_BLK_ERASE_COUNT (SDC) */
63
#define CMD24  (24)    /* WRITE_BLOCK */
64
#define CMD25  (25)    /* WRITE_MULTIPLE_BLOCK */
65
#define CMD32  (32)    /* ERASE_ER_BLK_START */
66
#define CMD33  (33)    /* ERASE_ER_BLK_END */
67
#define CMD38  (38)    /* ERASE */
68
#define CMD55  (55)    /* APP_CMD */
69
#define CMD58  (58)    /* READ_OCR */
70
71
72
static volatile
73
DSTATUS Stat = STA_NOINIT;  /* Disk status */
74
75
static volatile
76
BYTE Timer1, Timer2;  /* 100Hz decrement timer */
77
78
static
79
BYTE CardType;      /* Card type flags */
80
81
82
/*-----------------------------------------------------------------------*/
83
/* Power Control  (Platform dependent)                                   */
84
/*-----------------------------------------------------------------------*/
85
/* When the target system does not support socket power control, there   */
86
/* is nothing to do in these functions and chk_power always returns 1.   */
87
88
static
89
int power_status (void)    /* Socket power state: 0=off, 1=on */
90
{
91
  return 1;
92
}
93
94
static
95
void power_on (void)
96
{
97
  /*Nothing to do here, hardware initialization is already done*/
98
  return;
99
}
100
101
static
102
void power_off (void)
103
{
104
  /* We do not turn power off*/
105
  return;
106
}
107
108
109
110
/*-----------------------------------------------------------------------*/
111
/* Transmit/Receive data from/to MMC via SPI  (Platform dependent)       */
112
/*-----------------------------------------------------------------------*/
113
114
/* Exchange a byte */
115
static
116
BYTE xchg_spi (    /* Returns received data */
117
  BYTE dat    /* Data to be sent */
118
)
119
{
120
    /* Loop while DR register in not empty */
121
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
122
    {
123
    }
124
125
    /* Send a Byte through the SPI peripheral */
126
    SPI_I2S_SendData(SPI2, dat);
127
128
    /* Wait to receive a Byte */
129
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
130
    {
131
    }
132
133
    /* Return the Byte read from the SPI bus */
134
    return (uint8_t)SPI_I2S_ReceiveData(SPI2);
135
}
136
137
138
/*-----------------------------------------------------------------------*/
139
/* Wait for card ready                                                   */
140
/*-----------------------------------------------------------------------*/
141
142
static
143
int wait_ready (  /* 1:Ready, 0:Timeout */
144
  UINT wt      /* Timeout [ms] */
145
)
146
{
147
  BYTE d;
148
149
150
  Timer2 = wt / 10;
151
  do
152
    d = xchg_spi(0xFF);
153
  while (d != 0xFF && Timer2);
154
155
  return (d == 0xFF) ? 1 : 0;
156
}
157
158
159
160
/*-----------------------------------------------------------------------*/
161
/* Deselect the card and release SPI bus                                 */
162
/*-----------------------------------------------------------------------*/
163
164
static
165
void deselect (void)
166
{
167
  CS_HIGH();
168
  xchg_spi(0xFF);  /* Dummy clock (force DO hi-z for multiple slave SPI) */
169
}
170
171
172
173
/*-----------------------------------------------------------------------*/
174
/* Select the card and wait for ready                                    */
175
/*-----------------------------------------------------------------------*/
176
177
static
178
int select (void)  /* 1:Successful, 0:Timeout */
179
{
180
  CS_LOW();
181
  xchg_spi(0xFF);  /* Dummy clock (force DO enabled) */
182
183
  if (wait_ready(500)) return 1;  /* OK */
184
  deselect();
185
  return 0;  /* Timeout */
186
}
187
188
189
190
/*-----------------------------------------------------------------------*/
191
/* Receive a data packet from MMC                                        */
192
/*-----------------------------------------------------------------------*/
193
194
static
195
int rcvr_datablock (
196
  BYTE *buff,      /* Data buffer to store received data */
197
  UINT btr      /* Byte count (must be multiple of 4) */
198
)
199
{
200
  BYTE token;
201
202
203
  Timer1 = 20;
204
  do {              /* Wait for data packet in timeout of 200ms */
205
    token = xchg_spi(0xFF);
206
  } while ((token == 0xFF) && Timer1);
207
  if (token != 0xFE) return 0;  /* If not valid data token, retutn with error */
208
209
  do
210
  {
211
    *buff++ =xchg_spi(0xFF);
212
    *buff++ =xchg_spi(0xFF);
213
  }while(btr -= 2);
214
  xchg_spi(0xFF);          /* Discard CRC */
215
  xchg_spi(0xFF);
216
217
  return 1;            /* Return with success */
218
}
219
220
221
222
/*-----------------------------------------------------------------------*/
223
/* Send a data packet to MMC                                             */
224
/*-----------------------------------------------------------------------*/
225
226
#if  _USE_WRITE
227
static
228
int xmit_datablock (
229
  const BYTE *buff,  /* 512 byte data block to be transmitted */
230
  BYTE token      /* Data/Stop token */
231
)
232
{
233
  BYTE resp;
234
  uint16_t wc;
235
236
  if (!wait_ready(500)) return 0;
237
238
  xchg_spi(token);          /* Xmit data token */
239
  if (token != 0xFD) {  /* Is data token */
240
    wc = 512;
241
    do {              /* transmit the 512 byte data block to MMC */
242
      xchg_spi(*buff++);
243
      xchg_spi(*buff++);
244
    } while (wc-=2);
245
    xchg_spi(0xFF);          /* CRC (Dummy) */
246
    xchg_spi(0xFF);
247
    resp = xchg_spi(0xFF);      /* Reveive data response */
248
    //debug(USART2, "xchg_spi: %d", resp);
249
    if ((resp & 0x1F) != 0x05)    /* If not accepted, return with error */
250
      return 0;
251
  }
252
253
  return 1;
254
}
255
#endif
256
257
258
259
/*-----------------------------------------------------------------------*/
260
/* Send a command packet to MMC                                          */
261
/*-----------------------------------------------------------------------*/
262
263
static
264
BYTE send_cmd (    /* Returns R1 resp (bit7==1:Send failed) */
265
  BYTE cmd,    /* Command index */
266
  DWORD arg    /* Argument */
267
)
268
{
269
  BYTE n, res;
270
271
272
  if (cmd & 0x80) {  /* ACMD<n> is the command sequense of CMD55-CMD<n> */
273
    cmd &= 0x7F;
274
    res = send_cmd(CMD55, 0);
275
    if (res > 1) return res;
276
  }
277
278
  /* Select the card and wait for ready */
279
  deselect();
280
  if (!select()) return 0xFF;
281
282
  /* Send command packet */
283
  xchg_spi(0x40 | cmd);        /* Start + Command index */
284
  xchg_spi((BYTE)(arg >> 24));    /* Argument[31..24] */
285
  xchg_spi((BYTE)(arg >> 16));    /* Argument[23..16] */
286
  xchg_spi((BYTE)(arg >> 8));      /* Argument[15..8] */
287
  xchg_spi((BYTE)arg);        /* Argument[7..0] */
288
  n = 0x01;              /* Dummy CRC + Stop */
289
  if (cmd == CMD0) n = 0x95;      /* Valid CRC for CMD0(0) + Stop */
290
  if (cmd == CMD8) n = 0x87;      /* Valid CRC for CMD8(0x1AA) Stop */
291
  xchg_spi(n);
292
293
  /* Receive command response */
294
  if (cmd == CMD12) xchg_spi(0xFF);    /* Skip a stuff byte when stop reading */
295
  n = 10;                /* Wait for a valid response in timeout of 10 attempts */
296
  do
297
    res = xchg_spi(0xFF);
298
  while ((res & 0x80) && --n);
299
300
  return res;      /* Return with the response value */
301
}
302
303
304
305
/*--------------------------------------------------------------------------
306
307
   Public Functions
308
309
---------------------------------------------------------------------------*/
310
311
312
/*-----------------------------------------------------------------------*/
313
/* Initialize Disk Drive                                                 */
314
/*-----------------------------------------------------------------------*/
315
316
DSTATUS disk_initialize (
317
  BYTE pdrv    /* Physical drive nmuber (0) */
318
)
319
{
320
  BYTE n, cmd, ty, ocr[4];
321
322
323
  if (pdrv) return STA_NOINIT;    /* Supports only single drive */
324
  power_off();            /* Turn off the socket power to reset the card */
325
  if (Stat & STA_NODISK) return Stat;  /* No card in the socket */
326
  power_on();              /* Turn on the socket power */
327
  FCLK_SLOW();
328
  for (n = 10; n; n--) xchg_spi(0xFF);  /* 80 dummy clocks */
329
330
  ty = 0;
331
  if (send_cmd(CMD0, 0) == 1) {      /* Enter Idle state */
332
    Timer1 = 100;            /* Initialization timeout of 1000 msec */
333
    if (send_cmd(CMD8, 0x1AA) == 1) {  /* SDv2? */
334
      debug(USART2, "SDv2\n\r");
335
      for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);    /* Get trailing return value of R7 resp */
336
      if (ocr[2] == 0x01 && ocr[3] == 0xAA) {        /* The card can work at vdd range of 2.7-3.6V */
337
        while (Timer1 && send_cmd(ACMD41, 1UL << 30));  /* Wait for leaving idle state (ACMD41 with HCS bit) */
338
        if (Timer1 && send_cmd(CMD58, 0) == 0) {    /* Check CCS bit in the OCR */
339
          for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
340
          ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;  /* SDv2 */
341
        }
342
      }
343
    } else {              /* SDv1 or MMCv3 */
344
      if (send_cmd(ACMD41, 0) <= 1)   {
345
        debug(USART2, "SDv1\n\r");
346
        ty = CT_SD1; cmd = ACMD41;  /* SDv1 */
347
      } else {
348
        debug(USART2, "MMCv3\n\r");
349
        ty = CT_MMC; cmd = CMD1;  /* MMCv3 */
350
      }
351
      while (Timer1 && send_cmd(cmd, 0));      /* Wait for leaving idle state */
352
      if (!Timer1 || send_cmd(CMD16, 512) != 0)  /* Set R/W block length to 512 */
353
        ty = 0;
354
    }
355
  }
356
  CardType = ty;
357
  deselect();
358
359
  if (ty) {      /* Initialization succeded */
360
    Stat &= ~STA_NOINIT;    /* Clear STA_NOINIT */
361
    FCLK_FAST();
362
  } else {      /* Initialization failed */
363
    power_off();
364
  }
365
366
  return Stat;
367
}
368
369
370
371
/*-----------------------------------------------------------------------*/
372
/* Get Disk Status                                                       */
373
/*-----------------------------------------------------------------------*/
374
375
DSTATUS disk_status (
376
  BYTE pdrv    /* Physical drive nmuber (0) */
377
)
378
{
379
  if (pdrv) return STA_NOINIT;  /* Supports only single drive */
380
  return Stat;
381
}
382
383
384
385
/*-----------------------------------------------------------------------*/
386
/* Read Sector(s)                                                        */
387
/*-----------------------------------------------------------------------*/
388
389
DRESULT disk_read (
390
  BYTE pdrv,      /* Physical drive nmuber (0) */
391
  BYTE *buff,      /* Pointer to the data buffer to store read data */
392
  DWORD sector,    /* Start sector number (LBA) */
393
  BYTE count      /* Sector count (1..255) */
394
)
395
{
396
  if (pdrv || !count) return RES_PARERR;
397
  if (Stat & STA_NOINIT) return RES_NOTRDY;
398
399
  if (!(CardType & CT_BLOCK)) sector *= 512;  /* Convert to byte address if needed */
400
401
  if (count == 1) {  /* Single block read */
402
    if ((send_cmd(CMD17, sector) == 0)  /* READ_SINGLE_BLOCK */
403
      && rcvr_datablock(buff, 512))
404
      count = 0;
405
  }
406
  else {        /* Multiple block read */
407
    if (send_cmd(CMD18, sector) == 0) {  /* READ_MULTIPLE_BLOCK */
408
      do {
409
        if (!rcvr_datablock(buff, 512)) break;
410
        buff += 512;
411
      } while (--count);
412
      send_cmd(CMD12, 0);        /* STOP_TRANSMISSION */
413
    }
414
  }
415
  deselect();
416
417
  return count ? RES_ERROR : RES_OK;
418
}
419
420
421
422
/*-----------------------------------------------------------------------*/
423
/* Write Sector(s)                                                       */
424
/*-----------------------------------------------------------------------*/
425
426
#if _USE_WRITE
427
DRESULT disk_write (
428
  BYTE pdrv,      /* Physical drive nmuber (0) */
429
  const BYTE *buff,  /* Pointer to the data to be written */
430
  DWORD sector,    /* Start sector number (LBA) */
431
  BYTE count      /* Sector count (1..255) */
432
)
433
{
434
  if (pdrv || !count) return RES_PARERR;
435
  if (Stat & STA_NOINIT) return RES_NOTRDY;
436
  if (Stat & STA_PROTECT) return RES_WRPRT;
437
438
  if (!(CardType & CT_BLOCK)) sector *= 512;  /* Convert to byte address if needed */
439
440
  if (count == 1) {  /* Single block write */
441
    if ((send_cmd(CMD24, sector) == 0)  /* WRITE_BLOCK */
442
      && xmit_datablock(buff, 0xFE))
443
      count = 0;
444
  }
445
  else {        /* Multiple block write */
446
    if (CardType & CT_SDC) send_cmd(ACMD23, count);
447
    if (send_cmd(CMD25, sector) == 0) {  /* WRITE_MULTIPLE_BLOCK */
448
      do {
449
        if (!xmit_datablock(buff, 0xFC)) break;
450
        buff += 512;
451
      } while (--count);
452
      if (!xmit_datablock(0, 0xFD))  /* STOP_TRAN token */
453
        count = 1;
454
    }
455
  }
456
  deselect();
457
458
  return count ? RES_ERROR : RES_OK;
459
}
460
#endif
461
462
463
/*-----------------------------------------------------------------------*/
464
/* Miscellaneous Functions                                               */
465
/*-----------------------------------------------------------------------*/
466
467
#if _USE_IOCTL
468
DRESULT disk_ioctl (
469
  BYTE pdrv,    /* Physical drive nmuber (0) */
470
  BYTE cmd,    /* Control code */
471
  void *buff    /* Buffer to send/receive control data */
472
)
473
{
474
  DRESULT res;
475
  BYTE n, csd[16], *ptr = buff;
476
  DWORD *dp, st, ed, csize;
477
478
479
  if (pdrv) return RES_PARERR;
480
481
  res = RES_ERROR;
482
483
  if (cmd == CTRL_POWER) {
484
    switch (ptr[0]) {
485
    case 0:    /* Sub control code (POWER_OFF) */
486
      power_off();    /* Power off */
487
      res = RES_OK;
488
      break;
489
    case 1:    /* Sub control code (POWER_GET) */
490
      ptr[1] = (BYTE)power_status();
491
      res = RES_OK;
492
      break;
493
    default :
494
      res = RES_PARERR;
495
    }
496
  }
497
  else {
498
    if (Stat & STA_NOINIT) return RES_NOTRDY;
499
500
    switch (cmd) {
501
    case CTRL_SYNC :    /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
502
      if (select()) res = RES_OK;
503
      break;
504
505
    case GET_SECTOR_COUNT :  /* Get number of sectors on the disk (DWORD) */
506
      if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
507
        if ((csd[0] >> 6) == 1) {  /* SDC ver 2.00 */
508
          csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
509
          *(DWORD*)buff = csize << 10;
510
        } else {          /* SDC ver 1.XX or MMC*/
511
          n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
512
          csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
513
          *(DWORD*)buff = csize << (n - 9);
514
        }
515
        res = RES_OK;
516
      }
517
      break;
518
519
    case GET_BLOCK_SIZE :  /* Get erase block size in unit of sector (DWORD) */
520
      if (CardType & CT_SD2) {  /* SDv2? */
521
        if (send_cmd(ACMD13, 0) == 0) {  /* Read SD status */
522
          xchg_spi(0xFF);
523
          if (rcvr_datablock(csd, 16)) {        /* Read partial block */
524
            for (n = 64 - 16; n; n--) xchg_spi(0xFF);  /* Purge trailing data */
525
            *(DWORD*)buff = 16UL << (csd[10] >> 4);
526
            res = RES_OK;
527
          }
528
        }
529
      } else {          /* SDv1 or MMCv3 */
530
        if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {  /* Read CSD */
531
          if (CardType & CT_SD1) {  /* SDv1 */
532
            *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
533
          } else {          /* MMCv3 */
534
            *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
535
          }
536
          res = RES_OK;
537
        }
538
      }
539
      break;
540
541
    /* Following commands are never used by FatFs module */
542
543
    case MMC_GET_TYPE :    /* Get card type flags (1 byte) */
544
      *ptr = CardType;
545
      res = RES_OK;
546
      break;
547
548
    case MMC_GET_CSD :    /* Receive CSD as a data block (16 bytes) */
549
      if (send_cmd(CMD9, 0) == 0    /* READ_CSD */
550
        && rcvr_datablock(ptr, 16))
551
        res = RES_OK;
552
      break;
553
554
    case MMC_GET_CID :    /* Receive CID as a data block (16 bytes) */
555
      if (send_cmd(CMD10, 0) == 0    /* READ_CID */
556
        && rcvr_datablock(ptr, 16))
557
        res = RES_OK;
558
      break;
559
560
    case MMC_GET_OCR :    /* Receive OCR as an R3 resp (4 bytes) */
561
      if (send_cmd(CMD58, 0) == 0) {  /* READ_OCR */
562
        for (n = 4; n; n--) *ptr++ = xchg_spi(0xFF);
563
        res = RES_OK;
564
      }
565
      break;
566
567
    case MMC_GET_SDSTAT :  /* Receive SD statsu as a data block (64 bytes) */
568
      if (send_cmd(ACMD13, 0) == 0) {  /* SD_STATUS */
569
        xchg_spi(0xFF);
570
        if (rcvr_datablock(ptr, 64))
571
          res = RES_OK;
572
      }
573
      break;
574
575
    default:
576
      res = RES_PARERR;
577
    }
578
579
    deselect();
580
  }
581
582
  return res;
583
}
584
#endif
585
586
587
/*-----------------------------------------------------------------------*/
588
/* Device Timer Interrupt Procedure                                      */
589
/*-----------------------------------------------------------------------*/
590
/* This function must be called in period of 10ms                        */
591
592
void disk_timerproc (void)
593
{
594
  BYTE n, s;
595
596
597
  n = Timer1;        /* 100Hz decrement timer */
598
  if (n) Timer1 = --n;
599
  n = Timer2;
600
  if (n) Timer2 = --n;
601
602
  s = Stat;
603
604
//  if (SOCKWP)        /* Write protected */
605
//    s |= STA_PROTECT;
606
//  else          /* Write enabled */
607
//    s &= ~STA_PROTECT;
608
609
  if (SD_Detect() == SD_PRESENT)      /* Card inserted */
610
    s &= ~STA_NODISK;
611
  else          /* Socket empty */
612
    s |= (STA_NODISK | STA_NOINIT);
613
614
  Stat = s;        /* Update MMC status */
615
}
616
617
618
DWORD get_fattime(void)
619
{
620
  return 0;
621
}


Vlt fällt ja jemanden was auf. Danke.

Lg
Franz

von Franz (Gast)


Lesenswert?

Hallo!

Die besagte SD-Karte hat gestern den Geist aufgegeben. D.h sie 
funktioniert auch nicht mehr mit dem USB-Card Reader. Außerdem sind bei 
einem Filesystem Check einige Fehler aufgetreten, bevor sie tatsächlich 
kaputtgegangen ist. Evtl. hing der Fehler damit zusammen. Ich werde dem 
jedenfalls nicht weiter nachgehen.

Vlt kann den Code oben ja trotzdem jmd gebrauchen :)

Lg,
Franz

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.