1//*---------------------------------------------------------------------------- 2//* ATMEL Microcontroller Software Support - ROUSSET - 3//*---------------------------------------------------------------------------- 4//* The software is delivered "AS IS" without warranty or condition of any 5//* kind, either express, implied or statutory. This includes without 6//* limitation any warranty or condition with respect to merchantability or 7//* fitness for any particular purpose, or against the infringements of 8//* intellectual property rights of others. 9//*---------------------------------------------------------------------------- 10//* File Name : mci_device.c 11//* Object : TEST DataFlash Functions 12//* Creation : FB 26/11/2002 13//* 14//*---------------------------------------------------------------------------- 15 16#include <AT91C_MCI_Device.h> 17#include "stdio.h" 18 19#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ 20#define BUFFER_SIZE_MCI_DEVICE 512 21#define MASTER_CLOCK 60000000 22#define FALSE 0 23#define TRUE 1 24 25//* External Functions 26extern void AT91F_ASM_MCI_Handler(void); 27//* Global Variables 28AT91S_MciDeviceFeatures MCI_Device_Features; 29AT91S_MciDeviceDesc MCI_Device_Desc; 30AT91S_MciDevice MCI_Device; 31 32#undef ENABLE_WRITE 33#undef MMC 34 35//*---------------------------------------------------------------------------- 36//* \fn AT91F_MCI_SendCommand 37//* \brief Generic function to send a command to the MMC or SDCard 38//*---------------------------------------------------------------------------- 39int AT91F_MCI_SendCommand ( 40 AT91PS_MciDevice pMCI_Device, 41 unsigned int Cmd, 42 unsigned int Arg) 43{ 44 unsigned int error,status; 45 //unsigned int tick=0; 46 47 // Send the command 48 AT91C_BASE_MCI->MCI_ARGR = Arg; 49 AT91C_BASE_MCI->MCI_CMDR = Cmd; 50 51 // wait for CMDRDY Status flag to read the response 52 do 53 { 54 status = AT91C_BASE_MCI->MCI_SR; 55 //tick++; 56 } 57 while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); 58 59 // Test error ==> if crc error and response R3 ==> don't check error 60 error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR; 61 if(error != 0 ) 62 { 63 // if the command is SEND_OP_COND the CRC error flag is always present (cf : R3 response) 64 if ( (Cmd != AT91C_SDCARD_APP_OP_COND_CMD) && (Cmd != AT91C_MMC_SEND_OP_COND_CMD) ) 65 return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); 66 else 67 { 68 if (error != AT91C_MCI_RCRCE) 69 return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); 70 } 71 } 72 return AT91C_CMD_SEND_OK; 73} 74 75//*---------------------------------------------------------------------------- 76//* \fn AT91F_MCI_SDCard_SendAppCommand 77//* \brief Specific function to send a specific command to the SDCard 78//*---------------------------------------------------------------------------- 79int AT91F_MCI_SDCard_SendAppCommand ( 80 AT91PS_MciDevice pMCI_Device, 81 unsigned int Cmd_App, 82 unsigned int Arg ) 83{ 84 unsigned int status; 85 //unsigned int tick=0; 86 87 // Send the CMD55 for application specific command 88 AT91C_BASE_MCI->MCI_ARGR = (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address << 16 ); 89 AT91C_BASE_MCI->MCI_CMDR = AT91C_APP_CMD; 90 91 // wait for CMDRDY Status flag to read the response 92 do 93 { 94 status = AT91C_BASE_MCI->MCI_SR; 95 //tick++; 96 } 97 while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); 98 99 // if an error occurs 100 if (((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR) != 0 ) 101 return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); 102 103 // check if it is a specific command and then send the command 104 if ( (Cmd_App && AT91C_SDCARD_APP_ALL_CMD) == 0) 105 return AT91C_CMD_SEND_ERROR; 106 107 return( AT91F_MCI_SendCommand(pMCI_Device,Cmd_App,Arg) ); 108} 109 110//*---------------------------------------------------------------------------- 111//* \fn AT91F_MCI_GetStatus 112//* \brief Addressed card sends its status register 113//*---------------------------------------------------------------------------- 114int AT91F_MCI_GetStatus(AT91PS_MciDevice pMCI_Device,unsigned int relative_card_address) 115{ 116 if (AT91F_MCI_SendCommand(pMCI_Device, 117 AT91C_SEND_STATUS_CMD, 118 relative_card_address <<16) == AT91C_CMD_SEND_OK) 119 return (AT91C_BASE_MCI->MCI_RSPR[0]); 120 121 return AT91C_CMD_SEND_ERROR; 122} 123 124//*---------------------------------------------------------------------------- 125//* \fn AT91F_MCI_Device_Handler 126//* \brief MCI C interrupt handler 127//*---------------------------------------------------------------------------- 128void AT91F_MCI_Device_Handler( 129 AT91PS_MciDevice pMCI_Device, 130 unsigned int status) 131{ 132 // If End of Tx Buffer Empty interrupt occurred 133 if ( status & AT91C_MCI_TXBUFE ) 134 { 135 AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE; 136 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS; 137 138 pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; 139 } // End of if AT91C_MCI_TXBUFF 140 141 // If End of Rx Buffer Full interrupt occurred 142 if ( status & AT91C_MCI_RXBUFF ) 143 { 144 AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF; 145 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS; 146 147 pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; 148 } // End of if AT91C_MCI_RXBUFF 149 150} 151 152//*---------------------------------------------------------------------------- 153//* \fn AT91F_MCI_Handler 154//* \brief MCI Handler 155//*---------------------------------------------------------------------------- 156void AT91F_MCI_Handler(void) 157{ 158 int status; 159 160 status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR ); 161 162 AT91F_MCI_Device_Handler(&MCI_Device,status); 163} 164 165//*---------------------------------------------------------------------------- 166//* \fn AT91F_MCI_ReadBlock 167//* \brief Read an ENTIRE block or PARTIAL block 168//*---------------------------------------------------------------------------- 169int AT91F_MCI_ReadBlock( 170 AT91PS_MciDevice pMCI_Device, 171 int src, 172 unsigned int *dataBuffer, 173 int sizeToRead ) 174{ 175 //////////////////////////////////////////////////////////////////////////////////////////// 176 if(pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) 177 return AT91C_READ_ERROR; 178 179 if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) 180 return AT91C_READ_ERROR; 181 182 if ( (src + sizeToRead) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) 183 return AT91C_READ_ERROR; 184 185 // If source does not fit a begin of a block 186 if ( (src % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) 187 return AT91C_READ_ERROR; 188 189 // Test if the MMC supports Partial Read Block 190 // ALWAYS SUPPORTED IN SD Memory Card 191 if( (sizeToRead < pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) 192 && (pMCI_Device->pMCI_DeviceFeatures->Read_Partial == 0x00) ) 193 return AT91C_READ_ERROR; 194 195 if( sizeToRead > pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) 196 return AT91C_READ_ERROR; 197 //////////////////////////////////////////////////////////////////////////////////////////// 198 199 // Init Mode Register 200 AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); 201 202 if (sizeToRead %4) 203 sizeToRead = (sizeToRead /4)+1; 204 else 205 sizeToRead = sizeToRead/4; 206 207 AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); 208 AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer; 209 AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead; 210 211 // Send the Read single block command 212 if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_READ_SINGLE_BLOCK_CMD, src) != AT91C_CMD_SEND_OK ) 213 return AT91C_READ_ERROR; 214 215 pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_RX_SINGLE_BLOCK; 216 217 // Enable AT91C_MCI_RXBUFF Interrupt 218 AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF; 219 220 // (PDC) Receiver Transfer Enable 221 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN; 222 223 return AT91C_READ_OK; 224} 225 226 227#ifdef ENABLE_WRITE 228//*---------------------------------------------------------------------------- 229//* \fn AT91F_MCI_WriteBlock 230//* \brief Write an ENTIRE block but not always PARTIAL block !!! 231//*---------------------------------------------------------------------------- 232int AT91F_MCI_WriteBlock( 233 AT91PS_MciDevice pMCI_Device, 234 int dest, 235 unsigned int *dataBuffer, 236 int sizeToWrite ) 237{ 238 //////////////////////////////////////////////////////////////////////////////////////////// 239 if( pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) 240 return AT91C_WRITE_ERROR; 241 242 if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) 243 return AT91C_WRITE_ERROR; 244 245 if ( (dest + sizeToWrite) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) 246 return AT91C_WRITE_ERROR; 247 248 // If source does not fit a begin of a block 249 if ( (dest % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) 250 return AT91C_WRITE_ERROR; 251 252 // Test if the MMC supports Partial Write Block 253 if( (sizeToWrite < pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length) 254 && (pMCI_Device->pMCI_DeviceFeatures->Write_Partial == 0x00) ) 255 return AT91C_WRITE_ERROR; 256 257 if( sizeToWrite > pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length ) 258 return AT91C_WRITE_ERROR; 259 //////////////////////////////////////////////////////////////////////////////////////////// 260 261 // Init Mode Register 262 AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); 263 264 if (sizeToWrite %4) 265 sizeToWrite = (sizeToWrite /4)+1; 266 else 267 sizeToWrite = sizeToWrite/4; 268 269 // Init PDC for write sequence 270 AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); 271 AT91C_BASE_PDC_MCI->PDC_TPR = (unsigned int) dataBuffer; 272 AT91C_BASE_PDC_MCI->PDC_TCR = sizeToWrite; 273 274 // Send the write single block command 275 if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_WRITE_BLOCK_CMD, dest) != AT91C_CMD_SEND_OK) 276 return AT91C_WRITE_ERROR; 277 278 pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_TX_SINGLE_BLOCK; 279 280 // Enable AT91C_MCI_TXBUFE Interrupt 281 AT91C_BASE_MCI->MCI_IER = AT91C_MCI_TXBUFE; 282 283 // Enables TX for PDC transfert requests 284 AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTEN; 285 286 return AT91C_WRITE_OK; 287} 288#endif 289 290#ifdef MMC 291//*------------------------------------------------------------------------------------------------------------ 292//* \fn AT91F_MCI_MMC_SelectCard 293//* \brief Toggles a card between the Stand_by and Transfer states or between Programming and Disconnect states 294//*------------------------------------------------------------------------------------------------------------ 295int AT91F_MCI_MMC_SelectCard(AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address) 296{ 297 int status; 298 299 //* Check if the MMC card chosen is already the selected one 300 status = AT91F_MCI_GetStatus(pMCI_Device,relative_card_address); 301 302 if (status < 0) 303 return AT91C_CARD_SELECTED_ERROR; 304 305 if ((status & AT91C_SR_CARD_SELECTED) == AT91C_SR_CARD_SELECTED) 306 return AT91C_CARD_SELECTED_OK; 307 308 //* Search for the MMC Card to be selected, status = the Corresponding Device Number 309 status = 0; 310 while( (pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address != relative_card_address) 311 && (status < AT91C_MAX_MCI_CARDS) ) 312 status++; 313 314 if (status > AT91C_MAX_MCI_CARDS) 315 return AT91C_CARD_SELECTED_ERROR; 316 317 if (AT91F_MCI_SendCommand( pMCI_Device, 318 AT91C_SEL_DESEL_CARD_CMD, 319 pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address << 16) == AT91C_CMD_SEND_OK) 320 return AT91C_CARD_SELECTED_OK; 321 return AT91C_CARD_SELECTED_ERROR; 322} 323#endif 324 325//*---------------------------------------------------------------------------- 326//* \fn AT91F_MCI_GetCSD 327//* \brief Asks to the specified card to send its CSD 328//*---------------------------------------------------------------------------- 329int AT91F_MCI_GetCSD (AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address , unsigned int * response) 330{ 331 332 if(AT91F_MCI_SendCommand(pMCI_Device, 333 AT91C_SEND_CSD_CMD, 334 (relative_card_address << 16)) != AT91C_CMD_SEND_OK) 335 return AT91C_CMD_SEND_ERROR; 336 337 response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; 338 response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; 339 response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; 340 response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; 341 342 return AT91C_CMD_SEND_OK; 343} 344 345//*---------------------------------------------------------------------------- 346//* \fn AT91F_MCI_SetBlocklength 347//* \brief Select a block length for all following block commands (R/W) 348//*---------------------------------------------------------------------------- 349int AT91F_MCI_SetBlocklength(AT91PS_MciDevice pMCI_Device,unsigned int length) 350{ 351 return( AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_BLOCKLEN_CMD, length) ); 352} 353 354#ifdef MMC 355//*---------------------------------------------------------------------------- 356//* \fn AT91F_MCI_MMC_GetAllOCR 357//* \brief Asks to all cards to send their operations conditions 358//*---------------------------------------------------------------------------- 359int AT91F_MCI_MMC_GetAllOCR (AT91PS_MciDevice pMCI_Device) 360{ 361 unsigned int response =0x0; 362 363 while(1) 364 { 365 response = AT91F_MCI_SendCommand(pMCI_Device, 366 AT91C_MMC_SEND_OP_COND_CMD, 367 AT91C_MMC_HOST_VOLTAGE_RANGE); 368 if (response != AT91C_CMD_SEND_OK) 369 return AT91C_INIT_ERROR; 370 371 response = AT91C_BASE_MCI->MCI_RSPR[0]; 372 373 if ( (response & AT91C_CARD_POWER_UP_BUSY) == AT91C_CARD_POWER_UP_BUSY) 374 return(response); 375 } 376} 377#endif 378 379#ifdef MMC 380//*---------------------------------------------------------------------------- 381//* \fn AT91F_MCI_MMC_GetAllCID 382//* \brief Asks to the MMC on the chosen slot to send its CID 383//*---------------------------------------------------------------------------- 384int AT91F_MCI_MMC_GetAllCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) 385{ 386 int Nb_Cards_Found=-1; 387 388 while(1) 389 { 390 if(AT91F_MCI_SendCommand(pMCI_Device, 391 AT91C_MMC_ALL_SEND_CID_CMD, 392 AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) 393 return Nb_Cards_Found; 394 else 395 { 396 Nb_Cards_Found = 0; 397 //* Assignation of the relative address to the MMC CARD 398 pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Relative_Card_Address = Nb_Cards_Found + AT91C_FIRST_RCA; 399 //* Set the insert flag 400 pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Card_Inserted = AT91C_MMC_CARD_INSERTED; 401 402 if (AT91F_MCI_SendCommand(pMCI_Device, 403 AT91C_MMC_SET_RELATIVE_ADDR_CMD, 404 (Nb_Cards_Found + AT91C_FIRST_RCA) << 16) != AT91C_CMD_SEND_OK) 405 return AT91C_CMD_SEND_ERROR; 406 407 //* If no error during assignation address ==> Increment Nb_cards_Found 408 Nb_Cards_Found++ ; 409 } 410 } 411} 412#endif 413#ifdef MMC 414//*---------------------------------------------------------------------------- 415//* \fn AT91F_MCI_MMC_Init 416//* \brief Return the MMC initialisation status 417//*---------------------------------------------------------------------------- 418int AT91F_MCI_MMC_Init (AT91PS_MciDevice pMCI_Device) 419{ 420 unsigned int tab_response[4]; 421 unsigned int mult,blocknr; 422 unsigned int i,Nb_Cards_Found=0; 423 424 //* Resets all MMC Cards in Idle state 425 AT91F_MCI_SendCommand(pMCI_Device, AT91C_MMC_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); 426 427 if(AT91F_MCI_MMC_GetAllOCR(pMCI_Device) == AT91C_INIT_ERROR) 428 return AT91C_INIT_ERROR; 429 430 Nb_Cards_Found = AT91F_MCI_MMC_GetAllCID(pMCI_Device,tab_response); 431 if (Nb_Cards_Found != AT91C_CMD_SEND_ERROR) 432 { 433 //* Set the Mode Register 434 AT91C_BASE_MCI->MCI_MR = AT91C_MCI_MR_PDCMODE; 435 436 for(i = 0; i < Nb_Cards_Found; i++) 437 { 438 if (AT91F_MCI_GetCSD(pMCI_Device, 439 pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address, 440 tab_response) != AT91C_CMD_SEND_OK) 441 pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address = 0; 442 else 443 { 444 pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); 445 pMCI_Device->pMCI_DeviceFeatures[i].Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); 446 pMCI_Device->pMCI_DeviceFeatures[i].Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v22_SECT_SIZE_S) & AT91C_CSD_v22_SECT_SIZE_M ); 447 pMCI_Device->pMCI_DeviceFeatures[i].Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; 448 pMCI_Device->pMCI_DeviceFeatures[i].Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; 449 450 // None in MMC specification version 2.2 451 pMCI_Device->pMCI_DeviceFeatures[i].Erase_Block_Enable = 0; 452 453 pMCI_Device->pMCI_DeviceFeatures[i].Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; 454 pMCI_Device->pMCI_DeviceFeatures[i].Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; 455 456 //// Compute Memory Capacity 457 // compute MULT 458 mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); 459 // compute MSB of C_SIZE 460 blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; 461 // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR 462 blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); 463 464 pMCI_Device->pMCI_DeviceFeatures[i].Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length * blocknr; 465 //// End of Compute Memory Capacity 466 467 } // end of else 468 } // end of for 469 470 return AT91C_INIT_OK; 471 } // end of if 472 473 return AT91C_INIT_ERROR; 474} 475#endif 476 477//*---------------------------------------------------------------------------- 478//* \fn AT91F_MCI_SDCard_GetOCR 479//* \brief Asks to all cards to send their operations conditions 480//*---------------------------------------------------------------------------- 481int AT91F_MCI_SDCard_GetOCR (AT91PS_MciDevice pMCI_Device) 482{ 483 unsigned int response =0x0; 484 485 // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000. 486 pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = 0x0; 487 488 while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) 489 { 490 response = AT91F_MCI_SDCard_SendAppCommand(pMCI_Device, 491 AT91C_SDCARD_APP_OP_COND_CMD, 492 AT91C_MMC_HOST_VOLTAGE_RANGE); 493 if (response != AT91C_CMD_SEND_OK) 494 return AT91C_INIT_ERROR; 495 496 response = AT91C_BASE_MCI->MCI_RSPR[0]; 497 } 498 499 return(AT91C_BASE_MCI->MCI_RSPR[0]); 500} 501 502//*---------------------------------------------------------------------------- 503//* \fn AT91F_MCI_SDCard_GetCID 504//* \brief Asks to the SDCard on the chosen slot to send its CID 505//*---------------------------------------------------------------------------- 506int AT91F_MCI_SDCard_GetCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) 507{ 508 if(AT91F_MCI_SendCommand(pMCI_Device, 509 AT91C_ALL_SEND_CID_CMD, 510 AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) 511 return AT91C_CMD_SEND_ERROR; 512 513 response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; 514 response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; 515 response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; 516 response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; 517 518 return AT91C_CMD_SEND_OK; 519} 520 521//*---------------------------------------------------------------------------- 522//* \fn AT91F_MCI_SDCard_SetBusWidth 523//* \brief Set bus width for SDCard 524//*---------------------------------------------------------------------------- 525int AT91F_MCI_SDCard_SetBusWidth(AT91PS_MciDevice pMCI_Device) 526{ 527 volatile int ret_value; 528 char bus_width; 529 530 do 531 { 532 ret_value =AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address); 533 } 534 while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0)); 535 536 // Select Card 537 AT91F_MCI_SendCommand(pMCI_Device, 538 AT91C_SEL_DESEL_CARD_CMD, 539 (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address)<<16); 540 541 // Set bus width for Sdcard 542 if(pMCI_Device->pMCI_DeviceDesc->SDCard_bus_width == AT91C_MCI_SCDBUS) 543 bus_width = AT91C_BUS_WIDTH_4BITS; 544 else bus_width = AT91C_BUS_WIDTH_1BIT; 545 546 if (AT91F_MCI_SDCard_SendAppCommand(pMCI_Device,AT91C_SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK) 547 return AT91C_CMD_SEND_ERROR; 548 549 return AT91C_CMD_SEND_OK; 550} 551 552//*---------------------------------------------------------------------------- 553//* \fn AT91F_MCI_SDCard_Init 554//* \brief Return the SDCard initialisation status 555//*---------------------------------------------------------------------------- 556int AT91F_MCI_SDCard_Init (AT91PS_MciDevice pMCI_Device) 557{ 558 unsigned int tab_response[4]; 559 unsigned int mult,blocknr; 560 561 AT91F_MCI_SendCommand(pMCI_Device, AT91C_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); 562 563 if(AT91F_MCI_SDCard_GetOCR(pMCI_Device) == AT91C_INIT_ERROR) 564 return AT91C_INIT_ERROR; 565 566 if (AT91F_MCI_SDCard_GetCID(pMCI_Device,tab_response) == AT91C_CMD_SEND_OK) 567 { 568 pMCI_Device->pMCI_DeviceFeatures->Card_Inserted = AT91C_SD_CARD_INSERTED; 569 570 if (AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_RELATIVE_ADDR_CMD, 0) == AT91C_CMD_SEND_OK) 571 { 572 pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16); 573 if (AT91F_MCI_GetCSD(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address,tab_response) == AT91C_CMD_SEND_OK) 574 { 575 pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); 576 pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); 577 pMCI_Device->pMCI_DeviceFeatures->Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v21_SECT_SIZE_S) & AT91C_CSD_v21_SECT_SIZE_M ); 578 pMCI_Device->pMCI_DeviceFeatures->Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; 579 pMCI_Device->pMCI_DeviceFeatures->Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; 580 pMCI_Device->pMCI_DeviceFeatures->Erase_Block_Enable = (tab_response[3] >> AT91C_CSD_v21_ER_BLEN_EN_S) & AT91C_CSD_v21_ER_BLEN_EN_M; 581 pMCI_Device->pMCI_DeviceFeatures->Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; 582 pMCI_Device->pMCI_DeviceFeatures->Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; 583 584 //// Compute Memory Capacity 585 // compute MULT 586 mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); 587 // compute MSB of C_SIZE 588 blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; 589 // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR 590 blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); 591 592 pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length * blocknr; 593 //// End of Compute Memory Capacity 594 printf("SD-Card: %d Bytes\n\r", pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity); 595 596 if( AT91F_MCI_SDCard_SetBusWidth(pMCI_Device) == AT91C_CMD_SEND_OK ) 597 { 598 if (AT91F_MCI_SetBlocklength(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) == AT91C_CMD_SEND_OK) 599 return AT91C_INIT_OK; 600 } 601 } 602 } 603 } 604 return AT91C_INIT_ERROR; 605} 606 607//*---------------------------------------------------------------------------- 608//* \fn AT91F_CfgDevice 609//* \brief This function is used to initialise MMC or SDCard Features 610//*---------------------------------------------------------------------------- 611void AT91F_CfgDevice(void) 612{ 613 // Init Device Structure 614 615 MCI_Device_Features.Relative_Card_Address = 0; 616 MCI_Device_Features.Card_Inserted = AT91C_CARD_REMOVED; 617 MCI_Device_Features.Max_Read_DataBlock_Length = 0; 618 MCI_Device_Features.Max_Write_DataBlock_Length = 0; 619 MCI_Device_Features.Read_Partial = 0; 620 MCI_Device_Features.Write_Partial = 0; 621 MCI_Device_Features.Erase_Block_Enable = 0; 622 MCI_Device_Features.Sector_Size = 0; 623 MCI_Device_Features.Memory_Capacity = 0; 624 625 MCI_Device_Desc.state = AT91C_MCI_IDLE; 626 MCI_Device_Desc.SDCard_bus_width = AT91C_MCI_SCDBUS; 627 628 // Init AT91S_DataFlash Global Structure, by default AT45DB choosen !!! 629 MCI_Device.pMCI_DeviceDesc = &MCI_Device_Desc; 630 MCI_Device.pMCI_DeviceFeatures = &MCI_Device_Features; 631 632} 633 634//*---------------------------------------------------------------------------- 635//* \fn AT91F_MCI_Init 636//* \brief Initialsise Card 637//*---------------------------------------------------------------------------- 638int AT91F_MCI_Init(void) 639{ 640 641/////////////////////////////////////////////////////////////////////////////////////////// 642// MCI Init : common to MMC and SDCard 643/////////////////////////////////////////////////////////////////////////////////////////// 644 645 // Set up PIO SDC_TYPE to switch on MMC/SDCard and not DataFlash Card 646 AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); 647 AT91F_PIO_SetOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); 648 649 // Init MCI for MMC and SDCard interface 650 AT91F_MCI_CfgPIO(); 651 AT91F_MCI_CfgPMC(); 652 AT91F_PDC_Open(AT91C_BASE_PDC_MCI); 653 654 // Disable all the interrupts 655 AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF; 656 657 // Init MCI Device Structures 658 AT91F_CfgDevice(); 659 660 // Configure MCI interrupt 661 AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, 662 AT91C_ID_MCI, 663 AT91C_AIC_PRIOR_HIGHEST, 664 AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, 665 AT91F_ASM_MCI_Handler); 666 667 // Enable MCI interrupt 668 AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_MCI); 669 670 // Enable Receiver 671 AT91F_US_EnableRx((AT91PS_USART) AT91C_BASE_DBGU); 672 673 AT91F_MCI_Configure(AT91C_BASE_MCI, 674 AT91C_MCI_DTOR_1MEGA_CYCLES, 675 AT91C_MCI_MR_PDCMODE, // 15MHz for MCK = 60MHz (CLKDIV = 1) 676 AT91C_MCI_SDCARD_4BITS_SLOTA); 677 678 if(AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK) 679 return FALSE; 680 else 681 return TRUE; 682 683} 684 685//*---------------------------------------------------------------------------- 686//* \fn AT91F_MCIDeviceWaitReady 687//* \brief Wait for MCI Device ready 688//*---------------------------------------------------------------------------- 689void AT91F_MCIDeviceWaitReady(unsigned int timeout) 690{ 691 volatile int status; 692 693 do 694 { 695 status = AT91C_BASE_MCI->MCI_SR; 696 timeout--; 697 } 698 while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) ); 699} 700 701unsigned int swab32(unsigned int data) 702{ 703 unsigned int res = 0; 704 705 res = (data & 0x000000ff) << 24 | 706 (data & 0x0000ff00) << 8 | 707 (data & 0x00ff0000) >> 8 | 708 (data & 0xff000000) >> 24; 709 710 return res; 711} 712 713//*-------------------------------------------------------------------- 714//* \fn AT91F_MCI_ReadBlockSwab 715//* \brief Read Block and swap byte order 716//*-------------------------------------------------------------------- 717int AT91F_MCI_ReadBlockSwab( 718 AT91PS_MciDevice pMCI_Device, 719 int src, 720 unsigned int *databuffer, 721 int sizeToRead) 722{ 723 int i; 724 unsigned char *buf = (unsigned char *)databuffer; 725 726 //* Read Block 1 727 for(i=0;i<BUFFER_SIZE_MCI_DEVICE;i++) 728 *buf++ = 0x00; 729 AT91F_MCI_ReadBlock(&MCI_Device,src,databuffer,sizeToRead); 730 731 //* Wait end of Read 732 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); 733 734 { 735 int index; 736 unsigned int *uiBuffer = databuffer; 737 738 for(index = 0; index < 512/4; index++) 739 uiBuffer[index] = swab32(uiBuffer[index]); 740 } 741 return(1); 742} 743 744