]> rtime.felk.cvut.cz Git - arc.git/blob - communication/Com/Com_Com.c
467383bcd0b4b9009425f2040a2fc05f6e7d8af6
[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 //lint -esym(960,8.7)   PC-Lint misunderstanding of Misra 8.7 for Com_SystenEndianness and endianess_test\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 #include "Cpu.h"\r
33 \r
34 Com_BufferPduStateType Com_BufferPduState[COM_N_IPDUS];\r
35 \r
36 \r
37 uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
38         VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);\r
39         // Store pointer to signal for easier coding.\r
40         const ComSignal_type * Signal = GET_Signal(SignalId);\r
41         const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
42         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);\r
43 \r
44         if (isPduBufferLocked(getPduId(IPdu))) {\r
45                 return COM_BUSY;\r
46         }\r
47         //DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);\r
48 \r
49         // TODO: CopyData\r
50         // Com_CopyData(IPdu->ComIPduDataPtr, dataPtr, Signal->ComBitSize, Signal->ComBitPosition, 0);\r
51         Com_WriteSignalDataToPdu(Signal->ComHandleId, SignalDataPtr);\r
52 \r
53         // If the signal has an update bit. Set it!\r
54         if (Signal->ComSignalArcUseUpdateBit) {\r
55                 SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
56         }\r
57 \r
58         /*\r
59          * If signal has triggered transmit property, trigger a transmission!\r
60          */\r
61         if (Signal->ComTransferProperty == TRIGGERED) {\r
62                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
63         }\r
64         return E_OK;\r
65 }\r
66 \r
67 uint8 Com_ReceiveSignal(Com_SignalIdType SignalId, void* SignalDataPtr) {\r
68         VALIDATE_SIGNAL(SignalId, 0x0b, E_NOT_OK);\r
69         DEBUG(DEBUG_LOW, "Com_ReceiveSignal: SignalId %d\n", SignalId);\r
70 \r
71         const ComSignal_type * Signal = GET_Signal(SignalId);\r
72         const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
73         if (isPduBufferLocked(getPduId(IPdu))) {\r
74                 return COM_BUSY;\r
75         }\r
76 \r
77         // Com_CopyFromSignal(&ComConfig->ComSignal[SignalId], SignalDataPtr);\r
78         Com_ReadSignalDataFromPdu(SignalId, SignalDataPtr);\r
79 \r
80         //uint16 val = *(uint16 *)SignalDataPtr;\r
81         //val = bswap16(val);\r
82         // Sign extend!\r
83         return E_OK;\r
84 }\r
85 \r
86 uint8 Com_ReceiveDynSignal(Com_SignalIdType SignalId, void* SignalDataPtr, uint16* Length) {\r
87         const ComSignal_type * Signal = GET_Signal(SignalId);\r
88         Com_Arc_IPdu_type    *Arc_IPdu   = GET_ArcIPdu(Signal->ComIPduHandleId);\r
89         const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);\r
90 \r
91         Com_SignalType signalType = Signal->ComSignalType;\r
92         if (signalType != UINT8_DYN || isPduBufferLocked(getPduId(IPdu))) {\r
93                 return COM_SERVICE_NOT_AVAILABLE;\r
94         }\r
95 \r
96         if (*Length > Arc_IPdu->Com_Arc_DynSignalLength) {\r
97                 *Length = Arc_IPdu->Com_Arc_DynSignalLength;\r
98         }\r
99         uint8 startFromPduByte = (Signal->ComBitPosition) / 8;\r
100         memcpy(SignalDataPtr, IPdu->ComIPduDataPtr + startFromPduByte, *Length);\r
101         return E_OK;\r
102 }\r
103 \r
104 uint8 Com_SendDynSignal(Com_SignalIdType SignalId, const void* SignalDataPtr, uint16 Length) {\r
105         const ComSignal_type * Signal = GET_Signal(SignalId);\r
106         Com_Arc_IPdu_type    *Arc_IPdu   = GET_ArcIPdu(Signal->ComIPduHandleId);\r
107         const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);\r
108 \r
109         Com_SignalType signalType = Signal->ComSignalType;\r
110         if (signalType != UINT8_DYN) {\r
111                 return COM_SERVICE_NOT_AVAILABLE;\r
112         }\r
113         if (isPduBufferLocked(getPduId(IPdu))) {\r
114                 return COM_BUSY;\r
115         }\r
116         uint8 signalLength = Signal->ComBitSize / 8;\r
117         Com_BitPositionType bitPosition = Signal->ComBitPosition;\r
118         if (signalLength < Length) {\r
119                 return E_NOT_OK;\r
120         }\r
121         uint8 startFromPduByte = bitPosition / 8;\r
122         memcpy((void *)(IPdu->ComIPduDataPtr + startFromPduByte), SignalDataPtr, Length);\r
123         Arc_IPdu->Com_Arc_DynSignalLength = Length;\r
124         // If the signal has an update bit. Set it!\r
125         if (Signal->ComSignalArcUseUpdateBit) {\r
126                 SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
127         }\r
128          // If signal has triggered transmit property, trigger a transmission!\r
129         if (Signal->ComTransferProperty == TRIGGERED) {\r
130                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
131         }\r
132         return E_OK;\r
133 }\r
134 \r
135 Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, PduInfoType *PduInfoPtr) {\r
136         PDU_ID_CHECK(ComTxPduId, 0x13, E_NOT_OK);\r
137         /*\r
138          * COM260: This function must not check the transmission mode of the I-PDU\r
139          * since it should be possible to use it regardless of the transmission mode.\r
140          */\r
141 \r
142         /*\r
143          * COM395: This function must override the IPdu callouts used in Com_TriggerIPduTransmit();\r
144          */\r
145         const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);\r
146 \r
147         memcpy(PduInfoPtr->SduDataPtr, IPdu->ComIPduDataPtr, IPdu->ComIPduSize);\r
148         PduInfoPtr->SduLength = IPdu->ComIPduSize;\r
149         return E_OK;\r
150 }\r
151 \r
152 \r
153 //lint -esym(904, Com_TriggerIPduSend) //PC-Lint Exception of rule 14.7\r
154 void Com_TriggerIPduSend(PduIdType ComTxPduId) {\r
155         PDU_ID_CHECK(ComTxPduId, 0x17);\r
156 \r
157         const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);\r
158         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);\r
159 \r
160         // Is the IPdu ready for transmission?\r
161         if (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) {\r
162 \r
163         imask_t state;\r
164 \r
165         //lint --e(725) Suppress PC-Lint warning "Expected positive indentation...". What means?\r
166         Irq_Save(state);\r
167                 // Check callout status\r
168                 if (IPdu->ComIPduCallout != NULL) {\r
169                         if (!IPdu->ComIPduCallout(ComTxPduId, IPdu->ComIPduDataPtr)) {\r
170                                 // TODO Report error to DET.\r
171                                 // Det_ReportError();\r
172                             Irq_Restore(state);\r
173                                 return;\r
174                         }\r
175                 }\r
176                 PduInfoType PduInfoPackage;\r
177                 PduInfoPackage.SduDataPtr = (uint8 *)IPdu->ComIPduDataPtr;\r
178                 if (IPdu->ComIPduDynSignalRef != 0) {\r
179                         uint8 sizeWithoutDynSignal = IPdu->ComIPduSize - (IPdu->ComIPduDynSignalRef->ComBitSize/8);\r
180                         PduInfoPackage.SduLength = sizeWithoutDynSignal + Arc_IPdu->Com_Arc_DynSignalLength;\r
181                 } else {\r
182                         PduInfoPackage.SduLength = IPdu->ComIPduSize;\r
183                 }\r
184 \r
185                 // Send IPdu!\r
186                 if (PduR_ComTransmit(IPdu->ArcIPduOutgoingId, &PduInfoPackage) == E_OK) {\r
187                         // Clear all update bits for the contained signals\r
188                         for (uint8 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {\r
189                                 if (IPdu->ComIPduSignalRef[i]->ComSignalArcUseUpdateBit) {\r
190                                         CLEARBIT(IPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);\r
191                                 }\r
192                         }\r
193                 } else {\r
194                         UnlockTpBuffer(getPduId(IPdu));\r
195                 }\r
196             Irq_Restore(state);\r
197 \r
198                 // Reset miminum delay timer.\r
199                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;\r
200 \r
201         } else {\r
202                 //DEBUG(DEBUG_MEDIUM, "failed (MDT)!\n", ComTxPduId);\r
203         }\r
204 }\r
205 \r
206 //lint -esym(904, Com_RxIndication) //PC-Lint Exception of rule 14.7\r
207 void Com_RxIndication(PduIdType ComRxPduId, const PduInfoType* PduInfoPtr) {\r
208         PDU_ID_CHECK(ComRxPduId, 0x14);\r
209 \r
210         const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);\r
211         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);\r
212 \r
213         // If Ipdu is stopped\r
214         if (!Arc_IPdu->Com_Arc_IpduStarted) {\r
215                 return;\r
216         }\r
217 \r
218         // Check callout status\r
219         if (IPdu->ComIPduCallout != NULL) {\r
220                 if (!IPdu->ComIPduCallout(ComRxPduId, PduInfoPtr->SduDataPtr)) {\r
221                         // TODO Report error to DET.\r
222                         // Det_ReportError();\r
223                         return;\r
224                 }\r
225         }\r
226 \r
227         // Copy IPDU data\r
228         memcpy((void *)IPdu->ComIPduDataPtr, PduInfoPtr->SduDataPtr, IPdu->ComIPduSize);\r
229 \r
230         Com_RxProcessSignals(IPdu,Arc_IPdu);\r
231 \r
232         return;\r
233 }\r
234 \r
235 void Com_TpRxIndication(PduIdType PduId, NotifResultType Result) {\r
236         PDU_ID_CHECK(PduId, 0x14);\r
237 \r
238         const ComIPdu_type *IPdu = GET_IPdu(PduId);\r
239         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(PduId);\r
240 \r
241         // If Ipdu is stopped\r
242         if (!Arc_IPdu->Com_Arc_IpduStarted) {\r
243                 return;\r
244         }\r
245         // unlock buffer\r
246         imask_t state;\r
247         Irq_Save(state);\r
248         UnlockTpBuffer(getPduId(IPdu));\r
249         Irq_Restore(state);\r
250 \r
251         if (Result == NTFRSLT_OK) {\r
252                 Com_RxProcessSignals(IPdu,Arc_IPdu);\r
253         }\r
254 }\r
255 void Com_TpTxConfirmation(PduIdType PduId, NotifResultType Result) {\r
256         PDU_ID_CHECK(PduId, 0x15);\r
257         const ComIPdu_type *IPdu = GET_IPdu(PduId);\r
258 \r
259         imask_t state;\r
260         Irq_Save(state);\r
261         UnlockTpBuffer(getPduId(IPdu));\r
262         Irq_Restore(state);\r
263 }\r
264 void Com_TxConfirmation(PduIdType ComTxPduId) {\r
265         PDU_ID_CHECK(ComTxPduId, 0x15);\r
266 \r
267         (void)ComTxPduId; // Nothing to be done. This is just to avoid Lint warning.\r
268 }\r
269 \r
270 \r
271 Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
272 //#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?\r
273         const ComSignal_type * Signal = GET_Signal(SignalGroupId);\r
274         Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Signal->ComIPduHandleId);\r
275         const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
276 \r
277         if (isPduBufferLocked(getPduId(IPdu))) {\r
278                 return COM_BUSY;\r
279         }\r
280 \r
281         // Copy shadow buffer to Ipdu data space\r
282         const ComGroupSignal_type *groupSignal;\r
283         for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
284                 groupSignal = Signal->ComGroupSignal[i];\r
285                 // TODO CopyData\r
286                 // Com_CopyData(IPdu->ComIPduDataPtr, Arc_Signal->Com_Arc_ShadowBuffer,  groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
287                 Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, groupSignal->ComHandleId, Signal->Com_Arc_ShadowBuffer);\r
288         }\r
289 \r
290         // If the signal has an update bit. Set it!\r
291         if (Signal->ComSignalArcUseUpdateBit) {\r
292                 SETBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);\r
293         }\r
294 \r
295         /*\r
296          * If signal has triggered transmit property, trigger a transmission!\r
297          */\r
298         if (Signal->ComTransferProperty == TRIGGERED) {\r
299                 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;\r
300         }\r
301 \r
302         return E_OK;\r
303 }\r
304 \r
305 \r
306 Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {\r
307 //#warning Com_ReceiveSignalGroup should be performed atomically. Should we disable interrupts here?\r
308         const ComSignal_type * Signal = GET_Signal(SignalGroupId);\r
309         const ComIPdu_type *IPdu = GET_IPdu(Signal->ComIPduHandleId);\r
310 \r
311         if (isPduBufferLocked(getPduId(IPdu))) {\r
312                 return COM_BUSY;\r
313         }\r
314         // Copy Ipdu data buffer to shadow buffer.\r
315         const ComGroupSignal_type *groupSignal;\r
316         for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {\r
317                 groupSignal = Signal->ComGroupSignal[i];\r
318                 // TODO: CopyData\r
319                 // Com_CopyData(Arc_Signal->Com_Arc_ShadowBuffer, IPdu->ComIPduDataPtr, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);\r
320                 Com_ReadSignalDataFromPdu(groupSignal->ComHandleId, (void *)Signal->Com_Arc_ShadowBuffer);\r
321         }\r
322 \r
323 \r
324         return E_OK;\r
325 }\r
326 \r
327 void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {\r
328         Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
329 \r
330         // TODO: CopyData\r
331         // Com_CopyData(Arc_GroupSignal->Com_Arc_ShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);\r
332         Com_WriteSignalDataToPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer, 8);\r
333 }\r
334 \r
335 void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {\r
336         Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);\r
337         uint8 pduSize = GET_IPdu(GET_Signal(SignalId)->ComIPduHandleId)->ComIPduSize;\r
338         // TODO: CopyData\r
339         // Com_CopyData(SignalDataPtr, Arc_GroupSignal->Com_Arc_ShadowBuffer, GroupSignal->ComBitSize, 0, GroupSignal->ComBitPosition);\r
340         Com_ReadSignalDataFromPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer,pduSize);\r
341 }\r
342 \r
343 \r
344 \r