
AT91 Series
7
Tips and Warnings for Both Types of DMA Implementation
Pointer Alignment
Source and destination pointers must always be word-aligned because of the use of load and store multiple instructions. If
this is not the case, a word-alignment must be performed, using an “AND” with the existing word in the memory to copy the
first non-aligned bytes.
FIQ Rate
Since the DMA described in this application note performs the transfer of the packet(s) at the FIQ interrupt, it is necessary
to pace the FIQ at a rate defined by the application.
This application note does not describe how to generate the rate, but it can easily be done by using a timer channel which
is cyclically triggered to generate a tick. An FIQ is then generated on each tick. The FIQ can be generated by configuring
source 0 to be edge triggered, and by setting bit 0 in the AIC_ISCR register to one (0x00000001). The port P12, multi-
plexed with FIQ, should be configured as a PIO in order to prevent the FIQ from being generated by an external event.
Another way is to configure the port P12 as a peripheral, and to make the external hardware generate the FIQ which can be
configured to be edge or level triggered.
In any case, the source 0 (FIQ) of the AIC must be configured (register AIC_SMR0) and enabled (register AIC_IECR).
Tips and Warnings for DMA Channel Implementation
Temporary Buffer
This application does not implement a stack management to save the registers. For this reason, a temporary buffer has
been chosen in order to save and restore the non-banked registers in the function DmaChannelFiq. Of course, this tempo-
rary buffer can also be performed by a stack management. In this case, the function DmaChannelSet needs only the DMA
descriptor as a call parameter.
Pointer Incrementation
If the source and destination pointers are systematically incremented during the transfer, the command word with the
pointer management mask
ptrMask
is useless. In this case, the saving and conditional restoring of the source and destina-
tion pointers is also useless and the registers
R6
and
R7
are unused in the function DmaChannelFiq. As the mask is not
used, the register
R12
is also unused in the function DmaChannelFiq and can be used as the packet counter (in place of
R11
which must be restored).
This way only registers
R0
to
R3
in the function DmaChannelFiq must be saved, and the temporary buffer can be only 4-
word-sized.
Large Sized Blocks
If the blocks to transfer are significant (more than 15 words), the use of the registers can be optimized by increasing the
size of the temporary buffer.
R6
and
R7
are used only to save
R8
and
R9
. This can be done in the temporary buffer, and
whole non-banked registers (
R0
and
R7
) can be used for the transfer in the function DmaChannelFiq (care must be taken
however when restoring
R8
and
R9
).
The temporary buffer becomes 11 words (if optional increment feature is used), but the packets transferred are 8-words
(PACKET_SIZE).
It is necessary to add a 4-word conditional transfer before the 2-word transfer:
| | | *dest <- *src (load and store multiple 4 words with post
| | | increment) if needed
This is coded by:
ands r0, r10, #0x10
ldmneia r8!, {r0-r3}
stmneia r9!, {r0-r3}