tqijin
驱动小牛
驱动小牛
  • 注册日期2006-07-04
  • 最后登录2013-11-21
  • 粉丝3
  • 关注0
  • 积分31分
  • 威望1060点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
阅读:1730回复:2

版主大哥,高手们,救救小弟,DMA传输同步

楼主#
更多 发布于:2009-10-18 16:32
123456789
skymelai
驱动牛犊
驱动牛犊
  • 注册日期2007-08-10
  • 最后登录2010-01-29
  • 粉丝1
  • 关注0
  • 积分81分
  • 威望711点
  • 贡献值3点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-10-19 09:59
把你的代码贴出来。
tqijin
驱动小牛
驱动小牛
  • 注册日期2006-07-04
  • 最后登录2013-11-21
  • 粉丝3
  • 关注0
  • 积分31分
  • 威望1060点
  • 贡献值1点
  • 好评度14点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-10-19 12:56
  //派遣函数
switch (IoControlCode)
{
case IOCTL_DMA_DEVICE_HOST:
    {  
        if (InputBufferLength != sizeof(SIZE_T) + sizeof(SIZE_T) + sizeof(ULONG))
        {
            status = STATUS_INVALID_PARAMETER;
            length = 0;
            break;
        }

        dwDMASize      = *(SIZE_T *)((char *)inBuffer);
        dwDMACount     = *(SIZE_T *)((char *)inBuffer + sizeof(SIZE_T));
        dwDMAPattern   = *(ULONG  *)((char *)inBuffer + sizeof(SIZE_T) + sizeof(SIZE_T));

        WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPAddress,     (ULONG)devExt->BufferPhysicalAddress);
        WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPSize,        32);
        WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->WriteDMATLPCount,       dwDMACount);//DMA设置

        DMACSR2.ulong = READ_REGISTER_ULONG((PULONG)&devExt->Regs->DCSR2);

        DMACSR2.bits.WriteDMADone  = 0;
        DMACSR2.bits.WriteDMAStart = 1;
        DMACSR2.bits.ReadDMADone   = 0;
        DMACSR2.bits.ReadDMAStart  = 0;  
        WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->DCSR2,    DMACSR2.ulong);//启动DMA

       delay.QuadPart = -50*10000;
        KeWaitForSingleObject(&devExt->kEvent,Executive,KernelMode,FALSE,&delay);//等待事件kEvent发生
       status = STATUS_SUCCESS;

        length = 0;
        break;
    }
//////////////////////////////////////////////////////////////////////////////////
//ISR中断服务程序
BOOLEAN
PCIEEvtInterruptIsr(
    IN WDFINTERRUPT Interrupt,
    IN ULONG        MessageID
    )
{

    PDEVICE_EXTENSION   devExt;
    BOOLEAN             isRecognized = FALSE;
    __int64             i64End;
    union {
        DMA_INT     bits;
        ULONG       ulong;
    } DMAINT;
    
    devExt  = PCIEGetDeviceContext(WdfInterruptGetDevice(Interrupt));

    DMAINT.ulong = READ_REGISTER_ULONG( (PULONG) &devExt->Regs->INT);//中断状态寄存器

   isRecognized = (BOOLEAN)DMAINT.bits.INT_ASSERT;//判断有DMA中断
    if(isRecognized)
    {
        // Is write Int?
        //
        if (DMAINT.bits.INT_WR)
      {//判断是DMA读完成中断

           KeSetEvent(&devExt->kEvent,     (KPRIORITY) 0,  FALSE);//设置事件kEvent有效
            // To Clear the Interrupt
           WRITE_REGISTER_ULONG((PULONG)&devExt->Regs->INT, 0);//清中断
        }
    }

    return isRecognized;
}
游客

返回顶部