?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /******************************************************************************
2 *
3 * Microchip Memory Disk Drive File System
4 *
5 ******************************************************************************
6 * FileName: SD-SPI.c
7 * Dependencies: SD-SPI.h
8 * string.h
9 * FSIO.h
10 * FSDefs.h
11 * Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32
12 * Compiler: C18/C30/C32
13 * Company: Microchip Technology, Inc.
14 *
15 * Software License Agreement
16 *
17 * The software supplied herewith by Microchip Technology Incorporated
18 * (the “Company”) for its PICmicro® Microcontroller is intended and
19 * supplied to you, the Company’s customer, for use solely and
20 * exclusively on Microchip PICmicro Microcontroller products. The
21 * software is owned by the Company and/or its supplier, and is
22 * protected under applicable copyright laws. All rights are reserved.
23 * Any use in violation of the foregoing restrictions may subject the
24 * user to criminal sanctions under applicable laws, as well as to
25 * civil liability for the breach of the terms and conditions of this
26 * license.
27 *
28 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
29 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
30 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
32 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
33 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
34 *
35 *****************************************************************************
36 File Description:
37  
38 Change History:
39 Rev Description
40 ----- -----------
41 1.2.5 Fixed bug in the calculation of the capacity for v1.0 devices
42 1.2.6 No change
43 ********************************************************************/
44  
45 #include "Compiler.h"
46 #include "GenericTypeDefs.h"
47 #include "MDD File System\FSIO.h"
48 #include "MDD File System\FSDefs.h"
49 #include "MDD File System\SD-SPI.h"
50 #include "string.h"
51 #include "FSConfig.h"
52 #include "HardwareProfile.h"
53  
54 /******************************************************************************
55 * Global Variables
56 *****************************************************************************/
57  
58 // Description: Used for the mass-storage library to determine capacity
59 DWORD MDD_SDSPI_finalLBA;
60 WORD gMediaSectorSize;
61 BYTE gSDMode;
62 static MEDIA_INFORMATION mediaInformation;
63  
64 #ifdef __18CXX
65 // Summary: Table of SD card commands and parameters
66 // Description: The sdmmc_cmdtable contains an array of SD card commands, the corresponding CRC code, the
67 // response type that the card will return, and a parameter indicating whether to expect
68 // additional data from the card.
69 const rom typMMC_CMD sdmmc_cmdtable[] =
70 #else
71 const typMMC_CMD sdmmc_cmdtable[] =
72 #endif
73 {
74 // cmd crc response
75 {cmdGO_IDLE_STATE, 0x95, R1, NODATA},
76 {cmdSEND_OP_COND, 0xF9, R1, NODATA},
77 {cmdSEND_IF_COND, 0x87, R7, NODATA},
78 {cmdSEND_CSD, 0xAF, R1, MOREDATA},
79 {cmdSEND_CID, 0x1B, R1, MOREDATA},
80 {cmdSTOP_TRANSMISSION, 0xC3, R1, NODATA},
81 {cmdSEND_STATUS, 0xAF, R2, NODATA},
82 {cmdSET_BLOCKLEN, 0xFF, R1, NODATA},
83 {cmdREAD_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
84 {cmdREAD_MULTI_BLOCK, 0xFF, R1, MOREDATA},
85 {cmdWRITE_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
86 {cmdWRITE_MULTI_BLOCK, 0xFF, R1, MOREDATA},
87 {cmdTAG_SECTOR_START, 0xFF, R1, NODATA},
88 {cmdTAG_SECTOR_END, 0xFF, R1, NODATA},
89 {cmdERASE, 0xDF, R1b, NODATA},
90 {cmdAPP_CMD, 0x73, R1, NODATA},
91 {cmdREAD_OCR, 0x25, R7, NODATA},
92 {cmdCRC_ON_OFF, 0x25, R1, NODATA}
93 };
94  
95  
96  
97  
98 /******************************************************************************
99 * Prototypes
100 *****************************************************************************/
101 extern void Delayms(BYTE milliseconds);
102 BYTE MDD_SDSPI_ReadMedia(void);
103 MEDIA_INFORMATION * MDD_SDSPI_MediaInitialize(void);
104 MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address);
105  
106 #if defined __C30__ || defined __C32__
107 void OpenSPIM ( unsigned int sync_mode);
108 void CloseSPIM( void );
109 unsigned char WriteSPIM( unsigned char data_out );
110 #elif defined __18CXX
111 void OpenSPIM ( unsigned char sync_mode);
112 void CloseSPIM( void );
113 unsigned char WriteSPIM( unsigned char data_out );
114  
115 unsigned char WriteSPIManual(unsigned char data_out);
116 BYTE ReadMediaManual (void);
117 MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address);
118 #endif
119  
120  
121 #ifdef __PIC32MX__
122 /*********************************************************
123 Function:
124 static inline __attribute__((always_inline)) unsigned char SPICacutateBRG (unsigned int pb_clk, unsigned int spi_clk)
125 Summary:
126 Calculate the PIC32 SPI BRG value
127 Conditions:
128 None
129 Input:
130 pb_clk - The value of the PIC32 peripheral clock
131 spi_clk - The desired baud rate
132 Return:
133 The corresponding BRG register value.
134 Side Effects:
135 None.
136 Description:
137 The SPICalutateBRG function is used to determine an appropriate BRG register value for the PIC32 SPI module.
138 Remarks:
139 None
140 *********************************************************/
141  
142 static inline __attribute__((always_inline)) unsigned char SPICalutateBRG(unsigned int pb_clk, unsigned int spi_clk)
143 {
144 unsigned int brg;
145  
146 brg = pb_clk / (2 * spi_clk);
147  
148 if(pb_clk % (2 * spi_clk))
149 brg++;
150  
151 if(brg > 0x100)
152 brg = 0x100;
153  
154 if(brg)
155 brg--;
156  
157 return (unsigned char) brg;
158 }
159 #endif
160  
161  
162 /*********************************************************
163 Function:
164 BYTE MDD_SDSPI_MediaDetect
165 Summary:
166 Determines whether an SD card is present
167 Conditions:
168 The MDD_MediaDetect function pointer must be configured
169 to point to this function in FSconfig.h
170 Input:
171 None
172 Return Values:
173 TRUE - Card detected
174 FALSE - No card detected
175 Side Effects:
176 None.
177 Description:
178 The MDD_SDSPI_MediaDetect function determine if an SD card is connected to
179 the microcontroller.
180 If the MEDIA_SOFT_DETECT is not defined, the detection is done by polling
181 the SD card detect pin.
182 The MicroSD connector does not have a card detect pin, and therefore a
183 software mechanism must be used. To do this, the SEND_STATUS command is sent
184 to the card. If the card is not answering with 0x00, the card is either not
185 present, not configured, or in an error state. If this is the case, we try
186 to reconfigure the card. If the configuration fails, we consider the card not
187 present (it still may be present, but malfunctioning). In order to use the
188 software card detect mechanism, the MEDIA_SOFT_DETECT macro must be defined.
189  
190 Remarks:
191 None
192 *********************************************************/
193  
194 BYTE MDD_SDSPI_MediaDetect (void)
195 {
196 #ifndef MEDIA_SOFT_DETECT
197 return(!SD_CD);
198 #else
199 MMC_RESPONSE response;
200  
201 if (SPIENABLE == 0)
202 {
203 /* If the SPI module is not enabled, send manually the SEND_STATUS command */
204 #if (GetSystemClock() >= 25600000)
205 /* should only be here when GetSystemClock() >= 25600000 */
206 response = SendMMCCmdManual(SEND_STATUS,0x0);
207 #endif
208 }
209 else
210 {
211 response = SendMMCCmd(SEND_STATUS,0x0);
212 }
213  
214 /* Check the response to the SEND_STATUS command*/
215 if(response.r2._word != 0x00)
216 {
217 /* the card has not responded correctly to the SEND_STATUS command; try to reinitialize it */
218 MDD_SDSPI_MediaInitialize();
219 if (mediaInformation.errorCode == MEDIA_NO_ERROR)
220 {
221 /* if the card was reinitialized correctly, it means it is present */
222 return 1;
223 }
224 else
225 {
226 return 0;
227 }
228 }
229 else
230 {
231 /* No error was reported, the card is present and not */
232 return 1;
233 }
234 #endif
235  
236 }//end MediaDetect
237  
238  
239  
240 /*********************************************************
241 Function:
242 WORD MDD_SDSPI_ReadSectorSize (void)
243 Summary:
244 Determines the current sector size on the SD card
245 Conditions:
246 MDD_MediaInitialize() is complete
247 Input:
248 None
249 Return:
250 The size of the sectors for the physical media
251 Side Effects:
252 None.
253 Description:
254 The MDD_SDSPI_ReadSectorSize function is used by the
255 USB mass storage class to return the card's sector
256 size to the PC on request.
257 Remarks:
258 None
259 *********************************************************/
260  
261 WORD MDD_SDSPI_ReadSectorSize(void)
262 {
263 return gMediaSectorSize;
264 }
265  
266  
267 /*********************************************************
268 Function:
269 DWORD MDD_SDSPI_ReadCapacity (void)
270 Summary:
271 Determines the current capacity of the SD card
272 Conditions:
273 MDD_MediaInitialize() is complete
274 Input:
275 None
276 Return:
277 The capacity of the device
278 Side Effects:
279 None.
280 Description:
281 The MDD_SDSPI_ReadCapacity function is used by the
282 USB mass storage class to return the total number
283 of sectors on the card.
284 Remarks:
285 None
286 *********************************************************/
287 DWORD MDD_SDSPI_ReadCapacity(void)
288 {
289 return (MDD_SDSPI_finalLBA);
290 }
291  
292  
293 /*********************************************************
294 Function:
295 WORD MDD_SDSPI_InitIO (void)
296 Summary:
297 Initializes the I/O lines connected to the card
298 Conditions:
299 MDD_MediaInitialize() is complete. The MDD_InitIO
300 function pointer is pointing to this function.
301 Input:
302 None
303 Return:
304 None
305 Side Effects:
306 None.
307 Description:
308 The MDD_SDSPI_InitIO function initializes the I/O
309 pins connected to the SD card.
310 Remarks:
311 None
312 *********************************************************/
313  
314 void MDD_SDSPI_InitIO (void)
315 {
316 // Turn off the card
317 SD_CD_TRIS = INPUT; //Card Detect - input
318 SD_CS = 1; //Initialize Chip Select line
319 SD_CS_TRIS = OUTPUT; //Card Select - output
320 SD_WE_TRIS = INPUT; //Write Protect - input
321 }
322  
323  
324  
325 /*********************************************************
326 Function:
327 BYTE MDD_SDSPI_ShutdownMedia (void)
328 Summary:
329 Disables the SD card
330 Conditions:
331 The MDD_ShutdownMedia function pointer is pointing
332 towards this function.
333 Input:
334 None
335 Return:
336 None
337 Side Effects:
338 None.
339 Description:
340 This function will disable the SPI port and deselect
341 the SD card.
342 Remarks:
343 None
344 *********************************************************/
345  
346 BYTE MDD_SDSPI_ShutdownMedia(void)
347 {
348 // close the spi bus
349 CloseSPIM();
350  
351 // deselect the device
352 SD_CS = 1;
353  
354 return 0;
355 }
356  
357  
358 /*****************************************************************************
359 Function:
360 MMC_RESPONSE SendMMCCmd (BYTE cmd, DWORD address)
361 Summary:
362 Sends a command packet to the SD card.
363 Conditions:
364 None.
365 Input:
366 None.
367 Return Values:
368 MMC_RESPONSE - The response from the card
369 - Bit 0 - Idle state
370 - Bit 1 - Erase Reset
371 - Bit 2 - Illegal Command
372 - Bit 3 - Command CRC Error
373 - Bit 4 - Erase Sequence Error
374 - Bit 5 - Address Error
375 - Bit 6 - Parameter Error
376 - Bit 7 - Unused. Always 0.
377 Side Effects:
378 None.
379 Description:
380 SendMMCCmd prepares a command packet and sends it out over the SPI interface.
381 Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
382 Remarks:
383 None.
384 ***************************************************************************************/
385  
386 MMC_RESPONSE SendMMCCmd(BYTE cmd, DWORD address)
387 {
388 WORD timeout = 0x8;
389 BYTE index;
390 MMC_RESPONSE response;
391 CMD_PACKET CmdPacket;
392  
393 SD_CS = 0; //Card Select
394  
395 // Copy over data
396 CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
397 CmdPacket.address = address;
398 CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
399  
400 CmdPacket.TRANSMIT_BIT = 1; //Set Tranmission bit
401  
402 WriteSPIM(CmdPacket.cmd); //Send Command
403 WriteSPIM(CmdPacket.addr3); //Most Significant Byte
404 WriteSPIM(CmdPacket.addr2);
405 WriteSPIM(CmdPacket.addr1);
406 WriteSPIM(CmdPacket.addr0); //Least Significant Byte
407 WriteSPIM(CmdPacket.crc); //Send CRC
408  
409 // see if we are going to get a response
410 if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b || sdmmc_cmdtable[cmd].responsetype == R7)
411 {
412 do
413 {
414 response.r1._byte = MDD_SDSPI_ReadMedia();
415 timeout--;
416 }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
417 }
418 else if(sdmmc_cmdtable[cmd].responsetype == R2)
419 {
420 MDD_SDSPI_ReadMedia();
421  
422 response.r2._byte1 = MDD_SDSPI_ReadMedia();
423 response.r2._byte0 = MDD_SDSPI_ReadMedia();
424 }
425  
426 if(sdmmc_cmdtable[cmd].responsetype == R1b)
427 {
428 response.r1._byte = 0x00;
429  
430 for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
431 {
432 timeout = 0xFFFF;
433  
434 do
435 {
436 response.r1._byte = MDD_SDSPI_ReadMedia();
437 timeout--;
438 }while(response.r1._byte == 0x00 && timeout != 0);
439 }
440 }
441  
442 if (sdmmc_cmdtable[cmd].responsetype == R7)
443 {
444 response.r7.bytewise._returnVal = (DWORD)MDD_SDSPI_ReadMedia() << 24;
445 response.r7.bytewise._returnVal += (DWORD)MDD_SDSPI_ReadMedia() << 16;
446 response.r7.bytewise._returnVal += (DWORD)MDD_SDSPI_ReadMedia() << 8;
447 response.r7.bytewise._returnVal += (DWORD)MDD_SDSPI_ReadMedia();
448 }
449  
450 mSend8ClkCycles(); //Required clocking (see spec)
451  
452 // see if we are expecting data or not
453 if(!(sdmmc_cmdtable[cmd].moredataexpected))
454 SD_CS = 1;
455  
456 return(response);
457 }
458  
459 #ifdef __18CXX
460 #if (GetSystemClock() >= 25600000)
461  
462 /*****************************************************************************
463 Function:
464 MMC_RESPONSE SendMMCCmdManual (BYTE cmd, DWORD address)
465 Summary:
466 Sends a command packet to the SD card with bit-bang SPI.
467 Conditions:
468 None.
469 Input:
470 None.
471 Return Values:
472 MMC_RESPONSE - The response from the card
473 - Bit 0 - Idle state
474 - Bit 1 - Erase Reset
475 - Bit 2 - Illegal Command
476 - Bit 3 - Command CRC Error
477 - Bit 4 - Erase Sequence Error
478 - Bit 5 - Address Error
479 - Bit 6 - Parameter Error
480 - Bit 7 - Unused. Always 0.
481 Side Effects:
482 None.
483 Description:
484 SendMMCCmd prepares a command packet and sends it out over the SPI interface.
485 Response data of type 'R1' (as indicated by the SD/MMC product manual is returned.
486 This function is intended to be used when the clock speed of a PIC18 device is
487 so high that the maximum SPI divider can't reduce the clock below the maximum
488 SD card initialization sequence speed.
489 Remarks:
490 None.
491 ***************************************************************************************/
492  
493 MMC_RESPONSE SendMMCCmdManual(BYTE cmd, DWORD address)
494 {
495 WORD timeout = 0x8;
496 BYTE index;
497 MMC_RESPONSE response;
498 CMD_PACKET CmdPacket;
499  
500 SD_CS = 0; //Card Select
501  
502 // Copy over data
503 CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
504 CmdPacket.address = address;
505 CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
506  
507 CmdPacket.TRANSMIT_BIT = 1; //Set Tranmission bit
508  
509 WriteSPIManual(CmdPacket.cmd); //Send Command
510 WriteSPIManual(CmdPacket.addr3); //Most Significant Byte
511 WriteSPIManual(CmdPacket.addr2);
512 WriteSPIManual(CmdPacket.addr1);
513 WriteSPIManual(CmdPacket.addr0); //Least Significant Byte
514 WriteSPIManual(CmdPacket.crc); //Send CRC
515  
516 // see if we are going to get a response
517 if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b || sdmmc_cmdtable[cmd].responsetype == R7)
518 {
519 do
520 {
521 response.r1._byte = ReadMediaManual();
522 timeout--;
523 }while(response.r1._byte == MMC_FLOATING_BUS && timeout != 0);
524 }
525 else if(sdmmc_cmdtable[cmd].responsetype == R2)
526 {
527 ReadMediaManual();
528  
529 response.r2._byte1 = ReadMediaManual();
530 response.r2._byte0 = ReadMediaManual();
531 }
532  
533 if(sdmmc_cmdtable[cmd].responsetype == R1b)
534 {
535 response.r1._byte = 0x00;
536  
537 for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
538 {
539 timeout = 0xFFFF;
540  
541 do
542 {
543 response.r1._byte = ReadMediaManual();
544 timeout--;
545 }while(response.r1._byte == 0x00 && timeout != 0);
546 }
547 }
548 if (sdmmc_cmdtable[cmd].responsetype == R7)
549 {
550 response.r7.bytewise._returnVal = (DWORD)ReadMediaManual() << 24;
551 response.r7.bytewise._returnVal += (DWORD)ReadMediaManual() << 16;
552 response.r7.bytewise._returnVal += (DWORD)ReadMediaManual() << 8;
553 response.r7.bytewise._returnVal += (DWORD)ReadMediaManual();
554 }
555  
556 WriteSPIManual(0xFF); //Required clocking (see spec)
557  
558 // see if we are expecting data or not
559 if(!(sdmmc_cmdtable[cmd].moredataexpected))
560 SD_CS = 1;
561  
562 return(response);
563 }
564 #endif
565 #endif
566  
567  
568  
569 /*****************************************************************************
570 Function:
571 BYTE MDD_SDSPI_SectorRead (DWORD sector_addr, BYTE * buffer)
572 Summary:
573 Reads a sector of data from an SD card.
574 Conditions:
575 The MDD_SectorRead function pointer must be pointing towards this function.
576 Input:
577 sector_addr - The address of the sector on the card.
578 byffer - The buffer where the retrieved data will be stored. If
579 buffer is NULL, do not store the data anywhere.
580 Return Values:
581 TRUE - The sector was read successfully
582 FALSE - The sector could not be read
583 Side Effects:
584 None
585 Description:
586 The MDD_SDSPI_SectorRead function reads a sector of data bytes (512 bytes)
587 of data from the SD card starting at the sector address and stores them in
588 the location pointed to by 'buffer.'
589 Remarks:
590 The card expects the address field in the command packet to be a byte address.
591 The sector_addr value is converted to a byte address by shifting it left nine
592 times (multiplying by 512).
593 ***************************************************************************************/
594  
595 BYTE MDD_SDSPI_SectorRead(DWORD sector_addr, BYTE* buffer)
596 {
597 WORD index;
598 WORD delay;
599 MMC_RESPONSE response;
600 BYTE data_token;
601 BYTE status = TRUE;
602 DWORD new_addr;
603  
604 // send the cmd
605 if (gSDMode == SD_MODE_NORMAL)
606 new_addr = sector_addr << 9;
607 else
608 new_addr = sector_addr;
609 response = SendMMCCmd(READ_SINGLE_BLOCK,new_addr);
610  
611 // Make sure the command was accepted
612 if(response.r1._byte != 0x00)
613 {
614 response = SendMMCCmd (READ_SINGLE_BLOCK,new_addr);
615 if(response.r1._byte != 0x00)
616 {
617 return FALSE;
618 }
619 }
620  
621 index = 0x2FF;
622  
623 // Timing delay- at least 8 clock cycles
624 delay = 0x40;
625 while (delay)
626 delay--;
627  
628 //Now, must wait for the start token of data block
629 do
630 {
631 data_token = MDD_SDSPI_ReadMedia();
632 index--;
633  
634 delay = 0x40;
635 while (delay)
636 delay--;
637  
638 }while((data_token == MMC_FLOATING_BUS) && (index != 0));
639  
640 // Hopefully that zero is the datatoken
641 if((index == 0) || (data_token != DATA_START_TOKEN))
642 {
643 status = FALSE;
644 }
645 else
646 {
647 for(index = 0; index < gMediaSectorSize; index++) //Reads in a sector of data (512 bytes)
648 {
649 if(buffer != NULL)
650 {
651 #ifdef __18CXX
652 data_token = SPIBUF;
653 SPI_INTERRUPT_FLAG = 0;
654 SPIBUF = 0xFF;
655 while(!SPI_INTERRUPT_FLAG);
656 buffer[index] = SPIBUF;
657 #elif defined (__PIC32MX__)
658 buffer[index] = MDD_SDSPI_ReadMedia();
659 #else
660 SPIBUF = 0xFF;
661 while (!SPISTAT_RBF);
662 buffer[index] = SPIBUF;
663 #endif
664 }
665 else
666 {
667 MDD_SDSPI_ReadMedia();
668 }
669 }
670 // Now ensure CRC
671 mReadCRC(); //Read 2 bytes of CRC
672 //status = mmcCardCRCError;
673 }
674  
675 mSend8ClkCycles(); //Required clocking (see spec)
676  
677 SD_CS = 1;
678  
679 return(status);
680 }//end SectorRead
681  
682  
683 /*****************************************************************************
684 Function:
685 BYTE MDD_SDSPI_SectorWrite (DWORD sector_addr, BYTE * buffer, BYTE allowWriteToZero)
686 Summary:
687 Writes a sector of data to an SD card.
688 Conditions:
689 The MDD_SectorWrite function pointer must be pointing to this function.
690 Input:
691 sector_addr - The address of the sector on the card.
692 buffer - The buffer with the data to write.
693 allowWriteToZero -
694 - TRUE - Writes to the 0 sector (MBR) are allowed
695 - FALSE - Any write to the 0 sector will fail.
696 Return Values:
697 TRUE - The sector was written successfully.
698 FALSE - The sector could not be written.
699 Side Effects:
700 None.
701 Description:
702 The MDD_SDSPI_SectorWrite function writes one sector of data (512 bytes)
703 of data from the location pointed to by 'buffer' to the specified sector of
704 the SD card.
705 Remarks:
706 The card expects the address field in the command packet to be a byte address.
707 The sector_addr value is ocnverted to a byte address by shifting it left nine
708 times (multiplying by 512).
709 ***************************************************************************************/
710  
711 BYTE MDD_SDSPI_SectorWrite(DWORD sector_addr, BYTE* buffer, BYTE allowWriteToZero)
712 {
713 WORD index;
714 DWORD counter;
715 BYTE data_response;
716 MMC_RESPONSE response;
717 BYTE status = TRUE;
718  
719 if (sector_addr == 0 && allowWriteToZero == FALSE)
720 status = FALSE;
721 else
722 {
723 // send the cmd
724  
725 if (gSDMode == SD_MODE_NORMAL)
726 response = SendMMCCmd(WRITE_SINGLE_BLOCK,(sector_addr << 9));
727 else
728 response = SendMMCCmd(WRITE_SINGLE_BLOCK,(sector_addr));
729  
730 // see if it was accepted
731 if(response.r1._byte != 0x00)
732 status = FALSE;
733 else
734 {
735 WriteSPIM(DATA_START_TOKEN); //Send data start token
736  
737 for(index = 0; index < gMediaSectorSize; index++) //Send 512 bytes
738 {
739 #ifdef __18CXX
740 data_response = SPIBUF; //Clear BF flag, just in case it was previously left set.
741 SPI_INTERRUPT_FLAG = 0; //Clear interrupt flag, in case it was previously left set.
742 SPIBUF = buffer[index]; // write byte to SSP1BUF register
743 while( !SPI_INTERRUPT_FLAG ); // wait until bus cycle complete
744 data_response = SPIBUF; // Clear the SPIBUF
745 #elif defined (__PIC32MX__)
746 WriteSPIM(buffer[index]);
747 #else
748 SPIBUF = buffer[index];
749 while (!SPISTAT_RBF);
750 data_response = SPIBUF;
751 #endif
752 }
753  
754 // calc crc
755 mSendCRC(); //Send 2 bytes of CRC
756  
757 data_response = MDD_SDSPI_ReadMedia(); //Read response
758  
759 if((data_response & 0x0F) != DATA_ACCEPTED)
760 {
761 status = FALSE;
762 }
763 else
764 {
765 #if defined (__PIC32MX__)
766 do
767 {
768 putcSPI((unsigned int)0xFF);
769 data_response = getcSPI();
770 }while(!data_response);
771 #else
772 #ifdef __18CXX
773 counter = GetInstructionClock() / 82;
774 do //Wait for write completion
775 {
776 data_response = SPIBUF;
777 SPI_INTERRUPT_FLAG = 0;
778 SPIBUF = 0xFF;
779 counter--;
780 while(!SPI_INTERRUPT_FLAG);
781 data_response = SPIBUF;
782 }while((data_response == 0x00) && (counter != 0));
783 #else
784 counter = GetInstructionClock() / 44;
785 do //Wait for write completion
786 {
787 SPIBUF = 0xFF;
788 counter--;
789 while(!SPISTAT_RBF);
790 data_response = SPIBUF;
791 }while((data_response == 0x00) && (counter != 0));
792 #endif
793  
794 if(counter == 0) //if timeout first
795 status = FALSE;
796 #endif
797 }
798  
799 mSend8ClkCycles();
800 }
801  
802 SD_CS = 1;
803  
804 } // Not writing to 0 sector
805  
806 return(status);
807 } //end SectorWrite
808  
809  
810 /*****************************************************************************
811 Function:
812 BYTE MDD_SDSPI_WriteProtectState
813 Summary:
814 Indicates whether the card is write-protected.
815 Conditions:
816 The MDD_WriteProtectState function pointer must be pointing to this function.
817 Input:
818 None.
819 Return Values:
820 TRUE - The card is write-protected
821 FALSE - The card is not write-protected
822 Side Effects:
823 None.
824 Description:
825 The MDD_SDSPI_WriteProtectState function will determine if the SD card is
826 write protected by checking the electrical signal that corresponds to the
827 physical write-protect switch.
828 Remarks:
829 None
830 ***************************************************************************************/
831  
832 BYTE MDD_SDSPI_WriteProtectState(void)
833 {
834 return(SD_WE);
835 }
836  
837  
838 /*****************************************************************************
839 Function:
840 void Delayms (BYTE milliseconds)
841 Summary:
842 Delay.
843 Conditions:
844 None.
845 Input:
846 BYTE milliseconds - Number of ms to delay
847 Return:
848 None.
849 Side Effects:
850 None.
851 Description:
852 The Delayms function will delay a specified number of milliseconds. Used for SPI
853 timing.
854 Remarks:
855 Depending on compiler revisions, this function may delay for the exact time
856 specified. This shouldn't create a significant problem.
857 ***************************************************************************************/
858  
859 void Delayms(BYTE milliseconds)
860 {
861 BYTE ms;
862 DWORD count;
863  
864 ms = milliseconds;
865 while (ms--)
866 {
867 count = MILLISECDELAY;
868 while (count--);
869 }
870 Nop();
871 return;
872 }
873  
874  
875 /*****************************************************************************
876 Function:
877 void CloseSPIM (void)
878 Summary:
879 Disables the SPI module.
880 Conditions:
881 None.
882 Input:
883 None.
884 Return:
885 None.
886 Side Effects:
887 None.
888 Description:
889 Disables the SPI module.
890 Remarks:
891 None.
892 ***************************************************************************************/
893  
894 void CloseSPIM (void)
895 {
896 #if defined __C30__ || defined __C32__
897  
898 SPISTAT &= 0x7FFF;
899  
900 #elif defined __18CXX
901  
902 SPICON1 &= 0xDF;
903  
904 #endif
905 }
906  
907  
908  
909 /*****************************************************************************
910 Function:
911 unsigned char WriteSPIM (unsigned char data_out)
912 Summary:
913 Writes data to the SD card.
914 Conditions:
915 None.
916 Input:
917 data_out - The data to write.
918 Return:
919 0.
920 Side Effects:
921 None.
922 Description:
923 The WriteSPIM function will write a byte of data from the microcontroller to the
924 SD card.
925 Remarks:
926 None.
927 ***************************************************************************************/
928  
929 unsigned char WriteSPIM( unsigned char data_out )
930 {
931 #ifdef __PIC32MX__
932 BYTE clear;
933 putcSPI((BYTE)data_out);
934 clear = getcSPI();
935 return ( 0 ); // return non-negative#
936 #elif defined __18CXX
937 BYTE clear;
938 clear = SPIBUF;
939 SPI_INTERRUPT_FLAG = 0;
940 SPIBUF = data_out;
941 if (SPICON1 & 0x80)
942 return -1;
943 else
944 while (!SPI_INTERRUPT_FLAG);
945 return 0;
946 #else
947 BYTE clear;
948 SPIBUF = data_out; // write byte to SSP1BUF register
949 while( !SPISTAT_RBF ); // wait until bus cycle complete
950 clear = SPIBUF;
951 return ( 0 ); // return non-negative#
952 #endif
953 }
954  
955  
956  
957 /*****************************************************************************
958 Function:
959 BYTE MDD_SDSPI_ReadMedia (void)
960 Summary:
961 Reads a byte of data from the SD card.
962 Conditions:
963 None.
964 Input:
965 None.
966 Return:
967 The byte read.
968 Side Effects:
969 None.
970 Description:
971 The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
972 Remarks:
973 This function replaces ReadSPI, since some implementations of that function
974 will initialize SSPBUF/SPIBUF to 0x00 when reading. The card expects 0xFF.
975 ***************************************************************************************/
976 BYTE MDD_SDSPI_ReadMedia(void)
977 {
978  
979 #ifdef __C32__
980  
981 putcSPI((BYTE)0xFF);
982 return (BYTE)getcSPI();
983  
984 #elif defined __18CXX
985  
986 BYTE clear;
987 clear = SPIBUF;
988 SPI_INTERRUPT_FLAG = 0;
989 SPIBUF = 0xFF;
990 while (!SPI_INTERRUPT_FLAG);
991 return SPIBUF;
992  
993 #else
994 SPIBUF = 0xFF; //Data Out - Logic ones
995 while(!SPISTAT_RBF); //Wait until cycle complete
996 return(SPIBUF); //Return with byte read
997 #endif
998 }
999  
1000 /*****************************************************************************
1001 Function:
1002 void OpenSPIM (unsigned int sync_mode)
1003 Summary:
1004 Initializes the SPI module
1005 Conditions:
1006 None.
1007 Input:
1008 sync_mode - Sets synchronization
1009 Return:
1010 None.
1011 Side Effects:
1012 None.
1013 Description:
1014 The OpenSPIM function will enable and configure the SPI module.
1015 Remarks:
1016 None.
1017 ***************************************************************************************/
1018  
1019 #ifdef __18CXX
1020 void OpenSPIM (unsigned char sync_mode)
1021 #else
1022 void OpenSPIM( unsigned int sync_mode)
1023 #endif
1024 {
1025 SPISTAT = 0x0000; // power on state
1026  
1027 #ifndef __PIC32MX__
1028 SPICON1 = 0x0000; // power on state
1029 SPICON1 |= sync_mode; // select serial mode
1030 #endif
1031  
1032 #ifdef __18CXX
1033 SPICON1 |= 0x80;
1034 SPISTATbits.CKE = 1;
1035 #else
1036 SPICON1bits.CKP = 1;
1037 SPICON1bits.CKE = 0;
1038 #endif
1039  
1040 SPICLOCK = 0;
1041 SPIOUT = 0; // define SDO1 as output (master or slave)
1042 SPIIN = 1; // define SDI1 as input (master or slave)
1043 SPIENABLE = 1; // enable synchronous serial port
1044 }
1045  
1046  
1047 #ifdef __18CXX
1048 #if (GetSystemClock() >= 25600000)
1049  
1050 // Description: Delay value for the manual SPI clock
1051 #define MANUAL_SPI_CLOCK_VALUE 1
1052 /*****************************************************************************
1053 Function:
1054 unsigned char WriteSPIManual (unsigned char data_out)
1055 Summary:
1056 Write a character to the SD card with bit-bang SPI.
1057 Conditions:
1058 Make sure the SDI pin is pre-configured as a digital pin, if it is
1059 multiplexed with analog functionality.
1060 Input:
1061 data_out - Data to send.
1062 Return:
1063 0.
1064 Side Effects:
1065 None.
1066 Description:
1067 Writes a character to the SD card.
1068 Remarks:
1069 The WriteSPIManual function is for use on a PIC18 when the clock speed is so
1070 high that the maximum SPI clock divider cannot reduce the SPI clock speed below
1071 the maximum SD card initialization speed.
1072 ***************************************************************************************/
1073 unsigned char WriteSPIManual(unsigned char data_out)
1074 {
1075 unsigned char i;
1076 unsigned char clock;
1077  
1078 SPICLOCKLAT = 0;
1079 SPIOUTLAT = 1;
1080 SPICLOCK = OUTPUT;
1081 SPIOUT = OUTPUT;
1082  
1083 //Loop to send out 8 bits of SDO data and associated SCK clock.
1084 for(i = 0; i < 8; i++)
1085 {
1086 SPICLOCKLAT = 0;
1087 if(data_out & 0x80)
1088 SPIOUTLAT = 1;
1089 else
1090 SPIOUTLAT = 0;
1091 data_out = data_out << 1; //Bit shift, so next bit to send is in MSb position
1092 clock = MANUAL_SPI_CLOCK_VALUE;
1093 while (clock--);
1094 SPICLOCKLAT = 1;
1095 clock = MANUAL_SPI_CLOCK_VALUE;
1096 while (clock--);
1097 }
1098 SPICLOCKLAT = 0;
1099  
1100 return 0;
1101 }
1102  
1103  
1104 /*****************************************************************************
1105 Function:
1106 BYTE ReadMediaManual (void)
1107 Summary:
1108 Reads a byte of data from the SD card.
1109 Conditions:
1110 None.
1111 Input:
1112 None.
1113 Return:
1114 The byte read.
1115 Side Effects:
1116 None.
1117 Description:
1118 The MDD_SDSPI_ReadMedia function will read one byte from the SPI port.
1119 Remarks:
1120 This function replaces ReadSPI, since some implementations of that function
1121 will initialize SSPBUF/SPIBUF to 0x00 when reading. The card expects 0xFF.
1122 This function is for use on a PIC18 when the clock speed is so high that the
1123 maximum SPI clock prescaler cannot reduce the SPI clock below the maximum SD card
1124 initialization speed.
1125 ***************************************************************************************/
1126 BYTE ReadMediaManual (void)
1127 {
1128 unsigned char i;
1129 unsigned char clock;
1130 unsigned char result = 0x00;
1131  
1132 SPIOUTLAT = 1;
1133 SPIOUT = OUTPUT;
1134 SPIIN = INPUT;
1135 SPICLOCKLAT = 0;
1136 SPICLOCK = OUTPUT;
1137  
1138 //Loop to send 8 clock pulses and read in the returned bits of data. Data "sent" will be = 0xFF
1139 for(i = 0; i < 8; i++)
1140 {
1141 SPICLOCKLAT = 0;
1142 clock = MANUAL_SPI_CLOCK_VALUE;
1143 while (clock--);
1144 SPICLOCKLAT = 1;
1145 clock = MANUAL_SPI_CLOCK_VALUE;
1146 while (clock--);
1147 result = result << 1; //Bit shift the previous result. We receive the byte MSb first. This operation makes LSb = 0.
1148 if(SPIINPORT)
1149 result++; //Set the LSb if we detected a '1' on the SPIINPORT pin, otherwise leave as 0.
1150 }
1151 SPICLOCKLAT = 0;
1152  
1153 return result;
1154 }//end ReadMedia
1155  
1156 #endif // End >25600000
1157 #endif // End __18CXX
1158  
1159  
1160 /*****************************************************************************
1161 Function:
1162 MEDIA_INFORMATION * MDD_SDSPI_MediaInitialize (void)
1163 Summary:
1164 Initializes the SD card.
1165 Conditions:
1166 The MDD_MediaInitialize function pointer must be pointing to this function.
1167 Input:
1168 None.
1169 Return Values:
1170 The function returns a pointer to the MEDIA_INFORMATION structure. The
1171 errorCode member may contain the following values:
1172 * MEDIA_NO_ERROR - The media initialized successfully
1173 * MEDIA_CANNOT_INITIALIZE - Cannot initialize the media.
1174 Side Effects:
1175 None.
1176 Description:
1177 This function will send initialization commands to and SD card.
1178 Remarks:
1179 None.
1180 ***************************************************************************************/
1181 MEDIA_INFORMATION * MDD_SDSPI_MediaInitialize(void)
1182 {
1183 WORD timeout;
1184 MMC_RESPONSE response;
1185 BYTE CSDResponse[20];
1186 BYTE count, index;
1187 DWORD c_size;
1188 BYTE c_size_mult;
1189 BYTE block_len;
1190  
1191 #if defined __C30__ || defined __C32__
1192 WORD spiconvalue = 0x0003;
1193 #endif
1194 mediaInformation.errorCode = MEDIA_NO_ERROR;
1195 mediaInformation.validityFlags.value = 0;
1196 MDD_SDSPI_finalLBA = 0x00000000; //Will compute a valid value later, from the CSD register values we get from the card
1197  
1198 SD_CS = 1; //Initialize Chip Select line
1199  
1200 //Media powers up in the open-drain mode and cannot handle a clock faster
1201 //than 400kHz. Initialize SPI port to slower than 400kHz
1202 #if defined __C30__ || defined __C32__
1203 #ifdef __PIC32MX__
1204 OpenSPI(SPI_START_CFG_1, SPI_START_CFG_2);
1205 SPIBRG = SPICalutateBRG(GetPeripheralClock(), 400000);
1206 #else //else C30 = PIC24/dsPIC devices
1207 // Calculate the prescaler needed for the clock
1208 timeout = GetSystemClock() / 400000;
1209 // if timeout is less than 400k and greater than 100k use a 1:1 prescaler
1210 if (timeout == 0)
1211 {
1212 OpenSPIM (MASTER_ENABLE_ON | PRI_PRESCAL_1_1 | SEC_PRESCAL_1_1);
1213 }
1214 else
1215 {
1216 while (timeout != 0)
1217 {
1218 if (timeout > 8)
1219 {
1220 spiconvalue--;
1221 // round up
1222 if ((timeout % 4) != 0)
1223 timeout += 4;
1224 timeout /= 4;
1225 }
1226 else
1227 {
1228 break;
1229 }
1230 }
1231  
1232 timeout--;
1233  
1234 OpenSPIM (MASTER_ENABLE_ON | spiconvalue | ((~(timeout << 2)) & 0x1C));
1235 }
1236 #endif //#ifdef __PIC32MX__ (and corresponding #else)
1237  
1238  
1239 // let the card power on and initialize
1240 Delayms(1);
1241  
1242 //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
1243 for(timeout=0; timeout<10; timeout++)
1244 mSend8ClkCycles();
1245  
1246 SD_CS = 0;
1247  
1248 Delayms(1);
1249  
1250 // Send CMD0 to reset the media
1251 response = SendMMCCmd(GO_IDLE_STATE,0x0);
1252  
1253 if((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
1254 {
1255 SD_CS = 1; // deselect the devices
1256 mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
1257 return &mediaInformation;
1258 }
1259  
1260 response = SendMMCCmd(SEND_IF_COND, 0x1AA);
1261 if (((response.r7.bytewise._returnVal & 0xFFF) == 0x1AA) && (!response.r7.bitwise.bits.ILLEGAL_CMD))
1262 {
1263 timeout = 0xFFF;
1264 do
1265 {
1266 response = SendMMCCmd(SEND_OP_COND, 0x40000000);
1267 timeout--;
1268 }while(response.r1._byte != 0x00 && timeout != 0);
1269 response = SendMMCCmd(READ_OCR, 0x0);
1270 if (((response.r7.bytewise._returnVal & 0xC0000000) == 0xC0000000) && (response.r7.bytewise._byte == 0))
1271 {
1272 gSDMode = SD_MODE_HC;
1273 }
1274 else //if (((response.r7.bytewise._returnVal & 0xC0000000) == 0x80000000) && (response.r7.bytewise._byte == 0))
1275 {
1276 gSDMode = SD_MODE_NORMAL;
1277 }
1278 }
1279 else
1280 {
1281 gSDMode = SD_MODE_NORMAL;
1282  
1283 // According to spec cmd1 must be repeated until the card is fully initialized
1284 timeout = 0xFFF;
1285 do
1286 {
1287 response = SendMMCCmd(SEND_OP_COND,0x0);
1288 timeout--;
1289 }while(response.r1._byte != 0x00 && timeout != 0);
1290 }
1291  
1292 // see if it failed
1293 if(timeout == 0)
1294 {
1295 mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
1296 SD_CS = 1; // deselect the devices
1297 }
1298 else
1299 {
1300 #else //PIC18 device (#else of: #if defined __C30__ || defined __C32__)
1301  
1302 // let the card power on and initialize
1303 Delayms(1);
1304  
1305 #if (GetSystemClock() < 25600000)
1306  
1307 #if (GetSystemClock() < 1600000)
1308 OpenSPIM (SYNC_MODE_FAST);
1309 #elif (GetSystemClock() < 6400000)
1310 OpenSPIM (SYNC_MODE_MED);
1311 #else
1312 OpenSPIM (SYNC_MODE_SLOW);
1313 #endif
1314  
1315 // let the card power on and initialize
1316 Delayms(1);
1317  
1318 //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
1319 for(timeout=0; timeout<10; timeout++)
1320 mSend8ClkCycles();
1321  
1322 SD_CS = 0;
1323  
1324 Delayms(1);
1325  
1326 // Send CMD0 to reset the media
1327 response = SendMMCCmd(GO_IDLE_STATE,0x0);
1328  
1329 if((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
1330 {
1331 mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
1332 SD_CS = 1; // deselect the devices
1333 return &mediaInformation;
1334 }
1335  
1336 response = SendMMCCmd(SEND_IF_COND, 0x1AA);
1337 if (((response.r7.bytewise._returnVal & 0xFFF) == 0x1AA) && (!response.r7.bitwise.bits.ILLEGAL_CMD))
1338 {
1339 timeout = 0xFFF;
1340 do
1341 {
1342 response = SendMMCCmd(SEND_OP_COND, 0x40000000);
1343 timeout--;
1344 }while(response.r1._byte != 0x00 && timeout != 0);
1345 response = SendMMCCmd(READ_OCR, 0x0);
1346 if (((response.r7.bytewise._returnVal & 0xC0000000) == 0xC0000000) && (response.r7.bytewise._byte == 0))
1347 {
1348 gSDMode = SD_MODE_HC;
1349 }
1350 else //if (((response.r7.bytewise._returnVal & 0xC0000000) == 0x80000000) && (response.r7.bytewise._byte == 0))
1351 {
1352 gSDMode = SD_MODE_NORMAL;
1353 }
1354 }
1355 else
1356 {
1357 gSDMode = SD_MODE_NORMAL;
1358  
1359 // According to spec cmd1 must be repeated until the card is fully initialized
1360 timeout = 0xFFF;
1361 do
1362 {
1363 response = SendMMCCmd(SEND_OP_COND,0x0);
1364 timeout--;
1365 }while(response.r1._byte != 0x00 && timeout != 0);
1366 }
1367  
1368 #else //else of (#if (GetSystemClock() < 25600000))
1369 // Make sure the SPI module doesn't control the bus
1370 SPICON1 = 0x00;
1371  
1372 //Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
1373 for(timeout=0; timeout<10; timeout++)
1374 WriteSPIManual(0xFF);
1375  
1376 SD_CS = 0;
1377  
1378 Delayms(1);
1379  
1380 // Send CMD0 to reset the media
1381 response = SendMMCCmdManual (GO_IDLE_STATE, 0x0);
1382  
1383 if ((response.r1._byte == MMC_BAD_RESPONSE) || ((response.r1._byte & 0xF7) != 0x01))
1384 {
1385 SD_CS = 1; // deselect the devices
1386 mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
1387 return &mediaInformation;
1388 }
1389  
1390 response = SendMMCCmdManual(SEND_IF_COND, 0x1AA);
1391 if (((response.r7.bytewise._returnVal & 0xFFF) == 0x1AA) && (!response.r7.bitwise.bits.ILLEGAL_CMD))
1392 {
1393 timeout = 0xFFF;
1394 do
1395 {
1396 response = SendMMCCmdManual(SEND_OP_COND, 0x40000000);
1397 timeout--;
1398 }while(response.r1._byte != 0x00 && timeout != 0);
1399 response = SendMMCCmdManual(READ_OCR, 0x0);
1400 if (((response.r7.bytewise._returnVal & 0xC0000000) == 0xC0000000) && (response.r7.bytewise._byte == 0))
1401 {
1402 gSDMode = SD_MODE_HC;
1403 }
1404 else //if (((response.r7.bytewise._returnVal & 0xC0000000) == 0x80000000) && (response.r7.bytewise._byte == 0))
1405 {
1406 gSDMode = SD_MODE_NORMAL;
1407 }
1408 }
1409 else
1410 {
1411 gSDMode = SD_MODE_NORMAL;
1412 // According to the spec cmd1 must be repeated until the card is fully initialized
1413 timeout = 0xFFF;
1414 do
1415 {
1416 response = SendMMCCmdManual (SEND_OP_COND, 0x0);
1417 timeout--;
1418 }while(response.r1._byte != 0x00 && timeout != 0);
1419 }
1420 #endif //end of #if (GetSystemClock() < 25600000), and #else
1421  
1422 // see if it failed
1423 if (timeout == 0)
1424 {
1425 mediaInformation.errorCode = MEDIA_CANNOT_INITIALIZE;
1426 SD_CS = 1; // deselect the devices
1427 }
1428 else
1429 {
1430 #endif //end of (#if defined __C30__ || defined __C32__)), and #else (PIC18)
1431 //Common code below for all processors.
1432  
1433 Delayms (2);
1434  
1435 #ifdef __PIC32MX__
1436 #if (GetSystemClock() <= 20000000)
1437 SPIBRG = SPICalutateBRG(GetPeripheralClock(), 10000);
1438 #else
1439 SPIBRG = SPICalutateBRG(GetPeripheralClock(), SPI_FREQUENCY);
1440 #endif
1441 #else
1442 OpenSPIM(SYNC_MODE_FAST);
1443 #endif
1444  
1445 /* Send the CMD9 to read the CSD register */
1446 timeout = 0xFFF;
1447 do
1448 {
1449 response = SendMMCCmd(SEND_CSD, 0x00);
1450 timeout--;
1451 }while((response.r1._byte != 0x00) && (timeout != 0));
1452  
1453 /* According to the simplified spec, section 7.2.6, the card will respond
1454 with a standard response token, followed by a data block of 16 bytes
1455 suffixed with a 16-bit CRC.*/
1456 index = 0;
1457 for (count = 0; count < 20; count ++)
1458 {
1459 CSDResponse[index] = MDD_SDSPI_ReadMedia();
1460 index ++;
1461 /* Hopefully the first byte is the datatoken, however, some cards do
1462 not send the response token before the CSD register.*/
1463 if((count == 0) && (CSDResponse[0] == DATA_START_TOKEN))
1464 {
1465 /* As the first byte was the datatoken, we can drop it. */
1466 index = 0;
1467 }
1468 }
1469  
1470 //Extract some fields from the response for computing the card capacity.
1471 //Note: The structure format depends on if it is a CSD V1 or V2 device.
1472 //Therefore, need to first determine version of the specs that the card
1473 //is designed for, before interpreting the individual fields.
1474  
1475 //-------------------------------------------------------------
1476 //READ_BL_LEN: CSD Structure v1 cards always support 512 byte
1477 //read and write block lengths. Some v1 cards may optionally report
1478 //READ_BL_LEN = 1024 or 2048 bytes (and therefore WRITE_BL_LEN also
1479 //1024 or 2048). However, even on these cards, 512 byte partial reads
1480 //and 512 byte write are required to be supported.
1481 //On CSD structure v2 cards, it is always required that READ_BL_LEN
1482 //(and therefore WRITE_BL_LEN) be 512 bytes, and partial reads and
1483 //writes are not allowed.
1484 //Therefore, all cards support 512 byte reads/writes, but only a subset
1485 //of cards support other sizes. For best compatibility with all cards,
1486 //and the simplest firmware design, it is therefore preferrable to
1487 //simply ignore the READ_BL_LEN and WRITE_BL_LEN values altogether,
1488 //and simply hardcode the read/write block size as 512 bytes.
1489 //-------------------------------------------------------------
1490 gMediaSectorSize = 512u;
1491 mediaInformation.validityFlags.bits.sectorSize = TRUE;
1492 mediaInformation.sectorSize = gMediaSectorSize;
1493 //-------------------------------------------------------------
1494  
1495 //Calculate the MDD_SDSPI_finalLBA (see SD card physical layer simplified spec 2.0, section 5.3.2).
1496 //In USB mass storage applications, we will need this information to
1497 //correctly respond to SCSI get capacity requests. Note: method of computing
1498 //MDD_SDSPI_finalLBA depends on CSD structure spec version (either v1 or v2).
1499 if(CSDResponse[0] & 0xC0) //Check CSD_STRUCTURE field for v2+ struct device
1500 {
1501 //Must be a v2 device (or a reserved higher version, that doesn't currently exist)
1502  
1503 //Extract the C_SIZE field from the response. It is a 22-bit number in bit position 69:48. This is different from v1.
1504 //It spans bytes 7, 8, and 9 of the response.
1505 c_size = (((DWORD)CSDResponse[7] & 0x3F) << 16) | ((WORD)CSDResponse[8] << 8) | CSDResponse[9];
1506  
1507 MDD_SDSPI_finalLBA = ((DWORD)(c_size + 1) * (WORD)(1024u)) - 1; //-1 on end is correction factor, since LBA = 0 is valid.
1508 }
1509 else //if(CSDResponse[0] & 0xC0) //Check CSD_STRUCTURE field for v1 struct device
1510 {
1511 //Must be a v1 device.
1512 //Extract the C_SIZE field from the response. It is a 12-bit number in bit position 73:62.
1513 //Although it is only a 12-bit number, it spans bytes 6, 7, and 8, since it isn't byte aligned.
1514 c_size = ((DWORD)CSDResponse[6] << 16) | ((WORD)CSDResponse[7] << 8) | CSDResponse[8]; //Get the bytes in the correct positions
1515 c_size &= 0x0003FFC0; //Clear all bits that aren't part of the C_SIZE
1516 c_size = c_size >> 6; //Shift value down, so the 12-bit C_SIZE is properly right justified in the DWORD.
1517  
1518 //Extract the C_SIZE_MULT field from the response. It is a 3-bit number in bit position 49:47.
1519 c_size_mult = ((WORD)((CSDResponse[9] & 0x03) << 1)) | ((WORD)((CSDResponse[10] & 0x80) >> 7));
1520  
1521 //Extract the BLOCK_LEN field from the response. It is a 4-bit number in bit position 83:80.
1522 block_len = CSDResponse[5] & 0x0F;
1523  
1524 block_len = 1 << (block_len - 9); //-9 because we report the size in sectors of 512 bytes each
1525  
1526 //Calculate the MDD_SDSPI_finalLBA (see SD card physical layer simplified spec 2.0, section 5.3.2).
1527 //In USB mass storage applications, we will need this information to
1528 //correctly respond to SCSI get capacity requests (which will cause MDD_SDSPI_ReadCapacity() to get called).
1529 MDD_SDSPI_finalLBA = ((DWORD)(c_size + 1) * (WORD)((WORD)1 << (c_size_mult + 2)) * block_len) - 1; //-1 on end is correction factor, since LBA = 0 is valid.
1530 }
1531  
1532 // Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)
1533 response = SendMMCCmd(CRC_ON_OFF,0x0);
1534  
1535 // Now set the block length to media sector size. It should be already
1536 response = SendMMCCmd(SET_BLOCKLEN,gMediaSectorSize);
1537 }
1538  
1539 return &mediaInformation;
1540 }//end MediaInitialize
1541  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3