1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18 #include "gpio.h"
19
20 /**********************************************************************************************************************
21 * local constants *
22 *********************************************************************************************************************/
23
24 /**********************************************************************************************************************
25 * local macro *
26 *********************************************************************************************************************/
27
28 /**********************************************************************************************************************
29 * local data type *
30 *********************************************************************************************************************/
31
32 /**********************************************************************************************************************
33 * global variable *
34 *********************************************************************************************************************/
35
36 /**********************************************************************************************************************
37 * local variable *
38 *********************************************************************************************************************/
39
40 /**********************************************************************************************************************
41 * local function prototype *
42 *********************************************************************************************************************/
43
44 /**********************************************************************************************************************
45 * global function implementation *
46 *********************************************************************************************************************/
47
48 /**
49 * @brief This function enable the input function of a pin.
50 * @param[in] pin - the pin needs to set the input function.
51 * @return none.
52 */
gpio_input_en(gpio_pin_e pin)53 void gpio_input_en(gpio_pin_e pin)
54 {
55 unsigned char bit = pin & 0xff;
56 unsigned short group = pin & 0xf00;
57
58 if (group == GPIO_GROUPA || group == GPIO_GROUPB || group == GPIO_GROUPE) {
59 BM_SET(reg_gpio_ie(pin), bit);
60 } else if (group == GPIO_GROUPC) {
61 analog_write_reg8(areg_gpio_pc_ie, analog_read_reg8(areg_gpio_pc_ie) | bit);
62 } else if (group == GPIO_GROUPD) {
63 analog_write_reg8(areg_gpio_pd_ie, analog_read_reg8(areg_gpio_pd_ie) | bit);
64 }
65 }
66
67 /**
68 * @brief This function disable the input function of a pin.
69 * @param[in] pin - the pin needs to set the input function.
70 * @return none.
71 */
gpio_input_dis(gpio_pin_e pin)72 void gpio_input_dis(gpio_pin_e pin)
73 {
74 unsigned char bit = pin & 0xff;
75 unsigned short group = pin & 0xf00;
76
77 if (group == GPIO_GROUPA || group == GPIO_GROUPB || group == GPIO_GROUPE) {
78 BM_CLR(reg_gpio_ie(pin), bit);
79 } else if (group == GPIO_GROUPC) {
80 analog_write_reg8(areg_gpio_pc_ie, analog_read_reg8(areg_gpio_pc_ie) & (~bit));
81 } else if (group == GPIO_GROUPD) {
82 analog_write_reg8(areg_gpio_pd_ie, analog_read_reg8(areg_gpio_pd_ie) & (~bit));
83 }
84 }
85
86 /**
87 * @brief This function set the input function of a pin.
88 * @param[in] pin - the pin needs to set the input function
89 * @param[in] value - enable or disable the pin's input function(1: enable,0: disable )
90 * @return none
91 */
gpio_set_input(gpio_pin_e pin,unsigned char value)92 void gpio_set_input(gpio_pin_e pin, unsigned char value)
93 {
94 if (value) {
95 gpio_input_en(pin);
96 } else {
97 gpio_input_dis(pin);
98 }
99 }
100
101 /**
102 * @brief This function set the pin's driving strength at strong.
103 * @param[in] pin - the pin needs to set the driving strength
104 * @return none
105 */
gpio_ds_en(gpio_pin_e pin)106 void gpio_ds_en(gpio_pin_e pin)
107 {
108 unsigned char bit = pin & 0xff;
109 unsigned short group = pin & 0xf00;
110 if (group == GPIO_GROUPC) {
111 analog_write_reg8(areg_gpio_pc_ds, analog_read_reg8(areg_gpio_pc_ds) | bit);
112 } else if (group == GPIO_GROUPD) {
113 analog_write_reg8(areg_gpio_pd_ds, analog_read_reg8(areg_gpio_pd_ds) | bit);
114 } else {
115 BM_SET(reg_gpio_ds(pin), bit);
116 }
117 }
118
119 /**
120 * @brief This function set the pin's driving strength.
121 * @param[in] pin - the pin needs to set the driving strength at poor.
122 * @return none
123 */
gpio_ds_dis(gpio_pin_e pin)124 void gpio_ds_dis(gpio_pin_e pin)
125 {
126 unsigned char bit = pin & 0xff;
127 unsigned short group = pin & 0xf00;
128 if (group == GPIO_GROUPC) {
129 analog_write_reg8(areg_gpio_pc_ds, analog_read_reg8(areg_gpio_pc_ds) & (~bit));
130 } else if (group == GPIO_GROUPD) {
131 analog_write_reg8(areg_gpio_pd_ds, analog_read_reg8(areg_gpio_pd_ds) & (~bit));
132 } else {
133 BM_CLR(reg_gpio_ds(pin), bit);
134 }
135 }
136
137 /**
138 * @brief This function servers to set the specified GPIO as high resistor.
139 * @param[in] pin - select the specified GPIO
140 * @return none.
141 */
gpio_shutdown(gpio_pin_e pin)142 void gpio_shutdown(gpio_pin_e pin)
143 {
144 unsigned short group = pin & 0xf00;
145 unsigned char bit = pin & 0xff;
146 switch (group) {
147 case GPIO_GROUPA:
148 reg_gpio_pa_oen |= bit; // disable output
149 reg_gpio_pa_out &= (~bit); // set low level
150 reg_gpio_pa_ie &= (~bit); // disable input
151 break;
152 case GPIO_GROUPB:
153 reg_gpio_pb_oen |= bit;
154 reg_gpio_pb_out &= (~bit);
155 reg_gpio_pb_ie &= (~bit);
156 break;
157 case GPIO_GROUPC:
158 reg_gpio_pc_oen |= bit;
159 reg_gpio_pc_out &= (~bit);
160 analog_write_reg8(areg_gpio_pc_ie, analog_read_reg8(areg_gpio_pc_ie) & (~bit));
161 break;
162 case GPIO_GROUPD:
163 reg_gpio_pd_oen |= bit;
164 reg_gpio_pd_out &= (~bit);
165 analog_write_reg8(areg_gpio_pd_ie, analog_read_reg8(areg_gpio_pd_ie) & (~bit));
166 break;
167
168 case GPIO_GROUPE:
169 reg_gpio_pe_oen |= bit;
170 reg_gpio_pe_out &= (~bit);
171 reg_gpio_pe_ie &= (~bit);
172 break;
173
174 case GPIO_ALL: {
175 // as gpio
176 reg_gpio_pa_gpio = 0x7f;
177 reg_gpio_pb_gpio = 0xff;
178 reg_gpio_pc_gpio = 0xff;
179 reg_gpio_pd_gpio = 0xff;
180 reg_gpio_pe_gpio = 0xff;
181
182 // output disable
183 reg_gpio_pa_oen = 0xff;
184 reg_gpio_pb_oen = 0xff;
185 reg_gpio_pc_oen = 0xff;
186 reg_gpio_pd_oen = 0xff;
187 reg_gpio_pe_oen = 0xff;
188
189 // set low level
190 reg_gpio_pa_out = 0x00;
191 reg_gpio_pb_out = 0x00;
192 reg_gpio_pc_out = 0x00;
193 reg_gpio_pd_out = 0x00;
194 reg_gpio_pe_out = 0x00;
195
196 // disable input
197 reg_gpio_pa_ie = 0x80; // SWS
198 reg_gpio_pb_ie = 0x00;
199 analog_write_reg8(areg_gpio_pc_ie, 0);
200 analog_write_reg8(areg_gpio_pd_ie, 0);
201 reg_gpio_pe_ie = 0x00;
202 }
203 }
204 }
205
206 /**
207 * @brief This function set a pin's IRQ.
208 * @param[in] pin - the pin needs to enable its IRQ.
209 * @param[in] trigger_type - gpio interrupt type.
210 * 0: rising edge.
211 * 1: falling edge.
212 * 2: high level.
213 * 3: low level.
214 * @return none.
215 */
gpio_set_irq(gpio_pin_e pin,gpio_irq_trigger_type_e trigger_type)216 void gpio_set_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type)
217 {
218 switch (trigger_type) {
219 case INTR_RISING_EDGE:
220 BM_CLR(reg_gpio_pol(pin), pin & 0xff);
221 BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO);
222 break;
223 case INTR_FALLING_EDGE:
224 BM_SET(reg_gpio_pol(pin), pin & 0xff);
225 BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO);
226 break;
227 case INTR_HIGH_LEVEL:
228 BM_CLR(reg_gpio_pol(pin), pin & 0xff);
229 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO);
230 break;
231 case INTR_LOW_LEVEL:
232 BM_SET(reg_gpio_pol(pin), pin & 0xff);
233 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO);
234 break;
235 }
236 reg_gpio_irq_ctrl |= FLD_GPIO_CORE_INTERRUPT_EN;
237 reg_gpio_irq_clr = FLD_GPIO_IRQ_CLR; // must clear cause to unexpected interrupt.
238 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_MASK_GPIO);
239 }
240
241 /**
242 * @brief This function set a pin's IRQ_RISC0.
243 * @param[in] pin - the pin needs to enable its IRQ.
244 * @param[in] trigger_type - gpio interrupt type 0 rising edge 1 falling edge 2 high level 3 low level.
245 * @return none.
246 */
gpio_set_gpio2risc0_irq(gpio_pin_e pin,gpio_irq_trigger_type_e trigger_type)247 void gpio_set_gpio2risc0_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type)
248 {
249 switch (trigger_type) {
250 case INTR_RISING_EDGE:
251 BM_CLR(reg_gpio_pol(pin), pin & 0xff);
252 BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0);
253 break;
254 case INTR_FALLING_EDGE:
255 BM_SET(reg_gpio_pol(pin), pin & 0xff);
256 BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0);
257 break;
258 case INTR_HIGH_LEVEL:
259 BM_CLR(reg_gpio_pol(pin), pin & 0xff);
260 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0);
261 break;
262 case INTR_LOW_LEVEL:
263 BM_SET(reg_gpio_pol(pin), pin & 0xff);
264 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC0);
265 break;
266 }
267 reg_gpio_irq_clr = FLD_GPIO_IRQ_GPIO2RISC0_CLR; // must clear cause to unexpected interrupt.
268 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_MASK_GPIO2RISC0);
269 }
270
271 /**
272 * @brief This function set a pin's IRQ_RISC1.
273 * @param[in] pin - the pin needs to enable its IRQ.
274 * @param[in] trigger_type - gpio interrupt type 0 rising edge 1 falling edge 2 high level 3 low level
275 * @return none.
276 */
gpio_set_gpio2risc1_irq(gpio_pin_e pin,gpio_irq_trigger_type_e trigger_type)277 void gpio_set_gpio2risc1_irq(gpio_pin_e pin, gpio_irq_trigger_type_e trigger_type)
278 {
279 switch (trigger_type) {
280 case INTR_RISING_EDGE:
281 BM_CLR(reg_gpio_pol(pin), pin & 0xff);
282 BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1);
283 break;
284 case INTR_FALLING_EDGE:
285 BM_SET(reg_gpio_pol(pin), pin & 0xff);
286 BM_CLR(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1);
287 break;
288 case INTR_HIGH_LEVEL:
289 BM_CLR(reg_gpio_pol(pin), pin & 0xff);
290 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1);
291 break;
292 case INTR_LOW_LEVEL:
293 BM_SET(reg_gpio_pol(pin), pin & 0xff);
294 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_LVL_GPIO2RISC1);
295 break;
296 }
297 reg_gpio_irq_clr = FLD_GPIO_IRQ_GPIO2RISC1_CLR; // must clear cause to unexpected interrupt.
298 BM_SET(reg_gpio_irq_risc_mask, FLD_GPIO_IRQ_MASK_GPIO2RISC1);
299 }
300
301 /**
302 * @brief This function set a pin's pull-up/down resistor.
303 * @param[in] pin - the pin needs to set its pull-up/down resistor.
304 * @param[in] up_down_res - the type of the pull-up/down resistor.
305 * @return none.
306 */
gpio_set_up_down_res(gpio_pin_e pin,gpio_pull_type_e up_down_res)307 void gpio_set_up_down_res(gpio_pin_e pin, gpio_pull_type_e up_down_res)
308 {
309 unsigned char r_val = up_down_res & 0x03;
310
311 unsigned char base_ana_reg = 0x0e + ((pin >> 8) << 1) + ((pin & 0xf0) ? 1 : 0); // group = gpio>>8;
312 unsigned char shift_num, mask_not;
313
314 if (pin & 0x11) {
315 shift_num = 0;
316 mask_not = 0xfc;
317 } else if (pin & 0x22) {
318 shift_num = 2;
319 mask_not = 0xf3;
320 } else if (pin & 0x44) {
321 shift_num = 4;
322 mask_not = 0xcf;
323 } else if (pin & 0x88) {
324 shift_num = 6;
325 mask_not = 0x3f;
326 } else {
327 return;
328 }
329 analog_write_reg8(base_ana_reg, (analog_read_reg8(base_ana_reg) & mask_not) | (r_val << shift_num));
330 }
331
332 /**
333 * @brief This function set pin's 30k pull-up registor.
334 * @param[in] pin - the pin needs to set its pull-up registor.
335 * @return none.
336 * @attention This function sets the digital pull-up, it will not work after entering low power consumption.
337 */
gpio_set_pullup_res_30k(gpio_pin_e pin)338 void gpio_set_pullup_res_30k(gpio_pin_e pin)
339 {
340 unsigned char bit = pin & 0xff;
341 unsigned short group = pin & 0xf00;
342
343 if (group == GPIO_GROUPC) {
344 analog_write_reg8(areg_gpio_pc_pe, analog_read_reg8(areg_gpio_pc_pe) | bit);
345 } else if (group == GPIO_GROUPD) {
346 analog_write_reg8(areg_gpio_pd_pe, analog_read_reg8(areg_gpio_pd_pe) | bit);
347 } else {
348 BM_SET(reg_gpio_oen(pin), bit);
349 BM_SET(reg_gpio_out(pin), bit);
350 }
351 }
352
353 /**********************************************************************************************************************
354 * local function implementation *
355 *********************************************************************************************************************/
356