1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
17 //lint -esym(960,8.7) PC-Lint misunderstanding of Misra 8.7 for Com_SystenEndianness and endianess_test
\r
25 //#include <stdio.h>
\r
28 #include "Com_Arc_Types.h"
\r
29 #include "Com_Internal.h"
\r
30 #include "Com_misc.h"
\r
35 /* TODO: Better way to get endianness across all compilers? */
\r
36 static const uint32_t endianness_test = 0xdeadbeefU;
\r
37 ComSignalEndianess_type Com_SystemEndianness;
\r
40 const Com_ConfigType * ComConfig;
\r
43 void Com_Init(const Com_ConfigType *config ) {
\r
44 DEBUG(DEBUG_LOW, "--Initialization of COM--\n");
\r
50 uint32 firstTimeout;
\r
52 //lint --e(928) PC-Lint exception Misra 11.4, Must be like this. /tojo
\r
53 uint8 endiannessByte = *(const uint8 *)&endianness_test;
\r
54 if ( endiannessByte == 0xef ) { Com_SystemEndianness = COM_LITTLE_ENDIAN; }
\r
55 else if ( endiannessByte == 0xde ) { Com_SystemEndianness = COM_BIG_ENDIAN; }
\r
57 // No other endianness supported
\r
58 //lint --e(506) PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.
\r
62 // Initialize each IPdu
\r
63 //ComIPdu_type *IPdu;
\r
64 //Com_Arc_IPdu_type *Arc_IPdu;
\r
65 const ComSignal_type *Signal;
\r
66 const ComGroupSignal_type *GroupSignal;
\r
67 for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
\r
69 const ComIPdu_type *IPdu = GET_IPdu(i);
\r
70 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);
\r
71 Arc_IPdu->Com_Arc_DynSignalLength = 0;
\r
73 if (i >= COM_N_IPDUS) {
\r
74 DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_TOO_MANY_IPDU);
\r
79 // If this is a TX and cyclic IPdu, configure the first deadline.
\r
80 if ( (IPdu->ComIPduDirection == SEND) &&
\r
81 ( (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == PERIODIC) || (IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeMode == MIXED) )) {
\r
82 //IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
\r
83 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxModeTimePeriodTimer = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeTimeOffsetFactor;
\r
87 // Reset firstTimeout.
\r
88 firstTimeout = 0xffffffffu;
\r
90 // Initialize the memory with the default value.
\r
91 if (IPdu->ComIPduDirection == SEND) {
\r
92 memset((void *)IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);
\r
95 // For each signal in this PDU.
\r
96 //Arc_IPdu->NComIPduSignalRef = 0;
\r
97 for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL) ; j++) {
\r
98 Signal = IPdu->ComIPduSignalRef[j];
\r
99 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);
\r
101 // Configure signal deadline monitoring if used.
\r
102 if (Signal->ComTimeoutFactor > 0) {
\r
104 if (Signal->ComSignalArcUseUpdateBit) {
\r
105 // This signal uses an update bit, and hence has its own deadline monitoring.
\r
106 Arc_Signal->Com_Arc_DeadlineCounter = Signal->ComFirstTimeoutFactor; // Configure the deadline counter
\r
109 // This signal does not use an update bit, and should therefore use per I-PDU deadline monitoring.
\r
110 if (firstTimeout > Signal->ComFirstTimeoutFactor) {
\r
111 firstTimeout = Signal->ComFirstTimeoutFactor;
\r
116 // Clear update bits
\r
117 if (Signal->ComSignalArcUseUpdateBit) {
\r
118 CLEARBIT(IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
\r
121 // If this signal is a signal group
\r
122 if (Signal->Com_Arc_IsSignalGroup) {
\r
124 // For each group signal of this signal group.
\r
125 for(uint8 h = 0; Signal->ComGroupSignal[h] != NULL; h++) {
\r
126 GroupSignal = Signal->ComGroupSignal[h];
\r
127 Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(GroupSignal->ComHandleId);
\r
128 // Set pointer to shadow buffer
\r
129 Arc_GroupSignal->Com_Arc_ShadowBuffer = (void *)Signal->Com_Arc_ShadowBuffer;
\r
130 // Initialize group signal data.
\r
131 Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, GroupSignal->ComHandleId, GroupSignal->ComSignalInitValue);
\r
135 // Initialize signal data.
\r
136 Com_WriteSignalDataToPdu(Signal->ComHandleId, Signal->ComSignalInitValue);
\r
140 // Configure per I-PDU based deadline monitoring.
\r
141 for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL); j++) {
\r
142 Signal = IPdu->ComIPduSignalRef[j];
\r
143 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);
\r
145 if ( (Signal->ComTimeoutFactor > 0) && (!Signal->ComSignalArcUseUpdateBit) ) {
\r
146 Arc_Signal->Com_Arc_DeadlineCounter = firstTimeout;
\r
150 for (uint16 i = 0; i < COM_N_IPDUS; i++) {
\r
151 Com_BufferPduState[i].currentPosition = 0;
\r
152 Com_BufferPduState[i].locked = false;
\r
155 // An error occurred.
\r
157 DEBUG(DEBUG_LOW, "--Initialization of COM failed--\n");
\r
158 //DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_FILTER_CONFIGURATION);
\r
160 DEBUG(DEBUG_LOW, "--Initialization of COM completed--\n");
\r
165 void Com_DeInit( void ) {
\r
169 void Com_IpduGroupStart(Com_PduGroupIdType IpduGroupId,boolean Initialize) {
\r
170 (void)Initialize; // Nothing to be done. This is just to avoid Lint warning.
\r
171 for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
\r
172 if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
\r
173 Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 1;
\r
179 void Com_IpduGroupStop(Com_PduGroupIdType IpduGroupId) {
\r
180 for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
\r
181 if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
\r
182 Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 0;
\r
192 * @param RetryInfoPtr not supported
193 * @param TxDataCntPtr
196 BufReq_ReturnType Com_CopyTxData(PduIdType PduId, PduInfoType* PduInfoPtr, RetryInfoType* RetryInfoPtr, PduLengthType* TxDataCntPtr) {
\r
198 BufReq_ReturnType r = BUFREQ_OK;
\r
199 const ComIPdu_type *IPdu = GET_IPdu(PduId);
\r
200 boolean dirOk = ComConfig->ComIPdu[PduId].ComIPduDirection == SEND;
\r
205 sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;
\r
206 Com_BufferPduState[PduId].locked = true;
\r
207 if (dirOk && sizeOk) {
\r
208 void* source = (void *)IPdu->ComIPduDataPtr;
\r
209 memcpy(PduInfoPtr->SduDataPtr,source + Com_BufferPduState[PduId].currentPosition, PduInfoPtr->SduLength);
\r
210 Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
\r
211 *TxDataCntPtr = IPdu->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
\r
215 Irq_Restore(state);
\r
218 BufReq_ReturnType Com_CopyRxData(PduIdType PduId, const PduInfoType* PduInfoPtr, PduLengthType* RxBufferSizePtr) {
\r
220 BufReq_ReturnType r = BUFREQ_OK;
\r
221 uint8 remainingBytes;
\r
228 remainingBytes = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
\r
229 sizeOk = remainingBytes >= PduInfoPtr->SduLength;
\r
230 dirOk = GET_IPdu(PduId)->ComIPduDirection == RECEIVE;
\r
231 lockOk = isPduBufferLocked(PduId);
\r
232 if (dirOk && lockOk && sizeOk) {
\r
233 memcpy((void *)(GET_IPdu(PduId)->ComIPduDataPtr+Com_BufferPduState[PduId].currentPosition), PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength);
\r
234 Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
\r
235 *RxBufferSizePtr = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
\r
239 Irq_Restore(state);
\r
243 static void Com_SetDynSignalLength(PduIdType ComRxPduId,PduLengthType TpSduLength) {
\r
244 const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);
\r
245 if (IPdu->ComIPduDynSignalRef == 0) {
\r
248 const ComSignal_type * const dynSignal = IPdu->ComIPduDynSignalRef;
\r
249 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
\r
250 Arc_IPdu->Com_Arc_DynSignalLength = TpSduLength - (dynSignal->ComBitPosition/8);
\r
254 BufReq_ReturnType Com_StartOfReception(PduIdType ComRxPduId, PduLengthType TpSduLength, PduLengthType* RxBufferSizePtr) {
\r
255 PduLengthType ComIPduSize;
\r
257 BufReq_ReturnType r = BUFREQ_OK;
\r
258 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
\r
261 if (Arc_IPdu->Com_Arc_IpduStarted) {
\r
262 if (GET_IPdu(ComRxPduId)->ComIPduDirection == RECEIVE) {
\r
263 if (!Com_BufferPduState[ComRxPduId].locked) {
\r
264 ComIPduSize = GET_IPdu(ComRxPduId)->ComIPduSize;
\r
265 if (ComIPduSize >= TpSduLength) {
\r
266 Com_BufferPduState[ComRxPduId].locked = true;
\r
267 *RxBufferSizePtr = ComIPduSize;
\r
268 Com_SetDynSignalLength(ComRxPduId,TpSduLength);
\r
279 Irq_Restore(state);
\r