C1541-III mbed edition

Dependencies:   mbed

Committer:
gertk
Date:
Mon Aug 22 21:11:59 2011 +0000
Revision:
1:0cbbb66a6100
Parent:
0:28557a4d2215
updated the nRESET pin to an interrupt capable pin (p29)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gertk 0:28557a4d2215 1 /*------------------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 2 /*This is the lowlevel MMC/SD-card driver, */
gertk 0:28557a4d2215 3 /*in order to function with the allready available software, the routines use the name ATA */
gertk 0:28557a4d2215 4 /* */
gertk 0:28557a4d2215 5 /*Note that this driver is dirty because it polls the drive for it's flags. The */
gertk 0:28557a4d2215 6 /*routines in this driver should therefore only be called from a low priority task */
gertk 0:28557a4d2215 7 /*------------------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 8
gertk 0:28557a4d2215 9 /* History:
gertk 0:28557a4d2215 10 2007-09-28 Minor layout changes
gertk 0:28557a4d2215 11 2006-08-25 Hurray, SanDisk wouldn't be SanDisk if they wouldn't have something different in the specifications that are to be considered as STANDARD !!! Why tell me why (as in the famous song of Anita Meijer)
gertk 0:28557a4d2215 12 The 'manual-rs-mms.pdf' version of 13-5-2004, page 5-12 states: CMD55 (SPI) This optional MMCA command is not supported in the SanDisk MultiMediaCard/RS-MultiMediaCard.
gertk 0:28557a4d2215 13 How are the big-boys able to work with these kind of standards what kind of info do they have that I don't have.
gertk 0:28557a4d2215 14 Well, it's up to me now to handle this exception... <zucht>
gertk 0:28557a4d2215 15 2006-08-24 all card now work EXCEPT the SanDisk RS-MMC, it even claims to be an SD-card... at least in my code, wonder why that is, back to the documentation
gertk 0:28557a4d2215 16 2006-08-23 Hurray, the card that first would not function is now functional !!!
gertk 0:28557a4d2215 17 COMPLETELY NUTS!!! Some MMC/SD-cards DO NOT, I repeat DO NOT function according specification,
gertk 0:28557a4d2215 18 normally after giving the command 'CMD17' the command responds with an error token (should be 0 when all is OK)
gertk 0:28557a4d2215 19 But for some reason some cards do not give this and simply answer 0xFF (instead of 0x00) this code is not even vaild according specs...
gertk 0:28557a4d2215 20 I do not get it, but when I simply ignore the expected response and immediatley start polling for the start-of-data then there is no problem what so ever...
gertk 0:28557a4d2215 21 Have they gone nuts or am I missing something... why is nobody following the protocol... this is RS232 connectors all over again.
gertk 0:28557a4d2215 22 For those who are not familiar whith RS232 connectors, some people still do not know the difference between
gertk 0:28557a4d2215 23 DTE and DCE and just mount a connector that fits to the device that is not meant to be connected in the way it is used. And wire the pins until it works and viola... no longer according specs, but it works in their own setup so it appears nothing is wrong, that is until you connect a device that is according specs...
gertk 0:28557a4d2215 24 2006-08-21 added more debugging info in order to find the problem regarding the problems with some card not being supported...
gertk 0:28557a4d2215 25 added a retry mechanism on the SDCARD_init() routine
gertk 0:28557a4d2215 26 renamed the routines SDCARD to CARD, this because it also handles MMC cards so the old name was incorrect
gertk 0:28557a4d2215 27 2006-02-02 improvements in code layout... i.o.w. making it more readable
gertk 0:28557a4d2215 28 2006-01-29 added first steps for byte addressable read routine (read X bytes)
gertk 0:28557a4d2215 29 2006-01-26 a routine waiting for 0xFE contained a ';' to much, so it did not timeout
gertk 0:28557a4d2215 30 2005-12-23 removal of the CS handling routines... not required for this project...
gertk 0:28557a4d2215 31 2005-12-11 (Dennis) added proper CS handling to enable sharing of SPI bus
gertk 0:28557a4d2215 32 2005-04-19 start of project
gertk 0:28557a4d2215 33 */
gertk 0:28557a4d2215 34
gertk 0:28557a4d2215 35
gertk 0:28557a4d2215 36 /* TO DO:
gertk 0:28557a4d2215 37 ------
gertk 0:28557a4d2215 38 - improve 'AtaRead_X_Bytes'
gertk 0:28557a4d2215 39
gertk 0:28557a4d2215 40 */
gertk 0:28557a4d2215 41 /*------------------------------------------------------------------------------------------*/
gertk 0:28557a4d2215 42
gertk 0:28557a4d2215 43 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 44 /* includes */
gertk 0:28557a4d2215 45 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 46 #include "mbed.h"
gertk 0:28557a4d2215 47
gertk 0:28557a4d2215 48 //#include <stdio.h>
gertk 0:28557a4d2215 49 #include "ata.h"
gertk 0:28557a4d2215 50 #include "hardware.h"
gertk 0:28557a4d2215 51
gertk 0:28557a4d2215 52 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 53 /* constants */
gertk 0:28557a4d2215 54 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 55 #define FALSE 0 /*FALSE*/
gertk 0:28557a4d2215 56 #define TRUE 1 /*TRUE*/
gertk 0:28557a4d2215 57 #define MMCCARD 2
gertk 0:28557a4d2215 58 #define SDCARD 3
gertk 0:28557a4d2215 59
gertk 0:28557a4d2215 60 /*MMC commandset*/
gertk 0:28557a4d2215 61 #define CMD0 0x40 /*Resets the multimedia card*/
gertk 0:28557a4d2215 62 #define CMD1 0x41 /*Activates the card's initialization process*/
gertk 0:28557a4d2215 63 #define CMD2 0x42 /*--*/
gertk 0:28557a4d2215 64 #define CMD3 0x43 /*--*/
gertk 0:28557a4d2215 65 #define CMD4 0x44 /*--*/
gertk 0:28557a4d2215 66 #define CMD5 0x45 /*reseved*/
gertk 0:28557a4d2215 67 #define CMD6 0x46 /*reserved*/
gertk 0:28557a4d2215 68 #define CMD7 0x47 /*--*/
gertk 0:28557a4d2215 69 #define CMD8 0x48 /*reserved*/
gertk 0:28557a4d2215 70 #define CMD9 0x49 /*CSD : Ask the selected card to send its card specific data*/
gertk 0:28557a4d2215 71 #define CMD10 0x4a /*CID : Ask the selected card to send its card identification*/
gertk 0:28557a4d2215 72 #define CMD11 0x4b /*--*/
gertk 0:28557a4d2215 73 #define CMD12 0x4c /*STOP-command*/
gertk 0:28557a4d2215 74 #define CMD13 0x4d /*Ask the selected card to send its status register*/
gertk 0:28557a4d2215 75 #define CMD14 0x4e /*--*/
gertk 0:28557a4d2215 76 #define CMD15 0x4f /*--*/
gertk 0:28557a4d2215 77 #define CMD16 0x50 /*Select a block length (in bytes) for all following block commands (Read:between 1-512 and Write:only 512)*/
gertk 0:28557a4d2215 78 #define CMD17 0x51 /*Reads a block of the size selected by the SET_BLOCKLEN command, the start address and block length must be set so that the data transferred will not cross a physical block boundry*/
gertk 0:28557a4d2215 79 #define CMD18 0x52 /*--*/
gertk 0:28557a4d2215 80 #define CMD19 0x53 /*reserved*/
gertk 0:28557a4d2215 81 #define CMD20 0x54 /*--*/
gertk 0:28557a4d2215 82 #define CMD21 0x55 /*reserved*/
gertk 0:28557a4d2215 83 #define CMD22 0x56 /*reserved*/
gertk 0:28557a4d2215 84 #define CMD23 0x57 /*reserved*/
gertk 0:28557a4d2215 85 #define CMD24 0x58 /*Writes a block of the size selected by CMD16, the start address must be alligned on a sector boundry, the block length is always 512 bytes*/
gertk 0:28557a4d2215 86 #define CMD25 0x59 /*--*/
gertk 0:28557a4d2215 87 #define CMD26 0x5a /*--*/
gertk 0:28557a4d2215 88 #define CMD27 0x5b /*Programming of the programmable bits of the CSD*/
gertk 0:28557a4d2215 89 #define CMD28 0x5c /*If the card has write protection features, this command sets the write protection bit of the addressed group. The porperties of the write protection are coded in the card specific data (WP_GRP_SIZE)*/
gertk 0:28557a4d2215 90 #define CMD29 0x5d /*If the card has write protection features, this command clears the write protection bit of the addressed group*/
gertk 0:28557a4d2215 91 #define CMD30 0x5e /*If the card has write protection features, this command asks the card to send the status of the write protection bits. 32 write protection bits (representing 32 write protect groups starting at the specific address) followed by 16 CRD bits are transferred in a payload format via the data line*/
gertk 0:28557a4d2215 92 #define CMD31 0x5f /*reserved*/
gertk 0:28557a4d2215 93 #define CMD32 0x60 /*sets the address of the first sector of the erase group*/
gertk 0:28557a4d2215 94 #define CMD33 0x61 /*Sets the address of the last sector in a cont. range within the selected erase group, or the address of a single sector to be selected for erase*/
gertk 0:28557a4d2215 95 #define CMD34 0x62 /*Removes on previously selected sector from the erase selection*/
gertk 0:28557a4d2215 96 #define CMD35 0x63 /*Sets the address of the first erase group within a range to be selected for erase*/
gertk 0:28557a4d2215 97 #define CMD36 0x64 /*Sets the address of the last erase group within a continuos range to be selected for erase*/
gertk 0:28557a4d2215 98 #define CMD37 0x65 /*Removes one previously selected erase group from the erase selection*/
gertk 0:28557a4d2215 99 #define CMD38 0x66 /*Erases all previously selected sectors*/
gertk 0:28557a4d2215 100 #define CMD39 0x67 /*--*/
gertk 0:28557a4d2215 101 #define CMD40 0x68 /*--*/
gertk 0:28557a4d2215 102 #define CMD41 0x69 /*reserved*/
gertk 0:28557a4d2215 103 #define CMD42 0x6a /*reserved*/
gertk 0:28557a4d2215 104 #define CMD43 0x6b /*reserved*/
gertk 0:28557a4d2215 105 #define CMD44 0x6c /*reserved*/
gertk 0:28557a4d2215 106 #define CMD45 0x6d /*reserved*/
gertk 0:28557a4d2215 107 #define CMD46 0x6e /*reserved*/
gertk 0:28557a4d2215 108 #define CMD47 0x6f /*reserved*/
gertk 0:28557a4d2215 109 #define CMD48 0x70 /*reserved*/
gertk 0:28557a4d2215 110 #define CMD49 0x71 /*reserved*/
gertk 0:28557a4d2215 111 #define CMD50 0x72 /*reserved*/
gertk 0:28557a4d2215 112 #define CMD51 0x73 /*reserved*/
gertk 0:28557a4d2215 113 #define CMD52 0x74 /*reserved*/
gertk 0:28557a4d2215 114 #define CMD53 0x75 /*reserved*/
gertk 0:28557a4d2215 115 #define CMD54 0x76 /*reserved*/
gertk 0:28557a4d2215 116 #define CMD55 0x77 /*reserved*/
gertk 0:28557a4d2215 117 #define CMD56 0x78 /*reserved*/
gertk 0:28557a4d2215 118 #define CMD57 0x79 /*reserved*/
gertk 0:28557a4d2215 119 #define CMD58 0x7a /*reserved*/
gertk 0:28557a4d2215 120 #define CMD59 0x7b /*Turns the CRC option ON or OFF. A '1' in the CRC option bit will turn the option ON, a '0' will turn it OFF*/
gertk 0:28557a4d2215 121 #define CMD60 0x7c /*--*/
gertk 0:28557a4d2215 122 #define CMD61 0x7d /*--*/
gertk 0:28557a4d2215 123 #define CMD62 0x7e /*--*/
gertk 0:28557a4d2215 124 #define CMD63 0x7f /*--*/
gertk 0:28557a4d2215 125
gertk 0:28557a4d2215 126 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 127 /* globals */
gertk 0:28557a4d2215 128 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 129 unsigned char crc_7; /*contains CRC value*/
gertk 0:28557a4d2215 130 unsigned char response_1; /*byte that holds the first response byte*/
gertk 0:28557a4d2215 131 unsigned char response_2; /*byte that holds the second response byte*/
gertk 0:28557a4d2215 132 unsigned char response_3; /*byte that holds the third response byte*/
gertk 0:28557a4d2215 133 unsigned char response_4; /*byte that holds the fourth response byte*/
gertk 0:28557a4d2215 134 unsigned char response_5; /*byte that holds the fifth response byte*/
gertk 0:28557a4d2215 135
gertk 0:28557a4d2215 136 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 137 /* local functions */
gertk 0:28557a4d2215 138 /*--------------------------------------------------------*/
gertk 0:28557a4d2215 139 void Command_R0(char cmd,unsigned short AdrH,unsigned short AdrL);
gertk 0:28557a4d2215 140 void Command_R1(char cmd,unsigned short AdrH,unsigned short AdrL);
gertk 0:28557a4d2215 141 void Command_R2(char cmd,unsigned short AdrH,unsigned short AdrL);
gertk 0:28557a4d2215 142 void Command_R3(char cmd,unsigned short AdrH,unsigned short AdrL);
gertk 0:28557a4d2215 143 void MmcAddCrc7(unsigned char c);
gertk 0:28557a4d2215 144 void set_SPI_LowSpeed(void);
gertk 0:28557a4d2215 145 void set_SPI_HighSpeed(void);
gertk 0:28557a4d2215 146 unsigned char Card_CMD0(void);
gertk 0:28557a4d2215 147 unsigned char Card_CMD1(void);
gertk 0:28557a4d2215 148 unsigned char Card_BlockSize(void);
gertk 0:28557a4d2215 149 unsigned char WaitForSOD(void);
gertk 0:28557a4d2215 150 unsigned char Card_CID(void);
gertk 0:28557a4d2215 151 unsigned char Card_CSD(void);
gertk 0:28557a4d2215 152
gertk 0:28557a4d2215 153 /*************************************************************************************/
gertk 0:28557a4d2215 154 /*************************************************************************************/
gertk 0:28557a4d2215 155 /*External functions*/
gertk 0:28557a4d2215 156 /*************************************************************************************/
gertk 0:28557a4d2215 157 /*************************************************************************************/
gertk 0:28557a4d2215 158 SPI spicard(p11, p12, p13); // mosi, miso, sclk
gertk 0:28557a4d2215 159 DigitalOut SDCARD_CS(p14);
gertk 0:28557a4d2215 160 extern Timer timeout;
gertk 0:28557a4d2215 161 #define mySPI spicard.write
gertk 0:28557a4d2215 162
gertk 0:28557a4d2215 163 void set_SPI_LowSpeed(void)
gertk 0:28557a4d2215 164 {
gertk 0:28557a4d2215 165 spicard.frequency(100000); // low speed 100 kHz
gertk 0:28557a4d2215 166 }
gertk 0:28557a4d2215 167
gertk 0:28557a4d2215 168 void set_SPI_HighSpeed(void)
gertk 0:28557a4d2215 169 {
gertk 0:28557a4d2215 170 spicard.frequency(1000000); // Set to 1MHz for data transfer
gertk 0:28557a4d2215 171 }
gertk 0:28557a4d2215 172
gertk 0:28557a4d2215 173 /*wait for start of data transfer with timeout*/
gertk 0:28557a4d2215 174 unsigned char WaitForSOD(void)
gertk 0:28557a4d2215 175 {
gertk 0:28557a4d2215 176
gertk 0:28557a4d2215 177 timeout.reset();
gertk 0:28557a4d2215 178
gertk 0:28557a4d2215 179 while(mySPI(0xFF) != 0xFE)
gertk 0:28557a4d2215 180 if (timeout.read_us() >= 1000)
gertk 0:28557a4d2215 181 {
gertk 0:28557a4d2215 182 return(FALSE);
gertk 0:28557a4d2215 183 }
gertk 0:28557a4d2215 184 return(TRUE);
gertk 0:28557a4d2215 185 }
gertk 0:28557a4d2215 186
gertk 0:28557a4d2215 187 /*Enable the SDcard correctly*/
gertk 0:28557a4d2215 188 unsigned char CARD_Init(void)
gertk 0:28557a4d2215 189 {
gertk 0:28557a4d2215 190 unsigned short lp;
gertk 0:28557a4d2215 191
gertk 0:28557a4d2215 192 set_SPI_LowSpeed();
gertk 0:28557a4d2215 193 SDCARD_CS=1; /*SDcard Disabled*/
gertk 0:28557a4d2215 194 for(lp=0;lp<10;lp++) /*Set SDcard in SPI-Mode, Reset*/
gertk 0:28557a4d2215 195 mySPI(0xFF); /*10 * 8bits = 80 clockpulses*/
gertk 0:28557a4d2215 196 SDCARD_CS=0; /*SDcard Enabled*/
gertk 0:28557a4d2215 197
gertk 0:28557a4d2215 198 wait_ms(50);
gertk 0:28557a4d2215 199 // for(lp=0;lp<50000;lp++); /*delay for a lot of milliseconds (at least 16 bus clock cycles)*/
gertk 0:28557a4d2215 200
gertk 0:28557a4d2215 201 if (Card_CMD0() == FALSE)
gertk 0:28557a4d2215 202 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 203
gertk 0:28557a4d2215 204 Command_R1(CMD55,0,0); /*when the response is 0x04 (illegal command), this must be an MMC-card*/
gertk 0:28557a4d2215 205 if (response_1 == 0x05) /*determine MMC or SD*/
gertk 0:28557a4d2215 206 { /*An MMC-card has been detected, handle accordingly*/
gertk 0:28557a4d2215 207 /*-------------------------------------------------*/
gertk 0:28557a4d2215 208 if (Card_CMD1() == FALSE)
gertk 0:28557a4d2215 209 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 210 }
gertk 0:28557a4d2215 211 else
gertk 0:28557a4d2215 212 { /*An SD-card has been detected, handle accordingly*/
gertk 0:28557a4d2215 213 /*-------------------------------------------------*/
gertk 0:28557a4d2215 214 timeout.reset();
gertk 0:28557a4d2215 215 response_1 = 1;
gertk 0:28557a4d2215 216 while(response_1 != 0)
gertk 0:28557a4d2215 217 {
gertk 0:28557a4d2215 218 Command_R1(CMD41,0,0);
gertk 0:28557a4d2215 219 Command_R1(CMD55,0,0);
gertk 0:28557a4d2215 220 if (timeout.read_us() > 10000) /*timeout mechanism*/
gertk 0:28557a4d2215 221 {
gertk 0:28557a4d2215 222 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 223 }
gertk 0:28557a4d2215 224 }
gertk 0:28557a4d2215 225 }
gertk 0:28557a4d2215 226
gertk 0:28557a4d2215 227 if (Card_BlockSize() == FALSE)
gertk 0:28557a4d2215 228 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 229
gertk 0:28557a4d2215 230 set_SPI_HighSpeed();
gertk 0:28557a4d2215 231 return(TRUE);
gertk 0:28557a4d2215 232 }
gertk 0:28557a4d2215 233
gertk 0:28557a4d2215 234 /*Enable the SDcard according SanDisk RS-MMC (a.k.a. the idiots not follow the world's standards*/
gertk 0:28557a4d2215 235 unsigned char CARD_AlternativeInit(void)
gertk 0:28557a4d2215 236 {
gertk 0:28557a4d2215 237 unsigned short lp;
gertk 0:28557a4d2215 238
gertk 0:28557a4d2215 239 set_SPI_LowSpeed();
gertk 0:28557a4d2215 240 SDCARD_CS=1; /*SDcard Disabled*/
gertk 0:28557a4d2215 241 for(lp=0; lp < 10; lp++) /*Set SDcard in SPI-Mode, Reset*/
gertk 0:28557a4d2215 242 mySPI(0xFF); /*10 * 8bits = 80 clockpulses*/
gertk 0:28557a4d2215 243 SDCARD_CS=0; /*SDcard Enabled*/
gertk 0:28557a4d2215 244
gertk 0:28557a4d2215 245 wait_ms(50);
gertk 0:28557a4d2215 246 // for(lp=0; lp < 50000; lp++); /*delay for a lot of milliseconds (at least 16 bus clock cycles)*/
gertk 0:28557a4d2215 247
gertk 0:28557a4d2215 248 if (Card_CMD0() == FALSE)
gertk 0:28557a4d2215 249 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 250
gertk 0:28557a4d2215 251 if (Card_CMD1() == FALSE)
gertk 0:28557a4d2215 252 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 253
gertk 0:28557a4d2215 254 if (Card_BlockSize() == FALSE)
gertk 0:28557a4d2215 255 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 256
gertk 0:28557a4d2215 257 set_SPI_HighSpeed();
gertk 0:28557a4d2215 258 return(TRUE);
gertk 0:28557a4d2215 259 }
gertk 0:28557a4d2215 260
gertk 0:28557a4d2215 261
gertk 0:28557a4d2215 262 unsigned char Card_BlockSize(void)
gertk 0:28557a4d2215 263 {
gertk 0:28557a4d2215 264 unsigned char retry_counter;
gertk 0:28557a4d2215 265
gertk 0:28557a4d2215 266 retry_counter = 100; /*this routine is verrrrrrrry important, and sometimes fails on some cards so a retry mechanism is crucial*/
gertk 0:28557a4d2215 267 while(retry_counter--)
gertk 0:28557a4d2215 268 {
gertk 0:28557a4d2215 269 Command_R1(CMD16,0,512); /*Set read block length to 512 bytes, by the way 512 is default, but since nobody if following standards...*/
gertk 0:28557a4d2215 270 if (response_1 == 0)
gertk 0:28557a4d2215 271 break;
gertk 0:28557a4d2215 272
gertk 0:28557a4d2215 273 if (retry_counter == 0)
gertk 0:28557a4d2215 274 return(FALSE);
gertk 0:28557a4d2215 275 }
gertk 0:28557a4d2215 276 return(TRUE);
gertk 0:28557a4d2215 277 }
gertk 0:28557a4d2215 278
gertk 0:28557a4d2215 279 unsigned char Card_CID(void)
gertk 0:28557a4d2215 280 {
gertk 0:28557a4d2215 281 Command_R1(CMD10,0,0); /*read CID register (total of 16Bytes)*/
gertk 0:28557a4d2215 282 // if (response_1 !=0)
gertk 0:28557a4d2215 283 // {
gertk 0:28557a4d2215 284 // return(ERROR_CARDINIT_CID); /*exit if invalid response*/
gertk 0:28557a4d2215 285 // }
gertk 0:28557a4d2215 286 if (WaitForSOD() == FALSE) /*wait for start-of-data (function features time-out)*/
gertk 0:28557a4d2215 287 return(FALSE);
gertk 0:28557a4d2215 288
gertk 0:28557a4d2215 289 OutputToRS232(); /*set standard output to RS232*/
gertk 0:28557a4d2215 290 printf("\r\n\r\nCID registers (16bytes)\r\n-----------------------");
gertk 0:28557a4d2215 291 printf("\r\nCID(01) [manuf-ID] = %02X",(mySPI(0xFF))); /*manuf-ID, 3 bytes*/
gertk 0:28557a4d2215 292 printf("\r\nCID(02) [manuf-ID] = %02X",(mySPI(0xFF))); /*manuf-ID, 3 bytes*/
gertk 0:28557a4d2215 293 printf("\r\nCID(03) [manuf-ID] = %02X",(mySPI(0xFF))); /*manuf-ID, 3 bytes*/
gertk 0:28557a4d2215 294 printf("\r\nCID(04) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 295 printf("\r\nCID(05) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 296 printf("\r\nCID(06) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 297 printf("\r\nCID(07) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 298 printf("\r\nCID(08) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 299 printf("\r\nCID(09) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 300 printf("\r\nCID(10) [prodname] = %02X",(mySPI(0xFF))); /*productname, 7 bytes*/
gertk 0:28557a4d2215 301 printf("\r\nCID(11) [0x HW,FW] = %02X",(mySPI(0xFF))); /*revision, hi-nibble=HW, low-nibble=FW, 1 byte*/
gertk 0:28557a4d2215 302 printf("\r\nCID(12) [serial #] = %02X",(mySPI(0xFF))); /*serial number, 3 bytes*/
gertk 0:28557a4d2215 303 printf("\r\nCID(13) [serial #] = %02X",(mySPI(0xFF))); /*serial number, 3 bytes*/
gertk 0:28557a4d2215 304 printf("\r\nCID(14) [serial #] = %02X",(mySPI(0xFF))); /*serial number, 3 bytes*/
gertk 0:28557a4d2215 305 printf("\r\nCID(15) [0x Mo,Ye] = %02X",(mySPI(0xFF))); /*revision, hi-nibble=Month, low-nibble=Year, 1 byte*/
gertk 0:28557a4d2215 306 printf("\r\nCID(16) [7-1 =CRC] = %02X",(mySPI(0xFF))); /*7-1=CRC checksum, 0=not used, 1 byte*/
gertk 0:28557a4d2215 307 OutputToLCD(); /*set standard output to LCD*/
gertk 0:28557a4d2215 308 return(TRUE);
gertk 0:28557a4d2215 309 }
gertk 0:28557a4d2215 310
gertk 0:28557a4d2215 311 unsigned char Card_CSD(void)
gertk 0:28557a4d2215 312 {
gertk 0:28557a4d2215 313 unsigned short lp;
gertk 0:28557a4d2215 314
gertk 0:28557a4d2215 315 Command_R1(CMD9,0,0); /*read CSD register*/
gertk 0:28557a4d2215 316 // if (response_1 !=0)
gertk 0:28557a4d2215 317 // {
gertk 0:28557a4d2215 318 // return(ERROR_CARDINIT_CSD); /*exit if invalid response*/
gertk 0:28557a4d2215 319 // }
gertk 0:28557a4d2215 320 if (WaitForSOD() == FALSE) /*wait for start-of-data (function features time-out)*/
gertk 0:28557a4d2215 321 return(FALSE);
gertk 0:28557a4d2215 322
gertk 0:28557a4d2215 323 OutputToRS232(); /*set standard output to RS232*/
gertk 0:28557a4d2215 324 printf("\r\n\r\nCSD registers (16bytes)\r\n-----------------------");
gertk 0:28557a4d2215 325 for(lp=0; lp < 17; lp++)
gertk 0:28557a4d2215 326 {
gertk 0:28557a4d2215 327 printf("\r\nCSD(%02d) = %02X",lp,(mySPI(0xFF)));
gertk 0:28557a4d2215 328 }
gertk 0:28557a4d2215 329 OutputToLCD(); /*set standard output to LCD*/
gertk 0:28557a4d2215 330 return(TRUE);
gertk 0:28557a4d2215 331 }
gertk 0:28557a4d2215 332
gertk 0:28557a4d2215 333
gertk 0:28557a4d2215 334 /*request the status register of the card*/
gertk 0:28557a4d2215 335 unsigned char CARD_Status(unsigned char *ResponseData)
gertk 0:28557a4d2215 336 {
gertk 0:28557a4d2215 337 Command_R2(CMD13,0,0);
gertk 0:28557a4d2215 338 ResponseData[1] = response_1; /*return the first response byte (---) in reg[1]*/
gertk 0:28557a4d2215 339 ResponseData[0] = response_2; /*return the second response byte (LSB) in reg[0]*/
gertk 0:28557a4d2215 340 return(TRUE);
gertk 0:28557a4d2215 341 }
gertk 0:28557a4d2215 342
gertk 0:28557a4d2215 343
gertk 0:28557a4d2215 344 /*Request the OCR register (SD-card in SPI-mode that is to be done with CMD58), this will give us the operation condition sof the card*/
gertk 0:28557a4d2215 345 unsigned char CARD_OperatingConditions(unsigned char *ResponseData)
gertk 0:28557a4d2215 346 {
gertk 0:28557a4d2215 347 timeout.reset();
gertk 0:28557a4d2215 348 response_1 = 1;
gertk 0:28557a4d2215 349 while(response_1 != 0)
gertk 0:28557a4d2215 350 {
gertk 0:28557a4d2215 351 Command_R3(CMD58,0,0);
gertk 0:28557a4d2215 352 if (timeout.read_us()>255) /*timeout mechanism*/
gertk 0:28557a4d2215 353 {
gertk 0:28557a4d2215 354 return(FALSE);
gertk 0:28557a4d2215 355 }
gertk 0:28557a4d2215 356 }
gertk 0:28557a4d2215 357
gertk 0:28557a4d2215 358 ResponseData[3] = response_2; /*return the second response byte (MSB) in reg[3]*/
gertk 0:28557a4d2215 359 ResponseData[2] = response_3; /*return the third response byte (---) in reg[2]*/
gertk 0:28557a4d2215 360 ResponseData[1] = response_4; /*return the fourth response byte (---) in reg[1]*/
gertk 0:28557a4d2215 361 ResponseData[0] = response_5; /*return the fifth response byte (LSB) in reg[0]*/
gertk 0:28557a4d2215 362 return(TRUE);
gertk 0:28557a4d2215 363 }
gertk 0:28557a4d2215 364
gertk 0:28557a4d2215 365
gertk 0:28557a4d2215 366 /*Read XXX bytes from the card*/
gertk 0:28557a4d2215 367 /*In some suitations it is not relevant to read the entire sector,*/
gertk 0:28557a4d2215 368 /*Sometimes only one byte is required, then this routine comes in handy...*/
gertk 0:28557a4d2215 369 unsigned char AtaRead_X_Bytes(unsigned long lba, unsigned int offset, unsigned char *ReadData, unsigned int NmbrOfBytes)
gertk 0:28557a4d2215 370 {
gertk 0:28557a4d2215 371 unsigned long lp;
gertk 0:28557a4d2215 372 unsigned short upper_lba, lower_lba;
gertk 0:28557a4d2215 373 unsigned char *p,c;
gertk 0:28557a4d2215 374
gertk 0:28557a4d2215 375 lba = lba * 512; /*calculate byte address*/
gertk 0:28557a4d2215 376 upper_lba = (lba/65536);
gertk 0:28557a4d2215 377 lower_lba = (lba%65536);
gertk 0:28557a4d2215 378
gertk 0:28557a4d2215 379 Command_R1(CMD17, upper_lba, lower_lba); /*read block start at ...,...*/
gertk 0:28557a4d2215 380 // if (response_1 !=0) /*usually you would check the response, BUT not all do this, don't ask me why, but all cards eventually come with the 0xFE (start of data)*/
gertk 0:28557a4d2215 381 // return(FALSE); /*exit if invalid response*/
gertk 0:28557a4d2215 382
gertk 0:28557a4d2215 383 if (WaitForSOD() == FALSE) /*wait for start-of-data (function features time-out)*/
gertk 0:28557a4d2215 384 return(FALSE);
gertk 0:28557a4d2215 385
gertk 0:28557a4d2215 386 // /*read data and exit OK*/
gertk 0:28557a4d2215 387 // p=ReadData;
gertk 0:28557a4d2215 388 // do
gertk 0:28557a4d2215 389 // {
gertk 0:28557a4d2215 390 // SSPBUF = 0xff;
gertk 0:28557a4d2215 391 // while (!BF);
gertk 0:28557a4d2215 392 // *(p++)= SSPBUF;
gertk 0:28557a4d2215 393 // }
gertk 0:28557a4d2215 394 // while(--NmbrOfBytes);
gertk 0:28557a4d2215 395 //
gertk 0:28557a4d2215 396 // Command_R1(CMD12, 0xff, 0xff); /*send the stop command*/
gertk 0:28557a4d2215 397 // return(TRUE);
gertk 0:28557a4d2215 398
gertk 0:28557a4d2215 399 p=ReadData;
gertk 0:28557a4d2215 400 for(lp=0; lp < 512; lp++)
gertk 0:28557a4d2215 401 {
gertk 0:28557a4d2215 402 c=mySPI(0xff);
gertk 0:28557a4d2215 403 if(offset == 0) /*skip the inrelevant bytes*/
gertk 0:28557a4d2215 404 *(p++)=c;
gertk 0:28557a4d2215 405 else
gertk 0:28557a4d2215 406 {
gertk 0:28557a4d2215 407 *(p)=c;
gertk 0:28557a4d2215 408 offset--;
gertk 0:28557a4d2215 409 }
gertk 0:28557a4d2215 410 }
gertk 0:28557a4d2215 411
gertk 0:28557a4d2215 412 mySPI(0xff);
gertk 0:28557a4d2215 413 mySPI(0xff);
gertk 0:28557a4d2215 414 return(TRUE);
gertk 0:28557a4d2215 415 }
gertk 0:28557a4d2215 416
gertk 0:28557a4d2215 417
gertk 0:28557a4d2215 418 /*Read single block (with block-size set by CMD16 to 512 by default)*/
gertk 0:28557a4d2215 419 unsigned char AtaReadSector(unsigned long lba, unsigned char *ReadData)
gertk 0:28557a4d2215 420 {
gertk 0:28557a4d2215 421 unsigned short upper_lba, lower_lba;
gertk 0:28557a4d2215 422 unsigned char i;
gertk 0:28557a4d2215 423 unsigned char *p;
gertk 0:28557a4d2215 424
gertk 0:28557a4d2215 425
gertk 0:28557a4d2215 426 lba = lba * 512; /*calculate byte address*/
gertk 0:28557a4d2215 427 upper_lba = (lba/65536);
gertk 0:28557a4d2215 428 lower_lba = (lba%65536);
gertk 0:28557a4d2215 429 /*printf("\r\nlba=%ld, upper lba=%d, lower lba=%d",lba, upper_lba,lower_lba);*/
gertk 0:28557a4d2215 430
gertk 0:28557a4d2215 431 Command_R1(CMD17, upper_lba, lower_lba); /*read block start at ...,...*/
gertk 0:28557a4d2215 432 // if (response_1 !=0)
gertk 0:28557a4d2215 433 // {
gertk 0:28557a4d2215 434 // return(ERROR_ATAREAD_CMD17); /*exit if invalid response*/
gertk 0:28557a4d2215 435 // }
gertk 0:28557a4d2215 436
gertk 0:28557a4d2215 437 if (WaitForSOD() == FALSE) /*wait for start-of-data (function features time-out)*/
gertk 0:28557a4d2215 438 return(ERROR_ATAREAD_TIMEOUT);
gertk 0:28557a4d2215 439
gertk 0:28557a4d2215 440 /*read data and exit OK*/
gertk 0:28557a4d2215 441 p=ReadData;
gertk 0:28557a4d2215 442 i=0;
gertk 0:28557a4d2215 443 do
gertk 0:28557a4d2215 444 {
gertk 0:28557a4d2215 445 *(p++)=mySPI(0xff);
gertk 0:28557a4d2215 446 }
gertk 0:28557a4d2215 447 while(--i);
gertk 0:28557a4d2215 448
gertk 0:28557a4d2215 449 do
gertk 0:28557a4d2215 450 {
gertk 0:28557a4d2215 451 *(p++)=mySPI(0xff);
gertk 0:28557a4d2215 452 }
gertk 0:28557a4d2215 453 while(--i);
gertk 0:28557a4d2215 454 //for(lp=0; lp < 512; lp++)
gertk 0:28557a4d2215 455 // ReadData[lp] = mySPI(0xFF);
gertk 0:28557a4d2215 456
gertk 0:28557a4d2215 457 mySPI(0xff);
gertk 0:28557a4d2215 458 mySPI(0xff);
gertk 0:28557a4d2215 459 return(TRUE);
gertk 0:28557a4d2215 460 }
gertk 0:28557a4d2215 461
gertk 0:28557a4d2215 462
gertk 0:28557a4d2215 463
gertk 0:28557a4d2215 464 /*Write: 512 Byte-Mode, this will only work (read MMC and SD-card specs) with a sector/block size of 512*/
gertk 0:28557a4d2215 465 unsigned char AtaWriteSector(unsigned long lba, unsigned char *WriteData)
gertk 0:28557a4d2215 466 {
gertk 0:28557a4d2215 467 unsigned short upper_lba, lower_lba, lp; /*Variable 0...65535*/
gertk 0:28557a4d2215 468 unsigned char i;
gertk 0:28557a4d2215 469
gertk 0:28557a4d2215 470 lba = lba * 512; /*since the MMC and SD cards are byte addressable and the FAT relies on a sector address (where a sector is 512bytes big), we must multiply by 512 in order to get the byte address*/
gertk 0:28557a4d2215 471 upper_lba = (lba/65536);
gertk 0:28557a4d2215 472 lower_lba = (lba%65536);
gertk 0:28557a4d2215 473
gertk 0:28557a4d2215 474 Command_R1(CMD24, upper_lba, lower_lba);
gertk 0:28557a4d2215 475 if (response_1 != 0)
gertk 0:28557a4d2215 476 {
gertk 0:28557a4d2215 477 return(FALSE);
gertk 0:28557a4d2215 478 }
gertk 0:28557a4d2215 479 else
gertk 0:28557a4d2215 480 {
gertk 0:28557a4d2215 481 SDCARD_CS=0; /*SDcard Enabled*/
gertk 0:28557a4d2215 482 mySPI(0xFF);
gertk 0:28557a4d2215 483 mySPI(0xFF);
gertk 0:28557a4d2215 484 mySPI(0xFE);
gertk 0:28557a4d2215 485
gertk 0:28557a4d2215 486 for(lp=0; lp < 512; lp++)
gertk 0:28557a4d2215 487 {
gertk 0:28557a4d2215 488 mySPI(WriteData[lp]);
gertk 0:28557a4d2215 489 }
gertk 0:28557a4d2215 490 mySPI(255); // Send 2 Byte's without a meaning... although required by protocol
gertk 0:28557a4d2215 491 mySPI(255);
gertk 0:28557a4d2215 492
gertk 0:28557a4d2215 493 i = mySPI(0xFF);
gertk 0:28557a4d2215 494 // i &=0b.0001.1111;
gertk 0:28557a4d2215 495 // if (i != 0b.0000.0101)
gertk 0:28557a4d2215 496 // printf("Write error\n\r");
gertk 0:28557a4d2215 497 // else
gertk 0:28557a4d2215 498 // printf("Write succeeded?");
gertk 0:28557a4d2215 499 while(mySPI(0xFF) !=0xFF); /*wait until the card has finished writing the data*/
gertk 0:28557a4d2215 500 return(TRUE);
gertk 0:28557a4d2215 501 }
gertk 0:28557a4d2215 502 }
gertk 0:28557a4d2215 503
gertk 0:28557a4d2215 504
gertk 0:28557a4d2215 505 /*************************************************************************************/
gertk 0:28557a4d2215 506 /*Internal functions*/
gertk 0:28557a4d2215 507 /*************************************************************************************/
gertk 0:28557a4d2215 508
gertk 0:28557a4d2215 509 unsigned char Card_CMD0(void)
gertk 0:28557a4d2215 510 {
gertk 0:28557a4d2215 511 unsigned char retry_counter;
gertk 0:28557a4d2215 512
gertk 0:28557a4d2215 513 retry_counter = 100; /*this routine is verrrrrrrry important, and sometimes fails on some cards so a retry mechanism is crucial*/
gertk 0:28557a4d2215 514 while(retry_counter--)
gertk 0:28557a4d2215 515 {
gertk 0:28557a4d2215 516 Command_R1(CMD0,0,0); /*CMD0: Reset all cards to IDLE state*/
gertk 0:28557a4d2215 517 if (response_1 == 1)
gertk 0:28557a4d2215 518 break;
gertk 0:28557a4d2215 519
gertk 0:28557a4d2215 520 if (retry_counter == 0)
gertk 0:28557a4d2215 521 return(FALSE); /*error, quit routine*/
gertk 0:28557a4d2215 522 }
gertk 0:28557a4d2215 523 return(TRUE);
gertk 0:28557a4d2215 524 }
gertk 0:28557a4d2215 525
gertk 0:28557a4d2215 526 unsigned char Card_CMD1(void)
gertk 0:28557a4d2215 527 {
gertk 0:28557a4d2215 528 timeout.reset();
gertk 0:28557a4d2215 529 response_1 = 1;
gertk 0:28557a4d2215 530 while(response_1 != 0)
gertk 0:28557a4d2215 531 {
gertk 0:28557a4d2215 532 Command_R1(CMD1,0,0); /*activate the cards init process*/
gertk 0:28557a4d2215 533 if (timeout.read_us() > 10000) /*timeout mechanism*/
gertk 0:28557a4d2215 534 {
gertk 0:28557a4d2215 535 return(FALSE);
gertk 0:28557a4d2215 536 }
gertk 0:28557a4d2215 537 }
gertk 0:28557a4d2215 538 return(TRUE);
gertk 0:28557a4d2215 539 }
gertk 0:28557a4d2215 540
gertk 0:28557a4d2215 541
gertk 0:28557a4d2215 542 /*Send a command to the SDcard*/
gertk 0:28557a4d2215 543 void Command_R0(char cmd,unsigned short AdrH,unsigned short AdrL)
gertk 0:28557a4d2215 544 {
gertk 0:28557a4d2215 545 crc_7=0;
gertk 0:28557a4d2215 546 mySPI(0xFF); /*flush SPI-bus*/
gertk 0:28557a4d2215 547
gertk 0:28557a4d2215 548 mySPI(cmd);
gertk 0:28557a4d2215 549 MmcAddCrc7(cmd); /*update CRC*/
gertk 0:28557a4d2215 550 mySPI(AdrH/256); /*use upper 8 bits (everything behind the comma is discarded)*/
gertk 0:28557a4d2215 551 MmcAddCrc7(AdrH/256); /*update CRC*/
gertk 0:28557a4d2215 552 mySPI(AdrH%256); /*use lower 8 bits (shows the remaining part of the devision)*/
gertk 0:28557a4d2215 553 MmcAddCrc7(AdrH%256); /*update CRC*/
gertk 0:28557a4d2215 554 mySPI(AdrL/256); /*use upper 8 bits (everything behind the comma is discarded)*/
gertk 0:28557a4d2215 555 MmcAddCrc7(AdrL/256); /*update CRC*/
gertk 0:28557a4d2215 556 mySPI(AdrL%256); /*use lower 8 bits (shows the remaining part of the devision)*/
gertk 0:28557a4d2215 557 MmcAddCrc7(AdrL%256); /*update CRC*/
gertk 0:28557a4d2215 558
gertk 0:28557a4d2215 559 crc_7<<=1; /*shift all bits 1 position to the left, to free position 0*/
gertk 0:28557a4d2215 560 crc_7++; /*set LSB to '1'*/
gertk 0:28557a4d2215 561
gertk 0:28557a4d2215 562 mySPI(crc_7); /*transmit CRC*/
gertk 0:28557a4d2215 563 mySPI(0xFF); /*flush SPI-bus, or int other words process command*/
gertk 0:28557a4d2215 564 }
gertk 0:28557a4d2215 565
gertk 0:28557a4d2215 566
gertk 0:28557a4d2215 567 /*Send a command to the SDcard, a one byte response is expected*/
gertk 0:28557a4d2215 568 void Command_R1(char cmd,unsigned short AdrH,unsigned short AdrL)
gertk 0:28557a4d2215 569 {
gertk 0:28557a4d2215 570 Command_R0(cmd, AdrH, AdrL); /*send command*/
gertk 0:28557a4d2215 571 response_1 = mySPI(0xFF); /*return the reponse in the correct register*/
gertk 0:28557a4d2215 572 }
gertk 0:28557a4d2215 573
gertk 0:28557a4d2215 574
gertk 0:28557a4d2215 575 /*Send a command to the SDcard, a two byte response is expected*/
gertk 0:28557a4d2215 576 void Command_R2(char cmd,unsigned short AdrH,unsigned short AdrL)
gertk 0:28557a4d2215 577 {
gertk 0:28557a4d2215 578 Command_R0(cmd, AdrH, AdrL); /*send command*/
gertk 0:28557a4d2215 579 response_1 = mySPI(0xFF); /*return the reponse in the correct register*/
gertk 0:28557a4d2215 580 response_2 = mySPI(0xFF);
gertk 0:28557a4d2215 581 }
gertk 0:28557a4d2215 582
gertk 0:28557a4d2215 583
gertk 0:28557a4d2215 584 /*Send a command to the SDcard, a five byte response is expected*/
gertk 0:28557a4d2215 585 void Command_R3(char cmd,unsigned short AdrH,unsigned short AdrL)
gertk 0:28557a4d2215 586 {
gertk 0:28557a4d2215 587 Command_R0(cmd, AdrH, AdrL); /*send command*/
gertk 0:28557a4d2215 588 response_1 = mySPI(0xFF); /*return the reponse in the correct register*/
gertk 0:28557a4d2215 589 response_2 = mySPI(0xFF);
gertk 0:28557a4d2215 590 response_3 = mySPI(0xFF);
gertk 0:28557a4d2215 591 response_4 = mySPI(0xFF);
gertk 0:28557a4d2215 592 response_5 = mySPI(0xFF);
gertk 0:28557a4d2215 593 }
gertk 0:28557a4d2215 594
gertk 0:28557a4d2215 595
gertk 0:28557a4d2215 596 /*calculate CRC7 checksum*/
gertk 0:28557a4d2215 597 void MmcAddCrc7(unsigned char c)
gertk 0:28557a4d2215 598 {
gertk 0:28557a4d2215 599 unsigned char i;
gertk 0:28557a4d2215 600
gertk 0:28557a4d2215 601 i=8;
gertk 0:28557a4d2215 602 do
gertk 0:28557a4d2215 603 {
gertk 0:28557a4d2215 604 crc_7<<=1;
gertk 0:28557a4d2215 605 if(c&0x80)
gertk 0:28557a4d2215 606 crc_7^=0x09;
gertk 0:28557a4d2215 607 if(crc_7&0x80)
gertk 0:28557a4d2215 608 crc_7^=0x09;
gertk 0:28557a4d2215 609 c<<=1;
gertk 0:28557a4d2215 610 }
gertk 0:28557a4d2215 611 while(--i);
gertk 0:28557a4d2215 612 }