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