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