My team and I are working on setting up Basic Direct External DMA transfers on the T1024RDB. However, we are thus far unable to successfully setup the external DMA transactions. Our issue/procedure is as follows:
1. We set up the DMA controller for external control as shown in our code below
2. We initiate a DMA transfer sequence by asserting the DREQ signal from high to low.
3. The MR register responds to the DREQ signal and goes from 0 to 1 (as it should)
4. A DACK signal is generated by the DMA controller
5. DREQ returns to a high state.
6. A DMA transfer occurs from our source address to destination address with the amount of data specified in the BCR register
7. The MR register does not reset back to 0
8. The SR register Programming Error bit is set to 1
9. DREQ asserts back to a low state again to initiate another DMA transfer sequence
10. No DACK signal is generated by the DMA controller and the DREQ signal stays low as a result
According to the T1024RDB reference manual, a programming error can occur as a result of one of the following:
• Transfer started with a byte count of zero
• Stride transfer started with a stride size of zero
• Illegal type, defined by SATRn[SREADTTYPE] and DATRn[DWRITETTYPE],
used for the transfer.
We have our byte count set to a non zero value, striding turned off, and we have tried all the available options for SATRn[SREADTTYPE] and DATRn[DWRITETTYPE] defined in the T1024RDB reference manual. At this point we are a bit stuck as to what is causing our programming error and preventing further DMA transactions.
Any help would greatly be appreciated. I have included our setup below:
We first initialize the SATR, SAR, DATR, DAR, and BCR registers. Then I set the MR0 register. After setting the MR0 register we cause the DREQ signal to change state from high to low.
RCW:
AA 55 AA 55 01 0E 01 00 08 10 00 0E 00 00 00 00
00 00 00 00 00 00 00 00 4A 80 00 03 80 00 00 12
EC 02 70 00 21 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 07 08 00 00 00 00 00 0B 00 5A 08
00 00 00 00 00 00 00 06 08 13 80 40 55 FA 19 3A
MR0
mrType temp_DMA1_MR0;
temp_DMA1_MR0.bwc = 0x8; // bandwidth sharing
temp_DMA1_MR0.emp_en = 0; // enable external master pause
temp_DMA1_MR0.ems_en = 1; // enable channel from being started by an external DMA start pin
temp_DMA1_MR0.dahts = 0; // 1 byte destination hold transfer size
temp_DMA1_MR0.sahts = 0; // 1 byte source hold transfer size
temp_DMA1_MR0.dahe = 0; // disable destination address hold
temp_DMA1_MR0.sahe = 0; // disable source address hold
temp_DMA1_MR0.srw = 0; // normal operation
temp_DMA1_MR0.eosie = 0; // do not generate an interrupt upon completion of data transfer
temp_DMA1_MR0.eolnie = 0; // do not generate an interrupt upon completion of a list of DMA transfers
temp_DMA1_MR0.eolsie = 0; // do not generate an interrupt upon completion of all DMA transfers
temp_DMA1_MR0.eie = 0; // do not generate an interrupt if a programming or transfer error is detected
temp_DMA1_MR0.xfe = 0; // basic mode - disables striding feature in direct mode
temp_DMA1_MR0.cdsm_swsm = 0; // enable write to source address register to start transfer
temp_DMA1_MR0.ca = 0; // no effect
temp_DMA1_MR0.ctm = 1; // Configure channel for direct mode
temp_DMA1_MR0.cs = 0; // signal set DREQ
temp_DMA1_MR0.cc = 0; // no effect
DMA1_MR0->word = temp_DMA1_MR0.word;
SATR, SAR, DATR, DAR, BCR
unsigned int srceAddrUpper = 0x0; // Upper Source Address Bits
unsigned int srceAddrLower = 0x80000000; // Lower Source Address Bits
unsigned int destAddrUpper = 0x0; // Upper Destination Address Bits
unsigned int destAddrLower = 0x50000000; // Lower Destination Address Bits
unsigned int byteCount = 256; // byteCount
// Initialize Source Attribute Register - Channel 0
satrType temp_DMA1_SATR0;
sarType temp_DMA1_SAR0;
temp_DMA1_SATR0.ssme = 0; // disable stride mode
temp_DMA1_SATR0.sreadttype = 0x4; // read, do not snoop local processor
// Initialize Source Address
temp_DMA1_SATR0.esad = srceAddrUpper;
temp_DMA1_SAR0.sad = srceAddrLower;
// Initialize the Source Address
DMA1_SATR0->word = temp_DMA1_SATR0.word;
DMA1_SAR0->word = temp_DMA1_SAR0.word;
// Initialize Destination Attribute Register - Channel 0
datrType temp_DMA1_DATR0;
darType temp_DMA1_DAR0;
temp_DMA1_DATR0.nlwr = 1; // write without response
temp_DMA1_DATR0.dsme = 0; // disable stride mode
temp_DMA1_DATR0.dwritettype = 0x4; // write, do not snoop local processor
// Initialize Destination Address
temp_DMA1_DATR0.edad = destAddrUpper;
temp_DMA1_DAR0.dad = destAddrLower;
DMA1_DATR0->word = temp_DMA1_DATR0.word;
DMA1_DAR0-> word = temp_DMA1_DAR0.word;
// set byte size
DMA1_BCR0->bc = byteCount;
I should mention we have also tried doing an external DMA transfer using the same setup, but changing the source address to the RAM part installed on the T1024RDB. So our source and destination were both in RAM. I should mention that we have successfully set up this basic direct DMA transfers (non external) with our setup. We have only had issues once we started trying to do external DMA transfers.
Please try to use MR[BWC]=0x8
I have already tried MR[BWC] =0x8 with the same result. I also have tried different settings stride size and length, and transfer hold size.
The issue seems to be connected with the PCIe operation.
Have you also tried MR[BWC] =0x7?
Yes, I have tried 0x7 as well as many other sizes in the MR[BWC] register. I have tried doing DMA transfers from RAM to RAM, so no PCIe in the loop, and I still had the issue. So I am not sure it is related to PCIe operation.
Please use a digital scope to capture behaviour of DREQ, DACK and DONE signals near the processor's pins and provide the trace for inspection.
How exactly you have reworked the the T1024RDB to use the DMA control signals?
Please provide the DMA registers dumps:
1) before the transfer
2) after the transfer
What are the source and the destination memories?
Hi, here are the register dumps for DMA1 Channel 0
Registers after setting up MR register for external mode, but before asserting DREQ low (before problem)
DMA1_MR0 = 0x09040004
DMA1_SR0 = 0x00000000
DMA1_ECLNDAR0 = 0x00000000
DMA1_CLNDAR0 = 0x00000000
DMA1_SATR0 = 0x00040000
DMA1_SAR0 = 0x80000000
DMA1_DATR0 = 0x40040000
DMA1_DAR0 = 0x50000000
DMA1_BCR0 = 0x00000100
DMA1_ENLNDAR0 = 0x00000000
DMA1_NLNDAR0 = 0x00000000
DMA1_ECLSDAR0 = 0x00000000
DMA1_CLSDAR0 = 0x00000000
DMA1_ENLSDAR0 = 0x00000000
DMA1_NLSDAR0 = 0x00000000
DMA1_SSR0 = 0x00000fff
DMA1_DSR0 = 0x00000fff
Registers after asserting DREQ low (after problem)
DMA1_MR0 = 0x09040005
DMA1_SR0 = 0x00000010
DMA1_ECLNDAR0 = 0x00000000
DMA1_CLNDAR0 = 0x00000000
DMA1_SATR0 = 0x00040000
DMA1_SAR0 = 0x80000100
DMA1_DATR0 = 0x40040000
DMA1_DAR0 = 0x50000100
DMA1_BCR0 = 0x00000000
DMA1_ENLNDAR0 = 0x00000000
DMA1_NLNDAR0 = 0x00000000
DMA1_ECLSDAR0 = 0x00000000
DMA1_CLSDAR0 = 0x00000000
DMA1_ENLSDAR0 = 0x00000000
DMA1_NLSDAR0 = 0x00000000
DMA1_SSR0 = 0x00000fff
DMA1_DSR0 = 0x00000fff
What are the source and the destination memories?
Sorry about that.
Source Address: 0x80000000
Destination Address: 0x50000000
Transfer Size = 256 bytes
What are the source and the destination physical memories (interfaces)?
Is the DMA test running on bare board?
Our source destination is RAM on an FPGA connected via PCIe.
Our destination is RAM located on the T1024RDB RAM.
I am not sure exactly what you mean by the DMA test running on bare board, we are using the T1024RDB platform.