]> rtime.felk.cvut.cz Git - arc.git/blob - communication/Com/Com_Com.c
Initial commit.
[arc.git] / communication / Com / Com_Com.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
6  * This source code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16
17
18
19
20
21
22
23 #include <stdlib.h>\r
24 #include <string.h>\r
25 #include "Com_Com.h"\r
26 #include "Trace.h"\r
27 #include "CanIf.h"\r
28 #include "PduR.h"\r
29 #include "PduR_Com.h"\r
30 #include "Byteorder.h"\r
31 \r
32 uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
33         COM_VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);\r
34         // Store pointer to signal for easier coding.\r
35         ComGetSignal(SignalId);\r
36         ComGetEcoreSignal(SignalId);\r
37         ComGetIPdu(EcoreSignal->ComIPduHandleId);\r
38         ComGetEcoreIPdu(EcoreSignal->ComIPduHandleId);\r
39 \r
40         //DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);\r
41 \r
42         void *dataPtr = (void *)SignalDataPtr;\r
43 \r
44         if (Signal->ComSignalEndianess == BIG_ENDIAN) {\r
45                 if (Signal->ComSignalType == UINT16) {\r
46                         uint16 data;\r
47                         memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
48                         data = bswap16(data);\r
49                         dataPtr = &data;\r
50 \r
51                 } else if (Signal->ComSignalType == UINT32) {\r
52                         uint32 data;\r
53                         memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
54                         data = bswap32(data);\r
55                         dataPtr = &data;\r
56 \r
57                 } else if (Signal->ComSignalType == SINT16) {\r
58                         sint16 data;\r
59                         memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
60                         data = bswap16(data);\r
61                         dataPtr = &data;\r
62 \r
63                 } else if (Signal->ComSignalType == SINT32) {\r
64                         sint32 data;\r
65                         memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
66                         data = bswap32(data);\r
67                         dataPtr = &data;\r
68                 }\r
69 \r
70         }\r
71 \r
72         Com_CopyData(EcoreIPdu->ComIPduDataPtr, dataPtr, Signal->ComBitSize, Signal->ComBitPosition, 0);\r
73 \r
74         // If the signal has an update bit. Set it!\r
75         if (Signal->ComSignalEcoreUseUpdateBit) {\r
76                 setBit(EcoreIPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
77         }\r
78 \r
79         /*\r
80          * If signal has triggered transmit property, trigger a transmission!\r
81          */\r
82         if (Signal->ComTransferProperty == TRIGGERED) {\r
83                 EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
84         }\r
85         return E_OK;\r
86 }\r
87 \r
88 uint8 Com_ReceiveSignal(Com_SignalIdType SignalId, void* SignalDataPtr) {\r
89         ComGetSignal(SignalId);\r
90         COM_VALIDATE_SIGNAL(SignalId, 0x0b, E_NOT_OK);\r
91         DEBUG(DEBUG_LOW, "Com_ReceiveSignal: SignalId %d\n", SignalId);\r
92 \r
93         Com_CopyFromSignal(&ComConfig->ComSignal[SignalId], SignalDataPtr);\r
94 \r
95         if (Signal->ComSignalEndianess == BIG_ENDIAN) {\r
96                 if (Signal->ComSignalType == UINT16) {\r
97                         *(uint16*)SignalDataPtr = bswap16(*(uint16*)SignalDataPtr);\r
98                         //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
99 \r
100                 } else if (Signal->ComSignalType == UINT32) {\r
101                         *(uint32*)SignalDataPtr = bswap32(*(uint32*)SignalDataPtr);\r
102                         //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
103 \r
104                 } else if (Signal->ComSignalType == SINT16) {\r
105                         *(sint16*)SignalDataPtr = bswap16(*(sint16*)SignalDataPtr);\r
106                         //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
107 \r
108                 } else if (Signal->ComSignalType == SINT32) {\r
109                         *(sint32*)SignalDataPtr = bswap32(*(sint32*)SignalDataPtr);\r
110                         //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));\r
111                 }\r
112         }\r
113 \r
114 \r
115 \r
116         //uint16 val = *(uint16 *)SignalDataPtr;\r
117         //val = bswap16(val);\r
118         // Sign extend!\r
119         return E_OK;\r
120 }\r
121 \r
122 Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, uint8 *SduPtr) {\r
123         PduIdCheck(ComTxPduId, 0x13, E_NOT_OK);\r
124         /*\r
125          * COM260: This function must not check the transmission mode of the I-PDU\r
126          * since it should be possible to use it regardless of the transmission mode.\r
127          */\r
128 \r
129         /*\r
130          * COM395: This function must override the IPdu callouts used in Com_TriggerIPduTransmit();\r
131          */\r
132         ComGetIPdu(ComTxPduId);\r
133         ComGetEcoreIPdu(ComTxPduId);\r
134 \r
135         memcpy(SduPtr, EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
136         return E_OK;\r
137 }\r
138 \r
139 \r
140 void Com_TriggerIPduSend(PduIdType ComTxPduId) {\r
141         PduIdCheck(ComTxPduId, 0x17);\r
142 \r
143         //DEBUG(DEBUG_MEDIUM, "Com_TriggerIPduSend sending IPdu %d... ", ComTxPduId);\r
144         ComGetIPdu(ComTxPduId);\r
145         ComGetEcoreIPdu(ComTxPduId);\r
146 \r
147         // Is the IPdu ready for transmission?\r
148         if (EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduMinimumDelayTimer == 0) {\r
149                 //DEBUG(DEBUG_MEDIUM, "success!\n", ComTxPduId);\r
150 \r
151                 /*\r
152                 PduInfoType PduInfoPackage = {\r
153                         .SduDataPtr = malloc(IPdu->ComIPduSize),\r
154                         .SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize\r
155                 };\r
156                 memcpy((void *)PduInfoPackage.SduDataPtr, EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
157                 */\r
158 \r
159                 ComEcoreConfig.OutgoingPdu.SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize;\r
160                 memcpy((void *)ComEcoreConfig.OutgoingPdu.SduDataPtr, EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
161                 // Check callout status\r
162                 if (IPdu->ComIPduCallout != NULL) {\r
163                         if (!IPdu->ComIPduCallout(ComTxPduId, EcoreIPdu->ComIPduDataPtr)) {\r
164                                 // TODO Report error to DET.\r
165                                 // Det_ReportError();\r
166                                 return;\r
167                         }\r
168                 }\r
169 \r
170                 // Send IPdu!\r
171                 if (PduR_ComTransmit(ComTxPduId, &ComEcoreConfig.OutgoingPdu) == E_OK) {\r
172                         // Clear all update bits for the contained signals\r
173                         for (int i = 0; i < EcoreIPdu->NComIPduSignalRef; i++) {\r
174                                 if (IPdu->ComIPduSignalRef[i]->ComSignalEcoreUseUpdateBit) {\r
175                                         clearBit(EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);\r
176                                 }\r
177                         }\r
178                 }\r
179                 // Free allocted memory.\r
180                 // TODO: Is this the best way to solve this memory problem?\r
181                 //free(PduInfoPackage.SduDataPtr);\r
182 \r
183                 // Reset miminum delay timer.\r
184                 EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;\r
185 \r
186         } else {\r
187                 //DEBUG(DEBUG_MEDIUM, "failed (MDT)!\n", ComTxPduId);\r
188         }\r
189 }\r
190 \r
191 Std_ReturnType Com_RxIndication(PduIdType ComRxPduId, const uint8* SduPtr) {\r
192         PduIdCheck(ComRxPduId, 0x14, E_NOT_OK);\r
193 \r
194         ComGetIPdu(ComRxPduId);\r
195         ComGetEcoreIPdu(ComRxPduId);\r
196 \r
197         // If Ipdu is stopped\r
198         if (!EcoreIPdu->ComEcoreIpduStarted) {\r
199                 return E_OK;\r
200         }\r
201 \r
202         // Check callout status\r
203         if (IPdu->ComIPduCallout != NULL) {\r
204                 if (!IPdu->ComIPduCallout(ComRxPduId, SduPtr)) {\r
205                         // TODO Report error to DET.\r
206                         // Det_ReportError();\r
207                         return E_NOT_OK;\r
208                 }\r
209         }\r
210 \r
211         // Copy IPDU data\r
212         memcpy(EcoreIPdu->ComIPduDataPtr, SduPtr, IPdu->ComIPduSize);\r
213 \r
214         // For each signal.\r
215         const ComSignal_type *signal;\r
216         for (int i = 0; IPdu->ComIPduSignalRef[i] != NULL; i++) {\r
217                 signal = IPdu->ComIPduSignalRef[i];\r
218                 ComGetEcoreSignal(signal->ComHandleId);\r
219 \r
220                 // If this signal uses an update bit, then it is only considered if this bit is set.\r
221                 if (!signal->ComSignalEcoreUseUpdateBit ||\r
222                         (signal->ComSignalEcoreUseUpdateBit && testBit(EcoreIPdu->ComIPduDataPtr, signal->ComUpdateBitPosition))) {\r
223 \r
224                         if (signal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.\r
225                                 // Reset the deadline monitoring timer.\r
226                                 EcoreSignal->ComEcoreDeadlineCounter = signal->ComTimeoutFactor;\r
227                         }\r
228 \r
229                         /*\r
230                         // Zero new filter value.\r
231                         IPdu->ComIPduSignalRef[i]->ComFilter.ComFilterEcoreNewValue = 0;\r
232 \r
233                         //Fix this!!!\r
234                         Com_CopyFromSignal(IPdu->ComIPduSignalRef[i], &IPdu->ComIPduSignalRef[i]->ComFilter.ComFilterEcoreNewValue);\r
235                         */\r
236                         // Perform filtering\r
237                         //if (Com_Filter(IPdu->ComIPduSignalRef[i])) {\r
238 \r
239                                 // Check the signal processing mode.\r
240                                 if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {\r
241                                         // If signal processing mode is IMMEDIATE, notify the signal callback.\r
242                                         if (IPdu->ComIPduSignalRef[i]->ComNotification != NULL) {\r
243                                                 IPdu->ComIPduSignalRef[i]->ComNotification();\r
244                                         }\r
245 \r
246                                 } else {\r
247                                         // Signal processing mode is DEFERRED, mark the signal as updated.\r
248                                         EcoreSignal->ComSignalUpdated = 1;\r
249                                 }\r
250                         //}\r
251                 } else {\r
252                         DEBUG(DEBUG_LOW, "Com_RxIndication: Ignored signal %d of I-PDU %d since its update bit was not set\n", signal->ComHandleId, IPdu->ComIPduRxHandleId);\r
253                 }\r
254         }\r
255 \r
256         return E_OK;\r
257 }\r
258 \r
259 void Com_TxConfirmation(PduIdType ComTxPduId) {\r
260         PduIdCheck(ComTxPduId, 0x15);\r
261 }\r
262 \r
263 \r
264 Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
265 //#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?\r
266         ComGetSignal(SignalGroupId);\r
267         ComGetEcoreSignal(SignalGroupId);\r
268         ComGetEcoreIPdu(EcoreSignal->ComIPduHandleId);\r
269         ComGetIPdu(EcoreSignal->ComIPduHandleId);\r
270 \r
271 \r
272         // Copy shadow buffer to Ipdu data space\r
273         const ComGroupSignal_type *groupSignal;\r
274         for (int i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
275                 groupSignal = Signal->ComGroupSignal[i];\r
276                 Com_CopyData(EcoreIPdu->ComIPduDataPtr, EcoreSignal->ComEcoreShadowBuffer,  groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
277         }\r
278 \r
279         // If the signal has an update bit. Set it!\r
280         if (Signal->ComSignalEcoreUseUpdateBit) {\r
281                 setBit(EcoreIPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
282         }\r
283 \r
284         /*\r
285          * If signal has triggered transmit property, trigger a transmission!\r
286          */\r
287         if (Signal->ComTransferProperty == TRIGGERED) {\r
288                 EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
289         }\r
290 \r
291         return E_OK;\r
292 }\r
293 \r
294 \r
295 Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
296 //#warning Com_ReceiveSignalGroup should be performed atomically. Should we disable interrupts here?\r
297         ComGetSignal(SignalGroupId);\r
298         ComGetEcoreSignal(SignalGroupId);\r
299         ComGetEcoreIPdu(EcoreSignal->ComIPduHandleId);\r
300 \r
301         // Copy Ipdu data buffer to shadow buffer.\r
302         const ComGroupSignal_type *groupSignal;\r
303         for (int i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
304                 groupSignal = Signal->ComGroupSignal[i];\r
305                 Com_CopyData(EcoreSignal->ComEcoreShadowBuffer, EcoreIPdu->ComIPduDataPtr, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
306         }\r
307 \r
308 \r
309         return E_OK;\r
310 }\r
311 \r
312 void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
313         ComGetGroupSignal(SignalId);\r
314         ComGetEcoreGroupSignal(SignalId);\r
315         Com_CopyData(EcoreGroupSignal->ComEcoreShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);\r
316 }\r
317 \r
318 void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {\r
319         ComGetGroupSignal(SignalId);\r
320         ComGetEcoreGroupSignal(SignalId);\r
321         Com_CopyData(SignalDataPtr, EcoreGroupSignal->ComEcoreShadowBuffer, GroupSignal->ComBitSize, 0, GroupSignal->ComBitPosition);\r
322 }\r