Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

qm_dma.h
1 /*
2 * {% copyright %}
3 */
4
5 #ifndef __QM_DMA_H_
6 #define __QM_DMA_H_
7
8 #include "qm_common.h"
9 #include "qm_soc_regs.h"
10
11 /**
12 * DMA Driver for Quark Microcontrollers.
13 *
14 * @defgroup groupDMA DMA
15 * @{
16 */
17
18 /**
19 * DMA Handshake Polarity
20 */
21 typedef enum {
22 QM_DMA_HANDSHAKE_POLARITY_HIGH = 0x0, /**< Set HS polarity high. */
23 QM_DMA_HANDSHAKE_POLARITY_LOW = 0x1 /**< Set HS polarity low. */
24 } qm_dma_handshake_polarity_t;
25
26 /**
27 * DMA Burst Transfer Length
28 */
29 typedef enum {
30 QM_DMA_BURST_TRANS_LENGTH_1 = 0x0, /**< Burst length 1 data item. */
31 QM_DMA_BURST_TRANS_LENGTH_4 = 0x1, /**< Burst length 4 data items. */
32 QM_DMA_BURST_TRANS_LENGTH_8 = 0x2, /**< Burst length 8 data items. */
33 QM_DMA_BURST_TRANS_LENGTH_16 = 0x3, /**< Burst length 16 data items. */
34 QM_DMA_BURST_TRANS_LENGTH_32 = 0x4, /**< Burst length 32 data items. */
35 QM_DMA_BURST_TRANS_LENGTH_64 = 0x5, /**< Burst length 64 data items. */
36 QM_DMA_BURST_TRANS_LENGTH_128 =
37 0x6, /**< Burst length 128 data items. */
38 QM_DMA_BURST_TRANS_LENGTH_256 = 0x7 /**< Burst length 256 data items. */
39 } qm_dma_burst_length_t;
40
41 /**
42 * DMA Transfer Width
43 */
44 typedef enum {
45 QM_DMA_TRANS_WIDTH_8 = 0x0, /**< Transfer width of 8 bits. */
46 QM_DMA_TRANS_WIDTH_16 = 0x1, /**< Transfer width of 16 bits. */
47 QM_DMA_TRANS_WIDTH_32 = 0x2, /**< Transfer width of 32 bits. */
48 QM_DMA_TRANS_WIDTH_64 = 0x3, /**< Transfer width of 64 bits. */
49 QM_DMA_TRANS_WIDTH_128 = 0x4, /**< Transfer width of 128 bits. */
50 QM_DMA_TRANS_WIDTH_256 = 0x5 /**< Transfer width of 256 bits. */
51 } qm_dma_transfer_width_t;
52
53 /**
54 * DMA channel direction.
55 */
56 typedef enum {
57 QM_DMA_MEMORY_TO_MEMORY = 0x0, /**< Memory to memory transfer. */
58 QM_DMA_MEMORY_TO_PERIPHERAL =
59 0x1, /**< Memory to peripheral transfer. */
60 QM_DMA_PERIPHERAL_TO_MEMORY = 0x2 /**< Peripheral to memory transfer. */
61 } qm_dma_channel_direction_t;
62
63 /*
64 * DMA Transfer Type
65 */
66 typedef enum {
67 QM_DMA_TYPE_SINGLE, /**< Single block mode. */
68 QM_DMA_TYPE_MULTI_CONT, /**< Contiguous multiblock mode. */
69 QM_DMA_TYPE_MULTI_LL, /**< Link list multiblock mode. */
70 QM_DMA_TYPE_MULTI_LL_CIRCULAR /**< Link list multiblock mode with cyclic
71 operation. */
72 } qm_dma_transfer_type_t;
73
74 /**
75 * DMA channel configuration structure
76 */
77 typedef struct {
78 /** DMA channel handshake interface ID */
79 qm_dma_handshake_interface_t handshake_interface;
80
81 /** DMA channel handshake polarity */
82 qm_dma_handshake_polarity_t handshake_polarity;
83
84 /** DMA channel direction */
85 qm_dma_channel_direction_t channel_direction;
86
87 /** DMA source transfer width */
88 qm_dma_transfer_width_t source_transfer_width;
89
90 /** DMA destination transfer width */
91 qm_dma_transfer_width_t destination_transfer_width;
92
93 /** DMA source burst length */
94 qm_dma_burst_length_t source_burst_length;
95
96 /** DMA destination burst length */
97 qm_dma_burst_length_t destination_burst_length;
98
99 /** DMA transfer type */
100 qm_dma_transfer_type_t transfer_type;
101
102 /**
103 * Client callback for DMA transfer ISR
104 *
105 * @param[in] callback_context DMA client context.
106 * @param[in] len Data length transferred.
107 * @param[in] error Error code.
108 */
109 void (*client_callback)(void *callback_context, uint32_t len,
110 int error_code);
111
112 /** DMA client context passed to the callbacks */
113 void *callback_context;
114 } qm_dma_channel_config_t;
115
116 /*
117 * Multiblock linked list node structure. The client does not need to know the
118 * internals of this struct but only its size, so that the correct memory for
119 * the linked list can be allocated (one node per DMA transfer block).
120 */
121 typedef struct {
122 uint32_t source_address; /**< Block source address. */
123 uint32_t destination_address; /**< Block destination address. */
124 uint32_t linked_list_address; /**< Pointer to next LLI. */
125 uint32_t ctrl_low; /**< Bottom half Ctrl register. */
126 uint32_t ctrl_high; /**< Top half Ctrl register. */
127 /**< Destination/source status writebacks are disabled. */
128 } qm_dma_linked_list_item_t;
129
130 /**
131 * DMA single block transfer configuration structure
132 */
133 typedef struct {
134 uint32_t block_size; /**< DMA block size, Min = 1, Max = 4095. */
135 uint32_t *source_address; /**< DMA source transfer address. */
136 uint32_t *destination_address; /**< DMA destination transfer address. */
137
138 } qm_dma_transfer_t;
139
140 /**
141 * DMA multiblock transfer configuration structure
142 */
143 typedef struct {
144 uint32_t *source_address; /**< First block source address. */
145 uint32_t *destination_address; /**< First block destination address. */
146 uint16_t block_size; /**< DMA block size, Min = 1, Max = 4095. */
147 uint16_t
148 num_blocks; /**< Number of contiguous blocks to be transfered. */
149 qm_dma_linked_list_item_t *linked_list_first; /**< First block LLI
150 descriptor or NULL
151 (contiguous mode) */
152 } qm_dma_multi_transfer_t;
153
154 /**
155 * Initialise the DMA controller.
156 *
157 * The DMA controller and channels are first disabled.
158 * All DMA controller interrupts are masked
159 * using the controllers interrupt masking registers. The system
160 * DMA interrupts are then unmasked. Finally the DMA controller
161 * is enabled. This function must only be called once as it
162 * resets the DMA controller and interrupt masking.
163 *
164 * @param[in] dma DMA instance.
165 *
166 * @return Standard errno return type for QMSI.
167 * @retval 0 on success.
168 * @retval Negative @ref errno for possible error codes.
169 */
170 int qm_dma_init(const qm_dma_t dma);
171
172 /**
173 * Setup a DMA channel configuration.
174 *
175 * Configures the channel source width, burst size, channel direction,
176 * handshaking interface, transfer type and registers the client callback and
177 * callback context. qm_dma_init() must first be called before configuring a
178 * channel. This function only needs to be called once unless a channel is being
179 * repurposed or its transfer type is changed.
180 *
181 * @param[in] dma DMA instance.
182 * @param[in] channel_id The channel to start.
183 * @param[in] channel_config The DMA channel configuration as
184 * defined by the DMA client. This must not be NULL.
185 *
186 * @return Standard errno return type for QMSI.
187 * @retval 0 on success.
188 * @retval Negative @ref errno for possible error codes.
189 */
190 int qm_dma_channel_set_config(const qm_dma_t dma,
191 const qm_dma_channel_id_t channel_id,
192 qm_dma_channel_config_t *const channel_config);
193
194 /**
195 * Setup a DMA single block transfer.
196 *
197 * Configure the source address,destination addresses and block size.
198 * qm_dma_channel_set_config() must first be called before
199 * configuring a transfer. qm_dma_transfer_set_config() must
200 * be called before starting every transfer, even if the
201 * addresses and block size remain unchanged.
202 *
203 * @param[in] dma DMA instance.
204 * @param[in] channel_id The channel to start.
205 * @param[in] transfer_config The transfer DMA configuration
206 * as defined by the dma client.
207 * This must not be NULL.
208 *
209 * @return Standard errno return type for QMSI.
210 * @retval 0 on success.
211 * @retval Negative @ref errno for possible error codes.
212 */
213 int qm_dma_transfer_set_config(const qm_dma_t dma,
214 const qm_dma_channel_id_t channel_id,
215 qm_dma_transfer_t *const transfer_config);
216
217 /**
218 * Setup a DMA multiblock transfer.
219 *
220 * If the DMA channel has been configured for contiguous multiblock transfers,
221 * this function sets the source address, destination address, block size and
222 * number of block parameters needed to perform a continguous multiblock
223 * transfer. The linked_list_first parameter in the transfer struct is ignored.
224 *
225 * If the DMA channel has been configured for linked-list multiblock transfers,
226 * this function populates a linked list in the client memory area pointed at
227 * by the linked_list_first parameter in the transfer struct, using the provided
228 * parameters source address, destination address, block size and number of
229 * blocks (equal to the number of LLIs). This function may be called repeteadly
230 * in order to add different client buffers for transmission/reception that are
231 * not contiguous in memory (scatter-gather) in a buffer chain fashion. When
232 * calling qm_dma_transfer_start, the DMA core sees a single linked list built
233 * using consecutive calls to this function. Furthermore, if the transfer type
234 * is linked-list cyclic, the linked_list_address parameter of the last LLI
235 * points at the first LLI. The client needs to allocate enough memory starting
236 * at linked_list_first for the whole set of LLIs to fit, i.e. (num_blocks *
237 * sizeof(qm_dma_linked_list_item_t)).
238 *
239 * The DMA driver manages the block interrupts so that only when the last block
240 * of a buffer has been transfered, the client callback is invoked. Note that
241 * in linked-list mode, each buffer transfer results on a client callback, and
242 * all buffers need to contain the same number of blocks.
243 *
244 * qm_dma_multi_transfer_set_config() must be called before starting every
245 * transfer, even if the addresses, block size and other configuration
246 * information remain unchanged.
247 *
248 * @param[in] dma DMA instance.
249 * @param[in] channel_id The channel to start.
250 * @param[in] multi_transfer_config The transfer DMA configuration as defined by
251 * the dma client. This must not be NULL.
252 *
253 * @return Standard errno return type for QMSI.
254 * @retval 0 on success.
255 * @retval Negative @ref errno for possible error codes.
256 */
257 int qm_dma_multi_transfer_set_config(
258 const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
259 qm_dma_multi_transfer_t *const multi_transfer_config);
260
261 /**
262 * Start a DMA transfer.
263 *
264 * qm_dma_transfer_set_config() mustfirst be called
265 * before starting a transfer.
266 *
267 * @param[in] dma DMA instance.
268 * @param[in] channel_id The channel to start.
269 *
270 * @return Standard errno return type for QMSI.
271 * @retval 0 on success.
272 * @retval Negative @ref errno for possible error codes.
273 */
274 int qm_dma_transfer_start(const qm_dma_t dma,
275 const qm_dma_channel_id_t channel_id);
276
277 /**
278 * Terminate a DMA transfer.
279 *
280 * This function is only called if a transfer needs to be terminated manually.
281 * This may be require if an expected transfer complete callback
282 * has not been received. Terminating the transfer will
283 * trigger the transfer complete callback. The length
284 * returned by the callback is the transfer length at the
285 * time that the transfer was terminated.
286 *
287 * @param[in] dma DMA instance.
288 * @param[in] channel_id The channel to stop.
289 *
290 * @return Standard errno return type for QMSI.
291 * @retval 0 on success.
292 * @retval Negative @ref errno for possible error codes.
293 */
294 int qm_dma_transfer_terminate(const qm_dma_t dma,
295 const qm_dma_channel_id_t channel_id);
296
297 /**
298 * Setup and start memory to memory transfer.
299 *
300 * This function will setup a memory to memory transfer by
301 * calling qm_dma_transfer_setup() and will then start the
302 * transfer by calling qm_dma_transfer_start(). This is
303 * done for consistency across user applications.
304 *
305 * @param[in] dma DMA instance.
306 * @param[in] channel_id The channel to start.
307 * @param[in] transfer_config The transfer DMA configuration
308 * as defined by the dma client.
309 * This must not be NULL.
310 *
311 * @return Standard errno return type for QMSI.
312 * @retval 0 on success.
313 * @retval Negative @ref errno for possible error codes.
314 */
315 int qm_dma_transfer_mem_to_mem(const qm_dma_t dma,
316 const qm_dma_channel_id_t channel_id,
317 qm_dma_transfer_t *const transfer_config);
318
319 /**
320 * Save DMA peripheral's context.
321 *
322 * Saves the configuration of the specified DMA peripheral
323 * before entering sleep.
324 *
325 * @param[in] dma DMA device.
326 * @param[out] ctx DMA context structure. This must not be NULL.
327 *
328 * @return Standard errno return type for QMSI.
329 * @retval 0 on success.
330 * @retval Negative @ref errno for possible error codes.
331 */
332 int qm_dma_save_context(const qm_dma_t dma, qm_dma_context_t *const ctx);
333
334 /**
335 * Restore DMA peripheral's context.
336 *
337 * Restore the configuration of the specified DMA peripheral
338 * after exiting sleep.
339 *
340 * @param[in] dma DMA device.
341 * @param[in] ctx DMA context structure. This must not be NULL.
342 *
343 * @return Standard errno return type for QMSI.
344 * @retval 0 on success.
345 * @retval Negative @ref errno for possible error codes.
346 */
347 int qm_dma_restore_context(const qm_dma_t dma,
348 const qm_dma_context_t *const ctx);
349
350 /**
351 * @}
352 */
353
354 #endif /* __QM_DMA_H_ */
qm_dma_multi_transfer_t::num_blocks
uint16_t num_blocks
Number of contiguous blocks to be transfered.
Definition: qm_dma.h:148
QM_DMA_BURST_TRANS_LENGTH_256
Burst length 256 data items.
Definition: qm_dma.h:38
qm_dma_channel_config_t
DMA channel configuration structure.
Definition: qm_dma.h:77
qm_dma_channel_config_t::transfer_type
qm_dma_transfer_type_t transfer_type
DMA transfer type.
Definition: qm_dma.h:100
qm_dma_multi_transfer_t::destination_address
uint32_t * destination_address
First block destination address.
Definition: qm_dma.h:145
QM_DMA_TYPE_MULTI_LL
Link list multiblock mode.
Definition: qm_dma.h:69
QM_DMA_BURST_TRANS_LENGTH_8
Burst length 8 data items.
Definition: qm_dma.h:32
qm_dma_transfer_t::destination_address
uint32_t * destination_address
DMA destination transfer address.
Definition: qm_dma.h:136
qm_dma_t
qm_dma_t
DMA instances.
Definition: qm_soc_regs.h:1480
QM_DMA_BURST_TRANS_LENGTH_64
Burst length 64 data items.
Definition: qm_dma.h:35
QM_DMA_TRANS_WIDTH_64
Transfer width of 64 bits.
Definition: qm_dma.h:48
QM_DMA_BURST_TRANS_LENGTH_16
Burst length 16 data items.
Definition: qm_dma.h:33
qm_dma_transfer_t
DMA single block transfer configuration structure.
Definition: qm_dma.h:133
qm_dma_channel_config_t::source_burst_length
qm_dma_burst_length_t source_burst_length
DMA source burst length.
Definition: qm_dma.h:94
qm_dma_context_t
DMA context type.
Definition: qm_soc_regs.h:1911
qm_dma_multi_transfer_t::linked_list_first
qm_dma_linked_list_item_t * linked_list_first
First block LLI descriptor or NULL (contiguous mode)
Definition: qm_dma.h:149
qm_dma_transfer_t::block_size
uint32_t block_size
DMA block size, Min = 1, Max = 4095.
Definition: qm_dma.h:134
qm_dma_channel_config_t::callback_context
void * callback_context
DMA client context passed to the callbacks.
Definition: qm_dma.h:113
QM_DMA_TYPE_MULTI_LL_CIRCULAR
Link list multiblock mode with cyclic operation.
Definition: qm_dma.h:70
QM_DMA_TRANS_WIDTH_8
Transfer width of 8 bits.
Definition: qm_dma.h:45
qm_dma_transfer_type_t
qm_dma_transfer_type_t
Definition: qm_dma.h:66
qm_dma_handshake_polarity_t
qm_dma_handshake_polarity_t
DMA Handshake Polarity.
Definition: qm_dma.h:21
qm_dma_restore_context
int qm_dma_restore_context(const qm_dma_t dma, const qm_dma_context_t *const ctx)
Restore DMA peripheral's context.
Definition: qm_dma.c:705
qm_dma_channel_config_t::handshake_interface
qm_dma_handshake_interface_t handshake_interface
DMA channel handshake interface ID.
Definition: qm_dma.h:79
qm_dma_transfer_set_config
int qm_dma_transfer_set_config(const qm_dma_t dma, const qm_dma_channel_id_t channel_id, qm_dma_transfer_t *const transfer_config)
Setup a DMA single block transfer.
Definition: qm_dma.c:345
QM_DMA_MEMORY_TO_MEMORY
Memory to memory transfer.
Definition: qm_dma.h:57
qm_dma_burst_length_t
qm_dma_burst_length_t
DMA Burst Transfer Length.
Definition: qm_dma.h:29
qm_dma_channel_config_t::handshake_polarity
qm_dma_handshake_polarity_t handshake_polarity
DMA channel handshake polarity.
Definition: qm_dma.h:82
QM_DMA_HANDSHAKE_POLARITY_LOW
Set HS polarity low.
Definition: qm_dma.h:23
qm_dma_multi_transfer_set_config
int qm_dma_multi_transfer_set_config(const qm_dma_t dma, const qm_dma_channel_id_t channel_id, qm_dma_multi_transfer_t *const multi_transfer_config)
Setup a DMA multiblock transfer.
Definition: qm_dma.c:437
qm_dma_multi_transfer_t::block_size
uint16_t block_size
DMA block size, Min = 1, Max = 4095.
Definition: qm_dma.h:146
QM_DMA_TYPE_SINGLE
Single block mode.
Definition: qm_dma.h:67
QM_DMA_BURST_TRANS_LENGTH_128
Burst length 128 data items.
Definition: qm_dma.h:36
QM_DMA_PERIPHERAL_TO_MEMORY
Peripheral to memory transfer.
Definition: qm_dma.h:60
qm_dma_channel_config_t::destination_burst_length
qm_dma_burst_length_t destination_burst_length
DMA destination burst length.
Definition: qm_dma.h:97
qm_dma_channel_config_t::destination_transfer_width
qm_dma_transfer_width_t destination_transfer_width
DMA destination transfer width.
Definition: qm_dma.h:91
qm_dma_channel_set_config
int qm_dma_channel_set_config(const qm_dma_t dma, const qm_dma_channel_id_t channel_id, qm_dma_channel_config_t *const channel_config)
Setup a DMA channel configuration.
Definition: qm_dma.c:254
QM_DMA_BURST_TRANS_LENGTH_4
Burst length 4 data items.
Definition: qm_dma.h:31
QM_DMA_BURST_TRANS_LENGTH_32
Burst length 32 data items.
Definition: qm_dma.h:34
qm_dma_channel_config_t::source_transfer_width
qm_dma_transfer_width_t source_transfer_width
DMA source transfer width.
Definition: qm_dma.h:88
qm_dma_transfer_terminate
int qm_dma_transfer_terminate(const qm_dma_t dma, const qm_dma_channel_id_t channel_id)
Terminate a DMA transfer.
Definition: qm_dma.c:618
qm_dma_channel_direction_t
qm_dma_channel_direction_t
DMA channel direction.
Definition: qm_dma.h:56
qm_dma_transfer_start
int qm_dma_transfer_start(const qm_dma_t dma, const qm_dma_channel_id_t channel_id)
Start a DMA transfer.
Definition: qm_dma.c:582
QM_DMA_HANDSHAKE_POLARITY_HIGH
Set HS polarity high.
Definition: qm_dma.h:22
qm_dma_init
int qm_dma_init(const qm_dma_t dma)
Initialise the DMA controller.
Definition: qm_dma.c:208
QM_DMA_BURST_TRANS_LENGTH_1
Burst length 1 data item.
Definition: qm_dma.h:30
qm_dma_multi_transfer_t
DMA multiblock transfer configuration structure.
Definition: qm_dma.h:143
QM_DMA_MEMORY_TO_PERIPHERAL
Memory to peripheral transfer.
Definition: qm_dma.h:58
QM_DMA_TRANS_WIDTH_16
Transfer width of 16 bits.
Definition: qm_dma.h:46
qm_dma_transfer_t::source_address
uint32_t * source_address
DMA source transfer address.
Definition: qm_dma.h:135
qm_dma_transfer_width_t
qm_dma_transfer_width_t
DMA Transfer Width.
Definition: qm_dma.h:44
QM_DMA_TRANS_WIDTH_32
Transfer width of 32 bits.
Definition: qm_dma.h:47
QM_DMA_TRANS_WIDTH_256
Transfer width of 256 bits.
Definition: qm_dma.h:50
QM_DMA_TYPE_MULTI_CONT
Contiguous multiblock mode.
Definition: qm_dma.h:68
qm_dma_transfer_mem_to_mem
int qm_dma_transfer_mem_to_mem(const qm_dma_t dma, const qm_dma_channel_id_t channel_id, qm_dma_transfer_t *const transfer_config)
Setup and start memory to memory transfer.
Definition: qm_dma.c:656
qm_dma_channel_id_t
qm_dma_channel_id_t
DMA channel IDs.
Definition: qm_soc_regs.h:1486
qm_dma_multi_transfer_t::source_address
uint32_t * source_address
First block source address.
Definition: qm_dma.h:144
qm_dma_handshake_interface_t
qm_dma_handshake_interface_t
DMA hardware handshake interfaces.
Definition: qm_soc_regs.h:1493
QM_DMA_TRANS_WIDTH_128
Transfer width of 128 bits.
Definition: qm_dma.h:49
qm_dma_channel_config_t::channel_direction
qm_dma_channel_direction_t channel_direction
DMA channel direction.
Definition: qm_dma.h:85
qm_dma_save_context
int qm_dma_save_context(const qm_dma_t dma, qm_dma_context_t *const ctx)
Save DMA peripheral's context.
Definition: qm_dma.c:681