1 /*
2  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include <stdint.h>
10 #include "sdkconfig.h"
11 #include "freertos/FreeRTOS.h"
12 #include "esp_err.h"
13 #include "esp_intr_alloc.h"
14 #include "esp_heap_caps.h"
15 #include "soc/soc_caps.h"
16 #include "hal/gdma_hal.h"
17 #include "hal/gdma_ll.h"
18 #include "soc/gdma_periph.h"
19 #include "esp_private/gdma.h"
20 
21 #if CONFIG_GDMA_ISR_IRAM_SAFE || CONFIG_GDMA_CTRL_FUNC_IN_IRAM
22 #define GDMA_MEM_ALLOC_CAPS    (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
23 #else
24 #define GDMA_MEM_ALLOC_CAPS    MALLOC_CAP_DEFAULT
25 #endif
26 
27 #if CONFIG_GDMA_ISR_IRAM_SAFE
28 #define GDMA_INTR_ALLOC_FLAGS  (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED)
29 #else
30 #define GDMA_INTR_ALLOC_FLAGS  ESP_INTR_FLAG_INTRDISABLED
31 #endif
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 typedef struct gdma_pair_t gdma_pair_t;
38 typedef struct gdma_channel_t gdma_channel_t;
39 typedef struct gdma_tx_channel_t gdma_tx_channel_t;
40 typedef struct gdma_rx_channel_t gdma_rx_channel_t;
41 
42 typedef struct gdma_group_t {
43     int group_id;           // Group ID, index from 0
44     gdma_hal_context_t hal; // HAL instance is at group level
45     portMUX_TYPE spinlock;  // group level spinlock
46     uint32_t tx_periph_in_use_mask; // each bit indicates which peripheral (TX direction) has been occupied
47     uint32_t rx_periph_in_use_mask; // each bit indicates which peripheral (RX direction) has been occupied
48     gdma_pair_t *pairs[SOC_GDMA_PAIRS_PER_GROUP];  // handles of GDMA pairs
49     int pair_ref_counts[SOC_GDMA_PAIRS_PER_GROUP]; // reference count used to protect pair install/uninstall
50 } gdma_group_t;
51 
52 struct gdma_pair_t {
53     gdma_group_t *group;        // which group the pair belongs to
54     int pair_id;                // Pair ID, index from 0
55     gdma_tx_channel_t *tx_chan; // pointer of tx channel in the pair
56     gdma_rx_channel_t *rx_chan; // pointer of rx channel in the pair
57     int occupy_code;            // each bit indicates which channel has been occupied (an occupied channel will be skipped during channel search)
58     portMUX_TYPE spinlock;      // pair level spinlock
59 };
60 
61 struct gdma_channel_t {
62     gdma_pair_t *pair;  // which pair the channel belongs to
63     intr_handle_t intr; // per-channel interrupt handle
64     portMUX_TYPE spinlock;  // channel level spinlock
65     gdma_channel_direction_t direction; // channel direction
66     int periph_id; // Peripheral instance ID, indicates which peripheral is connected to this GDMA channel
67     size_t sram_alignment;  // alignment for memory in SRAM
68     size_t psram_alignment; // alignment for memory in PSRAM
69     esp_err_t (*del)(gdma_channel_t *channel); // channel deletion function, it's polymorphic, see `gdma_del_tx_channel` or `gdma_del_rx_channel`
70     struct {
71         uint32_t start_stop_by_etm: 1; // whether the channel is started/stopped by ETM
72     } flags;
73 };
74 
75 struct gdma_tx_channel_t {
76     gdma_channel_t base; // GDMA channel, base class
77     void *user_data;     // user registered DMA event data
78     gdma_event_callback_t on_trans_eof; // TX EOF callback
79 };
80 
81 struct gdma_rx_channel_t {
82     gdma_channel_t base; // GDMA channel, base class
83     void *user_data;     // user registered DMA event data
84     gdma_event_callback_t on_recv_eof; // RX EOF callback
85 };
86 
87 #ifdef __cplusplus
88 }
89 #endif
90