22.6.2.4 Arbitration
If a DMA channel is enabled and not suspended when it receives a transfer trigger, it will send a transfer request to the arbiter. When the arbiter receives the transfer request it will include the DMA channel in the queue of channels having pending transfers, and the corresponding Pending Channel x bit in the Pending Channels registers (PENDCH.PENDCHx) will be set. Depending on the arbitration scheme, the arbiter will choose which DMA channel will be the next active channel. The next transfer descriptor will be fetched from SRAM memory and stored internally in the Pre-Fetch Channel. The active channel is the DMA channel being granted access to perform its next burst transfer. When the Active Channel has completed a burst transfer, the descriptor stored in the Pre-Fetch Channel is transferred to the Active Channel and a new burst will take place.
When the descriptor stored in the Pre-Fetch Channel is transferred to the Active Channel,
the corresponding PENDCH.PENDCHx will be cleared. In the same way, depending on trigger
action settings and if the upcoming burst transfer is the first for the transfer request or
not, the corresponding Busy Channel x bit in the Busy Channels register (BUSYCH.BUSYCHx),
will either be set or remain ‘1
’. When the channel has performed its
granted burst transfer(s) it will be either fed into the queue of channels with pending
transfers, set to be waiting for a new transfer trigger, suspended, or disabled. This
depends on the channel and block transfer configuration. If the DMA channel is set to wait
for a new transfer trigger, suspended or disabled, the corresponding BUSYCH.BUSYCHx will be
cleared.
If a DMA channel is suspended while it has a pending transfer, it will be removed from the queue of pending channels, but the corresponding PENDCH.PENDCHx will remain set. The status will also be indicated in CHINTFLAGn.SUSP. When the same DMA channel is resumed, it will be added to the queue of pending channels again.
If a DMA channel gets disabled
(CHCTRLA.ENABLE=0
) while it has a pending transfer, it will be removed
from the queue of pending channels, and the corresponding PENDCH.PENDCHx will be
cleared.
Priority Levels
When a channel level is pending or the channel is transferring data, the corresponding Level Executing bit is set in the Active Channel and Levels register (ACTIVE.LVLEXx).
Each DMA channel supports up to 4-level priority scheme.
The priority level for a channel is configured by writing to the
Channel Arbitration Level bit group in the Channel Priority Level register
(CHPRILVL.PRILVL). As long as all priority levels are enabled, a channel with a higher
priority level number will have priority over a channel with a lower priority level number.
A priority level is enabled by writing the Priority Level x Enable bit in the Control
register (CTRL.LVLENx) to ‘1
’, for the corresponding level.
Within each priority level, the DMAC's
arbiter can be configured to prioritize statically or dynamically. For the arbiter to
perform static arbitration within a priority level, the Level X Round-Robin Scheduling
Enable bit in the Priority Control x register (PRICTRL0.RRLVLENx) has to be written to
‘0
’. When static arbitration is enabled (PRICTRL0.RRLVLENx is
‘0
’), the arbiter will prioritize a low channel number over a high
channel number as shown in the following figure. When using the static scheme, there is a
risk of high channel numbers never being granted access as the active channel. This can be
avoided using a dynamic arbitration scheme.
The dynamic arbitration scheme in the DMAC
is round-robin. Round-robin arbitration is enabled by writing PRICTRL0.RRLVLEN to
‘1
’, for a given priority level x. With the round-robin scheme, the
channel number of the last channel being granted access will have the lowest priority the
next time the arbiter has to grant access to a channel within the same priority level, as
shown in the following figure. The channel number of the last channel being granted access
as the active channel is stored in the Level x Channel Priority Number bit group in the
Priority Control 0 register (PRICTRL0.LVLPRIx) for the corresponding priority level.