diff options
Diffstat (limited to 'target/linux/at91/image/dfboot/src/mci_device.c')
-rw-r--r-- | target/linux/at91/image/dfboot/src/mci_device.c | 743 |
1 files changed, 0 insertions, 743 deletions
diff --git a/target/linux/at91/image/dfboot/src/mci_device.c b/target/linux/at91/image/dfboot/src/mci_device.c deleted file mode 100644 index cce74a3..0000000 --- a/target/linux/at91/image/dfboot/src/mci_device.c +++ /dev/null @@ -1,743 +0,0 @@ -//*---------------------------------------------------------------------------- -//* ATMEL Microcontroller Software Support - ROUSSET - -//*---------------------------------------------------------------------------- -//* The software is delivered "AS IS" without warranty or condition of any -//* kind, either express, implied or statutory. This includes without -//* limitation any warranty or condition with respect to merchantability or -//* fitness for any particular purpose, or against the infringements of -//* intellectual property rights of others. -//*---------------------------------------------------------------------------- -//* File Name : mci_device.c -//* Object : TEST DataFlash Functions -//* Creation : FB 26/11/2002 -//* -//*---------------------------------------------------------------------------- - -#include <AT91C_MCI_Device.h> -#include "stdio.h" - -#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ -#define BUFFER_SIZE_MCI_DEVICE 512 -#define MASTER_CLOCK 60000000 -#define FALSE 0 -#define TRUE 1 - -//* External Functions -extern void AT91F_ASM_MCI_Handler(void); -//* Global Variables -AT91S_MciDeviceFeatures MCI_Device_Features; -AT91S_MciDeviceDesc MCI_Device_Desc; -AT91S_MciDevice MCI_Device; - -#undef ENABLE_WRITE -#undef MMC - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SendCommand -//* \brief Generic function to send a command to the MMC or SDCard -//*---------------------------------------------------------------------------- -int AT91F_MCI_SendCommand ( - AT91PS_MciDevice pMCI_Device, - unsigned int Cmd, - unsigned int Arg) -{ - unsigned int error,status; - //unsigned int tick=0; - - // Send the command - AT91C_BASE_MCI->MCI_ARGR = Arg; - AT91C_BASE_MCI->MCI_CMDR = Cmd; - - // wait for CMDRDY Status flag to read the response - do - { - status = AT91C_BASE_MCI->MCI_SR; - //tick++; - } - while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); - - // Test error ==> if crc error and response R3 ==> don't check error - error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR; - if(error != 0 ) - { - // if the command is SEND_OP_COND the CRC error flag is always present (cf : R3 response) - if ( (Cmd != AT91C_SDCARD_APP_OP_COND_CMD) && (Cmd != AT91C_MMC_SEND_OP_COND_CMD) ) - return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); - else - { - if (error != AT91C_MCI_RCRCE) - return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); - } - } - return AT91C_CMD_SEND_OK; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SDCard_SendAppCommand -//* \brief Specific function to send a specific command to the SDCard -//*---------------------------------------------------------------------------- -int AT91F_MCI_SDCard_SendAppCommand ( - AT91PS_MciDevice pMCI_Device, - unsigned int Cmd_App, - unsigned int Arg ) -{ - unsigned int status; - //unsigned int tick=0; - - // Send the CMD55 for application specific command - AT91C_BASE_MCI->MCI_ARGR = (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address << 16 ); - AT91C_BASE_MCI->MCI_CMDR = AT91C_APP_CMD; - - // wait for CMDRDY Status flag to read the response - do - { - status = AT91C_BASE_MCI->MCI_SR; - //tick++; - } - while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); - - // if an error occurs - if (((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR) != 0 ) - return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); - - // check if it is a specific command and then send the command - if ( (Cmd_App && AT91C_SDCARD_APP_ALL_CMD) == 0) - return AT91C_CMD_SEND_ERROR; - - return( AT91F_MCI_SendCommand(pMCI_Device,Cmd_App,Arg) ); -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_GetStatus -//* \brief Addressed card sends its status register -//*---------------------------------------------------------------------------- -int AT91F_MCI_GetStatus(AT91PS_MciDevice pMCI_Device,unsigned int relative_card_address) -{ - if (AT91F_MCI_SendCommand(pMCI_Device, - AT91C_SEND_STATUS_CMD, - relative_card_address <<16) == AT91C_CMD_SEND_OK) - return (AT91C_BASE_MCI->MCI_RSPR[0]); - - return AT91C_CMD_SEND_ERROR; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_Device_Handler -//* \brief MCI C interrupt handler -//*---------------------------------------------------------------------------- -void AT91F_MCI_Device_Handler( - AT91PS_MciDevice pMCI_Device, - unsigned int status) -{ - // If End of Tx Buffer Empty interrupt occurred - if ( status & AT91C_MCI_TXBUFE ) - { - AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE; - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS; - - pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; - } // End of if AT91C_MCI_TXBUFF - - // If End of Rx Buffer Full interrupt occurred - if ( status & AT91C_MCI_RXBUFF ) - { - AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF; - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS; - - pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; - } // End of if AT91C_MCI_RXBUFF - -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_Handler -//* \brief MCI Handler -//*---------------------------------------------------------------------------- -void AT91F_MCI_Handler(void) -{ - int status; - - status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR ); - - AT91F_MCI_Device_Handler(&MCI_Device,status); -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_ReadBlock -//* \brief Read an ENTIRE block or PARTIAL block -//*---------------------------------------------------------------------------- -int AT91F_MCI_ReadBlock( - AT91PS_MciDevice pMCI_Device, - int src, - unsigned int *dataBuffer, - int sizeToRead ) -{ - //////////////////////////////////////////////////////////////////////////////////////////// - if(pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) - return AT91C_READ_ERROR; - - if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) - return AT91C_READ_ERROR; - - if ( (src + sizeToRead) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) - return AT91C_READ_ERROR; - - // If source does not fit a begin of a block - if ( (src % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) - return AT91C_READ_ERROR; - - // Test if the MMC supports Partial Read Block - // ALWAYS SUPPORTED IN SD Memory Card - if( (sizeToRead < pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) - && (pMCI_Device->pMCI_DeviceFeatures->Read_Partial == 0x00) ) - return AT91C_READ_ERROR; - - if( sizeToRead > pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) - return AT91C_READ_ERROR; - //////////////////////////////////////////////////////////////////////////////////////////// - - // Init Mode Register - AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); - - if (sizeToRead %4) - sizeToRead = (sizeToRead /4)+1; - else - sizeToRead = sizeToRead/4; - - AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); - AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer; - AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead; - - // Send the Read single block command - if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_READ_SINGLE_BLOCK_CMD, src) != AT91C_CMD_SEND_OK ) - return AT91C_READ_ERROR; - - pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_RX_SINGLE_BLOCK; - - // Enable AT91C_MCI_RXBUFF Interrupt - AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF; - - // (PDC) Receiver Transfer Enable - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN; - - return AT91C_READ_OK; -} - - -#ifdef ENABLE_WRITE -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_WriteBlock -//* \brief Write an ENTIRE block but not always PARTIAL block !!! -//*---------------------------------------------------------------------------- -int AT91F_MCI_WriteBlock( - AT91PS_MciDevice pMCI_Device, - int dest, - unsigned int *dataBuffer, - int sizeToWrite ) -{ - //////////////////////////////////////////////////////////////////////////////////////////// - if( pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) - return AT91C_WRITE_ERROR; - - if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) - return AT91C_WRITE_ERROR; - - if ( (dest + sizeToWrite) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) - return AT91C_WRITE_ERROR; - - // If source does not fit a begin of a block - if ( (dest % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) - return AT91C_WRITE_ERROR; - - // Test if the MMC supports Partial Write Block - if( (sizeToWrite < pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length) - && (pMCI_Device->pMCI_DeviceFeatures->Write_Partial == 0x00) ) - return AT91C_WRITE_ERROR; - - if( sizeToWrite > pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length ) - return AT91C_WRITE_ERROR; - //////////////////////////////////////////////////////////////////////////////////////////// - - // Init Mode Register - AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); - - if (sizeToWrite %4) - sizeToWrite = (sizeToWrite /4)+1; - else - sizeToWrite = sizeToWrite/4; - - // Init PDC for write sequence - AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); - AT91C_BASE_PDC_MCI->PDC_TPR = (unsigned int) dataBuffer; - AT91C_BASE_PDC_MCI->PDC_TCR = sizeToWrite; - - // Send the write single block command - if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_WRITE_BLOCK_CMD, dest) != AT91C_CMD_SEND_OK) - return AT91C_WRITE_ERROR; - - pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_TX_SINGLE_BLOCK; - - // Enable AT91C_MCI_TXBUFE Interrupt - AT91C_BASE_MCI->MCI_IER = AT91C_MCI_TXBUFE; - - // Enables TX for PDC transfert requests - AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTEN; - - return AT91C_WRITE_OK; -} -#endif - -#ifdef MMC -//*------------------------------------------------------------------------------------------------------------ -//* \fn AT91F_MCI_MMC_SelectCard -//* \brief Toggles a card between the Stand_by and Transfer states or between Programming and Disconnect states -//*------------------------------------------------------------------------------------------------------------ -int AT91F_MCI_MMC_SelectCard(AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address) -{ - int status; - - //* Check if the MMC card chosen is already the selected one - status = AT91F_MCI_GetStatus(pMCI_Device,relative_card_address); - - if (status < 0) - return AT91C_CARD_SELECTED_ERROR; - - if ((status & AT91C_SR_CARD_SELECTED) == AT91C_SR_CARD_SELECTED) - return AT91C_CARD_SELECTED_OK; - - //* Search for the MMC Card to be selected, status = the Corresponding Device Number - status = 0; - while( (pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address != relative_card_address) - && (status < AT91C_MAX_MCI_CARDS) ) - status++; - - if (status > AT91C_MAX_MCI_CARDS) - return AT91C_CARD_SELECTED_ERROR; - - if (AT91F_MCI_SendCommand( pMCI_Device, - AT91C_SEL_DESEL_CARD_CMD, - pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address << 16) == AT91C_CMD_SEND_OK) - return AT91C_CARD_SELECTED_OK; - return AT91C_CARD_SELECTED_ERROR; -} -#endif - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_GetCSD -//* \brief Asks to the specified card to send its CSD -//*---------------------------------------------------------------------------- -int AT91F_MCI_GetCSD (AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address , unsigned int * response) -{ - - if(AT91F_MCI_SendCommand(pMCI_Device, - AT91C_SEND_CSD_CMD, - (relative_card_address << 16)) != AT91C_CMD_SEND_OK) - return AT91C_CMD_SEND_ERROR; - - response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; - response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; - response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; - response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; - - return AT91C_CMD_SEND_OK; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SetBlocklength -//* \brief Select a block length for all following block commands (R/W) -//*---------------------------------------------------------------------------- -int AT91F_MCI_SetBlocklength(AT91PS_MciDevice pMCI_Device,unsigned int length) -{ - return( AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_BLOCKLEN_CMD, length) ); -} - -#ifdef MMC -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_MMC_GetAllOCR -//* \brief Asks to all cards to send their operations conditions -//*---------------------------------------------------------------------------- -int AT91F_MCI_MMC_GetAllOCR (AT91PS_MciDevice pMCI_Device) -{ - unsigned int response =0x0; - - while(1) - { - response = AT91F_MCI_SendCommand(pMCI_Device, - AT91C_MMC_SEND_OP_COND_CMD, - AT91C_MMC_HOST_VOLTAGE_RANGE); - if (response != AT91C_CMD_SEND_OK) - return AT91C_INIT_ERROR; - - response = AT91C_BASE_MCI->MCI_RSPR[0]; - - if ( (response & AT91C_CARD_POWER_UP_BUSY) == AT91C_CARD_POWER_UP_BUSY) - return(response); - } -} -#endif - -#ifdef MMC -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_MMC_GetAllCID -//* \brief Asks to the MMC on the chosen slot to send its CID -//*---------------------------------------------------------------------------- -int AT91F_MCI_MMC_GetAllCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) -{ - int Nb_Cards_Found=-1; - - while(1) - { - if(AT91F_MCI_SendCommand(pMCI_Device, - AT91C_MMC_ALL_SEND_CID_CMD, - AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) - return Nb_Cards_Found; - else - { - Nb_Cards_Found = 0; - //* Assignation of the relative address to the MMC CARD - pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Relative_Card_Address = Nb_Cards_Found + AT91C_FIRST_RCA; - //* Set the insert flag - pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Card_Inserted = AT91C_MMC_CARD_INSERTED; - - if (AT91F_MCI_SendCommand(pMCI_Device, - AT91C_MMC_SET_RELATIVE_ADDR_CMD, - (Nb_Cards_Found + AT91C_FIRST_RCA) << 16) != AT91C_CMD_SEND_OK) - return AT91C_CMD_SEND_ERROR; - - //* If no error during assignation address ==> Increment Nb_cards_Found - Nb_Cards_Found++ ; - } - } -} -#endif -#ifdef MMC -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_MMC_Init -//* \brief Return the MMC initialisation status -//*---------------------------------------------------------------------------- -int AT91F_MCI_MMC_Init (AT91PS_MciDevice pMCI_Device) -{ - unsigned int tab_response[4]; - unsigned int mult,blocknr; - unsigned int i,Nb_Cards_Found=0; - - //* Resets all MMC Cards in Idle state - AT91F_MCI_SendCommand(pMCI_Device, AT91C_MMC_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); - - if(AT91F_MCI_MMC_GetAllOCR(pMCI_Device) == AT91C_INIT_ERROR) - return AT91C_INIT_ERROR; - - Nb_Cards_Found = AT91F_MCI_MMC_GetAllCID(pMCI_Device,tab_response); - if (Nb_Cards_Found != AT91C_CMD_SEND_ERROR) - { - //* Set the Mode Register - AT91C_BASE_MCI->MCI_MR = AT91C_MCI_MR_PDCMODE; - - for(i = 0; i < Nb_Cards_Found; i++) - { - if (AT91F_MCI_GetCSD(pMCI_Device, - pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address, - tab_response) != AT91C_CMD_SEND_OK) - pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address = 0; - else - { - 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 ); - pMCI_Device->pMCI_DeviceFeatures[i].Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); - pMCI_Device->pMCI_DeviceFeatures[i].Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v22_SECT_SIZE_S) & AT91C_CSD_v22_SECT_SIZE_M ); - pMCI_Device->pMCI_DeviceFeatures[i].Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; - pMCI_Device->pMCI_DeviceFeatures[i].Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; - - // None in MMC specification version 2.2 - pMCI_Device->pMCI_DeviceFeatures[i].Erase_Block_Enable = 0; - - pMCI_Device->pMCI_DeviceFeatures[i].Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; - pMCI_Device->pMCI_DeviceFeatures[i].Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; - - //// Compute Memory Capacity - // compute MULT - mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); - // compute MSB of C_SIZE - blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; - // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR - blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); - - pMCI_Device->pMCI_DeviceFeatures[i].Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length * blocknr; - //// End of Compute Memory Capacity - - } // end of else - } // end of for - - return AT91C_INIT_OK; - } // end of if - - return AT91C_INIT_ERROR; -} -#endif - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SDCard_GetOCR -//* \brief Asks to all cards to send their operations conditions -//*---------------------------------------------------------------------------- -int AT91F_MCI_SDCard_GetOCR (AT91PS_MciDevice pMCI_Device) -{ - unsigned int response =0x0; - - // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000. - pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = 0x0; - - while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) - { - response = AT91F_MCI_SDCard_SendAppCommand(pMCI_Device, - AT91C_SDCARD_APP_OP_COND_CMD, - AT91C_MMC_HOST_VOLTAGE_RANGE); - if (response != AT91C_CMD_SEND_OK) - return AT91C_INIT_ERROR; - - response = AT91C_BASE_MCI->MCI_RSPR[0]; - } - - return(AT91C_BASE_MCI->MCI_RSPR[0]); -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SDCard_GetCID -//* \brief Asks to the SDCard on the chosen slot to send its CID -//*---------------------------------------------------------------------------- -int AT91F_MCI_SDCard_GetCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) -{ - if(AT91F_MCI_SendCommand(pMCI_Device, - AT91C_ALL_SEND_CID_CMD, - AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) - return AT91C_CMD_SEND_ERROR; - - response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; - response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; - response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; - response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; - - return AT91C_CMD_SEND_OK; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SDCard_SetBusWidth -//* \brief Set bus width for SDCard -//*---------------------------------------------------------------------------- -int AT91F_MCI_SDCard_SetBusWidth(AT91PS_MciDevice pMCI_Device) -{ - volatile int ret_value; - char bus_width; - - do - { - ret_value =AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address); - } - while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0)); - - // Select Card - AT91F_MCI_SendCommand(pMCI_Device, - AT91C_SEL_DESEL_CARD_CMD, - (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address)<<16); - - // Set bus width for Sdcard - if(pMCI_Device->pMCI_DeviceDesc->SDCard_bus_width == AT91C_MCI_SCDBUS) - bus_width = AT91C_BUS_WIDTH_4BITS; - else bus_width = AT91C_BUS_WIDTH_1BIT; - - if (AT91F_MCI_SDCard_SendAppCommand(pMCI_Device,AT91C_SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK) - return AT91C_CMD_SEND_ERROR; - - return AT91C_CMD_SEND_OK; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_SDCard_Init -//* \brief Return the SDCard initialisation status -//*---------------------------------------------------------------------------- -int AT91F_MCI_SDCard_Init (AT91PS_MciDevice pMCI_Device) -{ - unsigned int tab_response[4]; - unsigned int mult,blocknr; - - AT91F_MCI_SendCommand(pMCI_Device, AT91C_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); - - if(AT91F_MCI_SDCard_GetOCR(pMCI_Device) == AT91C_INIT_ERROR) - return AT91C_INIT_ERROR; - - if (AT91F_MCI_SDCard_GetCID(pMCI_Device,tab_response) == AT91C_CMD_SEND_OK) - { - pMCI_Device->pMCI_DeviceFeatures->Card_Inserted = AT91C_SD_CARD_INSERTED; - - if (AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_RELATIVE_ADDR_CMD, 0) == AT91C_CMD_SEND_OK) - { - pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16); - if (AT91F_MCI_GetCSD(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address,tab_response) == AT91C_CMD_SEND_OK) - { - pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); - pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); - pMCI_Device->pMCI_DeviceFeatures->Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v21_SECT_SIZE_S) & AT91C_CSD_v21_SECT_SIZE_M ); - pMCI_Device->pMCI_DeviceFeatures->Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; - pMCI_Device->pMCI_DeviceFeatures->Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; - pMCI_Device->pMCI_DeviceFeatures->Erase_Block_Enable = (tab_response[3] >> AT91C_CSD_v21_ER_BLEN_EN_S) & AT91C_CSD_v21_ER_BLEN_EN_M; - pMCI_Device->pMCI_DeviceFeatures->Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; - pMCI_Device->pMCI_DeviceFeatures->Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; - - //// Compute Memory Capacity - // compute MULT - mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); - // compute MSB of C_SIZE - blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; - // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR - blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); - - pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length * blocknr; - //// End of Compute Memory Capacity - printf("SD-Card: %d Bytes\n\r", pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity); - - if( AT91F_MCI_SDCard_SetBusWidth(pMCI_Device) == AT91C_CMD_SEND_OK ) - { - if (AT91F_MCI_SetBlocklength(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) == AT91C_CMD_SEND_OK) - return AT91C_INIT_OK; - } - } - } - } - return AT91C_INIT_ERROR; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_CfgDevice -//* \brief This function is used to initialise MMC or SDCard Features -//*---------------------------------------------------------------------------- -void AT91F_CfgDevice(void) -{ - // Init Device Structure - - MCI_Device_Features.Relative_Card_Address = 0; - MCI_Device_Features.Card_Inserted = AT91C_CARD_REMOVED; - MCI_Device_Features.Max_Read_DataBlock_Length = 0; - MCI_Device_Features.Max_Write_DataBlock_Length = 0; - MCI_Device_Features.Read_Partial = 0; - MCI_Device_Features.Write_Partial = 0; - MCI_Device_Features.Erase_Block_Enable = 0; - MCI_Device_Features.Sector_Size = 0; - MCI_Device_Features.Memory_Capacity = 0; - - MCI_Device_Desc.state = AT91C_MCI_IDLE; - MCI_Device_Desc.SDCard_bus_width = AT91C_MCI_SCDBUS; - - // Init AT91S_DataFlash Global Structure, by default AT45DB choosen !!! - MCI_Device.pMCI_DeviceDesc = &MCI_Device_Desc; - MCI_Device.pMCI_DeviceFeatures = &MCI_Device_Features; - -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCI_Init -//* \brief Initialsise Card -//*---------------------------------------------------------------------------- -int AT91F_MCI_Init(void) -{ - -/////////////////////////////////////////////////////////////////////////////////////////// -// MCI Init : common to MMC and SDCard -/////////////////////////////////////////////////////////////////////////////////////////// - - // Set up PIO SDC_TYPE to switch on MMC/SDCard and not DataFlash Card - AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); - AT91F_PIO_SetOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); - - // Init MCI for MMC and SDCard interface - AT91F_MCI_CfgPIO(); - AT91F_MCI_CfgPMC(); - AT91F_PDC_Open(AT91C_BASE_PDC_MCI); - - // Disable all the interrupts - AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF; - - // Init MCI Device Structures - AT91F_CfgDevice(); - - // Configure MCI interrupt - AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, - AT91C_ID_MCI, - AT91C_AIC_PRIOR_HIGHEST, - AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, - AT91F_ASM_MCI_Handler); - - // Enable MCI interrupt - AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_MCI); - - // Enable Receiver - AT91F_US_EnableRx((AT91PS_USART) AT91C_BASE_DBGU); - - AT91F_MCI_Configure(AT91C_BASE_MCI, - AT91C_MCI_DTOR_1MEGA_CYCLES, - AT91C_MCI_MR_PDCMODE, // 15MHz for MCK = 60MHz (CLKDIV = 1) - AT91C_MCI_SDCARD_4BITS_SLOTA); - - if(AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK) - return FALSE; - else - return TRUE; - -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_MCIDeviceWaitReady -//* \brief Wait for MCI Device ready -//*---------------------------------------------------------------------------- -void AT91F_MCIDeviceWaitReady(unsigned int timeout) -{ - volatile int status; - - do - { - status = AT91C_BASE_MCI->MCI_SR; - timeout--; - } - while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) ); -} - -unsigned int swab32(unsigned int data) -{ - unsigned int res = 0; - - res = (data & 0x000000ff) << 24 | - (data & 0x0000ff00) << 8 | - (data & 0x00ff0000) >> 8 | - (data & 0xff000000) >> 24; - - return res; -} - -//*-------------------------------------------------------------------- -//* \fn AT91F_MCI_ReadBlockSwab -//* \brief Read Block and swap byte order -//*-------------------------------------------------------------------- -int AT91F_MCI_ReadBlockSwab( - AT91PS_MciDevice pMCI_Device, - int src, - unsigned int *databuffer, - int sizeToRead) -{ - int i; - unsigned char *buf = (unsigned char *)databuffer; - - //* Read Block 1 - for(i=0;i<BUFFER_SIZE_MCI_DEVICE;i++) - *buf++ = 0x00; - AT91F_MCI_ReadBlock(&MCI_Device,src,databuffer,sizeToRead); - - //* Wait end of Read - AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); - - { - int index; - unsigned int *uiBuffer = databuffer; - - for(index = 0; index < 512/4; index++) - uiBuffer[index] = swab32(uiBuffer[index]); - } - return(1); -} - |