]> rtime.felk.cvut.cz Git - arc.git/blob - arch/arm/arm_cr4/drivers/Port.c
Merged in from default
[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 *)PORT_NOT_CONFIGURED)\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)\r
58 #define PORT_9_BASE ((Port_RegisterType *)0xFFF7DFE0)\r
59 #define PORT_10_BASE ((Port_RegisterType *)0xFFF7E1E0)\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 \r
78 \r
79 static Port_StateType _portState = PORT_UNINITIALIZED;\r
80 static const Port_ConfigType * _configPtr = &PortConfigData;\r
81 \r
82 #if PORT_DEV_ERROR_DETECT == STD_ON\r
83 #define VALIDATE_PARAM_CONFIG(_ptr,_api) \\r
84         if( (_ptr)==((void *)0) ) { \\r
85                 Det_ReportError(MODULE_ID_PORT, 0, _api, PORT_E_PARAM_CONFIG ); \\r
86                 return; \\r
87         }\r
88 \r
89 #define VALIDATE_STATE_INIT(_api)\\r
90         if(PORT_INITIALIZED!=_portState){\\r
91                 Det_ReportError(MODULE_ID_PORT, 0, _api, PORT_E_UNINIT ); \\r
92                 return; \\r
93         }\r
94 \r
95 #define VALIDATE_PARAM_PIN(_pin, _api)\\r
96         if(GET_PIN_PORT(_pin) >= PORT_NUMBER_OF_PORTS || Port_Base[GET_PIN_PORT(_pin)] == PORT_NOT_CONFIGURED || GET_PIN_PIN(_pin) > 7 ){\\r
97                 Det_ReportError(MODULE_ID_PORT, 0, _api, PORT_E_PARAM_PIN ); \\r
98                 return; \\r
99         }\r
100 \r
101 #else\r
102 #define VALIDATE_PARAM_CONFIG(_ptr,_api)\r
103 #define VALIDATE_STATE_INIT(_api)\r
104 #define VALIDATE_PARAM_PIN(_pin, _api)\r
105 #endif\r
106 \r
107 #if PORT_VERSION_INFO_API == STD_ON\r
108 static Std_VersionInfoType _Port_VersionInfo =\r
109 {\r
110   .vendorID   = (uint16)1,\r
111   .moduleID   = (uint16) MODULE_ID_PORT,\r
112   .instanceID = (uint8)1,\r
113   .sw_major_version = (uint8)PORT_SW_MAJOR_VERSION,\r
114   .sw_minor_version = (uint8)PORT_SW_MINOR_VERSION,\r
115   .sw_patch_version = (uint8)PORT_SW_PATCH_VERSION,\r
116   .ar_major_version = (uint8)PORT_AR_MAJOR_VERSION,\r
117   .ar_minor_version = (uint8)PORT_AR_MINOR_VERSION,\r
118   .ar_patch_version = (uint8)PORT_AR_PATCH_VERSION,\r
119 };\r
120 #endif\r
121 \r
122 void Port_RefreshPin(uint16 pinNumber) {\r
123         uint8 port = GET_PIN_PORT(_configPtr->pins[pinNumber].pin);\r
124         uint32 mask = GET_PIN_MASK(_configPtr->pins[pinNumber].pin);\r
125         uint16 conf = _configPtr->pins[pinNumber].conf;\r
126 \r
127         if (conf & PORT_FUNC) {\r
128                 // Don't do anything, let each driver configure???\r
129                 return;\r
130         }\r
131 \r
132         // Set pin direction\r
133         if (conf & PORT_PIN_OUT) {\r
134                 Port_Base[port]->DIR |= mask;\r
135 \r
136                 // Set open drain\r
137                 if (conf & PORT_ODE_ENABLE) {\r
138                         Port_Base[port]->PDR |= mask;\r
139                 } else {\r
140                         Port_Base[port]->PDR &= ~mask;\r
141                 }\r
142 \r
143         } else {\r
144                 Port_Base[port]->DIR &= ~mask;\r
145         }\r
146 \r
147         // Set pull up or down or nothing.\r
148         if (conf & PORT_PULL_NONE) {\r
149                 Port_Base[port]->PULDIS |= mask;\r
150 \r
151         } else {\r
152                 Port_Base[port]->PULDIS &= ~mask;\r
153                 if (conf & PORT_PULL_UP) {\r
154                         Port_Base[port]->PSL |= mask;\r
155 \r
156                 } else {\r
157                         Port_Base[port]->PSL &= ~mask;\r
158                 }\r
159         }\r
160 }\r
161 \r
162 \r
163 \r
164 void Port_Init(const Port_ConfigType *configType) {\r
165         VALIDATE_PARAM_CONFIG(configType, PORT_INIT_ID);\r
166 \r
167         _configPtr = (Port_ConfigType *)configType;\r
168 \r
169         // Bring GIO register out of reset.\r
170         gioREG->GCR0 = 1;\r
171 \r
172         for (uint16 i = 0; i < PORT_NUMBER_OF_PINS; i++) {\r
173                 Port_RefreshPin(i);\r
174         }\r
175 \r
176         _portState = PORT_INITIALIZED;\r
177 \r
178         return;\r
179 }\r
180 \r
181 #if ( PORT_SET_PIN_DIRECTION_API == STD_ON )\r
182 void Port_SetPinDirection( Port_PinType pin, Port_PinDirectionType direction )\r
183 {\r
184         VALIDATE_STATE_INIT(PORT_SET_PIN_DIRECTION_ID);\r
185         VALIDATE_PARAM_PIN(pin, PORT_SET_PIN_DIRECTION_ID);\r
186 \r
187         uint8 port = GET_PIN_PORT(pin);\r
188         uint32 mask = GET_PIN_MASK(pin);\r
189 \r
190         if (direction & PORT_PIN_IN) {\r
191                 Port_Base[port]->DIR |= mask;\r
192 \r
193         } else {\r
194                 Port_Base[port]->DIR &= ~mask;\r
195 \r
196         }\r
197 \r
198         return;\r
199 }\r
200 #endif\r
201 \r
202 void Port_RefreshPortDirection( void )\r
203 {\r
204         VALIDATE_STATE_INIT(PORT_REFRESH_PORT_DIRECTION_ID);\r
205         for (uint16 i = 0; i < PORT_NUMBER_OF_PINS; i++) {\r
206                 if (!(_configPtr->pins[i].conf & PORT_DIRECTION_CHANGEABLE)) {\r
207                         Port_RefreshPin(i);\r
208                 }\r
209         }\r
210         return;\r
211 }\r
212 \r
213 \r
214 #if PORT_VERSION_INFO_API == STD_ON\r
215 void Port_GetVersionInfo(Std_VersionInfoType* versionInfo)\r
216 {\r
217   VALIDATE_STATE_INIT(PORT_GET_VERSION_INFO_ID);\r
218   memcpy(versionInfo, &_Port_VersionInfo, sizeof(Std_VersionInfoType));\r
219   return;\r
220 }\r
221 #endif\r
222 \r
223 #if (PORT_SET_PIN_MODE_API == STD_ON)\r
224 void Port_SetPinMode(Port_PinType Pin, Port_PinModeType Mode) {\r
225         VALIDATE_STATE_INIT(PORT_SET_PIN_MODE_ID);\r
226         VALIDATE_PARAM_PIN(Pin, PORT_SET_PIN_MODE_ID);\r
227 \r
228         uint8 port = GET_PIN_PORT(Pin);\r
229         uint8 pin = GET_PIN_PIN(Pin);\r
230         uint32 mask = GET_PIN_MASK(Pin);\r
231 \r
232     Port_Base[port]->FUN &= ~mask;\r
233     Port_Base[port]->FUN |= ((Mode & 1) << pin);\r
234     return;\r
235 }\r
236 #endif\r