“Lab. 5” – Updating
Lab. 3 to use DMA
Test we understand DMA by using some simple
memory to memory DMA
Make life more interesting, since hardware is
involved, by using DMA to send out SPI signals
Transfer array using
“normal array handling”
Normal code
P0 address of start_array[0];
P1 address of final_array[0];
R0 max-value needed to transfer
R1 How many values already transferred
R1 = 0;
LOOP:
CC = R0 <= R1
IF CC JUMP DONE:
R2 = [P0++];
[P1++] = R2;
JUMP LOOP;
DONE:
Do something else
2 / 30
SPI -- point to SPI_TDBR
When SPI ready -- do transfer
Even more processor waiting
VERY BIG PIPELINE
LATENCY ISSUES
MANY INTERNAL
PROCESSOR STALLS
WHILE WAIT FOR R2 TO BE
READ, STORED and then TRANSMITTED
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Concept of a basis MEMDMA
and SPI DMA task
DMA
DMA_source_address_register address of start_array[0];
DMA_destination_address_register address of final_array[0];
DMA_max_count_register max-value needed to transfer
DMA_count_register How many values already transferred
R1 = 0;
LOOP:
CC = R0 <= R1
IF CC JUMP DONE:
R2 = [P0++];
[P1++] = R2;
JUMP LOOP;
DONE:
Do something else
3 / 30
SPI destination is SPI_TDBR
DMA hardware must “know” how to wait
until SPI hardware is ready
DMA_enable = true
Miminized pipeline issues
Processor can do
something else while DMA is
working
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Chapter 9 of the Blackfin
Hardware book
4 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Design expected functionality
of simple MEMDMA task
#define NUMPTS 1024
section (“SDRAM”) int destArray[NUMPTS];
int sourceArray[NUMPTS];
TEST(simpleDMAtask) {
Set_ArrayZero(destArray);
Set_KnownValues(sourceArray);
DoMEMDMATransfer(sourceArray, destArray, NUMPTS );
CHECK_ARRAY_EQUAL(sourceArray, destArray, NUMPTS ):
…. Other tests here ….
}
5 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
DMA registers we need to
worry about
Final exam question ideas
Other test examples
Did the hardware think it
transferred all the required values?
CHECK(NUMPTS ,
*pMDMA_S0_CURR_X_COUNT);
CHECK(NUMPTS ,
*pMDMA_D0_CURR_X_COUNT);
6 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Actual code
7 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
Not good as
final code in a program
as involves a wait
7/31/2017
Source DMA – read
Destination DMA – write
8 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
DMA register detail -- status
W1C bits
RO
Why only Destination
DMA status considered?
9 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
10 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Final test result
Placing array
in
external
memory
11 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Why the failures?
X_COUNT = 0. Perhaps this register only
useful when doing DMA (how much done
before error occurred) – not useful when
done
What one line did I change
to fix code?
12 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Try the same with SPI DMA
Essentially
identical code
to InitSPI( ) before
(Lab3)
13 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Design the tests to check if working
14 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Concept correct – implementation wrong
The book says
there is only
one channel for
non-memory
DMA
15 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Would this work
We can change
*pMDMA_S0_START_ADDR to
*pDMA0_START_ADDR perhaps
but how handle the SPI
destination?
16 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Use some ideas from Lab. 2
Something new if we
“make mistakes”
Specific
DMA channel
for SPI?
This tells us
Channel 5 dedicated to SPI
register_handler(ik_ivg10,….
IMASK |= 0x00001000
17 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
First attempt at the code
Just guessed
at the DMA
register names
based on earlier
code
Need to check the
bit positions
18 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Need to
check the
bit usage
on
CONFIG
and
STATUS
registers
19 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Second attempt at the code
Final exam hint
Common error in the lab.
Why did it happen?
How do you fix?
20 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Code “hangs” – where you
might expect it to hang
Final exam debug question – How would you determine if the code got into
ISR and perhaps is now hanging there?
Answer never got to the ISR – if “infinite loop” in ISR then would not be
showing the “infinite loop” here
21 / 30
DMA
(repeating code)
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Is the DMA channel running at all? Set break point to check
SPI_TDBR
=0
Transferred
1
IMASK
set
22 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Based on debug information
IMASK is set correctly
We transferred 1 “something”
Is direction correct?
Final Exam hint on testing
sourceArray[0] is being set to 0 as first thing to transfer to
SPI
SPI_TDBR has reset value is 0
Which of the two zeros are we seeing?
Need better array values to use during testing
23 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Run again after fixing test
*pSPI_TDBR = 0x100
This is not the reset
value (0) so correct
DMA transfer did
occur
From Lab. 2 – is
SIC_IMASK correct?
I also see that the DMA interrupts are not set
Previous Memory DMA code set interrupt on
MDMA_D0
channel – which we now don’t use.
24 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Set DMA Interrupt bit
Check SIC_IMASK Setting
25 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Check SIC_IMASK setting
*pSIC_IMASK |= 0x00001000
26 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
With SIC_IMASK fixed
We go immediately into ISR
Still to know
When did interrupt occur (at what line of code)?
Does interrupt clear?
Set break point at StartSPIDMA( ) and then step
through code to find out (F11)
27 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Single step results
Problem occurs “before we start DMA”
And we never get out of ISR
28 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Trying starting SPI after
DMA
29 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
First transfer is correct
None of the others
Only ever transfers
the “first” element of
sourceArray
Hangs
here when
doing line
92Since
hanges
second
time
around
loop
30 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Since hangs inside
SetupSPIDMA “2nd” time around
31 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Test to transfer many
First test works
Second test -- Hangs again
Final exam hint
Nasty
Code defect here
Try stopping and restarting SPI and
DMA
32 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Why does the first test fail
and the second test pass?
33 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Final exam answer would need
understanding of what a FIFO is.
34 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
Test Driven Development
Next stage
We wrote the tests
Wrote code to satisfy the tests
Modified the tests
“Code” just runs
Sometimes test fails first time but passes second time –
indication of a “race” condition (SPI_BAUD transfer rate
slower than Blackfin?)
We now need to keep the tests and REFACTOR the code
to make more use-able
With TTCOS (Lab. 3) need to make run without interrupts.
35 / 30
DMA
,
Copyright M. Smith, ECE, University of Calgary, Canada
7/31/2017
© Copyright 2026 Paperzz