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