]> rtime.felk.cvut.cz Git - arc.git/blob - arch/arm/arm_cr4/drivers/Dio.c
44c5db75f54f614ff2299be0c278e9e2d54fa510
[arc.git] / arch / arm / arm_cr4 / drivers / Dio.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 "Dio.h"\r
19 #include "Det.h"\r
20 #include "Cpu.h"\r
21 #include <string.h>\r
22 \r
23 GIO_RegisterType *GPIO_ports[] = { GIO_PORTA_BASE, GIO_PORTB_BASE };\r
24 \r
25 #define DIO_GET_PORT_FROM_CHANNEL_ID(_channelId) (_channelId >> 8)\r
26 #define DIO_GET_BIT_FROM_CHANNEL_ID(_channelId) (1 << (_channelId & 0x1F))\r
27 \r
28 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
29 static int Channel_Config_Contains(Dio_ChannelType channelId)\r
30 {\r
31         Dio_ChannelType* ch_ptr=(Dio_ChannelType*)(&DioChannelConfigData);\r
32         int rv=0;\r
33         while (DIO_END_OF_LIST!=*ch_ptr)\r
34         {\r
35         if (*ch_ptr==channelId)\r
36         {\r
37                 rv=1;\r
38                 break;\r
39         }\r
40         ch_ptr++;\r
41         }\r
42         return rv;\r
43 }\r
44 \r
45 static int Port_Config_Contains(Dio_PortType portId)\r
46 {\r
47         Dio_PortType* port_ptr=(Dio_PortType*)(&DioPortConfigData);\r
48         int rv=0;\r
49         while (DIO_END_OF_LIST!=*port_ptr)\r
50         {\r
51         if (*port_ptr==portId)\r
52         { rv=1; break;}\r
53         port_ptr++;\r
54         }\r
55         return rv;\r
56 }\r
57 \r
58 static int Channel_Group_Config_Contains(const Dio_ChannelGroupType* _channelGroupIdPtr)\r
59 {\r
60         Dio_ChannelGroupType* chGrp_ptr=(Dio_ChannelGroupType*)(&DioConfigData);\r
61         int rv=0;\r
62 \r
63         while (DIO_END_OF_LIST!=chGrp_ptr->port)\r
64         {\r
65         if (chGrp_ptr->port==_channelGroupIdPtr->port&&\r
66                 chGrp_ptr->offset==_channelGroupIdPtr->offset&&\r
67                 chGrp_ptr->mask==_channelGroupIdPtr->mask)\r
68         { rv=1; break;}\r
69         chGrp_ptr++;\r
70         }\r
71         return rv;\r
72 }\r
73 \r
74 #define VALIDATE_CHANNEL(_channelId, _api) \\r
75         if(0==Channel_Config_Contains(channelId)) {     \\r
76                 Det_ReportError(MODULE_ID_DIO,0,_api,DIO_E_PARAM_INVALID_CHANNEL_ID ); \\r
77                 level = 0;      \\r
78                 goto cleanup;   \\r
79                 }\r
80 #define VALIDATE_PORT(_portId, _api)\\r
81         if(0==Port_Config_Contains(_portId)) {\\r
82                 Det_ReportError(MODULE_ID_DIO,0,_api,DIO_E_PARAM_INVALID_PORT_ID ); \\r
83                 level = STD_LOW;\\r
84                 goto cleanup;\\r
85         }\r
86 #define VALIDATE_CHANNELGROUP(_channelGroupIdPtr, _api)\\r
87         if(0==Channel_Group_Config_Contains(_channelGroupIdPtr)) {\\r
88                 Det_ReportError(MODULE_ID_DIO,0,_api,DIO_E_PARAM_INVALID_GROUP_ID ); \\r
89                 level = STD_LOW;\\r
90                 goto cleanup;\\r
91         }\r
92 #else\r
93 #define VALIDATE_CHANNEL(_channelId, _api)\r
94 #define VALIDATE_PORT(_portId, _api)\r
95 #define VALIDATE_CHANNELGROUP(_channelGroupIdPtr, _api)\r
96 #endif\r
97 \r
98 Dio_PortLevelType Dio_ReadPort(Dio_PortType portId)\r
99 {\r
100         Dio_PortLevelType level = 0;\r
101         VALIDATE_PORT(portId, DIO_READPORT_ID);\r
102 \r
103         level = (uint8)GPIO_ports[portId]->DIN;\r
104 \r
105 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
106         cleanup:\r
107 #endif\r
108         return level;\r
109 }\r
110 \r
111 void Dio_WritePort(Dio_PortType portId, Dio_PortLevelType level)\r
112 {\r
113     VALIDATE_PORT(portId, DIO_WRITEPORT_ID);\r
114 \r
115         GPIO_ports[portId]->DOUT = (uint32)level;\r
116 \r
117 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
118         cleanup:\r
119 #endif\r
120         return;\r
121 }\r
122 \r
123 Dio_LevelType Dio_ReadChannel(Dio_ChannelType channelId)\r
124 {\r
125         Dio_LevelType level;\r
126         VALIDATE_CHANNEL(channelId, DIO_READCHANNEL_ID);\r
127 \r
128         Dio_PortLevelType portVal = Dio_ReadPort(DIO_GET_PORT_FROM_CHANNEL_ID(channelId));\r
129         Dio_PortLevelType bit = DIO_GET_BIT_FROM_CHANNEL_ID(channelId);\r
130 \r
131         if ((portVal & bit) != STD_LOW){\r
132                 level = STD_HIGH;\r
133         } else{\r
134                 level = STD_LOW;\r
135         }\r
136 \r
137 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
138         cleanup:\r
139 #endif\r
140         return (level);\r
141 }\r
142 \r
143 void Dio_WriteChannel(Dio_ChannelType channelId, Dio_LevelType level)\r
144 {\r
145         VALIDATE_CHANNEL(channelId, DIO_WRITECHANNEL_ID);\r
146 \r
147         Dio_PortType port = DIO_GET_PORT_FROM_CHANNEL_ID(channelId);\r
148         uint16 bit = DIO_GET_BIT_FROM_CHANNEL_ID(channelId);\r
149 \r
150         if (!( GPIO_ports[port]->DIR & bit)) { // This is an input channel.\r
151                 goto cleanup;\r
152         }\r
153 \r
154         Dio_PortLevelType portVal = Dio_ReadPort(port);\r
155 \r
156         if(level == STD_HIGH){\r
157                 portVal |= bit;\r
158         }else{\r
159                 portVal &= ~bit;\r
160         }\r
161 \r
162         Dio_WritePort(port, portVal);\r
163 \r
164         cleanup: return;\r
165 }\r
166 \r
167 \r
168 Dio_PortLevelType Dio_ReadChannelGroup(\r
169     const Dio_ChannelGroupType *channelGroupIdPtr)\r
170 {\r
171         Dio_LevelType level;\r
172         VALIDATE_CHANNELGROUP(channelGroupIdPtr,DIO_READCHANNELGROUP_ID);\r
173 \r
174         // Get masked values\r
175         level = Dio_ReadPort(channelGroupIdPtr->port) & channelGroupIdPtr->mask;\r
176 \r
177         // Shift down\r
178         level = level >> channelGroupIdPtr->offset;\r
179 \r
180 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
181         cleanup:\r
182 #endif\r
183         return level;\r
184 }\r
185 \r
186 void Dio_WriteChannelGroup(const Dio_ChannelGroupType *channelGroupIdPtr,\r
187     Dio_PortLevelType level)\r
188 {\r
189         VALIDATE_CHANNELGROUP(channelGroupIdPtr,DIO_WRITECHANNELGROUP_ID);\r
190 \r
191         // Shift up and apply mask so that no unwanted bits are affected\r
192         level = (level << channelGroupIdPtr->offset) & channelGroupIdPtr->mask;\r
193 \r
194         // Read port and clear out masked bits\r
195         Dio_PortLevelType portVal = Dio_ReadPort(channelGroupIdPtr->port) & (~channelGroupIdPtr->mask);\r
196 \r
197         // Or in the upshifted masked level\r
198         portVal |= level;\r
199 \r
200         Dio_WritePort(channelGroupIdPtr->port, portVal);\r
201 \r
202 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
203         cleanup:\r
204 #endif\r
205         return;\r
206 }\r
207 \r
208 \r