summaryrefslogtreecommitdiff
path: root/bsp/bouffalo_lab/libraries/bl_mcu_sdk/drivers/lhal/include/bflb_dma.h
blob: 2a07c7c27025388040588970edb386ee1072923c (plain)
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
#ifndef _BFLB_DMA_H
#define _BFLB_DMA_H

#include "bflb_core.h"

/** @addtogroup LHAL
  * @{
  */

/** @addtogroup DMA
  * @{
  */

/** @defgroup DMA_DIRECTION dma transfer direction definition
  * @{
  */
#define DMA_MEMORY_TO_MEMORY       0
#define DMA_MEMORY_TO_PERIPH       1
#define DMA_PERIPH_TO_MEMORY       2
#define DMA_PERIPH_TO_PERIPH       3
/**
  * @}
  */

/** @defgroup DMA_ADDR_INCREMENT dma source and destination address increment definition
  * @{
  */
#define DMA_ADDR_INCREMENT_DISABLE 0
#define DMA_ADDR_INCREMENT_ENABLE  1
/**
  * @}
  */

/** @defgroup DMA_DATA_WIDTH dma data width definition
  * @{
  */
#define DMA_DATA_WIDTH_8BIT        0
#define DMA_DATA_WIDTH_16BIT       1
#define DMA_DATA_WIDTH_32BIT       2
/**
  * @}
  */

/** @defgroup DMA_BURST_COUNT dma burst increment count definition
  * @{
  */
#define DMA_BURST_INCR1            0
#define DMA_BURST_INCR4            1
#define DMA_BURST_INCR8            2
#define DMA_BURST_INCR16           3
/**
  * @}
  */

#if defined(BL702) || defined(BL602) || defined(BL702L)
/** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
  * @{
  */
#define DMA_ADDR_UART0_TDR (0x4000A000 + 0x88)
#define DMA_ADDR_UART0_RDR (0x4000A000 + 0x8C)
#if !defined(BL702L)
#define DMA_ADDR_UART1_TDR (0x4000A100 + 0x88)
#define DMA_ADDR_UART1_RDR (0x4000A100 + 0x8C)
#endif
#define DMA_ADDR_I2C0_TDR (0x4000A300 + 0x88)
#define DMA_ADDR_I2C0_RDR (0x4000A300 + 0x8C)
#define DMA_ADDR_SPI0_TDR (0x4000A200 + 0x88)
#define DMA_ADDR_SPI0_RDR (0x4000A200 + 0x8C)
#if !defined(BL702L)
#define DMA_ADDR_I2S_TDR (0x4000AA00 + 0x88)
#define DMA_ADDR_I2S_RDR (0x4000AA00 + 0x8C)
#endif
#define DMA_ADDR_ADC_RDR (0x40002000 + 0x04)
#if !defined(BL702L)
#define DMA_ADDR_DAC_TDR (0x40002000 + 0x48)
#endif
#if defined(BL702L)
#define DMA_ADDR_IR_TDR    (0x4000A600 + 0x88)
#define DMA_ADDR_AUADC_RDR (0x4000AD00 + 0x88)
#endif
/**
  * @}
  */

/** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
  * @{
  */
#define DMA_REQUEST_NONE     0x00000000
#define DMA_REQUEST_UART0_RX 0x00000000
#define DMA_REQUEST_UART0_TX 0x00000001
#if !defined(BL702L)
#define DMA_REQUEST_UART1_RX 0x00000002
#define DMA_REQUEST_UART1_TX 0x00000003
#endif
#define DMA_REQUEST_I2C0_RX 0x00000006
#define DMA_REQUEST_I2C0_TX 0x00000007
#if defined(BL702L)
#define DMA_REQUEST_IR_TX 0x00000008
#endif
#define DMA_REQUEST_SPI0_RX 0x0000000A
#define DMA_REQUEST_SPI0_TX 0x0000000B
#if defined(BL702L)
#define DMA_REQUEST_AUADC_RX 0x0000000D
#endif
#if !defined(BL702L)
#define DMA_REQUEST_I2S_RX 0x00000014
#define DMA_REQUEST_I2S_TX 0x00000015
#endif
#define DMA_REQUEST_ADC 0x00000016
#if !defined(BL702L)
#define DMA_REQUEST_DAC 0x00000017
#endif
/**
  * @}
  */

#elif defined(BL616)
/** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
  * @{
  */
#define DMA_ADDR_UART0_TDR      (0x2000A000 + 0x88)
#define DMA_ADDR_UART0_RDR      (0x2000A000 + 0x8C)
#define DMA_ADDR_UART1_TDR      (0x2000A100 + 0x88)
#define DMA_ADDR_UART1_RDR      (0x2000A100 + 0x8C)
#define DMA_ADDR_I2C0_TDR       (0x2000A300 + 0x88)
#define DMA_ADDR_I2C0_RDR       (0x2000A300 + 0x8C)
#define DMA_ADDR_SPI0_TDR       (0x2000A200 + 0x88)
#define DMA_ADDR_SPI0_RDR       (0x2000A200 + 0x8C)
#define DMA_ADDR_I2S_TDR        (0x2000AB00 + 0x88)
#define DMA_ADDR_I2S_RDR        (0x2000AB00 + 0x8C)
#define DMA_ADDR_ADC_RDR        (0x20002000 + 0x04)
#define DMA_ADDR_DAC_TDR        (0x20002000 + 0x48)
#define DMA_ADDR_DBI_TDR        (0x2000A800 + 0x88)
#define DMA_ADDR_AUDAC_TDR      (0x20055000 + 0x94)
#define DMA_ADDR_AUADC_RDR      (0x2000A000 + 0xC88)
/**
  * @}
  */

/** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
  * @{
  */
#define DMA_REQUEST_NONE        0x00000000
#define DMA_REQUEST_UART0_RX    0x00000000
#define DMA_REQUEST_UART0_TX    0x00000001
#define DMA_REQUEST_UART1_RX    0x00000002
#define DMA_REQUEST_UART1_TX    0x00000003
#define DMA_REQUEST_I2C0_RX     0x00000006
#define DMA_REQUEST_I2C0_TX     0x00000007
#define DMA_REQUEST_SPI0_RX     0x0000000A
#define DMA_REQUEST_SPI0_TX     0x0000000B
#define DMA_REQUEST_DBI_TX      0x00000014
#define DMA_REQUEST_AUADC_RX    0x00000015
#define DMA_REQUEST_AUDAC_TX    0x0000000D
#define DMA_REQUEST_I2S_RX      0x00000010
#define DMA_REQUEST_I2S_TX      0x00000011
#define DMA_REQUEST_ADC         0x00000016
#define DMA_REQUEST_DAC         0x00000017

/**
  * @}
  */

#elif defined(BL808) || defined(BL606P)
/** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
  * @{
  */
#define DMA_ADDR_UART0_TDR   (0x2000A000 + 0x88)
#define DMA_ADDR_UART0_RDR   (0x2000A000 + 0x8C)
#define DMA_ADDR_UART1_TDR   (0x2000A100 + 0x88)
#define DMA_ADDR_UART1_RDR   (0x2000A100 + 0x8C)
#define DMA_ADDR_UART2_TDR   (0x2000AA00 + 0x88)
#define DMA_ADDR_UART2_RDR   (0x2000AA00 + 0x8C)
#define DMA_ADDR_UART3_TDR   (0x30002000 + 0x88)
#define DMA_ADDR_UART3_RDR   (0x30002000 + 0x8C)
#define DMA_ADDR_I2C0_TDR    (0x2000A300 + 0x88)
#define DMA_ADDR_I2C0_RDR    (0x2000A300 + 0x8C)
#define DMA_ADDR_I2C1_TDR    (0x2000A900 + 0x88)
#define DMA_ADDR_I2C1_RDR    (0x2000A900 + 0x8C)
#define DMA_ADDR_I2C2_TDR    (0x30003000 + 0x88)
#define DMA_ADDR_I2C2_RDR    (0x30003000 + 0x8C)
#define DMA_ADDR_I2C3_TDR    (0x30004000 + 0x88)
#define DMA_ADDR_I2C3_RDR    (0x30004000 + 0x8C)
#define DMA_ADDR_SPI0_TDR    (0x2000A200 + 0x88)
#define DMA_ADDR_SPI0_RDR    (0x2000A200 + 0x8C)
#define DMA_ADDR_SPI1_TDR    (0x30008000 + 0x88)
#define DMA_ADDR_SPI1_RDR    (0x30008000 + 0x8C)
#define DMA_ADDR_I2S_TDR     (0x2000AB00 + 0x88)
#define DMA_ADDR_I2S_RDR     (0x2000AB00 + 0x8C)
#define DMA_ADDR_ADC_RDR     (0x20002000 + 0x04)
#define DMA_ADDR_DAC_TDR     (0x20002000 + 0x48)
#define DMA_ADDR_IR_TDR      (0x2000A600 + 0x88)
/**
  * @}
  */

/** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
  * @{
  */
#define DMA_REQUEST_NONE     0x00000000
#define DMA_REQUEST_UART0_RX 0x00000000
#define DMA_REQUEST_UART0_TX 0x00000001
#define DMA_REQUEST_UART1_RX 0x00000002
#define DMA_REQUEST_UART1_TX 0x00000003
#define DMA_REQUEST_UART2_RX 0x00000004
#define DMA_REQUEST_UART2_TX 0x00000005
#define DMA_REQUEST_I2C0_RX  0x00000006
#define DMA_REQUEST_I2C0_TX  0x00000007
#define DMA_REQUEST_IR_TX    0x00000008
#define DMA_REQUEST_SPI0_RX  0x0000000A
#define DMA_REQUEST_SPI0_TX  0x0000000B
#define DMA_REQUEST_AUDIO_RX 0x0000000C
#define DMA_REQUEST_AUDIO_TX 0x0000000D
#define DMA_REQUEST_I2C1_RX  0x0000000E
#define DMA_REQUEST_I2C1_TX  0x0000000F
#define DMA_REQUEST_I2S_RX   0x00000010
#define DMA_REQUEST_I2S_TX   0x00000011
#define DMA_REQUEST_ADC      0x00000016
#define DMA_REQUEST_DAC      0x00000017

/* Only support dma2 */
#define DMA_REQUEST_UART3_RX 0x00000000
#define DMA_REQUEST_UART3_TX 0x00000001
#define DMA_REQUEST_SPI1_RX  0x00000002
#define DMA_REQUEST_SPI1_TX  0x00000003
#define DMA_REQUEST_I2C2_RX  0x00000006
#define DMA_REQUEST_I2C2_TX  0x00000007
#define DMA_REQUEST_I2C3_RX  0x00000008
#define DMA_REQUEST_I2C3_TX  0x00000009
/**
  * @}
  */

#elif defined(BL628)
/** @defgroup DMA_PERIPHERAL_REGBASE dma peripheral data register address definition
  * @{
  */
#define DMA_ADDR_UART0_TDR   (0x20010000 + 0x88)
#define DMA_ADDR_UART0_RDR   (0x20010000 + 0x8C)
#define DMA_ADDR_UART1_TDR   (0x20011000 + 0x88)
#define DMA_ADDR_UART1_RDR   (0x20011000 + 0x8C)
#define DMA_ADDR_UART2_TDR   (0x20012000 + 0x88)
#define DMA_ADDR_UART2_RDR   (0x20012000 + 0x8C)
#define DMA_ADDR_I2C0_TDR    (0x20014000 + 0x88)
#define DMA_ADDR_I2C0_RDR    (0x20014000 + 0x8C)
#define DMA_ADDR_I2C1_TDR    (0x20015000 + 0x88)
#define DMA_ADDR_I2C1_RDR    (0x20015000 + 0x8C)
#define DMA_ADDR_SPI0_TDR    (0x20018000 + 0x88)
#define DMA_ADDR_SPI0_RDR    (0x20018000 + 0x8C)
#define DMA_ADDR_I2S_TDR     (0x2001E000 + 0x88)
#define DMA_ADDR_I2S_RDR     (0x2001E000 + 0x8C)
#define DMA_ADDR_ADC_RDR     (0x20002000 + 0x04)
#define DMA_ADDR_DAC_TDR     (0x20002000 + 0x48)
/**
  * @}
  */

/** @defgroup DMA_PERIPHERAL_REQUEST dma peripheral request definition
  * @{
  */
#define DMA_REQUEST_NONE     0x00000000
#define DMA_REQUEST_UART0_RX 0x00000000
#define DMA_REQUEST_UART0_TX 0x00000001
#define DMA_REQUEST_UART1_RX 0x00000002
#define DMA_REQUEST_UART1_TX 0x00000003
#define DMA_REQUEST_UART2_RX 0x00000004
#define DMA_REQUEST_UART2_TX 0x00000005
#define DMA_REQUEST_I2C0_RX  0x00000006
#define DMA_REQUEST_I2C0_TX  0x00000007
#define DMA_REQUEST_I2C1_RX  0x00000008
#define DMA_REQUEST_I2C1_TX  0x00000009
#define DMA_REQUEST_SPI0_RX  0x0000000A
#define DMA_REQUEST_SPI0_TX  0x0000000B
#define DMA_REQUEST_I2S_RX   0x00000010
#define DMA_REQUEST_I2S_TX   0x00000011
#define DMA_REQUEST_ADC      0x00000016
#define DMA_REQUEST_DAC      0x00000017
/**
  * @}
  */

#endif

/** @defgroup DMA_CMD dma feature control cmd definition
  * @{
  */
#define DMA_CMD_SET_SRCADDR_INCREMENT (0x01)
#define DMA_CMD_SET_DSTADDR_INCREMENT (0x02)
#define DMA_CMD_SET_ADD_MODE          (0x03)
#define DMA_CMD_SET_REDUCE_MODE       (0x04)
#define DMA_CMD_SET_LLI_CONFIG        (0x05)
#define DMA_CMD_GET_LLI_CONTROL       (0x06)
/**
  * @}
  */

union bflb_dma_lli_control_s {
    struct
    {
        uint32_t TransferSize : 12; /* [11: 0],        r/w,        0x0 */
        uint32_t SBSize       : 2;  /* [13:12],        r/w,        0x1 */
        uint32_t dst_min_mode : 1;  /* [   14],        r/w,        0x0 */
        uint32_t DBSize       : 2;  /* [16:15],        r/w,        0x1 */
        uint32_t dst_add_mode : 1;  /* [   17],        r/w,        0x0 */
        uint32_t SWidth       : 2;  /* [19:18],        r/w,        0x2 */
        uint32_t reserved_20  : 1;  /* [   20],       rsvd,        0x0 */
        uint32_t DWidth       : 2;  /* [22:21],        r/w,        0x2 */
        uint32_t fix_cnt      : 2;  /* [24:23],        r/w,        0x0 */
        uint32_t SLargerD     : 1;  /* [   25],        r/w,        0x0 */
        uint32_t SI           : 1;  /* [   26],        r/w,        0x1 */
        uint32_t DI           : 1;  /* [   27],        r/w,        0x1 */
        uint32_t Prot         : 3;  /* [30:28],        r/w,        0x0 */
        uint32_t I            : 1;  /* [   31],        r/w,        0x0 */
    } bits;
    uint32_t WORD;
};

/**
 * @brief DMA channel lli pool structure
 *
 * @param src_addr        DMA source address
 * @param dst_addr        DMA destination address
 * @param nextlli         DMA next lli address
 * @param control         DMA lli config
 */
struct bflb_dma_channel_lli_pool_s {
    uint32_t src_addr;
    uint32_t dst_addr;
    uint32_t nextlli;
    union bflb_dma_lli_control_s control;
};

/**
 * @brief DMA channel lli transfer structure
 *
 * @param src_addr        DMA source address
 * @param dst_addr        DMA destination address
 * @param nbytes          How many bytes should be transferred
 */
struct bflb_dma_channel_lli_transfer_s {
    uint32_t src_addr;
    uint32_t dst_addr;
    uint32_t nbytes;
};

/**
 * @brief DMA configuration structure
 *
 * @param direction        DMA transfer direction, use @ref DMA_DIRECTION
 * @param src_req          DMA source request, use @ref DMA_PERIPHERAL_REQUEST
 * @param dst_req          DMA destination request, use @ref DMA_PERIPHERAL_REQUEST
 * @param src_addr_inc     DMA source address increment, use @ref DMA_ADDR_INCREMENT
 * @param dst_addr_inc     DMA destination address increment, use @ref DMA_ADDR_INCREMENT
 * @param src_burst_count  DMA source burst count, use @ref DMA_BURST_COUNT
 * @param dst_burst_count  DMA destination burst count, use @ref DMA_BURST_COUNT
 * @param src_width        DMA source data width, use @ref DMA_DATA_WIDTH
 * @param dst_width        DMA destination data width, use @ref DMA_DATA_WIDTH
 */
struct bflb_dma_channel_config_s {
    uint8_t direction;
    uint32_t src_req;
    uint32_t dst_req;
    uint8_t src_addr_inc;
    uint8_t dst_addr_inc;
    uint8_t src_burst_count;
    uint8_t dst_burst_count;
    uint8_t src_width;
    uint8_t dst_width;
};

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Initialize dma channel.
 *
 * @param [in] dev device handle
 * @param [in] config pointer to save dma channel configuration
 */
void bflb_dma_channel_init(struct bflb_device_s *dev, const struct bflb_dma_channel_config_s *config);

/**
 * @brief Deinitialize dma channel.
 *
 * @param [in] dev device handle
 */
void bflb_dma_channel_deinit(struct bflb_device_s *dev);

/**
 * @brief Start dma channel transfer.
 *
 * @param [in] dev device handle
 */
void bflb_dma_channel_start(struct bflb_device_s *dev);

/**
 * @brief Stop dma channel transfer.
 *
 * @param [in] dev device handle
 */
void bflb_dma_channel_stop(struct bflb_device_s *dev);

/**
 * @brief Check if dma channel is in busy.
 *
 * @param [in] dev device handle
 * @return true means dma channel does not transfer completely, otherwise transfers completely.
 */
bool bflb_dma_channel_isbusy(struct bflb_device_s *dev);

/**
 * @brief Register dma channel transmission completion interrupt callback.
 *
 * @param [in] dev device handle
 * @param [in] callback interrupt callback
 * @param [in] arg user data
 */
void bflb_dma_channel_irq_attach(struct bflb_device_s *dev, void (*callback)(void *arg), void *arg);

/**
 * @brief Unregister dma channel transmission completion interrupt callback.
 *
 * @param [in] dev device handle
 */
void bflb_dma_channel_irq_detach(struct bflb_device_s *dev);

/**
 * @brief Config dma channel lli.
 *
 * @param [in] dev device handle
 * @param [in] lli_pool pointer to lli pool
 * @param [in] max_lli_count lli pool size
 * @param [in] transfer pointer to transfer structure
 * @param [in] count transfer count.
 * @return A negated errno value on failure, otherwise means number of used lli.
 */
int bflb_dma_channel_lli_reload(struct bflb_device_s *dev,
                                struct bflb_dma_channel_lli_pool_s *lli_pool, uint32_t max_lli_count,
                                struct bflb_dma_channel_lli_transfer_s *transfer, uint32_t count);

/**
 * @brief Enable lli continueous mode.
 *
 * @param [in] dev device handle
 * @param [in] lli_pool pointer to lli pool
 * @param [in] used_lli_count number of used lli.
 */
void bflb_dma_channel_lli_link_head(struct bflb_device_s *dev,
                                    struct bflb_dma_channel_lli_pool_s *lli_pool,
                                    uint32_t used_lli_count);

/**
 * @brief Control dma feature.
 *
 * @param [in] dev device handle
 * @param [in] cmd feature command. use @ref DMA_CMD
 * @param [in] arg user data
 * @return A negated errno value on failure.
 */
int bflb_dma_feature_control(struct bflb_device_s *dev, int cmd, size_t arg);

/**
 * @brief Enable or disable dma channel transmission completion interrupt.
 *
 * @param [in] dev device handle
 * @param [in] mask true means disable, false means enable
 */
void bflb_dma_channel_tcint_mask(struct bflb_device_s *dev, bool mask);

/**
 * @brief Check if dma channel transfers completely.
 *
 * @param [in] dev device handle
 * @return true means yes, false means no.
 */
bool bflb_dma_channel_get_tcint_status(struct bflb_device_s *dev);

/**
 * @brief Clear dma channel transmission completion interrupt status.
 *
 * @param [in] dev device handle
 */
void bflb_dma_channel_tcint_clear(struct bflb_device_s *dev);

#ifdef __cplusplus
}
#endif

/**
  * @}
  */

/**
  * @}
  */

#endif