📄 sd_data.c
字号:
/***************************************************************************
* File: sd_data.c - Read / Write Functions
*
* The content of this file or document is CONFIDENTIAL and PROPRIETARY
* to Jade Technologies Co., Ltd. It is subject to the terms of a
* License Agreement between Licensee and Jade Technologies Co., Ltd.
* restricting among other things, the use, reproduction, distribution
* and transfer. Each of the embodiments, including this information
* and any derivative work shall retain this copyright notice.
*
* Copyright (c) 2005 Jade Technologies Co., Ltd.
* All rights reserved.
****************************************************************************/
#include "sd.h"
unsigned long TempBufAl[SECTORS_PER_BATCH*BYTES_PER_SECTOR/4];
extern unsigned long RCA;
//------------------------------------------------------------------------------
//
// Block read - read a number of sectors from the card
//
// Arguments:
// controller - instance created in SDI_InitInterface
// SectorNum - the number of first sector to be read
// SectorCnt - how many sectors to be read
// buffer - buffer to receive data
// errorcode - record error.
//
// Functions:
// Call function SDI_SafeRead to read data sector by sector.
//
//------------------------------------------------------------------------------
BOOL
SDI_BlockRead(
SD_controller* controller,
unsigned long SectorNum,
unsigned long SectorCnt,
unsigned char* buffer,
unsigned long* errorcode
)
{
unsigned long error = 0;
if (!controller)
error = 1;
if (!error)
{
unsigned long i;
unsigned long sectors_this = 0;
for (i=0; i<SectorCnt; i+=SECTORS_PER_BATCH)
{
sectors_this = MIN(SECTORS_PER_BATCH, (SectorCnt-i));
if (!SDI_SafeRead(controller, SectorNum+i, sectors_this, buffer+i*BYTES_PER_SECTOR, &error))
{
error = 2;
break;
}
}
}
if (error)
{
RETAILMSG(MSG_DATA, (_T("SD: SDI_BlockRead - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Block write - write a number of sectors to the card
//
// Arguments:
// controller - handle for the instance
// SectorNum - the number of first sector to be write
// SectorCnt - how many sectors to be write
// buffer - buffer to send data
// errorcode - record error
//
// Functions:
// Call function SDI_SafeWrite to write data sector by sector.
//
//------------------------------------------------------------------------------
BOOL
SDI_BlockWrite(
SD_controller* controller,
unsigned long SectorNum,
unsigned long SectorCnt,
unsigned char* buffer,
unsigned long* errorcode
)
{
unsigned long error = 0;
if (!controller)
error = 1;
if (!error)
{
unsigned long i;
unsigned long sectors_this = 0;
for (i=0; i<SectorCnt; i+=SECTORS_PER_BATCH)
{
sectors_this = MIN(SECTORS_PER_BATCH, (SectorCnt-i));
if (!SDI_SafeWrite(controller, SectorNum+i, sectors_this, buffer+i*BYTES_PER_SECTOR, &error))
{
error = 2;
break;
}
}
}
if (error)
{
RETAILMSG(MSG_DATA, (_T("SD: SD_BlockWrite - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
// for safe, retry RETRYNUM times if error.
#define RETRYNUM 3
//------------------------------------------------------------------------------
//
// Safe read - read a sector from the card
//
// Arguments:
// controller - instance created in SDI_InitInterface
// SectorNum - the number of first sector to be read
// buffer - buffer to receive data
// errorcode - record error.
//
// Functions:
// Call function SDI_SectorRead_FIFO or SDI_SectorRead_DMA
// to read data from a single sector. Reset if error occured,
// and retry last sector.
//
//------------------------------------------------------------------------------
BOOL
SDI_SafeRead(
SD_controller* controller,
unsigned long SectorNum,
unsigned long SectorCnt,
unsigned char* buffer,
unsigned long* errorcode
)
{
unsigned long error = 0;
unsigned long retry = RETRYNUM+1;
unsigned char * bufthis;
if ((int)buffer&0x3)
bufthis = (unsigned char*)TempBufAl;
else
bufthis = (unsigned char*)buffer;
if (!controller)
error = 1;
if (!error)
{
while (--retry)
{
if (controller->ifDMA)
{
SDI_BatchRead_DMA(controller, SectorNum, SectorCnt, bufthis, &error);
}
else
{
return FALSE;
}
if (!error)
break;
else
{
if (error > 2)
{
error = 0;
SDI_ResetInterface(controller, &error);
SDI_StartUpCard(controller, &error);
if (error)
{
error = 4;
break;
}
}
else
{
error = 3;
break;
}
}
}
if (retry != (RETRYNUM))
RETAILMSG(MSG_DATA, (_T("SD: SDI_SafeRead - retry:%d\r\n"), (RETRYNUM-retry)));
if (!retry)
error = 2;
}
if ((int)buffer&0x3)
memcpy(buffer, TempBufAl, BYTES_PER_SECTOR*SectorCnt);
if (error)
{
RETAILMSG(MSG_DATA, (_T("SD: SDI_SafeRead - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Safe write - write a sector to the card
//
// Arguments:
// controller - instance created in SDI_InitInterface
// SectorNum - the number of first sector to be write
// buffer - buffer to send data
// errorcode - record error.
//
// Functions:
// Call function SDI_SectorWrite_FIFO or SDI_SectorWrite_DMA
// to write data to a single sector. Reset if error occured,
// and retry last sector.
//
//------------------------------------------------------------------------------
BOOL
SDI_SafeWrite(
SD_controller* controller,
unsigned long SectorNum,
unsigned long SectorCnt,
unsigned char* buffer,
unsigned long* errorcode
)
{
unsigned long error = 0;
unsigned long retry = RETRYNUM+1;
unsigned char * bufthis;
if ((int)buffer&0x3)
{
bufthis = (unsigned char*)TempBufAl;
memcpy(TempBufAl, buffer, BYTES_PER_SECTOR*SectorCnt);
}
else
bufthis = (unsigned char*)buffer;
if (!controller)
error = 1;
if (!error)
{
while (--retry)
{
if (controller->ifDMA)
{
SDI_BatchWrite_DMA(controller, SectorNum, SectorCnt, bufthis, &error);
}
else
{
return FALSE;
}
if (!error)
break;
else
{
if (error > 2)
{
error = 0;
SDI_ResetInterface(controller, &error);
SDI_StartUpCard(controller, &error);
if (error)
{
error = 4;
break;
}
}
else
{
error = 3;
break;
}
}
}
if (retry != (RETRYNUM))
RETAILMSG(MSG_DATA, (_T("SD: SDI_SafeWrite - retry:%d\r\n"), (RETRYNUM-retry)));
if (!retry)
error = 2;
}
if (error)
{
RETAILMSG(MSG_DATA, (_T("SD: SDI_SafeWrite - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Read data from SD FIFO register by DMA
//
// Arguments:
// controller - instance created in SDI_InitInterface
// SectorNum - the number of first sector to be read
// SectorCnt - how many sectors to be write
// buffer - buffer to receive data
// errorcode - record error.
//
// Functions:
// Send command to card, then call functions SDI_InitDMA
// and SDI_StartDMA finished the transfer.
//
//------------------------------------------------------------------------------
BOOL
SDI_BatchRead_DMA(
SD_controller* controller,
unsigned long SectorNum,
unsigned long SectorCnt,
unsigned char* buffer,
unsigned long* errorcode
)
{
unsigned long error = 0;
unsigned long DataCtrl = 0;
SD_REG *regs;
if (!controller || !buffer)
error = 1;
if (!error)
{
if (SectorNum >= controller->CardCSD.CardSize / BYTES_PER_SECTOR)
error = 2;
}
if (!error)
{
if (!SDI_InitDMA(DISK_IOCTL_READ))
{
error = 5;
}
}
regs = controller->Registers;
if (!error)
{
if (!SDI_StartDMA(DISK_IOCTL_READ, ((unsigned long)PHYS_SD0_BASE+0x80), buffer, SectorCnt*BYTES_PER_SECTOR))
{
error = 6;
}
}
if (!error)
{
unsigned long temp = 0;
if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &temp))
{
if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &temp))
error = 3;
}
}
if (!error)
{
apBIT_SET(DataCtrl, MCI_DATA_ENABLE,1);
apBIT_SET(DataCtrl, MCI_DATA_DIRECTION, apMCI_DATA_RECEIVE);
apBIT_SET(DataCtrl, MCI_DATA_MODE, apMCI_DATA_BLOCKING);
apBIT_SET(DataCtrl, MCI_DATA_DMA_ENABLE, 1);
apBIT_SET(DataCtrl, MCI_DATA_BLOCKSIZE, BYTES_PER_SECTOR_SH);
regs->sd_MASK0 = 0;
regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;
regs->sd_DATATMR = 0xFFFFFFFF;
regs->sd_DATALEN = 0xFFFF;
regs->sd_DATACTRL = DataCtrl;
if (!SDI_SendCmd(controller, &CommandParameters[READ_MULTIPLE_BLOCK], SectorNum * BYTES_PER_SECTOR, 0, &error))
{
error = 4;
}
}
if (!error)
{
if (!SDI_WaitDMA(DISK_IOCTL_READ, ((unsigned long)PHYS_SD0_BASE+0x80), buffer, SectorCnt*BYTES_PER_SECTOR))
{
error = 8;
}
}
if (!error)
{
unsigned long FIFO_Dumper = 0;
while (regs->sd_STATUS & MCI_STATUS_RXDATAAVLBL)
FIFO_Dumper = regs->sd_FIFO;
}
if (!error)
{
if (!SDI_SendCmd(controller, &CommandParameters[STOP_TRANSMISSION], 0, 0, &error))
{
error = 7;
}
}
if (!error)
{
apMCI_sResponse response;
int i;
response.ShortResponse = 0;
for (i=0; i<100; i++)
{
SDI_SendCmd(controller, &CommandParameters[SEND_STATUS], RCA, &response, 0) ;
if (((response.ShortResponse >> 9) & 0x0F) == ST_TRAN)
break;
Sleep(1);
}
}
if (!error)
{
regs->sd_DATACTRL = 0;
regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;
}
if (error)
{
RETAILMSG(MSG_DATA, (_T("SD: SDI_BatchRead_DMA - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Write data to SD FIFO register by DMA
//
// Arguments:
// controller - instance created in SDI_InitInterface
// SectorNum - the number of first sector to be write
// SectorCnt - how many sectors to be write
// buffer - buffer to send data
// errorcode - record error.
//
// Functions:
// Send command to card, then call functions SDI_InitDMA
// and SDI_StartDMA finished the transfer.
//
//------------------------------------------------------------------------------
BOOL
SDI_BatchWrite_DMA(
SD_controller* controller,
unsigned long SectorNum,
unsigned long SectorCnt,
unsigned char* buffer,
unsigned long* errorcode
)
{
unsigned long error = 0;
unsigned long DataCtrl = 0;
SD_REG *regs;
if (!controller || !buffer)
error = 1;
if (!error)
{
if (SectorNum >= controller->CardCSD.CardSize / BYTES_PER_SECTOR)
error = 2;
}
if (!error)
{
if (!SDI_InitDMA(DISK_IOCTL_WRITE))
{
error = 5;
}
}
regs = controller->Registers;
if (!error)
{
unsigned long temp = 0;
if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &temp))
{
if (!SDI_SendCmd(controller, &CommandParameters[SET_BLOCKLEN], BYTES_PER_SECTOR, 0, &temp))
error = 3;
}
}
if (!error)
{
apBIT_SET(DataCtrl, MCI_DATA_ENABLE,1);
apBIT_SET(DataCtrl, MCI_DATA_DIRECTION, apMCI_DATA_TRANSMIT);
apBIT_SET(DataCtrl, MCI_DATA_MODE, apMCI_DATA_BLOCKING);
apBIT_SET(DataCtrl, MCI_DATA_DMA_ENABLE, 1);
apBIT_SET(DataCtrl, MCI_DATA_BLOCKSIZE, BYTES_PER_SECTOR_SH);
regs->sd_MASK0 = 0;
regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;
regs->sd_DATATMR = 0xFFFFFFFF;
regs->sd_DATALEN = 0xFFFF;
regs->sd_DATACTRL = DataCtrl;
if (!SDI_SendCmd(controller, &CommandParameters[WRITE_MULTIPLE_BLOCK], SectorNum * BYTES_PER_SECTOR, 0, &error))
{
error = 4;
}
}
if (!error)
{
if (!SDI_StartDMA(DISK_IOCTL_WRITE, ((unsigned long)PHYS_SD0_BASE+0x80), buffer, SectorCnt*BYTES_PER_SECTOR))
{
error = 6;
}
}
if (!error)
{
if (!SDI_WaitDMA(DISK_IOCTL_WRITE, ((unsigned long)PHYS_SD0_BASE+0x80), buffer, SectorCnt*BYTES_PER_SECTOR))
{
error = 8;
}
}
if (!error)
{
while (regs->sd_STATUS & MCI_STATUS_TXDATAAVLBL); // wait the Tx FIFO empty
}
if (!error)
{
if (!SDI_SendCmd(controller, &CommandParameters[STOP_TRANSMISSION], 0, 0, &error))
{
error = 7;
}
}
if (!error)
{
apMCI_sResponse response;
int i;
response.ShortResponse = 0;
for (i=0; i<100; i++)
{
SDI_SendCmd(controller, &CommandParameters[SEND_STATUS], RCA, &response, 0) ;
if (((response.ShortResponse >> 9) & 0x0F) == ST_TRAN)
break;
Sleep(1);
}
}
if (!error)
{
regs->sd_DATACTRL = 0;
regs->sd_CLEAR = MCI_STATUS_STATIC_MASK;
}
if (error)
{
RETAILMSG(MSG_DATA, (_T("SD: SDI_BatchWrite_DMA - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -