1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
25 #include "Com_Com.h"
\r
29 #include "PduR_Com.h"
\r
30 #include "Byteorder.h"
\r
32 uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {
\r
33 COM_VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);
\r
34 // Store pointer to signal for easier coding.
\r
35 ComGetSignal(SignalId);
\r
36 ComGetEcoreSignal(SignalId);
\r
37 ComGetIPdu(EcoreSignal->ComIPduHandleId);
\r
38 ComGetEcoreIPdu(EcoreSignal->ComIPduHandleId);
\r
40 //DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);
\r
42 void *dataPtr = (void *)SignalDataPtr;
\r
44 if (Signal->ComSignalEndianess == BIG_ENDIAN) {
\r
45 if (Signal->ComSignalType == UINT16) {
\r
47 memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
48 data = bswap16(data);
\r
51 } else if (Signal->ComSignalType == UINT32) {
\r
53 memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
54 data = bswap32(data);
\r
57 } else if (Signal->ComSignalType == SINT16) {
\r
59 memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
60 data = bswap16(data);
\r
63 } else if (Signal->ComSignalType == SINT32) {
\r
65 memcpy(&data, SignalDataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
66 data = bswap32(data);
\r
72 Com_CopyData(EcoreIPdu->ComIPduDataPtr, dataPtr, Signal->ComBitSize, Signal->ComBitPosition, 0);
\r
74 // If the signal has an update bit. Set it!
\r
75 if (Signal->ComSignalEcoreUseUpdateBit) {
\r
76 setBit(EcoreIPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
\r
80 * If signal has triggered transmit property, trigger a transmission!
\r
82 if (Signal->ComTransferProperty == TRIGGERED) {
\r
83 EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
\r
88 uint8 Com_ReceiveSignal(Com_SignalIdType SignalId, void* SignalDataPtr) {
\r
89 ComGetSignal(SignalId);
\r
90 COM_VALIDATE_SIGNAL(SignalId, 0x0b, E_NOT_OK);
\r
91 DEBUG(DEBUG_LOW, "Com_ReceiveSignal: SignalId %d\n", SignalId);
\r
93 Com_CopyFromSignal(&ComConfig->ComSignal[SignalId], SignalDataPtr);
\r
95 if (Signal->ComSignalEndianess == BIG_ENDIAN) {
\r
96 if (Signal->ComSignalType == UINT16) {
\r
97 *(uint16*)SignalDataPtr = bswap16(*(uint16*)SignalDataPtr);
\r
98 //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
100 } else if (Signal->ComSignalType == UINT32) {
\r
101 *(uint32*)SignalDataPtr = bswap32(*(uint32*)SignalDataPtr);
\r
102 //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
104 } else if (Signal->ComSignalType == SINT16) {
\r
105 *(sint16*)SignalDataPtr = bswap16(*(sint16*)SignalDataPtr);
\r
106 //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
108 } else if (Signal->ComSignalType == SINT32) {
\r
109 *(sint32*)SignalDataPtr = bswap32(*(sint32*)SignalDataPtr);
\r
110 //memcpy(SignalDataPtr, dataPtr, SignalTypeToSize(Signal->ComSignalType,Signal->ComSignalLength));
\r
116 //uint16 val = *(uint16 *)SignalDataPtr;
\r
117 //val = bswap16(val);
\r
122 Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, uint8 *SduPtr) {
\r
123 PduIdCheck(ComTxPduId, 0x13, E_NOT_OK);
\r
125 * COM260: This function must not check the transmission mode of the I-PDU
\r
126 * since it should be possible to use it regardless of the transmission mode.
\r
130 * COM395: This function must override the IPdu callouts used in Com_TriggerIPduTransmit();
\r
132 ComGetIPdu(ComTxPduId);
\r
133 ComGetEcoreIPdu(ComTxPduId);
\r
135 memcpy(SduPtr, EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSize);
\r
140 void Com_TriggerIPduSend(PduIdType ComTxPduId) {
\r
141 PduIdCheck(ComTxPduId, 0x17);
\r
143 //DEBUG(DEBUG_MEDIUM, "Com_TriggerIPduSend sending IPdu %d... ", ComTxPduId);
\r
144 ComGetIPdu(ComTxPduId);
\r
145 ComGetEcoreIPdu(ComTxPduId);
\r
147 // Is the IPdu ready for transmission?
\r
148 if (EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduMinimumDelayTimer == 0) {
\r
149 //DEBUG(DEBUG_MEDIUM, "success!\n", ComTxPduId);
\r
152 PduInfoType PduInfoPackage = {
\r
153 .SduDataPtr = malloc(IPdu->ComIPduSize),
\r
154 .SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize
\r
156 memcpy((void *)PduInfoPackage.SduDataPtr, EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSize);
\r
159 ComEcoreConfig.OutgoingPdu.SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize;
\r
160 memcpy((void *)ComEcoreConfig.OutgoingPdu.SduDataPtr, EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSize);
\r
161 // Check callout status
\r
162 if (IPdu->ComIPduCallout != NULL) {
\r
163 if (!IPdu->ComIPduCallout(ComTxPduId, EcoreIPdu->ComIPduDataPtr)) {
\r
164 // TODO Report error to DET.
\r
165 // Det_ReportError();
\r
171 if (PduR_ComTransmit(ComTxPduId, &ComEcoreConfig.OutgoingPdu) == E_OK) {
\r
172 // Clear all update bits for the contained signals
\r
173 for (int i = 0; i < EcoreIPdu->NComIPduSignalRef; i++) {
\r
174 if (IPdu->ComIPduSignalRef[i]->ComSignalEcoreUseUpdateBit) {
\r
175 clearBit(EcoreIPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);
\r
179 // Free allocted memory.
\r
180 // TODO: Is this the best way to solve this memory problem?
\r
181 //free(PduInfoPackage.SduDataPtr);
\r
183 // Reset miminum delay timer.
\r
184 EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;
\r
187 //DEBUG(DEBUG_MEDIUM, "failed (MDT)!\n", ComTxPduId);
\r
191 Std_ReturnType Com_RxIndication(PduIdType ComRxPduId, const uint8* SduPtr) {
\r
192 PduIdCheck(ComRxPduId, 0x14, E_NOT_OK);
\r
194 ComGetIPdu(ComRxPduId);
\r
195 ComGetEcoreIPdu(ComRxPduId);
\r
197 // If Ipdu is stopped
\r
198 if (!EcoreIPdu->ComEcoreIpduStarted) {
\r
202 // Check callout status
\r
203 if (IPdu->ComIPduCallout != NULL) {
\r
204 if (!IPdu->ComIPduCallout(ComRxPduId, SduPtr)) {
\r
205 // TODO Report error to DET.
\r
206 // Det_ReportError();
\r
212 memcpy(EcoreIPdu->ComIPduDataPtr, SduPtr, IPdu->ComIPduSize);
\r
214 // For each signal.
\r
215 const ComSignal_type *signal;
\r
216 for (int i = 0; IPdu->ComIPduSignalRef[i] != NULL; i++) {
\r
217 signal = IPdu->ComIPduSignalRef[i];
\r
218 ComGetEcoreSignal(signal->ComHandleId);
\r
220 // If this signal uses an update bit, then it is only considered if this bit is set.
\r
221 if (!signal->ComSignalEcoreUseUpdateBit ||
\r
222 (signal->ComSignalEcoreUseUpdateBit && testBit(EcoreIPdu->ComIPduDataPtr, signal->ComUpdateBitPosition))) {
\r
224 if (signal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.
\r
225 // Reset the deadline monitoring timer.
\r
226 EcoreSignal->ComEcoreDeadlineCounter = signal->ComTimeoutFactor;
\r
230 // Zero new filter value.
\r
231 IPdu->ComIPduSignalRef[i]->ComFilter.ComFilterEcoreNewValue = 0;
\r
234 Com_CopyFromSignal(IPdu->ComIPduSignalRef[i], &IPdu->ComIPduSignalRef[i]->ComFilter.ComFilterEcoreNewValue);
\r
236 // Perform filtering
\r
237 //if (Com_Filter(IPdu->ComIPduSignalRef[i])) {
\r
239 // Check the signal processing mode.
\r
240 if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {
\r
241 // If signal processing mode is IMMEDIATE, notify the signal callback.
\r
242 if (IPdu->ComIPduSignalRef[i]->ComNotification != NULL) {
\r
243 IPdu->ComIPduSignalRef[i]->ComNotification();
\r
247 // Signal processing mode is DEFERRED, mark the signal as updated.
\r
248 EcoreSignal->ComSignalUpdated = 1;
\r
252 DEBUG(DEBUG_LOW, "Com_RxIndication: Ignored signal %d of I-PDU %d since its update bit was not set\n", signal->ComHandleId, IPdu->ComIPduRxHandleId);
\r
259 void Com_TxConfirmation(PduIdType ComTxPduId) {
\r
260 PduIdCheck(ComTxPduId, 0x15);
\r
264 Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {
\r
265 //#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?
\r
266 ComGetSignal(SignalGroupId);
\r
267 ComGetEcoreSignal(SignalGroupId);
\r
268 ComGetEcoreIPdu(EcoreSignal->ComIPduHandleId);
\r
269 ComGetIPdu(EcoreSignal->ComIPduHandleId);
\r
272 // Copy shadow buffer to Ipdu data space
\r
273 const ComGroupSignal_type *groupSignal;
\r
274 for (int i = 0; Signal->ComGroupSignal[i] != NULL; i++) {
\r
275 groupSignal = Signal->ComGroupSignal[i];
\r
276 Com_CopyData(EcoreIPdu->ComIPduDataPtr, EcoreSignal->ComEcoreShadowBuffer, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);
\r
279 // If the signal has an update bit. Set it!
\r
280 if (Signal->ComSignalEcoreUseUpdateBit) {
\r
281 setBit(EcoreIPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
\r
285 * If signal has triggered transmit property, trigger a transmission!
\r
287 if (Signal->ComTransferProperty == TRIGGERED) {
\r
288 EcoreIPdu->ComEcoreTxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
\r
295 Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {
\r
296 //#warning Com_ReceiveSignalGroup should be performed atomically. Should we disable interrupts here?
\r
297 ComGetSignal(SignalGroupId);
\r
298 ComGetEcoreSignal(SignalGroupId);
\r
299 ComGetEcoreIPdu(EcoreSignal->ComIPduHandleId);
\r
301 // Copy Ipdu data buffer to shadow buffer.
\r
302 const ComGroupSignal_type *groupSignal;
\r
303 for (int i = 0; Signal->ComGroupSignal[i] != NULL; i++) {
\r
304 groupSignal = Signal->ComGroupSignal[i];
\r
305 Com_CopyData(EcoreSignal->ComEcoreShadowBuffer, EcoreIPdu->ComIPduDataPtr, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);
\r
312 void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {
\r
313 ComGetGroupSignal(SignalId);
\r
314 ComGetEcoreGroupSignal(SignalId);
\r
315 Com_CopyData(EcoreGroupSignal->ComEcoreShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);
\r
318 void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {
\r
319 ComGetGroupSignal(SignalId);
\r
320 ComGetEcoreGroupSignal(SignalId);
\r
321 Com_CopyData(SignalDataPtr, EcoreGroupSignal->ComEcoreShadowBuffer, GroupSignal->ComBitSize, 0, GroupSignal->ComBitPosition);
\r