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