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
24 * General requirements
\r
27 /** @req CANTP001 */
\r
28 /** @req CANTP019 */
\r
29 /** @req CANTP020 */
\r
30 /** @req CANTP156.Partially */
\r
31 /** @req CANTP150 */
\r
32 /** @req CANTP151 */
\r
33 /** @req CANTP152 */
\r
34 /** @req CANTP153 */
\r
35 /** @req CANTP155 */
\r
36 /** @req CANTP158 */
\r
37 /** @req CANTP003 */
\r
38 /** @req CANTP216 */
\r
39 /** @req CANTP217 */
\r
42 * Environmental requirements
44 /** @req CANTP164 */
\r
45 /** @req CANTP199 */
\r
48 #include "CanTp.h" /** @req CANTP219 */
\r
49 #include "CanTp_Cbk.h" /** @req CANTP233 */
\r
52 #include "SchM_CanTp.h"
\r
53 #include "PduR_CanTp.h"
\r
54 //#include "MemMap.h"
\r
56 //#define USE_DEBUG_PRINTF
\r
59 #define CANTP_IMMEDIATE_TX_CONFIRMATION STD_OFF
\r
61 #if ( CANTP_DEV_ERROR_DETECT == STD_ON ) /** @req CANTP006 *//** @req CANTP134 */
\r
63 /** @req CANTP132 */ /** @req CANTP021 */
\r
64 #define VALIDATE(_exp,_api,_err ) \
\r
66 Det_ReportError(MODULE_ID_CANTP, 0, _api, _err); \
\r
69 /** @req CANTP132 */ /** @req CANTP021 */
\r
70 #define VALIDATE_NO_RV(_exp,_api,_err ) \
\r
72 Det_ReportError(MODULE_ID_CANTP, 0, _api, _err); \
\r
75 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)
\r
78 #define VALIDATE(_exp,_api,_err )
\r
79 #define VALIDATE_NO_RV(_exp,_api,_err )
\r
80 #define DET_REPORTERROR(_x,_y,_z,_q)
\r
86 NotifResultType PduR_CanTpRxIndication(PduIdType CanTpRxPduId,
\r
87 NotifResultType Result) {
\r
92 BufReq_ReturnType PduR_CanTpProvideRxBuffer(PduIdType id, PduLengthType length,
\r
93 PduInfoType **PduInfoPtr) {
\r
97 BufReq_ReturnType PduR_CanTpProvideTxBuffer(PduIdType CanTpTxId,
\r
98 PduInfoType** PduinfoPtr, uint16 Length) {
\r
102 void PduR_CanTpTxConfirmation(PduIdType CanTpTxPduId, NotifResultType Result) {
\r
110 #define INLINE inline
\r
112 #define TIMER_DECREMENT(timer) \
\r
114 timer = timer - 1; \
\r
117 #define COUNT_DECREMENT(timer) \
\r
119 timer = timer - 1; \
\r
123 #define CANTP_ERR -1
\r
124 #define ISO15765_FLOW_CONTROL_STATUS_CTS 0
\r
125 #define ISO15765_FLOW_CONTROL_STATUS_WAIT 1
\r
126 #define ISO15765_FLOW_CONTROL_STATUS_OVFLW 2
\r
128 // - - - - - - - - - - - - - -
\r
130 #define ISO15765_TPCI_MASK 0x30
\r
131 #define ISO15765_TPCI_SF 0x00 /* Single Frame */
\r
132 #define ISO15765_TPCI_FF 0x10 /* First Frame */
\r
133 #define ISO15765_TPCI_CF 0x20 /* Consecutive Frame */
\r
134 #define ISO15765_TPCI_FC 0x30 /* Flow Control */
\r
135 #define ISO15765_TPCI_DL 0x7 /* Single frame data length mask */
\r
136 #define ISO15765_TPCI_FS_MASK 0x0F /* Flowcontrol status mask */
\r
138 // - - - - - - - - - - - - - -
\r
140 #define MAX_PAYLOAD_SF_STD_ADDR 7
\r
141 #define MAX_PAYLOAD_SF_EXT_ADDR 6
\r
143 #define MAX_PAYLOAD_FF_STD_ADDR 6
\r
144 #define MAX_PAYLOAD_FF_EXT_ADDR 5
\r
146 #define MAX_PAYLOAD_CF_STD_ADDR 7
\r
147 #define MAX_PAYLOAD_CF_EXT_ADDR 6
\r
149 #define SEGMENT_NUMBER_MASK 0x0f
\r
151 #define MAX_SEGMENT_DATA_SIZE 8 // Size of a CAN frame data bytes.
\r
157 UNINITIALIZED, IDLE, SF_OR_FF_RECEIVED_WAITING_PDUR_BUFFER, /** @req CANTP079 */
\r
158 RX_WAIT_CONSECUTIVE_FRAME, RX_WAIT_SDU_BUFFER,
\r
160 TX_WAIT_CAN_TP_TRANSMIT_CAN_TP_PROVIDE_TX_BUFFER, /** @req CANTP226 */
\r
161 TX_WAIT_CAN_TP_TRANSMIT_PENDING, /* CanTP_Transmit was called but no buffer was received (BUSY). */
\r
162 TX_WAIT_SEND_CONSECUTIVE_FRAME, TX_WAIT_FLOW_CONTROL,
\r
163 TX_WAIT_TX_CONFIRMATION
\r
164 } ISO15765TransferStateTypes;
\r
167 INVALID_FRAME, /* Not specified by ISO15765 - used as error return type when decoding frame. */
\r
168 SINGLE_FRAME, FIRST_FRAME, CONSECUTIVE_FRAME, FLOW_CONTROL_CTS_FRAME, /* Clear to send */
\r
169 FLOW_CONTROL_WAIT_FRAME, FLOW_CONTROL_OVERFLOW_FRAME
\r
170 } ISO15765FrameType;
\r
173 SEND_NEXT_CONSECUTIVE_FRAME, WAIT_FLOW_CONTROL, TRANSFER_FINISHED
\r
174 } ISO15765TxStateTypes;
\r
177 * In case no buffer is available at some cases the data needs to be
\r
178 * temporarly stored away.
\r
182 uint8 data[MAX_SEGMENT_DATA_SIZE];
\r
183 PduLengthType byteCount;
\r
187 * Structure that is keeping track on the run-time variables for the ongoing
\r
191 uint16 nextFlowControlCount; // Count down to next Flow Control.
\r
192 uint16 framesHandledCount; // Counter keeping track total frames handled.
\r
193 uint8 extendedAddress; // Not always used but need to be available.
\r
194 uint32 stateTimeoutCount; // Counter for timeout.
\r
195 uint8 STmin; // In case we are transmitters the remote node can configure this value (only valid for TX).
\r
196 uint8 BS; // Blocksize (only valid for TX).
\r
197 boolean NasNarPending;
\r
198 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
199 boolean txConfirmed;
\r
201 uint32 NasNarTimeoutCount; // CanTpNas, CanTpNar.
\r
202 ISO15765TransferStateTypes state; // Transfer state machine. TODO: Can this be initialized here?
\r
203 } ISO15765TransferControlType;
\r
206 * Container for TX or RX runtime paramters (TX/RX are identical?)
\r
209 ISO15765TransferControlType iso15765;
\r
210 PduInfoType *pdurBuffer; // The PDUR make an instance of this.
\r
211 PduLengthType pdurBufferCount; // Number of bytes in PDUR buffer.
\r
212 PduLengthType transferTotal; // Total length of the PDU.
\r
213 PduLengthType transferCount; // Counter ongoing transfer.
\r
214 CanIfSduType canFrameBuffer; // Temp storage of SDU data.
\r
215 CanTp_TransferInstanceMode mode; // CanTp030.
\r
216 } CanTp_ChannelPrivateType;
\r
219 #define CANIF_PDU_MAX_LENGTH 0x08 // Max length is 8 (it is CAN dlc=8).
\r
223 uint8 SduData[CANIF_PDU_MAX_LENGTH];
\r
224 PduLengthType SduLength;
\r
225 } CanTpFifoQueueItem;
\r
227 #define FIFO_QUEUE_DEPTH 10
\r
230 int fifoQueueReadIndex;
\r
231 int fifoQueueWriteIndex;
\r
232 CanTpFifoQueueItem queueList[FIFO_QUEUE_DEPTH];
\r
235 // - - - - - - - - - - - - - -
\r
240 CanTp_StateType internalState; /** @req CANTP027 */
\r
241 CanTp_ChannelPrivateType runtimeDataList[CANTP_NSDU_RUNTIME_LIST_SIZE];
\r
242 } CanTp_RunTimeDataType;
\r
244 // - - - - - - - - - - - - - -
\r
246 CanTp_RunTimeDataType CanTpRunTimeData = { .initRun = FALSE,
\r
247 .internalState = CANTP_OFF }; /** @req CANTP168 */
\r
249 static INLINE void fifoQueueInit( CanTpFifo *fifoQueue ) {
\r
250 fifoQueue->fifoQueueReadIndex = 0;
\r
251 fifoQueue->fifoQueueWriteIndex = 0;
\r
254 // - - - - - - - - - - - - - -
\r
256 static INLINE boolean fifoQueueRead( CanTpFifo *fifoQueue, CanTpFifoQueueItem *item ) {
\r
257 boolean ret = FALSE;
\r
259 readIndex = fifoQueue->fifoQueueReadIndex;
\r
260 if ( fifoQueue->fifoQueueReadIndex != fifoQueue->fifoQueueWriteIndex ) {
\r
262 if (++readIndex == FIFO_QUEUE_DEPTH) {
\r
265 item->PduId = fifoQueue->queueList[fifoQueue->fifoQueueReadIndex].PduId;
\r
266 item->SduLength = fifoQueue->queueList[fifoQueue->fifoQueueReadIndex].SduLength;
\r
267 for (int i=0; i<item->SduLength; i++) {
\r
268 item->SduData[i] = fifoQueue->queueList[fifoQueue->fifoQueueReadIndex].SduData[i];
\r
270 fifoQueue->fifoQueueReadIndex = readIndex;
\r
278 // - - - - - - - - - - - - - -
\r
280 static INLINE boolean fifoQueueWrite( CanTpFifo *fifoQueue, CanTpFifoQueueItem *item ) {
\r
281 boolean ret = FALSE;
\r
283 writeIndex = fifoQueue->fifoQueueWriteIndex;
\r
284 if (++writeIndex == FIFO_QUEUE_DEPTH) {
\r
287 if ( writeIndex != fifoQueue->fifoQueueReadIndex ) { // Check if space left.
\r
288 fifoQueue->queueList[fifoQueue->fifoQueueWriteIndex].PduId = item->PduId;
\r
289 fifoQueue->queueList[fifoQueue->fifoQueueWriteIndex].SduLength = item->SduLength;
\r
290 for (int i=0; i<item->SduLength;i++) {
\r
291 fifoQueue->queueList[fifoQueue->fifoQueueWriteIndex].SduData[i] = item->SduData[i];
\r
293 fifoQueue->fifoQueueWriteIndex = writeIndex;
\r
299 // - - - - - - - - - - - - - -
\r
301 static inline ISO15765FrameType getFrameType(
\r
302 const CanTp_AddressingFormantType *formatType,
\r
303 const PduInfoType *CanTpRxPduPtr) {
\r
304 ISO15765FrameType res = INVALID_FRAME;
\r
307 switch (*formatType) {
\r
308 case CANTP_STANDARD:
\r
309 DEBUG( DEBUG_MEDIUM, "CANTP_STANDARD\n");
\r
310 tpci = CanTpRxPduPtr->SduDataPtr[0];
\r
312 case CANTP_EXTENDED:
\r
313 DEBUG( DEBUG_MEDIUM, "CANTP_EXTENDED\n");
\r
314 tpci = CanTpRxPduPtr->SduDataPtr[1];
\r
320 switch (tpci & ISO15765_TPCI_MASK) {
\r
321 case ISO15765_TPCI_SF:
\r
322 res = SINGLE_FRAME;
\r
324 case ISO15765_TPCI_FF:
\r
327 case ISO15765_TPCI_CF:
\r
328 res = CONSECUTIVE_FRAME;
\r
330 case ISO15765_TPCI_FC: // Some kind of flow control.
\r
331 switch (tpci & ISO15765_TPCI_FS_MASK) {
\r
332 case ISO15765_FLOW_CONTROL_STATUS_CTS:
\r
333 res = FLOW_CONTROL_CTS_FRAME;
\r
335 case ISO15765_FLOW_CONTROL_STATUS_WAIT:
\r
336 res = FLOW_CONTROL_CTS_FRAME;
\r
338 case ISO15765_FLOW_CONTROL_STATUS_OVFLW:
\r
339 res = FLOW_CONTROL_CTS_FRAME;
\r
346 // - - - - - - - - - - - - - -
\r
348 static inline PduLengthType getPduLength(
\r
349 const CanTp_AddressingFormantType *formatType,
\r
350 const ISO15765FrameType iso15765Frame, const PduInfoType *CanTpRxPduPtr) {
\r
351 PduLengthType res = 0;
\r
352 uint8 tpci_offset = 0;
\r
354 switch (*formatType) {
\r
355 case CANTP_STANDARD:
\r
358 case CANTP_EXTENDED:
\r
365 switch (iso15765Frame) {
\r
367 // Parse the data length from the single frame header.
\r
368 res = CanTpRxPduPtr->SduDataPtr[tpci_offset] & ISO15765_TPCI_DL;
\r
371 // Parse the data length form the first frame.
\r
372 res = CanTpRxPduPtr->SduDataPtr[tpci_offset + 1] + ((PduLengthType)((CanTpRxPduPtr->SduDataPtr[tpci_offset]) & 0xf) << 8);
\r
375 res = 0; // TODO: maybe we should have an error code here.
\r
381 // - - - - - - - - - - - - - -
\r
383 static void initRx15765RuntimeData(const CanTp_RxNSduType *rxConfigParams,
\r
384 CanTp_ChannelPrivateType *rxRuntimeParams) {
\r
386 rxRuntimeParams->iso15765.state = IDLE;
\r
387 rxRuntimeParams->iso15765.NasNarPending = FALSE;
\r
388 rxRuntimeParams->iso15765.framesHandledCount = 0;
\r
389 rxRuntimeParams->iso15765.nextFlowControlCount = 0;
\r
390 rxRuntimeParams->pdurBufferCount = 0;
\r
391 rxRuntimeParams->transferTotal = 0;
\r
392 rxRuntimeParams->transferCount = 0;
\r
393 rxRuntimeParams->mode = CANTP_RX_WAIT; /** @req CANTP030 */
\r
394 rxRuntimeParams->pdurBuffer = NULL;
\r
397 // - - - - - - - - - - - - - -
\r
399 static void initTx15765RuntimeData(const CanTp_TxNSduType *txConfigParams,
\r
400 CanTp_ChannelPrivateType *txRuntimeParams) {
\r
402 txRuntimeParams->iso15765.state = IDLE;
\r
403 txRuntimeParams->iso15765.NasNarPending = FALSE;
\r
404 txRuntimeParams->iso15765.framesHandledCount = 0;
\r
405 txRuntimeParams->iso15765.nextFlowControlCount = 0;
\r
406 txRuntimeParams->pdurBufferCount = 0;
\r
407 txRuntimeParams->transferTotal = 0;
\r
408 txRuntimeParams->transferCount = 0;
\r
409 txRuntimeParams->mode = CANTP_TX_WAIT; /** @req CANTP030 */
\r
410 txRuntimeParams->pdurBuffer = NULL;
\r
414 // - - - - - - - - - - - - - -
\r
416 static INLINE BufReq_ReturnType copySegmentToPduRRxBuffer(const CanTp_RxNSduType *rxConfig,
\r
417 CanTp_ChannelPrivateType *rxRuntime, uint8 *segment,
\r
418 PduLengthType segmentSize, PduLengthType *bytesWrittenSuccessfully) {
\r
420 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
421 boolean endLoop = FALSE;
\r
422 *bytesWrittenSuccessfully = 0;
\r
424 while ((*bytesWrittenSuccessfully < segmentSize) && (!endLoop)) {
\r
425 // Copy the data that resides in the buffer.
\r
426 if (rxRuntime->pdurBuffer != NULL) {
\r
427 while ((*bytesWrittenSuccessfully < segmentSize ) && (rxRuntime->pdurBuffer->SduLength > rxRuntime->pdurBufferCount)) {
\r
428 rxRuntime->pdurBuffer->SduDataPtr[rxRuntime->pdurBufferCount++] = segment[(*bytesWrittenSuccessfully)++];
\r
431 if (*bytesWrittenSuccessfully < segmentSize ) {
\r
432 // We need to request a new buffer from the SDUR.
\r
433 // TODO: We should do a timeout here.
\r
434 ret = PduR_CanTpProvideRxBuffer(rxConfig->PduR_PduId, rxRuntime->transferTotal, &rxRuntime->pdurBuffer); /** @req CANTP079 */ /** @req CANTP080 */ /** @req CANTP064 */
\r
435 if (ret == BUFREQ_OK) {
\r
436 VALIDATE( rxRuntime->pdurBuffer->SduDataPtr != NULL,
\r
437 SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_RX_BUFFER );
\r
438 rxRuntime->pdurBufferCount = 0; // The buffer is emptied.
\r
439 } else if (ret == BUFREQ_BUSY) {
\r
440 rxRuntime->transferCount += *bytesWrittenSuccessfully;
\r
443 endLoop = TRUE; // Let calling function handle this error.
\r
446 rxRuntime->transferCount += segmentSize; //== bytesWrittenSuccessfully
\r
454 // - - - - - - - - - - - - - -
\r
456 static INLINE boolean copySegmentToLocalRxBuffer /*writeDataSegmentToLocalBuffer*/(
\r
457 CanTp_ChannelPrivateType *rxRuntime, uint8 *segment,
\r
458 PduLengthType segmentSize) {
\r
459 boolean ret = FALSE;
\r
461 if ( segmentSize < MAX_SEGMENT_DATA_SIZE ) {
\r
462 for (int i=0; i < segmentSize; i++) {
\r
463 rxRuntime->canFrameBuffer.data[i] = segment[i];
\r
465 rxRuntime->canFrameBuffer.byteCount = segmentSize;
\r
471 // - - - - - - - - - - - - - -
\r
473 static INLINE Std_ReturnType canReceivePaddingHelper(
\r
474 const CanTp_RxNSduType *rxConfig, CanTp_ChannelPrivateType *rxRuntime,
\r
475 PduInfoType *PduInfoPtr) {
\r
476 if (rxConfig->CanTpRxPaddingActivation == CANTP_ON) {
\r
477 for (int i = PduInfoPtr->SduLength; i < CANIF_PDU_MAX_LENGTH; i++) {
\r
478 PduInfoPtr->SduDataPtr[i] = 0x0; // TODO: Does it have to be padded with zeroes?
\r
480 PduInfoPtr->SduLength = CANIF_PDU_MAX_LENGTH;
\r
482 rxRuntime->iso15765.NasNarTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNar); /** @req CANTP075 */
\r
483 rxRuntime->iso15765.NasNarPending = TRUE;
\r
484 return CanIf_Transmit(rxConfig->CanIf_FcPduId, PduInfoPtr);
\r
487 // - - - - - - - - - - - - - -
\r
489 static INLINE Std_ReturnType canTansmitPaddingHelper(
\r
490 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime,
\r
491 PduInfoType *PduInfoPtr) {
\r
493 /** @req CANTP114 */
\r
494 /** @req CANTP040 */
\r
495 /** @req CANTP098 */
\r
496 /** @req CANTP116 */
\r
497 /** @req CANTP059 */
\r
499 if (txConfig->CanTpTxPaddingActivation == CANTP_ON) { /** @req CANTP225 */
\r
500 for (int i = PduInfoPtr->SduLength; i < CANIF_PDU_MAX_LENGTH; i++) {
\r
501 PduInfoPtr->SduDataPtr[i] = 0x0; // TODO: Does it have to be padded with zeroes?
\r
503 PduInfoPtr->SduLength = CANIF_PDU_MAX_LENGTH;
\r
505 txRuntime->iso15765.NasNarTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNas); /** @req CANTP075 */
\r
506 txRuntime->iso15765.NasNarPending = TRUE;
\r
507 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
508 txRuntime->iso15765.txConfirmed = FALSE;
\r
510 return CanIf_Transmit(txConfig->CanIf_PduId, PduInfoPtr);
\r
513 // - - - - - - - - - - - - - -
\r
515 static INLINE void sendFlowControlFrame(const CanTp_RxNSduType *rxConfig, CanTp_ChannelPrivateType *rxRuntime, BufReq_ReturnType flowStatus) {
\r
516 uint8 indexCount = 0;
\r
517 Std_ReturnType ret = E_NOT_OK;
\r
518 PduInfoType pduInfo;
\r
519 uint8 sduData[8]; // Note that buffer in declared on the stack.
\r
520 uint16 spaceFreePduRBuffer = 0;
\r
521 uint16 computedBs = 0;
\r
523 DEBUG( DEBUG_MEDIUM, "sendFlowControlFrame called!\n");
\r
524 pduInfo.SduDataPtr = &sduData[0];
\r
525 if (rxConfig->CanTpAddressingFormant == CANTP_EXTENDED) {
\r
526 sduData[indexCount++] = rxRuntime->iso15765.extendedAddress;
\r
528 switch (flowStatus) {
\r
531 sduData[indexCount++] = ISO15765_TPCI_FC | ISO15765_FLOW_CONTROL_STATUS_CTS;
\r
532 spaceFreePduRBuffer = rxRuntime->pdurBuffer->SduLength - rxRuntime->pdurBufferCount;
\r
533 if (rxConfig->CanTpAddressingFormant == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
534 computedBs = (spaceFreePduRBuffer / MAX_PAYLOAD_SF_EXT_ADDR) + 1; // + 1 is for local buffer.
\r
536 computedBs = (spaceFreePduRBuffer / MAX_PAYLOAD_SF_STD_ADDR) + 1; // + 1 is for local buffer.
\r
538 if (computedBs > rxConfig->CanTpBs) { // /** @req CANTP091 *//** @req CANTP084 */
\r
539 computedBs = rxConfig->CanTpBs;
\r
541 DEBUG( DEBUG_MEDIUM, "computedBs:%d\n", computedBs);
\r
542 sduData[indexCount++] = computedBs; // 734 PC-lint: Okej att casta till uint8?
\r
543 sduData[indexCount++] = (uint8) rxConfig->CanTpSTmin;
\r
544 rxRuntime->iso15765.nextFlowControlCount = computedBs;
\r
545 pduInfo.SduLength = indexCount;
\r
548 case BUFREQ_NOT_OK:
\r
551 sduData[indexCount++] = ISO15765_TPCI_FC | ISO15765_FLOW_CONTROL_STATUS_WAIT;
\r
552 pduInfo.SduLength = indexCount;
\r
554 case BUFREQ_OVFL: /** @req CANTP081 */
\r
555 sduData[indexCount++] = ISO15765_TPCI_FC | ISO15765_FLOW_CONTROL_STATUS_OVFLW;
\r
556 pduInfo.SduLength = indexCount;
\r
561 ret = canReceivePaddingHelper(rxConfig, rxRuntime, &pduInfo);
\r
563 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP084 */
\r
564 rxRuntime->iso15765.state = IDLE;
\r
565 rxRuntime->mode = CANTP_RX_WAIT;
\r
569 // - - - - - - - - - - - - - -
\r
572 static INLINE void handleConsecutiveFrame(const CanTp_RxNSduType *rxConfig,
\r
573 CanTp_ChannelPrivateType *rxRuntime, const PduInfoType *rxPduData) {
\r
574 uint8 indexCount = 0;
\r
575 uint8 segmentNumber = 0;
\r
576 uint8 extendedAddress = 0;
\r
577 PduLengthType bytesLeftToCopy = 0;
\r
578 PduLengthType bytesLeftToTransfer = 0;
\r
579 PduLengthType currentSegmentSize = 0;
\r
580 PduLengthType currentSegmentMaxSize = 0;
\r
581 PduLengthType bytesCopiedToPdurRxBuffer = 0;
\r
582 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
584 if (rxRuntime->iso15765.state == RX_WAIT_CONSECUTIVE_FRAME) {
\r
585 if (rxConfig->CanTpAddressingFormant == CANTP_EXTENDED) {
\r
586 extendedAddress = rxPduData->SduDataPtr[indexCount++];
\r
588 segmentNumber = rxPduData->SduDataPtr[indexCount++] & SEGMENT_NUMBER_MASK;
\r
589 if (segmentNumber != (rxRuntime->iso15765.framesHandledCount & SEGMENT_NUMBER_MASK)) {
\r
590 DEBUG(DEBUG_MEDIUM,"Segmentation number error detected - is the sending"
\r
591 "unit too fast? Increase STmin (cofig) to slow it down!\n");
\r
592 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_WRONG_SN); /** @req CANTP084 */
\r
593 rxRuntime->iso15765.state = IDLE;
\r
594 rxRuntime->mode = CANTP_RX_WAIT;
\r
596 currentSegmentMaxSize = CANIF_PDU_MAX_LENGTH - indexCount;
\r
597 bytesLeftToCopy = rxRuntime->transferTotal - rxRuntime->transferCount;
\r
598 if (bytesLeftToCopy < currentSegmentMaxSize) {
\r
599 currentSegmentSize = bytesLeftToCopy; // 1-5.
\r
601 currentSegmentSize = currentSegmentMaxSize; // 6 or 7, depends on addressing format used.
\r
603 // Copy received data to buffer provided by SDUR.
\r
604 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime,
\r
605 &rxPduData->SduDataPtr[indexCount],
\r
606 currentSegmentSize,
\r
607 &bytesCopiedToPdurRxBuffer);
\r
608 if (ret == BUFREQ_NOT_OK) {
\r
609 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NO_BUFFER); /** @req CANTP084 */
\r
610 rxRuntime->iso15765.state = IDLE;
\r
611 rxRuntime->mode = CANTP_RX_WAIT;
\r
612 } else if (ret == BUFREQ_BUSY) {
\r
613 boolean dataCopyFailure = FALSE;
\r
614 PduLengthType bytesNotCopiedToPdurRxBuffer = currentSegmentSize - bytesCopiedToPdurRxBuffer;
\r
615 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
616 if ( copySegmentToLocalRxBuffer(rxRuntime, /** @req CANTP067 */
\r
617 &rxPduData->SduDataPtr[1 + bytesCopiedToPdurRxBuffer],
\r
618 bytesNotCopiedToPdurRxBuffer ) != TRUE ) {
\r
619 rxRuntime->iso15765.state = IDLE;
\r
620 rxRuntime->mode = CANTP_RX_WAIT;
\r
621 dataCopyFailure = TRUE;
\r
622 DEBUG( DEBUG_MEDIUM, "Unexpected error, could not copy 'unaligned leftover' " "data to local buffer!\n");
\r
625 if ( copySegmentToLocalRxBuffer(rxRuntime, /** @req CANTP067 */
\r
626 &rxPduData->SduDataPtr[2 + bytesCopiedToPdurRxBuffer],
\r
627 bytesNotCopiedToPdurRxBuffer) != TRUE ) {
\r
628 rxRuntime->iso15765.state = IDLE;
\r
629 rxRuntime->mode = CANTP_RX_WAIT;
\r
630 dataCopyFailure = TRUE;
\r
631 DEBUG( DEBUG_MEDIUM, "Unexpected error, could not copy 'unaligned leftover' " "data to local buffer!\n");
\r
634 if ( !dataCopyFailure ) {
\r
635 rxRuntime->iso15765.framesHandledCount++;
\r
636 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr);
\r
637 rxRuntime->iso15765.state = RX_WAIT_SDU_BUFFER;
\r
638 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
639 sendFlowControlFrame(rxConfig, rxRuntime, ret); /** @req CANTP082 */
\r
641 } else if (ret == BUFREQ_OK) {
\r
642 bytesLeftToTransfer = rxRuntime->transferTotal - rxRuntime->transferCount;
\r
643 if (bytesLeftToTransfer > 0) {
\r
644 rxRuntime->iso15765.framesHandledCount++;
\r
645 COUNT_DECREMENT(rxRuntime->iso15765.nextFlowControlCount);
\r
646 if (rxRuntime->iso15765.nextFlowControlCount == 0) {
\r
647 sendFlowControlFrame(rxConfig, rxRuntime, BUFREQ_OK);
\r
649 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNcr); //UH
\r
652 DEBUG( DEBUG_MEDIUM,"ISO15765-Rx session finished, going back to IDLE!\n");
\r
653 rxRuntime->iso15765.state = IDLE;
\r
654 rxRuntime->mode = CANTP_RX_WAIT;
\r
655 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_OK); /** @req CANTP084 */
\r
660 } // 438, 550 PC-lint: extendedAdress not accessed. Extended adress needs to be implemented. Ticket #136
\r
662 // - - - - - - - - - - - - - -
\r
664 static INLINE Std_ReturnType sendConsecutiveFrame(
\r
665 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime) {
\r
666 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
667 uint8 sduData[CANIF_PDU_MAX_LENGTH];
\r
668 PduLengthType consecutiveFrameMaxPayload = 0;
\r
669 PduLengthType consecutiveFrameActualPayload = 0;
\r
670 PduLengthType remaningSduDataSize = 0;
\r
671 PduInfoType pduInfo;
\r
672 uint16 copyCount = 0;
\r
673 uint16 indexCount = 0;
\r
675 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
676 sduData[indexCount++] = (uint8) txConfig->CanTpNTa->CanTpNTa; // Target address.
\r
678 sduData[indexCount++] = ISO15765_TPCI_CF | (uint8)(
\r
679 (txRuntime->iso15765.framesHandledCount + 1) & ISO15765_TPCI_FS_MASK); // + 1 is because the consecutive frame numbering begins with 1 and not 0.
\r
681 // Always copy from the PDUR buffer data to the canFrameBuffer because if
\r
682 // we are unlucky the application give us very small buffers.
\r
683 consecutiveFrameMaxPayload = CANIF_PDU_MAX_LENGTH - indexCount;
\r
684 remaningSduDataSize = txRuntime->transferTotal - txRuntime->transferCount;
\r
686 // Calculate number of valid bytes that reside in this CF.
\r
687 if ( remaningSduDataSize < consecutiveFrameMaxPayload ) {
\r
688 consecutiveFrameActualPayload = remaningSduDataSize; // Last frame.
\r
690 consecutiveFrameActualPayload = consecutiveFrameMaxPayload;
\r
692 copyCount = txRuntime->canFrameBuffer.byteCount; // maybe some bytes already reside in the local buffer before we proceed asking for more data from application.
\r
693 while (copyCount < consecutiveFrameActualPayload) {
\r
694 if ( txRuntime->pdurBuffer->SduLength > txRuntime->pdurBufferCount ) {
\r
695 txRuntime->canFrameBuffer.data[copyCount] = txRuntime->pdurBuffer->SduDataPtr[txRuntime->pdurBufferCount++];
\r
697 txRuntime->canFrameBuffer.byteCount++;
\r
699 BufReq_ReturnType pdurResp = PduR_CanTpProvideTxBuffer(txConfig->PduR_PduId, &txRuntime->pdurBuffer, 0); /** @req CANTP226 */ /** @req CANTP086 */ /** @req CANTP117 */
\r
700 if (pdurResp == BUFREQ_OK) {
\r
701 txRuntime->pdurBufferCount = 0;
\r
703 } else if (pdurResp == BUFREQ_BUSY) {
\r
704 ret = E_OK; // We will remain in this state, called again later, not data lost/destroyed?
\r
706 /** @req CANTP087 */
\r
707 DEBUG( DEBUG_MEDIUM, "sendConsecutiveFrame failed, no buffer provided!\n");
\r
708 ret = E_NOT_OK; // Serious malfunction, function caller should cancel this transfer.
\r
713 if (copyCount == consecutiveFrameActualPayload) {
\r
714 for (int i=0; i<txRuntime->canFrameBuffer.byteCount; i++) {
\r
715 sduData[indexCount++] = txRuntime->canFrameBuffer.data[i];
\r
717 pduInfo.SduDataPtr = sduData;
\r
718 pduInfo.SduLength = indexCount; // also includes consecutive frame header.
\r
719 ret = canTansmitPaddingHelper(txConfig, txRuntime, &pduInfo);
\r
721 // Now we consider this frame sent and we can not handle
\r
722 // the scenario where the CAN queue is full.
\r
723 txRuntime->iso15765.framesHandledCount++;
\r
724 COUNT_DECREMENT(txRuntime->iso15765.nextFlowControlCount);
\r
725 txRuntime->transferCount += txRuntime->canFrameBuffer.byteCount;
\r
726 txRuntime->canFrameBuffer.byteCount = 0;
\r
727 DEBUG( DEBUG_MEDIUM, "transferCount:%d\n", txRuntime->transferCount);
\r
730 DEBUG( DEBUG_MEDIUM, "Unexpected error, should not happen!\n");
\r
735 // - - - - - - - - - - - - - -
\r
737 static INLINE void handleConsecutiveFrameSent(
\r
738 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime) {
\r
740 if (txRuntime->transferTotal <= txRuntime->transferCount) {
\r
741 // Transfer finished!
\r
742 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
743 txRuntime->iso15765.state = TX_WAIT_TX_CONFIRMATION;
\r
745 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_OK); /** @req CANTP074 *//** @req CANTP09 *//** @req CANTP204 */
\r
746 txRuntime->iso15765.state = IDLE;
\r
747 txRuntime->mode = CANTP_TX_WAIT;
\r
749 } else if (txRuntime->iso15765.nextFlowControlCount == 0) {
\r
750 if (txRuntime->iso15765.BS) { // Check if receiver expects flow control.
\r
751 // Time to send flow control!
\r
752 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNbs); /** @req CANTP264 */
\r
753 txRuntime->iso15765.state = TX_WAIT_FLOW_CONTROL;
\r
755 // Send next consecutive frame!
\r
756 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txRuntime->iso15765.STmin);
\r
757 txRuntime->iso15765.state = TX_WAIT_SEND_CONSECUTIVE_FRAME;
\r
760 // Send next consecutive frame!
\r
761 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txRuntime->iso15765.STmin);
\r
762 txRuntime->iso15765.state = TX_WAIT_SEND_CONSECUTIVE_FRAME;
\r
766 // - - - - - - - - - - - - - -
\r
768 static INLINE void handleFlowControlFrame(const CanTp_TxNSduType *txConfig,
\r
769 CanTp_ChannelPrivateType *txRuntime, const PduInfoType *txPduData) {
\r
770 int indexCount = 0;
\r
771 uint8 extendedAddress = 0;
\r
772 Std_ReturnType ret;
\r
775 if ( txRuntime->iso15765.state == TX_WAIT_FLOW_CONTROL ) {
\r
776 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
777 extendedAddress = txPduData->SduDataPtr[indexCount++];
\r
779 switch (txPduData->SduDataPtr[indexCount++] & ISO15765_TPCI_FS_MASK) {
\r
780 case ISO15765_FLOW_CONTROL_STATUS_CTS:
\r
782 { // This construction is added to make the hcs12 compiler happy.
\r
783 const uint8 bs = txPduData->SduDataPtr[indexCount++];
\r
784 txRuntime->iso15765.BS = bs;
\r
785 txRuntime->iso15765.nextFlowControlCount = bs;
\r
787 txRuntime->iso15765.STmin = txPduData->SduDataPtr[indexCount++];
\r
789 txRuntime->iso15765.BS = txPduData->SduDataPtr[indexCount++];
\r
790 txRuntime->iso15765.nextFlowControlCount = txRuntime->iso15765.BS;
\r
791 txRuntime->iso15765.STmin = txPduData->SduDataPtr[indexCount++];
\r
793 DEBUG( DEBUG_MEDIUM, "txRuntime->iso15765.STmin = %d\n", txRuntime->iso15765.STmin);
\r
794 ret = sendConsecutiveFrame(txConfig, txRuntime);
\r
796 handleConsecutiveFrameSent(txConfig, txRuntime);
\r
798 PduR_CanTpRxIndication(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP177 */ /** @req CANTP084 */
\r
799 txRuntime->iso15765.state = IDLE;
\r
800 txRuntime->mode = CANTP_TX_WAIT;
\r
803 case ISO15765_FLOW_CONTROL_STATUS_WAIT:
\r
804 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNbs); /*CanTp: 264*/
\r
805 txRuntime->iso15765.state = TX_WAIT_FLOW_CONTROL;
\r
807 case ISO15765_FLOW_CONTROL_STATUS_OVFLW:
\r
808 PduR_CanTpRxIndication(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK);
\r
809 txRuntime->iso15765.state = IDLE;
\r
810 txRuntime->mode = CANTP_TX_WAIT;
\r
814 DEBUG( DEBUG_MEDIUM, "Ignoring flow control, we do not expect it!");
\r
816 } // 438, 550 PC-lint: extendAdress används inte. EN BUG? Behöver fixas
\r
819 // - - - - - - - - - - - - - -
\r
821 static INLINE void handleSingleFrame(const CanTp_RxNSduType *rxConfig,
\r
822 CanTp_ChannelPrivateType *rxRuntime, const PduInfoType *rxPduData) {
\r
823 BufReq_ReturnType ret;
\r
824 PduLengthType pduLength;
\r
825 uint8 *data = NULL;
\r
826 PduLengthType bytesWrittenToSduRBuffer;
\r
829 if (rxRuntime->iso15765.state != IDLE) {
\r
830 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NOT_OK); // Abort current reception, we need to tell the current receiver it has been aborted.
\r
831 DEBUG( DEBUG_MEDIUM, "Single frame received and channel not IDLE!\n");
\r
833 (void) initRx15765RuntimeData(rxConfig, rxRuntime); /** @req CANTP124 */
\r
834 pduLength = getPduLength(&rxConfig->CanTpAddressingFormant, SINGLE_FRAME, rxPduData);
\r
836 if (rxRuntime->pdurBuffer != NULL) {
\r
837 VALIDATE_NO_RV( rxRuntime->pdurBuffer->SduDataPtr != NULL,
\r
838 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_INVALID_RX_LENGTH );
\r
841 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) { /** @req CANTP094 *//** @req CANTP095 */
\r
842 data = &rxPduData->SduDataPtr[1];
\r
844 data = &rxPduData->SduDataPtr[2];
\r
846 rxRuntime->transferTotal = pduLength;
\r
847 rxRuntime->iso15765.state = SF_OR_FF_RECEIVED_WAITING_PDUR_BUFFER;
\r
848 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
849 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr); /** @req CANTP166 */
\r
851 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime, data, pduLength, &bytesWrittenToSduRBuffer);
\r
853 if (ret == BUFREQ_OK) {
\r
854 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_OK);
\r
855 rxRuntime->iso15765.state = IDLE;
\r
856 rxRuntime->mode = CANTP_RX_WAIT;
\r
857 } else if (ret == BUFREQ_BUSY) {
\r
858 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
859 data = &rxPduData->SduDataPtr[1];
\r
861 data = &rxPduData->SduDataPtr[2];
\r
863 (void)copySegmentToLocalRxBuffer(rxRuntime, data, pduLength ); /** @req CANTP067 */
\r
864 rxRuntime->iso15765.state = RX_WAIT_SDU_BUFFER;
\r
865 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
867 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NO_BUFFER);
\r
868 rxRuntime->iso15765.state = IDLE;
\r
869 rxRuntime->mode = CANTP_RX_WAIT;
\r
873 // - - - - - - - - - - - - - -
\r
876 static INLINE void handleFirstFrame(const CanTp_RxNSduType *rxConfig,
\r
877 CanTp_ChannelPrivateType *rxRuntime, const PduInfoType *rxPduData) {
\r
878 BufReq_ReturnType ret;
\r
879 PduLengthType pduLength = 0;
\r
880 PduLengthType bytesWrittenToSduRBuffer;
\r
882 if (rxRuntime->iso15765.state != IDLE) {
\r
883 DEBUG( DEBUG_MEDIUM, "First frame received during Rx-session!\n" );
\r
884 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NOT_OK); // Abort current reception, we need to tell the current receiver it has been aborted.
\r
887 (void) initRx15765RuntimeData(rxConfig, rxRuntime); /** @req CANTP124 */
\r
888 pduLength = getPduLength(&rxConfig->CanTpAddressingFormant, FIRST_FRAME,
\r
890 rxRuntime->transferTotal = pduLength;
\r
892 VALIDATE_NO_RV( rxRuntime->transferTotal != 0,
\r
893 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_INVALID_RX_LENGTH );
\r
895 // Validate that that there is a reason for using the segmented transfers and
\r
896 // if not simply skip (single frame should have been used).
\r
897 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) { /** @req CANTP094 *//** @req CANTP095 */
\r
898 if (pduLength <= MAX_PAYLOAD_SF_STD_ADDR){
\r
902 if (pduLength <= MAX_PAYLOAD_SF_EXT_ADDR){
\r
906 // Validate that the SDU is full length in this first frame.
\r
907 if (rxPduData->SduLength < CANIF_PDU_MAX_LENGTH) {
\r
911 rxRuntime->iso15765.framesHandledCount = 1; // Segment count begins with 1 (FirstFrame has the 0).
\r
912 rxRuntime->iso15765.state = SF_OR_FF_RECEIVED_WAITING_PDUR_BUFFER;
\r
913 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
914 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr); /** @req CANTP166 */
\r
916 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
917 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime,
\r
918 &rxPduData->SduDataPtr[2],
\r
919 MAX_PAYLOAD_FF_STD_ADDR,
\r
920 &bytesWrittenToSduRBuffer);
\r
922 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime,
\r
923 &rxPduData->SduDataPtr[3],
\r
924 MAX_PAYLOAD_FF_EXT_ADDR,
\r
925 &bytesWrittenToSduRBuffer);
\r
927 if (ret == BUFREQ_OK) {
\r
928 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNcr);
\r
929 rxRuntime->iso15765.state = RX_WAIT_CONSECUTIVE_FRAME;
\r
930 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
931 sendFlowControlFrame(rxConfig, rxRuntime, ret);
\r
932 } else if (ret == BUFREQ_BUSY) {
\r
933 /** @req CANTP222 */
\r
934 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
935 (void)copySegmentToLocalRxBuffer(rxRuntime, &rxPduData->SduDataPtr[2], MAX_PAYLOAD_FF_STD_ADDR );
\r
937 (void)copySegmentToLocalRxBuffer(rxRuntime, &rxPduData->SduDataPtr[3], MAX_PAYLOAD_FF_EXT_ADDR );
\r
939 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr);
\r
940 rxRuntime->iso15765.state = RX_WAIT_SDU_BUFFER;
\r
941 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
942 sendFlowControlFrame(rxConfig, rxRuntime, ret); /** @req CANTP082 */
\r
943 } else if (ret == BUFREQ_OVFL) {
\r
944 sendFlowControlFrame(rxConfig, rxRuntime, ret); /** @req CANTP081 */
\r
945 rxRuntime->iso15765.state = IDLE;
\r
946 rxRuntime->mode = CANTP_RX_WAIT;
\r
950 // - - - - - - - - - - - - - -
\r
952 static INLINE ISO15765FrameType calcRequiredProtocolFrameType(
\r
953 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime) {
\r
955 ISO15765FrameType ret = INVALID_FRAME;
\r
956 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) {
\r
957 if (txRuntime->transferTotal <= MAX_PAYLOAD_CF_EXT_ADDR) {
\r
958 ret = SINGLE_FRAME;
\r
960 if (txConfig->CanTpTxTaType == CANTP_PHYSICAL) {
\r
963 DET_REPORTERROR( MODULE_ID_CANTP, 0, SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TATYPE );
\r
966 } else { // CANTP_STANDARD
\r
967 if (txRuntime->transferTotal <= MAX_PAYLOAD_CF_STD_ADDR) {
\r
968 ret = SINGLE_FRAME;
\r
970 if (txConfig->CanTpTxTaType == CANTP_PHYSICAL) {
\r
973 DET_REPORTERROR( MODULE_ID_CANTP, 0, SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TATYPE );
\r
981 // - - - - - - - - - - - - - -
\r
984 static INLINE Std_ReturnType sendSingleFrame(const CanTp_TxNSduType *txConfig,
\r
985 CanTp_ChannelPrivateType *txRuntime) {
\r
986 Std_ReturnType ret;
\r
987 uint16 indexCount = 0;
\r
988 PduInfoType pduInfo;
\r
989 uint8 sduData[CANIF_PDU_MAX_LENGTH];
\r
992 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
993 sduData[indexCount++] = (uint8) txConfig->CanTpNTa->CanTpNTa; // Target address.
\r
995 sduData[indexCount++] = ISO15765_TPCI_SF | txRuntime->transferTotal; // 734 PC-lint: Okej att casta till uint8?
\r
996 for (int i = 0; i < txRuntime->transferTotal; i++) {
\r
997 sduData[indexCount++] = txRuntime->pdurBuffer->SduDataPtr[i];
\r
1000 pduInfo.SduDataPtr = sduData;
\r
1001 pduInfo.SduLength = indexCount;
\r
1002 ret = canTansmitPaddingHelper(txConfig, txRuntime, &pduInfo);
\r
1006 // - - - - - - - - - - - - - -
\r
1008 static INLINE Std_ReturnType sendFirstFrame(const CanTp_TxNSduType *txConfig,
\r
1009 CanTp_ChannelPrivateType *txRuntime) {
\r
1010 Std_ReturnType ret;
\r
1011 uint8 indexCount = 0;
\r
1013 PduInfoType pduInfo;
\r
1014 uint8 sduData[CANIF_PDU_MAX_LENGTH];
\r
1016 DEBUG( DEBUG_MEDIUM, "sendFirstFrame called!\n");
\r
1018 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
1019 sduData[indexCount++] = (uint8) txConfig->CanTpNTa->CanTpNTa; // Target address.
\r
1021 sduData[indexCount++] = ISO15765_TPCI_FF | (uint8)(
\r
1022 (txRuntime->transferTotal & 0xf00) >> 8);
\r
1023 sduData[indexCount++] = (uint8)(txRuntime->transferTotal & 0xff);
\r
1024 for (i = 0; indexCount < CANIF_PDU_MAX_LENGTH; i++) {
\r
1025 sduData[indexCount++] = txRuntime->pdurBuffer->SduDataPtr[i];
\r
1026 txRuntime->pdurBufferCount++;
\r
1027 if (txRuntime->pdurBufferCount > txRuntime->pdurBuffer->SduLength) {
\r
1028 // TODO: Report failure - this is unexpected.
\r
1030 txRuntime->transferCount++;
\r
1032 pduInfo.SduDataPtr = sduData;
\r
1033 pduInfo.SduLength = indexCount;
\r
1034 ret = canTansmitPaddingHelper(txConfig, txRuntime, &pduInfo);
\r
1038 // - - - - - - - - - - - - - -
\r
1040 static INLINE BufReq_ReturnType canTpTransmitHelper(const CanTp_TxNSduType *txConfig,
\r
1041 CanTp_ChannelPrivateType *txRuntime) {
\r
1043 BufReq_ReturnType pdurResp = BUFREQ_NOT_OK;
\r
1044 Std_ReturnType res = E_NOT_OK;
\r
1045 ISO15765FrameType iso15765Frame = INVALID_FRAME;
\r
1047 pdurResp = PduR_CanTpProvideTxBuffer(txConfig->PduR_PduId, &txRuntime->pdurBuffer, 0); /** @req CANTP226 */ /** @req CANTP186 */
\r
1048 //if (txRuntime->iso15765.stateTimeoutCount != 0) { TODO: WHY WAS THIS DONE?
\r
1049 VALIDATE( txRuntime->pdurBuffer->SduDataPtr != NULL,
\r
1050 SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TX_BUFFER );
\r
1051 if (pdurResp == BUFREQ_OK) {
\r
1052 iso15765Frame = calcRequiredProtocolFrameType(txConfig, txRuntime);
\r
1053 switch (iso15765Frame) {
\r
1054 case SINGLE_FRAME:
\r
1055 res = sendSingleFrame(txConfig, txRuntime); /** @req CANTP231 */
\r
1056 if (res == E_OK) {
\r
1057 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
1058 txRuntime->iso15765.state = TX_WAIT_TX_CONFIRMATION;
\r
1060 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_OK); /** @req CANTP204 */
\r
1061 txRuntime->iso15765.state = IDLE;
\r
1062 txRuntime->mode = CANTP_TX_WAIT;
\r
1065 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1066 txRuntime->iso15765.state = IDLE;
\r
1067 txRuntime->mode = CANTP_TX_WAIT;
\r
1070 case FIRST_FRAME: {
\r
1071 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNbs); /** @req CANTP264 */
\r
1072 if ( txRuntime->iso15765.stateTimeoutCount == 0 ) {
\r
1073 DEBUG( DEBUG_MEDIUM, "WARNING! Too low CanTpNbs timeout!\n" );
\r
1075 txRuntime->iso15765.state = TX_WAIT_FLOW_CONTROL; // We will always expect a flow control at this stage.
\r
1076 res = sendFirstFrame(txConfig, txRuntime); /** @req CANTP231 */
\r
1077 if (res == E_OK) {
\r
1078 txRuntime->mode = CANTP_TX_PROCESSING;
\r
1082 case INVALID_FRAME:
\r
1084 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1085 txRuntime->iso15765.state = IDLE;
\r
1086 txRuntime->mode = CANTP_TX_WAIT;
\r
1089 } else if (pdurResp == BUFREQ_NOT_OK) {
\r
1090 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1091 txRuntime->iso15765.state = IDLE;
\r
1092 txRuntime->mode = CANTP_TX_WAIT;
\r
1093 } else if (pdurResp == BUFREQ_BUSY) {
\r
1094 /** @req CANTP184 */
\r
1095 txRuntime->iso15765.state = TX_WAIT_CAN_TP_TRANSMIT_PENDING; // We have to issue this request later from main until timeout.
\r
1096 txRuntime->mode = CANTP_TX_PROCESSING;
\r
1099 // TDDO: Put this in a logfile? Error response should have been sent from main.
\r
1104 // - - - - - - - - - - - - - -
\r
1107 Std_ReturnType CanTp_Transmit(PduIdType CanTpTxSduId,
\r
1108 const PduInfoType *CanTpTxInfoPtr) /** @req CANTP176 */
\r
1110 const CanTp_TxNSduType *txConfig = NULL;
\r
1111 CanTp_ChannelPrivateType *txRuntime = NULL;
\r
1112 BufReq_ReturnType res = BUFREQ_NOT_OK;
\r
1113 Std_ReturnType ret = 0;
\r
1115 DEBUG( DEBUG_MEDIUM, "CanTp_Transmit called in polite index: %d!\n", CanTpTxSduId);
\r
1117 VALIDATE( CanTpTxInfoPtr != NULL,
\r
1118 SERVICE_ID_CANTP_TRANSMIT, CANTP_E_PARAM_ADDRESS ); /** @req CANTP031 */
\r
1119 VALIDATE( CanTpRunTimeData.internalState == CANTP_ON, /** @req CANTP238 */
\r
1120 SERVICE_ID_CANTP_TRANSMIT, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1121 VALIDATE( CanTpTxSduId < CANTP_NSDU_CONFIG_LIST_SIZE, SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TX_ID );
\r
1123 txConfig =&CanTpConfig.CanTpNSduList[CanTpTxSduId].configData.CanTpTxNSdu;
\r
1125 txRuntime = &CanTpRunTimeData.runtimeDataList[txConfig->CanTpTxChannel]; // Runtime data.
\r
1126 if (txRuntime->iso15765.state == IDLE) {
\r
1127 txRuntime->pdurBufferCount = 0;
\r
1128 txRuntime->pdurBufferCount = 0;
\r
1129 txRuntime->transferCount = 0;
\r
1130 txRuntime->iso15765.framesHandledCount = 0;
\r
1131 txRuntime->transferTotal = CanTpTxInfoPtr->SduLength; /** @req CANTP225 */
\r
1132 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNcs);
\r
1133 txRuntime->mode = CANTP_TX_PROCESSING;
\r
1134 txRuntime->iso15765.state = TX_WAIT_CAN_TP_TRANSMIT_CAN_TP_PROVIDE_TX_BUFFER;
\r
1136 res = canTpTransmitHelper(txConfig, txRuntime);
\r
1142 case BUFREQ_NOT_OK:
\r
1143 ret = E_NOT_OK; /** @req CANTP072 */
\r
1150 DEBUG( DEBUG_MEDIUM, "CanTp can't transmit, it is already occupied!\n", CanTpTxSduId);
\r
1151 ret = E_NOT_OK; /** @req CANTP123 *//** @req CANTP206 */
\r
1153 return ret; // CAN level error code.
\r
1156 // - - - - - - - - - - - - - -
\r
1158 #if FRTP_CANCEL_TRANSMIT_REQUEST
\r
1159 Std_ReturnType FrTp_CancelTransmitRequest(PduIdType FrTpTxPduId,
\r
1160 FrTp_CancelReasonType FrTpCancelReason)
\r
1166 // - - - - - - - - - - - - - -
\r
1169 void CanTp_Init(void)
\r
1171 CanTp_ChannelPrivateType *runtimeData;
\r
1172 const CanTp_TxNSduType *txConfigParams;
\r
1173 const CanTp_RxNSduType *rxConfigParams;
\r
1175 for (int i=0; i < CANTP_NSDU_CONFIG_LIST_SIZE; i++) {
\r
1176 if ( CanTpConfig.CanTpNSduList[i].direction == IS015765_TRANSMIT ) {
\r
1177 txConfigParams = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1178 if (txConfigParams->CanTpTxChannel < CANTP_NSDU_RUNTIME_LIST_SIZE) {
\r
1179 runtimeData = &CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel];
\r
1181 runtimeData = &CanTpRunTimeData.runtimeDataList[CANTP_NSDU_RUNTIME_LIST_SIZE-1];
\r
1183 initTx15765RuntimeData( txConfigParams, runtimeData);
\r
1185 rxConfigParams = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1186 if (rxConfigParams->CanTpRxChannel < CANTP_NSDU_RUNTIME_LIST_SIZE) {
\r
1187 runtimeData = &CanTpRunTimeData.runtimeDataList[rxConfigParams->CanTpRxChannel];
\r
1189 runtimeData = &CanTpRunTimeData.runtimeDataList[CANTP_NSDU_RUNTIME_LIST_SIZE-1];
\r
1191 initRx15765RuntimeData( rxConfigParams, runtimeData);
\r
1194 fifoQueueInit( &CanTpRunTimeData.fifo );
\r
1195 CanTpRunTimeData.internalState = CANTP_ON; /** @req CANTP170 */
\r
1198 // - - - - - - - - - - - - - -
\r
1200 void CanTp_RxIndication(PduIdType CanTpRxPduId, /** @req CANTP078 */ /** @req CANTP035 */
\r
1201 const PduInfoType *CanTpRxPduPtr)
\r
1203 CanTpFifoQueueItem item;
\r
1204 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1205 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_UNINIT ); /** @req CANTP238 */ /** @req CANTP031 */
\r
1207 item.PduId = CanTpRxPduId;
\r
1208 item.SduLength = CanTpRxPduPtr->SduLength;
\r
1209 for (int i=0; i<item.SduLength; i++) {
\r
1210 item.SduData[i] = CanTpRxPduPtr->SduDataPtr[i];
\r
1212 if ( fifoQueueWrite( &CanTpRunTimeData.fifo, &item ) == FALSE ) { /** @req CANTP077 *//** @req CANTP235 */
\r
1213 DEBUG( DEBUG_MEDIUM, "WARNING!: Frames are lost!\n");
\r
1217 // - - - - - - - - - - - - - -
\r
1219 void CanTp_RxIndication_Main(PduIdType CanTpRxPduId,
\r
1220 const PduInfoType *CanTpRxPduPtr)
\r
1222 const CanTp_RxNSduType *rxConfigParams; // Params reside in ROM.
\r
1223 const CanTp_TxNSduType *txConfigParams;
\r
1224 const CanTp_AddressingFormantType *addressingFormat; // Configured
\r
1225 CanTp_ChannelPrivateType *runtimeParams; // Params reside in RAM.
\r
1226 ISO15765FrameType frameType;
\r
1228 DEBUG( DEBUG_MEDIUM, "CanTp_RxIndication: PduId=%d, [", CanTpRxPduId);
\r
1229 for (int i=0; i<CanTpRxPduPtr->SduLength; i++) {
\r
1230 DEBUG( DEBUG_MEDIUM, "%x, ", CanTpRxPduPtr->SduDataPtr[i]);
\r
1232 DEBUG( DEBUG_MEDIUM, "]");
\r
1234 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1235 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1237 if ( CanTpConfig.CanTpNSduList[CanTpRxPduId].direction == IS015765_TRANSMIT ) {
\r
1238 txConfigParams = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[CanTpRxPduId].configData; /** @req CANTP120 */
\r
1239 addressingFormat = &txConfigParams->CanTpAddressingMode;
\r
1240 runtimeParams = &CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel]; /** @req CANTP096 *//** @req CANTP121 *//** @req CANTP122 *//** @req CANTP190 */
\r
1241 rxConfigParams = NULL;
\r
1243 rxConfigParams = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[CanTpRxPduId].configData; /** @req CANTP120 */
\r
1244 addressingFormat = &rxConfigParams->CanTpAddressingFormant;
\r
1245 runtimeParams = &CanTpRunTimeData.runtimeDataList[rxConfigParams->CanTpRxChannel]; /** @req CANTP096 *//** @req CANTP121 *//** @req CANTP122 *//** @req CANTP190 */
\r
1246 txConfigParams = NULL;
\r
1249 frameType = getFrameType(addressingFormat, CanTpRxPduPtr); /** @req CANTP094 *//** @req CANTP095 */
\r
1250 switch (frameType) {
\r
1251 case SINGLE_FRAME: {
\r
1252 if (rxConfigParams != NULL) {
\r
1253 DEBUG( DEBUG_MEDIUM, "calling handleSingleFrame!\n");
\r
1254 handleSingleFrame(rxConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1257 DEBUG( DEBUG_MEDIUM, "Single frame received on ISO15765-Tx - is ignored!\n");
\r
1261 case FIRST_FRAME: {
\r
1262 if (rxConfigParams != NULL) {
\r
1263 DEBUG( DEBUG_MEDIUM, "calling handleFirstFrame!\n");
\r
1264 handleFirstFrame(rxConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1266 DEBUG( DEBUG_MEDIUM, "First frame received on ISO15765-Tx - is ignored!\n");
\r
1270 case CONSECUTIVE_FRAME: {
\r
1271 if (rxConfigParams != NULL) {
\r
1272 DEBUG( DEBUG_MEDIUM, "calling handleConsecutiveFrame!\n");
\r
1273 handleConsecutiveFrame(rxConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1275 DEBUG( DEBUG_MEDIUM, "Consecutive frame received on ISO15765-Tx - is ignored!\n");
\r
1279 case FLOW_CONTROL_CTS_FRAME: {
\r
1280 if (txConfigParams != NULL) {
\r
1281 DEBUG( DEBUG_MEDIUM, "calling handleFlowControlFrame!\n");
\r
1282 handleFlowControlFrame(txConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1284 DEBUG( DEBUG_MEDIUM, "Flow control frame received on ISO15765-Rx - is ignored!\n");
\r
1288 case INVALID_FRAME: {
\r
1289 DEBUG( DEBUG_MEDIUM, "INVALID_FRAME received - is ignored!\n!\n");
\r
1295 DEBUG( DEBUG_LOW, "CanTp_RxIndication_Main exit!\n");
\r
1298 // - - - - - - - - - - - - - -
\r
1300 void CanTp_TxConfirmation(PduIdType CanTpTxPduId) /** @req CANTP076 */
\r
1302 const CanTp_RxNSduType *rxConfigParams = NULL;
\r
1303 const CanTp_TxNSduType *txConfigParams = NULL;
\r
1305 DEBUG( DEBUG_MEDIUM, "CanTp_TxConfirmation called.\n" );
\r
1307 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1308 SERVICE_ID_CANTP_TX_CONFIRMATION, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1309 VALIDATE_NO_RV( CanTpTxPduId < CANTP_NSDU_CONFIG_LIST_SIZE,
\r
1310 SERVICE_ID_CANTP_TX_CONFIRMATION, CANTP_E_INVALID_TX_ID ); /** @req CANTP158 */
\r
1312 /** @req CANTP236 */
\r
1313 if ( CanTpConfig.CanTpNSduList[CanTpTxPduId].direction == IS015765_TRANSMIT ) {
\r
1314 txConfigParams = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[CanTpTxPduId].configData;
\r
1315 CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel].iso15765.NasNarPending = FALSE;
\r
1316 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
1317 CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel].iso15765.txConfirmed = TRUE;
\r
1320 rxConfigParams = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[CanTpTxPduId].configData;
\r
1321 CanTpRunTimeData.runtimeDataList[rxConfigParams->CanTpRxChannel].iso15765.NasNarPending = FALSE;
\r
1325 // - - - - - - - - - - - - - -
\r
1327 void CanTp_Shutdown(void) /** @req CANTP202 *//** @req CANTP200 *//** @req CANTP010 */
\r
1329 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1330 SERVICE_ID_CANTP_SHUTDOWN, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1332 CanTpRunTimeData.internalState = CANTP_OFF;
\r
1335 // - - - - - - - - - - - - - -
\r
1338 static inline boolean checkNasNarTimeout(CanTp_ChannelPrivateType *runtimeData) {
\r
1339 boolean ret = FALSE;
\r
1340 if (runtimeData->iso15765.NasNarPending) {
\r
1341 TIMER_DECREMENT(runtimeData->iso15765.NasNarTimeoutCount);
\r
1342 if (runtimeData->iso15765.NasNarTimeoutCount == 0) {
\r
1343 DEBUG( DEBUG_MEDIUM, "NAS timed out.\n" );
\r
1344 runtimeData->iso15765.state = IDLE;
\r
1345 runtimeData->iso15765.NasNarPending = FALSE;
\r
1352 // - - - - - - - - - - - - - -
\r
1355 void CanTp_MainFunction(void)
\r
1357 BufReq_ReturnType ret;
\r
1358 CanTpFifoQueueItem item;
\r
1359 PduLengthType bytesWrittenToSduRBuffer;
\r
1361 CanTp_ChannelPrivateType *txRuntimeListItem = NULL;
\r
1362 CanTp_ChannelPrivateType *rxRuntimeListItem = NULL;
\r
1364 const CanTp_TxNSduType *txConfigListItem = NULL;
\r
1365 const CanTp_RxNSduType *rxConfigListItem = NULL;
\r
1367 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1368 SERVICE_ID_CANTP_MAIN_FUNCTION, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1370 // Dispatch the messages that resides in the FIFO to CanTp_RxIndication_Main.
\r
1371 while ( fifoQueueRead( &CanTpRunTimeData.fifo, &item ) == TRUE ) {
\r
1372 PduInfoType pduInfo;
\r
1373 pduInfo.SduDataPtr = item.SduData;
\r
1374 pduInfo.SduLength = item.SduLength;
\r
1375 CanTp_RxIndication_Main( item.PduId, &pduInfo );
\r
1378 for( int i=0; i < CANTP_NSDU_CONFIG_LIST_SIZE; i++ ) {
\r
1379 #if 0 // TODO: Not tested yet
\r
1380 if (checkNasNarTimeout( txRuntimeListItem )) { /** @req CANTP075 */
\r
1381 PduR_CanTpTxConfirmation(txConfigListItem->PduR_CanTpTxPduId, NTFRSLT_NOT_OK); /** @req CANTP074 */ /** @req CANTP204 */
\r
1385 if ( CanTpConfig.CanTpNSduList[i].direction == IS015765_TRANSMIT ) {
\r
1386 txConfigListItem = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1387 txRuntimeListItem = &CanTpRunTimeData.runtimeDataList[txConfigListItem->CanTpTxChannel];
\r
1389 switch (txRuntimeListItem->iso15765.state) {
\r
1390 case TX_WAIT_CAN_TP_TRANSMIT_CAN_TP_PROVIDE_TX_BUFFER:
\r
1392 TIMER_DECREMENT(txRuntimeListItem->iso15765.stateTimeoutCount); /** @req CANTP185 */
\r
1393 if (txRuntimeListItem->iso15765.stateTimeoutCount == 0){
\r
1394 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 *//** @req CANTP185 */
\r
1396 txRuntimeListItem->iso15765.state = IDLE;
\r
1397 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1400 case TX_WAIT_CAN_TP_TRANSMIT_PENDING: {
\r
1401 (void) canTpTransmitHelper(txConfigListItem, txRuntimeListItem);/** @req CANTP184 */ /** @req CANTP089 */
\r
1404 case TX_WAIT_SEND_CONSECUTIVE_FRAME: {
\r
1405 TIMER_DECREMENT(txRuntimeListItem->iso15765.stateTimeoutCount); // Make sure that STmin timer has expired.
\r
1406 if (txRuntimeListItem->iso15765.stateTimeoutCount == 0) {
\r
1407 ret = sendConsecutiveFrame(txConfigListItem, txRuntimeListItem);
\r
1408 if ( ret == E_OK ) {
\r
1409 handleConsecutiveFrameSent(txConfigListItem, txRuntimeListItem);
\r
1411 DEBUG( DEBUG_MEDIUM, "ERROR: Consecutive frame could not be sent!\n");
\r
1412 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1413 txRuntimeListItem->iso15765.state = IDLE;
\r
1414 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1417 DEBUG( DEBUG_MEDIUM, "Waiting for STmin timer to expire!\n");
\r
1421 case TX_WAIT_FLOW_CONTROL:
\r
1422 //DEBUG( DEBUG_MEDIUM, "Waiting for flow control!\n");
\r
1423 TIMER_DECREMENT(txRuntimeListItem->iso15765.stateTimeoutCount);
\r
1424 if (txRuntimeListItem->iso15765.stateTimeoutCount == 0) {
\r
1425 DEBUG( DEBUG_MEDIUM, "State TX_WAIT_FLOW_CONTROL timed out!\n");
\r
1426 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */ /** @req CANTP185 */
\r
1427 txRuntimeListItem->iso15765.state = IDLE;
\r
1428 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1431 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
1432 case TX_WAIT_TX_CONFIRMATION:
\r
1433 if (txRuntimeListItem->iso15765.txConfirmed) {
\r
1434 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_OK); /** @req CANTP074 *//** @req CANTP09 *//** @req CANTP204 */
\r
1435 txRuntimeListItem->iso15765.state = IDLE;
\r
1436 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1444 rxConfigListItem = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1445 rxRuntimeListItem = &CanTpRunTimeData.runtimeDataList[rxConfigListItem->CanTpRxChannel];
\r
1446 switch (rxRuntimeListItem->iso15765.state) {
\r
1447 case RX_WAIT_CONSECUTIVE_FRAME: {
\r
1448 TIMER_DECREMENT (rxRuntimeListItem->iso15765.stateTimeoutCount);
\r
1449 if (rxRuntimeListItem->iso15765.stateTimeoutCount == 0) {
\r
1450 DEBUG( DEBUG_MEDIUM, "TIMEOUT!\n");
\r
1451 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK);
\r
1452 rxRuntimeListItem->iso15765.state = IDLE;
\r
1453 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1457 case RX_WAIT_SDU_BUFFER: {
\r
1458 TIMER_DECREMENT (rxRuntimeListItem->iso15765.stateTimeoutCount);
\r
1459 /* We end up here if we have requested a buffer from the
\r
1460 * PDUR but the response have been BUSY. We assume
\r
1461 * we have data in our local buffer and we are expected
\r
1462 * to send a flow-control clear to send (CTS).
\r
1464 if (rxRuntimeListItem->iso15765.stateTimeoutCount == 0) { /** @req CANTP223 */
\r
1465 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1466 rxRuntimeListItem->iso15765.state = IDLE;
\r
1467 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1468 } else { /** @req CANTP222 */
\r
1469 PduLengthType bytesRemaining = 0;
\r
1470 ret = copySegmentToPduRRxBuffer(rxConfigListItem, /** @req CANTP067, copies from local buffer to PDUR buffer. */
\r
1471 rxRuntimeListItem,
\r
1472 rxRuntimeListItem->canFrameBuffer.data,
\r
1473 rxRuntimeListItem->canFrameBuffer.byteCount,
\r
1474 &bytesWrittenToSduRBuffer);
\r
1475 bytesRemaining = rxRuntimeListItem->transferTotal -
\r
1476 rxRuntimeListItem->transferCount;
\r
1477 if (bytesRemaining > 0) {
\r
1478 sendFlowControlFrame( rxConfigListItem, rxRuntimeListItem, ret ); /** @req CANTP224 (Busy or CTS) */
\r
1480 if (ret == BUFREQ_OK) {
\r
1481 if ( bytesRemaining > 0 ) {
\r
1482 rxRuntimeListItem->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfigListItem->CanTpNcr); //UH
\r
1483 rxRuntimeListItem->iso15765.state = RX_WAIT_CONSECUTIVE_FRAME;
\r
1485 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_OK);
\r
1486 rxRuntimeListItem->iso15765.state = IDLE;
\r
1487 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1489 } else if (ret == BUFREQ_NOT_OK ) {
\r
1490 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP205 */
\r
1491 rxRuntimeListItem->iso15765.state = IDLE;
\r
1492 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1493 } else if ( ret == BUFREQ_BUSY ) {
\r
1494 DEBUG( DEBUG_MEDIUM, "Still busy!\n");
\r