]> rtime.felk.cvut.cz Git - arc.git/blob - arch/arm/arm_cr4/drivers/Port.c
67446fbeac69a6a4a79b7409128a6c624fcc34f4
[arc.git] / arch / arm / arm_cr4 / drivers / Port.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 #include "Std_Types.h"\r
18 #include "Port.h"\r
19 #include "Det.h"\r
20 #include "Cpu.h"\r
21 #include <string.h>\r
22 \r
23 #define GET_PIN_PORT(_pin) (_pin >> 8)\r
24 #define GET_PIN_PIN(_pin)  (_pin & 0x1F)\r
25 #define GET_PIN_MASK(_pin) (1 << (_pin & 0x1F))\r
26 \r
27 typedef enum\r
28 {\r
29     PORT_UNINITIALIZED = 0, PORT_INITIALIZED,\r
30 } Port_StateType;\r
31 \r
32 \r
33 typedef volatile struct\r
34 {\r
35     uint32 FUN;\r
36     uint32 DIR;\r
37     uint32 DIN;\r
38     uint32 DOUT;\r
39     uint32 DSET;\r
40     uint32 DCLR;\r
41     uint32 PDR;\r
42     uint32 PULDIS;\r
43     uint32 PSL;\r
44 } Port_RegisterType;\r
45 \r
46 \r
47 #define PORT_NOT_CONFIGURED 0x00000000\r
48 \r
49 #define PORT_0_BASE ((Port_RegisterType *)0xFFF7BC30)\r
50 #define PORT_1_BASE ((Port_RegisterType *)0xFFF7BC50)\r
51 #define PORT_2_BASE ((Port_RegisterType *)0xFFF7B848)                   // N2HET1 Base\r
52 #define PORT_3_BASE ((Port_RegisterType *)PORT_NOT_CONFIGURED)\r
53 #define PORT_4_BASE ((Port_RegisterType *)PORT_NOT_CONFIGURED)\r
54 #define PORT_5_BASE ((Port_RegisterType *)PORT_NOT_CONFIGURED)\r
55 #define PORT_6_BASE ((Port_RegisterType *)PORT_NOT_CONFIGURED)\r
56 #define PORT_7_BASE ((Port_RegisterType *)PORT_NOT_CONFIGURED)\r
57 #define PORT_8_BASE ((Port_RegisterType *)0xFFF7DDE0)                   // DCAN1 TX IO Control Register\r
58 #define PORT_9_BASE ((Port_RegisterType *)0xFFF7DFE0)                   // DCAN2 TX IO Control Register\r
59 #define PORT_10_BASE ((Port_RegisterType *)0xFFF7E1E0)                  // DCAN3 TX IO Control Register\r
60 #define PORT_NUMBER_OF_PORTS 11\r
61 \r
62 static Port_RegisterType * const Port_Base[] =\r
63 {\r
64     PORT_0_BASE,\r
65     PORT_1_BASE,\r
66     PORT_2_BASE,\r
67     PORT_3_BASE,\r
68     PORT_4_BASE,\r
69     PORT_5_BASE,\r
70     PORT_6_BASE,\r
71     PORT_7_BASE,\r
72     PORT_8_BASE,\r
73     PORT_9_BASE,\r
74     PORT_10_BASE,\r
75 };\r
76 \r
77 typedef volatile uint32 PinMuxBase;\r
78 \r
79 #define PINMUX0  ((PinMuxBase *)0xFFFFEB10)\r
80 #define PINMUX1  ((PinMuxBase *)0xFFFFEB14)\r
81 #define PINMUX2  ((PinMuxBase *)0xFFFFEB18)\r
82 #define PINMUX3  ((PinMuxBase *)0xFFFFEB1C)\r
83 #define PINMUX4  ((PinMuxBase *)0xFFFFEB20)\r
84 #define PINMUX5  ((PinMuxBase *)0xFFFFEB24)\r
85 #define PINMUX6  ((PinMuxBase *)0xFFFFEB28)\r
86 #define PINMUX7  ((PinMuxBase *)0xFFFFEB2C)\r
87 #define PINMUX8  ((PinMuxBase *)0xFFFFEB30)\r
88 #define PINMUX9  ((PinMuxBase *)0xFFFFEB34)\r
89 #define PINMUX10 ((PinMuxBase *)0xFFFFEB38)\r
90 #define PINMUX11 ((PinMuxBase *)0xFFFFEB3C)\r
91 #define PINMUX12 ((PinMuxBase *)0xFFFFEB40)\r
92 #define PINMUX13 ((PinMuxBase *)0xFFFFEB44)\r
93 #define PINMUX14 ((PinMuxBase *)0xFFFFEB48)\r
94 #define PINMUX15 ((PinMuxBase *)0xFFFFEB4C)\r
95 #define PINMUX16 ((PinMuxBase *)0xFFFFEB50)\r
96 #define PINMUX17 ((PinMuxBase *)0xFFFFEB54)\r
97 #define PINMUX18 ((PinMuxBase *)0xFFFFEB58)\r
98 #define PINMUX19 ((PinMuxBase *)0xFFFFEB5C)\r
99 #define PINMUX20 ((PinMuxBase *)0xFFFFEB60)\r
100 #define PINMUX21 ((PinMuxBase *)0xFFFFEB64)\r
101 #define PINMUX22 ((PinMuxBase *)0xFFFFEB68)\r
102 #define PINMUX23 ((PinMuxBase *)0xFFFFEB6C)\r
103 #define PINMUX24 ((PinMuxBase *)0xFFFFEB70)\r
104 #define PINMUX25 ((PinMuxBase *)0xFFFFEB74)\r
105 #define PINMUX26 ((PinMuxBase *)0xFFFFEB78)\r
106 #define PINMUX27 ((PinMuxBase *)0xFFFFEB7C)\r
107 #define PINMUX28 ((PinMuxBase *)0xFFFFEB80)\r
108 #define PINMUX29 ((PinMuxBase *)0xFFFFEB84)\r
109 #define PINMUX30 ((PinMuxBase *)0xFFFFEB88)\r
110 \r
111 static PinMuxBase * PinMux_Base[] =\r
112 {\r
113         PINMUX0,\r
114         PINMUX1,\r
115         PINMUX2,\r
116         PINMUX3,\r
117         PINMUX4,\r
118         PINMUX5,\r
119         PINMUX6,\r
120         PINMUX7,\r
121         PINMUX8,\r
122         PINMUX9,\r
123         PINMUX10,\r
124         PINMUX11,\r
125         PINMUX12,\r
126         PINMUX13,\r
127         PINMUX14,\r
128         PINMUX15,\r
129         PINMUX16,\r
130         PINMUX17,\r
131         PINMUX18,\r
132         PINMUX19,\r
133         PINMUX20,\r
134         PINMUX21,\r
135         PINMUX22,\r
136         PINMUX23,\r
137         PINMUX24,\r
138         PINMUX25,\r
139         PINMUX26,\r
140         PINMUX27,\r
141         PINMUX28,\r
142         PINMUX29,\r
143         PINMUX30\r
144 };\r
145 \r
146 static Port_StateType _portState = PORT_UNINITIALIZED;\r
147 static const Port_ConfigType * _configPtr = &PortConfigData;\r
148 \r
149 #if PORT_DEV_ERROR_DETECT == STD_ON\r
150 #define VALIDATE_PARAM_CONFIG(_ptr,_api) \\r
151         if( (_ptr)==((void *)0) ) { \\r
152                 Det_ReportError(MODULE_ID_PORT, 0, _api, PORT_E_PARAM_CONFIG ); \\r
153                 return; \\r
154         }\r
155 \r
156 #define VALIDATE_STATE_INIT(_api)\\r
157         if(PORT_INITIALIZED!=_portState){\\r
158                 Det_ReportError(MODULE_ID_PORT, 0, _api, PORT_E_UNINIT ); \\r
159                 return; \\r
160         }\r
161 \r
162 #define VALIDATE_PARAM_PIN(_pin, _api)\\r
163         if(GET_PIN_PORT(_pin) >= PORT_NUMBER_OF_PORTS || Port_Base[GET_PIN_PORT(_pin)] == PORT_NOT_CONFIGURED || GET_PIN_PIN(_pin) > 7 ){\\r
164                 Det_ReportError(MODULE_ID_PORT, 0, _api, PORT_E_PARAM_PIN ); \\r
165                 return; \\r
166         }\r
167 \r
168 #else\r
169 #define VALIDATE_PARAM_CONFIG(_ptr,_api)\r
170 #define VALIDATE_STATE_INIT(_api)\r
171 #define VALIDATE_PARAM_PIN(_pin, _api)\r
172 #endif\r
173 \r
174 #if PORT_VERSION_INFO_API == STD_ON\r
175 static Std_VersionInfoType _Port_VersionInfo =\r
176 {\r
177   .vendorID   = (uint16)1,\r
178   .moduleID   = (uint16) MODULE_ID_PORT,\r
179   .instanceID = (uint8)1,\r
180   .sw_major_version = (uint8)PORT_SW_MAJOR_VERSION,\r
181   .sw_minor_version = (uint8)PORT_SW_MINOR_VERSION,\r
182   .sw_patch_version = (uint8)PORT_SW_PATCH_VERSION,\r
183   .ar_major_version = (uint8)PORT_AR_MAJOR_VERSION,\r
184   .ar_minor_version = (uint8)PORT_AR_MINOR_VERSION,\r
185   .ar_patch_version = (uint8)PORT_AR_PATCH_VERSION,\r
186 };\r
187 #endif\r
188 \r
189 void Port_RefreshPin(uint16 pinNumber) {\r
190         uint8 port = GET_PIN_PORT(_configPtr->pins[pinNumber].pin);\r
191         uint32 mask = GET_PIN_MASK(_configPtr->pins[pinNumber].pin);\r
192         uint16 conf = _configPtr->pins[pinNumber].conf;\r
193 \r
194         uint32 pinmux = _configPtr->pins[pinNumber].pinmux;\r
195         uint8 pinmuxFunctionNum = _configPtr->pins[pinNumber].pinmuxFunctionNum;\r
196         uint8 pinmuxBaseNum = _configPtr->pins[pinNumber].pinmuxBaseNum;\r
197 \r
198         /* Enable Pin Muxing */\r
199                 kickerReg->KICKER0 = 0x83E70B13;\r
200                 kickerReg->KICKER1 = 0x95A4F1E0;\r
201 \r
202         /* ex.: Hack to connect N2HET1[27] (function 2) to pin A9 */\r
203         *PinMux_Base[pinmuxBaseNum] &= (~(0xFF << pinmux));//\r
204         *PinMux_Base[pinmuxBaseNum] |= (~(pinmuxFunctionNum << pinmux));\r
205 \r
206         /* Disable Pin Muxing */\r
207                 kickerReg->KICKER0 = 0x00000000;\r
208                 kickerReg->KICKER1 = 0x00000000;\r
209 \r
210         if (conf & PORT_FUNC) {\r
211                 // Don't do anything, let each driver configure???\r
212                 return;\r
213         }\r
214 \r
215         // Set pin direction\r
216         if (conf & PORT_PIN_OUT) {\r
217                 Port_Base[port]->DIR |= mask;\r
218 \r
219                 // Set open drain\r
220                 if (conf & PORT_ODE_ENABLE) {\r
221                         Port_Base[port]->PDR |= mask;\r
222                 } else {\r
223                         Port_Base[port]->PDR &= ~mask;\r
224                 }\r
225 \r
226         } else {\r
227                 Port_Base[port]->DIR &= ~mask;\r
228         }\r
229 \r
230         // Set pull up or down or nothing.\r
231         if (conf & PORT_PULL_NONE) {\r
232                 Port_Base[port]->PULDIS |= mask;\r
233 \r
234         } else {\r
235                 Port_Base[port]->PULDIS &= ~mask;\r
236                 if (conf & PORT_PULL_UP) {\r
237                         Port_Base[port]->PSL |= mask;\r
238 \r
239                 } else {\r
240                         Port_Base[port]->PSL &= ~mask;\r
241                 }\r
242         }\r
243 }\r
244 \r
245 \r
246 void Port_Init(const Port_ConfigType *configType) {\r
247         VALIDATE_PARAM_CONFIG(configType, PORT_INIT_ID);\r
248 \r
249         _configPtr = (Port_ConfigType *)configType;\r
250 \r
251         /* Bring GIO register out of reset. */\r
252         gioREG->GCR0 = 1;\r
253     gioREG->INTENACLR = 0xFF;  // Interrupt Enable Clear Register\r
254     gioREG->LVLCLR    = 0xFF;  // Interrupt Priority Clear Register\r
255 \r
256         for (uint16 i = 0; i < PORT_NUMBER_OF_PINS; i++) {\r
257                 Port_RefreshPin(i);\r
258         }\r
259 \r
260         _portState = PORT_INITIALIZED;\r
261 \r
262         return;\r
263 }\r
264 \r
265 #if ( PORT_SET_PIN_DIRECTION_API == STD_ON )\r
266 void Port_SetPinDirection( Port_PinType pin, Port_PinDirectionType direction )\r
267 {\r
268         VALIDATE_STATE_INIT(PORT_SET_PIN_DIRECTION_ID);\r
269         VALIDATE_PARAM_PIN(pin, PORT_SET_PIN_DIRECTION_ID);\r
270 \r
271         uint8 port = GET_PIN_PORT(pin);         // ex.: LED1 - 0x021b >> 8 = 2 (uint8)\r
272         uint32 mask = GET_PIN_MASK(pin);        // ex.: LED1 - 1 << (0x1b) = 0x08000000 (uint32)\r
273 \r
274         if (direction & PORT_PIN_IN) {\r
275                 Port_Base[port]->DIR |= mask;\r
276 \r
277         } else {\r
278                 Port_Base[port]->DIR &= ~mask;\r
279 \r
280         }\r
281 \r
282         return;\r
283 }\r
284 #endif\r
285 \r
286 void Port_RefreshPortDirection( void )\r
287 {\r
288         VALIDATE_STATE_INIT(PORT_REFRESH_PORT_DIRECTION_ID);\r
289         for (uint16 i = 0; i < PORT_NUMBER_OF_PINS; i++) {\r
290                 if (!(_configPtr->pins[i].conf & PORT_DIRECTION_CHANGEABLE)) {\r
291                         Port_RefreshPin(i);\r
292                 }\r
293         }\r
294         return;\r
295 }\r
296 \r
297 \r
298 #if PORT_VERSION_INFO_API == STD_ON\r
299 void Port_GetVersionInfo(Std_VersionInfoType* versionInfo)\r
300 {\r
301   VALIDATE_STATE_INIT(PORT_GET_VERSION_INFO_ID);\r
302   memcpy(versionInfo, &_Port_VersionInfo, sizeof(Std_VersionInfoType));\r
303   return;\r
304 }\r
305 #endif\r
306 \r
307 #if (PORT_SET_PIN_MODE_API == STD_ON)\r
308 void Port_SetPinMode(Port_PinType Pin, Port_PinModeType Mode) {\r
309         VALIDATE_STATE_INIT(PORT_SET_PIN_MODE_ID);\r
310         VALIDATE_PARAM_PIN(Pin, PORT_SET_PIN_MODE_ID);\r
311 \r
312         #if (PORT_DEV_ERROR_DETECT == STD_ON)\r
313                 Det_ReportError(MODULE_ID_PORT, 0, PORT_SET_PIN_MODE_ID, PORT_E_MODE_UNCHANGEABLE );\r
314         #endif\r
315 \r
316         uint8 port = GET_PIN_PORT(Pin);\r
317         uint8 pin = GET_PIN_PIN(Pin);\r
318         uint32 mask = GET_PIN_MASK(Pin);\r
319 \r
320     Port_Base[port]->FUN &= ~mask;\r
321     Port_Base[port]->FUN |= ((Mode & 1) << pin);\r
322     return;\r
323 }\r
324 #endif\r