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