]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Dio.c
#ifdef:ed all Det includes
[arc.git] / arch / ppc / mpc55xx / 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 \r
18 \r
19 \r
20 \r
21 \r
22 \r
23 /*\r
24  * ports: PBxx to PJxx with xx ranging from 0 to 15\r
25  *\r
26  */\r
27 \r
28 #include "Std_Types.h"\r
29 #include "Dio.h"\r
30 #if defined(USE_DET)\r
31 #include "Det.h"\r
32 #endif\r
33 #include <string.h>\r
34 #include "mpc55xx.h"\r
35 \r
36 #define CHANNEL_PTR             (&DioChannelConfigData)\r
37 #define CHANNEL_GRP_PTR (&DioConfigData)\r
38 #define PORT_PTR                (&DioPortConfigData)\r
39 \r
40 \r
41 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
42 static int Channel_Config_Contains(Dio_ChannelType channelId)\r
43 {\r
44   Dio_ChannelType* ch_ptr=(Dio_ChannelType*)CHANNEL_PTR;\r
45   int rv=0;\r
46   while (DIO_END_OF_LIST!=*ch_ptr)\r
47   {\r
48     if (*ch_ptr==channelId)\r
49     { rv=1; break;}\r
50     ch_ptr++;\r
51   }\r
52   return rv;\r
53 }\r
54 \r
55 static int Port_Config_Contains(Dio_PortType portId)\r
56 {\r
57   Dio_PortType* port_ptr=(Dio_PortType*)PORT_PTR;\r
58   int rv=0;\r
59   while (DIO_END_OF_LIST!=*port_ptr)\r
60   {\r
61     if (*port_ptr==portId)\r
62     { rv=1; break;}\r
63     port_ptr++;\r
64   }\r
65   return rv;\r
66 }\r
67 \r
68 static int Channel_Group_Config_Contains(const Dio_ChannelGroupType* _channelGroupIdPtr)\r
69 {\r
70   Dio_ChannelGroupType* chGrp_ptr=(Dio_ChannelGroupType*)CHANNEL_GRP_PTR;\r
71   int rv=0;\r
72 \r
73   while (DIO_END_OF_LIST!=chGrp_ptr->port)\r
74   {\r
75     if (chGrp_ptr->port==_channelGroupIdPtr->port&&\r
76         chGrp_ptr->offset==_channelGroupIdPtr->offset&&\r
77         chGrp_ptr->mask==_channelGroupIdPtr->mask)\r
78     { rv=1; break;}\r
79     chGrp_ptr++;\r
80   }\r
81   return rv;\r
82 }\r
83 \r
84 #define VALIDATE_CHANNEL(_channelId, _api) \\r
85         if(0==Channel_Config_Contains(channelId)) {     \\r
86                 Det_ReportError(MODULE_ID_DIO,0,_api,DIO_E_PARAM_INVALID_CHANNEL_ID ); \\r
87                 level = 0;      \\r
88                 goto cleanup;   \\r
89                 }\r
90 #define VALIDATE_PORT(_portId, _api)\\r
91         if(0==Port_Config_Contains(_portId)) {\\r
92                 Det_ReportError(MODULE_ID_DIO,0,_api,DIO_E_PARAM_INVALID_PORT_ID ); \\r
93                 level = STD_LOW;\\r
94                 goto cleanup;\\r
95         }\r
96 #define VALIDATE_CHANNELGROUP(_channelGroupIdPtr, _api)\\r
97         if(0==Channel_Group_Config_Contains(_channelGroupIdPtr)) {\\r
98                 Det_ReportError(MODULE_ID_DIO,0,_api,DIO_E_PARAM_INVALID_GROUP_ID ); \\r
99                 level = STD_LOW;\\r
100                 goto cleanup;\\r
101         }\r
102 #else\r
103 #define VALIDATE_CHANNEL(_channelId, _api)\r
104 #define VALIDATE_PORT(_portId, _api)\r
105 #define VALIDATE_CHANNELGROUP(_channelGroupIdPtr, _api)\r
106 #endif\r
107 \r
108 Dio_LevelType Dio_ReadChannel(Dio_ChannelType channelId)\r
109 {\r
110   Dio_LevelType level = STD_LOW;\r
111   VALIDATE_CHANNEL(channelId, DIO_READCHANNEL_ID);\r
112   if (SIU.PCR[channelId].B.IBE) {\r
113     // Read level from SIU.\r
114     if (SIU.GPDI [channelId].R) {\r
115       level = STD_HIGH;\r
116     }\r
117   } else if(SIU.PCR[channelId].B.OBE) {\r
118     // Read level from SIU.\r
119     if (SIU.GPDO [channelId].R) {\r
120       level = STD_HIGH;\r
121     }\r
122   }\r
123 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
124   cleanup:\r
125 #endif\r
126   return (level);\r
127 }\r
128 \r
129 void Dio_WriteChannel(Dio_ChannelType channelId, Dio_LevelType level)\r
130 {\r
131   VALIDATE_CHANNEL(channelId, DIO_WRITECHANNEL_ID);\r
132   // Write level to SIU.\r
133   if(SIU.PCR[channelId].B.OBE) {\r
134     SIU.GPDO [channelId].R = level;\r
135   }\r
136 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
137   cleanup:\r
138 #endif\r
139   return;\r
140 }\r
141 \r
142 Dio_PortLevelType Dio_ReadPort(Dio_PortType portId)\r
143 {\r
144   Dio_LevelType level;\r
145   VALIDATE_PORT(portId, DIO_READPORT_ID);\r
146 \r
147 #if defined(CFG_MPC5554)||defined(CFG_MPC5567)\r
148   vuint16_t *ptr = (vuint16_t *)&SIU.GPDI;\r
149 #elif defined(CFG_MPC560X)\r
150   vuint16_t *ptr = (vuint16_t *)&SIU.PGPDI;\r
151 #else\r
152   vuint16_t *ptr = (vuint16_t *)&SIU.PGPDI0; // The GPDI 0-3 is organized in 32bit chunks but we want to step them in 16bit port-widths\r
153 #endif\r
154   level = ptr[portId]; // Read the bit pattern (16bits) to the port\r
155 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
156   cleanup:\r
157 #endif\r
158   return level;\r
159 }\r
160 \r
161 void Dio_WritePort(Dio_PortType portId, Dio_PortLevelType level)\r
162 {\r
163   VALIDATE_PORT(portId, DIO_WRITEPORT_ID);\r
164 \r
165   // find address of first port\r
166 #if defined(CFG_MPC5554)||defined(CFG_MPC5567)\r
167   vuint16_t *ptr = (vuint16_t *)&SIU.GPDO;\r
168 #elif defined(CFG_MPC560X)\r
169   vuint16_t *ptr = (vuint16_t *)&SIU.PGPDO;\r
170 #else\r
171   vuint16_t *ptr = (vuint16_t *)&SIU.PGPDO0; // The GPDO 0-3 is organized in 32bit chunks but we want to step them in 16bit port-widths\r
172 #endif\r
173   ptr[portId] = level; // Write the bit pattern (16bits) to the port\r
174 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
175   cleanup:\r
176 #endif\r
177   return;\r
178 }\r
179 \r
180 Dio_PortLevelType Dio_ReadChannelGroup(\r
181     const Dio_ChannelGroupType *channelGroupIdPtr)\r
182 {\r
183   Dio_LevelType level;\r
184   VALIDATE_CHANNELGROUP(channelGroupIdPtr,DIO_READCHANNELGROUP_ID);\r
185 \r
186   // find address of first port\r
187 #if defined(CFG_MPC5554)||defined(CFG_MPC5567)\r
188   vuint16_t *ptr = (vuint16_t *)&SIU.GPDI;\r
189 #elif defined(CFG_MPC560X)\r
190   uint32 *ptr = (uint32 *)&SIU.PGPDI;\r
191 #else\r
192   uint16 *ptr = (uint16 *)&SIU.PGPDI0; // The GPDI 0-3 is organized in 32bit chunks but we want to step them in 16bit port-widths\r
193 #endif\r
194 \r
195 #if defined(CFG_MPC560X)\r
196         if(channelGroupIdPtr->port % 2)\r
197         {\r
198                 // Get masked values\r
199                 level = ptr[channelGroupIdPtr->port / 2] & channelGroupIdPtr->mask;\r
200 \r
201                 // Shift down\r
202                 level>>=channelGroupIdPtr->offset;\r
203         }\r
204         else\r
205         {\r
206                 // Get masked values\r
207                 level = ptr[channelGroupIdPtr->port / 2] & (channelGroupIdPtr->mask<<16);\r
208 \r
209                 // Shift down\r
210                 level>>=(channelGroupIdPtr->offset + 16);\r
211         }\r
212 #else\r
213   // Get masked values\r
214   level = ptr[channelGroupIdPtr->port] & channelGroupIdPtr->mask;\r
215 \r
216   // Shift down\r
217   level<<=channelGroupIdPtr->offset;\r
218 #endif\r
219 \r
220 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
221   cleanup:\r
222 #endif\r
223   return level;\r
224 }\r
225 \r
226 void Dio_WriteChannelGroup(const Dio_ChannelGroupType *channelGroupIdPtr,\r
227     Dio_PortLevelType level)\r
228 {\r
229 #if defined(CFG_MPC560X)\r
230         VALIDATE_CHANNELGROUP(channelGroupIdPtr,DIO_WRITECHANNELGROUP_ID);\r
231         // find address of first port of the masked register\r
232         uint32 *ptr = (uint32 *)&SIU.MPGPDO[0]; // modified by Cobb.The GPDI 0-3 is organized in 32bit chunks but we want to step them in 16bit port-widths\r
233 \r
234         // Build the 32 bits Mask_Valule, and write to masked output register\r
235         ptr[channelGroupIdPtr->port] = (vuint32_t)((((vuint32_t)channelGroupIdPtr->mask )<< 16)|((((vuint16_t)level)<<channelGroupIdPtr->offset)&0xFFFF));\r
236 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
237         cleanup:\r
238 #endif\r
239         return;\r
240 #endif\r
241 \r
242 #if defined(CFG_MPC5516)\r
243   VALIDATE_CHANNELGROUP(channelGroupIdPtr,DIO_WRITECHANNELGROUP_ID);\r
244   // find address of first port of the masked register\r
245   uint32 *ptr = (uint32 *)&SIU.MPGPDO0; // The GPDI 0-3 is organized in 32bit chunks but we want to step them in 16bit port-widths\r
246 \r
247   // Build the 32 bits Mask_Valule, and write to masked output register\r
248   ptr[channelGroupIdPtr->port] = (channelGroupIdPtr->mask << 16)&((level\r
249       <<channelGroupIdPtr->offset)|0xFFFF);\r
250 #if ( DIO_DEV_ERROR_DETECT == STD_ON )\r
251   cleanup:\r
252 #endif\r
253   return;\r
254 #endif\r
255 }\r
256 \r