转换精简ISA总线为16bit总线接口

 2020-11-6 17:29:13     作者:Emtronix    

  为了减少精简ISA总线的信号管脚数量,英创工控主板(ESM335x、ESM7000、ESM6802等)的精简ISA总线采取了地址数据时分复用的方式,总线的宽度为8-bit,总线周期在200ns内,这样支持10MB/s的数据率。在客户的某些应用场合,总线接口是独立的地址总线和数据总线,总线宽度则为16-bit。为了支持客户已有设计保持不变,需要把精简ISA总线转换为16-bit的总线格式,本文将介绍相应的转换电路及对应的操作代码。


  转换的基本思路是使用两个寄存器做地址寄存器,提供16-bit的地址总线,另外再使用两个寄存器作为数据寄存器。软件对转换过程的数据缓存是完全透明的。


转换电路


  在下面的电路中,精简ISA总线的地址A0高低分别表示16-bit地址或数据的高位字节和低位字节,译码信号为BHE;而精简ISA总线的地址A1的高低分别表示16-bit数据读写周期和16-bit地址写周期,译码信号为D_A_FLG。


  采用74‘s系列经典器件来实现总线的转换,可帮组理解转换的技术要点。在实际应用中,把这部分电路用FPGA或CPLD来实现会更加简便。


  电路图中信号名称带“#”或“_B”后缀的,表示信号是低电平有效。


转换精简ISA总线为16bit总线接口.png


  放大各个部分电路。


  译码部分:


转换精简ISA总线为16bit总线接口.png


  延时展宽部分。在FPGA或CPLD中,也可采用其它电路获得更好的效果:


转换精简ISA总线为16bit总线接口.png


  总线多路切换:


转换精简ISA总线为16bit总线接口.png


  上面的电路导出的16bit接口信号包括:

  ● BUS16_A[0..15]:16-bit地址总线;总线周期时有效,非总线周期保持原状态。

  ● BUS16_D[0..15]:双向16-bit数据总线;总线周期时有效,非总线周期为高阻态。

  ● BUS16_RD_B:读脉冲,低电平有效。

  ● BUS16_WE_B:写脉冲,低电平有效,上升沿锁存总线数据。


代码实例


  在WEC7平台ESM335x上的ISA总线操作函数如下:


// open "ISA1:"
HANDLE  hISA = CreateFile(_T("ISA1:"),                         // name of device
                            GENERIC_READ|GENERIC_WRITE,         // desired access
                            FILE_SHARE_READ|FILE_SHARE_WRITE,      // sharing mode
                            NULL,                                                      // security attributes
                            OPEN_EXISTING,                                    // creation disposition
                            FILE_FLAG_RANDOM_ACCESS,                    // flags/attributes
                            NULL);


  打开设备文件获得HANDLE后,就可以对总线进行读写操作了。


// convert ISA to 16-bit width for both address and data
#define BUS16_ADDR_REG_INDEX             ((DWORD)0) // ISA_A1 = 0: address registers
#define BUS16_DATA_REG_INDEX              ((DWORD)2) // ISA_A1 = 1: data register
 
BOOL Isa_Read16(HANDLE hISA, WORD wPortOffset, WORD* pBuf)
{
       DWORD dwValue;
       DWORD dwNbBytesReturn = 0;
 
       // write 16-bit address
       dwValue = (BUS16_ADDR_REG_INDEX << 16) | wPortOffset;
       WriteFile(hISA, &dwValue, sizeof(DWORD), &dwNbBytesReturn, NULL);
 
       // read 16-bit data
       *pBuf = (WORD)(BUS16_DATA_REG_INDEX & 0xFE);
       ReadFile(hISA, pBuf, sizeof(WORD), &dwNbBytesReturn, NULL);
 
       return TRUE;
}
 
BOOL Isa_Write16(HANDLE hISA, WORD wPortOffset, WORD wValue)
{
       DWORD dwValue;
       DWORD dwNbBytesReturn = 0;
 
       // write 16-bit address
       dwValue = (BUS16_ADDR_REG_INDEX << 16) | wPortOffset;
       WriteFile(hISA, &dwValue, sizeof(DWORD), &dwNbBytesReturn, NULL);
 
       // write 16-bit data
       dwValue = (BUS16_DATA_REG_INDEX << 16) | wValue;
       WriteFile(hISA, &dwValue, sizeof(DWORD), &dwNbBytesReturn, NULL);
 
       return TRUE;
}


  以上代码也可在ESM7000 WEC7平台上使用。在Linux平台,客户可编写类似的代码,也可请英创的技术编写相应的代码。