1 /*
2  * Copyright 2021 QuickLogic
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
18 
19  #include "core-v-mcu-config.h"
20  #include "efpga_template_reg_defs.h"
21  #include "hal_apb_gpio_reg_defs.h"
22  #include "hal_gpio.h"
23 
hal_efpgaio_output(uint8_t efpgaio_num,efpgaio_enum_typedef value)24 void hal_efpgaio_output(uint8_t efpgaio_num, efpgaio_enum_typedef value) {
25 
26 Efpga_t *efpga = (Efpga_t*)EFPGAIO_START_ADDR;
27 
28 switch(value) {
29 	case CLEAR:
30 		if (efpgaio_num < 32)
31 			efpga->fpgaio_out31_00 &= ~(1 << efpgaio_num) ;
32 		else if (efpgaio_num < 64)
33 			efpga->fpgaio_out63_32 &= ~(1 << (efpgaio_num-32)) ;
34 		else if (efpgaio_num < 80)
35 			efpga->fpgaio_out79_64 &= ~(1 << (efpgaio_num-64)) ;
36 		break;
37 	case SET:
38 		if (efpgaio_num < 32)
39 			efpga->fpgaio_out31_00 |= (1 << efpgaio_num) ;
40 		else if (efpgaio_num < 64)
41 			efpga->fpgaio_out63_32 |= (1 << (efpgaio_num-32)) ;
42 		else if (efpgaio_num < 80)
43 			efpga->fpgaio_out79_64 |= (1 << (efpgaio_num-64)) ;
44 		break;
45 	case TOGGLE:
46 		if (efpgaio_num < 32)
47 			efpga->fpgaio_out31_00 ^= (1 << efpgaio_num) ;
48 		else if (efpgaio_num < 64)
49 			efpga->fpgaio_out63_32 ^= (1 << (efpgaio_num-32)) ;
50 		else if (efpgaio_num < 80)
51 			efpga->fpgaio_out79_64 ^= (1 << (efpgaio_num-64)) ;
52 		break;
53 
54 	default:
55 		break;
56  }
57 }
58 
hal_efpgaio_outen(uint8_t efpgaio_num,efpgaio_enum_typedef value)59 void hal_efpgaio_outen(uint8_t efpgaio_num, efpgaio_enum_typedef value) {
60 
61 	Efpga_t *efpga = (Efpga_t*)EFPGAIO_START_ADDR;
62 
63 	switch(value) {
64 		case CLEAR:
65 			if (efpgaio_num < 32)
66 				efpga->fpgaio_oe31_00 &= ~(1 << efpgaio_num) ;
67 			else if (efpgaio_num < 64)
68 				efpga->fpgaio_oe63_32 &= ~(1 << (efpgaio_num-32)) ;
69 			else if (efpgaio_num < 80)
70 				efpga->fpgaio_oe79_64 &= ~(1 << (efpgaio_num-64)) ;
71 			break;
72 		case SET:
73 			if (efpgaio_num < 32)
74 				efpga->fpgaio_oe31_00 |= (1 << efpgaio_num) ;
75 			else if (efpgaio_num < 64)
76 				efpga->fpgaio_oe63_32 |= (1 << (efpgaio_num-32)) ;
77 			else if (efpgaio_num < 80)
78 				efpga->fpgaio_oe79_64 |= (1 << (efpgaio_num-64)) ;
79 			break;
80 		default:
81 			break;
82  }
83 }
84 
hal_efpgaio_input(uint8_t efpgaio_num)85 int hal_efpgaio_input(uint8_t efpgaio_num) {
86  int retval=-1;
87 	Efpga_t *efpga = (Efpga_t*)EFPGAIO_START_ADDR;
88 	if (efpgaio_num < 32)
89 		retval = (efpga->fpgaio_in31_00 >> efpgaio_num) & 0x1 ;
90 	else if (efpgaio_num < 64)
91 		retval = (efpga->fpgaio_in63_32 >> (efpgaio_num-32)) & 0x1 ;
92 	else if (efpgaio_num < 80)
93 		retval = (efpga->fpgaio_in79_64 >> (efpgaio_num-64)) & 0x1 ;
94 }
95 
hal_efpgaio_event(uint8_t event_num)96 void hal_efpgaio_event(uint8_t event_num) {
97 
98 	Efpga_t *efpga = (Efpga_t*)EFPGAIO_START_ADDR;
99 	efpga->fpga_event15_00 |= (1 << event_num);
100 	efpga->fpga_event15_00 &= ~(1 << event_num);
101 
102 }
103 
hal_efpgaio_status(gpio_hal_typedef * hgpio)104 void hal_efpgaio_status(gpio_hal_typedef *hgpio){
105 	Efpga_t *efpga = (Efpga_t*)EFPGAIO_START_ADDR;
106 	if (hgpio->number < 32) {
107 		hgpio->out_val  = (efpga->fpgaio_out31_00 >> hgpio->number) & 0x1;
108 		hgpio->in_val   = (efpga->fpgaio_in31_00  >> hgpio->number) & 0x1;
109 		hgpio->mode = (efpga->fpgaio_oe31_00  >> hgpio->number) & 0x1;
110 	} else if (hgpio->number < 64) {
111 		hgpio->out_val  = (efpga->fpgaio_out63_32 >> (hgpio->number - 32)) & 0x1;
112 		hgpio->in_val   = (efpga->fpgaio_in63_32  >> (hgpio->number - 32)) & 0x1;
113 		hgpio->mode = (efpga->fpgaio_oe63_32  >> (hgpio->number - 32)) & 0x1;
114 	} else if (hgpio->number < 64) {
115 		hgpio->out_val  = (efpga->fpgaio_out79_64 >> (hgpio->number - 64)) & 0x1;
116 		hgpio->in_val   = (efpga->fpgaio_in79_64  >> (hgpio->number - 64)) & 0x1;
117 		hgpio->mode = (efpga->fpgaio_oe79_64  >> (hgpio->number - 64)) & 0x1;
118 	}
119 }
120 
121 
hal_write_gpio(uint8_t gpio_num,uint8_t value)122 void hal_write_gpio(uint8_t gpio_num, uint8_t value) {
123 	if (value) {
124 		hal_set_gpio(gpio_num);
125 	} else {
126 		hal_clr_gpio(gpio_num);
127 	}
128 }
129 
hal_set_gpio(uint8_t gpio_num)130 void hal_set_gpio(uint8_t gpio_num) {
131 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
132 
133 	papbgpio->setgpio_b.gpio_num = gpio_num;
134 }
135 
hal_clr_gpio(uint8_t gpio_num)136 void hal_clr_gpio(uint8_t gpio_num) {
137 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
138 
139 	papbgpio->clrgpio_b.gpio_num = gpio_num;
140 }
141 
hal_toggle_gpio(uint8_t gpio_num)142 void hal_toggle_gpio(uint8_t gpio_num) {
143 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
144 
145 	papbgpio->toggpio_b.gpio_num = gpio_num;
146 }
147 
hal_set_gpio_num(uint8_t gpio_num)148 void hal_set_gpio_num(uint8_t gpio_num){
149 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
150 	unsigned int value = 0xff;
151 
152 	while ((value & 0xff) != gpio_num) {
153 		papbgpio->setsel= gpio_num;		// Set address for following reads
154 		value = papbgpio->rdstat;
155 	}
156 }
157 
hal_read_gpio_status(gpio_hal_typedef * hgpio)158 void hal_read_gpio_status(gpio_hal_typedef *hgpio){
159 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
160 	unsigned int value = 0xff;
161 
162 	while ((value & 0xff) != hgpio->number) {
163 		papbgpio->setsel_b.gpio_num = hgpio->number;		// Set address for following reads
164 		value = papbgpio->rdstat;
165 	}
166 	hgpio->mode = (uint8_t)((value >> 24) & 0x3); //papbgpio->rdstat_b.mode;
167 	hgpio->int_type = (uint8_t)((value >> 17) & 0x7); //papbgpio->rdstat_b.inttype;
168 	hgpio->int_en = (uint8_t)((value >> 16) & 0x1); //papbgpio->rdstat_b.inten;
169 	hgpio->in_val = (uint8_t)((value >> 12) & 0x1); //papbgpio->rdstat_b.input;
170 	hgpio->out_val = (uint8_t)((value >> 8) & 0x1); //papbgpio->rdstat_b.output;
171 	hgpio->number = (uint8_t)((value >> 0) & 0xFF); //papbgpio->rdstat_b.number;
172 
173 }
174 
hal_read_gpio_status_raw(uint8_t gpio_num,uint32_t * register_value)175 void hal_read_gpio_status_raw(uint8_t gpio_num, uint32_t* register_value){
176 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
177 	unsigned int value = 0xff;
178 
179 	while ((value & 0xff) != gpio_num) {
180 		papbgpio->setsel_b.gpio_num = gpio_num;		// Set address for following reads
181 		value = papbgpio->rdstat;
182 	}
183 
184 	*register_value = value;
185 }
186 
hal_gpio_int_ack(uint8_t gpio_num)187 void hal_gpio_int_ack (uint8_t gpio_num) {
188 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
189 	papbgpio->intack = gpio_num;
190 }
191 
hal_set_gpio_mode(uint8_t gpio_num,uint8_t gpio_mode)192 void hal_set_gpio_mode(uint8_t gpio_num, uint8_t gpio_mode){
193 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
194 	unsigned int value = gpio_num;
195 	value = (value & 0xfcffffff) | (gpio_mode << 24);
196 	//papbgpio->setmode_b.gpio_num = gpio_num;  //ToDo: is there a race here -- do we need to write both at same time?
197 	//papbgpio->setmode_b.mode = gpio_mode;
198 	papbgpio->setmode = value;
199 }
200 
hal_set_gpio_interrupt(uint8_t gpio_num,uint8_t interrupt_type,uint8_t interrupt_enable)201 void hal_set_gpio_interrupt(uint8_t gpio_num, uint8_t interrupt_type, uint8_t interrupt_enable){
202 	unsigned int regval;
203 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
204 	regval = papbgpio->setint;
205 	regval = regval & 0xFFF0FF00;
206 
207 	regval = regval | (((interrupt_type & REG_SETINT_INTTYPE_MASK) << REG_SETINT_INTTYPE_LSB ) |
208 			 ((interrupt_enable & REG_SETINT_INTENABLE_MASK) << REG_SETINT_INTENABLE_LSB) |
209 			 ((gpio_num & REG_SETINT_gpio_num_MASK ) << REG_SETINT_gpio_num_LSB));
210 
211 	papbgpio->setint = regval;
212 }
213 
hal_enable_gpio_interrupt(uint8_t gpio_num)214 void hal_enable_gpio_interrupt(uint8_t gpio_num){
215 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
216 	unsigned int regval = papbgpio->setint;
217 	regval = regval & (~(REG_SETINT_gpio_num_MASK << REG_SETINT_gpio_num_LSB));
218 	regval = regval & (~(REG_SETINT_INTENABLE_MASK << REG_SETINT_INTENABLE_LSB));
219 	regval = regval | (((0x1 & REG_SETINT_INTENABLE_MASK) << REG_SETINT_INTENABLE_LSB) |
220 			 ((gpio_num & REG_SETINT_gpio_num_MASK ) << REG_SETINT_gpio_num_LSB));
221 
222 	papbgpio->setint = regval;
223 }
224 
hal_disable_gpio_interrupt(uint8_t gpio_num)225 void hal_disable_gpio_interrupt(uint8_t gpio_num) {
226 
227 	ApbGpio_t*	papbgpio = (ApbGpio_t*)GPIO_START_ADDR;
228 	unsigned int regval = papbgpio->setint;
229 	regval = regval & (~(REG_SETINT_gpio_num_MASK << REG_SETINT_gpio_num_LSB));
230 	regval = regval & (~(REG_SETINT_INTENABLE_MASK << REG_SETINT_INTENABLE_LSB));
231 	regval = regval | ((gpio_num & REG_SETINT_gpio_num_MASK ) << REG_SETINT_gpio_num_LSB);
232 
233 	papbgpio->setint = regval;
234 }
235