Added Software projects

git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@55 9fe90eed-be63-e94b-8204-d34ff4c2ff93
This commit is contained in:
Matthias
2008-12-23 10:34:08 +00:00
parent ee5a771818
commit 373a8c32b2
348 changed files with 86781 additions and 0 deletions
+810
View File
@@ -0,0 +1,810 @@
/* ---------------------------------------------------------------------------
* mmc.c (c) 2008 Micro-key bv
* ---------------------------------------------------------------------------
* Micro-key bv
* Industrieweg 28, 9804 TG Noordhorn
* Postbus 92, 9800 AB Zuidhorn
* The Netherlands
* Tel: +31 594 503020
* Fax: +31 594 505825
* Email: support@microkey.nl
* Web: www.microkey.nl
* ---------------------------------------------------------------------------
* Description:
* ---------------------------------------------------------------------------
* Version(s): 0.1, Apr 22, 2008, MMi
* Creation.
* ---------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------
* System include files
* ---------------------------------------------------------------------------
*/
/* Compiler Includes */
#include <string.h>
#include <assert.h>
#include "LPC23xx.h"
#include "types.h"
/* ---------------------------------------------------------------------------
* Application include files
* ---------------------------------------------------------------------------
*/
#include "mmc.h"
#include "mmc_transfer.h"
#include "dio.h"
/* ---------------------------------------------------------------------------
* Local constant and macro definitions
* ---------------------------------------------------------------------------
*/
#define MMC_GLOBAL
#define __no_init
#define CSD_GET_TRAN_SPEED_EXP() (MmcSdCsd[ 0]&0x07)
#define CSD_GET_TRAN_SPEED_MANT() ((MmcSdCsd[ 0]&0xF8)>>3 )
#define CSD_GET_NSAC() (MmcSdCsd[ 1] )
#define CSD_GET_TAAC_EXP() (MmcSdCsd[ 2]&0x7)
#define CSD_GET_TAAC_MANT() ((MmcSdCsd[ 2]&0xF8)>>3 )
#define CSD_GET_R2W_FACTOR() ((MmcSdCsd[15]&0x1C)>>2 )
#define CSD_GET_READ_BL_LEN() (MmcSdCsd[ 6]&0x0F)
#define CSD_GET_C_SIZE() (((MmcSdCsd[ 5]&0x03)<<10) + (MmcSdCsd[4]<<2) + ((MmcSdCsd[11]&0xc0)>>6))
#define CSD_GET_C_SIZE_MULT() (((MmcSdCsd[10]&0x03)<<1 ) +((MmcSdCsd[9]&0x80)>>7))
#define CSD_GET_PERM_WRITE_PROTECT() ((MmcSdCsd[13]&0x20)>>5 )
#define CSD_GET_TMP_WRITE_PROTECT() ((MmcSdCsd[13]&0x10)>>4 )
volatile UINT32 i;
#define SpcInquiryRemovableMedium 0x80
#define SpcInquiryStandartVersion 5
#define SizeOfInquiryDescMmcDsk 36
const UINT32 MmcTransfExp[] =
{ 10000UL, 100000UL, 1000000UL, 10000000UL, 0UL, 0UL, 0UL, 0UL,
};
const UINT32 MmmcAccessTime [] =
{ 1UL, 10UL, 100UL, 1000UL, 10000UL, 100000UL, 1000000UL, 10000000UL,
};
const UINT32 MmcCsdMant[] =
{ 0UL, 10UL, 12UL, 13UL, 15UL, 20UL, 25UL, 30UL, 35UL, 40UL, 45UL, 50UL,
55UL, 60UL, 70UL, 80UL,
};
const MmcCommads_t MmcCmd[CMD_END] =
{ /* {TxData, Arg, Resp} */
{ 0x00, MmcNoArg, MmcNoResp }, /* CMD0 */
{ 0x01, MmcOcr, MmcR3 }, /* CMD1 */
{ 0x02, MmcNoArg, MmcR2 }, /* CMD2 */
{ 0x03, MmcRelAddr, MmcR1 }, /* CMD3 */
{ 0x07, MmcRelAddr, MmcR1 }, /* CMD7 */
{ 0x09, MmcRelAddr, MmcR2 }, /* CMD9 */
{ 0x0A, MmcRelAddr, MmcR2 }, /* CMD10 */
{ 0x0C, MmcNoArg, MmcR1b }, /* CMD12 */
{ 0x0D, MmcRelAddr, MmcR1 }, /* CMD13 */
{ 0x10, MmcBlockLen, MmcR1 }, /* CMD16 */
{ 0x11, MmcDataAdd, MmcR1 }, /* CMD17 */
{ 0x12, MmcDataAdd, MmcR1 }, /* CMD18 */
{ 0x18, MmcDataAdd, MmcR1 }, /* CMD24 */
{ 0x19, MmcDataAdd, MmcR1 }, /* CMD25 */
{ 0x1B, MmcOcr, MmcR1 }, /* CMD27 */
{ 0x1C, MmcDataAdd, MmcR1b }, /* CMD28 */
{ 0x1D, MmcDataAdd, MmcR1b }, /* CMD29 */
{ 0x1E, MmcDataAdd, MmcR1 }, /* CMD30 */
{ 0x20, MmcDataAdd, MmcR1 }, /* CMD32 */
{ 0x21, MmcDataAdd, MmcR1 }, /* CMD33 */
{ 0x22, MmcDataAdd, MmcR1 }, /* CMD34 */
{ 0x23, MmcDataAdd, MmcR1 }, /* CMD35 */
{ 0x24, MmcDataAdd, MmcR1 }, /* CMD36 */
{ 0x25, MmcDataAdd, MmcR1 }, /* CMD37 */
{ 0x26, MmcNoArg, MmcR1b }, /* CMD38 */
{ 0x2A, MmcNoArg, MmcR1b }, /* CMD42 */
{ 0x37, MmcRelAddr, MmcR1 }, /* CMD55 */
{ 0x38, MmcNoArg, MmcR1 }, /* CMD56 */
{ 0x06, MmcDataAdd, MmcR1 }, /* ACMD46 */
{ 0x29, MmcDataAdd, MmcR3 }, /* ACMD41 */
};
const UINT8 MmcDskInquiry[]__attribute__((aligned (4)))=
{
SbcDirectAccess, /* 0 PERIPHERAL QUALIFIER AND DEVICE*/
SpcInquiryRemovableMedium, /* 1 RMB */
SpcInquiryStandartVersion, /* 2 VERSION */
0x02, /* 3 NORMACA HISUP RESPONSE FORMAT */
36-4, /* 4 ADDITIONAL LENGTH (n-4) */
0x00, /* 5 SCCS */
/* for parallel SCSI only */
0x00, /* 6 BQUE ENCSERV VS MULTIP MCHNGR Obsolete Obsolete ADDR16 */
0x00, /* 7 RELADR Obsolete WBUS16† SYNC† LINKED Obsolete CMDQUE VS*/
'I','A','R',' ','S','y','s','.', /* 8 - 15 VENDOR IDENTIFICATION */
/* 16 - 31 PRODUCT IDENTIFICATION */
'L','P','C','2','3','7','8',' ','S','t','o','r','a','g','e',' ',
'1','.','0','0', /* 32 - 35 PRODUCT REVISION LEVEL */
};
/* ---------------------------------------------------------------------------
* Global variable definitions
* ---------------------------------------------------------------------------
*/
static UINT32 CardRCA;
UINT32 MmcLastError;
UINT32 dlycnt;
UINT32 Tnac;
UINT32 Twr;
UINT8 MmcSdCsd[16]__attribute__ ((aligned (4)));
static BOOLEAN bMmcPermWriteProtect;
BOOLEAN bMmcChanged;
DiskCtrlBlk_t MmcDskCtrlBlk;
/* ---------------------------------------------------------------------------
* Local variable definitions
* ---------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------
* Local function definitions
* ---------------------------------------------------------------------------
*/
/* Function returns TRUE if Card is inserted, FALSE if Card is removed */
inline BOOLEAN MmcPresent(void)
{
return (!(MMC_CP_FIO & MMC_CP_MASK));
}
/* Function returns TRUE is WriteProtection is activated, FALSE if
* Protection is off. If no Card is inserted, Function will also return
* TRUE. This results from the physical Switch Connection (See Datasheet).
* Usage of this Function only makes Sense with previous TRUE-Return
* from MmcPresent.
*/
inline BOOLEAN MmcWriteProtect(void)
{
if (!(MMC_WP_FIO & MMC_WP_MASK))
{
return (FALSE);
}
else
{
return (TRUE);
}
}
UINT32 MmcSetClockFreq (UINT32 Frequency)
{
UINT32 Pclk = SYS_GetFPclk(MCI_PCLK_OFFSET);
UINT32 Div;
Frequency <<= 1;
for(Div = 1; Div <= 256; ++Div)
{
if((Frequency * Div)> Pclk)
{
break;
}
}
MCI_CLOCK = ((Div - 1) & 0xFF); /* Set Clock Devider (Bit 0-7) */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_CLOCK |= (1 << 8); /* enable Clock (Bit 8) */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_CLOCK |= (1 << 9); /* Set PowerSave (Bit 9) */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
return(Pclk/(Div<<1)); /* Return real frequency */
}
void MmcInit(void)
{
UINT32 i;
MMC_CP_DIR &= ~MMC_CP_MASK; /* Set CP to Input */
MMC_CP_MODE &=~(1 << 24); /* Neither PullUp nor PullDown */
MMC_CP_MODE |= (1 << 25);
MMC_WP_DIR &= ~MMC_WP_MASK; /* Set WP to Input */
MMC_WP_MODE &=~(1 << 22); /* Neither PullUp nor PullDown */
MMC_WP_MODE |= (1 << 23);
PCLKSEL1 |= (1 << 24); /* set divider to /1 (Bit 24&25) */
PCLKSEL1 &=~(1 << 25);
PCONP |= 0x30000000; /* Set Power up */
PINSEL1 &=~(1 << 6); /* Assign Pin 0.19 (Bit 6&7) */
PINSEL1 |= (1 << 7);
PINSEL1 &=~(1 << 8); /* Assign Pin 0.20 (Bit 8&9) */
PINSEL1 |= (1 << 9);
PINSEL1 &=~(1 << 10); /* Assign Pin 0.21 (Bit 10&11) */
PINSEL1 |= (1 << 11);
PINSEL1 &=~(1 << 12); /* Assign Pin 0.22 (Bit 12&13) */
PINSEL1 |= (1 << 13);
PINSEL4 &=~(1 << 22); /* Assign Pin 2.11 (Bit 22&23) */
PINSEL4 |= (1 << 23);
PINSEL4 &=~(1 << 24); /* Assign Pin 2.12 (Bit 24&25) */
PINSEL4 |= (1 << 25);
PINSEL4 &=~(1 << 26); /* Assign Pin 2.13 (Bit 26&27) */
PINSEL4 |= (1 << 27);
PINMODE1 &=~(1 << 6) & ~(1 << 7); /* Set PullUp Pin 0.19 (Bit 6&7) */
PINMODE1 &=~(1 << 8) & ~(1 << 9); /* Set PullUp Pin 0.20 (Bit 8&9) */
PINMODE1 &=~(1 << 10) & ~(1 << 11); /* Set PullUp Pin 0.21 (Bit 10&11) */
PINMODE1 &=~(1 << 12) & ~(1 << 13); /* Set PullUp Pin 0.22 (Bit 12&13) */
MCI_COMMAND = 0; /* Clear MCI Command Register */
MCI_DATA_CTRL = 0; /* Clear MCI Data Control Register */
MCI_CLEAR = 0x7FF; /* Clear all pending interrupts. */
/* Power up, switch on VCC for the Flash Card - Wait shortly */
MCI_POWER = 0x02;
for (i = 0; i < 50000; i++);
MCI_POWER |= 0x01; /* Power on the Flash Card. */
for (i = 0; i < 50000; i++); /* Wait shortly */
MmcPowerDown();
GPDMA_SYNC = 0; /* DMA sync enable */
GPDMA_INT_ERR_CLR = 3; /* Clear DMA Error Interrupts */
GPDMA_INT_TCCLR = 3; /* Clear DMA Interrupts */
}
void MmcPowerDown(void)
{
SCS |= (1 << 3); /* Init Power State (Bit 3) */
MCI_POWER = 0;
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_MASK0 = 0; /* Disable all interrupts for now */
MCI_MASK1 = 0;
MCI_COMMAND = 0;
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_DATA_CTRL = 0;
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_CLEAR = 0x7FF;
MCI_CLOCK &=~(1 << 11); /* clear all pending interrupts */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MmcSetClockFreq(IdentificationModeClock); /* ClkFreq Ident Mode< 400kHz */
}
MmcState_t MmcSendCmd(MmcSpiCmdInd_t ComdInd, pUINT32 pArg)
{
UINT32 Status;
union
{
UINT32 Data;
struct
{
UINT32 CMDINDEX : 6;
UINT32 RESPONSE : 1;
UINT32 LONGRSP : 1;
UINT32 INTERRUPT : 1;
UINT32 PENDING : 1;
UINT32 ENABLE : 1;
UINT32 :21;
};
} Command;
/* The Command engine has to be Disabled when modifying the Argument
* of the Peripheral
*/
while ((MCI_STATUS << 11) == TRUE) /* While a Command is in Progress */
{
MCI_COMMAND = 0; /* Clear MCI Command Register */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
}
Command.Data = 0;
/* Copy Command-specific Index-Argument from MmcCmd LookUp Table to
* Command struct
*/
Command.CMDINDEX = MmcCmd[ComdInd].TxData;
if (pArg != NULL) /* Set Command Response depending on*/
{ /* asked Argument */
switch (MmcCmd[ComdInd].Resp)
{
case MmcR2:
Command.LONGRSP = 1;
case MmcR1:
case MmcR1b:
case MmcR3:
Command.RESPONSE = 1;
case MmcNoResp:;
}
}
Command.ENABLE = 1;
if (MmcCmd[ComdInd].Arg != MmcNoArg) /* If Argument exists */
{
MCI_ARGUMENT = *pArg; /* Copy Argument to MCI Argument Reg*/
}
else
{
MCI_ARGUMENT = 0;
}
MCI_COMMAND = Command.Data; /* Send Command to Card */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
while ((Status = MCI_STATUS & 0x000000C5) == 0);/* Wait command respond */
MCI_CLEAR = Status; /* Clear actual Status */
if (Status & (1UL << 2)) /* If Command TimeOut occourses */
{
MCI_COMMAND = 0; /* reset Command Register */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
return (MmcNoResponse); /* Return with Error Message */
}
if (Status & (1UL << 0)) /* Command CRC Error */
{
switch (MCI_COMMAND & 0x3F) /* Ignore CRC Error for following */
{ /* Commands */
case 1: /* CMD1 */
case 41: /* ACMD42 */
case 12: /* CMD12 */
MCI_COMMAND = 0;
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_ARGUMENT = 0xFFFFFFFF;
break;
default: /* No CRC Error Ignoring */
MCI_COMMAND = 0;
for(dlycnt = 10; dlycnt > 0;dlycnt--);
return (MmcCardError);
}
}
if (pArg != NULL)
{
switch (MmcCmd[ComdInd].Resp) /* Handle Command Response */
{
case MmcNoResp:
break;
case MmcR3:
*pArg = MCI_RESP0;
break;
case MmcR2:
*pArg++ = MCI_RESP0;
*pArg++ = MCI_RESP1;
*pArg++ = MCI_RESP2;
*pArg++ = MCI_RESP3;
break;
default:
if (MmcCmd[ComdInd].TxData != (MCI_RESP_CMD & 0x3F)) /* Bit 0-5*/
{
return (MmcCardError);
}
*pArg = MCI_RESP0;
}
}
MCI_COMMAND = 0;
for(dlycnt = 10; dlycnt > 0;dlycnt--);
return (MmcOk);
}
UINT32 Status;
MmcState_t MmcInitMedia(void)
{
UINT32 i;
UINT32 res;
UINT32 loopcnt;
volatile UINT32 Dly;
UINT8 MmcSdCid[16];
BOOLEAN CardDetected = FALSE;
Tnac = 1;
if (MmcPresent() == FALSE) /* If no Card inserted */
{
if (MCI_POWER & 0x3) /* Is Power up? */
{
MmcPowerDown(); /* Set to power down state */
}
return (MmcNoPresent); /* Return with Error Message */
}
MmcPowerDown(); /* Power Down */
MmcDly_1ms(100);
MCI_POWER &=~(1 << 0); /* power up (Bit 1) */
MCI_POWER |= (1 << 1);
for(dlycnt = 10; dlycnt > 0;dlycnt--);
while ((MCI_POWER & 0x3) != 0x2);
MCI_POWER |= (1 << 0); /* power reserved (Bit 0) */
MCI_POWER &=~(1 << 1);
MmcDly_1ms(100);
MCI_POWER &=~(1 << 6); /* Disable OpenDrain Mode */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
MCI_POWER = 0x02; /* Power up (Bit 1) */
for (loopcnt = 0; loopcnt < 50000; loopcnt++);
MCI_POWER |= 0x01; /* Power on the Flash Card */
for (loopcnt = 0; loopcnt < 50000; loopcnt++);
if (MmcSendCmd(CMD0, NULL) != MmcOk) /* Send Cmd0, Reset Card */
{
return (MmcNoResponse);
}
MCI_POWER |= 0x40; /* Set OpenDrain output control */
MmcDskCtrlBlk.DiskType = DiskMMC; /* Determinate Card type SD or MMC */
for (i=100; i; --i) /* Try detecting several Times */
{
MCI_POWER &=~(1 << 6); /* Disable OpenDrain Mode */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
res = 0;
if (((Status = MmcSendCmd(CMD55, &res)) == MmcOk) && (res & 0x100))
{ /* Send Notification for ACMD41 */
res = OcrReg;
if ((MmcSendCmd(ACMD41, &res) == MmcOk) && (res & 0x80000000))
/* Activates Init Process (only SD) */
{ /* Gets here when SD Card detected */
CardDetected = TRUE;
MmcDskCtrlBlk.DiskType = DiskSD;
break;
}
}
else /* If Cmd55 fails */
{
MCI_POWER |= (1 << 6); /* enable OpenDrain Mode */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
res = OcrReg;
if (MmcSendCmd(CMD1, &res) == MmcOk && (res & 0x80000000))
/* CMD1 for MMC Init sequence */
{ /* Gets here when MMC Card detected */
CardDetected = TRUE;
break;
}
}
MmcDly_1ms(50);
} /* end Card Detection */
if (CardDetected == FALSE) /* If no Card recognized */
{
return (MmcNoResponse); /* Return with Error Message */
}
if (MmcSendCmd(CMD2, (pUINT32)MmcSdCid) != MmcOk) /* Read CID from Card */
{
return (MmcNoResponse); /* Return with Error Message */
}
/* Set address */
CardRCA = (MmcDskCtrlBlk.DiskType == DiskMMC) ? 0x00010000 : 0x00000000;
if (MmcSendCmd(CMD3, &CardRCA) != MmcOk)
{
return (MmcNoResponse);
}
if (MmcDskCtrlBlk.DiskType == DiskSD)
{
CardRCA &= 0xFFFF0000;
}
else
{
CardRCA = 0x00010000;
}
MCI_POWER &=~(1 << 6); /* Disable OpenDrain Mode */
for(dlycnt = 10; dlycnt > 0;dlycnt--);
/* Read Card specific Data from Card */
MmcSdCsd[0] = 0;
MmcSdCsd[1] = 0;
MmcSdCsd[2] = CardRCA >> 16;
MmcSdCsd[3] = CardRCA >> 24;
if (MmcSendCmd(CMD9, (pUINT32)MmcSdCsd) != MmcOk)
{
return (MmcNoResponse);
}
MmcCsdImplemet(); /* Implement CSD data */
res = CardRCA;
if (MmcSendCmd(CMD7, &res) != MmcOk) /* Select Card */
{
return (MmcNoResponse);
}
res = CardRCA;
if (MmcOk != MmcSendCmd(CMD13, &res)) /* Send Card Status Register */
{
return (MmcNoResponse);
} else if (!(res & READY_FOR_DATA) || ((res & CURRENT_STATE)
!= CARD_TRAN))
{
return (MmcCardError);
}
if (MmcDskCtrlBlk.DiskType == DiskSD)
{
MCI_CLOCK |= (1 << 11); /* Use wide bus for SD */
for (loopcnt = 0; loopcnt < 100; loopcnt++);
res = CardRCA;
if (((Status = MmcSendCmd(CMD55, &res)) != MmcOk) || !(res & 0x100))
/* Send Notification for ACMD6 */
{
return (MmcCardError);
}
res = 2;
if (MmcSendCmd(ACMD6, &res) != MmcOk) /* Set bus width 4bits */
{
return (MmcCardError);
}
}
res = MmcDskCtrlBlk.BlockSize;
if (MmcSendCmd(CMD16, &res)) /* Set Block size */
{
return (MmcNoResponse);
}
return (MmcOk);
}
UINT32 Tets;
void MmcCsdImplemet(void)
{
UINT32 Freq;
UINT64 Tmp;
// Calculate SPI max clock
Freq = MmcTransfExp[CSD_GET_TRAN_SPEED_EXP()] * MmcCsdMant[CSD_GET_TRAN_SPEED_MANT()];
Freq = MmcSetClockFreq(Freq);
if (MmcDskCtrlBlk.DiskType == DiskMMC)
{
// Calculate Time outs for MMC cards
Tmp = MmmcAccessTime[CSD_GET_TAAC_EXP()] * MmcCsdMant[CSD_GET_TAAC_MANT()];
Tmp /= 10000; // us
// Freq [Hz], Tmp[1 us], *10
Tmp = (Freq*Tmp)/100000LL;
// NSAC*100*10
Tmp += 1000*CSD_GET_NSAC();
// Max time out
Tnac = Tmp;
Twr = Tmp * (1<<CSD_GET_R2W_FACTOR());
}
else
{
// Calculate Time outs for SD cards
// Freq [Hz], RD_TIME_OUT[ms]
Tmp = Freq/1000;
Tnac = Tmp * RD_TIME_OUT;
Twr = Tmp * WR_TIME_OUT;
}
// Calculate Block size and Block Number
MmcDskCtrlBlk.BlockSize = 1<<CSD_GET_READ_BL_LEN();
MmcDskCtrlBlk.BlockNumb = (CSD_GET_C_SIZE()+1)*(4<<CSD_GET_C_SIZE_MULT());
// Set Write Protect
bMmcPermWriteProtect = CSD_GET_PERM_WRITE_PROTECT() |\
CSD_GET_TMP_WRITE_PROTECT();
MmcDskCtrlBlk.WriteProtect = MmcWriteProtect() |\
bMmcPermWriteProtect;
}
inline MmcState_t MmcVerify(const UINT8 * pData, UINT32 Add, UINT32 Length)
{
__no_init static UINT8 TempBuffer[2048]__attribute__ ((section (".dmaram")));
/* maximum block length is 2048 */
MmcState_t Status = MmcOk;
UINT32 i = 0;
while (Length)
{
Status = MmcReadBlock(TempBuffer, Add);
if (Status != MmcOk)
{
break;
}
for (i = 0; i < MmcDskCtrlBlk.BlockSize; ++i)
{
if (TempBuffer[i] != *pData++)
{
return (MmcMiscompare);
}
}
Length -= MmcDskCtrlBlk.BlockSize;
Add += MmcDskCtrlBlk.BlockSize;
}
return (Status);
}
UINT32 MmcGetLastError(void)
{
return(MmcLastError);
}
void MmcStatusUpdate(void)
{
UINT32 Data = CardRCA;
// Update WP state
MmcDskCtrlBlk.WriteProtect = MmcWriteProtect() |\
bMmcPermWriteProtect;
if (!MmcPresent())
{
MmcDskCtrlBlk.DiskStatus = DiskNotPresent;
MmcPowerDown();
return;
}
if ((MmcDskCtrlBlk.DiskStatus != DiskCommandPass))
{
switch (MmcInitMedia())
{
case MmcOk:
MmcDskCtrlBlk.DiskStatus = DiskCommandPass;
MmcDskCtrlBlk.MediaChanged = TRUE;
break;
case MmcCardError:
MmcDskCtrlBlk.DiskStatus = DiskNotReady;
break;
default:
MmcDskCtrlBlk.DiskStatus = DiskNotPresent;
break;
}
}
else if (MmcSendCmd(CMD13, &Data) != MmcOk)
{
MmcDskCtrlBlk.DiskStatus = DiskNotReady;
}
else if (!(Data & READY_FOR_DATA))
{
MmcDskCtrlBlk.DiskStatus = DiskNotReady;
}
else if ((Data & CURRENT_STATE) == CARD_TRAN)
{
MmcDskCtrlBlk.DiskStatus = DiskCommandPass;
}
else
{
MmcDskCtrlBlk.DiskStatus = DiskNotReady;
}
}
void MmcDiskInit(void)
{
MmcDskCtrlBlk.BlockNumb =0;
MmcDskCtrlBlk.BlockSize =0;
MmcLastError = 0;
// Init SPI
MmcInit();
// Media Init
switch (MmcInitMedia())
{
case MmcOk:
MmcCsdImplemet();
MmcDskCtrlBlk.DiskStatus = DiskCommandPass;
MmcDskCtrlBlk.MediaChanged = TRUE;
break;
case MmcCardError:
MmcDskCtrlBlk.DiskStatus = DiskNotReady;
break;
default:
MmcDskCtrlBlk.DiskStatus = DiskNotPresent;
break;
}
}
#ifdef MMC_DISK_INFO
UINT32 MmcDiskInfo (pUINT8 pData, DiskInfoType_t DiskInfoType)
{
pMmc3FormatCapResponse_t pFormatCapacity;
switch (DiskInfoType)
{
case DiskInquiry:
memcpy(pData,MmcDskInquiry,SizeOfInquiryDescMmcDsk);
return(SizeOfInquiryDescMmcDsk);
case DiskFormatCapacity:
pFormatCapacity = (pMmc3FormatCapResponse_t)pData;
memset(pFormatCapacity,0,sizeof(Mmc3FormatCapResponse_t));
pFormatCapacity->CapacityListLength = sizeof(Mmc3FormatCapDescriptor_t);
if (MmcDskCtrlBlk.DiskStatus != DiskCommandPass)
{
pFormatCapacity->MaximumDescriptor.DescriptorType = FormattedMedia;
pFormatCapacity->MaximumDescriptor.BlockLength[0] = (MmcDskCtrlBlk.BlockSize >> 16) & 0xFF;
pFormatCapacity->MaximumDescriptor.BlockLength[1] = (MmcDskCtrlBlk.BlockSize >> 8) & 0xFF;
pFormatCapacity->MaximumDescriptor.BlockLength[2] = (MmcDskCtrlBlk.BlockSize ) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[0] = (MmcDskCtrlBlk.BlockNumb >> 24) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[1] = (MmcDskCtrlBlk.BlockNumb >> 16) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[2] = (MmcDskCtrlBlk.BlockNumb >> 8) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[3] = (MmcDskCtrlBlk.BlockNumb ) & 0xFF;
}
else
{
pFormatCapacity->MaximumDescriptor.DescriptorType = NoMediaPresent;
pFormatCapacity->MaximumDescriptor.BlockLength[0] = (2048 >> 16) & 0xFF;
pFormatCapacity->MaximumDescriptor.BlockLength[1] = (2048 >> 8) & 0xFF;
pFormatCapacity->MaximumDescriptor.BlockLength[2] = (2048 ) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[0] = (0xFFFFFFFF >> 24) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[1] = (0xFFFFFFFF >> 16) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[2] = (0xFFFFFFFF >> 8) & 0xFF;
pFormatCapacity->MaximumDescriptor.NumberofBlocks[3] = (0xFFFFFFFF ) & 0xFF;
}
return(sizeof(Mmc3FormatCapResponse_t));
}
return(0);
}
#endif
pDiskCtrlBlk_t MmcGetDiskCtrlBkl(void)
{
return (&MmcDskCtrlBlk);
}
UINT32 SYS_GetFSclk(void)
{
UINT32 Mul = 1, Div = 1, Osc, Fsclk;
if (PLLSTAT & (1 << 25))
{
// when PLL is connected
Mul = (PLLSTAT & 0x7FFF) +1;
Div = ((PLLSTAT >> 16) & 0xFF) +1;
}
// Find clk source
switch (CLKSRCSEL & 0x3)
{
case 0:
Osc = I_RC_OSC_FREQ;
break;
case 1:
Osc = MAIN_OSC_FREQ;
break;
case 2:
Osc = RTC_OSC_FREQ;
break;
default:
Osc = 0;
}
// Calculate system frequency
Fsclk = Osc*Mul*2;
Fsclk /= Div*(CCLKCFG+1);
return (Fsclk);
}
UINT32 SYS_GetFPclk(UINT32 Periphery)
{
UINT32 Fpclk;
pUINT32 pReg = (pUINT32)((Periphery < 32) ? &PCLKSEL0 : &PCLKSEL1);
Periphery &= 0x1F; // %32
Fpclk = SYS_GetFSclk();
// find peripheral appropriate periphery divider
switch ((*pReg >> Periphery) & 3)
{
case 0:
Fpclk /= 4;
break;
case 1:
break;
case 2:
Fpclk /= 2;
break;
default:
Fpclk /= 8;
}
return (Fpclk);
}
void Dly100us(void *arg)
{
volatile UINT32 Dly = (UINT32)arg, Dly100;
for (; Dly; Dly--)
for (Dly100 = 500; Dly100; Dly100--)
;
}