1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18 /** @page DMA
19 *
20 * Introduction
21 * ===============
22 *
23 *
24 * API Reference
25 * ===============
26 * Header File: dma.h
27 */
28 #ifndef DMA_H_
29 #define DMA_H_
30 #include "reg_include/register_b91.h"
31 typedef enum {
32 DMA0 = 0,
33 DMA1,
34 DMA2,
35 DMA3,
36 DMA4,
37 DMA5,
38 DMA6,
39 DMA7,
40 } dma_chn_e;
41
42 typedef enum {
43 DMA_CHN0_IRQ = BIT(0),
44 DMA_CHN1_IRQ = BIT(1),
45 DMA_CHN2_IRQ = BIT(2),
46 DMA_CHN3_IRQ = BIT(3),
47 DMA_CHN4_IRQ = BIT(4),
48 DMA_CHN5_IRQ = BIT(5),
49 DMA_CHN6_IRQ = BIT(6),
50 DMA_CHN7_IRQ = BIT(7),
51 } dma_irq_chn_e;
52
53 typedef enum {
54 DMA_REQ_SPI_AHB_TX = 0,
55 DMA_REQ_SPI_AHB_RX,
56 DMA_REQ_UART0_TX,
57 DMA_REQ_UART0_RX,
58 DMA_REQ_SPI_APB_TX,
59 DMA_REQ_SPI_APB_RX,
60 DMA_REQ_I2C_TX,
61 DMA_REQ_I2C_RX,
62 DMA_REQ_ZB_TX,
63 DMA_REQ_ZB_RX,
64 DMA_REQ_PWM_TX,
65 DMA_REQ_RESERVED,
66 DMA_REQ_ALGM_TX,
67 DMA_REQ_ALGM_RX,
68 DMA_REQ_UART1_TX,
69 DMA_REQ_UART1_RX,
70 DMA_REQ_AUDIO0_TX,
71 DMA_REQ_AUDIO0_RX,
72 DMA_REQ_AUDIO1_TX,
73 DMA_REQ_AUDIO1_RX,
74 } dma_req_sel_e;
75
76 typedef enum {
77 DMA_ADDR_INCREMENT = 0,
78 DMA_ADDR_DECREMENT,
79 DMA_ADDR_FIX,
80 } dma_addr_ctrl_e;
81
82 typedef enum {
83 DMA_NORMAL_MODE = 0,
84 DMA_HANDSHAKE_MODE,
85 } dma_mode_e;
86
87 typedef enum {
88 DMA_CTR_BYTE_WIDTH = 0,
89 DMA_CTR_HWORD_WIDTH,
90 DMA_CTR_WORD_WIDTH,
91 } dma_ctr_width_e;
92
93 typedef enum {
94 DMA_BYTE_WIDTH = 1,
95 DMA_HWORD_WIDTH = 2,
96 DMA_WORD_WIDTH = 4,
97 } dma_transfer_width_e;
98
99 typedef enum {
100 TC_MASK = BIT(1),
101 ERR_MASK = BIT(2),
102 ABT_MASK = BIT(3),
103 } dma_irq_mask_e;
104
105 typedef struct {
106 unsigned int dst_req_sel : 5; /* DstReqSel :8:4 */
107 unsigned int src_req_sel : 5; /* SrcReqSel :13:9 */
108 unsigned int dst_addr_ctrl : 2; /* DstAddrCtrl :15:14 0:increment address 1: decrement address 2: fixed address */
109 unsigned int src_addr_ctrl : 2; /* SrcAddrCtrl :17:16 0:increment address 1: decrement address 2: fixed address */
110 unsigned int dstmode : 1; /* DstMode:18 0 normal mode 1 handshake */
111 unsigned int srcmode : 1; /* SrcMode :19 0 normal mode 1 handshake */
112 unsigned int dstwidth : 2; /* DstWidth :21:20 00:byte 01:hword 02:word */
113 unsigned int srcwidth : 2; /* SrcWidth :23:22 00:byte 01:hword 02:word */
114 unsigned int src_burst_size : 3; /* SrcBurstSize: 26:24 */
115 unsigned int vacant_bit : 1; /* vacant:27 */
116 unsigned int read_num_en : 1; /* Rnum_en :28 */
117 unsigned int priority : 1; /* Pri :29 */
118 unsigned int write_num_en : 1; /* wnum_en : 30 */
119 unsigned int auto_en : 1; /* auto_en : 31 */
120 } dma_config_t;
121
122 typedef struct {
123 unsigned int dma_chain_ctl;
124 unsigned int dma_chain_src_addr;
125 unsigned int dma_chain_dst_addr;
126 unsigned int dma_chain_data_len;
127 unsigned int dma_chain_llp_ptr;
128 } dma_chain_config_t;
129
130 /**
131 * @brief This function configures DMA control register.
132 * @param[in] chn - dma channel
133 * @param[in] config - the prt of dma_config that configured control register
134 * @return none
135 */
dma_config(dma_chn_e chn,dma_config_t * config)136 static inline void dma_config(dma_chn_e chn, dma_config_t *config)
137 {
138 BM_CLR(reg_dma_ctrl(chn), BIT_RNG(4, 31));
139 reg_dma_ctrl(chn) |= (*(unsigned int *)config) << 4;
140 }
141
142 /**
143 * @brief This function servers to enable dma that selected channel.
144 * @param[in] chn - dma channel.
145 * @return none
146 */
dma_chn_en(dma_chn_e chn)147 static inline void dma_chn_en(dma_chn_e chn)
148 {
149 BM_SET(reg_dma_ctr0(chn), BIT(0));
150 }
151
152 /**
153 * @brief This function servers to disable dma that selected channel.
154 * @param[in] chn - dma channel.
155 * @return none
156 */
dma_chn_dis(dma_chn_e chn)157 static inline void dma_chn_dis(dma_chn_e chn)
158 {
159 BM_CLR(reg_dma_ctr0(chn), BIT(0));
160 }
161
162 /**
163 * @brief This function servers to set dma irq mask.
164 * @param[in] chn - dma channel.
165 * @param[in] mask - dma irq mask.
166 * @return none
167 */
dma_set_irq_mask(dma_chn_e chn,dma_irq_mask_e mask)168 static inline void dma_set_irq_mask(dma_chn_e chn, dma_irq_mask_e mask)
169 {
170 reg_dma_ctr0(chn) = (reg_dma_ctr0(chn) | BIT_RNG(1, 3)) & (~(mask));
171 }
172
173 /**
174 * @brief This function servers to clr dma irq mask.
175 * @param[in] chn - dma channel.
176 * @param[in] mask - dma irq mask.
177 * @return none
178 * attention the mask of dma tc/err/abt is enable default.we must disable when don'n use it.
179 */
dma_clr_irq_mask(dma_chn_e chn,dma_irq_mask_e mask)180 static inline void dma_clr_irq_mask(dma_chn_e chn, dma_irq_mask_e mask)
181 {
182 reg_dma_ctr0(chn) |= (mask);
183 }
184
185 /**
186 * @brief This function servers to get the terminal count irq status channel.
187 * @return the dma terminal count irq status channel.
188 */
dma_get_tc_irq_status(dma_irq_chn_e tc_chn)189 static inline unsigned char dma_get_tc_irq_status(dma_irq_chn_e tc_chn)
190 {
191 return reg_dma_tc_isr & tc_chn;
192 }
193
194 /**
195 * @brief This function servers to clear the irq of terminal count status.
196 * @param[in] tc_chn -terminal count irq status channel.
197 * @return none
198 */
dma_clr_tc_irq_status(dma_irq_chn_e tc_chn)199 static inline void dma_clr_tc_irq_status(dma_irq_chn_e tc_chn)
200 {
201 reg_dma_tc_isr = tc_chn;
202 }
203
204 /**
205 * @brief This function servers to get the error irq status channel.
206 * @return the dma error irq status channel.
207 */
dma_get_err_irq_status(dma_irq_chn_e err_chn)208 static inline unsigned char dma_get_err_irq_status(dma_irq_chn_e err_chn)
209 {
210 return reg_dma_err_isr & err_chn;
211 }
212
213 /**
214 * @brief This function servers to clear the abort status of channel.
215 * @param[in] err_chn -error status channel.
216 * @return none
217 */
dma_clr_err_irq_status(dma_irq_chn_e err_chn)218 static inline void dma_clr_err_irq_status(dma_irq_chn_e err_chn)
219 {
220 reg_dma_err_isr = err_chn;
221 }
222
223 /**
224 * @brief This function servers to get the abort status of channel.
225 * @return the dma abort irq status channel.
226 */
dma_get_abt_irq_status(dma_irq_chn_e abt_chn)227 static inline unsigned char dma_get_abt_irq_status(dma_irq_chn_e abt_chn)
228 {
229 return reg_dma_abt_isr & abt_chn;
230 }
231
232 /**
233 * @brief This function servers to clear the abort status of channel.
234 * @param[in] abt_chn -abort irq status channel.
235 * @return none
236 */
dma_clr_abt_irq_status(dma_irq_chn_e abt_chn)237 static inline void dma_clr_abt_irq_status(dma_irq_chn_e abt_chn)
238 {
239 reg_dma_abt_isr = abt_chn;
240 }
241
242 /**
243 * @brief this function set the DMA to tx/rx size byte.
244 * @param[in] chn - DMA channel
245 * @param[in] size_byte - the address of dma tx/rx size.
246 * The maximum transmission length of DMA is 0xFFFFFC bytes and cannot exceed this length.
247 * @param[in] byte_width - dma tx/rx width
248 * @return none
249 */
dma_set_size(dma_chn_e chn,unsigned int size_byte,dma_transfer_width_e byte_width)250 static inline void dma_set_size(dma_chn_e chn, unsigned int size_byte, dma_transfer_width_e byte_width)
251 {
252 reg_dma_size(chn) = ((size_byte + byte_width - 1) / byte_width) | ((size_byte % byte_width) << 22);
253 }
254
255 /**
256 * @brief this function calculate the DMA to tx/rx size byte.
257 * @param[in] size_byte - the address of dma tx/rx size
258 * @param[in] byte_width - dma tx/rx width
259 * @return none
260 */
dma_cal_size(unsigned int size_byte,dma_transfer_width_e byte_width)261 static inline unsigned int dma_cal_size(unsigned int size_byte, dma_transfer_width_e byte_width)
262 {
263 return (((size_byte + byte_width - 1) / byte_width) | ((size_byte % byte_width) << 22));
264 }
265
266 /**
267 * @brief this function set source and destination address for DMA,
268 * src_address dst_address
269 * tx sram interface fifo.
270 * rx interface fifo sram
271 * @param[in] chn - DMA channel
272 * @param[in] src_addr - the address of source.
273 * @param[in] dst_addr - the address of destination.
274 * @return none
275 */
dma_set_address(dma_chn_e chn,unsigned int src_addr,unsigned int dst_addr)276 static inline void dma_set_address(dma_chn_e chn, unsigned int src_addr, unsigned int dst_addr)
277 {
278 reg_dma_src_addr(chn) = src_addr;
279 reg_dma_dst_addr(chn) = dst_addr;
280 }
281
282 /**
283 * @brief this function set source address for DMA,
284 * @param[in] chn - DMA channel
285 * @param[in] src_addr - the address of source.
286 * */
dma_set_src_address(dma_chn_e chn,unsigned int src_addr)287 static inline void dma_set_src_address(dma_chn_e chn, unsigned int src_addr)
288 {
289 reg_dma_src_addr(chn) = src_addr;
290 }
291
292 /**
293 * @brief this function set destination address for DMA,
294 * @param[in] chn - DMA channel
295 * @param[in] dst_addr - the address of destination.
296 * */
dma_set_dst_address(dma_chn_e chn,unsigned int dst_addr)297 static inline void dma_set_dst_address(dma_chn_e chn, unsigned int dst_addr)
298 {
299 reg_dma_dst_addr(chn) = dst_addr;
300 }
301
302 /**
303 * @brief this function set reset DMA,
304 * @return none
305 */
dma_reset(void)306 static inline void dma_reset(void)
307 {
308 reg_rst1 &= ~(FLD_RST1_DMA);
309 reg_rst1 |= FLD_RST1_DMA;
310 }
311
312 #endif
313