• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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