1 // Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
\r
3 // This file is part of SCSI2SD.
\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
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
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
18 #include "stm32f2xx.h"
\r
20 #include "bsp_driver_sd.h"
\r
31 #include "scsiPhy.h"
\r
39 enum SD_CMD_STATE { CMD_STATE_IDLE, CMD_STATE_READ, CMD_STATE_WRITE };
\r
40 static int sdCmdState = CMD_STATE_IDLE;
\r
41 static uint32_t sdCmdNextLBA; // Only valid in CMD_STATE_READ or CMD_STATE_WRITE
\r
42 static uint32_t sdCmdTime;
\r
43 static uint32_t sdLastCmdState = CMD_STATE_IDLE;
\r
45 enum SD_IO_STATE { SD_DMA, SD_ACCEPTED, SD_IDLE };
\r
46 static int sdIOState = SD_IDLE;
\r
48 // Private DMA variables.
\r
49 static uint8 sdDMARxChan = CY_DMA_INVALID_CHANNEL;
\r
50 static uint8 sdDMATxChan = CY_DMA_INVALID_CHANNEL;
\r
52 // Dummy location for DMA to send unchecked CRC bytes to
\r
53 static uint8 discardBuffer __attribute__((aligned(4)));
\r
55 // 2 bytes CRC, response, 8bits to close the clock..
\r
56 // "NCR" time is up to 8 bytes.
\r
57 static uint8_t writeResponseBuffer[8] __attribute__((aligned(4)));
\r
59 // Padded with a dummy byte just to allow the tx DMA channel to
\r
60 // use 2-byte bursts for performance.
\r
61 static uint8_t writeStartToken[2] __attribute__((aligned(4))) = {0xFF, 0xFC};
\r
63 // Source of dummy SPI bytes for DMA
\r
64 static uint8_t dummyBuffer[2] __attribute__((aligned(4))) = {0xFF, 0xFF};
\r
66 volatile uint8_t sdRxDMAComplete;
\r
67 volatile uint8_t sdTxDMAComplete;
\r
69 static void sdCompleteRead();
\r
70 static void sdCompleteWrite();
\r
72 CY_ISR_PROTO(sdRxISR);
\r
75 sdRxDMAComplete = 1;
\r
77 CY_ISR_PROTO(sdTxISR);
\r
80 sdTxDMAComplete = 1;
\r
83 static uint8 sdCrc7(uint8* chr, uint8 cnt, uint8 crc)
\r
86 for(a = 0; a < cnt; a++)
\r
88 uint8 Data = chr[a];
\r
90 for(i = 0; i < 8; i++)
\r
93 if( (Data & 0x80) ^ (crc & 0x80) ) {crc ^= 0x09;}
\r
101 // Read and write 1 byte.
\r
102 static uint8_t sdSpiByte(uint8_t value)
\r
104 SDCard_WriteTxData(value);
\r
105 trace(trace_spinSpiByte);
\r
106 while (!(SDCard_ReadRxStatus() & SDCard_STS_RX_FIFO_NOT_EMPTY)) {}
\r
107 trace(trace_sdSpiByte);
\r
108 return SDCard_ReadRxData();
\r
111 static void sdWaitWriteBusy()
\r
116 val = sdSpiByte(0xFF);
\r
117 } while (val != 0xFF);
\r
120 static void sdPreCmdState(uint32_t newState)
\r
122 if (sdCmdState == CMD_STATE_READ)
\r
126 else if (sdCmdState == CMD_STATE_WRITE)
\r
130 sdCmdState = CMD_STATE_IDLE;
\r
132 if (sdLastCmdState != newState && newState != CMD_STATE_IDLE)
\r
135 sdLastCmdState = newState;
\r
139 static uint16_t sdDoCommand(
\r
143 int use2byteResponse)
\r
145 int waitWhileBusy = (cmd != SD_GO_IDLE_STATE) && (cmd != SD_STOP_TRANSMISSION);
\r
147 // "busy" probe. We'll examine the results later.
\r
150 SDCard_WriteTxData(0xFF);
\r
153 // send is static as the address must remain consistent for the static
\r
154 // DMA descriptors to work.
\r
155 // Size must be divisible by 2 to suit 2-byte-burst TX DMA channel.
\r
156 static uint8_t send[6] __attribute__((aligned(4)));
\r
157 send[0] = cmd | 0x40;
\r
158 send[1] = param >> 24;
\r
159 send[2] = param >> 16;
\r
160 send[3] = param >> 8;
\r
162 if (unlikely(useCRC))
\r
164 send[5] = (sdCrc7(send, 5, 0) << 1) | 1;
\r
168 send[5] = 1; // stop bit
\r
171 static uint8_t dmaRxTd = CY_DMA_INVALID_TD;
\r
172 static uint8_t dmaTxTd = CY_DMA_INVALID_TD;
\r
173 if (unlikely(dmaRxTd == CY_DMA_INVALID_TD))
\r
175 dmaRxTd = CyDmaTdAllocate();
\r
176 dmaTxTd = CyDmaTdAllocate();
\r
177 CyDmaTdSetConfiguration(dmaTxTd, sizeof(send), CY_DMA_DISABLE_TD, TD_INC_SRC_ADR|SD_TX_DMA__TD_TERMOUT_EN);
\r
178 CyDmaTdSetAddress(dmaTxTd, LO16((uint32)&send), LO16((uint32)SDCard_TXDATA_PTR));
\r
179 CyDmaTdSetConfiguration(dmaRxTd, sizeof(send), CY_DMA_DISABLE_TD, SD_RX_DMA__TD_TERMOUT_EN);
\r
180 CyDmaTdSetAddress(dmaRxTd, LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&discardBuffer));
\r
183 sdTxDMAComplete = 0;
\r
184 sdRxDMAComplete = 0;
\r
186 CyDmaChSetInitialTd(sdDMARxChan, dmaRxTd);
\r
187 CyDmaChSetInitialTd(sdDMATxChan, dmaTxTd);
\r
189 // Some Samsung cards enter a busy-state after single-sector reads.
\r
190 // But we also need to wait for R1B to complete from the multi-sector
\r
194 trace(trace_spinSDRxFIFO);
\r
195 while (!(SDCard_ReadRxStatus() & SDCard_STS_RX_FIFO_NOT_EMPTY)) {}
\r
196 int busy = SDCard_ReadRxData() != 0xFF;
\r
197 if (unlikely(busy))
\r
199 trace(trace_spinSDBusy);
\r
200 while (sdSpiByte(0xFF) != 0xFF) {}
\r
204 // The DMA controller is a bit trigger-happy. It will retain
\r
205 // a drq request that was triggered while the channel was
\r
207 CyDmaChSetRequest(sdDMATxChan, CY_DMA_CPU_REQ);
\r
208 CyDmaClearPendingDrq(sdDMARxChan);
\r
210 // There is no flow control, so we must ensure we can read the bytes
\r
211 // before we start transmitting
\r
212 CyDmaChEnable(sdDMARxChan, 1);
\r
213 CyDmaChEnable(sdDMATxChan, 1);
\r
215 trace(trace_spinSDDMA);
\r
216 int allComplete = 0;
\r
217 while (!allComplete)
\r
219 uint8_t intr = CyEnterCriticalSection();
\r
220 allComplete = sdTxDMAComplete && sdRxDMAComplete;
\r
225 CyExitCriticalSection(intr);
\r
228 uint16_t response = sdSpiByte(0xFF); // Result code or stuff byte
\r
229 if (unlikely(cmd == SD_STOP_TRANSMISSION))
\r
231 // Stuff byte is required for this command only.
\r
232 // Part 1 Simplified standard 3.01
\r
233 // "The stop command has an execution delay due to the serial command
\r
235 response = sdSpiByte(0xFF);
\r
238 uint32_t start = getTime_ms();
\r
240 trace(trace_spinSDBusy);
\r
241 while ((response & 0x80) && likely(elapsedTime_ms(start) <= 200))
\r
243 response = sdSpiByte(0xFF);
\r
245 if (unlikely(use2byteResponse))
\r
247 response = (response << 8) | sdSpiByte(0xFF);
\r
253 static inline uint16_t sdCommandAndResponse(uint8_t cmd, uint32_t param)
\r
255 return sdDoCommand(cmd, param, 0, 0);
\r
258 static inline uint16_t sdCRCCommandAndResponse(uint8_t cmd, uint32_t param)
\r
260 return sdDoCommand(cmd, param, 1, 0);
\r
263 // Clear the sticky status bits on error.
\r
264 static void sdClearStatus()
\r
267 uint16_t r2 = sdDoCommand(SD_SEND_STATUS, 0, 1, 1);
\r
272 sdReadMultiSectorPrep(uint32_t sdLBA, uint32_t sdSectors)
\r
274 uint32_t tmpNextLBA = sdLBA + sdSectors;
\r
278 sdLBA = sdLBA * SD_SECTOR_SIZE;
\r
279 tmpNextLBA = tmpNextLBA * SD_SECTOR_SIZE;
\r
282 if (sdCmdState == CMD_STATE_READ && sdCmdNextLBA == sdLBA)
\r
284 // Well, that was lucky. We're already reading this data
\r
285 sdCmdNextLBA = tmpNextLBA;
\r
286 sdCmdTime = getTime_ms();
\r
290 sdPreCmdState(CMD_STATE_READ);
\r
292 uint8_t v = sdCommandAndResponse(SD_READ_MULTIPLE_BLOCK, sdLBA);
\r
298 scsiDev.status = CHECK_CONDITION;
\r
299 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
300 scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
\r
301 scsiDev.phase = STATUS;
\r
305 sdCmdNextLBA = tmpNextLBA;
\r
306 sdCmdState = CMD_STATE_READ;
\r
307 sdCmdTime = getTime_ms();
\r
313 dmaReadSector(uint8_t* outputBuffer)
\r
315 // Wait for a start-block token.
\r
316 // Don't wait more than 200ms. The standard recommends 100ms.
\r
317 uint32_t start = getTime_ms();
\r
318 uint8_t token = sdSpiByte(0xFF);
\r
319 trace(trace_spinSDBusy);
\r
320 while (token != 0xFE && likely(elapsedTime_ms(start) <= 200))
\r
322 if (unlikely(token && ((token & 0xE0) == 0)))
\r
327 token = sdSpiByte(0xFF);
\r
329 if (unlikely(token != 0xFE))
\r
331 if (transfer.multiBlock)
\r
335 if (scsiDev.status != CHECK_CONDITION)
\r
337 scsiDev.status = CHECK_CONDITION;
\r
338 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
339 scsiDev.target->sense.asc = UNRECOVERED_READ_ERROR;
\r
340 scsiDev.phase = STATUS;
\r
346 static uint8_t dmaRxTd[2] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};
\r
347 static uint8_t dmaTxTd = CY_DMA_INVALID_TD;
\r
348 if (unlikely(dmaRxTd[0] == CY_DMA_INVALID_TD))
\r
350 dmaRxTd[0] = CyDmaTdAllocate();
\r
351 dmaRxTd[1] = CyDmaTdAllocate();
\r
352 dmaTxTd = CyDmaTdAllocate();
\r
354 // Receive 512 bytes of data and then 2 bytes CRC.
\r
355 CyDmaTdSetConfiguration(dmaRxTd[0], SD_SECTOR_SIZE, dmaRxTd[1], TD_INC_DST_ADR);
\r
356 CyDmaTdSetConfiguration(dmaRxTd[1], 2, CY_DMA_DISABLE_TD, SD_RX_DMA__TD_TERMOUT_EN);
\r
357 CyDmaTdSetAddress(dmaRxTd[1], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&discardBuffer));
\r
359 CyDmaTdSetConfiguration(dmaTxTd, SD_SECTOR_SIZE + 2, CY_DMA_DISABLE_TD, SD_TX_DMA__TD_TERMOUT_EN);
\r
360 CyDmaTdSetAddress(dmaTxTd, LO16((uint32)&dummyBuffer), LO16((uint32)SDCard_TXDATA_PTR));
\r
363 CyDmaTdSetAddress(dmaRxTd[0], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)outputBuffer));
\r
365 sdIOState = SD_DMA;
\r
366 sdTxDMAComplete = 0;
\r
367 sdRxDMAComplete = 0;
\r
369 // Re-loading the initial TD's here is very important, or else
\r
370 // we'll be re-using the last-used TD, which would be the last
\r
371 // in the chain (ie. CRC TD)
\r
372 CyDmaChSetInitialTd(sdDMARxChan, dmaRxTd[0]);
\r
373 CyDmaChSetInitialTd(sdDMATxChan, dmaTxTd);
\r
375 // The DMA controller is a bit trigger-happy. It will retain
\r
376 // a drq request that was triggered while the channel was
\r
378 CyDmaChSetRequest(sdDMATxChan, CY_DMA_CPU_REQ);
\r
379 CyDmaClearPendingDrq(sdDMARxChan);
\r
381 // There is no flow control, so we must ensure we can read the bytes
\r
382 // before we start transmitting
\r
383 CyDmaChEnable(sdDMARxChan, 1);
\r
384 CyDmaChEnable(sdDMATxChan, 1);
\r
388 sdReadSectorDMAPoll()
\r
390 if (sdRxDMAComplete && sdTxDMAComplete)
\r
392 // DMA transfer is complete
\r
393 sdIOState = SD_IDLE;
\r
402 void sdReadSingleSectorDMA(uint32_t lba, uint8_t* outputBuffer)
\r
404 sdPreCmdState(CMD_STATE_READ);
\r
409 lba = lba * SD_SECTOR_SIZE;
\r
411 v = sdCommandAndResponse(SD_READ_SINGLE_BLOCK, lba);
\r
417 scsiDev.status = CHECK_CONDITION;
\r
418 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
419 scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
\r
420 scsiDev.phase = STATUS;
\r
424 dmaReadSector(outputBuffer);
\r
429 sdReadMultiSectorDMA(uint8_t* outputBuffer)
\r
431 // Pre: sdReadMultiSectorPrep called.
\r
432 dmaReadSector(outputBuffer);
\r
435 static void sdCompleteRead()
\r
437 if (unlikely(sdIOState != SD_IDLE))
\r
439 // Not much choice but to wait until we've completed the transfer.
\r
440 // Cancelling the transfer can't be done as we have no way to reset
\r
442 trace(trace_spinSDCompleteRead);
\r
443 while (!sdReadSectorDMAPoll()) { /* spin */ }
\r
447 if (sdCmdState == CMD_STATE_READ)
\r
449 uint8 r1b = sdCommandAndResponse(SD_STOP_TRANSMISSION, 0);
\r
451 if (unlikely(r1b) && (scsiDev.phase == DATA_IN))
\r
453 scsiDev.status = CHECK_CONDITION;
\r
454 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
455 scsiDev.target->sense.asc = UNRECOVERED_READ_ERROR;
\r
456 scsiDev.phase = STATUS;
\r
460 // R1b has an optional trailing "busy" signal, but we defer waiting on this.
\r
461 // The next call so sdCommandAndResponse will wait for the busy state to
\r
464 sdCmdState = CMD_STATE_IDLE;
\r
468 sdWriteMultiSectorDMA(uint8_t* outputBuffer)
\r
470 static uint8_t dmaRxTd[2] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};
\r
471 static uint8_t dmaTxTd[3] = { CY_DMA_INVALID_TD, CY_DMA_INVALID_TD, CY_DMA_INVALID_TD};
\r
472 if (unlikely(dmaRxTd[0] == CY_DMA_INVALID_TD))
\r
474 dmaRxTd[0] = CyDmaTdAllocate();
\r
475 dmaRxTd[1] = CyDmaTdAllocate();
\r
476 dmaTxTd[0] = CyDmaTdAllocate();
\r
477 dmaTxTd[1] = CyDmaTdAllocate();
\r
478 dmaTxTd[2] = CyDmaTdAllocate();
\r
480 // Transmit 512 bytes of data and then 2 bytes CRC, and then get the response byte
\r
481 // We need to do this without stopping the clock
\r
482 CyDmaTdSetConfiguration(dmaTxTd[0], 2, dmaTxTd[1], TD_INC_SRC_ADR);
\r
483 CyDmaTdSetAddress(dmaTxTd[0], LO16((uint32)&writeStartToken), LO16((uint32)SDCard_TXDATA_PTR));
\r
485 CyDmaTdSetConfiguration(dmaTxTd[1], SD_SECTOR_SIZE, dmaTxTd[2], TD_INC_SRC_ADR);
\r
487 CyDmaTdSetConfiguration(dmaTxTd[2], 2 + sizeof(writeResponseBuffer), CY_DMA_DISABLE_TD, SD_TX_DMA__TD_TERMOUT_EN);
\r
488 CyDmaTdSetAddress(dmaTxTd[2], LO16((uint32)&dummyBuffer), LO16((uint32)SDCard_TXDATA_PTR));
\r
490 CyDmaTdSetConfiguration(dmaRxTd[0], SD_SECTOR_SIZE + 4, dmaRxTd[1], 0);
\r
491 CyDmaTdSetAddress(dmaRxTd[0], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&discardBuffer));
\r
492 CyDmaTdSetConfiguration(dmaRxTd[1], sizeof(writeResponseBuffer), CY_DMA_DISABLE_TD, SD_RX_DMA__TD_TERMOUT_EN|TD_INC_DST_ADR);
\r
493 CyDmaTdSetAddress(dmaRxTd[1], LO16((uint32)SDCard_RXDATA_PTR), LO16((uint32)&writeResponseBuffer));
\r
495 CyDmaTdSetAddress(dmaTxTd[1], LO16((uint32)outputBuffer), LO16((uint32)SDCard_TXDATA_PTR));
\r
498 sdIOState = SD_DMA;
\r
499 // The DMA controller is a bit trigger-happy. It will retain
\r
500 // a drq request that was triggered while the channel was
\r
502 CyDmaChSetRequest(sdDMATxChan, CY_DMA_CPU_REQ);
\r
503 CyDmaClearPendingDrq(sdDMARxChan);
\r
505 sdTxDMAComplete = 0;
\r
506 sdRxDMAComplete = 0;
\r
508 // Re-loading the initial TD's here is very important, or else
\r
509 // we'll be re-using the last-used TD, which would be the last
\r
510 // in the chain (ie. CRC TD)
\r
511 CyDmaChSetInitialTd(sdDMARxChan, dmaRxTd[0]);
\r
512 CyDmaChSetInitialTd(sdDMATxChan, dmaTxTd[0]);
\r
514 // There is no flow control, so we must ensure we can read the bytes
\r
515 // before we start transmitting
\r
516 CyDmaChEnable(sdDMARxChan, 1);
\r
517 CyDmaChEnable(sdDMATxChan, 1);
\r
521 sdWriteSectorDMAPoll()
\r
523 if (sdRxDMAComplete && sdTxDMAComplete)
\r
525 if (sdIOState == SD_DMA)
\r
527 // Retry a few times. The data token format is:
\r
533 dataToken = writeResponseBuffer[i]; // Response
\r
535 } while (((dataToken & 0x0101) != 1) && (i < sizeof(writeResponseBuffer)));
\r
537 // At this point we should either have an accepted token, or we'll
\r
538 // timeout and proceed into the error case below.
\r
539 if (unlikely(((dataToken & 0x1F) >> 1) != 0x2)) // Accepted.
\r
541 sdIOState = SD_IDLE;
\r
544 sdSpiByte(0xFD); // STOP TOKEN
\r
547 sdCmdState = CMD_STATE_IDLE;
\r
551 scsiDev.status = CHECK_CONDITION;
\r
552 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
553 scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
\r
554 scsiDev.phase = STATUS;
\r
558 sdIOState = SD_ACCEPTED;
\r
562 if (sdIOState == SD_ACCEPTED)
\r
564 // Wait while the SD card is busy
\r
565 if (sdSpiByte(0xFF) == 0xFF)
\r
567 sdIOState = SD_IDLE;
\r
571 return sdIOState == SD_IDLE;
\r
579 static void sdCompleteWrite()
\r
581 if (unlikely(sdIOState != SD_IDLE))
\r
583 // Not much choice but to wait until we've completed the transfer.
\r
584 // Cancelling the transfer can't be done as we have no way to reset
\r
586 trace(trace_spinSDCompleteWrite);
\r
587 while (!sdWriteSectorDMAPoll()) { /* spin */ }
\r
590 if (sdCmdState == CMD_STATE_WRITE)
\r
594 sdSpiByte(0xFD); // STOP TOKEN
\r
600 if (likely(scsiDev.phase == DATA_OUT))
\r
602 uint16_t r2 = sdDoCommand(SD_SEND_STATUS, 0, 0, 1);
\r
606 scsiDev.status = CHECK_CONDITION;
\r
607 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
608 scsiDev.target->sense.asc = WRITE_ERROR_AUTO_REALLOCATION_FAILED;
\r
609 scsiDev.phase = STATUS;
\r
612 sdCmdState = CMD_STATE_IDLE;
\r
615 void sdCompleteTransfer()
\r
617 sdPreCmdState(CMD_STATE_IDLE);
\r
621 // SD Version 2 (SDHC) support
\r
622 static int sendIfCond()
\r
628 // 11:8 Host voltage. 1 = 2.7-3.6V
\r
629 // 7:0 Echo bits. Ignore.
\r
630 uint8 status = sdCRCCommandAndResponse(SD_SEND_IF_COND, 0x000001AA);
\r
632 if (status == SD_R1_IDLE)
\r
636 // Read 32bit response. Should contain the same bytes that
\r
637 // we sent in the command parameter.
\r
644 else if (status & SD_R1_ILLEGAL)
\r
653 } while (--retries > 0);
\r
655 return retries > 0;
\r
658 static int sdOpCond()
\r
660 uint32_t start = getTime_ms();
\r
665 sdCRCCommandAndResponse(SD_APP_CMD, 0);
\r
666 // Host Capacity Support = 1 (SDHC/SDXC supported)
\r
667 status = sdCRCCommandAndResponse(SD_APP_SEND_OP_COND, 0x40000000);
\r
671 // Spec says to poll for 1 second.
\r
672 } while ((status != 0) && (elapsedTime_ms(start) < 1000));
\r
674 return status == 0;
\r
677 static int sdReadOCR()
\r
679 uint32_t start = getTime_ms();
\r
688 status = sdCRCCommandAndResponse(SD_READ_OCR, 0);
\r
689 if(status) { break; }
\r
691 for (i = 0; i < 4; ++i)
\r
693 buf[i] = sdSpiByte(0xFF);
\r
696 sdDev.ccs = (buf[0] & 0x40) ? 1 : 0;
\r
697 complete = (buf[0] & 0x80);
\r
699 } while (!status &&
\r
701 (elapsedTime_ms(start) < 1000));
\r
703 return (status == 0) && complete;
\r
706 static void sdReadCID()
\r
711 uint8 status = sdCRCCommandAndResponse(SD_SEND_CID, 0);
\r
712 if(status){return;}
\r
717 startToken = sdSpiByte(0xFF);
\r
718 } while(maxWait-- && (startToken != 0xFE));
\r
719 if (startToken != 0xFE) { return; }
\r
721 for (i = 0; i < 16; ++i)
\r
723 sdDev.cid[i] = sdSpiByte(0xFF);
\r
725 sdSpiByte(0xFF); // CRC
\r
726 sdSpiByte(0xFF); // CRC
\r
729 static int sdReadCSD()
\r
734 uint8 status = sdCRCCommandAndResponse(SD_SEND_CSD, 0);
\r
735 if(status){goto bad;}
\r
740 startToken = sdSpiByte(0xFF);
\r
741 } while(maxWait-- && (startToken != 0xFE));
\r
742 if (startToken != 0xFE) { goto bad; }
\r
744 for (i = 0; i < 16; ++i)
\r
746 sdDev.csd[i] = sdSpiByte(0xFF);
\r
748 sdSpiByte(0xFF); // CRC
\r
749 sdSpiByte(0xFF); // CRC
\r
751 if ((sdDev.csd[0] >> 6) == 0x00)
\r
754 // C_SIZE in bits [73:62]
\r
755 uint32 c_size = (((((uint32)sdDev.csd[6]) & 0x3) << 16) | (((uint32)sdDev.csd[7]) << 8) | sdDev.csd[8]) >> 6;
\r
756 uint32 c_mult = (((((uint32)sdDev.csd[9]) & 0x3) << 8) | ((uint32)sdDev.csd[0xa])) >> 7;
\r
757 uint32 sectorSize = sdDev.csd[5] & 0x0F;
\r
758 sdDev.capacity = ((c_size+1) * ((uint64)1 << (c_mult+2)) * ((uint64)1 << sectorSize)) / SD_SECTOR_SIZE;
\r
760 else if ((sdDev.csd[0] >> 6) == 0x01)
\r
763 // C_SIZE in bits [69:48]
\r
766 ((((uint32)sdDev.csd[7]) & 0x3F) << 16) |
\r
767 (((uint32)sdDev.csd[8]) << 8) |
\r
768 ((uint32)sdDev.csd[7]);
\r
769 sdDev.capacity = (c_size + 1) * 1024;
\r
782 static void sdInitDMA()
\r
784 // One-time init only.
\r
785 static uint8_t init = 0;
\r
790 //TODO MM SEE STUPID SD_DMA_RxCplt that require the SD IRQs to preempt
\r
791 // Configured with 4 bits preemption, NO sub priority.
\r
792 HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 8, 0);
\r
793 HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
\r
794 HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 8, 0);
\r
795 HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
\r
798 SD_TX_DMA_DmaInitialize(
\r
799 2, // Bytes per burst
\r
800 1, // request per burst
\r
801 HI16(CYDEV_SRAM_BASE),
\r
802 HI16(CYDEV_PERIPH_BASE)
\r
806 SD_RX_DMA_DmaInitialize(
\r
807 1, // Bytes per burst
\r
808 1, // request per burst
\r
809 HI16(CYDEV_PERIPH_BASE),
\r
810 HI16(CYDEV_SRAM_BASE)
\r
813 CyDmaChDisable(sdDMATxChan);
\r
814 CyDmaChDisable(sdDMARxChan);
\r
816 SD_RX_DMA_COMPLETE_StartEx(sdRxISR);
\r
817 SD_TX_DMA_COMPLETE_StartEx(sdTxISR);
\r
822 void sdTmpRead(uint8_t* data, uint32_t lba, int sectors)
\r
824 BSP_SD_ReadBlocks_DMA((uint32_t*) data, lba * 512ll, 512, sectors);
\r
827 void sdTmpWrite(uint8_t* data, uint32_t lba, int sectors)
\r
829 BSP_SD_WriteBlocks_DMA((uint32_t*) data, lba * 512ll, 512, sectors);
\r
837 // TODO sdCmdState = CMD_STATE_IDLE;
\r
840 sdDev.capacity = 0;
\r
841 memset(sdDev.csd, 0, sizeof(sdDev.csd));
\r
842 memset(sdDev.cid, 0, sizeof(sdDev.cid));
\r
844 // TODO should be in POLL method!
\r
849 SD_CS_SetDriveMode(SD_CS_DM_STRONG);
\r
850 SD_CS_Write(1); // Set CS inactive (active low)
\r
852 // Set the SPI clock for 400kHz transfers
\r
853 // 25MHz / 400kHz approx factor of 63.
\r
854 // The register contains (divider - 1)
\r
855 uint16_t clkDiv25MHz = SD_Data_Clk_GetDividerRegister();
\r
856 SD_Data_Clk_SetDivider(((clkDiv25MHz + 1) * 63) - 1);
\r
857 // Wait for the clock to settle.
\r
860 SDCard_Start(); // Enable SPI hardware
\r
862 // Power on sequence. 74 clock cycles of a "1" while CS unasserted.
\r
863 for (i = 0; i < 10; ++i)
\r
868 SD_CS_Write(0); // Set CS active (active low)
\r
872 v = sdDoCommand(SD_GO_IDLE_STATE, 0, 1, 0);
\r
873 if(v != 1){goto bad;}
\r
876 if (!sendIfCond()) goto bad; // Sets V1 or V2 flag CMD8
\r
877 if (!sdOpCond()) goto bad; // ACMD41. Wait for init completes.
\r
878 if (!sdReadOCR()) goto bad; // CMD58. Get CCS flag. Only valid after init.
\r
880 // This command will be ignored if sdDev.ccs is set.
\r
881 // SDHC and SDXC are always 512bytes.
\r
882 v = sdCRCCommandAndResponse(SD_SET_BLOCKLEN, SD_SECTOR_SIZE); //Force sector size
\r
884 v = sdCRCCommandAndResponse(SD_CRC_ON_OFF, 0); //crc off
\r
887 // now set the sd card back to full speed.
\r
888 // The SD Card spec says we can run SPI @ 25MHz
\r
891 // We can't run at full-speed with the pullup resistors enabled.
\r
892 SD_MISO_SetDriveMode(SD_MISO_DM_DIG_HIZ);
\r
893 SD_MOSI_SetDriveMode(SD_MOSI_DM_STRONG);
\r
894 SD_SCK_SetDriveMode(SD_SCK_DM_STRONG);
\r
896 SD_Data_Clk_SetDivider(clkDiv25MHz);
\r
900 // Clear out rubbish data through clock change
\r
902 SDCard_ReadRxStatus();
\r
903 SDCard_ReadTxStatus();
\r
904 SDCard_ClearFIFO();
\r
906 if (!sdReadCSD()) goto bad;
\r
913 SD_Data_Clk_SetDivider(clkDiv25MHz); // Restore the clock for our next retry
\r
914 sdDev.capacity = 0;
\r
922 uint8_t error = BSP_SD_Init();
\r
923 if (error == MSD_OK)
\r
925 memcpy(sdDev.csd, &SDCardInfo.SD_csd, sizeof(sdDev.csd));
\r
926 memcpy(sdDev.cid, &SDCardInfo.SD_cid, sizeof(sdDev.cid));
\r
927 sdDev.capacity = SDCardInfo.CardCapacity / SD_SECTOR_SIZE;
\r
928 blockDev.state |= DISK_PRESENT | DISK_INITIALISED;
\r
931 // SD Benchmark code
\r
933 #ifdef SD_BENCHMARK
\r
938 int maxSectors = MAX_SECTOR_SIZE / SD_SECTOR_SIZE;
\r
941 i < (100LL * 1024 * 1024 / (maxSectors * SD_SECTOR_SIZE));
\r
944 sdTmpRead(&scsiDev.data[0], 0, maxSectors);
\r
948 for(int i = 0; i < 10; ++i) s2s_delay_ms(1000);
\r
956 blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED);
\r
958 sdDev.capacity = 0;
\r
966 void sdWriteMultiSectorPrep(uint32_t sdLBA, uint32_t sdSectors)
\r
968 uint32_t tmpNextLBA = sdLBA + sdSectors;
\r
972 sdLBA = sdLBA * SD_SECTOR_SIZE;
\r
973 tmpNextLBA = tmpNextLBA * SD_SECTOR_SIZE;
\r
976 if (sdCmdState == CMD_STATE_WRITE && sdCmdNextLBA == sdLBA)
\r
978 // Well, that was lucky. We're already writing this data
\r
979 sdCmdNextLBA = tmpNextLBA;
\r
980 sdCmdTime = getTime_ms();
\r
984 sdPreCmdState(CMD_STATE_WRITE);
\r
986 // Set the number of blocks to pre-erase by the multiple block write
\r
987 // command. We don't care about the response - if the command is not
\r
988 // accepted, writes will just be a bit slower. Max 22bit parameter.
\r
989 uint32 blocks = sdSectors > 0x7FFFFF ? 0x7FFFFF : sdSectors;
\r
990 sdCommandAndResponse(SD_APP_CMD, 0);
\r
991 sdCommandAndResponse(SD_APP_SET_WR_BLK_ERASE_COUNT, blocks);
\r
993 uint8_t v = sdCommandAndResponse(SD_WRITE_MULTIPLE_BLOCK, sdLBA);
\r
998 scsiDev.status = CHECK_CONDITION;
\r
999 scsiDev.target->sense.code = HARDWARE_ERROR;
\r
1000 scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE;
\r
1001 scsiDev.phase = STATUS;
\r
1005 sdCmdTime = getTime_ms();
\r
1006 sdCmdNextLBA = tmpNextLBA;
\r
1007 sdCmdState = CMD_STATE_WRITE;
\r
1014 if ((scsiDev.phase == BUS_FREE) &&
\r
1015 (sdCmdState != CMD_STATE_IDLE) &&
\r
1016 (elapsedTime_ms(sdCmdTime) >= 50))
\r
1018 sdPreCmdState(CMD_STATE_IDLE);
\r
1022 void sdCheckPresent()
\r
1024 // Check if there's an SD card present.
\r
1025 if ((scsiDev.phase == BUS_FREE) &&
\r
1026 (sdIOState == SD_IDLE) &&
\r
1027 (sdCmdState == CMD_STATE_IDLE))
\r
1029 // The CS line is pulled high by the SD card.
\r
1030 // De-assert the line, and check if it's high.
\r
1031 // This isn't foolproof as it'll be left floating without
\r
1032 // an SD card. We can't use the built-in pull-down resistor as it will
\r
1033 // overpower the SD pullup resistor.
\r
1035 SD_CS_SetDriveMode(SD_CS_DM_DIG_HIZ);
\r
1037 // Delay extended to work with 60cm cables running cards at 2.85V
\r
1038 CyDelayCycles(128);
\r
1039 uint8_t cs = SD_CS_Read();
\r
1040 SD_CS_SetDriveMode(SD_CS_DM_STRONG) ;
\r
1042 if (cs && !(blockDev.state & DISK_PRESENT))
\r
1044 static int firstInit = 1;
\r
1051 blockDev.state |= DISK_PRESENT | DISK_INITIALISED;
\r
1053 // Always "start" the device. Many systems (eg. Apple System 7)
\r
1054 // won't respond properly to
\r
1055 // LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED sense
\r
1056 // code, even if they stopped it first with
\r
1057 // START STOP UNIT command.
\r
1058 blockDev.state |= DISK_STARTED;
\r
1063 for (i = 0; i < MAX_SCSI_TARGETS; ++i)
\r
1065 scsiDev.targets[i].unitAttention = PARAMETERS_CHANGED;
\r
1071 else if (!cs && (blockDev.state & DISK_PRESENT))
\r
1073 sdDev.capacity = 0;
\r
1074 blockDev.state &= ~DISK_PRESENT;
\r
1075 blockDev.state &= ~DISK_INITIALISED;
\r
1077 for (i = 0; i < MAX_SCSI_TARGETS; ++i)
\r
1079 scsiDev.targets[i].unitAttention = PARAMETERS_CHANGED;
\r