📄 cf.c
字号:
#include "def.h"
#include "2440addr.h"
#include "2440lib.h"
//#include "config.h"
//#include "board.h"
#define IDE_A0 (1<<1) //
#define IDE_A1 (1<<2) //
#define IDE_A2 (1<<3) //
//#define IDE_CS0 ( 0x28000020 ) //
//#define IDE_CS1 ( 0x28000030 ) //
#define IDE_CS0 ( 0x28000000 )
#define IDE_CS1 ( 0x28800000 )
//#define printf Uart_Printf
#define CFCard_Dected ( rGPGDAT&(1<<7) )
/*GPIO引脚影射寄存器地址*/
#define CF_REG_DATA IDE_CS0 /*数据寄存器*/
#define CF_REG_ERR (IDE_CS0 + IDE_A0) /*读错误寄存器*/
#define CF_REG_FEATURE (IDE_CS0 + IDE_A0) /*写功能寄存器*/
#define CF_REG_SECCNT (IDE_CS0 + IDE_A1) /*扇区计数器*/
#define CF_REG_SECTOR (IDE_CS0 + IDE_A1 + IDE_A0) /*扇区号*/
#define CF_REG_CYLINDER_LOW (IDE_CS0 + IDE_A2) /*柱面低8位*/
#define CF_REG_CYLINDER_HIGH (IDE_CS0 + IDE_A2 + IDE_A0) /*柱面高8位*/
#define CF_REG_DEVICE_HEAD (IDE_CS0 + IDE_A2 + IDE_A1) /*选择主从,模式,磁头*/
#define CF_REG_COMMAND (IDE_CS0 + IDE_A2 + IDE_A1 + IDE_A0)/*写命令寄存器*/
#define CF_REG_STATUS (IDE_CS0 + IDE_A2 + IDE_A1 + IDE_A0)/*读状态寄存器*/
#define CF_REG_CONTROL (IDE_CS1 + IDE_A2 + IDE_A1) /*写控制寄存器*/
#define CF_REG_ASTATUS (IDE_CS1 + IDE_A2 + IDE_A1) /*读辅助状态寄存器*/
/*设备磁头寄存器*/
#define CF_DevReg_DEV0 0x00 /*设备为主盘*/
#define CF_DevReg_DEV1 0x10 /*设备为从盘*/
#define CF_DevReg_b5 0x20 /*保留位,为1*/
#define CF_DevReg_LBA 0x40 /*模式选择位*/
#define CF_DevReg_b7 0x80 /*保留位,为1*/
volatile int CFCard_Flag;
U8 CF_Dev_Config ;
/***************************************************************************
Function name: CF_WriteSetting
Parameter : Sectors:写入的起始扇区号 Count:扇区数
Description : CF读设置命令序列
Return : void
Argument : 确定选择的是主设备或是从设备和地址模式(使用LBA模式)
Autor & date :
****************************************************************************/
void CF_WriteSetting(U32 Sectors , U8 Count)
{
outportw(0,CF_REG_FEATURE); /*写特征寄存器,与驱动接口*/
outportw(Count,CF_REG_SECCNT); /*写扇区计数寄存器,与驱动接口*/
outportw(Sectors,CF_REG_SECTOR); /*写扇区寄存器,与驱动接口*/
outportw(Sectors/0x100,CF_REG_CYLINDER_LOW); /*写柱面低8位寄存器,与驱动接口*/
outportw(Sectors/0x10000,CF_REG_DEVICE_HEAD); /*写设备磁头寄存器,与驱动接口*/
outportw(((Sectors/0x1000000)&0x0f)|CF_Dev_Config,CF_REG_DEVICE_HEAD); /*写设备磁头寄存器,与驱动接口*/
outportw(0x30,CF_REG_COMMAND); /*写命令寄存器,与驱动接口,0x30 写扇区命令*/
}
/***************************************************************************
Function name: CF_ReadSetting
Parameter : Sectors:写入的起始扇区号 Count:扇区数
Description : CF读设置命令序列
Return : void
Argument : 确定选择的是主设备或是从设备和地址模式(使用LBA模式)
Autor & date :
****************************************************************************/
void CF_ReadSetting(U32 Sectors , U8 Count)
{
outportw(0,CF_REG_FEATURE); /*写特征寄存器,与驱动接口*/
outportw(Count,CF_REG_SECCNT); /*写扇区计数寄存器,与驱动接口*/
outportw(Sectors,CF_REG_SECTOR); /*写扇区寄存器,与驱动接口*/
outportw(Sectors/0x100,CF_REG_CYLINDER_LOW); /*写柱面低8位寄存器,与驱动接口*/
outportw(Sectors/0x10000,CF_REG_DEVICE_HEAD); /*写设备磁头寄存器,与驱动接口*/
outportw(((Sectors/0x1000000)&0x0f)|CF_Dev_Config,CF_REG_DEVICE_HEAD); /*写设备磁头寄存器,与驱动接口*/
outportw(0x20,CF_REG_COMMAND); /*写命令寄存器,与驱动接口,0x20 读扇区命令*/
}
/***************************************************************************
Function name: CF_IsBusy
Parameter : void
Description : 忙检测
Return : void
Argument :
Autor & date :
****************************************************************************/
U8 CF_IsBusy(void)
{
int time=0xffff; //没有精确的值
U8 status=FALSE;
while(time--)
{
inportw(CF_REG_ASTATUS);
if(!(inportw(CF_REG_STATUS)&0x80)) //判断CF卡是否忙
status=TRUE;
else
status=FALSE;
}
return status;
}
/***************************************************************************
Function name: CF_Init
Parameter : void
Description : CF卡初始化
Return : void
Argument :
Autor & date :
****************************************************************************/
void CF_Init(void)
{
rGPGCON = rGPGCON & (~(0x0f<<14)) ; //GPG7,GPG8 is input
//rGPECON = rGPECON & (~(0x03<<24)) ; //GPE12 is input
rGPBCON = rGPBCON & (~(0x03<<18)); //GPB9 input
rGPBCON = rGPBCON & (~(0x03<<20)) | (1<<20); //GPB10 output
//rGPFCON = rGPFCON & (~(0x03<<6)) ; //GPF3 is input
//rGPHCON = rGPHCON & (~(0x03<<20)) | (1<<20) ; //GPH10 is output
}
/***************************************************************************
Function name: CF_Probe
Parameter : void
Description : CF卡探测
Return : void
Argument :
Autor & date :
****************************************************************************/
void CF_Probe(void)
{
//rPDATB = ( rPDATB&(~(1<<5)) ) | ((0&1)<<5); //CF Power off
//rGPHDAT = ( rGPHDAT&(~(1<<10)) ) | ((0&1)<<10);
//rGPBDAT = ( (rGPBDAT&(~(1<<10)))|(1<<10));
//rGPBDAT = rGPBDAT|(1<<10);
rGPBDAT = ( rGPBDAT&(~(1<<10)) ) | ((0&1)<<10);
if(CFCard_Dected) //Probe CF CARD
CFCard_Flag=FALSE;
else
CFCard_Flag=TRUE;
if(CFCard_Flag)
{
//rPDATB = ( rPDATB&(~(1<<5)) ) | ((1&1)<<5);//Pwoer ON
//rGPHDAT = ( rGPHDAT&(~(1<<10)) ) | ((1&1)<<10);
rGPBDAT = ( rGPBDAT&(~(1<<10)) ) | ((1&1)<<10);
Uart_Printf("CF Card Detect OK\n");
}
else
Uart_Printf( "CF Card is NOT Pluged!!!\n" ) ;
}
/***************************************************************************
Function name: CF_Write_Sector
Parameter : void
Description : CF写扇区函数
Return : void
Argument :
Autor & date :
****************************************************************************/
int CF_Write_Sector(U16 * Buffer, U32 Sector ,U8 count)
{
U8 Status=FALSE;
U16 i;
if(!CFCard_Flag) /*CF卡不可用,立即返回*/
return FALSE;
CF_WriteSetting( Sector, count); /*写扇区设置*/
do
{ count--;
if(CF_IsBusy()) /*等待设备请求数据传输*/
{
for(i = 0; i < 256; i ++) /*连续写256个字(512字节)数据,即写入一个扇区*/
{
outportw(*(Buffer++),CF_REG_DATA); /*向数据寄存器写一个字数据*/
}
Buffer +=256; /*调要写入数据缓冲区的指针*/
}
else
break; /*出错退出*/
}while(count>0);
if(CF_IsBusy()) /*等待设备就绪,读取状态寄存器同时检测设备是否出错*/
Status = TRUE; /*操作正确*/
return Status; /*返回*/
}
/***************************************************************************
Function name: CF_Read_Sector
Parameter : void
Description : CF读扇区函数
Return : void
Argument :
Autor & date :
****************************************************************************/
int CF_Read_Sector(U16 * Buffer, U32 Sector ,U8 count)
{
U8 Status=FALSE;
U16 i;
U16 j;
if(!(CFCard_Flag)) /*CF卡不可用,立即返回*/
return FALSE; /*设备无效直接返回*/
CF_ReadSetting( Sector, count); /*读扇区设置*/
do
{
count--; /*扇区数减1*/
if(CF_IsBusy()) /* 等待设备请求数据传输*/
{
for(i = 0; i < 256; i ++) /*连续读256个字(512字节)数据,及一个扇区大小*/
{
//*Buffer=inportw(CF_REG_DATA);
//Buffer++;
j=inportw(CF_REG_DATA);
*(Buffer++)=j;
//*(Buffer++)=inportw(CF_REG_DATA); /*从数据寄存器读一个字数据*/
}
Buffer +=256; /*调整数据格式*/
}
else break;
//else return 0; /*出错,退出d0...while*/
}while(count>0); /*所有扇区数据传输完成*/
if(CF_IsBusy()) /*等待设备就绪,读取状态寄存器同时检测设备是否出错*/
Status = TRUE; /*操作正确*/
return Status; /*返回*/
}
/***************************************************************************
Function name: CF_SetDevice
Parameter : void
Description : 设置CF控制器
Return : void
Argument :
Autor & date :
****************************************************************************/
void CF_SetDevice(void)
{
CF_Dev_Config = CF_DevReg_DEV1 + /*选择设备1*/
CF_DevReg_b5 +
CF_DevReg_LBA+ /*工作在LAB模式*/
CF_DevReg_b7;
outportw(CF_Dev_Config,CF_REG_DEVICE_HEAD);
}
/***************************************************************************
Function name: CF_Card_Test
Parameter : void
Description : CF读写测试
Return : void
Argument :
Autor & date :
****************************************************************************/
void CF_Card_Test( void )
{
U32 m,n ;
U16 data[512] ;
CF_Init(); //CF总线初始化
CF_Probe(); //CF驱动初始化
CF_SetDevice(); //设置CF设备
if(!(CFCard_Flag))return;
//给要写入CF卡的数组赋值
for( m = 0 ; m < 32 ; m++ ) data[m] = m ;
Uart_Printf("write data : \n");
for( m = 0; m < 2; m++ )
{
for( n = 0; n < 16; n++ )
Uart_Printf( "%04x ", data[m*16+n] ) ;
Uart_Printf("\n");
}
Uart_Printf("\nCF Card Write Sector Test\n\n" );
CF_Write_Sector(data, 0, 2 ) ; //将data数组的数据写入扇区0中
//在读出CF卡之前,先将数组清零
for( m = 0 ; m < 32 ; m++ ) data[m] = 0 ;
Uart_Printf("\nCF Card Read Sector Test\n\n" );
CF_Read_Sector(data, 0, 2 ) ; //将写入扇区0的数据读出来
//打印读出的数据
for( m = 0; m < 2; m++ )
{
for( n = 0; n < 16; n++ )
Uart_Printf( "%04x ", data[m*16+n] ) ;
Uart_Printf("\n");
}
for( m = 0 ; m < 32 ; m++ )
{
if( data[m] != m )
break ;
}
if( m == 32 ) Uart_Printf("\n读出的数据与写入的数据完全相符!\n");
else Uart_Printf("\n读出的数据与写入的数据在地址0x%04处不符! \n", m );
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -