Hello together,
I have a small example code working, using a major loop of 5, reading 4 Bytes every time by the minor loop.
For our application, I need a Major Loop with 65536 counts, reading 16 Bytes every time.
The problem: if I have no active linking, I have only 15 bits to define the CITER value.
I think I have to realize it by linking channels. But which registers I have to set up, in addtion to my small working example?
Thanks for any help!
Kind regards!
The Code:
#ifdef __arm__
// Set PORTF Pin for DMA Request
// DMA Request for rising edge; Port as GPIO;
PORTF->PCR[22] &= ~PORT_PCR_IRQC_MASK &~PORT_PCR_MUX_MASK;
PORTF->PCR[22] = PORT_PCR_IRQC(1) | PORT_PCR_MUX(1);
// Enable clock for DMAMUX and DMA
SIM->SCGC6 |= SIM_SCGC6_DMAMUX1_MASK;
SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
// Enable Channel 0 and set PORTF (FPGA_INT#2) as DMA request source
DMAMUX1->CHCFG[0] |= DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(53);
// Enable request signal for channel 0
DMA0->ERQ = DMA_ERQ_ERQ16_MASK;
// Set memory address for source and destination
DMA0->TCD[16].SADDR = FPGA_DMA_rdDMA;
DMA0->TCD[16].DADDR = DDR_ADRESS_START;
// Set an offset for source and destination address
DMA0->TCD[16].SOFF = 0x00; // Source address offset per transaction
DMA0->TCD[16].DOFF = 0x04; // Destination address offset per transaction
// Set source and destination data transfer size 32bit
DMA0->TCD[16].ATTR = DMA_ATTR_SSIZE(2) | DMA_ATTR_DSIZE(2);
// Number of bytes to be transfered in each service request of the channel
DMA0->TCD[16].NBYTES_MLNO = 0x04; // 4 Bytes pro Minor Loop
// Current major iteration count (a single iteration of 5 bytes)
DMA0->TCD[16].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(5);
DMA0->TCD[16].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(5);
// Adjustment value used to restore the source and destiny address to the initial value
DMA0->TCD[16].SLAST = 0x00; // Source address adjustment
DMA0->TCD[16].DLAST_SGA = -0x14; // Destination address adjustment
// Setup control and status register
DMA0->TCD[16].CSR = 0;
#else
#endif
Hi,
Attached you can find an example for CodeWarrior using Major Linking functionality of the DMA. Please refer to the code for more information. If you are not using CodeWarrior you can check the contents of the Source folder inside.
Hope this information can help you
Best Regards,
Adrian Sanchez Cano
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi,
thanks for the fast reply. But my problem still exists. I found this example already.
According to my understanding, the second TCD is triggered every time the first TCD finishes a major loop. So if I have four minor loops the second TCDs minor loops are only trriggered with every fourth Hardware-Trigger.
I tested this in the debugger:
ch1-Minor1 / ch1-Minor2 / ch1-Minor3 / ch1-Minor4 / ch2-Minor1 / ch1-Minor1 / ch1-Minor2 / ch1-Minor3 / ch1-Minor4 / ch2-Minor2 / ch1-Minor1...
But what I want to realize is, tha when the first channel has finished, the second channel starts:
ch1-Minor1 / ch1-Minor2 / ch1-Minor3 / ch1-Minor4 / ch2-Minor1 / ch2-Minor2 / ch2-Minor3 / ch2-Minor4 / ch1-Minor1 /...
I found a pdf (Examples of Setting the DMA Controller on the Power Architecure MPC5675K Family of Micrcontrolers, Rev. 1, 6/2012) where exactly this case is described.
How can I realize this? Or have I theroefore to use the Minor Loop linking?
Hello AnEngineer,
A new TCD is fetched every time a major loop is finished. As my understanding the DMA must works as you think. Please confirm that the CITER and BITER registers in the second TCD are not one (it would means that the major loop has only one minor loop).
If you have doubts about the minor and major loops please read the documents in this post.
Best regards,
Earl.