Fix errors reading the last sector of SD card.
[SCSI2SD.git] / software / SCSI2SD / SCSI2SD.cydsn / sd.c
1 //      Copyright (C) 2013 Michael McMaster <michael@codesrc.com>\r
2 //\r
3 //      This file is part of SCSI2SD.\r
4 //\r
5 //      SCSI2SD is free software: you can redistribute it and/or modify\r
6 //      it under the terms of the GNU General Public License as published by\r
7 //      the Free Software Foundation, either version 3 of the License, or\r
8 //      (at your option) any later version.\r
9 //\r
10 //      SCSI2SD is distributed in the hope that it will be useful,\r
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 //      GNU General Public License for more details.\r
14 //\r
15 //      You should have received a copy of the GNU General Public License\r
16 //      along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.\r
17 \r
18 #include "device.h"\r
19 #include "scsi.h"\r
20 #include "config.h"\r
21 #include "disk.h"\r
22 #include "sd.h"\r
23 #include "led.h"\r
24 \r
25 #include "scsiPhy.h"\r
26 \r
27 #include <string.h>\r
28 \r
29 // Global\r
30 SdDevice sdDev;\r
31 \r
32 static uint8 sdCrc7(uint8* chr, uint8 cnt, uint8 crc)\r
33 {\r
34         uint8 a;\r
35         for(a = 0; a < cnt; a++)\r
36         {\r
37                 uint8 Data = chr[a];\r
38                 uint8 i;\r
39                 for(i = 0; i < 8; i++)\r
40                 {\r
41                         crc <<= 1;\r
42                         if( (Data & 0x80) ^ (crc & 0x80) ) {crc ^= 0x09;}\r
43                         Data <<= 1;\r
44                 }\r
45         }\r
46         return crc & 0x7F;\r
47 }\r
48 \r
49 // Read and write 1 byte.\r
50 static uint8 sdSpiByte(uint8 value)\r
51 {\r
52         SDCard_WriteTxData(value);\r
53         while (!(SDCard_ReadRxStatus() & SDCard_STS_RX_FIFO_NOT_EMPTY)) {}\r
54         return SDCard_ReadRxData();\r
55 }\r
56 \r
57 static void sdSendCRCCommand(uint8 cmd, uint32 param)\r
58 {\r
59         uint8 send[6];\r
60 \r
61         send[0] = cmd | 0x40;\r
62         send[1] = param >> 24;\r
63         send[2] = param >> 16;\r
64         send[3] = param >> 8;\r
65         send[4] = param;\r
66         send[5] = (sdCrc7(send, 5, 0) << 1) | 1;\r
67 \r
68         for(cmd = 0; cmd < sizeof(send); cmd++)\r
69         {\r
70                 sdSpiByte(send[cmd]);\r
71         }\r
72         // Allow command to process before reading result code.\r
73         sdSpiByte(0xFF);\r
74 }\r
75 \r
76 static void sdSendCommand(uint8 cmd, uint32 param)\r
77 {\r
78         uint8 send[6];\r
79 \r
80         send[0] = cmd | 0x40;\r
81         send[1] = param >> 24;\r
82         send[2] = param >> 16;\r
83         send[3] = param >> 8;\r
84         send[4] = param;\r
85         send[5] = 0;\r
86 \r
87         for(cmd = 0; cmd < sizeof(send); cmd++)\r
88         {\r
89                 sdSpiByte(send[cmd]);\r
90         }\r
91         // Allow command to process before reading result code.\r
92         sdSpiByte(0xFF);\r
93 }\r
94 \r
95 static uint8 sdReadResp()\r
96 {\r
97         uint8 v;\r
98         uint8 i = 128;\r
99         do\r
100         {\r
101                 v = sdSpiByte(0xFF);\r
102         } while(i-- && (v & 0x80));\r
103         return v;\r
104 }\r
105 \r
106 static uint8 sdCommandAndResponse(uint8 cmd, uint32 param)\r
107 {\r
108         sdSpiByte(0xFF);\r
109         sdSendCommand(cmd, param);\r
110         return sdReadResp();\r
111 }\r
112 \r
113 static uint8 sdCRCCommandAndResponse(uint8 cmd, uint32 param)\r
114 {\r
115         sdSpiByte(0xFF);\r
116         sdSendCRCCommand(cmd, param);\r
117         return sdReadResp();\r
118 }\r
119 \r
120 // Clear the sticky status bits on error.\r
121 static void sdClearStatus()\r
122 {\r
123         uint8 r2hi = sdCRCCommandAndResponse(SD_SEND_STATUS, 0);\r
124         uint8 r2lo = sdSpiByte(0xFF);\r
125         (void) r2hi; (void) r2lo;\r
126 }\r
127 \r
128 \r
129 void sdPrepareRead()\r
130 {\r
131         uint8 v;\r
132         uint32 len = (transfer.lba + transfer.currentBlock);\r
133         if (!sdDev.ccs)\r
134         {\r
135                 len = len * SCSI_BLOCK_SIZE;\r
136         }\r
137         v = sdCommandAndResponse(SD_READ_MULTIPLE_BLOCK, len);\r
138         if (v)\r
139         {\r
140                 scsiDiskReset();\r
141                 sdClearStatus();\r
142 \r
143                 scsiDev.status = CHECK_CONDITION;\r
144                 scsiDev.sense.code = HARDWARE_ERROR;\r
145                 scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
146                 scsiDev.phase = STATUS;\r
147         }\r
148 }\r
149 \r
150 static void doReadSector()\r
151 {\r
152         int prep, i, guard;\r
153         \r
154         // Wait for a start-block token.\r
155         // Don't wait more than 100ms, which is the timeout recommended\r
156         // in the standard.\r
157         //100ms @ 64Hz = 6400000\r
158         int maxWait = 6400000;\r
159         uint8 token = sdSpiByte(0xFF);\r
160         while (token != 0xFE && (maxWait-- > 0))\r
161         {\r
162                 token = sdSpiByte(0xFF);\r
163         }\r
164         if (token != 0xFE)\r
165         {\r
166                 if (transfer.multiBlock)\r
167                 {\r
168                         sdCompleteRead();\r
169                 }\r
170                 if (scsiDev.status != CHECK_CONDITION)\r
171                 {\r
172                         scsiDev.status = CHECK_CONDITION;\r
173                         scsiDev.sense.code = HARDWARE_ERROR;\r
174                         scsiDev.sense.asc = UNRECOVERED_READ_ERROR;\r
175                         scsiDev.phase = STATUS;\r
176                 }\r
177                 return;\r
178         }\r
179 \r
180         // Don't do a bus settle delay if we're already in the correct phase.\r
181         if (transfer.currentBlock == 0)\r
182         {\r
183                 scsiEnterPhase(DATA_IN);\r
184         }\r
185         \r
186         // Quickly seed the FIFO\r
187         prep = 4;\r
188         CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO\r
189         CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO\r
190         CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO\r
191         CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO\r
192 \r
193         i = 0;\r
194         guard = 0;\r
195 \r
196         // This loop is critically important for performance.\r
197         // We stream data straight from the SDCard fifos into the SCSI component\r
198         // FIFO's. If the loop isn't fast enough, the transmit FIFO's will empty,\r
199         // and performance will suffer. Every clock cycle counts.       \r
200         while (i < SCSI_BLOCK_SIZE)\r
201         {\r
202                 uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);\r
203                 uint8_t scsiStatus = CY_GET_REG8(scsiTarget_StatusReg__STATUS_REG);\r
204 \r
205                 // Read from the SPIM fifo if there is room to stream the byte to the\r
206                 // SCSI fifos\r
207                 if((sdRxStatus & SDCard_STS_RX_FIFO_NOT_EMPTY) &&\r
208                         (scsiStatus & 1) // SCSI TX FIFO NOT FULL\r
209                         )\r
210                 {\r
211                         uint8_t val = CY_GET_REG8(SDCard_RXDATA_PTR);\r
212                         CY_SET_REG8(scsiTarget_datapath__F0_REG, val);\r
213                         guard++;\r
214                 }\r
215 \r
216                 // Byte has been sent out the SCSI interface.\r
217                 if (scsiStatus & 2) // SCSI RX FIFO NOT EMPTY\r
218                 {\r
219                         CY_GET_REG8(scsiTarget_datapath__F1_REG);\r
220                         ++i;\r
221                 }\r
222 \r
223                 // How many bytes are in a 4-byte FIFO ? 5.  4 FIFO bytes PLUS one byte\r
224                 // being processed bit-by-bit. Artifically limit the number of bytes in the \r
225                 // "combined" SPIM TX and RX FIFOS to the individual FIFO size.\r
226                 // Unlike the SCSI component, SPIM doesn't check if there's room in\r
227                 // the output FIFO before starting to transmit.\r
228                 if ((prep - guard < 4) && (prep < SCSI_BLOCK_SIZE))\r
229                 {\r
230                         CY_SET_REG8(SDCard_TXDATA_PTR, 0xFF); // Put a byte in the FIFO\r
231                         prep++;\r
232                 }               \r
233         }\r
234 \r
235         sdSpiByte(0xFF); // CRC\r
236         sdSpiByte(0xFF); // CRC\r
237         scsiDev.dataLen = SCSI_BLOCK_SIZE;\r
238         scsiDev.dataPtr = SCSI_BLOCK_SIZE;\r
239 }\r
240 \r
241 void sdReadSectorSingle()\r
242 {\r
243         uint8 v;\r
244         uint32 len = (transfer.lba + transfer.currentBlock);\r
245         if (!sdDev.ccs)\r
246         {\r
247                 len = len * SCSI_BLOCK_SIZE;\r
248         }       \r
249         v = sdCommandAndResponse(SD_READ_SINGLE_BLOCK, len);\r
250         if (v)\r
251         {\r
252                 scsiDiskReset();\r
253                 sdClearStatus();\r
254 \r
255                 scsiDev.status = CHECK_CONDITION;\r
256                 scsiDev.sense.code = HARDWARE_ERROR;\r
257                 scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
258                 scsiDev.phase = STATUS;\r
259         }\r
260         else\r
261         {\r
262                 doReadSector();\r
263         }\r
264 }\r
265 \r
266 void sdReadSectorMulti()\r
267 {\r
268         // Pre: sdPrepareRead called.\r
269         \r
270         doReadSector();\r
271 }\r
272 \r
273 \r
274 void sdCompleteRead()\r
275 {\r
276         // We cannot send even a single "padding" byte, as we normally would when\r
277         // sending a command.  If we've just finished reading the very last block\r
278         // on the card, then reading an additional dummy byte will just trigger\r
279         // an error condition as we're trying to read past-the-end of the storage\r
280         // device.\r
281         // ie. do not use sdCommandAndResponse here.\r
282         uint8 r1b;\r
283         sdSendCommand(SD_STOP_TRANSMISSION, 0);\r
284         r1b = sdReadResp();\r
285 \r
286         if (r1b)\r
287         {\r
288                 // Try very hard to make sure the transmission stops\r
289                 int retries = 255;\r
290                 while (r1b && retries)\r
291                 {\r
292                         r1b = sdCommandAndResponse(SD_STOP_TRANSMISSION, 0);\r
293                         retries--;\r
294                 }\r
295 \r
296                 scsiDev.status = CHECK_CONDITION;\r
297                 scsiDev.sense.code = HARDWARE_ERROR;\r
298                 scsiDev.sense.asc = UNRECOVERED_READ_ERROR;\r
299                 scsiDev.phase = STATUS;\r
300         }\r
301 \r
302         // R1b has an optional trailing "busy" signal.\r
303         {\r
304                 uint8 busy;\r
305                 do\r
306                 {\r
307                         busy = sdSpiByte(0xFF);\r
308                 } while (busy == 0);\r
309         }\r
310 }\r
311 \r
312 static void sdWaitWriteBusy()\r
313 {\r
314         uint8 val;\r
315         do\r
316         {\r
317                 val = sdSpiByte(0xFF);\r
318         } while (val != 0xFF);\r
319 }\r
320 \r
321 int sdWriteSector()\r
322 {\r
323         int prep, i, guard;     \r
324         int result, maxWait;\r
325         uint8 dataToken;\r
326 \r
327         // Don't do a bus settle delay if we're already in the correct phase.\r
328         if (transfer.currentBlock == 0)\r
329         {\r
330                 scsiEnterPhase(DATA_OUT);\r
331         }\r
332         \r
333         sdSpiByte(0xFC); // MULTIPLE byte start token\r
334         \r
335         prep = 0;\r
336         i = 0;\r
337         guard = 0;\r
338 \r
339         // This loop is critically important for performance.\r
340         // We stream data straight from the SCSI fifos into the SPIM component\r
341         // FIFO's. If the loop isn't fast enough, the transmit FIFO's will empty,\r
342         // and performance will suffer. Every clock cycle counts.       \r
343         while (i < SCSI_BLOCK_SIZE)\r
344         {\r
345                 uint8_t sdRxStatus = CY_GET_REG8(SDCard_RX_STATUS_PTR);\r
346                 uint8_t scsiStatus = CY_GET_REG8(scsiTarget_StatusReg__STATUS_REG);\r
347 \r
348                 // Read from the SCSI fifo if there is room to stream the byte to the\r
349                 // SPIM fifos\r
350                 // See sdReadSector for comment on guard (FIFO size is really 5)\r
351                 if((guard - i < 4) &&\r
352                         (scsiStatus & 2)) // SCSI RX FIFO NOT EMPTY\r
353                 {\r
354                         uint8_t val = CY_GET_REG8(scsiTarget_datapath__F1_REG);\r
355                         CY_SET_REG8(SDCard_TXDATA_PTR, val);\r
356                         guard++;\r
357                 }\r
358         \r
359                 // Byte has been sent out the SPIM interface.\r
360                 if (sdRxStatus & SDCard_STS_RX_FIFO_NOT_EMPTY)\r
361                 {\r
362                          CY_GET_REG8(SDCard_RXDATA_PTR);\r
363                         ++i;\r
364                 }\r
365 \r
366                 if (prep < SCSI_BLOCK_SIZE &&\r
367                         (scsiStatus & 1) // SCSI TX FIFO NOT FULL\r
368                         )\r
369                 {\r
370                         // Trigger the SCSI component to read a byte\r
371                         CY_SET_REG8(scsiTarget_datapath__F0_REG, 0xFF);\r
372                         prep++;\r
373                 }                       \r
374         }\r
375         \r
376         sdSpiByte(0x00); // CRC\r
377         sdSpiByte(0x00); // CRC\r
378 \r
379         // Don't wait more than 1s.\r
380         // My 2g Kingston micro-sd card doesn't respond immediately.\r
381         // My 16Gb card does.\r
382         maxWait = 1000000;\r
383         dataToken = sdSpiByte(0xFF); // Response\r
384         while (dataToken == 0xFF && maxWait-- > 0)\r
385         {\r
386                 CyDelayUs(1);\r
387                 dataToken = sdSpiByte(0xFF);\r
388         }\r
389         if (((dataToken & 0x1F) >> 1) != 0x2) // Accepted.\r
390         {\r
391                 uint8 r1b, busy;\r
392                 \r
393                 sdWaitWriteBusy();\r
394 \r
395                 r1b = sdCommandAndResponse(SD_STOP_TRANSMISSION, 0);\r
396                 (void) r1b;\r
397                 sdSpiByte(0xFF);\r
398 \r
399                 // R1b has an optional trailing "busy" signal.\r
400                 do\r
401                 {\r
402                         busy = sdSpiByte(0xFF);\r
403                 } while (busy == 0);\r
404 \r
405                 // Wait for the card to come out of busy.\r
406                 sdWaitWriteBusy();\r
407 \r
408                 scsiDiskReset();\r
409                 sdClearStatus();\r
410 \r
411                 scsiDev.status = CHECK_CONDITION;\r
412                 scsiDev.sense.code = HARDWARE_ERROR;\r
413                 scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
414                 scsiDev.phase = STATUS;\r
415                 result = 0;\r
416         }\r
417         else\r
418         {\r
419                 sdWaitWriteBusy();\r
420                 result = 1;\r
421         }\r
422 \r
423         return result;\r
424 }\r
425 \r
426 void sdCompleteWrite()\r
427 {\r
428         uint8 r1, r2;\r
429         \r
430         sdSpiByte(0xFD); // STOP TOKEN\r
431         // Wait for the card to come out of busy.\r
432         sdWaitWriteBusy();\r
433 \r
434         r1 = sdCommandAndResponse(13, 0); // send status\r
435         r2 = sdSpiByte(0xFF);\r
436         if (r1 || r2)\r
437         {\r
438                 sdClearStatus();\r
439                 scsiDev.status = CHECK_CONDITION;\r
440                 scsiDev.sense.code = HARDWARE_ERROR;\r
441                 scsiDev.sense.asc = WRITE_ERROR_AUTO_REALLOCATION_FAILED;\r
442                 scsiDev.phase = STATUS;\r
443         }\r
444 }\r
445 \r
446 \r
447 // SD Version 2 (SDHC) support\r
448 static int sendIfCond()\r
449 {\r
450         int retries = 50;\r
451 \r
452         do\r
453         {\r
454                 uint8 status = sdCRCCommandAndResponse(SD_SEND_IF_COND, 0x000001AA);\r
455 \r
456                 if (status == SD_R1_IDLE)\r
457                 {\r
458                         // Version 2 card.\r
459                         sdDev.version = 2;\r
460                         // Read 32bit response. Should contain the same bytes that\r
461                         // we sent in the command parameter.\r
462                         sdSpiByte(0xFF);\r
463                         sdSpiByte(0xFF);\r
464                         sdSpiByte(0xFF);\r
465                         sdSpiByte(0xFF);\r
466                         break;\r
467                 }\r
468                 else if (status & SD_R1_ILLEGAL)\r
469                 {\r
470                         // Version 1 card.\r
471                         sdDev.version = 1;\r
472                         sdClearStatus();\r
473                         break;\r
474                 }\r
475 \r
476                 sdClearStatus();\r
477         } while (--retries > 0);\r
478 \r
479         return retries > 0;\r
480 }\r
481 \r
482 static int sdOpCond()\r
483 {\r
484         int retries = 50;\r
485 \r
486         uint8 status;\r
487         do\r
488         {\r
489                 CyDelay(33); // Spec says to retry for 1 second.\r
490 \r
491                 sdCRCCommandAndResponse(SD_APP_CMD, 0);\r
492                 // Host Capacity Support = 1 (SDHC/SDXC supported)\r
493                 status = sdCRCCommandAndResponse(SD_APP_SEND_OP_COND, 0x40000000);\r
494 \r
495                 sdClearStatus();\r
496         } while ((status != 0) && (--retries > 0));\r
497 \r
498         return retries > 0;\r
499 }\r
500 \r
501 static int sdReadOCR()\r
502 {\r
503         uint8 buf[4];\r
504         int i;\r
505         \r
506         uint8 status = sdCRCCommandAndResponse(SD_READ_OCR, 0);\r
507         if(status){goto bad;}\r
508 \r
509         for (i = 0; i < 4; ++i)\r
510         {\r
511                 buf[i] = sdSpiByte(0xFF);\r
512         }\r
513 \r
514         sdDev.ccs = (buf[0] & 0x40) ? 1 : 0;\r
515 \r
516         return 1;\r
517 bad:\r
518         return 0;\r
519 }\r
520 \r
521 static int sdReadCSD()\r
522 {\r
523         uint8 startToken;\r
524         int maxWait, i;\r
525         uint8 buf[16];\r
526         \r
527         uint8 status = sdCRCCommandAndResponse(SD_SEND_CSD, 0);\r
528         if(status){goto bad;}\r
529 \r
530         maxWait = 1023;\r
531         do\r
532         {\r
533                 startToken = sdSpiByte(0xFF);\r
534         } while(maxWait-- && (startToken != 0xFE));\r
535         if (startToken != 0xFE) { goto bad; }\r
536 \r
537         for (i = 0; i < 16; ++i)\r
538         {\r
539                 buf[i] = sdSpiByte(0xFF);\r
540         }\r
541         sdSpiByte(0xFF); // CRC\r
542         sdSpiByte(0xFF); // CRC\r
543 \r
544         if ((buf[0] >> 6) == 0x00)\r
545         {\r
546                 // CSD version 1\r
547                 // C_SIZE in bits [73:62]\r
548                 uint32 c_size = (((((uint32)buf[6]) & 0x3) << 16) | (((uint32)buf[7]) << 8) | buf[8]) >> 6;\r
549                 uint32 c_mult = (((((uint32)buf[9]) & 0x3) << 8) | ((uint32)buf[0xa])) >> 7;\r
550                 uint32 sectorSize = buf[5] & 0x0F;\r
551                 sdDev.capacity = ((c_size+1) * ((uint64)1 << (c_mult+2)) * ((uint64)1 << sectorSize)) / SCSI_BLOCK_SIZE;\r
552         }\r
553         else if ((buf[0] >> 6) == 0x01)\r
554         {\r
555                 // CSD version 2\r
556                 // C_SIZE in bits [69:48]\r
557 \r
558                 uint32 c_size =\r
559                         ((((uint32)buf[7]) & 0x3F) << 16) |\r
560                         (((uint32)buf[8]) << 8) |\r
561                         ((uint32)buf[7]);\r
562                 sdDev.capacity = (c_size + 1) * 1024;\r
563         }\r
564         else\r
565         {\r
566                 goto bad;\r
567         }\r
568 \r
569         return 1;\r
570 bad:\r
571         return 0;\r
572 }\r
573 \r
574 int sdInit()\r
575 {\r
576         int result = 0;\r
577         int i;\r
578         uint8 v;\r
579         \r
580         sdDev.version = 0;\r
581         sdDev.ccs = 0;\r
582         sdDev.capacity = 0;\r
583 \r
584         SD_CS_Write(1); // Set CS inactive (active low)\r
585         SD_Init_Clk_Start(); // Turn on the slow 400KHz clock\r
586         SD_Clk_Ctl_Write(0); // Select the 400KHz clock source.\r
587         SDCard_Start(); // Enable SPI hardware\r
588 \r
589         // Power on sequence. 74 clock cycles of a "1" while CS unasserted.\r
590         for (i = 0; i < 10; ++i)\r
591         {\r
592                 sdSpiByte(0xFF);\r
593         }\r
594 \r
595         SD_CS_Write(0); // Set CS active (active low)\r
596         CyDelayUs(1);\r
597 \r
598         v = sdCRCCommandAndResponse(SD_GO_IDLE_STATE, 0);\r
599         if(v != 1){goto bad;}\r
600 \r
601         ledOn();\r
602         if (!sendIfCond()) goto bad; // Sets V1 or V2 flag\r
603         if (!sdOpCond()) goto bad;\r
604         if (!sdReadOCR()) goto bad;\r
605 \r
606         // This command will be ignored if sdDev.ccs is set.\r
607         // SDHC and SDXC are always 512bytes.\r
608         v = sdCRCCommandAndResponse(SD_SET_BLOCKLEN, SCSI_BLOCK_SIZE); //Force sector size\r
609         if(v){goto bad;}\r
610         v = sdCRCCommandAndResponse(SD_CRC_ON_OFF, 0); //crc off\r
611         if(v){goto bad;}\r
612 \r
613         // now set the sd card up for full speed\r
614         // The SD Card spec says we can run SPI @ 25MHz\r
615         // But the PSoC 5LP SPIM datasheet says the most we can do is 18MHz.\r
616         // I've confirmed that no data is ever put into the RX FIFO when run at\r
617         // 20MHz or 25MHz.\r
618         // ... and then we get timing analysis failures if the BUS_CLK is over 62MHz.\r
619         // So we run the MASTER_CLK and BUS_CLK at 60MHz, and run the SPI clock at 30MHz\r
620         // (15MHz SPI transfer clock).\r
621         SDCard_Stop();\r
622         SD_Data_Clk_Start(); // Turn on the fast clock\r
623         SD_Clk_Ctl_Write(1); // Select the fast clock source.\r
624         SD_Init_Clk_Stop(); // Stop the slow clock.\r
625         CyDelayUs(1);\r
626         SDCard_Start();\r
627 \r
628         // Clear out rubbish data through clock change\r
629         CyDelayUs(1);\r
630         SDCard_ReadRxStatus();\r
631         SDCard_ReadTxStatus();\r
632         SDCard_ClearFIFO();\r
633 \r
634         if (!sdReadCSD()) goto bad;\r
635 \r
636         result = 1;\r
637         goto out;\r
638 \r
639 bad:\r
640         sdDev.capacity = 0;\r
641 \r
642 out:\r
643         sdClearStatus();\r
644         ledOff();\r
645         return result;\r
646 \r
647 }\r
648 \r
649 void sdPrepareWrite()\r
650 {\r
651         uint32 len;\r
652         uint8 v;\r
653         \r
654         // Set the number of blocks to pre-erase by the multiple block write command\r
655         // We don't care about the response - if the command is not accepted, writes\r
656         // will just be a bit slower.\r
657         // Max 22bit parameter.\r
658         uint32 blocks = transfer.blocks > 0x7FFFFF ? 0x7FFFFF : transfer.blocks;\r
659         sdCommandAndResponse(SD_APP_CMD, 0);\r
660         sdCommandAndResponse(SD_APP_SET_WR_BLK_ERASE_COUNT, blocks);\r
661 \r
662         len = (transfer.lba + transfer.currentBlock);\r
663         if (!sdDev.ccs)\r
664         {\r
665                 len = len * SCSI_BLOCK_SIZE;\r
666         }\r
667         v = sdCommandAndResponse(25, len);\r
668         if (v)\r
669         {\r
670                 scsiDiskReset();\r
671                 sdClearStatus();\r
672                 scsiDev.status = CHECK_CONDITION;\r
673                 scsiDev.sense.code = HARDWARE_ERROR;\r
674                 scsiDev.sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;\r
675                 scsiDev.phase = STATUS;\r
676         }\r
677 }\r
678 \r