1 |
202 |
olivier.gi |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
2 |
|
|
<html><head><title>openMSP430 DMA Interface</title>
|
3 |
|
|
|
4 |
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>
|
5 |
|
|
<h3>Table of content</h3>
|
6 |
|
|
|
7 |
|
|
<ul>
|
8 |
|
|
<li><a href="#1.%20Introduction"> 1. Introduction</a></li>
|
9 |
|
|
<li><a href="#2.%20Signal%20list"> 2. Signal list</a></li>
|
10 |
|
|
<li><a href="#3.%20Protocol"> 3. Protocol</a></li>
|
11 |
|
|
<ul>
|
12 |
|
|
<li><a href="#3.1%20Simple%20transfer"> 3.1 Simple transfer</a></li>
|
13 |
|
|
<li><a href="#3.2%20Transfer%20with%20wait%20states"> 3.2 Transfer with wait states</a></li>
|
14 |
|
|
<li><a href="#3.3%20Multiple%20transfers"> 3.3 Multiple transfers</a></li>
|
15 |
|
|
<li><a href="#3.4%20Transfer%20response"> 3.4 Transfer response</a></li>
|
16 |
|
|
<li><a href="#3.5%20Priority%20control"> 3.5 Priority control</a></li>
|
17 |
|
|
<ul>
|
18 |
|
|
<li><a href="#3.5.1%20Data%20rate%20control"> 3.5.1 Data rate control</a></li>
|
19 |
|
|
<li><a href="#3.5.2%20Bootloader%20case"> 3.5.2 Bootloader case</a></li>
|
20 |
|
|
</ul>
|
21 |
|
|
</ul>
|
22 |
|
|
<li><a href="#4.%20ASIC%20Implementation">4. ASIC Implementation</a></li>
|
23 |
|
|
<ul>
|
24 |
|
|
<li><a href="#4.1%20Clock%20domains"> 4.1 Clock domains</a></li>
|
25 |
|
|
<li><a href="#4.2%20DMA%20wakeup"> 4.2 DMA wakeup</a></li>
|
26 |
|
|
</ul>
|
27 |
|
|
</ul>
|
28 |
|
|
|
29 |
|
|
<a name="1.%20Introduction"></a>
|
30 |
|
|
<h1>1. Introduction</h1>
|
31 |
|
|
|
32 |
|
|
The openMSP430 Direct-Memory-Access interface acts as a gateway to the whole logical 64kB memory space and can
|
33 |
|
|
be enabled be uncommenting the DMA_IF_EN macro in the <i>"openMSP430_defines.sv"</i> file:<br><br>
|
34 |
|
|
<code>
|
35 |
|
|
//-------------------------------------------------------<br>
|
36 |
|
|
// Include/Exclude DMA interface support<br>
|
37 |
|
|
//-------------------------------------------------------<br>
|
38 |
|
|
`define DMA_IF_EN<br>
|
39 |
|
|
</code>
|
40 |
|
|
<br>
|
41 |
|
|
It supports the efficient connection of Bootloader, DMA controller, Memory-BIST or any other hardware
|
42 |
204 |
olivier.gi |
unit requiring direct read/write access to the CPU memory space.
|
43 |
202 |
olivier.gi |
<br>
|
44 |
|
|
The interface is also designed as to reuse the existing arbitration logic within the memory-backbone
|
45 |
|
|
and thus minimize to timing costs of its physical implementation (i.e. no additional muxing layer on
|
46 |
|
|
an already critical timing path).
|
47 |
|
|
<br><br>
|
48 |
|
|
An simple system using the DMA interface typically consists of a DMA master directly connected to
|
49 |
|
|
openMSP430 core:
|
50 |
204 |
olivier.gi |
<br><img src="http://opencores.org/usercontent,img,1431381105" alt="DMA simple systems" title="DMA simple systems" width="80%">
|
51 |
202 |
olivier.gi |
<br><br>
|
52 |
|
|
However, it is also possible to combine different DMA masters using a custom arbitration logic:
|
53 |
204 |
olivier.gi |
<br><img src="http://opencores.org/usercontent,img,1431381122" alt="DMA complex system" title="DMA complex system" width="80%">
|
54 |
202 |
olivier.gi |
<br><br>
|
55 |
|
|
|
56 |
|
|
<a name="2.%20Signal%20list"></a>
|
57 |
|
|
<h1>2. Signal list</h1>
|
58 |
|
|
|
59 |
|
|
<table border="1">
|
60 |
|
|
<tbody>
|
61 |
|
|
<tr align="center">
|
62 |
|
|
<td><b>Name</b></td>
|
63 |
|
|
<td><b>Source</b></td>
|
64 |
|
|
<td><b>Type</b></td>
|
65 |
|
|
<td><b>Description</b></td>
|
66 |
|
|
</tr>
|
67 |
|
|
<tr>
|
68 |
|
|
<td><b>MCLK</b><br><small>System clock</small></td>
|
69 |
|
|
<td align="center"> openMSP430 </td>
|
70 |
|
|
<td align="center">System</td>
|
71 |
|
|
<td>This clock times all DMA transfers. All signal timings are related to the rising edge of MCLK.</td>
|
72 |
|
|
</tr>
|
73 |
|
|
<tr>
|
74 |
|
|
<td><b>PUC_RST</b><br><small>System reset</small></td>
|
75 |
|
|
<td align="center"> openMSP430 </td>
|
76 |
|
|
<td align="center">System</td>
|
77 |
|
|
<td>The system reset is active HIGH and is used to reset the sytem, including the DMA master(s).</td>
|
78 |
|
|
</tr>
|
79 |
|
|
<tr>
|
80 |
|
|
<td><b>DMA_WKUP</b><br><small>Wakeup</small></td>
|
81 |
|
|
<td align="center">DMA Master<br><small>(Asynchronous)</small></td>
|
82 |
|
|
<td align="center">System</td>
|
83 |
|
|
<td>When HIGH in a Low-Power-Mode, the wakeup signal restores the clocks necessary for the DMA transfer (see <a href="#4.%20ASIC%20Implementation">ASIC Implementation</a> section).</td>
|
84 |
|
|
</tr>
|
85 |
|
|
<tr>
|
86 |
|
|
<td><b>DMA_ADDR[15:1]</b><br><small>Address bus</small></td>
|
87 |
|
|
<td align="center">DMA Master</td>
|
88 |
|
|
<td align="center">Address</td>
|
89 |
|
|
<td>This is the 15-bit address bus allowing to access the 64kB address space (16b words).</td>
|
90 |
|
|
</tr>
|
91 |
|
|
<tr>
|
92 |
|
|
<td><b>DMA_DIN[15:0]</b><br><small>Write data bus</small></td>
|
93 |
|
|
<td align="center">DMA Master</td>
|
94 |
|
|
<td align="center">Data</td>
|
95 |
|
|
<td>The write data bus is used to transfer data from the DMA master to openMSP430 system during write operations.</td>
|
96 |
|
|
</tr>
|
97 |
|
|
<tr>
|
98 |
|
|
<td><b>DMA_DOUT[15:0]</b><br><small>Read data bus</small></td>
|
99 |
|
|
<td align="center"> openMSP430 </td>
|
100 |
|
|
<td align="center">Data</td>
|
101 |
|
|
<td>The read data bus is used to transfer data from the openMSP430 system to the DMA master during read operations.</td>
|
102 |
|
|
</tr>
|
103 |
|
|
<tr>
|
104 |
|
|
<td><b>DMA_EN</b><br><small>Transfer enable</small></td>
|
105 |
|
|
<td align="center">DMA Master</td>
|
106 |
|
|
<td align="center">Control</td>
|
107 |
|
|
<td>Indicates that the current DMA transfer is active.</td>
|
108 |
|
|
</tr>
|
109 |
|
|
<tr>
|
110 |
|
|
<td><b>DMA_WE[1:0]</b><br><small>Transfer direction</small></td>
|
111 |
|
|
<td align="center">DMA Master</td>
|
112 |
|
|
<td align="center">Control</td>
|
113 |
|
|
<td>When HIGH, this signal indicates a write transfer on the selected byte, and a read transfer when LOW.</td>
|
114 |
|
|
</tr>
|
115 |
|
|
<tr>
|
116 |
|
|
<td><b>DMA_PRIORITY</b><br><small>Transfer priority</small></td>
|
117 |
|
|
<td align="center">DMA Master</td>
|
118 |
|
|
<td align="center">Control</td>
|
119 |
|
|
<td>When HIGH, this signal indicates a high priority DMA transfer (i.e. CPU is stopped). When LOW, low priority DMA transfer have to wait for the CPU to free the accessed ressource.</td>
|
120 |
|
|
</tr>
|
121 |
|
|
<tr>
|
122 |
|
|
<td><b>DMA_READY</b><br><small>Transfer done</small></td>
|
123 |
|
|
<td align="center"> openMSP430 </td>
|
124 |
|
|
<td align="center">Response</td>
|
125 |
|
|
<td>When HIGH the DMA_READY signal indicates that a transfer has finished on the bus. This signal may be driven LOW to add wait states to the transfer.</td>
|
126 |
|
|
</tr>
|
127 |
|
|
<tr>
|
128 |
|
|
<td><b>DMA_RESP</b><br><small>Transfer response</small></td>
|
129 |
|
|
<td align="center"> openMSP430 </td>
|
130 |
|
|
<td align="center">Response</td>
|
131 |
|
|
<td>The transfer response provides additional information on the status of a transfer (OKAY if LOW, ERROR when HIGH).</td>
|
132 |
|
|
</tr>
|
133 |
|
|
</tbody>
|
134 |
|
|
</table>
|
135 |
|
|
|
136 |
|
|
<br>
|
137 |
|
|
|
138 |
|
|
<a name="3.%20Protocol"></a>
|
139 |
|
|
<h1>3. Protocol</h1>
|
140 |
|
|
|
141 |
|
|
<a name="3.1%20Simple%20transfer"></a>
|
142 |
|
|
<h2>3.1 Simple transfer</h2>
|
143 |
|
|
|
144 |
|
|
The following figure shows the simplest transfer, one with no wait states.<br>
|
145 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431552266" alt="DMA simple transfer" title="DMA simple transfer" width="60%"><br>
|
146 |
|
|
In a simple transfer with no wait states:
|
147 |
|
|
<ul>
|
148 |
|
|
<li>The DMA master drives the address, control signals and write data onto the bus after the rising edge of MCLK.</li>
|
149 |
|
|
<li>The openMSP430 ressource (pmem/dmem/peripheral) then samples the address, control and write data information on the next rising edge of the clock.</li>
|
150 |
|
|
<li>For read access, after the openMSP430 ressource has sampled the address and control it can start to drive the read data
|
151 |
|
|
and this is sampled by the DMA master on the third rising edge of the clock.</li>
|
152 |
|
|
</ul>
|
153 |
|
|
|
154 |
|
|
<a name="3.2%20Transfer%20with%20wait%20states"></a>
|
155 |
|
|
<h2>3.2 Transfer with wait states</h2>
|
156 |
|
|
The openMSP430 can insert wait states into any transfer, as shown in the following figure, which extends
|
157 |
|
|
the transfer by two clock cycles, thus taking additional time for completion.
|
158 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431552287" alt="DMA transfer with wait states" title="DMA transfer with wait states" width="90%"><br>
|
159 |
|
|
For both read and write operations the DMA master must hold the address, control and write data stable throughout the extended cycles.
|
160 |
|
|
<br><br>
|
161 |
|
|
<b>Note:</b> wait states are inserted by the openMSP430 if the CPU is currently busy reading or writing to the same ressource that the DMA controller also wants to access.
|
162 |
|
|
<br>
|
163 |
|
|
<a name="3.3%20Multiple%20transfers"></a>
|
164 |
|
|
<h2>3.3 Multiple transfers</h2>
|
165 |
|
|
|
166 |
|
|
The following figure shows three transfers to unrelated addresses, A, B & C.
|
167 |
|
|
|
168 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431552310" alt="DMA multiple transfer" title="DMA multiple transfer" width="100%"><br>
|
169 |
|
|
We can here observe:
|
170 |
|
|
<ul>
|
171 |
|
|
<li>the transfers to addresses A and C are both zero wait state.</li>
|
172 |
|
|
<li>the transfer to address B is one wait state.</li>
|
173 |
|
|
<li>the read data from A is available during the <b>first</b> clock cycle when the address and control B are applied.</li>
|
174 |
|
|
<li>the read data from B is available during the clock cycle when the address and control C are applied.</li>
|
175 |
|
|
</ul>
|
176 |
|
|
|
177 |
|
|
<a name="3.4%20Transfer%20response"></a>
|
178 |
|
|
<h2>3.4 Transfer response</h2>
|
179 |
|
|
|
180 |
|
|
The following figure shows two transfers to unrelated addresses, A & B.
|
181 |
|
|
|
182 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431552329" alt="DMA error response" title="DMA error response" width="70%"><br>
|
183 |
|
|
We can here observe:
|
184 |
|
|
<ul>
|
185 |
|
|
<li>the transfer to address A returns an ERROR response (note that transfer returning an ERROR response <b>never</b> have wait states).</li>
|
186 |
|
|
<li>the transfer to address B is a regular transfer (i.e. OKAY response) without wait state.</li>
|
187 |
|
|
</ul>
|
188 |
|
|
<b>Note:</b> an ERROR response are generated if the transfer address lays between the program and data memories, where nothing is mapped.
|
189 |
|
|
<br>
|
190 |
|
|
|
191 |
|
|
<a name="3.5%20Priority%20control"></a>
|
192 |
|
|
<h2>3.5 Priority control</h2>
|
193 |
|
|
|
194 |
|
|
<a name="3.5.1%20Data%20rate%20control"></a>
|
195 |
|
|
<h3>3.5.1 Data rate control</h3>
|
196 |
|
|
The DMA_PRIORITY control signal is available to the DMA master for controlling the application data rate requirements.<br>
|
197 |
|
|
<ul>
|
198 |
|
|
<li>When CLEARED, DMA transfers have a <b>fixed lower priority</b> than the CPU. This means that depending on the
|
199 |
|
|
exact kind of instructions currently executed by the CPU, the completion time of the DMA transfers cannot be
|
200 |
|
|
predicted (i.e. DMA transfers are completed only when the CPU is not accessing the trageted ressource).</li>
|
201 |
|
|
<li>When SET, DMA transfers have a <b>fixed higher priority</b> over the CPU. This means that the CPU will
|
202 |
|
|
will stop execution and give the full bandwidth to the DMA controller. In that scenario, DMA transfers complete
|
203 |
|
|
in a single clock cycle (i.e. without any wait states), as the targeted ressources are always available
|
204 |
|
|
(i.e. the CPU is not executing).</li>
|
205 |
|
|
<li>If the application requirements need something in between (namely a minimum DMA transfer data-rate with reduced effect
|
206 |
204 |
olivier.gi |
on the firmware exection), then the DMA master can dynamically change the DMA_PRIORITY as required.</li>
|
207 |
202 |
olivier.gi |
</ul>
|
208 |
|
|
These scenario are illustrated in the following figure.
|
209 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431638398" alt="DMA error response" title="DMA error response" width="100%"><br>
|
210 |
|
|
We can here observe:
|
211 |
|
|
<ul>
|
212 |
|
|
<li>phase <b>A</b> illustrates LOW-PRIORITY transfers. Less DMA transfer are completed during that time as shown by the number of wait states.</li>
|
213 |
|
|
<li>phase <b>B</b> illustrates HIGH-PRIORITY transfers. DMA transfers are completed with each clock cycle (i.e. no wait state).</li>
|
214 |
|
|
<li>phase <b>C</b> illustrates MIXED-PRIORITY transfers where the DMA controller is dynamically adjusting the priority to achieve its target minimum data-rate.</li>
|
215 |
|
|
</ul>
|
216 |
|
|
|
217 |
|
|
<a name="3.5.2%20Bootloader%20case"></a>
|
218 |
|
|
<h3>3.5.2 Bootloader case</h3>
|
219 |
|
|
In general, the purpose of a bootloader is to initialize the program memory at startup (i.e after Power-On-Reset).<br>
|
220 |
|
|
DMA transfers driven by the bootloader should therefore be performed in HIGH-PRIORITY mode, as the CPU should not start
|
221 |
|
|
executing instructions on a non-initialized memory.<br>
|
222 |
|
|
Once the memory initialization is completed, a reset pulse should be generated by the bootloader to make sure the CPU
|
223 |
|
|
re-fetches the new RESET vector from the program memory.<br>
|
224 |
|
|
<br>
|
225 |
|
|
A bootloader could be for example be connected as following:
|
226 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431724552" alt="DMA bootloader" title="DMA bootloader" width="50%"><br>
|
227 |
|
|
|
228 |
|
|
The bootloading sequence is illustrated in the following figure:
|
229 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431724534" alt="DMA bootloader waveform" title="DMA bootloader waveform" width="100%"><br>
|
230 |
|
|
|
231 |
|
|
<a name="4.%20ASIC%20Implementation"></a>
|
232 |
|
|
<h1>4. ASIC Implementation</h1>
|
233 |
|
|
|
234 |
|
|
<a name="4.1%20Clock%20domains"></a>
|
235 |
|
|
<h2>4.1 Clock domains</h2>
|
236 |
|
|
If the ASIC low power options are enabled, it is possible to perform DMA accesses when the main CPU is in <b>any</b> Low-Power-Mode (LPMx).<br>
|
237 |
|
|
However, in order to avoid unnecessary power consumption while restoring the clocks for the DMA transfer, the MCLK
|
238 |
|
|
system clock has been split into two clock domains.
|
239 |
|
|
<ul>
|
240 |
|
|
<li>MCLK_CPU : clocks the CPU core itself, namely the frontend and execution logic.
|
241 |
|
|
When the CPU is in LPMx mode, this clock is ALWAYS OFF, even if a DMA transfer is currently on going.</li>
|
242 |
|
|
<li>MCLK_DMA : clocks the rest of the system (excluding the DBG interface) and gives access to the 64kB memory
|
243 |
|
|
adddress range to the DMA master. This clock is restored in LPMx modes by asserting the DMA_WKUP pin.</li>
|
244 |
|
|
</ul>
|
245 |
|
|
This table summarizes the clock operating modes:<br><br>
|
246 |
|
|
<table border="1">
|
247 |
|
|
<tbody><tr align="center">
|
248 |
|
|
<td rowspan="2"><b>Clock Name</b></td>
|
249 |
|
|
<td rowspan="2"><b>CPU Active</b></td>
|
250 |
|
|
<td colspan="2"><b>CPU Low-Power-Mode</b></td>
|
251 |
|
|
</tr>
|
252 |
|
|
<tr align="center">
|
253 |
|
|
<td>DMA_WKUP=0</td>
|
254 |
|
|
<td>DMA_WKUP=1</td>
|
255 |
|
|
</tr>
|
256 |
|
|
<tr align="center">
|
257 |
|
|
<td>MCLK_CPU</td>
|
258 |
|
|
<td>ON</td>
|
259 |
|
|
<td>OFF</td>
|
260 |
|
|
<td>OFF</td>
|
261 |
|
|
</tr>
|
262 |
|
|
<tr align="center">
|
263 |
|
|
<td>MCLK_DMA</td>
|
264 |
|
|
<td>ON</td>
|
265 |
|
|
<td>OFF</td>
|
266 |
|
|
<td>ON</td>
|
267 |
|
|
</tr>
|
268 |
|
|
</tbody>
|
269 |
|
|
</table>
|
270 |
|
|
<br>
|
271 |
|
|
Clock domains are illustrated in the following diagram:
|
272 |
|
|
<br><img src="http://opencores.org/usercontent,img,1431726489" alt="DMA clock domains" title="DMA clock domains" width="50%"><br>
|
273 |
|
|
|
274 |
|
|
<a name="4.2%20DMA%20wakeup"></a>
|
275 |
|
|
<h2>4.2 DMA wakeup</h2>
|
276 |
|
|
As shown in the "Peripherals" chapter, the Basic-Clock-Module has several
|
277 |
|
|
control registers giving some flexibility to the firmware as to which clocks
|
278 |
|
|
are restored when the DMA_WKUP pin is asserted.<br><br>
|
279 |
|
|
|
280 |
|
|
<table border="1">
|
281 |
|
|
<tbody><tr align="center">
|
282 |
|
|
<td rowspan="2"><b>Register Name</b></td>
|
283 |
|
|
<td rowspan="2"><b>Address</b></td>
|
284 |
|
|
<td colspan="16"><b>Bit Field</b></td>
|
285 |
|
|
</tr>
|
286 |
|
|
<tr align="center">
|
287 |
|
|
<td>7</td><td>6</td><td>5</td><td>4</td>
|
288 |
|
|
<td>3</td><td>2</td><td>1</td><td>0</td>
|
289 |
|
|
</tr>
|
290 |
|
|
<tr align="center">
|
291 |
|
|
<td>BCSTL1</td>
|
292 |
|
|
<td>0x0006</td>
|
293 |
|
|
<td colspan="2"><small><i>unused</i></small></td>
|
294 |
|
|
<td colspan="2"><b>DIVAx</b></td>
|
295 |
|
|
<td colspan="1"><b><small>DMA_SCG1</small></b></td>
|
296 |
|
|
<td colspan="1"><b><small>DMA_SCG0</small></b></td>
|
297 |
|
|
<td colspan="1"><b><small>DMA_OSCOFF</small></b></td>
|
298 |
|
|
<td colspan="1"><b><small>DMA_CPUOFF</small></b></td>
|
299 |
|
|
</tr>
|
300 |
|
|
</tbody>
|
301 |
|
|
</table>
|
302 |
|
|
<ul>
|
303 |
|
|
<li><b>DMA_SCG1</b>   : Restore SMCLK with DMA wakeup</li>
|
304 |
|
|
<li><b>DMA_SCG0</b>   : Restore DCO oscillator with DMA wakeup</li>
|
305 |
|
|
<li><b>DMA_OSCOFF</b> : Restore LFXT oscillator with DMA wakeup</li>
|
306 |
|
|
<li><b>DMA_CPUOFF</b> : Restore MCLK_DMA with DMA wakeup</li>
|
307 |
|
|
</ul>
|
308 |
|
|
Note that the DMA_WKUP functionality can be disabled by keeping all these bitfields <b>CLEARED</b>.
|
309 |
|
|
<br>
|
310 |
|
|
<br>
|
311 |
|
|
|
312 |
204 |
olivier.gi |
</body></html>
|