1 #ifndef _BFLB_DMA_H
2 #define _BFLB_DMA_H
3 
4 #include "bflb_core.h"
5 
6 /** @addtogroup LHAL
7   * @{
8   */
9 
10 /** @addtogroup DMA
11   * @{
12   */
13 
14 /** @defgroup DMA_DIRECTION dma transfer direction definition
15   * @{
16   */
17 #define DMA_MEMORY_TO_MEMORY       0
18 #define DMA_MEMORY_TO_PERIPH       1
19 #define DMA_PERIPH_TO_MEMORY       2
20 #define DMA_PERIPH_TO_PERIPH       3
21 /**
22   * @}
23   */
24 
25 /** @defgroup DMA_ADDR_INCREMENT dma source and destination address increment definition
26   * @{
27   */
28 #define DMA_ADDR_INCREMENT_DISABLE 0
29 #define DMA_ADDR_INCREMENT_ENABLE  1
30 /**
31   * @}
32   */
33 
34 /** @defgroup DMA_DATA_WIDTH dma data width definition
35   * @{
36   */
37 #define DMA_DATA_WIDTH_8BIT        0
38 #define DMA_DATA_WIDTH_16BIT       1
39 #define DMA_DATA_WIDTH_32BIT       2
40 /**
41   * @}
42   */
43 
44 /** @defgroup DMA_BURST_COUNT dma burst increment count definition
45   * @{
46   */
47 #define DMA_BURST_INCR1            0
48 #define DMA_BURST_INCR4            1
49 #define DMA_BURST_INCR8            2
50 #define DMA_BURST_INCR16           3
51 /**
52   * @}
53   */
54 
55 #if defined(BL702) || defined(BL602) || defined(BL702L)
56 /** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
57   * @{
58   */
59 #define DMA_ADDR_UART0_TDR (0x4000A000 + 0x88)
60 #define DMA_ADDR_UART0_RDR (0x4000A000 + 0x8C)
61 #if !defined(BL702L)
62 #define DMA_ADDR_UART1_TDR (0x4000A100 + 0x88)
63 #define DMA_ADDR_UART1_RDR (0x4000A100 + 0x8C)
64 #endif
65 #define DMA_ADDR_I2C0_TDR (0x4000A300 + 0x88)
66 #define DMA_ADDR_I2C0_RDR (0x4000A300 + 0x8C)
67 #define DMA_ADDR_SPI0_TDR (0x4000A200 + 0x88)
68 #define DMA_ADDR_SPI0_RDR (0x4000A200 + 0x8C)
69 #if !defined(BL702L)
70 #define DMA_ADDR_I2S_TDR (0x4000AA00 + 0x88)
71 #define DMA_ADDR_I2S_RDR (0x4000AA00 + 0x8C)
72 #endif
73 #define DMA_ADDR_ADC_RDR (0x40002000 + 0x04)
74 #if !defined(BL702L)
75 #define DMA_ADDR_DAC_TDR (0x40002000 + 0x48)
76 #endif
77 #if defined(BL702L)
78 #define DMA_ADDR_IR_TDR    (0x4000A600 + 0x88)
79 #define DMA_ADDR_AUADC_RDR (0x4000AD00 + 0x88)
80 #endif
81 /**
82   * @}
83   */
84 
85 /** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
86   * @{
87   */
88 #define DMA_REQUEST_NONE     0x00000000
89 #define DMA_REQUEST_UART0_RX 0x00000000
90 #define DMA_REQUEST_UART0_TX 0x00000001
91 #if !defined(BL702L)
92 #define DMA_REQUEST_UART1_RX 0x00000002
93 #define DMA_REQUEST_UART1_TX 0x00000003
94 #endif
95 #define DMA_REQUEST_I2C0_RX 0x00000006
96 #define DMA_REQUEST_I2C0_TX 0x00000007
97 #if defined(BL702L)
98 #define DMA_REQUEST_IR_TX 0x00000008
99 #endif
100 #define DMA_REQUEST_SPI0_RX 0x0000000A
101 #define DMA_REQUEST_SPI0_TX 0x0000000B
102 #if defined(BL702L)
103 #define DMA_REQUEST_AUADC_RX 0x0000000D
104 #endif
105 #if !defined(BL702L)
106 #define DMA_REQUEST_I2S_RX 0x00000014
107 #define DMA_REQUEST_I2S_TX 0x00000015
108 #endif
109 #define DMA_REQUEST_ADC 0x00000016
110 #if !defined(BL702L)
111 #define DMA_REQUEST_DAC 0x00000017
112 #endif
113 /**
114   * @}
115   */
116 
117 #elif defined(BL616)
118 /** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
119   * @{
120   */
121 #define DMA_ADDR_UART0_TDR      (0x2000A000 + 0x88)
122 #define DMA_ADDR_UART0_RDR      (0x2000A000 + 0x8C)
123 #define DMA_ADDR_UART1_TDR      (0x2000A100 + 0x88)
124 #define DMA_ADDR_UART1_RDR      (0x2000A100 + 0x8C)
125 #define DMA_ADDR_I2C0_TDR       (0x2000A300 + 0x88)
126 #define DMA_ADDR_I2C0_RDR       (0x2000A300 + 0x8C)
127 #define DMA_ADDR_SPI0_TDR       (0x2000A200 + 0x88)
128 #define DMA_ADDR_SPI0_RDR       (0x2000A200 + 0x8C)
129 #define DMA_ADDR_I2S_TDR        (0x2000AB00 + 0x88)
130 #define DMA_ADDR_I2S_RDR        (0x2000AB00 + 0x8C)
131 #define DMA_ADDR_ADC_RDR        (0x20002000 + 0x04)
132 #define DMA_ADDR_DAC_TDR        (0x20002000 + 0x48)
133 #define DMA_ADDR_DBI_TDR        (0x2000A800 + 0x88)
134 #define DMA_ADDR_AUDAC_TDR      (0x20055000 + 0x94)
135 #define DMA_ADDR_AUADC_RDR      (0x2000A000 + 0xC88)
136 /**
137   * @}
138   */
139 
140 /** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
141   * @{
142   */
143 #define DMA_REQUEST_NONE        0x00000000
144 #define DMA_REQUEST_UART0_RX    0x00000000
145 #define DMA_REQUEST_UART0_TX    0x00000001
146 #define DMA_REQUEST_UART1_RX    0x00000002
147 #define DMA_REQUEST_UART1_TX    0x00000003
148 #define DMA_REQUEST_I2C0_RX     0x00000006
149 #define DMA_REQUEST_I2C0_TX     0x00000007
150 #define DMA_REQUEST_SPI0_RX     0x0000000A
151 #define DMA_REQUEST_SPI0_TX     0x0000000B
152 #define DMA_REQUEST_DBI_TX      0x00000014
153 #define DMA_REQUEST_AUADC_RX    0x00000015
154 #define DMA_REQUEST_AUDAC_TX    0x0000000D
155 #define DMA_REQUEST_I2S_RX      0x00000010
156 #define DMA_REQUEST_I2S_TX      0x00000011
157 #define DMA_REQUEST_ADC         0x00000016
158 #define DMA_REQUEST_DAC         0x00000017
159 
160 /**
161   * @}
162   */
163 
164 #elif defined(BL808) || defined(BL606P)
165 /** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
166   * @{
167   */
168 #define DMA_ADDR_UART0_TDR   (0x2000A000 + 0x88)
169 #define DMA_ADDR_UART0_RDR   (0x2000A000 + 0x8C)
170 #define DMA_ADDR_UART1_TDR   (0x2000A100 + 0x88)
171 #define DMA_ADDR_UART1_RDR   (0x2000A100 + 0x8C)
172 #define DMA_ADDR_UART2_TDR   (0x2000AA00 + 0x88)
173 #define DMA_ADDR_UART2_RDR   (0x2000AA00 + 0x8C)
174 #define DMA_ADDR_UART3_TDR   (0x30002000 + 0x88)
175 #define DMA_ADDR_UART3_RDR   (0x30002000 + 0x8C)
176 #define DMA_ADDR_I2C0_TDR    (0x2000A300 + 0x88)
177 #define DMA_ADDR_I2C0_RDR    (0x2000A300 + 0x8C)
178 #define DMA_ADDR_I2C1_TDR    (0x2000A900 + 0x88)
179 #define DMA_ADDR_I2C1_RDR    (0x2000A900 + 0x8C)
180 #define DMA_ADDR_I2C2_TDR    (0x30003000 + 0x88)
181 #define DMA_ADDR_I2C2_RDR    (0x30003000 + 0x8C)
182 #define DMA_ADDR_I2C3_TDR    (0x30004000 + 0x88)
183 #define DMA_ADDR_I2C3_RDR    (0x30004000 + 0x8C)
184 #define DMA_ADDR_SPI0_TDR    (0x2000A200 + 0x88)
185 #define DMA_ADDR_SPI0_RDR    (0x2000A200 + 0x8C)
186 #define DMA_ADDR_SPI1_TDR    (0x30008000 + 0x88)
187 #define DMA_ADDR_SPI1_RDR    (0x30008000 + 0x8C)
188 #define DMA_ADDR_I2S_TDR     (0x2000AB00 + 0x88)
189 #define DMA_ADDR_I2S_RDR     (0x2000AB00 + 0x8C)
190 #define DMA_ADDR_ADC_RDR     (0x20002000 + 0x04)
191 #define DMA_ADDR_DAC_TDR     (0x20002000 + 0x48)
192 #define DMA_ADDR_IR_TDR      (0x2000A600 + 0x88)
193 /**
194   * @}
195   */
196 
197 /** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
198   * @{
199   */
200 #define DMA_REQUEST_NONE     0x00000000
201 #define DMA_REQUEST_UART0_RX 0x00000000
202 #define DMA_REQUEST_UART0_TX 0x00000001
203 #define DMA_REQUEST_UART1_RX 0x00000002
204 #define DMA_REQUEST_UART1_TX 0x00000003
205 #define DMA_REQUEST_UART2_RX 0x00000004
206 #define DMA_REQUEST_UART2_TX 0x00000005
207 #define DMA_REQUEST_I2C0_RX  0x00000006
208 #define DMA_REQUEST_I2C0_TX  0x00000007
209 #define DMA_REQUEST_IR_TX    0x00000008
210 #define DMA_REQUEST_SPI0_RX  0x0000000A
211 #define DMA_REQUEST_SPI0_TX  0x0000000B
212 #define DMA_REQUEST_AUDIO_RX 0x0000000C
213 #define DMA_REQUEST_AUDIO_TX 0x0000000D
214 #define DMA_REQUEST_I2C1_RX  0x0000000E
215 #define DMA_REQUEST_I2C1_TX  0x0000000F
216 #define DMA_REQUEST_I2S_RX   0x00000010
217 #define DMA_REQUEST_I2S_TX   0x00000011
218 #define DMA_REQUEST_ADC      0x00000016
219 #define DMA_REQUEST_DAC      0x00000017
220 
221 /* Only support dma2 */
222 #define DMA_REQUEST_UART3_RX 0x00000000
223 #define DMA_REQUEST_UART3_TX 0x00000001
224 #define DMA_REQUEST_SPI1_RX  0x00000002
225 #define DMA_REQUEST_SPI1_TX  0x00000003
226 #define DMA_REQUEST_I2C2_RX  0x00000006
227 #define DMA_REQUEST_I2C2_TX  0x00000007
228 #define DMA_REQUEST_I2C3_RX  0x00000008
229 #define DMA_REQUEST_I2C3_TX  0x00000009
230 /**
231   * @}
232   */
233 
234 #elif defined(BL628)
235 /** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
236   * @{
237   */
238 #define DMA_ADDR_UART0_TDR   (0x20010000 + 0x88)
239 #define DMA_ADDR_UART0_RDR   (0x20010000 + 0x8C)
240 #define DMA_ADDR_UART1_TDR   (0x20011000 + 0x88)
241 #define DMA_ADDR_UART1_RDR   (0x20011000 + 0x8C)
242 #define DMA_ADDR_UART2_TDR   (0x20012000 + 0x88)
243 #define DMA_ADDR_UART2_RDR   (0x20012000 + 0x8C)
244 #define DMA_ADDR_I2C0_TDR    (0x20014000 + 0x88)
245 #define DMA_ADDR_I2C0_RDR    (0x20014000 + 0x8C)
246 #define DMA_ADDR_I2C1_TDR    (0x20015000 + 0x88)
247 #define DMA_ADDR_I2C1_RDR    (0x20015000 + 0x8C)
248 #define DMA_ADDR_SPI0_TDR    (0x20018000 + 0x88)
249 #define DMA_ADDR_SPI0_RDR    (0x20018000 + 0x8C)
250 #define DMA_ADDR_I2S_TDR     (0x2001E000 + 0x88)
251 #define DMA_ADDR_I2S_RDR     (0x2001E000 + 0x8C)
252 #define DMA_ADDR_ADC_RDR     (0x20002000 + 0x04)
253 #define DMA_ADDR_DAC_TDR     (0x20002000 + 0x48)
254 /**
255   * @}
256   */
257 
258 /** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
259   * @{
260   */
261 #define DMA_REQUEST_NONE     0x00000000
262 #define DMA_REQUEST_UART0_RX 0x00000000
263 #define DMA_REQUEST_UART0_TX 0x00000001
264 #define DMA_REQUEST_UART1_RX 0x00000002
265 #define DMA_REQUEST_UART1_TX 0x00000003
266 #define DMA_REQUEST_UART2_RX 0x00000004
267 #define DMA_REQUEST_UART2_TX 0x00000005
268 #define DMA_REQUEST_I2C0_RX  0x00000006
269 #define DMA_REQUEST_I2C0_TX  0x00000007
270 #define DMA_REQUEST_I2C1_RX  0x00000008
271 #define DMA_REQUEST_I2C1_TX  0x00000009
272 #define DMA_REQUEST_SPI0_RX  0x0000000A
273 #define DMA_REQUEST_SPI0_TX  0x0000000B
274 #define DMA_REQUEST_I2S_RX   0x00000010
275 #define DMA_REQUEST_I2S_TX   0x00000011
276 #define DMA_REQUEST_ADC      0x00000016
277 #define DMA_REQUEST_DAC      0x00000017
278 /**
279   * @}
280   */
281 
282 #endif
283 
284 /** @defgroup DMA_CMD dma feature control cmd definition
285   * @{
286   */
287 #define DMA_CMD_SET_SRCADDR_INCREMENT (0x01)
288 #define DMA_CMD_SET_DSTADDR_INCREMENT (0x02)
289 #define DMA_CMD_SET_ADD_MODE          (0x03)
290 #define DMA_CMD_SET_REDUCE_MODE       (0x04)
291 #define DMA_CMD_SET_LLI_CONFIG        (0x05)
292 #define DMA_CMD_GET_LLI_CONTROL       (0x06)
293 /**
294   * @}
295   */
296 
297 union bflb_dma_lli_control_s {
298     struct
299     {
300         uint32_t TransferSize : 12; /* [11: 0],        r/w,        0x0 */
301         uint32_t SBSize       : 2;  /* [13:12],        r/w,        0x1 */
302         uint32_t dst_min_mode : 1;  /* [   14],        r/w,        0x0 */
303         uint32_t DBSize       : 2;  /* [16:15],        r/w,        0x1 */
304         uint32_t dst_add_mode : 1;  /* [   17],        r/w,        0x0 */
305         uint32_t SWidth       : 2;  /* [19:18],        r/w,        0x2 */
306         uint32_t reserved_20  : 1;  /* [   20],       rsvd,        0x0 */
307         uint32_t DWidth       : 2;  /* [22:21],        r/w,        0x2 */
308         uint32_t fix_cnt      : 2;  /* [24:23],        r/w,        0x0 */
309         uint32_t SLargerD     : 1;  /* [   25],        r/w,        0x0 */
310         uint32_t SI           : 1;  /* [   26],        r/w,        0x1 */
311         uint32_t DI           : 1;  /* [   27],        r/w,        0x1 */
312         uint32_t Prot         : 3;  /* [30:28],        r/w,        0x0 */
313         uint32_t I            : 1;  /* [   31],        r/w,        0x0 */
314     } bits;
315     uint32_t WORD;
316 };
317 
318 /**
319  * @brief DMA channel lli pool structure
320  *
321  * @param src_addr        DMA source address
322  * @param dst_addr        DMA destination address
323  * @param nextlli         DMA next lli address
324  * @param control         DMA lli config
325  */
326 struct bflb_dma_channel_lli_pool_s {
327     uint32_t src_addr;
328     uint32_t dst_addr;
329     uint32_t nextlli;
330     union bflb_dma_lli_control_s control;
331 };
332 
333 /**
334  * @brief DMA channel lli transfer structure
335  *
336  * @param src_addr        DMA source address
337  * @param dst_addr        DMA destination address
338  * @param nbytes          How many bytes should be transferred
339  */
340 struct bflb_dma_channel_lli_transfer_s {
341     uint32_t src_addr;
342     uint32_t dst_addr;
343     uint32_t nbytes;
344 };
345 
346 /**
347  * @brief DMA configuration structure
348  *
349  * @param direction        DMA transfer direction, use @ref DMA_DIRECTION
350  * @param src_req          DMA source request, use @ref DMA_PERIPHERAL_REQUEST
351  * @param dst_req          DMA destination request, use @ref DMA_PERIPHERAL_REQUEST
352  * @param src_addr_inc     DMA source address increment, use @ref DMA_ADDR_INCREMENT
353  * @param dst_addr_inc     DMA destination address increment, use @ref DMA_ADDR_INCREMENT
354  * @param src_burst_count  DMA source burst count, use @ref DMA_BURST_COUNT
355  * @param dst_burst_count  DMA destination burst count, use @ref DMA_BURST_COUNT
356  * @param src_width        DMA source data width, use @ref DMA_DATA_WIDTH
357  * @param dst_width        DMA destination data width, use @ref DMA_DATA_WIDTH
358  */
359 struct bflb_dma_channel_config_s {
360     uint8_t direction;
361     uint32_t src_req;
362     uint32_t dst_req;
363     uint8_t src_addr_inc;
364     uint8_t dst_addr_inc;
365     uint8_t src_burst_count;
366     uint8_t dst_burst_count;
367     uint8_t src_width;
368     uint8_t dst_width;
369 };
370 
371 #ifdef __cplusplus
372 extern "C" {
373 #endif
374 
375 /**
376  * @brief Initialize dma channel.
377  *
378  * @param [in] dev device handle
379  * @param [in] config pointer to save dma channel configuration
380  */
381 void bflb_dma_channel_init(struct bflb_device_s *dev, const struct bflb_dma_channel_config_s *config);
382 
383 /**
384  * @brief Deinitialize dma channel.
385  *
386  * @param [in] dev device handle
387  */
388 void bflb_dma_channel_deinit(struct bflb_device_s *dev);
389 
390 /**
391  * @brief Start dma channel transfer.
392  *
393  * @param [in] dev device handle
394  */
395 void bflb_dma_channel_start(struct bflb_device_s *dev);
396 
397 /**
398  * @brief Stop dma channel transfer.
399  *
400  * @param [in] dev device handle
401  */
402 void bflb_dma_channel_stop(struct bflb_device_s *dev);
403 
404 /**
405  * @brief Check if dma channel is in busy.
406  *
407  * @param [in] dev device handle
408  * @return true means dma channel does not transfer completely, otherwise transfers completely.
409  */
410 bool bflb_dma_channel_isbusy(struct bflb_device_s *dev);
411 
412 /**
413  * @brief Register dma channel transmission completion interrupt callback.
414  *
415  * @param [in] dev device handle
416  * @param [in] callback interrupt callback
417  * @param [in] arg user data
418  */
419 void bflb_dma_channel_irq_attach(struct bflb_device_s *dev, void (*callback)(void *arg), void *arg);
420 
421 /**
422  * @brief Unregister dma channel transmission completion interrupt callback.
423  *
424  * @param [in] dev device handle
425  */
426 void bflb_dma_channel_irq_detach(struct bflb_device_s *dev);
427 
428 /**
429  * @brief Config dma channel lli.
430  *
431  * @param [in] dev device handle
432  * @param [in] lli_pool pointer to lli pool
433  * @param [in] max_lli_count lli pool size
434  * @param [in] transfer pointer to transfer structure
435  * @param [in] count transfer count.
436  * @return A negated errno value on failure, otherwise means number of used lli.
437  */
438 int bflb_dma_channel_lli_reload(struct bflb_device_s *dev,
439                                 struct bflb_dma_channel_lli_pool_s *lli_pool, uint32_t max_lli_count,
440                                 struct bflb_dma_channel_lli_transfer_s *transfer, uint32_t count);
441 
442 /**
443  * @brief Enable lli continueous mode.
444  *
445  * @param [in] dev device handle
446  * @param [in] lli_pool pointer to lli pool
447  * @param [in] used_lli_count number of used lli.
448  */
449 void bflb_dma_channel_lli_link_head(struct bflb_device_s *dev,
450                                     struct bflb_dma_channel_lli_pool_s *lli_pool,
451                                     uint32_t used_lli_count);
452 
453 /**
454  * @brief Control dma feature.
455  *
456  * @param [in] dev device handle
457  * @param [in] cmd feature command. use @ref DMA_CMD
458  * @param [in] arg user data
459  * @return A negated errno value on failure.
460  */
461 int bflb_dma_feature_control(struct bflb_device_s *dev, int cmd, size_t arg);
462 
463 /**
464  * @brief Enable or disable dma channel transmission completion interrupt.
465  *
466  * @param [in] dev device handle
467  * @param [in] mask true means disable, false means enable
468  */
469 void bflb_dma_channel_tcint_mask(struct bflb_device_s *dev, bool mask);
470 
471 /**
472  * @brief Check if dma channel transfers completely.
473  *
474  * @param [in] dev device handle
475  * @return true means yes, false means no.
476  */
477 bool bflb_dma_channel_get_tcint_status(struct bflb_device_s *dev);
478 
479 /**
480  * @brief Clear dma channel transmission completion interrupt status.
481  *
482  * @param [in] dev device handle
483  */
484 void bflb_dma_channel_tcint_clear(struct bflb_device_s *dev);
485 
486 #ifdef __cplusplus
487 }
488 #endif
489 
490 /**
491   * @}
492   */
493 
494 /**
495   * @}
496   */
497 
498 #endif