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