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 earliestDeadline;
\r
51 uint32 firstTimeout;
\r
53 //lint --e(928) PC-Lint exception Misra 11.4, Must be like this. /tojo
\r
54 uint8 endiannessByte = *(const uint8 *)&endianness_test;
\r
55 if ( endiannessByte == 0xef ) { Com_SystemEndianness = COM_LITTLE_ENDIAN; }
\r
56 else if ( endiannessByte == 0xde ) { Com_SystemEndianness = COM_BIG_ENDIAN; }
\r
58 // No other endianness supported
\r
59 //lint --e(506) PC-Lint exception Misra 13.7, 14.1, Allow boolean to always be false.
\r
63 // Initialize each IPdu
\r
64 //ComIPdu_type *IPdu;
\r
65 //Com_Arc_IPdu_type *Arc_IPdu;
\r
66 const ComSignal_type *Signal;
\r
67 const ComGroupSignal_type *GroupSignal;
\r
68 for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
\r
70 const ComIPdu_type *IPdu = GET_IPdu(i);
\r
71 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(i);
\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 earliest deadline.
\r
88 earliestDeadline = 0xffffffffu;
\r
89 firstTimeout = 0xffffffffu;
\r
91 // Initialize the memory with the default value.
\r
92 if (IPdu->ComIPduDirection == SEND) {
\r
93 memset(Arc_IPdu->ComIPduDataPtr, IPdu->ComTxIPdu.ComTxIPduUnusedAreasDefault, IPdu->ComIPduSize);
\r
96 // For each signal in this PDU.
\r
97 //Arc_IPdu->NComIPduSignalRef = 0;
\r
98 for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL) ; j++) {
\r
99 Signal = IPdu->ComIPduSignalRef[j];
\r
100 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);
\r
102 // If this signal already has been configured this is most likely an error.
\r
103 if (Arc_Signal->ComIPduDataPtr != NULL) {
\r
104 // DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_SIGNAL_CONFIGURATION);
\r
108 // Configure signal deadline monitoring if used.
\r
109 if (Signal->ComTimeoutFactor > 0) {
\r
111 if (Signal->ComSignalArcUseUpdateBit) {
\r
112 // This signal uses an update bit, and hence has its own deadline monitoring.
\r
113 Arc_Signal->Com_Arc_DeadlineCounter = Signal->ComFirstTimeoutFactor; // Configure the deadline counter
\r
114 Arc_Signal->ComTimeoutFactor = Signal->ComTimeoutFactor;
\r
117 // This signal does not use an update bit, and should therefore use per I-PDU deadline monitoring.
\r
118 // Find the earliest deadline for this I-PDU and setup the deadline later.
\r
119 if (earliestDeadline > Signal->ComTimeoutFactor) {
\r
120 earliestDeadline = Signal->ComTimeoutFactor;
\r
122 if (firstTimeout > Signal->ComFirstTimeoutFactor) {
\r
123 firstTimeout = Signal->ComFirstTimeoutFactor;
\r
128 // Increment helper counters
\r
129 //Arc_IPdu->NComIPduSignalRef = j + 1;
\r
131 Arc_Signal->ComIPduDataPtr = Arc_IPdu->ComIPduDataPtr;
\r
132 Arc_Signal->ComIPduHandleId = i;
\r
134 // Clear update bits
\r
135 if (Signal->ComSignalArcUseUpdateBit) {
\r
136 CLEARBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
\r
139 // If this signal is a signal group
\r
140 if (Signal->Com_Arc_IsSignalGroup) {
\r
142 // For each group signal of this signal group.
\r
143 for(uint8 h = 0; Signal->ComGroupSignal[h] != NULL; h++) {
\r
144 GroupSignal = Signal->ComGroupSignal[h];
\r
145 Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(GroupSignal->ComHandleId);
\r
146 // Set pointer to shadow buffer
\r
147 Arc_GroupSignal->Com_Arc_ShadowBuffer = Arc_Signal->Com_Arc_ShadowBuffer;
\r
148 // Initialize group signal data.
\r
149 Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, GroupSignal->ComHandleId, GroupSignal->ComSignalInitValue);
\r
153 // Initialize signal data.
\r
154 Com_WriteSignalDataToPdu(Signal->ComHandleId, Signal->ComSignalInitValue);
\r
158 // Configure per I-PDU based deadline monitoring.
\r
159 for (uint16 j = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[j] != NULL); j++) {
\r
160 Signal = IPdu->ComIPduSignalRef[j];
\r
161 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(Signal->ComHandleId);
\r
163 if ( (Signal->ComTimeoutFactor > 0) && (!Signal->ComSignalArcUseUpdateBit) ) {
\r
164 Arc_Signal->ComTimeoutFactor = earliestDeadline;
\r
165 Arc_Signal->Com_Arc_DeadlineCounter = firstTimeout;
\r
169 for (uint16 i = 0; i < COM_N_IPDUS; i++) {
\r
170 Com_BufferPduState[i].currentPosition = 0;
\r
171 Com_BufferPduState[i].locked = false;
\r
174 // An error occurred.
\r
176 DEBUG(DEBUG_LOW, "--Initialization of COM failed--\n");
\r
177 //DET_REPORTERROR(COM_MODULE_ID, COM_INSTANCE_ID, 0x01, COM_E_INVALID_FILTER_CONFIGURATION);
\r
179 DEBUG(DEBUG_LOW, "--Initialization of COM completed--\n");
\r
184 void Com_DeInit( void ) {
\r
188 void Com_IpduGroupStart(Com_PduGroupIdType IpduGroupId,boolean Initialize) {
\r
189 (void)Initialize; // Nothing to be done. This is just to avoid Lint warning.
\r
190 for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
\r
191 if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
\r
192 Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 1;
\r
197 void Com_IpduGroupStop(Com_PduGroupIdType IpduGroupId) {
\r
198 for (uint16 i = 0; !ComConfig->ComIPdu[i].Com_Arc_EOL; i++) {
\r
199 if (ComConfig->ComIPdu[i].ComIPduGroupRef == IpduGroupId) {
\r
200 Com_Arc_Config.ComIPdu[i].Com_Arc_IpduStarted = 0;
\r
209 * @param RetryInfoPtr not supported
210 * @param TxDataCntPtr
213 BufReq_ReturnType Com_CopyTxData(PduIdType PduId, PduInfoType* PduInfoPtr, RetryInfoType* RetryInfoPtr, PduLengthType* TxDataCntPtr) {
\r
216 BufReq_ReturnType r = BUFREQ_OK;
\r
217 const ComIPdu_type *IPdu = GET_IPdu(PduId);
\r
218 boolean dirOk = ComConfig->ComIPdu[PduId].ComIPduDirection == SEND;
\r
219 boolean sizeOk = IPdu->ComIPduSize >= Com_BufferPduState[PduId].currentPosition + PduInfoPtr->SduLength;
\r
220 if (dirOk && sizeOk) {
\r
221 void* source = GET_ArcIPdu(PduId)->ComIPduDataPtr;
\r
222 memcpy(PduInfoPtr->SduDataPtr,source + Com_BufferPduState[PduId].currentPosition, PduInfoPtr->SduLength);
\r
223 Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
\r
224 *TxDataCntPtr = IPdu->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
\r
228 Irq_Restore(state);
\r
231 BufReq_ReturnType Com_CopyRxData(PduIdType PduId, const PduInfoType* PduInfoPtr, PduLengthType* RxBufferSizePtr) {
\r
234 BufReq_ReturnType r = BUFREQ_OK;
\r
235 uint8 remainingBytes = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
\r
236 boolean sizeOk = remainingBytes >= PduInfoPtr->SduLength;
\r
237 boolean dirOk = GET_IPdu(PduId)->ComIPduDirection == RECEIVE;
\r
238 boolean lockOk = isPduBufferLocked(PduId);
\r
239 if (dirOk && lockOk && sizeOk) {
\r
240 memcpy(GET_ArcIPdu(PduId)->ComIPduDataPtr+Com_BufferPduState[PduId].currentPosition, PduInfoPtr->SduDataPtr, PduInfoPtr->SduLength);
\r
241 Com_BufferPduState[PduId].currentPosition += PduInfoPtr->SduLength;
\r
242 *RxBufferSizePtr = GET_IPdu(PduId)->ComIPduSize - Com_BufferPduState[PduId].currentPosition;
\r
247 Irq_Restore(state);
\r
249 BufReq_ReturnType Com_StartOfReception(PduIdType ComRxPduId, PduLengthType TpSduLength, PduLengthType* RxBufferSizePtr) {
\r
250 PduLengthType ComIPduSize;
\r
253 BufReq_ReturnType r = BUFREQ_OK;
\r
254 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
\r
255 if (Arc_IPdu->Com_Arc_IpduStarted) {
\r
256 if (GET_IPdu(ComRxPduId)->ComIPduDirection == RECEIVE) {
\r
257 if (!Com_BufferPduState[ComRxPduId].locked) {
\r
258 ComIPduSize = GET_IPdu(ComRxPduId)->ComIPduSize;
\r
259 if (ComIPduSize >= TpSduLength) {
\r
260 Com_BufferPduState[ComRxPduId].locked = true;
\r
261 *RxBufferSizePtr = ComIPduSize;
\r
262 Com_BufferPduState[ComRxPduId].locked = true;
\r
273 Irq_Restore(state);
\r