1  /*
2  * Copyright (C) 2017-2024 Alibaba Group Holding Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 
20 /******************************************************************************
21  * @file     target_get.c
22  * @brief    CSI Source File for target API
23  * @version  V1.0
24  * @date     9. April 2020
25  ******************************************************************************/
26 
27 #include <stdint.h>
28 #include <soc.h>
29 #include <csi_core.h>
30 #include <csi_config.h>
31 #include <drv/common.h>
32 #include <drv/pin.h>
33 #include <drv/dma.h>
34 
35 extern csi_perip_info_t g_soc_info[];
36 extern const csi_dma_ch_spt_list_t dma_spt_list[];
37 
target_get(csi_dev_tag_t dev_tag,uint32_t idx,csi_dev_t * dev)38 csi_error_t target_get(csi_dev_tag_t dev_tag, uint32_t idx, csi_dev_t *dev)
39 {
40     csi_error_t ret = CSI_OK;
41     csi_perip_info_t *info;
42 
43     if (dev == NULL) {
44         ret = CSI_ERROR;
45     }
46 
47     ///< 使用包含外设基地址,外设中断号,外设设备号,外设设备类型成员的结构体数组变量初始化info
48     info = (csi_perip_info_t *)&g_soc_info;
49 
50     ///< 获取相应的设备类型和设备号
51     while (info->reg_base) {
52         if ((info->dev_tag == (uint16_t)dev_tag) && (info->idx == (uint8_t)idx)) {
53             break;
54         }
55 
56         info++;
57     }
58 
59     ///< 初始化设备的统一句柄:基地址,中断号,设备号,设备类型
60     if (info->reg_base == 0U) {
61         ret = CSI_ERROR;
62     }
63 
64     if (ret != CSI_ERROR) {
65         dev->reg_base = info->reg_base;
66         dev->irq_num  = info->irq_num;
67         dev->idx      = info->idx;
68         dev->dev_tag  = (uint16_t)dev_tag;
69     }
70 
71     return ret;
72 }
73 
target_pin_to_devidx(pin_name_t pin_name,const csi_pinmap_t * pinmap)74 uint32_t target_pin_to_devidx(pin_name_t pin_name, const  csi_pinmap_t *pinmap)
75 {
76     const csi_pinmap_t *map = pinmap;
77     uint32_t ret = 0xFFFFFFFFU;
78 
79     while ((uint32_t)map->pin_name != 0xFFFFFFFFU) {
80         if ((map->pin_name == pin_name) && (csi_pin_get_mux(pin_name) == map->pin_func)) {
81             ret = map->idx;
82             break;
83         }
84 
85         map++;
86     }
87 
88     return ret;
89 }
90 
target_pin_to_channel(pin_name_t pin_name,const csi_pinmap_t * pinmap)91 uint32_t target_pin_to_channel(pin_name_t pin_name, const csi_pinmap_t *pinmap)
92 {
93     const csi_pinmap_t *map = pinmap;
94     uint32_t ret = 0xFFFFFFFFU;
95 
96     while ((uint32_t)map->pin_name != 0xFFFFFFFFU) {
97         if (map->pin_name == pin_name) {
98             ret = (uint32_t)map->channel;
99             break;
100         }
101 
102         map++;
103     }
104 
105     return ret;
106 }
107 
target_gpio_to_pin(uint8_t gpio_idx,uint8_t channel,const csi_pinmap_t * pinmap)108 pin_name_t target_gpio_to_pin(uint8_t gpio_idx, uint8_t channel, const csi_pinmap_t *pinmap)
109 {
110     const csi_pinmap_t *map = pinmap;
111     pin_name_t ret = (pin_name_t)0xFFU;
112 
113     while ((uint32_t)map->pin_name != 0xFFFFFFFFU) {
114         if ((map->idx == gpio_idx) && (map->channel == channel)) {
115             ret = map->pin_name;
116             break;
117         }
118 
119         map++;
120     }
121 
122     return ret;
123 }
124 
target_get_optimal_dma_channel(void * dma_list,uint32_t ctrl_num,csi_dev_t * parent_dev,void * ch_info)125 csi_error_t target_get_optimal_dma_channel(void *dma_list, uint32_t ctrl_num, csi_dev_t *parent_dev, void *ch_info)
126 {
127     uint32_t spt_id, ch_info_id, ctrl_id, ch_id;
128     int32_t is_find = 0;
129     csi_error_t csi_ret = CSI_OK;
130     csi_dma_t **list = (csi_dma_t **)dma_list;
131     csi_dma_ch_desc_t *dma_ch_info = (csi_dma_ch_desc_t *)ch_info;
132 
133     if (parent_dev == NULL) {
134         /* the MEM2MEM mode */
135         for (ctrl_id = 0U; ctrl_id < ctrl_num; ctrl_id++) {
136             for (ch_id = 0U; ch_id < list[ctrl_id]->ch_num; ch_id++) {
137                 if (!(list[ctrl_id]->alloc_status & ((uint32_t)1 << ch_id))) {
138                     dma_ch_info->ch_idx = (uint8_t)ch_id;
139                     dma_ch_info->ctrl_idx = (uint8_t)ctrl_id;
140                     /* find the channel */
141                     is_find = 1;
142                     break;
143                 }
144             }
145 
146             if (is_find) {
147                 break;
148             }
149         }
150 
151         if (is_find == 0) {
152             csi_ret = CSI_ERROR;
153         }
154     } else {
155         /* the MEM2PERH mode or PERH2MEM mode */
156         for (spt_id = 0U; dma_spt_list[spt_id].dev_tag != 0xFFFFU; spt_id++) {
157             if ((dma_spt_list[spt_id].dev_tag == parent_dev->dev_tag) && ((uint8_t)dma_spt_list[spt_id].ctrl_idx == parent_dev->idx)) {
158                 break;
159             }
160         }
161 
162         if (dma_spt_list[spt_id].dev_tag == 0xFFFFU) {
163             csi_ret = CSI_ERROR;
164         }
165 
166         for (ch_info_id = 0U;; ch_info_id++) {
167             if (dma_spt_list[spt_id].ch_list[ch_info_id].ctrl_idx == 0xFFU) {
168                 csi_ret = CSI_ERROR;
169                 break;
170             }
171 
172             for (ctrl_id = 0U; ctrl_id < ctrl_num; ctrl_id++) {
173                 if ((ctrl_id == dma_spt_list[spt_id].ch_list[ch_info_id].ctrl_idx) &&
174                     !(list[ctrl_id]->alloc_status & ((uint32_t)1 << dma_spt_list[spt_id].ch_list[ch_info_id].ch_idx))) {
175                     dma_ch_info->ch_idx = dma_spt_list[spt_id].ch_list[ch_info_id].ch_idx;
176                     dma_ch_info->ctrl_idx = dma_spt_list[spt_id].ch_list[ch_info_id].ctrl_idx;
177                     /* find the channel */
178                     is_find = 1;
179                     break;
180                 }
181             }
182 
183             if (is_find) {
184                 break;
185             }
186         }
187     }
188 
189     return csi_ret;
190 }
191