]> rtime.felk.cvut.cz Git - arc.git/blob - communication/Com/Com_misc.c
c433347ddd064c540d6f957d45063a5a940056ee
[arc.git] / communication / Com / Com_misc.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 #include <string.h>\r
20 #include <assert.h>\r
21 \r
22 #include "Com_Arc_Types.h"\r
23 #include "Com.h"\r
24 #include "Com_Internal.h"\r
25 #include "Com_misc.h"\r
26 #include "debug.h"\r
27 #include "Cpu.h"\r
28 \r
29 \r
30 void Com_ReadSignalDataFromPdu(\r
31                         const Com_SignalIdType signalId,\r
32                         void *signalData) {\r
33 \r
34         // Get PDU\r
35         const ComSignal_type * Signal = GET_Signal(signalId);\r
36         uint8 pduSize = GET_IPdu(Signal->ComIPduHandleId)->ComIPduSize;\r
37         // Get data\r
38         Com_ReadSignalDataFromPduBuffer(\r
39                         signalId,\r
40                         FALSE,\r
41                         signalData,\r
42                         GET_IPdu(Signal->ComIPduHandleId)->ComIPduDataPtr,\r
43                         pduSize);\r
44 }\r
45 \r
46 void Com_ReadGroupSignalDataFromPdu(\r
47                 const Com_SignalIdType parentSignalId,\r
48                 const Com_SignalIdType groupSignalId,\r
49                 void *signalData) {\r
50 \r
51         // Get PDU\r
52         const ComSignal_type * Signal = GET_Signal(parentSignalId);\r
53         uint8 pduSize = GET_IPdu(Signal->ComIPduHandleId)->ComIPduSize;\r
54         // Get data\r
55         Com_ReadSignalDataFromPduBuffer(\r
56                         groupSignalId,\r
57                         TRUE,\r
58                         signalData,\r
59                         GET_IPdu(Signal->ComIPduHandleId)->ComIPduDataPtr,\r
60                         pduSize);\r
61 }\r
62 \r
63 void Com_ReadSignalDataFromPduBuffer(\r
64                 const uint16 signalId,\r
65                 const boolean isGroupSignal,\r
66                 void *signalData,\r
67                 const void *pduBuffer,\r
68                 uint8 pduSize) {\r
69 \r
70         Com_SignalType signalType;\r
71         ComSignalEndianess_type signalEndianess;\r
72         uint8 signalLength;\r
73         Com_BitPositionType bitPosition;\r
74         uint8 bitSize;\r
75 \r
76         if (!isGroupSignal) {\r
77                 const ComSignal_type * Signal =  GET_Signal(signalId);\r
78                 signalType = Signal->ComSignalType;\r
79                 signalEndianess = Signal->ComSignalEndianess;\r
80                 signalLength = Signal->ComBitSize / 8;\r
81                 bitPosition = Signal->ComBitPosition;\r
82                 bitSize = Signal->ComBitSize;\r
83         } else {\r
84                 const ComGroupSignal_type *GroupSignal = GET_GroupSignal(signalId);\r
85                 signalType = GroupSignal->ComSignalType;\r
86                 signalEndianess = GroupSignal->ComSignalEndianess;\r
87                 signalLength = GroupSignal->ComBitSize / 8;\r
88                 bitPosition = GroupSignal->ComBitPosition;\r
89                 bitSize = GroupSignal->ComBitSize;\r
90         }\r
91 \r
92         uint8 destSize = SignalTypeToSize(signalType, signalLength);\r
93 \r
94         // Pointer to a byte of the source and dest respectively.\r
95         uint8 *signalDataBytes = (uint8 *)signalData;\r
96         uint8 signalDataBytesArray[8];\r
97         const uint8 *pduBufferBytes = (const uint8 *)pduBuffer + (bitPosition/8);\r
98         Com_BitPositionType startBitOffset = 0;\r
99 \r
100         if (signalEndianess == COM_OPAQUE || signalType == UINT8_N) {\r
101                 // Aligned opaque data -> straight copy\r
102                 memcpy(signalDataBytes, pduBufferBytes, destSize);\r
103 \r
104         } else {\r
105                 // Unaligned data and/or endianness conversion\r
106 \r
107                 if (signalEndianess == COM_LITTLE_ENDIAN) {\r
108                         // Swap source bytes before reading\r
109                         // TODO: Must adapt to larger PDUs!\r
110                         uint8 pduBufferBytes_swap[8];\r
111                         for (uint8 i = 0; i < 8; ++i) {\r
112                                 pduBufferBytes_swap[i] = pduBufferBytes[7 - i];\r
113                         }\r
114                         startBitOffset = intelBitNrToPduOffset(bitPosition%8, bitSize, 64);\r
115                         //lint -save -esym(960,12.5) PC-Lint Exception: OK. PC-Lint Wrong interpretation of MISRA rule 12.5.\r
116                         Com_ReadDataSegment(\r
117                                         signalDataBytesArray, pduBufferBytes_swap, destSize,\r
118                                         startBitOffset, bitSize,\r
119                                         SignalTypeSignedness(signalType));\r
120                         //lint -restore\r
121                 } else {\r
122                         startBitOffset = motorolaBitNrToPduOffset(bitPosition%8);\r
123                         Com_ReadDataSegment(\r
124                                         signalDataBytesArray, pduBufferBytes, destSize,\r
125                                         startBitOffset, bitSize,\r
126                                         SignalTypeSignedness(signalType));\r
127                 }\r
128 \r
129                 if (Com_SystemEndianness == COM_BIG_ENDIAN) {\r
130                         // Straight copy\r
131                         uint8 i;\r
132                         for (i = 0; i < destSize; i++) {\r
133                                 signalDataBytes[i] = signalDataBytesArray[i];\r
134                         }\r
135 \r
136                 } else if (Com_SystemEndianness == COM_LITTLE_ENDIAN) {\r
137                         // Data copy algorithm creates big-endian output data so we swap\r
138                         uint8 i;\r
139                         for (i = 0; i < destSize; i++) {\r
140                                 signalDataBytes[(destSize - 1) - i] = signalDataBytesArray[i];\r
141                         }\r
142                 } else {\r
143                         //lint --e(506) PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.\r
144                         assert(0);\r
145                 }\r
146         }\r
147 }\r
148 \r
149 \r
150 void Com_WriteSignalDataToPdu(\r
151                         const Com_SignalIdType signalId,\r
152                         const void *signalData) {\r
153 \r
154         // Get PDU\r
155         const ComSignal_type *Signal     = GET_Signal(signalId);\r
156         const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);\r
157 \r
158         // Get data\r
159         Com_WriteSignalDataToPduBuffer(\r
160                         signalId,\r
161                         FALSE,\r
162                         signalData,\r
163                         (void *)IPdu->ComIPduDataPtr,\r
164                         IPdu->ComIPduSize);\r
165 }\r
166 \r
167 void Com_WriteGroupSignalDataToPdu(\r
168                 const Com_SignalIdType parentSignalId,\r
169                 const Com_SignalIdType groupSignalId,\r
170                 const void *signalData) {\r
171 \r
172         // Get PDU\r
173         const ComSignal_type *Signal     = GET_Signal(parentSignalId);\r
174         const ComIPdu_type   *IPdu       = GET_IPdu(Signal->ComIPduHandleId);\r
175 \r
176         // Get data\r
177         Com_WriteSignalDataToPduBuffer(\r
178                         groupSignalId,\r
179                         TRUE,\r
180                         signalData,\r
181                         (void *)IPdu->ComIPduDataPtr,\r
182                         IPdu->ComIPduSize);\r
183 }\r
184 \r
185 \r
186 void Com_WriteSignalDataToPduBuffer(\r
187                         const uint16 signalId,\r
188                         const boolean isGroupSignal,\r
189                         const void *signalData,\r
190                         void *pduBuffer,\r
191                         const uint8 pduSize) {\r
192         // TODO: Implement writing little-endian signals\r
193 \r
194         Com_SignalType signalType;\r
195         uint8 signalLength;\r
196         Com_BitPositionType bitPosition;\r
197         uint8 bitSize;\r
198         ComSignalEndianess_type endian;\r
199 \r
200         if (!isGroupSignal) {\r
201                 const ComSignal_type * Signal =  GET_Signal(signalId);\r
202                 signalType = Signal->ComSignalType;\r
203                 signalLength = Signal->ComBitSize / 8;\r
204                 bitPosition = Signal->ComBitPosition;\r
205                 bitSize = Signal->ComBitSize;\r
206                 endian = Signal->ComSignalEndianess;\r
207         } else {\r
208                 const ComGroupSignal_type *GroupSignal = GET_GroupSignal(signalId);\r
209                 signalType = GroupSignal->ComSignalType;\r
210                 signalLength = GroupSignal->ComBitSize / 8;\r
211                 bitPosition = GroupSignal->ComBitPosition;\r
212                 bitSize = GroupSignal->ComBitSize;\r
213                 endian = GroupSignal->ComSignalEndianess;\r
214         }\r
215 \r
216         uint8 signalBufferSize = SignalTypeToSize(signalType, signalLength);\r
217         uint8 pduSignalMask[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
218 \r
219         uint8 signalDataBytesArray[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
220         const uint8 *signalDataBytes = (const uint8 *)signalData;\r
221         if (endian == COM_OPAQUE || signalType == UINT8_N) {\r
222                 //assert(bitPosition % 8 == 0);\r
223                 //assert(bitSize % 8 == 0);\r
224                 uint8 *pduBufferBytes = (uint8 *)pduBuffer;\r
225                 uint8 startFromPduByte = bitPosition / 8;\r
226                 memcpy(pduBufferBytes + startFromPduByte, signalDataBytes, signalLength);\r
227         } else {\r
228                 if (Com_SystemEndianness == COM_BIG_ENDIAN) {\r
229                         // Straight copy\r
230                         uint8 i;\r
231                         for (i = 0; i < signalBufferSize; i++) {\r
232                                 signalDataBytesArray[i] = signalDataBytes[i];\r
233                         }\r
234 \r
235                 } else if (Com_SystemEndianness == COM_LITTLE_ENDIAN) {\r
236                         // Data copy algorithm assumes big-endian input data so we swap\r
237                         uint8 i;\r
238                         for (i = 0; i < signalBufferSize; i++) {\r
239                                 signalDataBytesArray[(signalBufferSize - 1) - i] = signalDataBytes[i];\r
240                         }\r
241                 } else {\r
242                         //lint --e(506) PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.\r
243                         assert(0);\r
244                 }\r
245 \r
246                 if (endian == COM_BIG_ENDIAN) {\r
247                         Com_BitPositionType startBitOffset = motorolaBitNrToPduOffset(bitPosition%8);\r
248                         uint8 pduBufferBytesStraight[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
249 \r
250                         Com_WriteDataSegment(pduBufferBytesStraight, pduSignalMask,\r
251                                         signalDataBytesArray, signalBufferSize, startBitOffset, bitSize);\r
252 \r
253                         // Straight copy into real pdu buffer (with mutex)\r
254                         uint8 *pduBufferBytes = ((uint8 *)pduBuffer)+(bitPosition/8);\r
255                         uint8 i;\r
256                         imask_t irq_state;\r
257                         Irq_Save(irq_state);\r
258                         for (i = 0; i < 8; i++) {\r
259                                 pduBufferBytes[ i ]  &=        ~( pduSignalMask[ i ] );\r
260                                 pduBufferBytes[ i ]  |=  pduBufferBytesStraight[ i ];\r
261                         }\r
262                         Irq_Restore(irq_state);\r
263 \r
264                 } else {\r
265                         uint8 startBitOffset = intelBitNrToPduOffset(bitPosition%8, bitSize, 64);\r
266                         uint8 pduBufferBytesSwapped[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
267 \r
268                         Com_WriteDataSegment(pduBufferBytesSwapped, pduSignalMask,\r
269                                         signalDataBytesArray, signalBufferSize, startBitOffset, bitSize);\r
270 \r
271                         // Swapped copy into real pdu buffer (with mutex)\r
272                         uint8 *pduBufferBytes = ((uint8 *)pduBuffer)+(bitPosition/8);\r
273                         uint8 i;\r
274                         imask_t irq_state;\r
275                         Irq_Save(irq_state);\r
276                         // actually it is only necessary to iterate through the bytes that are written.\r
277                         for (i = 0; i < 8; i++) {\r
278                                 pduBufferBytes[ i ]  &=       ~( pduSignalMask[ (8 - 1) - i ] );\r
279                                 pduBufferBytes[ i ]  |=  pduBufferBytesSwapped[ (8 - 1) - i ];\r
280                         }\r
281                         Irq_Restore(irq_state);\r
282                 }\r
283         }\r
284 }\r
285 \r
286 \r
287 /*\r
288  * Read an arbitrary signal segment from buffer.\r
289  * dest:                   pointer to start of destination buffer\r
290  * source:                 pointer to start of source buffer\r
291  * destByteLength:         size of destination buffer in bytes\r
292  * segmentStartBitOffset:  bit offset to signal segment (from first bit in *source data)\r
293  * segmentBitLength:       length in bits of the signal segment to be read\r
294  *\r
295  * Example:\r
296  *    Source data: (ABC... = signal segment)\r
297  *    | -----ABC | DEFGHIJK | LMNOPQ-- |\r
298  *         B0         B1         B2\r
299  *  Parameters:\r
300  *    dest:                  pointer to 32 bit space (needs to be at least 3 bytes to keep the 17 signal bits)\r
301  *    destByteLength:          4\r
302  *    source:                *B0\r
303  *    segmentStartBitOffset:   5\r
304  *    segmentBitLength:       17\r
305  *\r
306  *  Result:\r
307  *    Destination:\r
308  *    | -------- | -------A | BCDEFGHI | JKLMNOPQ |\r
309  *\r
310  */\r
311 void Com_ReadDataSegment(uint8 *dest, const uint8 *source, uint8 destByteLength,\r
312                 Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength, boolean signedOutput) {\r
313 \r
314         Com_BitPositionType sourceEndBitOffset = segmentStartBitOffset + segmentBitLength - 1;\r
315         Com_BitPositionType sourceStartByte = segmentStartBitOffset / 8;\r
316         uint8 sourceEndByte = (sourceEndBitOffset) / 8;\r
317         uint8 sourceByteLength = sourceEndByte - sourceStartByte;\r
318 \r
319         uint8 segmentStartBitOffsetInsideByte = segmentStartBitOffset % 8;\r
320         uint16 sourceStartByteMask;\r
321 \r
322         uint8 sourceAlignmentShift = 7 - (sourceEndBitOffset % 8);\r
323         uint8 segmentByteLength = 1 + (segmentBitLength - 1) / 8;\r
324         uint8 sourceByteNr = 0;\r
325         uint8 destByteNr = 0;\r
326 \r
327         uint16 shiftReg = 0;\r
328 \r
329         boolean negative;\r
330 \r
331         if ( signedOutput && (*(source + sourceStartByte) & (0x80u >> segmentStartBitOffsetInsideByte)) ) {\r
332                 negative = TRUE;\r
333                 sourceStartByteMask = (0xFF00u >> segmentStartBitOffsetInsideByte);\r
334                 memset(dest, 0xFF, destByteLength);\r
335         } else {\r
336                 negative = FALSE;\r
337                 sourceStartByteMask = (0x00FFu >> segmentStartBitOffsetInsideByte);\r
338                 memset(dest, 0x00u, destByteLength);\r
339         }\r
340 \r
341         // setup to point to end (LSB) of buffers\r
342         source += sourceEndByte;\r
343         dest += destByteLength - 1;\r
344 \r
345         if (negative) {\r
346         // compiles and writes one destination byte on each iteration\r
347                 do {\r
348                         shiftReg = *(source - sourceByteNr) | 0xFF00u;          // read source byte (already matching "byte space")\r
349                         if (sourceByteNr == sourceByteLength) {                         // if we are on the last source byte..\r
350                                 shiftReg |= sourceStartByteMask;                        // ..we need to mask out stuff we don't want\r
351                         }\r
352                         shiftReg >>= sourceAlignmentShift;                                      // shift down to align\r
353                         *(dest - destByteNr) &= shiftReg | 0xFF00u;             // write into destination byte\r
354 \r
355                         sourceByteNr++;                                                                         // move to next source byte\r
356                         if ( (sourceAlignmentShift != 0)                                                // do we have more bits for current dest. byte in this source byte?\r
357                                         && (sourceByteNr <= sourceByteLength) ) {\r
358                                 shiftReg = *(source - sourceByteNr) | 0xFF00u;  // read next source byte\r
359                                 if (sourceByteNr == sourceByteLength) {                 // if we are on the last source byte..\r
360                                         shiftReg |= sourceStartByteMask;                // ..we need to mask out stuff we don't want\r
361                                 }\r
362                                 shiftReg = (uint16)~(shiftReg);                                         // shifting inverted to shift in 1:s\r
363                                 shiftReg <<= 8;                                                         // shift up (to match destination "byte space")\r
364                                 shiftReg = (uint16)~shiftReg;\r
365                                 shiftReg >>= sourceAlignmentShift;                              // shift down to align\r
366                                 *(dest - destByteNr) &= shiftReg | 0xFF00u;     // write into destination byte\r
367                         }\r
368                         destByteNr++;\r
369                 } while (destByteNr < segmentByteLength);\r
370         } else { // positive\r
371                 do {\r
372                         shiftReg = *(source - sourceByteNr) & 0x00FFu;          // read source byte (already matching "byte space")\r
373                         if (sourceByteNr == sourceByteLength) {                         // if we are on the last source byte..\r
374                                 shiftReg &= sourceStartByteMask;                        // ..we need to mask out stuff we don't want\r
375                         }\r
376                         shiftReg >>= sourceAlignmentShift;                                      // shift down to align\r
377                         *(dest - destByteNr) |= shiftReg & 0x00FFu;             // write into destination byte\r
378 \r
379                         sourceByteNr++;                                                                         // move to next source byte\r
380                         if (sourceAlignmentShift != 0                                           // do we have more bits for current dest. byte in this source byte?\r
381                                         && sourceByteNr <= sourceByteLength) {\r
382                                 shiftReg = *(source - sourceByteNr) & 0x00FFu;  // read next source byte\r
383                                 if (sourceByteNr == sourceByteLength) {                 // if we are on the last source byte..\r
384                                         shiftReg &= sourceStartByteMask;                // ..we need to mask out stuff we don't want\r
385                                 }\r
386                                 shiftReg <<= 8;                                                         // shift up (to match destination "byte space")\r
387                                 shiftReg >>= sourceAlignmentShift;                              // shift down to align\r
388                                 *(dest - destByteNr) |= shiftReg & 0x00FFu;     // write into destination byte\r
389                         }\r
390                         destByteNr++;\r
391                 } while (destByteNr < segmentByteLength);\r
392         }\r
393 }\r
394 \r
395 /*\r
396  * Copies the <segmentBitLength> least significant bits from <signal> into <pdu>.\r
397  * The bit segment is placed in <pdu> so that the most significant bit ends up\r
398  * at <segmentStartBitOffset> from the msb of <pdu>.\r
399  * <pduSignalMask> is cleared and written to contain a mask with 1´s where the\r
400  * signal is located in the <pdu>.\r
401  */\r
402 void Com_WriteDataSegment(uint8 *pdu, uint8 *pduSignalMask, const uint8 *signalDataPtr, uint8 destByteLength,\r
403                 Com_BitPositionType segmentStartBitOffset, uint8 segmentBitLength) {\r
404         Com_BitPositionType pduEndBitOffset = segmentStartBitOffset + segmentBitLength - 1;\r
405         uint8 pduStartByte = segmentStartBitOffset / 8;\r
406         uint8 pduEndByte = (pduEndBitOffset) / 8;\r
407         uint8 pduByteLength = pduEndByte - pduStartByte;\r
408 \r
409         uint8 segmentStartBitOffsetInsideByte = segmentStartBitOffset % 8;\r
410         uint8 pduStartByteMask = (0xFFu >> segmentStartBitOffsetInsideByte);\r
411 \r
412         uint8 pduAlignmentShift = 7 - (pduEndBitOffset % 8);\r
413         uint8 segmentByteLength = 1 + (segmentBitLength - 1) / 8;\r
414         uint8 pduByteNr = 0;\r
415         uint8 signalByteNr = 0;\r
416 \r
417         uint16 shiftReg = 0;\r
418         uint16 clearReg = 0;\r
419 \r
420         // clear pduSignalMask all the way from 0\r
421         memset(pduSignalMask, 0x00, pduEndByte);\r
422 \r
423         // setup to point to end (LSB) of buffers\r
424         pdu           += pduEndByte;\r
425         pduSignalMask += pduEndByte;\r
426 \r
427         signalDataPtr += destByteLength - 1;\r
428 \r
429         // splits and writes one source byte on each iteration\r
430         do {\r
431                 shiftReg = *(signalDataPtr - signalByteNr) & 0x00FFu;\r
432                 clearReg = 0x00FF;\r
433                 //lint -save -e701 -e734 //PC-Lint Wrong interpretation of MISRA rule 10.5.\r
434                 shiftReg <<= pduAlignmentShift;\r
435                 clearReg <<= pduAlignmentShift;\r
436                 //lint -restore\r
437                 if (pduByteNr == pduByteLength) {\r
438                         shiftReg &= pduStartByteMask;\r
439                         clearReg &= pduStartByteMask;\r
440                 }\r
441                 *(pdu           - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
442                 *(pduSignalMask - pduByteNr) |= (uint16) (clearReg & 0x00FFu);\r
443                 *(pdu           - pduByteNr) |= shiftReg & 0x00FFu;\r
444 \r
445                 pduByteNr++;\r
446                 if ( (pduAlignmentShift != 0)\r
447                                 && (pduByteNr <= pduByteLength) ) {\r
448                         shiftReg = *(signalDataPtr - signalByteNr) & 0x00FFu;\r
449                         clearReg = 0x00FF;\r
450                         //lint -save -e701 -e734 //PC-Lint Wrong interpretation of MISRA rule 10.5.\r
451                         shiftReg <<= pduAlignmentShift;\r
452                         clearReg <<= pduAlignmentShift;\r
453                         shiftReg >>= 8;\r
454                         clearReg >>= 8;\r
455                         //lint -restore\r
456                         if (pduByteNr == pduByteLength) {\r
457                                 shiftReg &= pduStartByteMask;\r
458                                 clearReg &= pduStartByteMask;\r
459                         }\r
460                         *(pdu           - pduByteNr) &= (uint16)~(clearReg & 0x00FFu);\r
461                         *(pduSignalMask - pduByteNr) |= (uint16) (clearReg & 0x00FFu);\r
462                         *(pdu           - pduByteNr) |= shiftReg & 0x00FFu;\r
463                 }\r
464                 signalByteNr++;\r
465         } while (signalByteNr < segmentByteLength);\r
466 }\r
467 \r
468 /*\r
469  * Converts from motorola CAN bit nr to PDU bit offset\r
470  *\r
471  *             motorolaBitNr:  7  6  5  4  3  2  1  0 15 14 13 12 ...\r
472  *  motorolaBitNrToPduOffset:  0  1  2  3  4  5  6  7  8  9 10 11 ...\r
473  */\r
474 Com_BitPositionType motorolaBitNrToPduOffset (Com_BitPositionType motorolaBitNr) {\r
475         uint8 byte = motorolaBitNr / 8;\r
476         Com_BitPositionType offsetToByteStart = (Com_BitPositionType) (byte * 8u);\r
477         Com_BitPositionType offsetInsideByte = motorolaBitNr % 8;\r
478         return (Com_BitPositionType) (offsetToByteStart + (7u - offsetInsideByte));\r
479 }\r
480 \r
481 /*\r
482  * Converts from intel CAN bit nr to PDU bit offset\r
483  *\r
484  *                        pduNumBits: 40\r
485  *  intelBitNr (after PDU byte-swap): 39 38 37 36 35 34 33 32 31 ...  3  2  1  0\r
486  *             intelBitNrToPduOffset:  0  1  2  3  4  5  6  7  8 ... 36 37 38 39\r
487  */\r
488 Com_BitPositionType intelBitNrToPduOffset (Com_BitPositionType intelBitNr, Com_BitPositionType segmentBitLength, Com_BitPositionType pduBitLength) {\r
489         return pduBitLength - (intelBitNr + segmentBitLength);\r
490 }\r
491 \r
492 void Com_RxProcessSignals(const ComIPdu_type *IPdu,Com_Arc_IPdu_type *Arc_IPdu) {\r
493         const ComSignal_type *comSignal;\r
494         for (uint8 i = 0; IPdu->ComIPduSignalRef[i] != NULL; i++) {\r
495                 comSignal = IPdu->ComIPduSignalRef[i];\r
496                 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(comSignal->ComHandleId);\r
497 \r
498                 // If this signal uses an update bit, then it is only considered if this bit is set.\r
499                 if ( (!comSignal->ComSignalArcUseUpdateBit) ||\r
500                         ( (comSignal->ComSignalArcUseUpdateBit) && (TESTBIT(IPdu->ComIPduDataPtr, comSignal->ComUpdateBitPosition)) ) ) {\r
501 \r
502                         if (comSignal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.\r
503                                 // Reset the deadline monitoring timer.\r
504                                 Arc_Signal->Com_Arc_DeadlineCounter = comSignal->ComTimeoutFactor;\r
505                         }\r
506 \r
507                         // Check the signal processing mode.\r
508                         if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {\r
509                                 // If signal processing mode is IMMEDIATE, notify the signal callback.\r
510                                 if (IPdu->ComIPduSignalRef[i]->ComNotification != NULL) {\r
511                                         IPdu->ComIPduSignalRef[i]->ComNotification();\r
512                                 }\r
513 \r
514                         } else {\r
515                                 // Signal processing mode is DEFERRED, mark the signal as updated.\r
516                                 Arc_Signal->ComSignalUpdated = 1;\r
517                         }\r
518 \r
519                 } else {\r
520                         DEBUG(DEBUG_LOW, "Com_RxIndication: Ignored signal %d of I-PD %d since its update bit was not set\n", comSignal->ComHandleId, ComRxPduId);\r
521                 }\r
522         }\r
523 }\r
524 void UnlockTpBuffer(PduIdType PduId) {\r
525         Com_BufferPduState[PduId].locked = false;\r
526         Com_BufferPduState[PduId].currentPosition = 0;\r
527 }\r
528 \r
529 boolean isPduBufferLocked(PduIdType id) {\r
530         imask_t state;\r
531         Irq_Save(state);\r
532         boolean bufferLocked = Com_BufferPduState[id].locked;\r
533         Irq_Restore(state);\r
534         if (bufferLocked) {\r
535                 return true;\r
536         } else {\r
537                 return false;\r
538         }\r
539 }\r
540 PduIdType getPduId(const ComIPdu_type* IPdu) {\r
541         return (PduIdType)(IPdu - (ComConfig->ComIPdu));\r
542 }\r