sd-card.c (163533) | sd-card.c (164137) |
---|---|
1/*- 2 * Copyright (c) 2006 M. Warner Losh. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * This software is derived from software provide by Kwikbyte who specifically 25 * disclaimed copyright on the code. 26 * | 1/*- 2 * Copyright (c) 2006 M. Warner Losh. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * This software is derived from software provide by Kwikbyte who specifically 25 * disclaimed copyright on the code. 26 * |
27 * $FreeBSD: head/sys/boot/arm/at91/libat91/sd-card.c 163533 2006-10-20 09:12:05Z imp $ | 27 * $FreeBSD: head/sys/boot/arm/at91/libat91/sd-card.c 164137 2006-11-09 20:32:36Z imp $ |
28 */ 29 30//*---------------------------------------------------------------------------- 31//* ATMEL Microcontroller Software Support - ROUSSET - 32//*---------------------------------------------------------------------------- 33//* The software is delivered "AS IS" without warranty or condition of any 34//* kind, either express, implied or statutory. This includes without 35//* limitation any warranty or condition with respect to merchantability or --- 10 unchanged lines hidden (view full) --- 46#include "mci_device.h" 47#include "lib.h" 48#include "sd-card.h" 49 50#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ 51#define BUFFER_SIZE_MCI_DEVICE 512 52#define MASTER_CLOCK 60000000 53 | 28 */ 29 30//*---------------------------------------------------------------------------- 31//* ATMEL Microcontroller Software Support - ROUSSET - 32//*---------------------------------------------------------------------------- 33//* The software is delivered "AS IS" without warranty or condition of any 34//* kind, either express, implied or statutory. This includes without 35//* limitation any warranty or condition with respect to merchantability or --- 10 unchanged lines hidden (view full) --- 46#include "mci_device.h" 47#include "lib.h" 48#include "sd-card.h" 49 50#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ 51#define BUFFER_SIZE_MCI_DEVICE 512 52#define MASTER_CLOCK 60000000 53 |
54//Private functions 55//static void initInts(void); 56static void AT91F_MCI_Handler(void); 57 | |
58//* Global Variables | 54//* Global Variables |
59AT91S_MciDeviceFeatures MCI_Device_Features; 60AT91S_MciDeviceDesc MCI_Device_Desc; | |
61AT91S_MciDevice MCI_Device; 62char Buffer[BUFFER_SIZE_MCI_DEVICE]; 63 64/****************************************************************************** 65**Error return codes 66******************************************************************************/ 67#define MCI_UNSUPP_SIZE_ERROR 5 68#define MCI_UNSUPP_OFFSET_ERROR 6 69 70//*---------------------------------------------------------------------------- | 55AT91S_MciDevice MCI_Device; 56char Buffer[BUFFER_SIZE_MCI_DEVICE]; 57 58/****************************************************************************** 59**Error return codes 60******************************************************************************/ 61#define MCI_UNSUPP_SIZE_ERROR 5 62#define MCI_UNSUPP_OFFSET_ERROR 6 63 64//*---------------------------------------------------------------------------- |
71//* \fn AT91F_MCIDeviceWaitReady | 65//* \fn MCIDeviceWaitReady |
72//* \brief Wait for MCI Device ready 73//*---------------------------------------------------------------------------- 74static void | 66//* \brief Wait for MCI Device ready 67//*---------------------------------------------------------------------------- 68static void |
75AT91F_MCIDeviceWaitReady(unsigned int timeout) | 69MCIDeviceWaitReady(unsigned int timeout) |
76{ 77 volatile int status; 78 79 do 80 { 81 status = AT91C_BASE_MCI->MCI_SR; 82 timeout--; 83 } 84 while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) ); 85 | 70{ 71 volatile int status; 72 73 do 74 { 75 status = AT91C_BASE_MCI->MCI_SR; 76 timeout--; 77 } 78 while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) ); 79 |
86 AT91F_MCI_Handler(); | 80 status = AT91C_BASE_MCI->MCI_SR; 81 82 // If End of Tx Buffer Empty interrupt occurred 83 if (MCI_Device.state == AT91C_MCI_TX_SINGLE_BLOCK && status & AT91C_MCI_TXBUFE) { 84 AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE; 85 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS; 86 MCI_Device.state = AT91C_MCI_IDLE; 87 } // End of if AT91C_MCI_TXBUFF 88 89 // If End of Rx Buffer Full interrupt occurred 90 if (MCI_Device.state == AT91C_MCI_RX_SINGLE_BLOCK && status & AT91C_MCI_RXBUFF) { 91 AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF; 92 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS; 93 MCI_Device.state = AT91C_MCI_IDLE; 94 } // End of if AT91C_MCI_RXBUFF |
87} 88 | 95} 96 |
89#if 0 90int 91MCI_write (unsigned dest, char* source, unsigned length) | 97inline static unsigned int 98swap(unsigned int a) |
92{ | 99{ |
93 unsigned sectorLength = 1 << MCI_Device.pMCI_DeviceFeatures->WRITE_BL_LEN; 94 unsigned offset = dest % sectorLength; 95 AT91S_MCIDeviceStatus status; 96 int sizeToWrite; | 100 return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) 101 | ((a & 0xff000000) >> 24)); 102} |
97 | 103 |
98 //As long as there is data to write 99 while (length) | 104inline static void 105wait_ready() 106{ 107 int status; 108 109 // wait for CMDRDY Status flag to read the response 110 do |
100 { | 111 { |
101 //See if we've got at least a sector to write 102 if (length > sectorLength) 103 sizeToWrite = sectorLength; 104 //Else just write the remainder 105 else 106 sizeToWrite = length; | 112 status = AT91C_BASE_MCI->MCI_SR; 113 } while( !(status & AT91C_MCI_CMDRDY) ); 114} |
107 | 115 |
108 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); 109 //Do the writing 110 status = AT91F_MCI_WriteBlock(&MCI_Device, dest, (unsigned int*)source, sizeToWrite); 111 //TODO:Status checking | 116//*---------------------------------------------------------------------------- 117//* \fn MCI_SendCommand 118//* \brief Generic function to send a command to the MMC or SDCard 119//*---------------------------------------------------------------------------- 120static int 121MCI_SendCommand( 122 unsigned int Cmd, 123 unsigned int Arg) 124{ 125 unsigned int error; |
112 | 126 |
113 //Update counters & pointers 114 length -= sizeToWrite; 115 dest += sizeToWrite; 116 source += sizeToWrite; 117 } | 127 AT91C_BASE_MCI->MCI_ARGR = Arg; 128 AT91C_BASE_MCI->MCI_CMDR = Cmd; |
118 | 129 |
130// printf("CMDR %x ARG %x\n", Cmd, Arg); 131 wait_ready(); 132 // Test error ==> if crc error and response R3 ==> don't check error 133 error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR; 134 if (error != 0) { 135 if (error != AT91C_MCI_RCRCE) 136 return (1); 137 } |
|
119 return 0; 120} | 138 return 0; 139} |
121#endif | |
122 | 140 |
123inline static unsigned int 124swap(unsigned int a) | 141//*---------------------------------------------------------------------------- 142//* \fn MCI_GetStatus 143//* \brief Addressed card sends its status register 144//*---------------------------------------------------------------------------- 145static unsigned int 146MCI_GetStatus() |
125{ | 147{ |
126 return (((a & 0xff) << 24) | ((a & 0xff00) << 8) | ((a & 0xff0000) >> 8) 127 | ((a & 0xff000000) >> 24)); | 148 if (MCI_SendCommand(SEND_STATUS_CMD, MCI_Device.RCA << 16)) 149 return AT91C_CMD_SEND_ERROR; 150 return (AT91C_BASE_MCI->MCI_RSPR[0]); |
128} 129 | 151} 152 |
153//*---------------------------------------------------------------------------- 154//* \fn MCI_ReadBlock 155//* \brief Read an ENTIRE block or PARTIAL block 156//*---------------------------------------------------------------------------- 157static int 158MCI_ReadBlock(int src, unsigned int *dataBuffer, int sizeToRead) 159{ 160 unsigned log2sl = MCI_Device.READ_BL_LEN; 161 unsigned sectorLength = 1 << log2sl; 162 163 /////////////////////////////////////////////////////////////////////// 164 if (MCI_Device.state != AT91C_MCI_IDLE) 165 return 1; 166 167 if ((MCI_GetStatus() & AT91C_SR_READY_FOR_DATA) == 0) 168 return 1; 169 170 /////////////////////////////////////////////////////////////////////// 171 172 // Init Mode Register 173 AT91C_BASE_MCI->MCI_MR |= ((sectorLength << 16) | AT91C_MCI_PDCMODE); 174 175 sizeToRead = sizeToRead / 4; 176 177 AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); 178 AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer; 179 AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead; 180 181 // Send the Read single block command 182 if (MCI_SendCommand(READ_SINGLE_BLOCK_CMD, src)) 183 return AT91C_READ_ERROR; 184 MCI_Device.state = AT91C_MCI_RX_SINGLE_BLOCK; 185 186 // Enable AT91C_MCI_RXBUFF Interrupt 187 AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF; 188 189 // (PDC) Receiver Transfer Enable 190 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN; 191 192 return 0; 193} 194 |
|
130int 131MCI_read(char* dest, unsigned source, unsigned length) 132{ | 195int 196MCI_read(char* dest, unsigned source, unsigned length) 197{ |
133 unsigned log2sl = MCI_Device.pMCI_DeviceFeatures->READ_BL_LEN; | 198 unsigned log2sl = MCI_Device.READ_BL_LEN; |
134 unsigned sectorLength = 1 << log2sl; | 199 unsigned sectorLength = 1 << log2sl; |
135 AT91S_MCIDeviceStatus status; | |
136 int sizeToRead; 137 unsigned int *walker; 138 139 //As long as there is data to read 140 while (length) 141 { 142 if (length > sectorLength) 143 sizeToRead = sectorLength; 144 else 145 sizeToRead = length; 146 | 200 int sizeToRead; 201 unsigned int *walker; 202 203 //As long as there is data to read 204 while (length) 205 { 206 if (length > sectorLength) 207 sizeToRead = sectorLength; 208 else 209 sizeToRead = length; 210 |
147 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); | 211 MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); |
148 //Do the reading | 212 //Do the reading |
149 status = AT91F_MCI_ReadBlock(&MCI_Device, source, 150 (unsigned int*)dest, sizeToRead); 151 152 //TODO:Status checking 153 if (status != AT91C_READ_OK) | 213 if (MCI_ReadBlock(source, 214 (unsigned int*)dest, sizeToRead)) |
154 return -1; 155 156 //* Wait MCI Device Ready | 215 return -1; 216 217 //* Wait MCI Device Ready |
157 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); | 218 MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); |
158 159 // Fix erratum in MCI part 160 for (walker = (unsigned int *)dest; 161 walker < (unsigned int *)(dest + sizeToRead); walker++) 162 *walker = swap(*walker); 163 164 //Update counters & pointers 165 length -= sizeToRead; 166 dest += sizeToRead; 167 source += sizeToRead; 168 } 169 170 return 0; 171} 172 | 219 220 // Fix erratum in MCI part 221 for (walker = (unsigned int *)dest; 222 walker < (unsigned int *)(dest + sizeToRead); walker++) 223 *walker = swap(*walker); 224 225 //Update counters & pointers 226 length -= sizeToRead; 227 dest += sizeToRead; 228 source += sizeToRead; 229 } 230 231 return 0; 232} 233 |
234//*---------------------------------------------------------------------------- 235//* \fn MCI_SDCard_SendAppCommand 236//* \brief Specific function to send a specific command to the SDCard 237//*---------------------------------------------------------------------------- 238static int 239MCI_SDCard_SendAppCommand( 240 unsigned int Cmd_App, 241 unsigned int Arg) 242{ 243 // Send the CMD55 for application specific command 244 AT91C_BASE_MCI->MCI_ARGR = (MCI_Device.RCA << 16 ); 245 AT91C_BASE_MCI->MCI_CMDR = APP_CMD; |
|
173 | 246 |
247 wait_ready(); 248 // if an error occurs 249 if (AT91C_BASE_MCI->MCI_SR & AT91C_MCI_SR_ERROR) 250 return (1); 251 return (MCI_SendCommand(Cmd_App,Arg)); 252} 253 |
|
174//*---------------------------------------------------------------------------- | 254//*---------------------------------------------------------------------------- |
175//* \fn AT91F_CfgDevice 176//* \brief This function is used to initialise MMC or SDCard Features | 255//* \fn MCI_GetCSD 256//* \brief Asks to the specified card to send its CSD |
177//*---------------------------------------------------------------------------- | 257//*---------------------------------------------------------------------------- |
178static void AT91F_CfgDevice(void) | 258static int 259MCI_GetCSD(unsigned int rca, unsigned int *response) |
179{ | 260{ |
180 // Init Device Structure | 261 262 if (MCI_SendCommand(SEND_CSD_CMD, (rca << 16))) 263 return 1; 264 265 response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; 266 response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; 267 response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; 268 response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; 269 270 return 0; 271} |
181 | 272 |
182 MCI_Device_Features.Relative_Card_Address = 0; 183 MCI_Device_Features.Card_Inserted = AT91C_SD_CARD_INSERTED; 184 MCI_Device_Features.READ_BL_LEN = 0; 185 MCI_Device_Features.WRITE_BL_LEN = 0; 186 MCI_Device_Features.Read_Partial = 0; 187 MCI_Device_Features.Write_Partial = 0; 188 MCI_Device_Features.Erase_Block_Enable = 0; 189 MCI_Device_Features.Sector_Size = 0; 190 MCI_Device_Features.Memory_Capacity = 0; 191 MCI_Device_Desc.state = AT91C_MCI_IDLE; 192 MCI_Device_Desc.SDCard_bus_width = AT91C_MCI_SCDBUS; 193 MCI_Device.pMCI_DeviceDesc = &MCI_Device_Desc; 194 MCI_Device.pMCI_DeviceFeatures = &MCI_Device_Features; | 273//*---------------------------------------------------------------------------- 274//* \fn MCI_SDCard_GetOCR 275//* \brief Asks to all cards to send their operations conditions 276//*---------------------------------------------------------------------------- 277static int 278MCI_SDCard_GetOCR() 279{ 280 unsigned int response=0x0; 281 282 // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000. 283 MCI_Device.RCA = 0x0; 284 285 while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) { 286 if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD, 287 AT91C_MMC_HOST_VOLTAGE_RANGE)) 288 return 1; 289 response = AT91C_BASE_MCI->MCI_RSPR[0]; 290 } 291 return (0); |
195} 196 | 292} 293 |
197static void AT91F_MCI_Handler(void) | 294//*---------------------------------------------------------------------------- 295//* \fn MCI_SDCard_GetCID 296//* \brief Asks to the SDCard on the chosen slot to send its CID 297//*---------------------------------------------------------------------------- 298static int 299MCI_SDCard_GetCID(unsigned int *response) |
198{ | 300{ |
199 int status; | 301 if (MCI_SendCommand(ALL_SEND_CID_CMD, AT91C_NO_ARGUMENT)) 302 return 1; 303 304 response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; 305 response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; 306 response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; 307 response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; 308 309 return 0; 310} |
200 | 311 |
201// status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR ); 202 status = AT91C_BASE_MCI->MCI_SR; | 312//*---------------------------------------------------------------------------- 313//* \fn MCI_SDCard_SetBusWidth 314//* \brief Set bus width for SDCard 315//*---------------------------------------------------------------------------- 316static int 317MCI_SDCard_SetBusWidth() 318{ 319 volatile int ret_value; 320 char bus_width; |
203 | 321 |
204 AT91F_MCI_Device_Handler(&MCI_Device, status); | 322 do { 323 ret_value=MCI_GetStatus(); 324 } 325 while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0)); 326 327 // Select Card 328 MCI_SendCommand(SEL_DESEL_CARD_CMD, (MCI_Device.RCA)<<16); 329 330 // Set bus width for Sdcard 331 if (MCI_Device.SDCard_bus_width == AT91C_MCI_SCDBUS) 332 bus_width = AT91C_BUS_WIDTH_4BITS; 333 else 334 bus_width = AT91C_BUS_WIDTH_1BIT; 335 336 if (MCI_SDCard_SendAppCommand( 337 SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK) 338 return 1; 339 340 return 0; |
205} 206 207//*---------------------------------------------------------------------------- 208//* \fn main 209//* \brief main function 210//*---------------------------------------------------------------------------- 211int 212sdcard_init(void) 213{ | 341} 342 343//*---------------------------------------------------------------------------- 344//* \fn main 345//* \brief main function 346//*---------------------------------------------------------------------------- 347int 348sdcard_init(void) 349{ |
214/////////////////////////////////////////////////////////////////////////////// 215// MCI Init : common to MMC and SDCard 216/////////////////////////////////////////////////////////////////////////////// | 350 unsigned int tab_response[4]; 351#ifdef REPORT_SIZE 352 unsigned int mult,blocknr; 353#endif 354 int i; |
217 | 355 |
218 //initInts(); 219 | |
220 // Init MCI for MMC and SDCard interface 221 AT91F_MCI_CfgPIO(); 222 AT91F_MCI_CfgPMC(); 223 AT91F_PDC_Open(AT91C_BASE_PDC_MCI); 224 | 356 // Init MCI for MMC and SDCard interface 357 AT91F_MCI_CfgPIO(); 358 AT91F_MCI_CfgPMC(); 359 AT91F_PDC_Open(AT91C_BASE_PDC_MCI); 360 |
225 // Init MCI Device Structures 226 AT91F_CfgDevice(); | 361 // Init Device Structure 362 MCI_Device.state = AT91C_MCI_IDLE; 363 MCI_Device.SDCard_bus_width = AT91C_MCI_SCDBUS; |
227 | 364 |
228 AT91F_MCI_Configure(AT91C_BASE_MCI, 229 AT91C_MCI_DTOR_1MEGA_CYCLES, 230 AT91C_MCI_PDCMODE, 231 AT91C_MCI_SDCARD_4BITS_SLOTA); 232 233 if (AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK) | 365 //* Reset the MCI 366 AT91C_BASE_MCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN; 367 AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF; 368 AT91C_BASE_MCI->MCI_DTOR = AT91C_MCI_DTOR_1MEGA_CYCLES; 369 AT91C_BASE_MCI->MCI_MR = AT91C_MCI_PDCMODE; 370 AT91C_BASE_MCI->MCI_SDCR = AT91C_MCI_SDCARD_4BITS_SLOTA; 371 MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); 372 373 for (i = 0; i < 100; i++) { 374 if (!MCI_SDCard_GetOCR(&MCI_Device)) 375 break; 376 printf("."); 377 } 378 if (i >= 100) |
234 return 0; | 379 return 0; |
380 if (MCI_SDCard_GetCID(tab_response)) 381 return 0; 382 if (MCI_SendCommand(SET_RELATIVE_ADDR_CMD, 0)) 383 return 0; 384 385 MCI_Device.RCA = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16); 386 if (MCI_GetCSD(MCI_Device.RCA,tab_response)) 387 return 0; 388 MCI_Device.READ_BL_LEN = (tab_response[1] >> CSD_1_RD_B_LEN_S) & 389 CSD_1_RD_B_LEN_M; 390#ifdef REPORT_SIZE 391 // compute MULT 392 mult = 1 << ( ((tab_response[2] >> CSD_2_C_SIZE_M_S) & 393 CSD_2_C_SIZE_M_M) + 2 ); 394 // compute MSB of C_SIZE 395 blocknr = ((tab_response[1] >> CSD_1_CSIZE_H_S) & 396 CSD_1_CSIZE_H_M) << 2; 397 // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR 398 blocknr = mult * ((blocknr + ((tab_response[2] >> CSD_2_CSIZE_L_S) & 399 CSD_2_CSIZE_L_M)) + 1); 400 MCI_Device.Memory_Capacity = (1 << MCI_Device.READ_BL_LEN) * blocknr; 401#endif 402 if (MCI_SDCard_SetBusWidth()) 403 return 0; 404 if (MCI_SendCommand(SET_BLOCKLEN_CMD, 1 << MCI_Device.READ_BL_LEN)) 405 return 0; 406#ifdef REPORT_SIZE 407 printf("Found SD card %u bytes\n", MCI_Device.Memory_Capacity); 408#endif |
|
235 return 1; 236} | 409 return 1; 410} |