1
2 /* Copyright Canaan Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <rtthread.h>
18 #include "dmalock.h"
19
20 struct dmac_host
21 {
22 struct rt_semaphore sem;
23 struct rt_mutex mutex;
24 uint8_t channel_used[DMAC_CHANNEL_COUNT];
25 char *channel_name[DMAC_CHANNEL_COUNT];
26 };
27
28 static struct dmac_host _dmac_host;
29
dmalock_init(void)30 void dmalock_init(void)
31 {
32 rt_sem_init(&_dmac_host.sem, "dma_sem", DMAC_CHANNEL_COUNT, RT_IPC_FLAG_FIFO);
33 rt_mutex_init(&_dmac_host.mutex, "dma_mutex", RT_IPC_FLAG_PRIO);
34 for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
35 {
36 _dmac_host.channel_used[i] = 0;
37 _dmac_host.channel_name[i] = NULL;
38 }
39 }
40
_dmalock_sync_take(dmac_channel_number_t * chn,int timeout_ms,const char * name)41 int _dmalock_sync_take(dmac_channel_number_t *chn, int timeout_ms, const char *name)
42 {
43 rt_err_t result;
44
45 *chn = DMAC_CHANNEL_MAX;
46 result = rt_sem_take(&_dmac_host.sem, timeout_ms);
47 if (result == RT_EOK)
48 {
49 rt_mutex_take(&_dmac_host.mutex, RT_WAITING_FOREVER);
50 for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
51 {
52 if (_dmac_host.channel_used[i] == 0)
53 {
54 _dmac_host.channel_used[i] = 1;
55 _dmac_host.channel_name[i] = name;
56 *chn = i;
57 break;
58 }
59 }
60 rt_mutex_release(&_dmac_host.mutex);
61 }
62 return result;
63 }
64
dmalock_release(dmac_channel_number_t chn)65 void dmalock_release(dmac_channel_number_t chn)
66 {
67 if (chn >= DMAC_CHANNEL_MAX)
68 return;
69 _dmac_host.channel_name[chn] = NULL;
70 _dmac_host.channel_used[chn] = 0;
71 rt_sem_release(&_dmac_host.sem);
72 }
73
dma_ch_info(int argc,char ** argv)74 static void dma_ch_info(int argc, char **argv)
75 {
76 uint32_t cnt = 0;
77
78 for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
79 {
80 if (_dmac_host.channel_used[i] != 0)
81 {
82 rt_kprintf("dma_ch%d is using by func [%s]\n", i, _dmac_host.channel_name[i]);
83 cnt++;
84 }
85 }
86
87 if(cnt == 0)
88 rt_kprintf(" no dma_ch is using.\n");
89 }
90 MSH_CMD_EXPORT(dma_ch_info, list dma channel informationn.);
91