• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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