A DMA (Direct Me mory A ccess ) Co ntroller allows fas t data transfe rs betwe en mem ories without using the CPU. The transfer is activated by an external event. The control
signals and the address and data buses are managed by the DMA controller.
The AT91M40400 does not feat ure a DMA controll er as a per ipheral . Howeve r, it ca n
be implemented by softwar e by usin g the load mu ltiple (ldm) and s tore mul tiple (st m)
instructions (refer to the “ARM Architectural Reference Manual”).
This application note proposes two different ways to implement a software DMA using
the ARM Fast Interrupt (FIQ) as the external event. The code has been designed to
reduce the number of instruction fetches as much as possible.
AT91 Series
ARM
®
Thumb®
Microcontrollers
Application Note
Rev. 1169A–10/98
1
Page 2
Theory of Operation
The principle of DMA is that an external event causes a fast memory copy. In this case the external event is the Fast Interrupt pin (FIQ) since the FIQ mode on the ARM7TDMI
saved before b eing used in FIQ mod e. The se reg iste rs are i nitia lized befor e en abli ng th e FIQ inter rupt, then direc tly u sed
when the external event occurs.
This application note describe s two ways to impl ement a soft ware DMA. Both i mplemen tations ma ke the tran sfer by splitting the block to be transferred into packets of 4 words.
Note: In this document 1 packet = 4 words; 1 word = 4 bytes
DMA Turbo
•
DMA Channel
•
at each FIQ interrupt, thus freeing the core between packets.
As the FIQ interrupt is used, the DMA mus t be able to acce ss the ba nked regi sters. Thi s can only be done by swi tchin g to
FIQ mode and only if the CPU is i n p riv il eged s tate (any m ode ex ce pt User Mode). This app li ca tio n no te a ssumes that the
user function calls are per fo rmed while the CPU is in priv il eg ed sta te. It d oes no t d es crib e h ow to s wi tch fr om un priv il ege d
to privileged state. This can be done on another level by using the “swi” instruction of the ARM core or the Advanced Interrupt Controller features all owing an in terrupt entry to be forced . In the las t case, FIQ o r AIC’s softwa re interrup t can be
forced to set up software DMA.
Table 1.
FilesContents
dma _turb.sCode source for DMA Turbo
dma_chnl.sCode source for DMA channel
dma.hDMA prototypes and structures for application use
: Copies one packet (4 words) from a source buffer to a destination buffer at each FIQ interrupt.
: Copies the number of packets (4 words) de fined by the u ser from a so urce buffer to a destinat ion buffer
Source Files
™
processor has banked registers (r8 to r14) which do not need to be
arm.incARM core definition
DMA Turbo
The DMA Turbo allows 1 packet (4 words) to be transferred at each FIQ interrupt from a source buffer to a desti nation
buffer. Source and destination buffer pointers are post-incremented after each transfer.
The main advantage to this implementation is that no registers need to be saved. It is also a faster way to transfer data than
the DMA Channel implementation.
The functions used to manage the DMA Turbo are defined in
Table 3.
void DmaTurboSet (int *source, int *destination)Initialize the FIQ registers for the DMA transfer
void DmaTurboGet (int *source, int size)Check the end of the transfer
void DmaTurboFiq (void)FIQ treatment and DMA transfer
The
by clearing bit F in the CPSR.
DMA Turbo User Functions
DmaTurboSet
function initializes the FIQ banked registers for the DMA Turbo transfer, then enables the DMA transfer
void DmaTurboSet (int *source, int *destination)
source
destination
Begin
| Switch to FIQ mode and save entry mode
| Memorize source buffer pointer (r12_fiq = 'src_pt')
| Memorize destination buffer pointer (r13_fiq = 'dest_pt')
| Enable DMA (Clear bit F)
| Restore entry mode
End
the source buffer pointer
the destination buffer pointer
dma_turb.c
:
AT91 Series
DmaTurboGet
The
DMA transfer by setting bit F in the CPSR.
int DmaTurboGet (int * source, int size)
Begin
| Switch to FIQ mode and save entry mode
| Calculate number of transferred words
| Disable DMA (Clear bit F) if number of transferred words >= size
| Restore entry mode
End
DmaTurboFiq
The
nation buffer.
void DmaTurboFiq (void)
Begin
| *dest_pt <- *src_pt (multiple load and store 4 words with post increment)
End
function checks that the end of the transfer occurred (“size” words received), and, if it did, disables the
returns the number of words already received
source
size
the number of words to be copied
function is activated by the FIQ (vector address 0x1C), and copies 4 words from source buffer to desti-
the source buffer pointer at beginning
Alternate Implementation
The DMA Turbo can be modified to transfer more than 4 words per FIQ. For this, the pair of instructions “ldm” and “stm”
(refer to the “ARM A rchitec tural Re ferenc e Manu al”) m ust be r epeate d as m any tim es as necess ary. Di fferent ty pes o f
source and destination buffers can be supported by using the options of post/pre increment/decrement of these instructions.
It can also be modified to make the number of words to transfer defined by the caller. This has the advantage of allowing
the dynamic tran sfer s ize, b ut one reg iste r must be r eserv ed fo r the c ount (e.g. r11). Ther efore, o nly 3 regi ster s are avai lable for the transfer itself.
3
Page 4
DMA Channel
The DMA Channel implemen tation cop ies the number of packets ( 4 words) defined by the user at eac h FIQ interrupt un til
the remaining n umb er o f b yte s is le ss t han 1 pa ck et (4 words). These r em ain ing b yte s ar e trans fe rred a t the following FIQ
interrupt, and the DMA is stopped by disabling the FIQ.
One inconvenience of thi s implement ation is that no n-banke d registe rs are used. Theref ore, it is man datory to sa ve these
registers before the transfer, and to restore them afterwards.
The main advantage is that the size of the transfer is controlled, and there is no risk of overwriting the memory.
The block is copied fr om the source to the des tination by boun daries of pack ets. When no mor e whole packets ca n be
transferred, the remaining bytes (less than 16) are transferred in a way which optimizes the number of fetches:
• 2 words (8 to 15 remaining bytes)
• 1 word (4 to 7 remaining bytes)
• 1 half-word (2 or 3 r emaining bytes)
• 1 byte (1 byte remaining)
The user can choose to increase, after each FIQ copy, the source pointer, the destination pointer, both pointers or neither.
Table 4.
RegisterParameter
r14Link register - return address
r13Temporar y buffer address
r12Increment mask
r11Number of packets to copy per FIQ
r10Block size (byte numb er)
r9Destination address
r8Source address
r6 to r7Working registers (must be saved and restored)
r0 to r3Transfer registers (must be saved and restored)
Registers Used
4
AT91 Series
Page 5
AT91 Series
Type Definition
The DMA channel parameters are set through a structure named “dma_descriptor”. This type is defined in dma.h:
typedef struct dma_descriptor
{
u_char*src;// Source pointer
u_char*dest;// Destination pointer
u_intnb_bytes;// Total number of bytes to copy
u_intnb_packets; // Maximum number of packets to copy at each FIQ
u_intdma_mask;// DMA channel mask (INC_SRC and/or INC_DEST)
} dma_descriptor;
The user can choose whether or not to increase the source/destination pointers using the “dma_mask” field, the value of
which is an OR-combination of the constants INC_SRC and INC_DEST (These constants are defined in dma.h).
User Functions
The functions used to manage the DMA Channel are defined in
Table 5.
void DmaChannelSet (dma_descriptor *dma_desc, int *buf)Initialize the FIQ registers for the DMA transfer
void DmaChannelGet (void)Get the count of remaining bytes to be transferred
void DmaChannelFiq (void)FIQ treatment and DMA transfer
DMA Channel User Functions
dma_chnl.c
:
DmaChannelSet
The
void DmaChannelSet (dma_descriptor *dma_desc, int *buf);
Begin
| Switch to FIQ mode and save entry mode
| r13_fiq <- temporary buffer pointer
| Load banked registers from the DMA descriptor
| Set default number of packets to transfer (1) if not defined by user
| Enable DMA (Clear bit F) if number of bytes to transfer > 0
| Restore entry mode
End
DmaChannelGet
The
int DmaChannelGet(void)
Begin
| Switch to FIQ mode and save entry mode
| Return number of bytes remaining to be transferred
| Restore entry mode
End
function sets and enables the DMA Channel
dma_desc
buf
pointer to the DMA descriptor
temporary buffer (7*4 bytes needed) to store non-banked used registers
function returns the remaining number of bytes to be transferred
returns remaining number of bytes
5
Page 6
DmaChannelFiq
The
to the <destination> if possible.
function is activated by the FIQ (vector addr es s 0x1 C) , an d c opies r 11 x 4 words from the <sou rce>
void DmaChannelFiq (void)
Begin
| Save used registers in the temporary buffer
| Save source and destination
| While (nb_packets > 0) and (nb_bytes >= PACKET_SIZE)
| | Update nb_bytes by subtracting PACKET_SIZE from it
| | *dest <- *src (multiple load and store 4 words with post increment)
| | Decrement nb_packets
| EndWhile
| If (nb_packets == 0) (i.e. All blocks transferred)
| Then
| | === Copy last bytes to copy (< 16) ===
| | *dest <- *src
| | If needed, load and store multiple 2 words with post increment
| | If needed, load and store 1 word with post increment
| | If needed, load and store 1 half-word with post increment
| | If needed, load and store 1 byte with post increment
| | Clear nb_bytes
| | Disable DMA (SPSR.F <- 0)
| Endif
| Restore src (if not INC_SRC)
| Restore destination (if not INC_DEST)
| Restore used registers
End
Required Resources
Table 6.
ParameterValue
Code Size20 words
Register UsageR8 to R14 (banked FIQ
Peripheral UsageFIQ Interrupt
Table 7.
ParameterValue
Code Size51 words
Register UsageR8 to R14 (banked FIQ
Peripheral UsageFIQ Interrupt
DMA Turbo
registers)
DMA Channel
registers)
6
AT91 Series
Page 7
AT91 Series
Tips and Warnings for Both Types of DMA Implementation
Pointer Alignment
Source and destinati on p oin ter s mus t al way s be wor d- alig ned bec au se o f the us e of l oad and s to re mul tip le i ns truc tio ns . 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 desc r ibed i n thi s a ppl ication note performs th e t rans fer of the pa ck et(s ) at the FIQ interrupt, it is n eces sa ry
to pace the FIQ at a rate defined by the application.
This application note do es not describe how to g ene rate t he r at e, b ut i t c an eas il y be done by usi ng a ti mer chan nel wh ic h
is cyclically tri ggered to generat e a tick. An FIQ is then gene rated on each tick. The FIQ can be gen erated by configu ring
source 0 to be edge triggered, and by setting bi t 0 in the AIC_ISCR register to one (0x0 0000001). The port P1 2, multiplexed 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
rary buffer can also be performed by a stack management. In this case, the function
descriptor as a call parameter.
DmaChannelFiq
DmaChannelSet
. Of course, this tempo-
needs only the DMA
Pointer Incrementation
If the source and destination pointers are systematically incremented during the transfer, the command word with the
pointer management mask
tion pointers is also useles s and the registe rs
used, the regis ter
R11
which must be restored).
This way only registers
word-sized.
R12
ptrMask
is also unused in the fun ction
R0
to R3 in the function
is useless. In this case, the saving and conditional restoring of the source and destina-
R6
and R7 are unused in th e func tion
DmaChannelFiq
DmaChannelFiq
and can be used as the pa cket cou nter ( in place of
must be saved, and the tem porary buffer can be only 4-
DmaChannelFiq
. As the mask is not
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
R6
size of the temporary buffer.
whole non-banked registers (
however when restoring
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