📄 cfc_data.c
字号:
}
if (error)
{
RETAILMSG(1, (_T("CFCARD: WriteSectorsFIFO - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Read sectors from FIFO by DMA
//
// Arguments:
// regs - Cf registers' base address
// buf - buffer to receive data
// sectornum - the number of first sector to be read
// sectorcnt - how many sectors to be read
// errorcode - record error
//
// Functions:
// Send command to card, then config DMA. Wait the end of transfer.
//
//------------------------------------------------------------------------------
BOOL
CFC_ReadSectors_DMA(
CFRegs *regs,
unsigned short *buf,
unsigned long sectornum,
unsigned long sectorcnt,
unsigned long *errorcode
)
{
unsigned long k = SleepCircle;
unsigned char atastatus, ataerror;
unsigned long Opcode = DISK_IOCTL_READ;
unsigned long error = 0;
if (regs == NULL || buf == NULL)
error = 1;
if (!error)
{
AtaSetSectorNum(regs, (unsigned char)sectornum);
AtaSetCylinderLow(regs, (unsigned char)(sectornum>>8));
AtaSetCylinderHigh(regs, (unsigned char)(sectornum>>16));
AtaSetHead(regs, 0xe0 | (unsigned char)(sectornum>>24));
AtaSetSectorCount(regs, (unsigned char)sectorcnt);
AtaSetCommand(regs, ATA_CMD_READ);
while (k--)
{
AtaReadStatus(regs, atastatus);
if (atastatus == 0x58)
break;
if (atastatus & (0x01))
{
AtaReadError(regs, ataerror);
error = 2;
break;
}
}
}
if (!error)
{
CFC_SetFifoAccessMode(regs);
regs->CF_ADDR_CFINTena = 0;
regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo)
| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
regs->CF_ADDR_SectorCfg = 0x7f00 + sectorcnt;
regs->CF_ADDR_FIFOreq = (1<<FIFOreq_DmaRxReq) | (1<<FIFOreq_StopFifo)
| (1<<FIFOreq_RXPush) | (1<<FIFOreq_RXPop) ;
if (!CFC_InitDMA(DISK_IOCTL_READ))
{
error = 3;
}
else
{
if (!CFC_StartDMA(
regs,
DISK_IOCTL_READ,
(unsigned long)(CF_HOST_BASE_ADDRESS+0x80),
buf,
sectorcnt))
{
error = 4;
}
}
}
if (!error)
{
regs->CF_ADDR_CFINTena = (1<<CfRawIntr_RxPopOver);
if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
{
RETAILMSG(1, (_T("CFCARD: ReadSectorsDMA - read rxpopover TIMEOUT\r\n")));
regs->CF_ADDR_CFINTena = 0; //(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
InterruptDone(SYSINTR_CF);
error = 5;
}
else
{
// RETAILMSG(MSG_DATA, (_T("CFCARD: ReadSectorsDMA - CF_ADDR_TXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_TXFIFOCnt));
// RETAILMSG(MSG_DATA, (_T("CFCARD: ReadSectorsDMA - CF_ADDR_RXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_RXFIFOCnt));
regs->CF_ADDR_CFINTena = 0; //(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo)
| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
regs->CF_ADDR_FIFOreq = 0x00;
// regs->CF_ADDR_CFINTR = (1<<CfRawIntr_RxPopOver);
regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
InterruptDone(SYSINTR_CF);
}
}
if (!error)
{
while (k--)
{
AtaReadStatus(regs, atastatus);
if (atastatus == 0x50)
break;
if (atastatus & 0x01)
{
AtaReadError(regs, ataerror);
RETAILMSG(1, (_T("CFCARD: ReadSectorsDMA - ataerror(0x%x)\r\n"), ataerror));
error = 6;
break;
}
}
}
if (error)
{
RETAILMSG(1, (_T("CFCARD: ReadSectorsDMA - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Write sectors to FIFO by DMA
//
// Arguments:
// regs - Cf registers' base address
// buf - buffer to send data
// sectornum - the number of first sector to be write
// sectorcnt - how many sectors to be write
// errorcode - record error
//
// Functions:
// Send command to card, then config DMA. Wait the end of transfer.
//
//------------------------------------------------------------------------------
BOOL
CFC_WriteSectors_DMA(
CFRegs *regs,
unsigned short *buf,
unsigned long sectornum,
unsigned long sectorcnt,
unsigned long *errorcode
)
{
unsigned long k = SleepCircle;
unsigned char atastatus, ataerror;
unsigned long Opcode = DISK_IOCTL_WRITE;
unsigned long error = 0;
if (regs == NULL || buf == NULL)
error = 1;
if (!error)
{
AtaSetSectorNum(regs, (unsigned char)sectornum);
AtaSetCylinderLow(regs, (unsigned char)(sectornum>>8));
AtaSetCylinderHigh(regs, (unsigned char)(sectornum>>16));
AtaSetHead(regs, 0xe0 | (unsigned char)(sectornum>>24));
AtaSetSectorCount(regs, (unsigned char)sectorcnt);
AtaSetCommand(regs, ATA_CMD_WRITE);
while (k--)
{
AtaReadStatus(regs, atastatus);
if (atastatus == 0x58) //addr7, atastatus
break;
if (atastatus & (0x01))
{
AtaReadError(regs, ataerror);
error = 2;
break;
}
}
}
if (!error)
{
CFC_SetFifoAccessMode(regs);
regs->CF_ADDR_CFINTena = 0;
regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo) |
(1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
regs->CF_ADDR_SectorCfg = 0x7f00 + sectorcnt;
regs->CF_ADDR_FIFOreq = (1<<FIFOreq_DmaTxReq) | (1<<FIFOreq_StopFifo)
| (1<<FIFOreq_TXPush) | (1<<FIFOreq_TXPop) ;
if (!CFC_InitDMA(DISK_IOCTL_WRITE))
{
error = 3;
}
else
{
if (!CFC_StartDMA(
regs,
DISK_IOCTL_WRITE,
(unsigned long)(CF_HOST_BASE_ADDRESS+0x80),
buf,
sectorcnt))
{
error = 4;
}
}
}
if (!error)
{
regs->CF_ADDR_CFINTena = (1<<CfRawIntr_TxPopOver);
if (WaitForSingleObject(cfDataEvent, 1000) == WAIT_TIMEOUT)
{
RETAILMSG(1, (_T("CFCARD: WriteSectorsDMA - write txpopover TIMEOUT\r\n")));
regs->CF_ADDR_CFINTena = 0; //(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
InterruptDone(SYSINTR_CF);
error = 5;
}
else
{
// RETAILMSG(MSG_DATA, (_T("CFCARD: WriteSectorsDMA - CF_ADDR_TXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_TXFIFOCnt));
// RETAILMSG(MSG_DATA, (_T("CFCARD: WriteSectorsDMA - CF_ADDR_RXFIFOCnt:0x%x\r\n"), regs->CF_ADDR_RXFIFOCnt));
regs->CF_ADDR_CFINTena = 0; //(1<<CfRawIntr_CfInsert) | (1<<CfRawIntr_CfRemove);
regs->CF_ADDR_FIFOreq = (1<<FIFOreq_ClearFifo)
| (1<<FIFOreq_IntrClr) | (1<<FIFOreq_FifoCntClr);
regs->CF_ADDR_FIFOreq = 0x00;
// regs->CF_ADDR_CFINTR = (1<<CfRawIntr_TxPopOver);
regs->CF_ADDR_CFINTR = CF_DATA_INTR_MASK;
InterruptDone(SYSINTR_CF);
}
}
if (!error)
{
while (k--)
{
AtaReadStatus(regs, atastatus);
if (atastatus == 0x50)
break;
if (atastatus & 0x01)
{
AtaReadError(regs, ataerror);
RETAILMSG(1, (_T("CFCARD: WriteSectorsDMA - ataerror(0x%x)\r\n"), ataerror));
error = 6;
break;
}
}
}
if (error)
{
RETAILMSG(1, (_T("CFCARD: WriteSectorsDMA - error:%d\r\n"), error));
if (errorcode)
*errorcode = error;
return FALSE;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Read a byte from card
//
// Arguments:
// regs - Cf registers' base address
// offset - the byte's offset
// result - data to be read
//
// Functions:
// Read a byte from card. Always used to read common registers.
//
//------------------------------------------------------------------------------
int
CFC_ReadByte(
CFRegs *regs,
unsigned long offset,
unsigned char* result
)
{
static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
unsigned long wordoffset = offset / 4;
if (regs == 0 || result ==0)
return 0;
offset = offset % 4;
regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) +
(CFMODE_MEMORY<<CfU_Signal_cs_b) +
(bytecode[offset]<<CfU_Signal_be_b);
*result = (unsigned char)(regs->CF_BaseADDR_CARD[wordoffset]>> (offset*8));
return 1;
}
//------------------------------------------------------------------------------
//
// Write a byte to card
//
// Arguments:
// regs - Cf registers' base address
// offset - the byte's offset
// data - data to be written
//
// Functions:
// Write a byte to card. Always used to write common registers.
//
//------------------------------------------------------------------------------
int
CFC_WriteByte(
CFRegs *regs,
unsigned long offset,
unsigned char data
)
{
static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
unsigned long wordoffset = offset / 4;
if (regs == 0)
return 0;
offset = offset % 4;
regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) +
(CFMODE_MEMORY<<CfU_Signal_cs_b) +
(bytecode[offset]<<CfU_Signal_be_b);
regs->CF_BaseADDR_CARD[wordoffset] = data << (offset*8);
return 1;
}
//------------------------------------------------------------------------------
//
// Read a half-word from card
//
// Arguments:
// regs - Cf registers' base address
// offset - the half-word's offset
// result - data to be read
//
// Functions:
// Read a half-word from card. Always used to read data registers.
//
//------------------------------------------------------------------------------
int
CFC_ReadHWd(
CFRegs *regs,
unsigned long offset,
unsigned short* result
)
{
static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
unsigned long wordoffset = offset / 4;
if (regs == 0 || result ==0)
return 0;
offset = offset % 4;
regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) +
(CFMODE_MEMORY<<CfU_Signal_cs_b) +
((bytecode[offset]&bytecode[offset+1])<<CfU_Signal_be_b);
*result = (unsigned short)(regs->CF_BaseADDR_CARD[wordoffset] >> (offset*8));
return 1;
}
//------------------------------------------------------------------------------
//
// Write a half-word to card
//
// Arguments:
// regs - Cf registers' base address
// offset - the half-word's offset
// result - data to be write
//
// Functions:
// Write a half-word to card. Always used to write data registers.
//
//------------------------------------------------------------------------------
int
CFC_WriteHWd(
CFRegs *regs,
unsigned long offset,
unsigned short data
)
{
static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
unsigned long wordoffset = offset / 4;
if (regs == 0)
return 0;
offset = offset % 4;
regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) +
(CFMODE_MEMORY<<CfU_Signal_cs_b) +
((bytecode[offset]&bytecode[offset+1])<<CfU_Signal_be_b);
regs->CF_BaseADDR_CARD[wordoffset] = data << (offset*8);
return 1;
}
//------------------------------------------------------------------------------
//
// Set FIFO access mode
//
// Arguments:
// regs - Cf registers' base address
//
// Functions:
// Used to set FIFO to memory mode.
//
//------------------------------------------------------------------------------
int
CFC_SetFifoAccessMode(
CFRegs *regs
)
{
static unsigned char bytecode[] = { CfValidByte0, CfValidByte1, CfValidByte2, CfValidByte3 };
regs->CF_ADDR_u_signal = (1<<CfU_Signal_cf) +
(CFMODE_MEMORY<<CfU_Signal_cs_b) +
((bytecode[0]&bytecode[1])<<CfU_Signal_be_b);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -