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