]> rtime.felk.cvut.cz Git - arc.git/blob - communication/Com/Com_Com.c
c58676c4429da33eda26302254af0162feeb60a4
[arc.git] / communication / Com / Com_Com.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 #include <stdlib.h>\r
24 #include <string.h>\r
25 #include "Com_Arc_Types.h"\r
26 #include "Com.h"\r
27 #include "Com_Internal.h"\r
28 #include "Com_misc.h"\r
29 #include "debug.h"\r
30 #include "PduR.h"\r
31 #include "Det.h"\r
32 \r
33 \r
34 uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
35         VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);\r
36         // Store pointer to signal for easier coding.\r
37         const ComSignal_type * Signal = GET_Signal(SignalId);\r
38         Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalId);\r
39         const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
40         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
41 \r
42         //DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);\r
43 \r
44         // TODO: CopyData\r
45         // Com_CopyData(Arc_IPdu->ComIPduDataPtr, dataPtr, Signal->ComBitSize, Signal->ComBitPosition, 0);\r
46         Com_WriteSignalDataToPdu(Signal->ComHandleId, SignalDataPtr);\r
47 \r
48         // If the signal has an update bit. Set it!\r
49         if (Signal->ComSignalArcUseUpdateBit) {\r
50                 SETBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
51         }\r
52 \r
53         /*\r
54          * If signal has triggered transmit property, trigger a transmission!\r
55          */\r
56         if (Signal->ComTransferProperty == TRIGGERED) {\r
57                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
58         }\r
59         return E_OK;\r
60 }\r
61 \r
62 uint8 Com_ReceiveSignal(Com_SignalIdType SignalId, void* SignalDataPtr) {\r
63         VALIDATE_SIGNAL(SignalId, 0x0b, E_NOT_OK);\r
64         DEBUG(DEBUG_LOW, "Com_ReceiveSignal: SignalId %d\n", SignalId);\r
65 \r
66         // Com_CopyFromSignal(&ComConfig->ComSignal[SignalId], SignalDataPtr);\r
67         Com_ReadSignalDataFromPdu(SignalId, SignalDataPtr);\r
68 \r
69         //uint16 val = *(uint16 *)SignalDataPtr;\r
70         //val = bswap16(val);\r
71         // Sign extend!\r
72         return E_OK;\r
73 }\r
74 \r
75 Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, uint8 *SduPtr) {\r
76         PDU_ID_CHECK(ComTxPduId, 0x13, E_NOT_OK);\r
77         /*\r
78          * COM260: This function must not check the transmission mode of the I-PDU\r
79          * since it should be possible to use it regardless of the transmission mode.\r
80          */\r
81 \r
82         /*\r
83          * COM395: This function must override the IPdu callouts used in Com_TriggerIPduTransmit();\r
84          */\r
85         const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);\r
86         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);\r
87 \r
88         memcpy(SduPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
89         return E_OK;\r
90 }\r
91 \r
92 \r
93 //lint -esym(904, Com_TriggerIPduSend) //PC-Lint Exception of rule 14.7\r
94 void Com_TriggerIPduSend(PduIdType ComTxPduId) {\r
95         PDU_ID_CHECK(ComTxPduId, 0x17);\r
96 \r
97         //DEBUG(DEBUG_MEDIUM, "Com_TriggerIPduSend sending IPdu %d... ", ComTxPduId);\r
98         const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);\r
99         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);\r
100 \r
101         // Is the IPdu ready for transmission?\r
102         if (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) {\r
103                 //DEBUG(DEBUG_MEDIUM, "success!\n", ComTxPduId);\r
104 \r
105                 /*\r
106                 PduInfoType PduInfoPackage = {\r
107                         .SduDataPtr = malloc(IPdu->ComIPduSize),\r
108                         .SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize\r
109                 };\r
110                 memcpy((void *)PduInfoPackage.SduDataPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
111                 */\r
112 \r
113                 Com_Arc_Config.OutgoingPdu.SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize;\r
114                 memcpy((void *)Com_Arc_Config.OutgoingPdu.SduDataPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
115                 // Check callout status\r
116                 if (IPdu->ComIPduCallout != NULL) {\r
117                         if (!IPdu->ComIPduCallout(ComTxPduId, Arc_IPdu->ComIPduDataPtr)) {\r
118                                 // TODO Report error to DET.\r
119                                 // Det_ReportError();\r
120                                 return;\r
121                         }\r
122                 }\r
123 \r
124                 // Send IPdu!\r
125                 if (PduR_ComTransmit(IPdu->ArcIPduOutgoingId, &Com_Arc_Config.OutgoingPdu) == E_OK) {\r
126                         // Clear all update bits for the contained signals\r
127                         for (uint8 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
128                         //for (int i = 0; i < Arc_IPdu->NComIPduSignalRef; i++) {\r
129                                 if (IPdu->ComIPduSignalRef[i]->ComSignalArcUseUpdateBit) {\r
130                                         CLEARBIT(Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);\r
131                                 }\r
132                         }\r
133                 }\r
134                 // Free allocted memory.\r
135                 // TODO: Is this the best way to solve this memory problem?\r
136                 //free(PduInfoPackage.SduDataPtr);\r
137 \r
138                 // Reset miminum delay timer.\r
139                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;\r
140 \r
141         } else {\r
142                 //DEBUG(DEBUG_MEDIUM, "failed (MDT)!\n", ComTxPduId);\r
143         }\r
144 }\r
145 \r
146 //lint -esym(904, Com_RxIndication) //PC-Lint Exception of rule 14.7\r
147 void Com_RxIndication(PduIdType ComRxPduId, const uint8* SduPtr) {\r
148         PDU_ID_CHECK(ComRxPduId, 0x14);\r
149 \r
150         const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);\r
151         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);\r
152 \r
153         // If Ipdu is stopped\r
154         if (!Arc_IPdu->Com_Arc_IpduStarted) {\r
155                 return;\r
156         }\r
157 \r
158         // Check callout status\r
159         if (IPdu->ComIPduCallout != NULL) {\r
160                 if (!IPdu->ComIPduCallout(ComRxPduId, SduPtr)) {\r
161                         // TODO Report error to DET.\r
162                         // Det_ReportError();\r
163                         return;\r
164                 }\r
165         }\r
166 \r
167         // Copy IPDU data\r
168         memcpy(Arc_IPdu->ComIPduDataPtr, SduPtr, IPdu->ComIPduSize);\r
169 \r
170         // For each signal.\r
171         const ComSignal_type *comSignal;\r
172         for (uint8 i = 0; IPdu->ComIPduSignalRef[i] != NULL; i++) {\r
173                 comSignal = IPdu->ComIPduSignalRef[i];\r
174                 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(comSignal->ComHandleId);\r
175 \r
176                 // If this signal uses an update bit, then it is only considered if this bit is set.\r
177                 if ( (!comSignal->ComSignalArcUseUpdateBit) ||\r
178                         ( (comSignal->ComSignalArcUseUpdateBit) && (TESTBIT(Arc_IPdu->ComIPduDataPtr, comSignal->ComUpdateBitPosition)) ) ) {\r
179 \r
180                         if (comSignal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.\r
181                                 // Reset the deadline monitoring timer.\r
182                                 Arc_Signal->Com_Arc_DeadlineCounter = comSignal->ComTimeoutFactor;\r
183                         }\r
184 \r
185                         // Check the signal processing mode.\r
186                         if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {\r
187                                 // If signal processing mode is IMMEDIATE, notify the signal callback.\r
188                                 if (IPdu->ComIPduSignalRef[i]->ComNotification != NULL) {\r
189                                         IPdu->ComIPduSignalRef[i]->ComNotification();\r
190                                 }\r
191 \r
192                         } else {\r
193                                 // Signal processing mode is DEFERRED, mark the signal as updated.\r
194                                 Arc_Signal->ComSignalUpdated = 1;\r
195                         }\r
196 \r
197                 } else {\r
198                         DEBUG(DEBUG_LOW, "Com_RxIndication: Ignored signal %d of I-PD %d since its update bit was not set\n", comSignal->ComHandleId, ComRxPduId);\r
199                 }\r
200         }\r
201 \r
202         return;\r
203 }\r
204 \r
205 void Com_TxConfirmation(PduIdType ComTxPduId) {\r
206         PDU_ID_CHECK(ComTxPduId, 0x15);\r
207         (void)ComTxPduId; // Nothing to be done. This is just to avoid Lint warning.\r
208 }\r
209 \r
210 \r
211 Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
212 //#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?\r
213         const ComSignal_type * Signal = GET_Signal(SignalGroupId);\r
214         Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalGroupId);\r
215         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);\r
216         const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);\r
217 \r
218 \r
219         // Copy shadow buffer to Ipdu data space\r
220         const ComGroupSignal_type *groupSignal;\r
221         for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
222                 groupSignal = Signal->ComGroupSignal[i];\r
223                 // TODO CopyData\r
224                 // Com_CopyData(Arc_IPdu->ComIPduDataPtr, Arc_Signal->Com_Arc_ShadowBuffer,  groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
225                 Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, groupSignal->ComHandleId, Arc_Signal->Com_Arc_ShadowBuffer);\r
226         }\r
227 \r
228         // If the signal has an update bit. Set it!\r
229         if (Signal->ComSignalArcUseUpdateBit) {\r
230                 SETBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
231         }\r
232 \r
233         /*\r
234          * If signal has triggered transmit property, trigger a transmission!\r
235          */\r
236         if (Signal->ComTransferProperty == TRIGGERED) {\r
237                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
238         }\r
239 \r
240         return E_OK;\r
241 }\r
242 \r
243 \r
244 Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
245 //#warning Com_ReceiveSignalGroup should be performed atomically. Should we disable interrupts here?\r
246         const ComSignal_type * Signal = GET_Signal(SignalGroupId);\r
247         Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalGroupId);\r
248 \r
249         // Copy Ipdu data buffer to shadow buffer.\r
250         const ComGroupSignal_type *groupSignal;\r
251         for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
252                 groupSignal = Signal->ComGroupSignal[i];\r
253                 // TODO: CopyData\r
254                 // Com_CopyData(Arc_Signal->Com_Arc_ShadowBuffer, Arc_IPdu->ComIPduDataPtr, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
255                 Com_ReadSignalDataFromPdu(groupSignal->ComHandleId, (void *)Arc_Signal->Com_Arc_ShadowBuffer);\r
256         }\r
257 \r
258 \r
259         return E_OK;\r
260 }\r
261 \r
262 void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
263         Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
264         // TODO: CopyData\r
265         // Com_CopyData(Arc_GroupSignal->Com_Arc_ShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);\r
266         Com_WriteSignalDataToPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer);\r
267 }\r
268 \r
269 void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {\r
270         Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
271         // TODO: CopyData\r
272         // Com_CopyData(SignalDataPtr, Arc_GroupSignal->Com_Arc_ShadowBuffer, GroupSignal->ComBitSize, 0, GroupSignal->ComBitPosition);\r
273         Com_ReadSignalDataFromPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer);\r
274 }\r