02-02-2009 11:29 AM
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.
02-03-2009 06:28 PM
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.
02-04-2009 02:36 PM
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 lowVIRTEX5_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.
02-11-2009 10:21 AM
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;
}
12-08-2012 08:05 AM