Datasheet AT91 Datasheet (Atmel)

Page 1
Software DMA Implementation

Introduction

A DMA (Direct Me mory A ccess ) Co ntroller allows fas t data transfe rs betwe en mem o­ries 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 Inter­rupt 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 split­ting 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 Inter­rupt 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.
Files Contents
dma _turb.s Code source for DMA Turbo dma_chnl.s Code source for DMA channel dma.h DMA 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.inc ARM 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.
Table 2.
Register Parameter
r14 Link register - return address r13 ‘dest_pt’ = Destination buffer pointer r12 ‘src_pt’ = Source buffer pointer r8 to r11 Transfer registers
Registers Used
2
AT91 Series
Page 3

User Functions

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 instruc­tions.
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 l­able 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.
Register Parameter
r14 Link register - return address r13 Temporar y buffer address r12 Increment mask r11 Number of packets to copy per FIQ r10 Block size (byte numb er) r9 Destination address r8 Source address r6 to r7 Working registers (must be saved and restored) r0 to r3 Transfer 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_int nb_bytes; // Total number of bytes to copy u_int nb_packets; // Maximum number of packets to copy at each FIQ u_int dma_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.
Parameter Value
Code Size 20 words Register Usage R8 to R14 (banked FIQ
Peripheral Usage FIQ Interrupt
Table 7.
Parameter Value
Code Size 51 words Register Usage R8 to R14 (banked FIQ
Peripheral Usage FIQ 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, 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 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
This is coded by:
ands r0, r10, #0x10 ldmneia r8!, {r0-r3} stmneia r9!, {r0-r3}
R8
and R7 are used onl y t o sav e R8 and R9. This can be done in th e tempor ary buffe r, and
R0
and R7) can be used for the transfer in the function
and R9).
DmaChannelFiq
(care must be taken
7
Loading...