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
25 #include "Com_Arc_Types.h"
\r
27 #include "Com_Internal.h"
\r
28 #include "Com_misc.h"
\r
34 uint8 Com_SendSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {
\r
35 VALIDATE_SIGNAL(SignalId, 0x0a, E_NOT_OK);
\r
36 // Store pointer to signal for easier coding.
\r
37 const ComSignal_type * Signal = GET_Signal(SignalId);
\r
38 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalId);
\r
39 const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);
\r
40 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);
\r
42 //DEBUG(DEBUG_LOW, "Com_SendSignal: id %d, nBytes %d, BitPosition %d, intVal %d\n", SignalId, nBytes, signal->ComBitPosition, (uint32)*(uint8 *)SignalDataPtr);
\r
45 // Com_CopyData(Arc_IPdu->ComIPduDataPtr, dataPtr, Signal->ComBitSize, Signal->ComBitPosition, 0);
\r
46 Com_WriteSignalDataToPdu(Signal->ComHandleId, SignalDataPtr);
\r
48 // If the signal has an update bit. Set it!
\r
49 if (Signal->ComSignalArcUseUpdateBit) {
\r
50 SETBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
\r
54 * If signal has triggered transmit property, trigger a transmission!
\r
56 if (Signal->ComTransferProperty == TRIGGERED) {
\r
57 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
\r
62 uint8 Com_ReceiveSignal(Com_SignalIdType SignalId, void* SignalDataPtr) {
\r
63 VALIDATE_SIGNAL(SignalId, 0x0b, E_NOT_OK);
\r
64 DEBUG(DEBUG_LOW, "Com_ReceiveSignal: SignalId %d\n", SignalId);
\r
66 // Com_CopyFromSignal(&ComConfig->ComSignal[SignalId], SignalDataPtr);
\r
67 Com_ReadSignalDataFromPdu(SignalId, SignalDataPtr);
\r
69 //uint16 val = *(uint16 *)SignalDataPtr;
\r
70 //val = bswap16(val);
\r
75 Std_ReturnType Com_TriggerTransmit(PduIdType ComTxPduId, uint8 *SduPtr) {
\r
76 PDU_ID_CHECK(ComTxPduId, 0x13, E_NOT_OK);
\r
78 * COM260: This function must not check the transmission mode of the I-PDU
\r
79 * since it should be possible to use it regardless of the transmission mode.
\r
83 * COM395: This function must override the IPdu callouts used in Com_TriggerIPduTransmit();
\r
85 const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);
\r
86 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);
\r
88 memcpy(SduPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);
\r
93 //lint -esym(904, Com_TriggerIPduSend) //PC-Lint Exception of rule 14.7
\r
94 void Com_TriggerIPduSend(PduIdType ComTxPduId) {
\r
95 PDU_ID_CHECK(ComTxPduId, 0x17);
\r
97 //DEBUG(DEBUG_MEDIUM, "Com_TriggerIPduSend sending IPdu %d... ", ComTxPduId);
\r
98 const ComIPdu_type *IPdu = GET_IPdu(ComTxPduId);
\r
99 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComTxPduId);
\r
101 // Is the IPdu ready for transmission?
\r
102 if (Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer == 0) {
\r
103 //DEBUG(DEBUG_MEDIUM, "success!\n", ComTxPduId);
\r
106 PduInfoType PduInfoPackage = {
\r
107 .SduDataPtr = malloc(IPdu->ComIPduSize),
\r
108 .SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize
\r
110 memcpy((void *)PduInfoPackage.SduDataPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);
\r
113 Com_Arc_Config.OutgoingPdu.SduLength = ComConfig->ComIPdu[ComTxPduId].ComIPduSize;
\r
114 memcpy((void *)Com_Arc_Config.OutgoingPdu.SduDataPtr, Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSize);
\r
115 // Check callout status
\r
116 if (IPdu->ComIPduCallout != NULL) {
\r
117 if (!IPdu->ComIPduCallout(ComTxPduId, Arc_IPdu->ComIPduDataPtr)) {
\r
118 // TODO Report error to DET.
\r
119 // Det_ReportError();
\r
125 if (PduR_ComTransmit(IPdu->ArcIPduOutgoingId, &Com_Arc_Config.OutgoingPdu) == E_OK) {
\r
126 // Clear all update bits for the contained signals
\r
127 for (uint8 i = 0; (IPdu->ComIPduSignalRef != NULL) && (IPdu->ComIPduSignalRef[i] != NULL); i++) {
\r
128 //for (int i = 0; i < Arc_IPdu->NComIPduSignalRef; i++) {
\r
129 if (IPdu->ComIPduSignalRef[i]->ComSignalArcUseUpdateBit) {
\r
130 CLEARBIT(Arc_IPdu->ComIPduDataPtr, IPdu->ComIPduSignalRef[i]->ComUpdateBitPosition);
\r
134 // Free allocted memory.
\r
135 // TODO: Is this the best way to solve this memory problem?
\r
136 //free(PduInfoPackage.SduDataPtr);
\r
138 // Reset miminum delay timer.
\r
139 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduMinimumDelayTimer = IPdu->ComTxIPdu.ComTxIPduMinimumDelayFactor;
\r
142 //DEBUG(DEBUG_MEDIUM, "failed (MDT)!\n", ComTxPduId);
\r
146 //lint -esym(904, Com_RxIndication) //PC-Lint Exception of rule 14.7
\r
147 void Com_RxIndication(PduIdType ComRxPduId, const uint8* SduPtr) {
\r
148 PDU_ID_CHECK(ComRxPduId, 0x14);
\r
150 const ComIPdu_type *IPdu = GET_IPdu(ComRxPduId);
\r
151 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(ComRxPduId);
\r
153 // If Ipdu is stopped
\r
154 if (!Arc_IPdu->Com_Arc_IpduStarted) {
\r
158 // Check callout status
\r
159 if (IPdu->ComIPduCallout != NULL) {
\r
160 if (!IPdu->ComIPduCallout(ComRxPduId, SduPtr)) {
\r
161 // TODO Report error to DET.
\r
162 // Det_ReportError();
\r
168 memcpy(Arc_IPdu->ComIPduDataPtr, SduPtr, IPdu->ComIPduSize);
\r
170 // For each signal.
\r
171 const ComSignal_type *comSignal;
\r
172 for (uint8 i = 0; IPdu->ComIPduSignalRef[i] != NULL; i++) {
\r
173 comSignal = IPdu->ComIPduSignalRef[i];
\r
174 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(comSignal->ComHandleId);
\r
176 // If this signal uses an update bit, then it is only considered if this bit is set.
\r
177 if ( (!comSignal->ComSignalArcUseUpdateBit) ||
\r
178 ( (comSignal->ComSignalArcUseUpdateBit) && (TESTBIT(Arc_IPdu->ComIPduDataPtr, comSignal->ComUpdateBitPosition)) ) ) {
\r
180 if (comSignal->ComTimeoutFactor > 0) { // If reception deadline monitoring is used.
\r
181 // Reset the deadline monitoring timer.
\r
182 Arc_Signal->Com_Arc_DeadlineCounter = comSignal->ComTimeoutFactor;
\r
185 // Check the signal processing mode.
\r
186 if (IPdu->ComIPduSignalProcessing == IMMEDIATE) {
\r
187 // If signal processing mode is IMMEDIATE, notify the signal callback.
\r
188 if (IPdu->ComIPduSignalRef[i]->ComNotification != NULL) {
\r
189 IPdu->ComIPduSignalRef[i]->ComNotification();
\r
193 // Signal processing mode is DEFERRED, mark the signal as updated.
\r
194 Arc_Signal->ComSignalUpdated = 1;
\r
198 DEBUG(DEBUG_LOW, "Com_RxIndication: Ignored signal %d of I-PD %d since its update bit was not set\n", comSignal->ComHandleId, ComRxPduId);
\r
205 void Com_TxConfirmation(PduIdType ComTxPduId) {
\r
206 PDU_ID_CHECK(ComTxPduId, 0x15);
\r
207 (void)ComTxPduId; // Nothing to be done. This is just to avoid Lint warning.
\r
211 Std_ReturnType Com_SendSignalGroup(Com_SignalGroupIdType SignalGroupId) {
\r
212 //#warning Com_SendSignalGroup should be performed atomically. Should we disable interrupts here?
\r
213 const ComSignal_type * Signal = GET_Signal(SignalGroupId);
\r
214 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalGroupId);
\r
215 Com_Arc_IPdu_type *Arc_IPdu = GET_ArcIPdu(Arc_Signal->ComIPduHandleId);
\r
216 const ComIPdu_type *IPdu = GET_IPdu(Arc_Signal->ComIPduHandleId);
\r
219 // Copy shadow buffer to Ipdu data space
\r
220 const ComGroupSignal_type *groupSignal;
\r
221 for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {
\r
222 groupSignal = Signal->ComGroupSignal[i];
\r
224 // Com_CopyData(Arc_IPdu->ComIPduDataPtr, Arc_Signal->Com_Arc_ShadowBuffer, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);
\r
225 Com_WriteGroupSignalDataToPdu(Signal->ComHandleId, groupSignal->ComHandleId, Arc_Signal->Com_Arc_ShadowBuffer);
\r
228 // If the signal has an update bit. Set it!
\r
229 if (Signal->ComSignalArcUseUpdateBit) {
\r
230 SETBIT(Arc_IPdu->ComIPduDataPtr, Signal->ComUpdateBitPosition);
\r
234 * If signal has triggered transmit property, trigger a transmission!
\r
236 if (Signal->ComTransferProperty == TRIGGERED) {
\r
237 Arc_IPdu->Com_Arc_TxIPduTimers.ComTxIPduNumberOfRepetitionsLeft = IPdu->ComTxIPdu.ComTxModeTrue.ComTxModeNumberOfRepetitions + 1;
\r
244 Std_ReturnType Com_ReceiveSignalGroup(Com_SignalGroupIdType SignalGroupId) {
\r
245 //#warning Com_ReceiveSignalGroup should be performed atomically. Should we disable interrupts here?
\r
246 const ComSignal_type * Signal = GET_Signal(SignalGroupId);
\r
247 Com_Arc_Signal_type * Arc_Signal = GET_ArcSignal(SignalGroupId);
\r
249 // Copy Ipdu data buffer to shadow buffer.
\r
250 const ComGroupSignal_type *groupSignal;
\r
251 for (uint8 i = 0; Signal->ComGroupSignal[i] != NULL; i++) {
\r
252 groupSignal = Signal->ComGroupSignal[i];
\r
254 // Com_CopyData(Arc_Signal->Com_Arc_ShadowBuffer, Arc_IPdu->ComIPduDataPtr, groupSignal->ComBitSize, groupSignal->ComBitPosition, groupSignal->ComBitPosition);
\r
255 Com_ReadSignalDataFromPdu(groupSignal->ComHandleId, (void *)Arc_Signal->Com_Arc_ShadowBuffer);
\r
262 void Com_UpdateShadowSignal(Com_SignalIdType SignalId, const void *SignalDataPtr) {
\r
263 Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);
\r
265 // Com_CopyData(Arc_GroupSignal->Com_Arc_ShadowBuffer, SignalDataPtr, GroupSignal->ComBitSize, GroupSignal->ComBitPosition, 0);
\r
266 Com_WriteSignalDataToPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer);
\r
269 void Com_ReceiveShadowSignal(Com_SignalIdType SignalId, void *SignalDataPtr) {
\r
270 Com_Arc_GroupSignal_type *Arc_GroupSignal = GET_ArcGroupSignal(SignalId);
\r
272 // Com_CopyData(SignalDataPtr, Arc_GroupSignal->Com_Arc_ShadowBuffer, GroupSignal->ComBitSize, 0, GroupSignal->ComBitPosition);
\r
273 Com_ReadSignalDataFromPduBuffer(SignalId, TRUE, SignalDataPtr, (void *)Arc_GroupSignal->Com_Arc_ShadowBuffer);
\r