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:
@@ -0,0 +1,307 @@
|
||||
/* ---------------------------------------------------------------------------
|
||||
* mmc_transfer.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, May 08, 2008, MMi
|
||||
* Creation.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* System include files
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "LPC23xx.h"
|
||||
#include "types.h"
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Application include files
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#include "mmc_transfer.h"
|
||||
#include "mmc.h"
|
||||
#include "dio.h"
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local constant and macro definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#define Card_Page_Size 512
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Global variable definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
extern UINT32 Tnac;
|
||||
extern UINT32 Twr;
|
||||
extern DiskCtrlBlk_t MmcDskCtrlBlk;
|
||||
|
||||
UINT32 dlycnt;
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local variable definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
UINT8 ReadFromCard[512] __attribute__ ((section (".dmaram")));
|
||||
UINT8 WriteToCard[512] __attribute__ ((section (".dmaram")));
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Local function definitions
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MmcState_t CardRead (pUINT8 pData, UINT32 Address, UINT32 Length)
|
||||
{
|
||||
UINT32 ArrayIndex = 0;
|
||||
UINT32 loopcnt;
|
||||
MmcState_t Status = MmcOk;
|
||||
|
||||
for (loopcnt = 0; loopcnt < Card_Page_Size; loopcnt++)/* Prepare Buffer */
|
||||
{
|
||||
ReadFromCard[loopcnt] = 0; /* Set all Positions to Zero */
|
||||
}
|
||||
|
||||
/* Error or Wrong Argument Handle Block */
|
||||
if (MmcPresent() == FALSE) /* Check if Card is present */
|
||||
{
|
||||
return (MmcNoPresent); /* Return NoCardPresent State */
|
||||
}
|
||||
if (checkLength(Length) == FALSE) /* Check Read Length for validity */
|
||||
{
|
||||
return (MmcMiscompare); /* Return WrongLength State */
|
||||
}
|
||||
|
||||
Address = ((Address / Card_Page_Size) * Card_Page_Size);
|
||||
/* Calculate first Address of Page */
|
||||
|
||||
do /* Loop to handle multible Reads */
|
||||
{
|
||||
Status = MmcReadBlock((pUINT8)ReadFromCard, Address);
|
||||
/* Read 512 from Card */
|
||||
memcpy (&(pData[ArrayIndex]), ReadFromCard, Card_Page_Size);
|
||||
/* Copy read Content to User Buffer */
|
||||
|
||||
/* Recalculate Loop Values */
|
||||
Length -= Card_Page_Size;
|
||||
Address += Card_Page_Size;
|
||||
ArrayIndex += Card_Page_Size;
|
||||
} while (Length > 0);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
MmcState_t CardWrite (pUINT8 pData, UINT32 Address, UINT32 Length)
|
||||
{
|
||||
UINT32 ArrayIndex = 0;
|
||||
UINT32 loopcnt;
|
||||
MmcState_t Status = MmcOk;
|
||||
|
||||
for (loopcnt = 0; loopcnt < Card_Page_Size; loopcnt++)/* Prepare Buffer */
|
||||
{
|
||||
WriteToCard[loopcnt] = 0; /* Set all Positions to Zero */
|
||||
}
|
||||
|
||||
/* Error or Wrong Argument Handle Block */
|
||||
if (MmcPresent() == FALSE) /* Check if Card is Present */
|
||||
{
|
||||
return (MmcNoPresent); /* Return NoCardPresent State */
|
||||
}
|
||||
if (MmcWriteProtect() == TRUE) /* Check if Card is Writeprotected */
|
||||
{
|
||||
return (MmcProtect); /* Return WriteProtect State */
|
||||
}
|
||||
if (checkLength(Length) == FALSE) /* Check Read Length for validity */
|
||||
{
|
||||
return (MmcMiscompare); /* Return WrongLength State */
|
||||
}
|
||||
if (Address < 0x200) /* Defend Master Boot Sector */
|
||||
{
|
||||
return (MmcCardError); /* Return Error State */
|
||||
}
|
||||
|
||||
|
||||
Address = ((Address / Card_Page_Size) * Card_Page_Size);
|
||||
/* Calculate first Address of Page */
|
||||
|
||||
do
|
||||
{
|
||||
memcpy (WriteToCard, &(pData[ArrayIndex]), Card_Page_Size);
|
||||
/* Copy 512Bytes in send-Buffer */
|
||||
Status = MmcWriteBlock((pUINT8)WriteToCard, Address);
|
||||
/* Write 512 Bytes to Card */
|
||||
|
||||
/* Recalculate Loop Values */
|
||||
Length -= Card_Page_Size;
|
||||
Address += Card_Page_Size;
|
||||
ArrayIndex += Card_Page_Size;
|
||||
} while (Length > 0);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
inline BOOLEAN checkLength (UINT32 Length)
|
||||
{
|
||||
if (Length == 0)
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
/* Check data length - Must be divisible of Card Block Size */
|
||||
if ((Length % MmcDskCtrlBlk.BlockSize) != 0)
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
inline MmcState_t MmcReadBlock(pUINT8 pData, UINT32 Add)
|
||||
{
|
||||
UINT32 Data;
|
||||
MmcState_t Status = MmcOk;
|
||||
|
||||
PCONP |= (1 << 29); /* Turn on MCI Power */
|
||||
MCI_DATA_TMR = Tnac; /* Set Read Timeout */
|
||||
MCI_CLEAR = 0x000007FF; /* Clear all Interrupt Flags */
|
||||
|
||||
/* General Purpose DMA (GPDMA) Control Settings for Reading */
|
||||
GPDMA_CONFIG = 0x00; /* Disable DMA */
|
||||
GPDMA_CH0_LLI = 0; /* No link List available */
|
||||
GPDMA_CH0_CTRL = 0x00; /* Reset DMA Control Block */
|
||||
GPDMA_CH0_SRC = (UINT32)&MCI_FIFO; /* Set MCI FIFO as Source Adress */
|
||||
|
||||
GPDMA_CH0_CTRL = (Card_Page_Size & 0x0FFF) /* 512 Byte Transfer Size */
|
||||
| (0x04 << 12) /* 32 Bit Source Burst Size */
|
||||
| (0x04 << 15) /* 32 Bit Destination Burst Size */
|
||||
| (0x02 << 18) /* 32 Bit Source width size */
|
||||
| (0x00 << 21) /* 8 Bit Destination width size */
|
||||
| (1 << 27) /* Destination index increment */
|
||||
| (1U << 31); /* Terminal count interrupt */
|
||||
|
||||
MCI_DATA_LEN = MmcDskCtrlBlk.BlockSize; /* Set Transfer Blocksize */
|
||||
Data = Add; /* Hand over Adress */
|
||||
Status = MmcSendCmd(CMD17, &Data); /* Send Write Command to Card */
|
||||
|
||||
|
||||
if (MmcOk != Status) /* If Command Response is not OK: */
|
||||
{
|
||||
return (Status); /* return Status and exit Function */
|
||||
}
|
||||
|
||||
if (!(Data & READY_FOR_DATA)
|
||||
||((Data & CURRENT_STATE) != CARD_TRAN))
|
||||
{ /* Check Command Response */
|
||||
MmcSendCmd(CMD12, NULL);
|
||||
return (MmcCardError);
|
||||
}
|
||||
|
||||
GPDMA_CH0_DEST = (UINT32)pData; /* Set DMA Destination Adress */
|
||||
|
||||
/* DMA Channel Configuration Block */
|
||||
GPDMA_CH0_CFG = 0x00; /* Reset DMA Channel Configuration */
|
||||
GPDMA_CH0_CFG = (0x10000)
|
||||
| (0x04 << 1) /* Source Device is Peripheral */
|
||||
| (0x00 << 6) /* Destination Device is Memory */
|
||||
| (0x06 << 11); /* Peripheral to Memory Mode */
|
||||
|
||||
GPDMA_INT_TCCLR = 0x01; /* Clear all Terminal Interrupts */
|
||||
GPDMA_CONFIG = 0x01; /* enable GPDMA after setup Channel */
|
||||
while ((GPDMA_CONFIG & 0x01)!= 0x01); /* Poll Enable bit until set */
|
||||
GPDMA_CH0_CFG |= (1 << 0); /* enable DMA Channel */
|
||||
|
||||
MCI_DATA_CTRL = (0x0001) /* Data Transfer enable */
|
||||
| (0x01 << 1) /* From Card to Controller */
|
||||
| (0x00 << 2) /* Block Data Transfer */
|
||||
| (0x01 << 3) /* DMA enabled */
|
||||
| (0x09 << 4); /* BlockSize 2^9 = 512 Byte */
|
||||
for(dlycnt = 10; dlycnt > 0; dlycnt--);
|
||||
|
||||
while (MCI_STATUS & (1 << 13)); /* Poll RxActive until read finish */
|
||||
GPDMA_CH0_CFG &=~(1 << 0); /* Disable DMA channel */
|
||||
MCI_DATA_CTRL = 0; /* Reset Data Control Register */
|
||||
for(dlycnt = 10; dlycnt > 0; dlycnt--);
|
||||
|
||||
/* Interrupt Handling Block */
|
||||
if (GPDMA_RAW_INT_ERR_STAT & (1 << 0)) /* Channel requests Interrupt */
|
||||
{
|
||||
GPDMA_INT_ERR_CLR |= (1 << 0); /* clear Flag, terminate transfer */
|
||||
return (MmcDmaError);
|
||||
}
|
||||
|
||||
/* Error Handling Block */
|
||||
if (MCI_STATUS & (1 << 3)) /* Timeout Error */
|
||||
{
|
||||
MCI_CLEAR = 1UL << 3; /* Clear Timeout Bit */
|
||||
return (MmcNoResponse); /* Return with Error Message */
|
||||
}
|
||||
if (MCI_STATUS & (1 << 9)) /* StartBit not detected in Wide */
|
||||
{ /* Bus Mode on every four Lines */
|
||||
MCI_CLEAR = 1UL << 9; /* Clear StartBitError bit */
|
||||
return (MmcCardError); /* Return with Error Message */
|
||||
}
|
||||
if (MCI_STATUS & (1 << 1)) /* DATA CRC Error */
|
||||
{
|
||||
MCI_CLEAR = 1UL << 1; /* Clear Data CRC Error Bit */
|
||||
return (MmcCardError); /* Return with Error Message */
|
||||
}
|
||||
if (MCI_STATUS & (1 << 5)) /* Read FIFO Overrun Error */
|
||||
{
|
||||
MCI_CLEAR = 1UL << 5; /* Clean FIFO Overrun Error Bit */
|
||||
return (MmcCardError); /* Return with Error Message */
|
||||
}
|
||||
|
||||
MCI_CLEAR = (1UL << 8) /* Clear DATA END and DATA BLOCK END*/
|
||||
| (1UL << 10);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
inline MmcState_t MmcWriteBlock(const UINT8 * pData, UINT32 Add)
|
||||
{
|
||||
UINT32 Data;
|
||||
|
||||
|
||||
MmcState_t Status = MmcOk;
|
||||
|
||||
PCONP |= (1 << 29); /* Turn on MCI Power */
|
||||
MCI_DATA_TMR = Twr; /* Set write Timeout */
|
||||
MCI_CLEAR = 0x000007FF; /* Clear all related flags */
|
||||
|
||||
/* General Purpose DMA (GPDMA) Control Settings for Writing */
|
||||
GPDMA_CONFIG = 0x00; /* Disable DMA */
|
||||
GPDMA_CH0_LLI = 0; /* No link List */
|
||||
GPDMA_CH0_CTRL = 0x00; /* Reset DMA Control Block */
|
||||
GPDMA_CH0_DEST = (UINT32)&MCI_FIFO; /* Set MCI FIFO as Destination */
|
||||
|
||||
GPDMA_CH0_CTRL = (Card_Page_Size & 0x0FFF) /* 512 Byte Transfer Size */
|
||||
| (0x04 << 12) /* 32 Bit Source Burst Size */
|
||||
| (0x04 << 15) /* 32 Bit Destination Burst Size */
|
||||
| (0x00 << 18) /* 8 bit Source width Size */
|
||||
| (0x02 << 21) /* 32 Bit Destination width Size */
|
||||
| (1 << 26) /* Source index increment */
|
||||
| (1U << 31); /* Terminal count interrupt enable */
|
||||
|
||||
|
||||
MCI_DATA_LEN = MmcDskCtrlBlk.BlockSize; /* Set Transfer Blocksize */
|
||||
Data = Add; /* Hand over Adress */
|
||||
Status = MmcSendCmd(CMD24, &Data); /* Send Write Command */
|
||||
|
||||
if (MmcOk != Status) /* If Command Response is NOT OK */
|
||||
{
|
||||
return (Status); /* Return with Error Message */
|
||||
}
|
||||
|
||||
if (!(Data & READY_FOR_DATA)
|
||||
|| ((Data & CURRENT_STATE) != CARD_TRAN))
|
||||
{ /* Check Command Response */
|
||||
MmcSendCmd(CMD12, NULL);
|
||||
return (MmcCardError);
|
||||
Reference in New Issue
Block a user