Transcript Chapter 5

Chapter 5
Enhanced Direct Memory Access
(EDMA)
DSK 1-day Workshop Student Guide
TMS320C6000 Peripherals (207-289)
Learning Objectives



The need for a DMA (EDMA).
Terms and definitions (with examples).
EDMA functionality, including:




Programming the EDMA, including:


Chapter 5, Slide 2
Transfer modes and synchronisation.
EDMA interrupt.
Quick DMA (QDMA).
Using the Chip Support Library (CSL).
Example “inout” program using Ping-Pong
EDMA.
The Need for a DMA

There are two methods for transferring data
from one part of the memory to another, these
are using:
(1) CPU.
(2) DMA.

Chapter 5, Slide 3
If a DMA is used then the CPU only needs to
configure the DMA. Whilst the transfer is
taking place the CPU is then free to perform
other operations.
How can we Improve System?
DSK
HWI
CPU
McBSP
DAC
CPU must:



Chapter 5, Slide 4
Generate sine wave samples
Respond to McBSP interrupt
Send data to codec (via McBSP)
How can we improve system performance?
Block Processing with EDMA
DSK
CPU
Buffer
McBSP
EDMA
DAC
CPU

Generates buffer of samples at a time
EDMA


Handles McBSP interrupt, reduces CPU int. overhead
Sends data to codec
If EDMA handles the McBSP event,
how does the CPU know when to run?
Chapter 5, Slide 5
Use EDMA
DSK
CPU
Buffer
McBSP0
EDMA


Chapter 5, Slide 6
EDMA
interrupt
XEVT0
event
8KHz  buffersize
8KHz
DAC
EDMA interrupt tells CPU when to run
Reduces CPU interrupts by factor of buffersize
How does the EDMA work?
Introduction to the EDMA


The ‘C6416 on-chip EDMA controller allows
data transfers between the level two (L2)
cache memory controller and the device
peripherals.
These transfers include:




Chapter 5, Slide 7
Cache servicing.
Non-cacheable memory accesses.
User programmed data transfers.
Host accesses.
EDMA Interface

The C621x/C671x/C641x Block diagram.
The EDMA allows data transfer to/from any addressable memory spaces.
Chapter 5, Slide 8
EDMA Functionality



Chapter 5, Slide 9
The data transfer is performed with zero
overhead.
It is transparent to the CPU which means that
the EDMA and CPU operations can be
independent.
However, if the EDMA and CPU both try to
access the same memory location arbitration
will be performed by the program memory
controller.
EDMA Functionality
Source
mem1
A0
A1
A2
A3
A4
A5
EDMA
Options
Source
Destination
Xfr Count
Chapter 5, Slide 10
Destination
mem2
A5
A4
A3
A2
A1
A0
A0
A1
A2
A3
A4
A5
What information is needed
by the EDMA
to perform transfers?
EDMA Overview
EDMA
Channel 0
Channel 1



16 channels
Stores parameters for 69 more transfer config’s
Per channel: high/low priority, else round-robin
Channel 2
...
Options
15
Source
Reload 1
Transfer Count
Reload 2
Destination
...
Reload 69
Chapter 5, Slide 11
Index
Count Reload†
Link Addr†
31
16 15
0
EDMA Overview
EDMA
Enhanced DMA
Channel 0

Channel 1


16 channels
Stores parameters for 69 more transfer config’s
Per channel: high/low priority, else round-robin
Channel 2
...
Options
15
Source
Reload 1
Transfer Count
Reload 2
Destination
Index
...
Count Reload†
Link Addr†
31
16 15
0
Reload 69
QDMA
Quick-DMA


Chapter 5, Slide 12

Additional DMA channel
Higher priority
Less transfer overhead


No sync capability
Can’t autoinit
(no † registers)
EDMA Features

The ‘C6416 on-chip EDMA controller has the
following features:



Chapter 5, Slide 13
16 channels.
1 auxiliary channel dedicated for the HPI (not
accessible to the user).
1 Quick DMA (QDMA).
EDMA Channel Priorities

The ‘C6416 EDMA channels have two
programmable levels of priority (Level 0
reserved only for the L2).
Options
(PRI 31:29) Priority Level
000b
Level 0: Urgent
001b
Level 1: High
010b
Level 2: Low
011-111b
Reserved
Requestors
L2 Controller *
EDMA, QDMA, HPI
EDMA, QDMA
* Requests from CPU/L1 and L2 controller
Chapter 5, Slide 14
EDMA Performance


The ‘C6211/C6711 EDMA can perform
element transfers with single-cycle throughput
provided there is no conflict.
The following conditions can limit the
performance:


Chapter 5, Slide 15
EDMA stalls when there are multiple transfer
requests on the same priority level.
EDMA accesses to L2 SRAM with lower priority
than the CPU.
EDMA - How much to move
Block
Frame
The smallest piece of information
Frame 1
Elem 1
transferred by the EDMA is called...
Frame 2
Element
Elem 2
ESIZE
.
.
.
.
00: 32-bits
01: 16-bits
10: 8-bits
11: rsvd
Elem N
Frame M
Options
Source
Transfer Count
Destination
Index
Cnt Reload Link Addr
31
0
28 27
ESIZE
# Frames
31
16 15



Chapter 5, Slide 16
# Elements
N
= Element count (ELECNT).
M
= Frame count (FRMCNT).
See SPRU190 page 6-5 for more.
0
How the EDMA Works

The EDMA has a parameter RAM composed
of:

Channel parameters.

Reload channel parameters.
Parameter RAM
Channel 0
Options
Channel 1
Source
...
Channel 15
Transfer Count
Reload 0
Index
Reload 1
Count Reload
Link Addr
31
16 15
0
...
Reload 69
Chapter 5, Slide 17
Destination
EDMA: Linking Transfers
Channel 0
Channel 1
Channel 2
...
15
Reload 1
Options
Source
Transfer Count
Destination
Index
Count Reload
Link Addr
31
16 15
0
Reload 2
...
Reload 69




Offloads CPU ... can reinitialize EDMA all channel registers
Next transfer configuration specified by Link Address
Perform simple re-initialization or create linked-list of events
Useful for ping-pong buffers, data sorting, circular buffers, etc.
Chapter 5, Slide 18
How the EDMA Works

The EDMA has a parameter RAM composed
of:





Chapter 5, Slide 19
Channel parameters.
Reload channel parameters.
The user programs both channel and reload
channel parameters.
The channel parameters contain all the
information needed for the EDMA in order to
perform a transfer.
When a transfer is complete the channel
parameters are reloaded from the corresponding
reload channel.
EDMA Parameters

The parameters in the parameter table need to
be determined before the EDMA can be
programmed.
Options
Source
Transfer Count
Destination
Index
Count Reload
Link Addr
31
16 15
0
Chapter 5, Slide 20
EDMA Parameters (Options)
31
29 28
PRI
27
ESIZE
26
25
2DS
24
SUM
23
2DD
22
21
DUM
20
TCINT
19
16 15
TCC
2
RSVD
EDMA Channel Options Register
Bit Field
Label
31:29
PRI
28:27
Priority levels for the EDMA event
ESIZE Element size (32/16/8-bit)
26
2DS
Source dimension
25:24
SUM
Source address update mode
23
2DD
Destination dimension
22:21
DUM
Destination address update mode
20
19:16
1
0
Chapter 5, Slide 21
Description
TCINT Transfer complete interrupt enable
TCC
Transfer complete code
LINK Link
FS
Frame synchronisation
1
0
LINK
FS
EDMA Parameters (Options)
Chapter 5, Slide 22
EDMA Parameters (Options)
Chapter 5, Slide 23
EDMA Parameters


Source: Start address of the source.
Transfer Count:



Chapter 5, Slide 24
Upper 16 bits [31:16]: Frame count.
Lower 16 bits [15:0]: Element count.
Destination: Start address of the destination.
EDMA Parameters

Index:




Chapter 5, Slide 25
Upper 16 bits [31:16]: Frame index.
Lower 16 bits [15:0]: Element index.
Count reload: Value to be reloaded into the
element count when a frame is complete (only
used in 1-D mode).
Link address: Specifies the address from where
the parameters are reloaded. The 16-bit value
is added to 0x01A0 xxxx to form the 32-bit
address.
EDMA Synchronization

Two methods for initiating a transfer:
(1)
CPU initiated.
This is known as unsynchronized EDMA. With
this method the CPU writes to the Event Register
(ER) through the Event Set Register (ESR) in
order to start the EDMA transfer (this can be
used to simulate an event).
Chapter 5, Slide 26
EDMA Synchronization

Two methods for initiating a transfer:
(1)
(2)
CPU initiated.
Event triggered.
In this case the event is latched in the Event
Register (ER) which then triggers the transfer.
The events that can trigger a transfer are given
on the following slide.
Chapter 5, Slide 27
EDMA Synchronization - CPU initiated
Sync event
Event Register
Event Enable Register
Event Set Register
1
Start Channel 2 transfer
Event Clear Register
Chapter 5, Slide 28
EDMA Synchronization - Event triggered
Sync event
Event Register
1
Enable Channel 2
Event Enable Register
1
Start Channel 2 transfer
Event Set Register
Event Clear Register
Chapter 5, Slide 29
EDMA Synchronization - Event trigger Disable
Sync event
Event Register
10
Disable Channel 2
Event Enable Register
0
Event Set Register
No transfer
Clear event bit
Event Clear Register
1
Chapter 5, Slide 30
EDMA Events
Channel
Event
0
DSPINT
1
TINT0
2
TINT1
3
SD_INT
4
EXT_INT4
5
EXT_INT5
6
EXT_INT6
7
EXT_INT7
8
EDMA_TCC8
9
EDMA_TCC9
10
EDMA_TCC10
11
EMDA_TCC11
12
XEVT0
13
REVT0
14
XEVT1
15
REVT1

Chapter 5, Slide 31
Event Description
Host port host to DSP interrupt
Timer 0 interrupt
Timer 1 interrupt
EMIF SDRAM timer interrupt
External interrupt pin 4
External interrupt pin 5
External interrupt pin 6
External interrupt pin 7
EDMA transfer complete code 1000b interrupt
EDMA TCC 1001b interrupt
EDMA TCC 1010b interrupt
EDMA TCC 1011b interrupt
McBSP0 transmit event
McBSP0 receive event
McBSP1 transmit event
McBSP1 receive event
An event can be cleared using the CPU by writing
to the Event Clear Register (ECR).
Transfer Synchronization


The synchronization mode depends on whether
or not the transfer is two dimensional.
Therefore first specify that the transfer is
either 1-D or 2-D.
26
23
2DS
2DD
Options Register
Destination dimension
Source dimension


Chapter 5, Slide 32
0b = 1 dimensional
1b = 2 dimensional
1-D Synchronisation


There are two modes of synchronisation in the
1-D transfer mode.
These are:



Chapter 5, Slide 33
Element synchronized: each event causes one
element to be transferred.
Frame synchronized: each event causes a whole
frame to be transferred.
The FS bit is used to specify the
synchronization mode.
1-D Transfer Synchronization

Element synchronized (FS=0):




In this case the EDMA transfers each element after
receiving the synchronization event until the whole
frame is transferred.
The element count is then reloaded and the frame
count decremented.
The frame index is then added to the last element
address to calculate the next frame start address.
If the link is enabled (LINK=1b) then the transfer
parameters are reloaded.
0
FS Options Register
Chapter 5, Slide 34
Example: 1-D Transfer with FS=0
Source
Destination
8-bit Pixels
SRC:
1 2 3 4 5 6
7 8 9 10 11 12
DST:
13 14 15 16 17 18
Sync event
19 20 21 22 23 24
8
9
10
11
25 26 27 28 29 30
8 bits





ESIZE = 10b
ELECNT = 4
FRMCNT = 0
SUM = 01b








Chapter 5, Slide 35
00b = 32-bits
01b = 16-bits
10b = 8-bits
11b = Reserved
FRMCNT = M - 1
00b = Fixed
01b = Increment
10b = Decrement
11b = Modified by INDEX
Example: 1-D Transfer with FS=0
Source
Destination
8-bit Pixels
SRC:
1 2 3 4 5 6
8
9
10
11
DST:
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
8 bits
ESIZE
10
Options
Source = SRC+7
FRMCNT = 0
ELECNT = 4
Destination = DST
FRMIDX
ELEIDX
Count Reload
Link Addr
31
16 15
0
Chapter 5, Slide 36
Example: 1-D Transfer with FS=0
Source
Destination
8-bit Pixels
SRC:
Sync event
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
DST:
6
10
14
18
22
21 22 23 24
25 26 27 28




8 bits
ESIZE = 10b (8-bits)
ELECNT = 5, FRMCNT = 0
SUM = 11b
ELEIDX = 4
In this mode:
Next frame addr = Last element addr + FRMIDX
Chapter 5, Slide 37
1-D Transfer Synchronisation

Frame synchronized (FS=1):




Chapter 5, Slide 38
In this case the EDMA transfers a whole frame
after receiving the synchronization event.
In this mode the frame index no longer represents
the difference between the address of the last
element of the frame and the start address of the
next frame.
The frame index is added to the start address of the
frame to derive the start address of the next frame.
See the example on the following slide.
Example: 1-D Transfer with FS=1
Source
Destination
16-bit Data
SRC:
Sync event
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49
DST:
8
10
12
16
...
36
40
42
44
...
16 bits


All elements in a frame are offset by ELEIDX bytes.
All frames in a block are offset by FRMIDX bytes.
Chapter 5, Slide 39
Example: 1-D Transfer with FS=1
Source
Destination
16-bit Data
SRC:
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49





ESIZE = 01b (16bits)
ELECNT = 3
FRMCNT = 4
SUM = 11b, 2DS = 0, FS = 1
FRMIDX = 16, ELEIDX = 4
DST:
8
10
12
16
...
36
40
42
44
16 bits
In this mode:
Next frame addr = First element addr + FRMIDX
Chapter 5, Slide 40
Example: 1-D Transfer with FS=1
Source
Destination
8-bit Pixels
SRC:
Sync event
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30





Chapter 5, Slide 41
ESIZE = 10b
ELECNT = 2
FRMCNT = 2
SUM = 01b, 2DS =0b, FS = 1
FRMIDX = 12, ELEIDX = 2
DST:
2
4
14
16
26
28
8 bits
2-D Synchronization


There are two modes of synchronization in the
2-D transfer mode.
These are:



Chapter 5, Slide 42
Array synchronized: each event causes one line of
the array to be transferred.
Block synchronized: each event causes the entire
block to be transferred.
The FS bit is used to specify the
synchronization mode.
2-D Transfer Synchronization

Array synchronized (FS=0):




Chapter 5, Slide 43
This is the same as the 1-D frame synchronisation mode
except that the elements are all contiguous.
One array is transferred per synchronisation event.
The frame count is equal to the number of frames
minus one because when the FRMCNT=0 the complete
transfer parameters are reloaded after sending the last
transfer request to the address generation hardware.
The frame index is added to the start address of the
frame to derive the next frame address.
Example: 2-D Transfer with FS=0
Source
Destination
16-bit Data
SRC:
Sync event
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39
40 40 41 42
43 44 45 46 47 48 49
DST:
8
9
10
11
15
...
40
16 bits


Chapter 5, Slide 44
With 2D transfers there is no indexing
between elements, therefore ELEIDX is not
used in 2D transfers.
To specify a 2D source set 2DS in channel
options.
Example: 2-D Transfer with FS=0
Source
Destination
16-bit Data
SRC:
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39
40 40 41 42
43 44 45 46 47 48 49




ESIZE = 01b (16bits)
ELECNT = 4, FRMCNT = 4
SUM = 01b, 2DS = 1b
FRMIDX = 14, ELEIDX = N/A
DST:
8
9
10
11
15
...
40
16 bits
In this mode:
Next frame addr = First element addr + FRMIDX
Chapter 5, Slide 45
2-D Transfer Synchronization

Block synchronized (FS=1):



Chapter 5, Slide 46
This is the same as the 1-D frame synchronization
mode except that the elements are all contiguous.
The entire block is transferred following the
synchronization event.
At the end of each frame the frame index is added to
the last element address to calculate the next frame
start address.
Example: 2-D Transfer with FS=1
Source
Destination
16-bit Data
SRC:
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
Sync event
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39
40 40 41 42
43 44 45 46 47 48 49




ESIZE = 01b (16bits)
ELECNT = 4, FRMCNT = 4
SUM = 01b, 2DS = 1b
FRMIDX = 8, ELEIDX = N/A
DST:
8
9
10
11
15
...
40
16 bits
In this mode:
Next frame addr = Last element addr + FRMIDX
Chapter 5, Slide 47
EDMA Interrupt Generation



Chapter 5, Slide 48
The EDMA controller is responsible for
generating transfer completion interrupts to
the CPU.
The EDMA generates a single interrupt
(EDMA_INT) to the CPU on behalf of all 16
channels.
The programmer has to read the CIPR register
to determine which channel caused the
interrupt or which interrupts are pending
while the ISR is being serviced.
EDMA Interrupt Generation


Each channel has an OPTIONS register
OPTIONS contains:


31
OPTIONS
Chapter 5, Slide 49
TCINT - do you want to interrupt CPU?
TCC
- 4 bit completion code (your choice)
20
TCINT
19
16
TCC
0
EDMA Interrupt Generation


Each channel has an OPTIONS register
OPTIONS contains:



TCINT - do you want to interrupt CPU?
TCC
- 4 bit completion code (your choice)
Upon completion: If you set TCINT = 1, then CIPR bit equal to
TCC value (you set) is set to one
31
OPTIONS
19
TCINT
31
CIPR
20
rsvd
Chapter 5, Slide 50
15
16
0
TCC
14
CIP15 CIP14
8
7
6
5
4
3
2
1
0
CIP8 CIP7 CIP6 CIP5 CIP4 CIP3 CIP2 CIP1 CIP0
EDMA Interrupt Generation


Each channel has an OPTIONS register
OPTIONS contains:





TCINT - do you want to interrupt CPU?
TCC
- 4 bit completion code (your choice)
Upon completion: If you set TCINT = 1, then CIPR bit equal to
TCC value (you set) is set to one
CIER bit must be set for CPU to be interrupted
Only 1 EDMA interrupt to CPU. Upon int, CPU should service all
pending channels set in CIPR
31
OPTIONS
20
19
TCINT
31
15
16
0
TCC
14
8
7
6
5
4
3
2
1
0
CIPR
rsvd
CIP15 CIP14
CIP8 CIP7 CIP6 CIP5 CIP4 CIP3 CIP2 CIP1 CIP0
CIER
rsvd
CIE15 CIE14
CIE8 CIE7 CIE6 CIE5 CIE4 CIE3 CIE2 CIE1 CIE0
Chapter 5, Slide 51
Chaining EDMA Transfers



Chapter 5, Slide 52
After completion of an EDMA channel transfer
another EDMA channel transfer can be
triggered.
This triggering mechanism is similar to event
triggering.
However this method can only be used to
trigger EDMA channels 8 to 11.
Chaining EDMA Transfers

In addition to setting the TCINT and TCC bits
there is also another register, the Channel
Chain Enable Register (CCER) that must be
set.
31
12
Reserved
11
10
9
8
CCE11
CCE10
CCE9
CCE8
Channel Chain Enable Register (CCER)
Chapter 5, Slide 53
7
0
Reserved
Chaining EDMA Transfers
Channel Changing … ah, that is, Channel Chaining


Upon completion, one EDMA channel can kick-off another
Rather than setting CIER bit (to enable CPU int), set CCER
to enable channel 8-11 to start
31
OPTIONS
TCINT
CIPR
CCER
20
19
16
0
TCC
CIP11 CIP10 CIP9 CIP8
rsvd
Chapter 5, Slide 54
CCE11CCE10 CCE9 CCE8
rsvd
REVT1
XEVT1
EVT15
EVT14
EVT11
EE15
EE14
EE11
ESR15
TINT0
DSPINT
EVT8
EVT1
EVT0
EE8
EE1
EE0
EDMA Interrupt Generation
ESR14
ESR11
CC11
CC8
ESR8
Event Register
(ER)
Event Enable Register
(EER)
ESR1
ESR0
Triggers
Triggers
Triggers
Triggers
Triggers
Triggers
Channel 15
Channel 14
Channel 11
Channel 8
Channel 1
Channel 0
Complete
Complete
Complete
Complete
Complete
Complete
TCINT
TCC
TCINT
TCC
4
4
Decoder
CIP15
Decoder
CIP14
CIP11
CIP8
CCE11
CCE8
CC11
CIE15
CIE14
EDMA_INT
Chapter 5, Slide 55
CIE11
CIP1
CIP0
Channel Interrupt
Pending Register (CIPR)
Channel Chain Enable
Register (CCER)
CC8
CIE8
CIE1
CIE0
Channel Interrupt
Enable Register (CIER)
EDMA Config
Options
EDMA_Handle myEDMA, myLNK;
Source
Transfer Count
Destination
Index
Count Reload
Link Addr
31
16 15
0
EDMA_Config myConfig = {
options,
source,
length,
destination,
index,
reload:link
};
edma_init () {
1. open XEVT0 EDMA channel
// McBSP0 transmit event
2. allocate LINK parameter location
3. update EDMA_Config with LINK location
4. configure EDMA channel & link location
5. enable EDMA channel
6. enable EDMA interrupt to CPU
}
Chapter 5, Slide 56
EDMA Config
Options
EDMA_Handle myEDMA, myLNK;
Source
Transfer Count
Destination
Index
Count Reload
Link Addr
31
16 15
0
EDMA_Config myConfig = {
options,
source,
length,
destination,
index,
reload:link
};
void edma_init (void) {
hEdma = EDMA_open( EDMA_CHA_XEVT0, EDMA_OPEN_RESET );
hEdmaLINK = EDMA_allocTable( -1 );
myConfig.rld = EDMA_MK_RLD(myLNK,0);
EDMA_config(hEdma, &my_edma_Config);
EDMA_config(hEdmaLINK, &my_edma_Config);
EDMA_enableChannel( hEdma );
EDMA_intClear(5); EDMA_intEnable(5); }
Chapter 5, Slide 57
EDMA Interrupt (to CPU)
DSK
edma_HWI
Buffer
McBSP
EDMA
DAC
// Interrupt Service Routine
edma_HWI() {
block_sine();
}
Chapter 5, Slide 58
block_sine()
DSK
edma_HWI
Buffer
McBSP
EDMA
DAC
short buffer[128];
main()
{ init_EDMA();
init_HWI()
...
}
Chapter 5, Slide 59
void block_sine() {
for (i = 0; i < 128; i++) {
buffer[i] = sineGen();
}}
Introduction to the Quick DMA (QDMA)




Chapter 5, Slide 60
The QDMA provides a very efficient way of
moving data.
It supports nearly all the same modes as the
EDMA however transfer requests are
submitted faster.
However it does not support reload of a count
or link.
Therefore the QDMA is suited to one-off moves
of blocks of data internally whereas the EDMA
is suited to moving data between peripherals
and the memory.
QDMA Registers

The QDMA is programmed via two sets of five
write-only memory mapped registers:


Writing to the first set of registers configures the
QDMA but does not submit a request.
Writing to the second set of registers configures the
QDMA and submits a transfer request.
QDMA Registers (Set 1)
QDMA Pseudo Registers (Set 2)
0x0200 0000
Options
0x0200 0020
Options
0x0200 0004
Source
0x0200 0024
Source
0x0200 0008
Transfer Count
0x0200 0028
Transfer Count
0x0200 000c
Destination
0x0200 002c
Destination
0x0200 0010
Index
16 15
0x0200 0030
Index
16 15
Chapter 5, Slide 61
31
0
31
0
QDMA Options Register
31
29 28
PRI
27
ESIZE
26
25
2DS
24
SUM
23
22
2DD
21
DUM
20
TCINT
19
16 15
TCC
Label
31:29
PRI
28:27
Chapter 5, Slide 62
Description
Priority levels for the QDMA event
ESIZE Element size (32/16/8-bit)
26
2DS
Source dimension
25:24
SUM
Source address update mode
23
2DD
Destination dimension
22:21
DUM
Destination address update mode
20
TCINT Transfer complete interrupt enable
19:16
TCC
Transfer complete code
0
FS
Frame synchronisation
1
RSVD RSVD
EDMA Channel Options Register
Bit Field
2
0
FS
Other QDMA Registers


Source: Start address of the source.
Transfer Count:




Destination: Start address of the destination.
Index:


Chapter 5, Slide 63
Upper 16 bits [31:16]: Frame count.
Lower 16 bits [15:0]: Element count.
Upper 16 bits [31:16]: Frame index.
Lower 16 bits [15:0]: Element index.
Configuring the QDMA

Five writes are required to submit a request:


The first four registers are configured by writing to the
corresponding QDMA registers.
The fifth register is configured by writing to the
corresponding pseudo register causing the request to be
submitted.
QDMA Registers (Set 1)
QDMA Pseudo Registers (Set 2)
0x0200 0000
Options
0x0200 0020
Options
0x0200 0004
Source
0x0200 0024
Source
0x0200 0008
Transfer Count
0x0200 0028
Transfer Count
0x0200 000c
Destination
0x0200 002c
Destination
0x0200 0010
Index
16 15
0x0200 0030
Index
16 15
Chapter 5, Slide 64
31
0
31
0
Features of the QDMA



Chapter 5, Slide 65
All transfers are frame synchronised.
Although linking is not supported, completion
interrupts and channel chaining are supported.
The values held in the registers are not changed
by the hardware hence the same transfer can be
repeated by a single write to one of the pseudo
registers.
Programming the EDMA

There are three methods available for
programming the EDMA:
(1) Writing directly to the EDMA registers.
(2) Using the Chip Support Library (CSL).
(3) Graphically using the DSP/BIOS GUI interface.
Chapter 5, Slide 66
Programming the EDMA - Direct
(1) Writing directly to the EDMA registers:


Although this method is straightforward, it relies on
a good understanding of the EDMA and the DSP
memory map.
This method is tedious and prone to errors.
#include <intr.h>
#include <regs.h>
#include <c6211dsk.h>
void EDMA_setup (void)
{
*(unsigned volatile int *) ECR = 0xffff;
*(unsigned volatile int *) EER = 0xffff;
*(unsigned volatile int *) CIPR = 0xffff;
*(unsigned volatile int *) CIER = 0xffff;
...
}
Chapter 5, Slide 67
Programming the EDMA - CSL
(2) Using the Chip Support Library:



Chapter 5, Slide 68
The CSL provides a C language interface for
configuring and controlling the on-chip peripherals,
in this case the EDMA.
The library is modular with each module
corresponding to a specific peripheral. This has the
advantage of reducing the code size.
Some modules rely on other modules also being
included, for example the IRQ module is required
when using the EDMA module.
Programming the EDMA - CSL

The CSL can be divided into four sections:
Constants
Functions
Macros
Structure
EDMA_CHA_CNT
EDMA_SUPPORT
EDMA_TABLE_CNT
EDMA_allocTable
EDMA_allocTableEx
EDMA_chain
EDMA_clearChannel
EDMA_clearParm
EDMA_close
EDMA_config
EDMA_configArgs
EDMA_disableChaining
EDMA_enableChaining
EDMA_disableChannel
EDMA_enableChannel
EDMA_freeTable
EDMA_freeTableEx
EDMA_getChannel
EDMA_getConfig
…
EDMA_ADDR (<REG>)
EDMA_RGET(<REG>)
EDMA_RSET(<REG>,X)
EDMA_FGET(<REG>,<FIELD>)
EDMA_FSET(<REG>,<FIELD>,fieldval)
EDMA_FSETS(<REG>,<FIELD>,<SYM>)
EDMA_RGETA(addr, <REG>)
EDMA_RSETA(addr,<REG>,x)
EDMA_FGETA(addr,<REG>,<FIELD>)
EDMA_FSETA(addr,<REG>,<FIELD>,fieldval)
EDMA_FSETSA(addr,<REG>,<FIELD>,<SYM>)
EDMA_ADDRH(h,<REG>)
EDMA_RGETH(h,<REG>)
EDMA_RSETH(h,<REG>,x)
EDMA_FGETH(h,<REG>,<FIELD>)
EDMA_FSETH(h,<REG>,<FIELD>,fieldval)
EDMA_Config

Chapter 5, Slide 69
See Code Composer Studio help for more details.
Programming the EDMA - CSL Example: Polling
#includes
Uint16 src[N], dst[N]; // Global Declarations
void TEST_edma()
{
Int16 i;
EDMA_Handle hEdmaCha8; // EDMA number 8 is used in this example
EDMA_Config edmaCfg8 = {
EDMA_FMKS(OPT, PRI, URGENT) | // highest priority for EDMA
EDMA_FMKS(OPT, ESIZE, 16BIT) | // element size is 16 bits
EDMA_FMKS(OPT, 2DS, NO)
| // 1-dimensional transfer from source
EDMA_FMKS(OPT, SUM, INC)
| // increment source address while transferring elements
EDMA_FMKS(OPT, 2DD, NO)
| // 1-dimensional transfer to destination
EDMA_FMKS(OPT, DUM, INC)
| // increment dest address while transferring elements
EDMA_FMKS(OPT, TCINT, YES)
| // indicate transfer completion
EDMA_FMK (OPT, TCC, TCC_NUM) | // set bit 8 upon transfer completion
EDMA_FMKS(OPT, LINK, NO)
| // after transfer completion don't link to other configuration
EDMA_FMKS(OPT, FS, YES),
// select frame-sync. An event implies a transfer of a frame of elemnts
(Uint32)src,
// source address
EDMA_FMKS(CNT, FRMCNT, OF(0)) | // 0 - means: transfer only one frame
EDMA_FMKS(CNT, ELECNT, OF(16)), // each frame (one in this example) consists of 16 elements
(Uint32)dst,
// dest address
};
… // to be continued
Chapter 5, Slide 70
Programming the EDMA - CSL Example : Polling
/* Set src values and clear destination */
for (i = 0; i < N; i++) {
src[i] = i;
dst[i] = 0;
}
/* Configure EDMA */
hEdmaCha8 = EDMA_open(8, EDMA_OPEN_RESET);
EDMA_config(hEdmaCha8, &edmaCfg8);
/* Start CPU initiated EDMA transfer by setting bit 24 in ESR */
EDMA_setChannel(hEdmaCha8);
/* Poll EDMA interrupt to see if its done */
while (!EDMA_intTest(TCC_NUM));
{
;
}
/* We are done, so close EDMA channel */
EDMA_close(hEdmaCha8);
/* Check data */
for (i = 0; i < N; i++)
if (dst[i] != src[i]){
printf("failed\n"); }
/* Test passed */
printf("success\n");
}
Chapter 5, Slide 71
Programming the EDMA - CSL Example : Polling
main()
{
/* Call BSL init */
DSK6416_init();
printf("Start EDMA test\n");
TEST_edma();
}
Chapter 5, Slide 72
Programming the EDMA - CSL Example : Int
#includes
Uint16 src[N], dst[N]; // Global Declarations
void TEST_edma()
{
Int16 i;
EDMA_Handle hEdmaCha8; // EDMA number 8 is used in this example
EDMA_Config edmaCfg8 = {
EDMA_FMKS(OPT, PRI, URGENT) | // highest priority for EDMA
EDMA_FMKS(OPT, ESIZE, 16BIT) | // element size is 16 bits
EDMA_FMKS(OPT, 2DS, NO)
| // 1-dimensional transfer from source
EDMA_FMKS(OPT, SUM, INC)
| // increment source address while transferring elements
EDMA_FMKS(OPT, 2DD, NO)
| // 1-dimensional transfer to destination
EDMA_FMKS(OPT, DUM, INC)
| // increment dest address while transferring elements
EDMA_FMKS(OPT, TCINT, YES)
| // indicate transfer completion
EDMA_FMK (OPT, TCC, TCC_NUM) | // set bit 8 upon transfer completion
EDMA_FMKS(OPT, LINK, NO)
EDMA_FMKS(OPT, FS, YES),
| // after transfer completion don't link to other configuration
// select frame-sync. An event implies a transfer of a frame of elemnts
(Uint32)src,
// source address
EDMA_FMKS(CNT, FRMCNT, OF(0)) | // 0 - means: transfer only one frame
EDMA_FMKS(CNT, ELECNT, OF(16)), // each frame (one in this example) consists of 16 elements
(Uint32)dst,
// dest address
};
… //to be continued
Chapter 5, Slide 73
Programming the EDMA - CSL Example : Int
/* Set src values and clear destination */
for (i = 0; i < N; i++) {
src[i] = i;
dst[i] = 0;
}
/* Configure EDMA */
hEdmaCha8 = EDMA_open (8, EDMA_OPEN_RESET);
EDMA_config (hEdmaCha8, &edmaCfg8);
EDMA_intEnable (TCC_NUM); // enable CIER bit 8 to cause a interrupt to CPU
IRQ_clear (IRQ_EVT_EDMAINT); // clear any possible pending interrupts
IRQ_enable (IRQ_EVT_EDMAINT); // enable EDMA interrupt enterring CPU
IRQ_globalEnable (); // actually, not necessary, since this is done by DSP/BIOS
/* Start CPU initiated EDMA transfer by setting bit 24 in ESR */
EDMA_setChannel (hEdmaCha8);
}
Chapter 5, Slide 74
Programming the EDMA - CSL Example : Int
void edmaISR(void)
{
if (EDMA_intTest (TCC_NUM)){
SWI_post (&SWIedma);
}
}
void SWIcheckEdma (void)
{
int i;
/* Check data */
for (i = 0; i < N; i++)
if (dst[i] != src[i]){
printf ("failed\n");
return;
}
/* Test passed */
printf ("success\n");
}
Chapter 5, Slide 75
Programming the EDMA - CSL Example : Int
main()
{
/* Call BSL init */
DSK6416_init();
printf("Start EDMA test\n");
TEST_edma();
}
Chapter 5, Slide 76
Programming the EDMA - CSL Example : Timer
#includes
Uint16 src[N], dst[N]; // Global Declarations
TIMER_Handle hTimer; // handle for the timer device
// int numTimer1Intr = 0; // timer-count
void TEST_edma()
{
Int16 i;
EDMA_Handle hEdmaCha2; // EDMA number 8 is used in this example
EDMA_Config edmaCfg2 = {
EDMA_FMKS (OPT, PRI, URGENT) | // highest priority for EDMA
EDMA_FMKS (OPT, ESIZE, 16BIT) | // element size is 16 bits
EDMA_FMKS (OPT, 2DS, NO)
| // 1-dimensional transfer from source
EDMA_FMKS (OPT, SUM, INC)
| // increment source address while transferring elements
EDMA_FMKS (OPT, 2DD, NO)
| // 1-dimensional transfer to destination
EDMA_FMKS (OPT, DUM, INC)
| // increment dest address while transferring elements
EDMA_FMKS (OPT, TCINT, YES)
| // indicate transfer completion
EDMA_FMK (OPT, TCC, TCC_NUM) | // set bit 8 upon transfer completion
EDMA_FMKS (OPT, LINK, NO)
| // after transfer completion don't link to other configuration
EDMA_FMKS (OPT, FS, NO),
// select frame-sync. An event implies a transfer of a frame of elemnts
(Uint32)src,
// source address
EDMA_FMKS (CNT, FRMCNT, OF(0)) | // 0 - means: transfer only one frame
EDMA_FMKS (CNT, ELECNT, OF(16)), // each frame (one in this example) consists of 16 elements
(Uint32)dst,
// dest address
};
Chapter 5, Slide 77
Programming the EDMA - CSL Example : Timer
/* Set src values and clear destination */
for (i = 0; i < N; i++) {
src[i] = i;
dst[i] = 0;
}
/* Configure EDMA */
hEdmaCha2 = EDMA_open (2, EDMA_OPEN_RESET);
EDMA_config (hEdmaCha2, &edmaCfg2);
EDMA_intEnable (TCC_NUM); // enable CIER bit 8 to cause a interrupt to CPU
IRQ_clear (IRQ_EVT_EDMAINT); // clear any possible pending interrupts
IRQ_enable (IRQ_EVT_EDMAINT); // enable EDMA interrupt enterring CPU
IRQ_globalEnable(); // actually, not necessary, since this is done by DSP/BIOS
// create handle for timer 1
hTimer = TIMER_open (TIMER_DEV1, TIMER_OPEN_RESET);
// configure timer
TIMER_configArgs (hTimer,
TIMER_CTL_OF (0x200),
TIMER_PRD_OF (TPRD),
TIMER_CNT_OF (0)
);
//Enable timer interrupt
// IRQ_enable (IRQ_EVT_TINT1); // timer-count
TIMER_start (hTimer);
EDMA_enableChannel (hEdmaCha2);
}
Chapter 5, Slide 78
Programming the EDMA - CSL Example : Timer
void timerISR(void) // timer-count
{
//
numTimer1Intr++; // timer-count
}
void edmaISR(void)
{
if (EDMA_intTest(TCC_NUM)){
SWI_post(&SWIedma);
}
}
void SWIcheckEdma(void)
{
int i;
/* Check data */
for (i = 0; i < N; i++)
if (dst[i] != src[i]) {
printf("failed\n");
return;
}
/* Test passed */
printf("success\n");
}
Chapter 5, Slide 79
Programming the EDMA - CSL Example : Timer
main()
{
/* Call BSL init */
// DSK6416_init();
printf("Start EDMA test\n");
TEST_edma();
// go to DSP/BIOS
}
Chapter 5, Slide 80
Programming the EDMA - CSL Example
Buffer (ping)
1000
1000
Ping_data
1000
Outbuff
1000
EDMA
Pong_data
2000
Sync event
Timer 1
Chapter 5, Slide 81
Buffer (pong)
swiProcess
Func
Programming the EDMA - CSL Example
Buffer (ping)
1000
1000
Ping_data
1000
Processing by CPU
Outbuff
1000
1000
1000
EDMA
Pong_data
2000
Buffer (pong)
2000
2000
Sync event
Timer 1
Chapter 5, Slide 82
swiProcess
Func
2000
1000
Programming the EDMA - CSL Example
Buffer (ping)
1000
1001
1000
1001
Ping_data
1001
Outbuff
2000
2000
1000
1001
EDMA
Pong_data
2000
swiProcess
Buffer (pong)
Func
2000
2000
2000
Processing by CPU
Sync event
Timer 1
Chapter 5, Slide 83
2000
Programming the EDMA - CSL Example

CSL programming procedure:
(1) Create handles for the EDMA channel and
reload parameters:
EDMA_Handle hEdma;
(2) Create the EDMA configuration:
EDMA_Config cfgEdma;
Chapter 5, Slide 84
Programming the EDMA - CSL Example

CSL programming procedure (cont):
(3) Create the configuration structures for the ping
and pong channels:
EDMA_Config cfgEdmaPong = {0x28720002,
EDMA_SRC_OF(McBSP0_DRR),
EDMA_CNT_OF(BUFF_SZ),
EDMA_DST_OF((unsigned int)cin_data),
EDMA_IDX_OF(0x00000004),
EDMA_RLD_OF(0x00000000)};
EDMA_Config cfgEdmaPing = {0x28720002,
EDMA_SRC_OF(McBSP0_DRR),
EDMA_CNT_OF(BUFF_SZ),
EDMA_DST_OF((unsigned int)in_data),
EDMA_IDX_OF(0x00000004),
EDMA_RLD_OF(0x00000000)};
Chapter 5, Slide 85
Pong Configuration:
0x403A0002,
//Options
FS=0
(element sync); bits 0
LINK=1
(concatenating of blocks of frames); bits 1
TCC=1010b (CIPR[0xA] bit is set upon transfer completion); bits 19-16
TCINT=1
(Set CIPR[0xA] bit upon transfer complete;
if CIPR[0xA] is also set, then an interrupt to the CPU is generated); bits 20
SUM=0
(source address not updated); bits 25-24
DUM = 01b (destination address is incremented by element size ); bits 22-21
2DD=2DS=0 (non 2D synchronization) ; bits 26, 23
ESIZE=00b
(32-bits elements); bits 28-27
PRI=010b
(Low priority); bits 31-29
EDMA_SRC_OF(&pong_data),
// Source address: (address of pong data integer)
EDMA_CNT_OF(BUFF_SZ),
// Transfer count: FC=0 (one frame);
// EC=BUFF_SZ
EDMA_DST_OF(pong),
// Destination address (pong buffer)
EDMA_IDX_OF(0x00000004),
// Index:FIX=0; EIX=4
EDMA_RLD_OF(0x00000000)
// Element count reload and link address
Chapter 5, Slide 86
Pong Configuration using CSL
EDMA_Config cfgEdmaPong = {
EDMA_OPT_RMK(
EDMA_OPT_PRI_LOW,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF(TCCINTNUM),
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
),
EDMA_SRC_OF(&pong_data),
EDMA_CNT_OF(BUFF_SZ),
EDMA_DST_OF(pong),
EDMA_IDX_OF(0x00000004),
EDMA_RLD_OF(0x00000000)
};
Chapter 5, Slide 87
Programming the EDMA - CSL Example

CSL programming procedure (cont):
(4) Map the event to a physical interrupt (see
Interrupt section):
IRQ_map (IRQ_EVT_EDMAINT, 8);
This maps the EDMA_INT interrupt to CPU_INT8.
(5) Set the interrupt dispatcher configuration
structure (see Interrupt section):
IRQ_configArgs (IRQ_EVT_EDMAINT,
EdmaIsr,
0x00000000,
IRQ_CCMASK_DEFAULT,
IRQ_IEMASK_ALL);
Chapter 5, Slide 88
Programming the EDMA - CSL Example

CSL programming procedure (cont):
(6) Open up an EDMA channel associated with the
Timer 1 (remember each EDMA is associated
with a specific event):
hEdma = EDMA_open (EDMA_CHA_TINT1, EDMA_OPEN_RESET);
(7) Allocate the EDMA reload parameters:
hEdmaPing = EDMA_allocTable (-1);
hEdmaPong = EDMA_allocTable (-1);
Note: -1 means allocate at any available location.
(8) Copy the first reload configuration structure to
the EDMA configuration structure:
cfgEdma = cfgEdmaPing;
Chapter 5, Slide 89
Programming the EDMA - CSL Example

CSL programming procedure (cont):
(9)Configure the link fields of the configuration
structure:
cfgEdmaPing.rld = EDMA_RLD_RMK(0,hEdmaPong);
cfgEdmaPong.rld = EDMA_RLD_RMK(0,hEdmaPing);
cfgEdma.rld
= EDMA_RLD_RMK(0,hEdmaPong);
This can be done at stage 3 but in this way we do not know
the numerical value of the reload address.
(10) Setup the EDMA channel using the configuration
structure:
EDMA_config (hEdmaPing, &cfgEdmaPing);
EDMA_config (hEdmaPong, &cfgEdmaPong);
Chapter 5, Slide 90
Programming the EDMA - CSL Example

CSL programming procedure (cont):
(11) Finally initialise all the EDMA registers:
EDMA_RSET (ECR, 0xffff);
// clear all events
EDMA_enableChannel(hEdma);
EDMA_RSET (EER, 0x4);
// set the timer 1 event enable bit
EDMA_RSET (CIPR, 0xffff);
EDMA_RSET (CIER, 0x4);
// make the timer 1 event generate
// an EDMA_INT interrupt

An example CCS project is included in:

Chapter 5, Slide 91
\Lab 05\Edma_Inout_Staticcfg
Programming the EDMA - DSP/BIOS GUI
(3) DSP/BIOS GUI Interface

Chapter 5, Slide 92
With this method the configuration structure is
created graphically and the setup code is generated
automatically.
Programming the EDMA - DSP/BIOS GUI

Procedure:
(1) Create a configuration using
the EDMA configuration
manager.
Chapter 5, Slide 93
Programming the EDMA - DSP/BIOS GUI

Procedure:
(2) Right click and select “Properties”, see the figure
below, and then select “Advanced” and fill all
parameters as shown below.
Chapter 5, Slide 94
Programming the EDMA - DSP/BIOS GUI

Procedure:
(3) If you are using symbolic parameters such as
“in_data” you need to declare it in the “CSL
Extern Declaration”, see below figure.
Chapter 5, Slide 95
Programming the EDMA - DSP/BIOS GUI

Procedure:
(4) A file is then generated that contains the
configuration code. The file generated for this
example is shown on the next slide.
Chapter 5, Slide 96
Programming the EDMA - DSP/BIOS GUI
/*
/*
/*
Do *not* directly modify this file. It was
generated by the Configuration Tool; any */
changes risk being overwritten.
*/
*/
/* INPUT edma_inout_csl.cdb */
/* Include Header File */
#include "edma_inout_cslcfg.h"
extern far Uint16 McBSP0_DRR;
extern far Uint16 in_data[];
extern far Uint16 BUFF_SZ;
/* Config Structures */
EDMA_Config cfgEdmaPing = {
0x28720002,
/* Option */
0x018C0000,
/* Source Address - Numeric
*/
0x00000002,
/* Transfer Counter */
(Uint32) in_data, /* Destination Address - Symbolic
*/
0x00000004,
/* Transfer Index */
0x000001B0
/* Element Count Reload and Link Address
};
/*
Handles
*/
/*
* ======== CSL_cfgInit() ========
*/
void CSL_cfgInit()
{
}
Chapter 5, Slide 97
*/
*-----------------------------------------------------------------------------* This program uses the timers to trigger EDMA events. These events in turn
* trigger linked EDMA parameter tables to fill a ping-pong buffer structure.
* Set a breakpoint on swiProcessFunc(int arg). Then open two memory windows.
* Use ping as the address for one memory window and pong for the other. Then
* run the application. You'll note that the program bounces between the ping
* and pong buffers filling each with a value that comes from the source. The
* source in this case is the SDRAM timer control register and it simulates
* input data.(Note: This example runs with CACHE enable).
\******************************************************************************/
#include <std.h>
#include <swi.h>
#include <log.h>
Pre-processor replaces line with the
#include <clk.h>
named ‘header file’
#include <csl.h>
#include <csl_cache.h>
#include <csl_edma.h>
#include <csl_timer.h>
#include <csl_irq.h>
/*----------------------------------------------------------------------------*/
/* declare DSP/BIOS objects created with the configuration tool */
extern far SWI_Obj SwiMain;
Pre-processor replaces all occurrences
extern far LOG_Obj LogMain;
identifier with the define value.
extern far SWI_Obj swiProcess;
extern far LOG_Obj trace;
of
By convention, identifiers are all capital
/* Pick which EDMA transfer completion interrupt we want to use */
#define TCCINTNUM 10
Chapter 5, Slide 98
/* define some constants */
#define BUFF_SZ 256
/* ping-pong buffer sizes in # of ints */
#define FCPU 150000000
/* CPU clock frequency
*/
#define SRATE 8000
/* data sample rate (simulated w/timer */
#define TPRD (FCPU/(4*SRATE)) /* timer period
*/
/* Create the buffers. We want to align the buffers to be cache friendly */
/* by aligning them on an L2 cache line boundary.
*/
#pragma DATA_ALIGN(ping,128);
#pragma DATA_ALIGN(pong,128);
#pragma DATA_ALIGN(outbuff,128);
int ping[BUFF_SZ];
An array of BUFF_SZ integers.
int pong[BUFF_SZ];
Indexed as pong[0], pong[1], …
int outbuff[BUFF_SZ];
/* These two variables serve as the data sources for this example. */
/* Also want to align these on a cache line boundary since they */
/* sources of EDMA transfers.
*/
#pragma DATA_ALIGN(ping_data,128);
#pragma DATA_ALIGN(pong_data,128);
static int ping_data;
static int pong_data;
Assign an initial value to the variable
/* global variable used to track the ping-pong'ing */
static int pingpong = 0;
Chapter 5, Slide 99
Type
Variable name
Variables defined externally to a
function body (including ‘main’) have
a global scope.
/* declare some CSL objects */
TIMER_Handle hTimer; /* Handle for the timer device */
EDMA_Handle
hEdma; /* Handle for the EDMA channel */
EDMA_Handle
hEdmaPing; /* Handle for the ping EDMA reload parameters */
EDMA_Handle
hEdmaPong; /* Handle for the pong EDMA reload parameters */
EDMA_Config
cfgEdma; /* EDMA configuration structure
*/
/* Create the EDMA configuration structure for ping transfers */
EDMA_Config cfgEdmaPing = {
EDMA_OPT_RMK(
EDMA_OPT_PRI_LOW,
// low priority
EDMA_OPT_ESIZE_32BIT,
// element size = 4 bytes
EDMA_OPT_2DS_NO,
// one-dimension synchronization for source
EDMA_OPT_SUM_NONE,
// do not increment source address
EDMA_OPT_2DD_NO,
// one-dimension synchronization for destination
EDMA_OPT_DUM_INC,
// increment destination address
EDMA_OPT_TCINT_YES,
// upon EDMA completion, generate an EDMA interrupt to PC
EDMA_OPT_TCC_OF(TCCINTNUM), // set bit 10 in Channel Interrupt Pending Register (CIPR)
EDMA_OPT_LINK_YES,
// Upon completion, reload parameter specified by link-address
EDMA_OPT_FS_NO
// FS=0  element synchronization
),
EDMA_SRC_OF(&ping_data),
// source address: address of ‘ping_data’ variable
EDMA_CNT_OF(BUFF_SZ),
// one frame (FRMIDX=0); ‘BUFF_SZ’ elements in frame
EDMA_DST_OF(ping),
// one frame (FRMCNT=0); ‘BUFF_SZ’
EDMA_IDX_OF(0x00000004),
// difference between adjacent elements = 4 bytes (no gaps)
EDMA_RLD_OF(0x00000000)
// to be defined later
};
Chapter 5, Slide 100
/* Create the EDMA configuration structure for pong transfers */
EDMA_Config cfgEdmaPong = {
EDMA_OPT_RMK(
EDMA_OPT_PRI_LOW,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_NO,
EDMA_OPT_SUM_NONE,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_INC,
EDMA_OPT_TCINT_YES,
EDMA_OPT_TCC_OF(TCCINTNUM),
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
),
EDMA_SRC_OF(&pong_data),
// source address = address of ‘pong_data’ variable
EDMA_CNT_OF(BUFF_SZ),
EDMA_DST_OF(pong),
// destination address = ‘pong’ buffer
EDMA_IDX_OF(0x00000004),
EDMA_RLD_OF(0x00000000)
};
Chapter 5, Slide 101
/*----------------------------------------------------------------------------*/
void main(){
/* initialize the CSL library */
CSL_init();
/* initialize the input source data */
ping_data=0x00000000;
pong_data=0x80000000;
/* Since these variables are the source of an EDMA transfer, we */
/* need to flush them out of the cache since we just wrote to them. */
CACHE_flush(CACHE_L2,&ping_data,1);
CACHE_flush(CACHE_L2,&pong_data,1);
/* Let's disable/clear related interrupts just in case they are pending */
/* fram a previous run of the program.
*/
IRQ_reset(IRQ_EVT_EDMAINT);
// reset any pending EDMA interrupt at CPU
EDMA_intDisable(TCCINTNUM);
// prevent generation EDMA interrupt ( CIER[10] = 0)
EDMA_intClear(TCCINTNUM);
// clear pending interrupt at EDMA ( CIPR[10] = 0)
/* Although not required, let's clear all of the EDMA parameter RAM. */
/* This makes it easier to view the RAM and see the changes as we */
/* configure it.
*/
EDMA_clearPram(0x00000000);
/* Let's open up a timer device, we'll use this to simulate input events */
/* at a gien sample rate.
*/
hTimer = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET);
Chapter 5, Slide 102
/* Lets open up the EDMA channel associated with timer #1. */
hEdma = EDMA_open(EDMA_CHA_TINT1, EDMA_OPEN_RESET);
/* We also need two EDMA reload parameter sets so let's allocate them */
/* here. Notice the -1, this means allocate any availale tale.
*/
hEdmaPing = EDMA_allocTable(-1);
hEdmaPong = EDMA_allocTable(-1);
/* Let's copy the ping reload configuration structure to an */
/* intermediate configuration structure.
*/
cfgEdma = cfgEdmaPing;
/* Let's initialize the link fields of the configuration structures */
cfgEdmaPing.rld = EDMA_RLD_RMK(0,hEdmaPong); // Ping parameters reloads Pong parameters
cfgEdmaPong.rld = EDMA_RLD_RMK(0,hEdmaPing); // Pong parameters reloads Ping parameters
cfgEdma.rld = EDMA_RLD_RMK(0,hEdmaPong);
/* Now let's program up the EDMA channel with the configuration structure */
EDMA_config(hEdma, &cfgEdma);
/* Let's also configure the reload parameter tables in the EDMA PRAM */
/* with the values in the configuration structures.
*/
EDMA_config(hEdmaPing, &cfgEdmaPing);
EDMA_config(hEdmaPong, &cfgEdmaPong);
Chapter 5, Slide 103
/* Configure up the timer. */
TIMER_configArgs(hTimer,
TIMER_CTL_OF(0x00000200),
TIMER_PRD_OF(TPRD),
TIMER_CNT_OF(0)
);
/* Enable the related interrupts */
IRQ_enable(IRQ_EVT_EDMAINT); // enable EDMA interrupt at CPU
EDMA_intEnable(TCCINTNUM); // enable generating interrupt at EDMA (CEIR[10] = 1)
/* Enable the EDMA channel */
EDMA_enableChannel(hEdma);
// enable EDMA channel 2 (associated with Timer 1) EER[2] =1
/* Finally, enable the timer which will drive everything. */
TIMER_start(hTimer);
}
Chapter 5, Slide 104
void swiProcessFunc (int arg){
int *inbuff;
int x;
if (pingpong){
/* If pingpong is 0, then we own the ping input buffer */
inbuff = ping;
LOG_printf(&trace,"Ping");
}else{
/* If pingpong is 1, then we own the pong input buffer */
inbuff = pong;
LOG_printf(&trace,"Pong");
}
/* Now let's process the input buffer, for simplicity, we'll */
/* just copy it to the output buffer.
*/
for (x=0; x<BUFF_SZ; x++) {
outbuff[x] = inbuff[x];
}
/* If this example is enhanced to actually do something with the */
/* output buffer such as DMA it somewhere, you will want to flush */
/* it out of the cache first.
*/
CACHE_flush(CACHE_L2,outbuff,BUFF_SZ);
/* Since we're done processing the input buffer, clean it from cache, */
/* this invalidates it from cache to ensure we read a fresh version */
/* the next time.
*/
CACHE_clean(CACHE_L2,inbuff,BUFF_SZ);
}
Chapter 5, Slide 105
void hwiEdmaIsr ( int arg){
/* Clear the pending interrupt from the EDMA interrupt pending register */
EDMA_intClear(TCCINTNUM);
// CIPR[10] = 0
/* Perform ping-pong */
pingpong = (pingpong + 1) & 1;
/* Based on if we ping'ed or pong'ed, we need to set the EDMA channel */
if (pingpong){
/* Currently doing pong so setup next frame for ping */
/* Modify the input data source, this just simulates */
/* the input data changing.
*/
ping_data++;
/* Rememer to flush this variable out of the cache */
/* since it's the source of an EDMA transfer
*/
CACHE_flush(CACHE_L2,&ping_data,1);
}else{
/* Currently doing ping so setup next frame for pong */
/* Modify the output data source, this just simulates */
/* the input data changing.
*/
pong_data++;
/* Rememer to flush this variable out of the cache */
/* since it's the source of an EDMA transfer
*/
CACHE_flush(CACHE_L2,&pong_data,1);
}
/* Notify the app that we just ping-pong'ed */
SWI_post(&swiProcess);
}
Chapter 5, Slide 106
Chapter 5
Enhanced Direct Memory Access
(EDMA)
- End -