Forum Discussion
Altera_Forum
Honored Contributor
11 years agoPCIe MSI interrupt sharing problem
Hi, MSI shared for DMA Read and Write. In ISR() routine, checks status to determine read or write completion. Either there is missing MSI or Read completion MSI can be mistaking as Write comple...
Altera_Forum
Honored Contributor
11 years agoHost: Windows 7 KDMF device driver
FPGA: Cyclone V GT PCIe hard IP with DMA interface The ISR(): BOOLEAN PCIeEvtInterruptIsr(IN WDFINTERRUPT Interrupt, IN ULONG MessageID) { PFDO_DATA FdoData = NULL; ULONG ulStatusR = 1; ULONG ulStatusW = 1; for (i = 0; i < bNumOfWriteDesc; i++) {//check All Write Status ulStatusW &= pWriteReg->ulStatus;}
if (ulstatusw != 0) { //write complete
fdodata->ulirqcntw++;
if (fdodata->m_ulloopsw > 0 && fdodata->m_ulloopsw < 0x7fffffff) {
fdodata->m_ulloopsw--;
bdowrite = true; //more to go
}
else {//done
rtlzeromemory(pwritereg, 0x200);//clears all write status
fdodata->ulwritedone = 1;
}
}
else {
for (i = 0; i < bnumofreaddesc; i++) {//check all read status
ulstatusr &= preadreg->ulstatus; } if (ulStatusR != 0) { //Read Complete FdoData->ulIRQCntR++; if (FdoData->m_ulLoopsR > 0 && FdoData->m_ulLoopsR < 0x7FFFFFFF) { FdoData->m_ulLoopsR--; bDoRead = TRUE;//more to go } else {//Done RtlZeroMemory(pReadReg, 0x200);//Clears all Read Status FdoData->ulReadDone = 1; } } else { FdoData->ulErrors++; WdfInterruptQueueDpcForIsr(Interrupt); return FALSE; } } if (bDoWrite) { RtlZeroMemory((PUCHAR)pStatusRegW, 0x200);//Clears all Write Status LastPtr = bNumOfReadDesc; } if (bDoRead) { RtlZeroMemory((PUCHAR)pStatusRegR, 0x200);//Clears all Read Status LastPtr = bNumOfWriteDesc; } if (FdoData->ulReadDone == 1 || FdoData->ulWriteDone == 1) { WdfInterruptQueueDpcForIsr(Interrupt); //processing } return TRUE; } Thanks,