?? cf.c
字號:
/*
* DSPdap-bootloader - DSP based Digital Audio Player, Bootloader
* Copyright (C) 2004-2007 Roger Quadros <rogerquads @ yahoo . com>
* http://dspdap.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: CF.c,v 1.2 2007/06/03 08:54:03 Roger Exp $
*/
#include "CF.h"
#include "types.h"
#include "IO.h" //for read_mem() and write_mem()
#define CF_DET 6 //CF detect on A6 pin
#define CF_BUSY_TIMEOUT 100 //Count time to wait for CF to be not busy
#define CF_READY_TIMEOUT 100 //Count time to wait for CF to be ready
#define CF_DRQ_TIMEOUT 100 //Count time to wait for CF to request data
static void delay()
{
int i;
for(i=0; i<0x7fff; i++)
{
asm(" nop");
}
}
int CF_IsPresent()
{
int word;
word = get_AGPIO();
if(word & (1<<CF_DET))
return 0; //CF not present as CF_DET line is high
else
return 1;
}
//provides a hardware reset to the CF card
void CF_HardReset()
{
asm(" BCLR XF"); //make XF low
delay(); //wait for at least 25us
asm(" BSET XF"); //make XF high
delay(); //wait for at least 25us
delay(); //wait for at least 25us
}
enum BUSY_STATUS CF_CheckBusyStatus()
{
int timeout;
for(timeout = 0; timeout < CF_BUSY_TIMEOUT; timeout++)
{
if(read_mem(STATUS_REG) & 0x80)
{
//CF still busy
delay(); //wait in loop till timeout
}
else
{
return CF_NOT_BUSY; //CF is not busy.. return immediately
}
}
return CF_BUSY;
}
enum READY_STATUS CF_CheckReadyStatus()
{
int timeout;
for(timeout = 0; timeout < CF_READY_TIMEOUT; timeout++)
{
if(read_mem(STATUS_REG) & 0x40)
{
return CF_READY; //CF is ready... return immediately
}
else
{
//CF not yet ready
delay(); //wait in loop till timeout
}
}
return CF_NOT_READY;
}
enum DRQ_STATUS CF_CheckDrqStatus()
{
int timeout;
for(timeout = 0; timeout < CF_DRQ_TIMEOUT; timeout++)
{
if(read_mem(STATUS_REG) & 0x08)
{
return CF_DRQ_SET; //DRQ is set... return immediately
}
else
{
//DRQ not yet set
delay(); //wait in loop till timeout
}
}
return CF_DRQ_RESET;
}
//Following variables are used to issue ATA commands
//unsigned short Command_Value;
unsigned short Drive_Head_Val; //LBA(27-24)
unsigned short Cyl_High_Val; //LBA(23-16)
unsigned short Cyl_Low_Val; //LBA(15-8)
unsigned short Sector_Num_Val; //LBA(7-0)
//unsigned short Sector_Count_Val;
unsigned short Feature_Val;
//Fills the ATA registers appropriately with the given physical sector addres
//and sector count and issues the command.
void CF_IssueCommand(unsigned long physicalSector, unsigned short sectorCount, unsigned short command)
{
//Set ATA registers based on given Physical/LBA address
Sector_Num_Val = physicalSector & 0xFF; //get bits 7-0
physicalSector >>= 8;
Cyl_Low_Val = physicalSector & 0xFF; //get bits 15-8
physicalSector >>= 8;
Cyl_High_Val = physicalSector & 0xFF; //get bits 23-16
physicalSector >>= 8;
Drive_Head_Val = 0xE0; //set LBA = 1, DRV = 0
Drive_Head_Val |= physicalSector & 0xF; //get bits 27-24
//write into the ATA registers
write_mem(SECTOR_NO_REG, Sector_Num_Val);
write_mem(CYL_LOW_REG, Cyl_Low_Val);
write_mem(CYL_HIGH_REG, Cyl_High_Val);
write_mem(DRIVE_HEAD_REG, Drive_Head_Val);
//sector count
write_mem(SECTOR_CNT_REG, sectorCount);
//command
write_mem(COMMAND_REG, command);
}
//executes the identify drive command. the data returned by compact flash
//is stored in buffer.
int CF_IdentifyDrive(UI buffer[256])
{
int i;
//check is CF is Not Busy
if(CF_CheckBusyStatus() == CF_BUSY)
return -1; //error
//check if CF is Ready
if(CF_CheckReadyStatus() == CF_NOT_READY)
return -1; //error
//CF is not Busy and is Ready so issue command
CF_IssueCommand(0, 0, IDENTIFY_DRIVE_CMD);
//check to see if CF DRQ is set
if(CF_CheckDrqStatus() == CF_DRQ_SET)
{
//yes. so read data (256 words) into buffer
for(i=0; i<256; i++)
buffer[i] = read_mem(DATA_REG);
return 0; //success
}
else
return -1; //error
}
//reads the contents (256 words) of the given sector into buffer
int CF_ReadSector(unsigned long LBA_address, void* buffer)
{
//check is CF is Not Busy
if(CF_CheckBusyStatus() == CF_BUSY)
return -1; //error
//check if CF is Ready
if(CF_CheckReadyStatus() == CF_NOT_READY)
return -2; //error
//CF is not Busy and is Ready so issue command
CF_IssueCommand(LBA_address, 1, READ_SECTORS_CMD);
//check to see if CF DRQ is set
if(CF_CheckDrqStatus() == CF_DRQ_SET)
{
//yes. so read data (256 words) into buffer
read_sector(DATA_REG, buffer);
return 0; //success
}
else
return -3; //error
}
//prepares for reading given number of sectors
int CF_ReadSectors(unsigned long LBA_address, unsigned short num_sectors)
{
//check is CF is Not Busy
if(CF_CheckBusyStatus() == CF_BUSY)
return -1; //error
//check if CF is Ready
if(CF_CheckReadyStatus() == CF_NOT_READY)
return -2; //error
//CF is not Busy and is Ready so issue command
CF_IssueCommand(LBA_address, num_sectors, READ_SECTORS_CMD);
//actual reading of data will be performed by application if success
//is returned by this function
//waiting for DRQ will be done in read_sector()
return 0; //success
}
//prepares for writing the given number of sectors
int CF_WriteSectors(unsigned long LBA_address, unsigned short num_sectors)
{
//check is CF is Not Busy
if(CF_CheckBusyStatus() == CF_BUSY)
return -1; //error
//check if CF is Ready
if(CF_CheckReadyStatus() == CF_NOT_READY)
return -2; //error
//CF is not Busy and is Ready so issue command
CF_IssueCommand(LBA_address, num_sectors, WRITE_SECTORS_CMD);
//actual writing of data will be performed by application if success
//is returned by this function
//waiting for DRQ will be done in write_sector()
return 0; //success
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -