📄 cf_io.c
字号:
#include "CF_IO.h"
uint8_t CF_Initialize(void)
{
CF_DataOffset = 0;
CF_CurrentLBA = 0;
outb(CF_COMMAND_REG, CF_CMD_DIAGNOSTIC); //执行诊断指令,判断CF卡是否可用
loop_until_bit_is_clear(CF_STATUS_REG, 7); //等待BUSY位清空
if(inb(CF_ERROR_REG) == 0x01) //返回0x01表示成功
{
outb(CF_FEATURE_REG, 0x01);
outb(CF_DRIVER_REG, 0xa0);
outb(CF_COMMAND_REG, CF_CMD_SETFEATURE); //设置驱动器特性
loop_until_bit_is_clear(CF_STATUS_REG, 7);
return inb(CF_ERROR_REG);
}
else
return inb(CF_ERROR_REG);
}
void CF_ChangeDrive(unsigned char d)
{
if(d)
sbi(CF_DRIVER_REG, 4); //从盘
else
cbi(CF_DRIVER_REG, 4); //主盘
}
uint8_t CF_GetCardInfo(CF_TInfo *I)
{
uint8_t i;
outb(CF_COMMAND_REG, CF_CMD_IDENTITY); //执行获取CF卡信息的指令
loop_until_bit_is_clear(CF_STATUS_REG, 7);
if(inb(CF_ERROR_REG))
return inb(CF_ERROR_REG);
else
{
loop_until_bit_is_set(CF_STATUS_REG, 3);
I->Signature = inw(CF_DATA_REG);
I->Cylinders = inw(CF_DATA_REG);
inw(CF_DATA_REG);
I->Heads = inw(CF_DATA_REG);
inw(CF_DATA_REG);
inw(CF_DATA_REG);
I->SectorsPerTrack = inw(CF_DATA_REG);
I->TotalSectors = ((uint32_t)inw(CF_DATA_REG)) << 16;
I->TotalSectors += inw(CF_DATA_REG);
inw(CF_DATA_REG);
for(i = 0; i < 20; i ++)
I->SerialNumber[i] = inb(CF_DATA_REG);
for(i = 0; i < 7; i ++)
inw(CF_DATA_REG);
for(i = 0; i < 40; i ++)
I->ModelNumber[i] = inb(CF_DATA_REG);
for(i = 0; i < 13; i ++)
inw(CF_DATA_REG);
I->LBAs = inw(CF_DATA_REG);
I->LBAs += ((uint32_t)inw(CF_DATA_REG)) << 16;
for(i = 0; i < 194; i ++)
inw(CF_DATA_REG);
I->TotalSize = I->TotalSectors << 9;
return 0;
}
}
uint8_t CF_ReadSector(uint16_t cylinder, uint8_t head, uint8_t sector, uint8_t sectorcount, char *buf)
{
uint8_t i = 0;
cbi(CF_DRIVER_REG, 6); //以柱面号/磁头号/扇区号的方式访问
outb(CF_SECTOR_COUNT_REG, sectorcount); //要读取的扇区数
outb(CF_SECTOR_REG, sector); //扇区号
outb(CF_CYLINDER_L_REG, *(uint8_t *)(&cylinder)); //柱面号低位
outb(CF_CYLINDER_H_REG, *(((uint8_t *)(&cylinder)) + 1)); //柱面号高位
(*(uint8_t *)(CF_HEAD_REG)) &= 0b11110000;
(*(uint8_t *)(CF_HEAD_REG)) |= head & 0b00001111; //设置磁头号(CF_HEAD_REG低4位为磁头号)
outb(CF_COMMAND_REG, CF_CMD_READSECTOR); //执行读取指令
loop_until_bit_is_clear(CF_STATUS_REG, 7); //等待BUSY位清空
if(inb(CF_ERROR_REG)) //不返回0x00表示有错
return inb(CF_ERROR_REG);
else
{
do
{
loop_until_bit_is_set(CF_STATUS_REG, 3); //等待DataRequest位置位
do
{
*(buf ++) = inb(CF_DATA_REG); //顺序把数据寄存器的值放到buf中
*(buf ++) = inb(CF_DATA_REG);
}while(--i);
}while(--sectorcount);
return 0;
}
}
uint8_t CF_LBAReadSector(uint32_t LBA, uint8_t sectorcount, char *buf)
{
uint8_t i = 0;
sbi(CF_DRIVER_REG, 6); //以LBA方式访问
outb(CF_SECTOR_COUNT_REG, sectorcount);
outb(CF_LBA_0_7_REG, *(uint8_t *)(&LBA));
outb(CF_LBA_8_15_REG, *(((uint8_t *)(&LBA)) + 1));
outb(CF_LBA_16_23_REG, *(((uint8_t *)(&LBA)) + 2));
(*(uint8_t *)(CF_LBA_24_27_REG)) &= 0b11110000;
(*(uint8_t *)(CF_LBA_24_27_REG)) |= *(((uint8_t *)(&LBA)) + 3) & 0b00001111;
outb(CF_COMMAND_REG, CF_CMD_READSECTOR);
loop_until_bit_is_clear(CF_STATUS_REG, 7);
if(inb(CF_ERROR_REG))
return inb(CF_ERROR_REG);
else
{
do
{
loop_until_bit_is_set(CF_STATUS_REG, 3);
do
{
*(buf ++) = inb(CF_DATA_REG);
*(buf ++) = inb(CF_DATA_REG);
}while(--i);
}while(--sectorcount);
return 0;
}
}
uint8_t CF_WriteSector(uint16_t cylinder, uint8_t head, uint8_t sector, uint8_t sectorcount, char *buf)
{
uint8_t i = 0;
cbi(CF_DRIVER_REG, 6);
outb(CF_SECTOR_COUNT_REG, sectorcount);
outb(CF_SECTOR_REG, sector);
outb(CF_CYLINDER_L_REG, *(uint8_t *)(&cylinder));
outb(CF_CYLINDER_H_REG, *(((uint8_t *)(&cylinder)) + 1));
(*(uint8_t *)(CF_HEAD_REG)) &= 0b11110000;
(*(uint8_t *)(CF_HEAD_REG)) |= head & 0b00001111;
outb(CF_COMMAND_REG, CF_CMD_WRITESECTOR);
loop_until_bit_is_clear(CF_STATUS_REG, 7);
if(inb(CF_ERROR_REG))
return inb(CF_ERROR_REG);
else
{
do
{
loop_until_bit_is_set(CF_STATUS_REG, 3); //等待DataRequest位置位
do
{
outb(CF_DATA_REG, *(buf ++)); //顺序把buf中的内容送到数据寄存器
outb(CF_DATA_REG, *(buf ++));
}while(--i);
}while(--sectorcount);
loop_until_bit_is_clear(CF_STATUS_REG, 7); //等待BUSY位清空
return inb(CF_ERROR_REG);
}
}
uint8_t CF_LBAWriteSector(uint32_t LBA, uint8_t sectorcount, char *buf)
{
uint8_t i = 0;
sbi(CF_DRIVER_REG, 6);
outb(CF_SECTOR_COUNT_REG, sectorcount);
outb(CF_LBA_0_7_REG, *(uint8_t *)(&LBA));
outb(CF_LBA_8_15_REG, *(((uint8_t *)(&LBA)) + 1));
outb(CF_LBA_16_23_REG, *(((uint8_t *)(&LBA)) + 2));
(*(uint8_t *)(CF_LBA_24_27_REG)) &= 0b11110000;
(*(uint8_t *)(CF_LBA_24_27_REG)) |= *(((uint8_t *)(&LBA)) + 3) & 0b00001111;
outb(CF_COMMAND_REG, CF_CMD_WRITESECTOR);
loop_until_bit_is_clear(CF_STATUS_REG, 7);
if(inb(CF_ERROR_REG))
return inb(CF_ERROR_REG);
else
{
do
{
loop_until_bit_is_set(CF_STATUS_REG, 3);
do
{
outb(CF_DATA_REG, *(buf ++));
outb(CF_DATA_REG, *(buf ++));
}while(--i);
}while(--sectorcount);
loop_until_bit_is_clear(CF_STATUS_REG, 7);
return inb(CF_ERROR_REG);
}
}
void CF_Sleep(void)
{
outb(CF_COMMAND_REG, CF_CMD_SLEEP);
}
void CF_Standby(void)
{
outb(CF_COMMAND_REG, CF_CMD_STANDBY);
}
uint8_t CF_LBAOpen(uint32_t LBA)
{
CF_DataOffset = 0;
CF_CurrentLBA = LBA;
sbi(CF_DRIVER_REG, 6);
outb(CF_SECTOR_COUNT_REG, 1);
outb(CF_LBA_0_7_REG, *(uint8_t *)(&LBA));
outb(CF_LBA_8_15_REG, *(((uint8_t *)(&LBA)) + 1));
outb(CF_LBA_16_23_REG, *(((uint8_t *)(&LBA)) + 2));
(*(uint8_t *)(CF_LBA_24_27_REG)) &= 0b11110000;
(*(uint8_t *)(CF_LBA_24_27_REG)) |= *(((uint8_t *)(&LBA)) + 3) & 0b00001111;
outb(CF_COMMAND_REG, CF_CMD_READSECTOR);
loop_until_bit_is_clear(CF_STATUS_REG, 7);
return inb(CF_ERROR_REG);
}
uint8_t CF_LBAReadb(void)
{
CF_DataOffset ++;
return inb(CF_DATA_REG);
}
uint16_t CF_LBAReadw(void)
{
CF_DataOffset += 2;
return inw(CF_DATA_REG);
}
uint32_t CF_LBAReadl(void)
{
uint32_t r;
CF_DataOffset += 4;
r = inw(CF_DATA_REG);
r += ((uint32_t)inw(CF_DATA_REG)) << 16;
return r;
}
void CF_LBASeek(uint16_t o)
{
uint16_t i;
if(o < CF_DataOffset)
{
CF_LBAOpen(CF_CurrentLBA);
for(i = 0; i < o; i ++)
inb(CF_DATA_REG);
}
else
for(i = CF_DataOffset; i < o; i ++)
inb(CF_DATA_REG);
CF_DataOffset = o;
}
void CF_LBAClose(void)
{
CF_LBASeek(0x200);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -