ADI的BF561双核DSP怎么做开发,我来说一说(六)IDE硬盘设计

发布于:2025-04-09 ⋅ 阅读:(35) ⋅ 点赞:(0)

作者的话

ADI的双核DSP,最早的一颗是Blackfin系列的BF561,这颗DSP我用了很久,比较熟悉,且写过一些给新手的教程。

是的你没有看错,就是IDE,那个最老的硬盘,我们当年做过此类设计。

硬件准备

ADZS-BF561-EZKIT开发板:ADI原厂评估板

AD-ICE20000仿真器:ADI现阶段性能最好的DSP仿真器

产品链接:https://item.taobao.com/item.htm?id=753233120844

软件准备

Visual DSP++5.1.2
CCES2.11.1

硬件环境的搭建

在这里插入图片描述
程序内容

通过对 ADSP-BF561 处理器 EBIU端口编程控制 IDE接口对硬盘的读写。

在这里插入图片描述

硬件的实现:
如图 1所示,CPLD 的作用是为 IDE硬盘分配总线地址,IDE硬盘有两根地址线 /IDE_CS0和
/IDE_CS1。/IDE_CS0 是选通命令块寄存器,命令块寄存器包含了对硬盘读写控制的寄存器,通过配置这些寄存器对硬盘进行读写操作;/IDE_CS1是控制块寄存器,它包含了设备控制,状态读取等寄存器,在正常的硬盘操作中,不会用到这些寄存器。设计中,将/CS1 和/CS0通过与门 74LVC08连接总线驱动器的片选线上,以做到访问/CS0和/CS1 都能将总线选通。由于硬盘的逻辑电平为 5V,BF561 的逻辑电平为 3.3V,为了使其相匹配采用总线驱动芯片 74LVC245作电平的转换。74LVC245 为双向 8 位总线驱动芯片,用两片作数据总线驱动,一片用作控制信号线的电平匹配。74LVC245传输数据方向的控制脚 DIR,其逻辑时序与BF561 的读控制时序相同,将其连接在 BF561 的/AOE脚,以控制数据的传输方向。

在这里插入图片描述

IDE接口第 39 引脚/DASP,有一 LED指示灯 D9,其作用为当硬盘忙时,该引脚输出低电平,该指示灯亮起。在硬盘读写数据时,它会根据硬盘的工作状态作闪烁。

模块工作模式:

IDE在硬件连接上有两种工作模式:DMA 传输模式和 PIO传输模式。

由于 BF561的 DMA控制器只是从接口到内存的控制,无法对外部器件做 DMA控制。如需实现硬盘的
DMA 传输模式,必须选用专用的 DMA控制芯片。为了简化硬件设计,选用 PIO 16位模式做为硬盘的控
制模式。

IDE 寄存器的访问:

IDE总线上有三根地址线,电路中将其连接于 BF561的 A1、A2和 A3,通过改变地址线的状态,来访
问不同的寄存器。表 2 为 IDE寄存器对应的地址线状态表。

在这里插入图片描述
在这里插入图片描述

数据寄存器(R/W):这是一个 16位 PIO数据寄存器,用于对扇区的读、写和格式化操作。

错误寄存器(R):该寄存器是一个 8 位的寄存器,它反映控制寄存器在诊断方式或操作方式下的错误
原因。

扇区数寄存器(R/W):它记录读、写命令的扇区数。当多扇区传输时,每完成一个扇区操作,该寄存器自动减 1,直至为 0。如果初值为 0,则表示 256;如果有错误产生,该寄存器包含已经操作成功的扇区数。

扇区号寄存器(R/W):它记录读、写和校验命令指令起始扇区号。

柱面号寄存器(R/W):它记录读、写、校验、寻址和格式化命令指定的柱面号,在 LBA 寻址方式下,这 2 个寄存器包含起始扇区号的 1和 2 字节。

驱动器/磁头寄存器(R/W):它记录读、写、校验、寻道和格式化命令指定的驱动器号、磁头号和寻址方式。

硬盘扇区寻址:

硬盘的扇区寻址有两种方式,一种是以磁头,柱面,扇区为寻址标准的物理寻址方式(CHS)。一种是基
于磁盘包含总扇区数的逻辑寻址(LBA)。

物理寻址:
这种方式需根据硬盘所包含的磁头,柱面,扇区的数量进行寻址,涉及参数多,扇区缺乏连续性,但可以精确定位到所要操作的扇区的位置,常用于一些固定扇区地址的数据操作,如读取 MBR(主引导扇区)和 DBR(DOS引导扇区)数据。

逻辑寻址:
逻辑寻址是为硬盘所有的扇区进行连续的逻辑编号,操作时只需指定出这个扇区的逻辑编号即可。因为每个扇区都有一个特定的编号,整个磁盘就像是一个整体,常用于文件系统的扇区操作。但由于不同容量的磁盘,磁头,柱面数不同,因此不利于固定地址的扇区操作,如读取 DBR(DOS引导扇区)。

逻辑寻址和物理寻址的寄存器配置:

驱动器/磁头寄存器(Device/Head)在 ATA-IDE中的定义:
Device/Head:

在这里插入图片描述

HS0~HS3(磁头选择):在 CHS模式中,是指定对哪一个磁头进行操作。在 LBA 方式中,是逻辑扇
区的高 4 位。

DEV 驱动器选择:0选择主驱动器,1选择从驱动器。

L(LBA方式):L=1,置驱动器为 LBA 模式;L=0,置驱动器为 CHS模式。

在定义磁盘的寻址方式时,我们只需要定义 Device/Head寄存器的 D6 位即可。在 LBA 寻址中,寄存器
Sector Number为所要读取扇区号的第一个字节,寄存器 Cylinder Low为第二个字节,寄存器 Cylinder High为第三个字节,寄存器 Device/Head的低四位为高 4 位。这些寄存器组成一个 28位的逻辑寻址地址寄存器。

核心代码分析

BYTE Wait_Ready(void)
{
BYTE statbyte;
BYTE flag = 0;
while (!flag)
{
statbyte = *pStatus ;// Read Status Register
if (statbyte & IDE_ERROR)
{
statbyte=*pErrorReg; //检查硬盘工作是否有错误
return statbyte; //如果有,读错误寄存器,并返回错误码
}
if (statbyte & IDE_DRDY)
flag = 1; // 检查硬盘是否 ready
}
return 0; //无错,返回 0
}
int fnIDE_ReadBufferSector(WORD *buf,DWORD LBALocation,BYTE count)
{
WORD i,temp;
BYTE j;
BYTE errorcode;
unsigned short Head, Cyl_H,Cyl_L,SecNum;
Wait_ReadyBusy(); //等待硬盘是否准备好可以操作
*pDriveHead=((LBALocation >> 24) & 0xFF) | 0xE0; //将逻辑地址送入地址寄存器
*pCylinderHigh=(LBALocation >> 16) & 0xFF;
*pCylinderLow=(LBALocation >> 8) & 0xFF;
*pSectorNumber=LBALocation & 0xFF;
*pSectorCount=count; //要读取得扇区数
*pCommand=0x21; //读取数据
j=count;
temp=0;
do
{
Wait_DRQ(); //等待数据传输是否准备好
for(i=0; i < SECTORWORDSIZE; i++) //读取数据
{
buf[temp+i] = *pDataPort;
}
j–;
temp += SECTORWORDSIZE ;
}while(j!=0); //判断是否读完全部的扇区
errorcode = CheckforError(); //校验是否有错
if (errorcode!=0) //如果有错,返回 1
return 1;
return 0; //校验正确,返回 0
}
int fnIDE_WriteBufferSector(WORD *buf,DWORD LBALocation,BYTE count)
{
WORD i,temp;
BYTE j;
BYTE errorcode;
Wait_ReadyBusy(); //等待硬盘是否准备好可以操作
*pDriveHead=((LBALocation >> 24) & 0xFF) | 0xE0; //将逻辑地址送入地址寄存器
*pCylinderHigh=(LBALocation >> 16) & 0xFF;
*pCylinderLow=(LBALocation >> 8) & 0xFF;
*pSectorNumber=LBALocation & 0xFF;
*pSectorCount=count; //要读取得扇区数
*pCommand=0x31; //写入扇区
j=count;
temp=0;
do
{
Wait_DRQ(); //等待数据传输是否准备好
for(i=0; i < SECTORWORDSIZE; i++)
{
*pDataPort=buf[temp+i];
}
j–;
temp += SECTORWORDSIZE ;
}while(j!=0); //判断是否写完全部的扇区
errorcode = CheckforError(); //校验是否有错
if (errorcode!=0) //如果有错,返回 1
return 1;
return 0; //校验正确,返回 0
}