1 /*
2  * ==========================================================
3  *
4  *    Copyright (C) 2020 QuickLogic Corporation
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  * 		http://www.apache.org/licenses/LICENSE-2.0
9  *    Unless required by applicable law or agreed to in writing, software
10  *    distributed under the License is distributed on an "AS IS" BASIS,
11  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  *    See the License for the specific language governing permissions and
13  *    limitations under the License.
14  *
15  *    File      : eoss3_hal_pad_config.c
16  *    Purpose   : This file contains macros, structures and APIs to
17  *             configure pads
18  *
19  *
20  * ===========================================================
21  *
22  */
23 #include <eoss3_hal_pad_config.h>
24 #include <stdint.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 /// @cond <section name>
29 #define  OUTPUT_EN		((uint8_t)0x00)   /* Output Enable */
30 #define  INPUT_DIS		((uint8_t)0x00)   /* Input Disable */
31 #define  OUTPUT_DRV_DIS		((uint8_t)0x01)   /* Output Disable */
32 
33 #define EXT_REGS_MAX	44
34 #define EXT_REGS_PADS_VARS_MAX	8
35 #define IO_INPUT_MAX	8
36 #define IO_MUX_MAX  2
37 
38 #define DEFAULT_VAL_0   0
39 #define DEFAULT_VAL_1   1
40 #define DEFAULT_VAL_N1   -1
41 
42 /*Extended Pad config register offset starts from */
43 /*! \var int8_t  SEL_EXT_PAD_REGS
44     \brief This array contains all the possible pad selection for given register.
45     These registers are extention to PAD config registers [0 to 45]. First value
46     in an array is default value and rest indexes need to be written for given pad.
47     Offset of extended register starts from 0x100. This offset is embedded in each
48     pad function macro.
49 */
50 
51 const int8_t  SEL_EXT_PAD_REGS[EXT_REGS_MAX][EXT_REGS_PADS_VARS_MAX] = {
52       {DEFAULT_VAL_1, PAD_1}, //100
53       {DEFAULT_VAL_1, PAD_15,PAD_32,PAD_44}, //104
54       {DEFAULT_VAL_1, PAD_41}, //108
55       {DEFAULT_VAL_1, PAD_0}, //10C
56       {DEFAULT_VAL_1, PAD_14, PAD_33, PAD_45}, //110
57       {DEFAULT_VAL_1, PAD_40}, //114
58       {PAD_16, PAD_0}, //118
59       {PAD_20, PAD_0}, //11C
60       {PAD_19, PAD_0}, //120
61       {PAD_36, PAD_0}, //124
62       {DEFAULT_VAL_0, PAD_10, PAD_28}, //128
63       {DEFAULT_VAL_0, PAD_10, PAD_28}, //12C
64       {DEFAULT_VAL_N1}, //Dummy 130
65       {DEFAULT_VAL_0, PAD_14,PAD_16,PAD_25,PAD_45}, //GAP 134
66       {DEFAULT_VAL_0, PAD_6,PAD_15,PAD_21,PAD_24,PAD_28,PAD_40,PAD_44}, //138
67       {DEFAULT_VAL_0, PAD_3}, //13C
68       {DEFAULT_VAL_0, PAD_2,PAD_6,PAD_18,PAD_24,PAD_35,PAD_36}, //140
69       {DEFAULT_VAL_0, PAD_4,PAD_8,PAD_21,PAD_25,PAD_37,PAD_38}, //144
70       {DEFAULT_VAL_0, PAD_5,PAD_9,PAD_22,PAD_28,PAD_39,PAD_40}, //148
71       {DEFAULT_VAL_0, PAD_7,PAD_10,PAD_26,PAD_29,PAD_44}, //14C
72       {DEFAULT_VAL_0, PAD_11,PAD_14,PAD_27,PAD_30,PAD_45}, //150
73       {DEFAULT_VAL_0, PAD_12,PAD_15,PAD_31,PAD_32,PAD_41}, //154
74       {DEFAULT_VAL_0, PAD_13,PAD_23,PAD_33,PAD_34,PAD_42}, //158
75       {DEFAULT_VAL_1, PAD_17,PAD_22}, //15C
76       {DEFAULT_VAL_0, 0}, //160 //IO_REG_SEL, handled seperately using an arry IO_INPUT_PAD_SEL
77       {DEFAULT_VAL_N1, 0}, //Dummy 164
78       {DEFAULT_VAL_N1, 0}, //Dummy 168
79       {DEFAULT_VAL_N1, 0}, //Dummy 16C
80       {DEFAULT_VAL_1, 0}, //170 Debugger pad selection happed using bootstap pin
81       {DEFAULT_VAL_1, 0}, //174 Debugger pad selection happed using bootstap pin
82       {DEFAULT_VAL_N1, 0}, //Dummy 178
83       {DEFAULT_VAL_N1, 0}, //Dummy 17C
84       {DEFAULT_VAL_1, 0}, //180 FBIO : Special handling for each bit
85       {DEFAULT_VAL_1, PAD_32}, //184 FBIO : Special handling for each bit (we can subtract
86       {DEFAULT_VAL_0, 0}, //Dummy 188
87       {DEFAULT_VAL_0, 0}, //Dummy 18C
88       {DEFAULT_VAL_0, PAD_8,PAD_29}, //190
89       {DEFAULT_VAL_0, PAD_6,PAD_28}, //194
90       {DEFAULT_VAL_N1, 0}, //Dummy 198
91       {DEFAULT_VAL_N1, 0}, //Dummy 19C
92       {DEFAULT_VAL_0, PAD_23}, //1A0
93       {DEFAULT_VAL_0, PAD_31}, //1A4
94       {DEFAULT_VAL_0, PAD_9,PAD_30}, //0x1A8
95       {DEFAULT_VAL_0, PAD_38}, //0x1AC
96       };
97 
98 /*! \var uint8_t IO_INPUT_PAD_SEL
99     \brief This array contains pad selection for GPIO input configuration written in
100     IO_REG_SEL register.
101 */
102 const uint8_t IO_INPUT_PAD_SEL[IO_INPUT_MAX][IO_MUX_MAX] =
103       {{PAD_6,PAD_24}, {PAD_9,PAD_26}, {PAD_11,PAD_28}, {PAD_14,PAD_30},
104       {PAD_18,PAD_31},{PAD_21,PAD_36},{PAD_22,PAD_38},{PAD_23,PAD_45}};
105 
106 /// @endcond
107 
HAL_PAD_Config(PadConfig * pxPadInit)108 void HAL_PAD_Config(PadConfig *pxPadInit)
109 {
110 	PadConfigReg xPadRegVal;
111 	uint32_t *pExtRegAddr;
112 	uint32_t uiExtRegAddr;
113 	uint8_t ucCount, ucIdx;
114 	int8_t ucIsValid=false;
115 
116 	memset(&xPadRegVal, 0, sizeof(uint32_t));
117 
118 	xPadRegVal.bCtrl = pxPadInit->ucCtrl;
119 
120 	xPadRegVal.bFunc = pxPadInit->ucFunc & 0x03; /*Since we have been using only two bits to define function.*/
121 
122 	xPadRegVal.bOPull = pxPadInit->ucPull;
123 	xPadRegVal.bODrv = pxPadInit->ucDrv;
124 	xPadRegVal.bSpeed = pxPadInit->ucSpeed;
125 	xPadRegVal.bSmtTrg = pxPadInit->ucSmtTrg;
126 
127 	ucIsValid = false;
128     /* In case of output mode selection */
129     if((pxPadInit->ucMode == PAD_MODE_OUTPUT_EN))
130     {
131     	ucIsValid = true;
132     	xPadRegVal.bOEn = OUTPUT_EN;
133 	xPadRegVal.bIEn = INPUT_DIS;
134     }
135     else if((pxPadInit->ucMode == PAD_MODE_INPUT_EN))
136     {
137     	ucIsValid = true;
138     	xPadRegVal.bOEn = OUTPUT_DRV_DIS;
139 	xPadRegVal.bIEn = pxPadInit->ucMode;
140     }
141 
142     if(ucIsValid)
143     {
144     	pExtRegAddr = (uint32_t *)IO_MUX;
145     	pExtRegAddr += pxPadInit->ucPin;
146 
147 	memcpy(pExtRegAddr, &xPadRegVal, sizeof(uint32_t));
148     }
149 
150     /*Check if it needs any additional register need to be configured or Pad selection to be performed*/
151     if( (uiExtRegAddr = (pxPadInit->ucFunc >> EXT_REG_OFFSET_SHIFT)) )
152     {
153     	/*Check if special handling needed.*/
154     	if((uiExtRegAddr == FBIO_SEL_1) ||  (uiExtRegAddr == FBIO_SEL_2))
155     	{
156     		if(uiExtRegAddr == FBIO_SEL_2)
157     		{
158     			uiExtRegAddr = uiExtRegAddr | IO_MUX_BASE;
159     			pExtRegAddr = (uint32_t *)uiExtRegAddr;
160     			*pExtRegAddr |= 1 << (pxPadInit->ucPin - 32);
161     		}
162     		else
163     		{
164     			uiExtRegAddr |= IO_MUX_BASE;
165     			pExtRegAddr = (uint32_t *)uiExtRegAddr;
166     			*pExtRegAddr |= 1 << pxPadInit->ucPin;
167     		}
168     	}
169     	else if(uiExtRegAddr == IO_REG_SEL) /*GPIO Input Configuration*/
170     	{
171     		ucIsValid = false;
172     		/*GPIO Input configuration*/
173     		if((pxPadInit->ucMode == PAD_MODE_INPUT_EN))
174     		{
175     			for(ucIdx=0; ucIdx<IO_INPUT_MAX; ucIdx++)
176     			{
177     				for(ucCount=0;ucCount<IO_MUX_MAX;ucCount++)
178     				{
179     					if(IO_INPUT_PAD_SEL[ucIdx][ucCount] == pxPadInit->ucPin)
180     					{
181     						/*Found requested pad in Input array*/
182     						ucIsValid = true;
183     						uiExtRegAddr |= IO_MUX_BASE;
184     						pExtRegAddr = (uint32_t *)uiExtRegAddr;
185     						*pExtRegAddr |= ucCount << ucIdx;
186     						break;
187     					}
188     				}
189     			}
190     		}
191     	}
192     	else
193     	{
194     		ucIsValid = false;
195 
196 			/*Check if it is not pointing to dummy address*/
197 			if(SEL_EXT_PAD_REGS[(uiExtRegAddr - EXT_REG_OFFSET_BASE)/4][0] ==  -1)
198 			{
199 				ucIsValid = false;
200 			}
201 			else
202 			{
203                 /*Start searching pad from index 1 as 0th is default value*/
204 				for(ucCount = 1; ucCount < EXT_REGS_PADS_VARS_MAX; ucCount++)
205 				{
206 					/*Compare pin number in the extended register array finding index in that two dimensional array*/
207 					if(SEL_EXT_PAD_REGS[(uiExtRegAddr - EXT_REG_OFFSET_BASE)/4][ucCount] ==  pxPadInit->ucPin)
208 					{
209 						uiExtRegAddr |= IO_MUX_BASE;
210 						pExtRegAddr = (uint32_t *)uiExtRegAddr;
211 						*pExtRegAddr = ucCount;
212 						break;
213 					}
214 				}
215 			}
216     	}
217     }
218 }
219 
HAL_PAD_DeConfig(PadConfig * pxPadInit)220 void HAL_PAD_DeConfig(PadConfig *pxPadInit)
221 {
222 	//Write Padconfig register to default values
223 	//Write Ext pad config register to def value.
224 }
225