00001
00020
00021
00022
00023
00024
00025 #include <string.h>
00026
00027
00028 #include "dbg_assert.h"
00029
00030 #include "ke_event.h"
00031
00032 #include "hal_dma.h"
00033
00034 #include "dbg.h"
00035
00036 #if NX_GP_DMA
00038 const uint8_t dma2chan[DMA_MAX] =
00039 {
00040 [DMA_DL] = IPC_DMA_CHANNEL_CTRL_TX,
00041 [DMA_UL] = IPC_DMA_CHANNEL_CTRL_RX,
00042 };
00043
00045 const uint8_t dma2lli[DMA_MAX] =
00046 {
00047 [DMA_DL] = IPC_DMA_LLI_GP_DL,
00048 [DMA_UL] = IPC_DMA_LLI_GP_UL,
00049 };
00050
00052 #define DMA_LLICTRL(index) (IPC_DMA_LLI_COUNTER_EN|(dma2lli[index]<<IPC_DMA_LLI_COUNTER_POS) \
00053 | IPC_DMA_LLI_IRQ_EN|(dma2lli[index] << IPC_DMA_LLI_IRQ_POS))
00054
00055
00056
00057
00058
00059
00060 struct hal_dma_env_tag hal_dma_env;
00061
00062 #if (HAL_DMA_POOL)
00064 struct hal_dma_desc_tag hal_dma_desc_pool[HAL_DMA_DESC_POOL_SIZE];
00065 #endif //(HAL_DMA_POOL)
00066
00067
00068
00069
00070
00071 #if (HAL_DMA_POOL)
00072
00082 __INLINE bool hal_dma_is_in_pool(struct hal_dma_desc_tag *desc)
00083 {
00084 return((desc >= &hal_dma_desc_pool[0]) &&
00085 (desc <= &hal_dma_desc_pool[HAL_DMA_DESC_POOL_SIZE - 1]));
00086 }
00087 #endif //(HAL_DMA_POOL)
00088
00089 void hal_dma_init(void)
00090 {
00091 int i;
00092
00093
00094 for (i = 0; i < DMA_MAX; i++)
00095 {
00096 co_list_init(&hal_dma_env.prog[i]);
00097 hal_dma_env.lli_cnt[i] = dma_lli_counter_get(dma2lli[i]);
00098 }
00099
00100 #if (HAL_DMA_POOL)
00101
00102 memset(&hal_dma_desc_pool[0], 0, HAL_DMA_DESC_POOL_SIZE * sizeof(struct hal_dma_desc_tag));
00103
00104
00105 co_list_init(&hal_dma_env.free_gp_dma_descs);
00106
00107 for (i = 0; i < HAL_DMA_DESC_POOL_SIZE; i++)
00108 {
00109
00110 co_list_push_back(&hal_dma_env.free_gp_dma_descs, &hal_dma_desc_pool[i].hdr);
00111 }
00112 #endif //(HAL_DMA_POOL)
00113 }
00114
00115
00116 void hal_dma_push(struct hal_dma_desc_tag *desc, int type)
00117 {
00118 struct dma_desc *dma_desc = desc->dma_desc;
00119 struct co_list *list = &hal_dma_env.prog[type];
00120
00121
00122 if ((desc->cb != NULL)
00123 #if (HAL_DMA_POOL)
00124 || hal_dma_is_in_pool(desc)
00125 #endif
00126 )
00127 {
00128
00129 dma_desc->ctrl = DMA_LLICTRL(type);
00130
00131
00132
00133 GLOBAL_INT_DISABLE();
00134 co_list_push_back(list, &desc->hdr);
00135 GLOBAL_INT_RESTORE();
00136 }
00137 else
00138 {
00139
00140 dma_desc->ctrl = 0;
00141 }
00142
00143
00144 dma_push(dma_desc, dma_desc, dma2chan[type]);
00145 }
00146
00147 void hal_dma_evt(int dma_queue)
00148 {
00149 int lli = dma2lli[dma_queue];
00150
00151
00152 if (dma_queue == DMA_DL)
00153 {
00154 ke_evt_clear(KE_EVT_GP_DMA_DL_BIT);
00155 }
00156 else
00157 {
00158 ke_evt_clear(KE_EVT_GP_DMA_UL_BIT);
00159 }
00160
00161
00162 while (hal_dma_env.lli_cnt[dma_queue] != dma_lli_counter_get(lli))
00163 {
00164 struct hal_dma_desc_tag *desc;
00165
00166
00167 GLOBAL_INT_DISABLE();
00168 desc = (struct hal_dma_desc_tag *) co_list_pop_front(&hal_dma_env.prog[dma_queue]);
00169 GLOBAL_INT_RESTORE();
00170
00171
00172 ASSERT_ERR(desc != NULL);
00173
00174
00175 dma_int_ack_clear(CO_BIT(lli + DMA_LLI_IRQ_LSB));
00176
00177
00178 if (desc->cb != NULL)
00179 {
00180 desc->cb(desc->env, dma_queue);
00181 }
00182
00183 #if (HAL_DMA_POOL)
00184
00185 if (hal_dma_is_in_pool(desc))
00186 {
00187 co_list_push_back(&hal_dma_env.free_gp_dma_descs, &desc->hdr);
00188 }
00189 #endif //(HAL_DMA_POOL)
00190
00191
00192 hal_dma_env.lli_cnt[dma_queue]++;
00193 }
00194
00195
00196 dma_lli_enable(lli);
00197 }
00198
00199 void hal_dma_dl_irq(void)
00200 {
00201
00202 dma_lli_disable(IPC_DMA_LLI_GP_DL);
00203
00204
00205 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_GP_DL + DMA_LLI_IRQ_LSB));
00206
00207
00208 ke_evt_set(KE_EVT_GP_DMA_DL_BIT);
00209 }
00210
00211 void hal_dma_ul_irq(void)
00212 {
00213
00214 dma_lli_disable(IPC_DMA_LLI_GP_UL);
00215
00216
00217 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_GP_UL + DMA_LLI_IRQ_LSB));
00218
00219
00220 ke_evt_set(KE_EVT_GP_DMA_UL_BIT);
00221 }
00222
00223 #if (HAL_DMA_POOL)
00224 struct hal_dma_desc_tag *hal_dma_get_desc(void)
00225 {
00226 return ((struct hal_dma_desc_tag *)co_list_pop_front(&hal_dma_env.free_gp_dma_descs));
00227 }
00228
00229 void hal_dma_release_desc(struct hal_dma_desc_tag *gp_dma_desc)
00230 {
00231 co_list_push_back(&hal_dma_env.free_gp_dma_descs, &gp_dma_desc->hdr);
00232 }
00233 #endif //(HAL_DMA_POOL)
00234
00235 #endif
00236