Enhanced Direct Memory Access (eDMA)
MPC5606S Microcontroller Reference Manual, Rev. 7
Freescale Semiconductor 475
for (number_of_dest_writes) {
write_to_amba-ahb (dma_engine.daddr, dest_xfr_size) = dma_engine.data;
/* generate the next-state destination address */
/* sum the current daddr with the signed destination offset */
ns_addr = dma_engine.daddr + (int) dma_engine.doff;
/* if enabled, apply the power-of-2 modulo to the next-state dest addr */
if (dma_engine.dmod != 0)
address_select = (1 << dma_engine.dmod) - 1;
else
address_select = 0xffff_ffff;
dma_engine.daddr = ns_addr & address_select
| dma_engine.daddr & ~address_select;
}
if (cancel_transfer)
break;
/* check for a higher priority channel to service if: */
/* 1) preemption is enabled */
/* 2) in fixed arbitration mode */
/* 3) a higher priority channel is requesting service */
/* 4) not already servicing a preempting channel */
if ((DCHPRIn.ecp = 1) & fixed_arbitration_mode
higher_pri_request & ~current_channel_is_preempt)
service_preempt_channel;
/* the bandwidth control field determines when the next read/write occurs */
if (dma_engine.bwc > 1)
stall_dma_engine (1 << dma_engine.bwc);
/* decrement the minor loop byte count */
dma_engine.nbytes = dma_engine.nbytes - xfr_size;
}while (dma_engine.nbytes > 0) /* end of minor inner loop */
dma_engine.citer--; /* decrement major loop iteration count */
/* if the major loop is not yet exhausted, update certain TCD values in the RAM */
if (dma_engine.citer != 0) {
write_to_local_memory [channel].saddr = dma_engine.saddr;
write_to_local_memory [channel].daddr = dma_engine.daddr;
write_to_local_memory [channel].citer = dma_engine.citer;
/* if minor loop linking is enabled, make the channel link */
if (dma_engine.citer.e_link)
TCD[citer.linkch].start = 1; /* specified channel service req */
/* check for interrupt assertion if half of the major iterations are done */
if (dma_engine.int_half && (dma_engine.citer == (dma_engine.biter >> 1)))
generate_interrupt (channel);
dma_engine.active = 0; /* clear the channel busy flag */
}
else { /* major loop is complete, dma_engine.citer == 0 */