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