chen_qi_lin
驱动牛犊
驱动牛犊
  • 注册日期2008-06-06
  • 最后登录2009-04-29
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2525回复:2

PCI卡DMA传输问题

楼主#
更多 发布于:2009-02-19 16:34
本人最近在Windows下使用Tiger320芯片做一个PCI卡,使用其DMA进行数据传输,现遇到不解:


描述如下: 在对TIGER320芯片初始化后,随即启动DMA,未进行任何读写操作,可是DMA却不断发出读写中断信号,
           我怀疑是芯片初始化问题,或者是硬件设计上存在问题,不知有没有大侠用过TIGERE320芯片,望赐教。
gucheng82
驱动牛犊
驱动牛犊
  • 注册日期2005-05-23
  • 最后登录2009-03-07
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望87点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-02-21 10:37
没用过这个芯片,帮顶~~
好好分析下它的手册,看看DMA相关寄存器设置对了没有,还有就是中断源是什么。若怀疑是硬件问题,可以用示波器量下相关管脚的信号
chen_qi_lin
驱动牛犊
驱动牛犊
  • 注册日期2008-06-06
  • 最后登录2009-04-29
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望21点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-02-24 20:24
首先感谢楼上大哥的关注。
下面我把DataSheet中的DMA相关的说明列出来,请大家看看:
Bus mastering DMA
Tiger320 PCI bus master supports bi-directional data transfer.
DMA-READ is referred as the data transfer from the serial input port to the system memory.
DMA-WRITE is for data transferred from system memory to the serial output port.
Each direction of DMA has it own set of registers and logic. They can be programmed for different
configurations of the DMA transfer.

Setup of DMA operation
To setup the DMA operation, first the DMA start address and the DMA end address registers
need to be set to the relevant physical system memory locations. The Tiger320 DMA logic does
not require a counter value.
The difference between the DMA end address and DMA start address will be the amount of data
that is to be transferred by the DMA. If the start address is “X” and the data transferred is “n”
bytes, the end address will be “X + n - 4”. The minus 4 is needed to point to the very last location
as the first location is 0 and not 1.
The serial port will always transfer 32 bits of data for each frame sync.
Important to note that the DMA start and end addresses must be on a double word boundary.

Status register
There is a DMA interrupt address register to enable DMA status checking. When the DMA
reaches the interrupt address, it will set the flag in Interrupt 0 status register (Index 0x6). Reading
the status register and writing back the read value of 1 (if an interrupt has occurred) will clear the
flag. Please note, writing a 0 will not clear the flag.

Control register
Control register (Index 0x0) bit 6 controls the mode for generating the interrupt.
Set to 0 for level trigger, in this mode the interrupt will occur when the event happens and the
status bit will remain set to 1 only as long as the conditions that created the interrupt still exist.
Set to 1 for edge trigger, in this mode the interrupt will occur when the event happens and the
status bit will remain set until it is cleared by writing a 1 to the DMA status register.
Control register (Index 0x0) bit 7 is used to configure the DMA operation mode. When it is set to
0, the bus master DMA is set as self-address mode. The DMA will automatically wrap around to
the starting address if the ending address is reached. If it is set 1, normal mode, the DMA will
stop DMA when the end address is reached. The major difference between the self-address DMA
mode and the normal DMA mode is the hardware will continuously transfer data without CPU
attention in the self-address mode.
To start the DMA operation, set the Operation register (Index 0x1) bit 0 to 1. To stop the DMA
operation, set this bit to 0. Bit 1 of this register is used to restart the DMA operation in normal
mode. This bit is not used in the self-address mode.
The status of DMA transfer can be monitored by reading the current DMA address. This register
contains the current DMA address pointer. Interrupt 0 status register (Index 0x6) bit 0 to 3 has the
status of the current DMA operation. Each bit can generate interrupt if the mask bit is set.
In the event that the PCI bus master logic detects an abort condition, Interrupt 0 status register
(Index 0x6) bit 4 and 5 will be set based on the abort condition. It can be cleared by reading the
status register. To recover the PCI master state machine, set the reset bit in register 0 to 1 and
reset it to 0, also enable the DMA operation by setting register 1 bit 0 to 1.

DMA register addresses
Index 0xB ~ 0x8 DMA write starting address
Index 0xF ~ 0xC DMA write interrupt address
Index 0x13 ~ 0x10 DMA write end address
Index 0x17 ~ 0x14 DMA write current address
Index 0x1B ~ 0x18 DMA read starting address
Index 0x1F ~ 0x1C DMA read interrupt address
Index 0x23 ~ 0x20 DMA read end address
Index 0x27 ~ 0x24 DMA read current address

Software considerations
The basic setup flow for the DMA is:
1. Allocate non-cacheable continuous DMA memory.
2. Set DMA start and end address registers.
3. Fill the DMA write buffer.
4. Set DMA start bit.

Self-address DMA mode is the most powerful feature of Tiger320. The DMA hardware only
requires to be initialized once and no further software setup is necessary. It provides the status
registers and interrupt for the host processor to detect current DMA status. Also, it provides an
almost unlimited system memory buffer for the data transfer.
Once the DMA is setup, the main CPU can use a timer polling routine to monitor the current DMA
status and process the downstream and upstream data buffer. The interval time is based on the
size of allocated system memory.
The normal DMA mode has a similar control flow as PC DMA controller. The major difference is
there is no counter register. The end address is used instead. Also, the trigger of the DMA has it’s
own control register.

DMA 实现的功能是将主机提供的数据写到设备上,并从设备上读取数据写到主机中,也就是数据的双向传输。
其中,中断是由DMA读写数据位置产生的。

根据它的描述,我用Windows DDK开发WDM驱动,编写基于PCI总线主设备的共用缓冲区的DMA传输。

我的初始化流程及源代码如下:

1. 关中断
DisableInterrupts(DeviceExtension);

2.初始化设备
VOID InitHardware(PNSKYPE_DEVICE_EXTENSION pdx)
{
// tiger320 芯片信号拉高
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL), CNTL_EXTRST_PIN_STATE);

// 信号拉低
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL), 0x00);
    
Delay(250);    // 延时

// 信号再次拉高
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL), CNTL_EXTRST_PIN_STATE);

// 重置PCI接口、DMA逻辑及串口信号
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL), READ_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL)) | CNTL_RESET_DMA_LOGIC | CNTL_RESET_SERIAL_PORT);

/* Wait 1/4 of a sec */
Delay(250);

// 设置为普通模式,并且起用DMA自动回环模式(即将DMA读写地址到达结束位置后,自动返回到起始地址)
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL), READ_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL)) | PIB_15_CYCLE_OPER2 | CNTL_EXTRST_PIN_STATE);

// Make sure serial port and DMA are out of reset
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL), READ_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_CNTL)) & CNTL_MASK);

// Configure serial port for MSB->LSB operation
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_SERCTL), 0xC1);

// Delay FSC by 0 so it's properly aligned
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_FSCDELAY), 0x00);

Delay(250);

// Setup DMA Addresses 这些地址是在启动驱动时分配的共用读写缓冲区
WRITE_PORT_ULONG((PULONG)(pdx->PortBase + TIGER320_DMAWS), pdx->paCommonWriteBuffer.LowPart);                // Write start
WRITE_PORT_ULONG((PULONG)(pdx->PortBase + TIGER320_DMAWI), pdx->paCommonWriteBuffer.LowPart + 16 -4);        // Middle (interrupt)
WRITE_PORT_ULONG((PULONG)(pdx->PortBase + TIGER320_DMAWE), pdx->paCommonWriteBuffer.LowPart + 32 -4);        // End

WRITE_PORT_ULONG((PULONG)(pdx->PortBase + TIGER320_DMARS), pdx->paCommonReadBuffer.LowPart);                // Read start
WRITE_PORT_ULONG((PULONG)(pdx->PortBase + TIGER320_DMARI), pdx->paCommonReadBuffer.LowPart + 16 -4);        // Middle (interrupt)
WRITE_PORT_ULONG((PULONG)(pdx->PortBase + TIGER320_DMARE), pdx->paCommonReadBuffer.LowPart + 32 -4);        // End

// Clear any pending interrupts by writing 1's to any that are currently asserted    
WRITE_PORT_UCHAR((PUCHAR)(pdx->PortBase + TIGER320_INTSTAT), 0xFF);

/* Wait 1/4 of a second more */
Delay(250);
}

3. 开中断
EnableInterrupts(DeviceExtension);

4. 开启DMA
StartDMA(DeviceExtension);
......

对了,这里还得补充一下,TIGER320芯片有两大功能:
1) Network device
2) Communication device

A. 若以Communication device来初始化时,启动DMA后,就会不断的产生DMA的读写中断,但我根本就没有向读写缓冲区中填写数据,理应不该产生这些中断信号,难到DMA会空读这段缓冲区不成?
B. 若以Network device来初始化时,启动DMA,不会产生DMA读写中断,但我向读写缓冲区中填写数据的时候,却无任何中断产生,理应产生的中断信号,难道DMA没有被成功开启?

 因大多数DMA的驱动都是基于包的传输。在此,特向各位大哥们请教,写基于总线主设备的共用缓冲区的WDM的DMA传输是不是以如下几步:
1. 获取DMA对象
2. 分配读写共用缓冲区
3. 关中断,设置中断服务函数
4. 初始化设备
5. 设置DMA寄存器(将共用缓冲区的起始及结束地址写入DMA相应的寄存器)
6.清中断及开中断
7. 开启DMA

若有哪位大侠对这方面精通,肯求加我的QQ:364170604,详细情况细谈,在此拜谢!并感谢所有对驱动有不断追求之士!
游客

返回顶部