cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
golson
Scholar
Scholar
6,825 Views
Registered: ‎04-07-2008

DMA START FUNCTION

Hi,

  I am wondering about how I should write my driver.

 

I have come up with a function DMA Start.

 

here it is:

void VIRTEX5_DMAStart(VIRTEX5_DMA_HANDLE hDma, BOOL fIsRead)

{

UINT32 dmacst;

if (!IsValidDmaHandle(hDma, "VIRTEX5_DMAStart")) return;

VIRTEX5_DMASyncCpu(hDma);

/* Start DMA Transfer */

//VIRTEX5_WriteReg32(hDma->hDev, VIRTEX5_DDMACR_OFFSET,

// fIsRead ? 0x10000 : 0x1);

printf("\n Entered DMA Start \n");

 

VIRTEX5_WriteReg32(hDma->hDev, VIRTEX5_DMACST_OFFSET,

fIsRead ? 0x4 : 0x1); // flip it hi then flip it low

dmacst = VIRTEX5_ReadReg32(hDma->hDev, VIRTEX5_DMACST_OFFSET);

printf(
"\n dmacst = %d \n", dmacst);

VIRTEX5_WriteReg32(hDma->hDev, VIRTEX5_DMACST_OFFSET,0x0); // put back low

dmacst = VIRTEX5_ReadReg32(hDma->hDev, VIRTEX5_DMACST_OFFSET);

printf(
"\n dmacst = %d \n", dmacst);

}

 

 

It does work to a point.  And it may be correct however later on I can not send more data.  I also noticed my first packet

only has two data words in it. followed by normal full data packets coming out.

 

I am thinking that I should not bring the DMACST signlal back low so quickly.  Maybe it affected the state machine.

 

 

 

 

 

 

0 Kudos
4 Replies
zhuhaibo79
Visitor
Visitor
6,796 Views
Registered: ‎11-13-2008

Have u change DMACST behavor ?  host driver set dma start and can not clear it .  driver can only clear dma done signal.

 

i am also trying dma  , it don't work .  maybe some other reg should be set.

0 Kudos
golson
Scholar
Scholar
6,771 Views
Registered: ‎04-07-2008

Here is My New Start Function:

 

void VIRTEX5_DMAStart(VIRTEX5_DMA_HANDLE hDma, BOOL fIsRead)

{

//UINT32 dmacst;

 if (!IsValidDmaHandle(hDma, "VIRTEX5_DMAStart")) return;

VIRTEX5_DMASyncCpu(hDma);

printf("\n Entered DMA Start \n");

VIRTEX5_WriteReg32(hDma->hDev, VIRTEX5_DMACST_OFFSET, fIsRead ? 0x4 : 0x1); // flip it hi then flip it low

VIRTEX5_WriteReg32(hDma->hDev, VIRTEX5_DMACST_OFFSET, 0x0); // put back low

}

 

And the next function:

 

BOOL VIRTEX5_DMAIsDone(WDC_DEVICE_HANDLE hDev, BOOL fIsRead)

{

UINT32 dmacst;

BOOL boolean_value;

int i;

printf("\n Entered DMAIsDone \n");

if (!IsValidDevice(hDev, "VIRTEX5_DMAIsDone"))

{

printf(
"Device is no longer valid \n"); return FALSE;

}

for( i = 0; i <= 0x30; i = i+4 )

{

WDC_ReadAddr32(hDev, 0, i, &dmacst);

printf(
"\n just after done dmacst = %x \t i = %d = %x\n", dmacst , i, i);

}

//dmacst = VIRTEX5_ReadReg32(hDev, VIRTEX5_DMACST_OFFSET);

//WDC_ReadAddr32(hDev, 0, VIRTEX5_DMACST_OFFSET, &dmacst);

WDC_ReadAddr32(hDev, 0, 0x28, &dmacst);

///WDC_DIAG_ReadRegGary(hDev, gVIRTEX5_Regs, VIRTEX5_REGS_NUM );

//WDC_DIAG_ReadWriteReg(hDev, gVIRTEX5_Regs, VIRTEX5_REGS_NUM, WDC_WRITE, FALSE);

//VIRTEX5_DMACST_OFFSET

printf("\n just after done dmacst = %d \n", dmacst);

 

// For XAPP859 Design

// Note Byte0 bit 3 is Read DMA Done, 0 not done, 1 done BIT3 (counting 0, BIT0 included)

// Note Byte0 bit 1 is Write DMA Done, 0 not done, 1 done BIT1

boolean_value = (fIsRead ? dmacst & BIT3 : dmacst & BIT1) ? TRUE : FALSE;

if (boolean_value == TRUE) // fixed a mistake here gary was single equal

{

WDC_ReadAddr32(hDev, 0, 0x28, &dmacst);

printf(
"\n dmacst = %x \n", dmacst);

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMACST_OFFSET, 0x0000000a); // host can not clear this bit

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMACST_OFFSET, 0x00000000);

}

else

{

printf(
"\n FALSE 51 \n");

}

//return (fIsRead ? dmacst & BIT3 : dmacst & BIT1) ? TRUE : FALSE;

 return boolean_value;

}

 

 They seem to work.  But I can only start one time because some state machine may not be going back to Idle.

 

I am trying to figure that out.

 

 

 

 

0 Kudos
golson
Scholar
Scholar
6,715 Views
Registered: ‎04-07-2008

Here is my initialization function when I added writing to the wxs and rxs register I was able to

send as many times as I want.  I forgot to write a value to wxs register.

 

void VIRTEX5_DMADevicePrepare(VIRTEX5_DMA_HANDLE hDma, BOOL fIsRead, WORD wSize,

WORD wCount, UINT32 ddr2_address, UINT32 max_read_request_size )

{

UINT32 u32Pattern; // to be removed later

//UINT32 tlps;

UINT32 LowerAddr; // for read source, for write destination

//BYTE UpperAddr;

UINT32 UpperAddr; // for read source, for write destination

UINT32 returnvalue;

WDC_DEVICE_HANDLE hDev;

PVIRTEX5_DEV_CTX pDevCtx;

if (!IsValidDmaHandle(hDma, "VIRTEX5_DMADevicePrepare")) return;

hDev = hDma->hDev;

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAS_OFFSET, 0x00000000); //80 1

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAD_L_OFFSET, 0x00000000); //84 2

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAD_U_OFFSET, 0x00000000); //88 3

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARAS_L_OFFSET, 0x00000000); //8C 4

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARAS_U_OFFSET, 0x00000000); //90 5

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARAD_OFFSET, 0x00000000); //94 6

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWXS_OFFSET, 0x00000000); //98 7

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARXS_OFFSET, 0x00000000); //9C 8

//VIRTEX5_WriteReg32(hDev, VIRTEX5_RSVRD20_OFFSET, 0x00000000); //A0 9

//VIRTEX5_WriteReg32(hDev, VIRTEX5_RSVRD24_OFFSET, 0x00000000); //A4 10

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMACST_OFFSET, 0x00000000); //A8 11

//VIRTEX5_WriteReg32(hDev, VIRTEX5_RSRVD2C_OFFSET, 0x00000000); //AC 12

// for 512 200 hex

// for 4096 800 hex

// for 128 80 hex

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARXS_OFFSET, 0x00000800); //9C 13

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWXS_OFFSET, 0x00000800); //98 14

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAD_L_OFFSET, 0x00000000); //84 15

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARAS_L_OFFSET, 0x00000000); //8C 16

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAS_OFFSET, 0x00000000); //80 17

//VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARAD_OFFSET, 0x00000000); //94 18

LowerAddr = (UINT32)hDma->pDma->Page[0].pPhysicalAddr;

UpperAddr = (UINT32)(hDma->pDma->Page[0].pPhysicalAddr >> 32);

if (fIsRead)

{

// So is this destination or source I believe this would be source for a 64 bit address

// for read

// VIRTEX5_DMARAS_L_OFFSET = 0xc, //[31:0] dmaras_l DMA read address source lower regs 7'b000_1100

// VIRTEX5_DMARAS_U_OFFSET = 0x10, //[31:0] dmaras_u DMA read address source upper regs 7'b001_0000

// VIRTEX5_DMARAD_OFFSET = 0x14, //[31:0] dmarad DMA read address destination register 7'b001_0100

/* Set lower 32bit of DMA address */

//VIRTEX5_WriteReg32(hDev, VIRTEX5_RDMATLPA_OFFSET, LowerAddr);

// This Is PC MEMORY - Host Memory

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAD_L_OFFSET, LowerAddr); //84 19

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMARAS_L_OFFSET, LowerAddr); //8C 20

}

else

{

// FOR REFERENCE

//VIRTEX5_DMAWAS_OFFSET = 0x0, //[31:0] dmawas DMA write address source register 7'b000_0000

//VIRTEX5_DMAWAD_L_OFFSET = 0x4, //[31:0] dmawad_l DMA write address destinations lower regs 7'b000_0100

//VIRTEX5_DMAWAD_U_OFFSET = 0x8, //[31:0] dmawad_u DMA write address destinations upper regs 7'b000_1000

 //VIRTEX5_DMAWXS_OFFSET = 0x18, //[31:0] dmawxs DMA write transfer size register - can be up to 0x00100000 7'b001_1000

 

/* Set lower 32bit of DMA address (HOST MEMORY)*/

//VIRTEX5_WriteReg32(hDev, VIRTEX5_WDMATLPA_OFFSET, LowerAddr);

// Set lower Host Write Destination Address

// This Is PC MEMORY - Host Memory Lower Address

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAD_L_OFFSET, LowerAddr);

// Set Upper Host Addresses Write Destination Address

// This Is PC MEMORY - Host Memory Upper Address

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAD_U_OFFSET, UpperAddr);

// Set Write Address Source (DDR2 Memory)

//

VIRTEX5_WriteReg32(hDev, VIRTEX5_DMAWAS_OFFSET, ddr2_address); // ddr2 write address source

}

pDevCtx = (PVIRTEX5_DEV_CTX)WDC_GetDevContext(hDev);

pDevCtx->fIsRead = fIsRead;

u32Pattern = 0; // perhaps will remove this

pDevCtx->u32Pattern = u32Pattern;

pDevCtx->dwTotalCount = (DWORD)wCount * (DWORD)wSize;

}

0 Kudos
Anonymous
Not applicable
3,791 Views

Hi golson :
Thanks you code,I also do same research for PCIE and driver , my Email is wangxk@ihep.ac.cn ,Can you tell me you Email so that we can communicate with each other?
0 Kudos