1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 /**
16 ****************************************************************************************
17 *
18 * @file dma_api.h
19 *
20 * @brief DMA utility functions
21 *
22 ****************************************************************************************
23 */
24
25 #ifndef _DMA_API_H_
26 #define _DMA_API_H_
27
28 /*
29 * INCLUDE FILES
30 ****************************************************************************************
31 */
32 #include "arch.h"
33 #include "dma_generic.h"
34
35 /// Structure describing the DMA driver environment
36 typedef struct {
37 /* Last DMA descriptor pushed for each channel */
38 volatile dma_desc_t *last_dma[DMA_CHANNEL_MAX];
39 } dma_env_t;
40
41 /// DMA environment structure
42 extern dma_env_t dma_env;
43
44 /**
45 ****************************************************************************************
46 * @brief Initialization
47 ****************************************************************************************
48 */
49 void dma_init(void);
50
51 void dma_trsc_init(int channel_idx);
52
53 void dma_trsc_trans_start(volatile dma_desc_t *desc, uint32_t len, int channel_idx);
54
55 /**
56 ****************************************************************************************
57 * @brief Chains a chained list of descriptors in the DMA
58 *
59 * @param[in] first : First DMA descriptor of the list (filled by the caller)
60 * @param[in] last : Last DMA descriptor of the list (filled by the caller)
61 * @param[in] channel_idx : Channel index
62 *
63 ****************************************************************************************
64 */
65 void dma_push(dma_desc_t *first, dma_desc_t *last, int channel_idx);
66
67 /**
68 ****************************************************************************************
69 * @brief Disable an LLI IRQ.
70 *
71 * @param[in] lli LLI IRQ index (must be in range 0..15)
72 *
73 ****************************************************************************************
74 */
dma_lli_disable(int lli)75 __STATIC_INLINE void dma_lli_disable(int lli)
76 {
77 dma_ch_ctlr_chena_clrb(lli);
78 }
79
80 /**
81 ****************************************************************************************
82 * @brief Enable an LLI IRQ.
83 *
84 * @param[in] lli LLI IRQ index (must be in range 0..15)
85 *
86 ****************************************************************************************
87 */
dma_lli_enable(int lli)88 __STATIC_INLINE void dma_lli_enable(int lli)
89 {
90 dma_ch_ctlr_chena_setb(lli);
91 }
92
93 /**
94 ****************************************************************************************
95 * @brief Poll for an LLI IRQ.
96 *
97 * @param[in] lli LLI IRQ index (must be in range 0..15)
98 *
99 ****************************************************************************************
100 */
dma_lli_poll(int lli)101 __STATIC_INLINE void dma_lli_poll(int lli)
102 {
103 while (!(dma_ch_icsr_tll_irst_getb(lli)));
104 }
105
dma_ch_int_clear(int ch_idx)106 __STATIC_INLINE void dma_ch_int_clear(int ch_idx)
107 {
108 uint32_t status = dma_ch_icsr_get(ch_idx);
109
110 if (status & DMA_CH_TBL2_IMST_BIT) {
111 dma_ch_icsr_tbl2_iclr_setb(ch_idx);
112 }
113 if (status & DMA_CH_TLL_IRST_BIT) {
114 int irq_active = (__get_IPSR() != 0) ? 1 : 0;
115 dma_ch_icsr_tll_iclr_setb(ch_idx);
116 if (irq_active) {
117 dma_env.last_dma[ch_idx] = 0; // llist done
118 } else {
119 GLOBAL_INT_DISABLE();
120 dma_env.last_dma[ch_idx] = 0; // llist done
121 GLOBAL_INT_RESTORE();
122 }
123 }
124 }
125
dma_trsc_word_set(int channel_idx,int count)126 __STATIC_INLINE void dma_trsc_word_set(int channel_idx, int count)
127 {
128 uint32_t reg_val = 0 ;
129 // dma_ch_ctlr_set(channel_idx, (0x01UL << DMA_CH_BUSBU_LSB));
130 reg_val = (count | (REQ_TRSC << DMA_CH_RQTYP_LSB)
131 | (AHB_WORD << DMA_CH_DBUSU_LSB)
132 | ((uint32_t)AHB_WORD << DMA_CH_SBUSU_LSB));
133 dma_ch_tbl0cr_set(channel_idx, reg_val);
134 dma_ch_tsr_set(channel_idx, (4 << DMA_CH_STRANSZ_LSB) | (4 << DMA_CH_DTRANSZ_LSB));
135 }
136
dma_trsc_byte_set(int channel_idx)137 __STATIC_INLINE void dma_trsc_byte_set(int channel_idx)
138 {
139 uint32_t reg_val = 0 ;
140 // dma_ch_ctlr_set(channel_idx, (0x01UL << DMA_CH_BUSBU_LSB));
141 reg_val = (0x800 | (REQ_TRSC << DMA_CH_RQTYP_LSB)
142 | (AHB_WORD << DMA_CH_DBUSU_LSB)
143 | ((uint32_t)AHB_BYTE << DMA_CH_SBUSU_LSB));
144 dma_ch_tbl0cr_set(channel_idx, reg_val);
145 dma_ch_tsr_set(channel_idx, (1 << DMA_CH_STRANSZ_LSB) | (4 << DMA_CH_DTRANSZ_LSB));
146 }
147
dma_desc_length_set(volatile dma_desc_t * desc,uint32_t len)148 __STATIC_INLINE void dma_desc_length_set(volatile dma_desc_t *desc, uint32_t len)
149 {
150 desc->TBL0CR = ((len > 0x1000) ? 0x1000 : len) | (REQ_LLIST << DMA_CH_RQTYP_LSB)
151 | (AHB_WORD << DMA_CH_DBUSU_LSB)
152 | ((uint32_t)AHB_WORD << DMA_CH_SBUSU_LSB);
153 desc->TBL1CR = (len << DMA_CH_TBL1_CNT_LSB) & DMA_CH_TBL1_CNT_MASK;
154 desc->TBL2CR = (len << DMA_CH_TBL2_CNT_LSB) & DMA_CH_TBL2_CNT_MASK;
155 desc->TSR = (4 << DMA_CH_STRANSZ_LSB) | (4 << DMA_CH_DTRANSZ_LSB);
156 }
157
dma_desc_byte_trans_length_set(volatile dma_desc_t * desc,uint32_t len)158 __STATIC_INLINE void dma_desc_byte_trans_length_set(volatile dma_desc_t *desc, uint32_t len)
159 {
160 desc->TBL0CR = ((len > 0x1000) ? 0x1000 : len) | (REQ_LLIST << DMA_CH_RQTYP_LSB)
161 | (AHB_WORD << DMA_CH_DBUSU_LSB)
162 | ((uint32_t)AHB_BYTE << DMA_CH_SBUSU_LSB);
163 desc->TBL1CR = (len << DMA_CH_TBL1_CNT_LSB) & DMA_CH_TBL1_CNT_MASK;
164 desc->TBL2CR = (len << DMA_CH_TBL2_CNT_LSB) & DMA_CH_TBL2_CNT_MASK;
165 desc->TSR = (1 << DMA_CH_STRANSZ_LSB) | (4 << DMA_CH_DTRANSZ_LSB);
166 }
167
dma_desc_length_set_with_tbl0cnt(volatile dma_desc_t * desc,uint32_t len,uint32_t tbl0_cnt)168 __STATIC_INLINE void dma_desc_length_set_with_tbl0cnt(volatile dma_desc_t *desc, uint32_t len, uint32_t tbl0_cnt)
169 {
170 desc->TBL0CR = ((tbl0_cnt << DMA_CH_TBL0_CNT_LSB) & DMA_CH_TBL0_CNT_MASK)
171 | (REQ_LLIST << DMA_CH_RQTYP_LSB)
172 | (AHB_WORD << DMA_CH_DBUSU_LSB)
173 | ((uint32_t)AHB_WORD << DMA_CH_SBUSU_LSB);
174 desc->TBL1CR = (len << DMA_CH_TBL1_CNT_LSB) & DMA_CH_TBL1_CNT_MASK;
175 desc->TBL2CR = (len << DMA_CH_TBL2_CNT_LSB) & DMA_CH_TBL2_CNT_MASK;
176 desc->TSR = (4 << DMA_CH_STRANSZ_LSB) | (4 << DMA_CH_DTRANSZ_LSB);
177 }
178
dma_desc_lastlli_setb(dma_desc_t * desc)179 __STATIC_INLINE void dma_desc_lastlli_setb(dma_desc_t *desc)
180 {
181 desc->TBL0CR |= DMA_CH_LASTLLI_BIT;
182 }
183
dma_desc_lastlli_clrb(volatile dma_desc_t * desc)184 __STATIC_INLINE void dma_desc_lastlli_clrb(volatile dma_desc_t *desc)
185 {
186 desc->TBL0CR &= ~DMA_CH_LASTLLI_BIT;
187 }
188
dma_desc_dedicated_int_en_setb(volatile dma_desc_t * desc)189 __STATIC_INLINE void dma_desc_dedicated_int_en_setb(volatile dma_desc_t *desc)
190 {
191 desc->TBL2CR |= DMA_CH_LLI_DEDIC_INT_EN_BIT;
192 }
193
dma_desc_dedicated_int_en_clrb(dma_desc_t * desc)194 __STATIC_INLINE void dma_desc_dedicated_int_en_clrb(dma_desc_t *desc)
195 {
196 desc->TBL2CR &= ~DMA_CH_LLI_DEDIC_INT_EN_BIT;
197 }
198
dma_desc_dedicated_counter_en_setb(volatile dma_desc_t * desc)199 __STATIC_INLINE void dma_desc_dedicated_counter_en_setb(volatile dma_desc_t *desc)
200 {
201 desc->TBL2CR |= DMA_CH_LLI_DEDIC_COUNTER_EN_BIT;
202 }
203
dma_desc_dedicated_counter_en_clrb(volatile dma_desc_t * desc)204 __STATIC_INLINE void dma_desc_dedicated_counter_en_clrb(volatile dma_desc_t *desc)
205 {
206 desc->TBL2CR &= ~DMA_CH_LLI_DEDIC_COUNTER_EN_BIT;
207 }
208
209 #endif // _DMA_API_H_
210