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