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