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 TIMER_DECREMENT(timer) \
\r
112 timer = timer - 1; \
\r
115 #define COUNT_DECREMENT(timer) \
\r
117 timer = timer - 1; \
\r
121 #define CANTP_ERR -1
\r
122 #define ISO15765_FLOW_CONTROL_STATUS_CTS 0
\r
123 #define ISO15765_FLOW_CONTROL_STATUS_WAIT 1
\r
124 #define ISO15765_FLOW_CONTROL_STATUS_OVFLW 2
\r
126 // - - - - - - - - - - - - - -
\r
128 #define ISO15765_TPCI_MASK 0x30
\r
129 #define ISO15765_TPCI_SF 0x00 /* Single Frame */
\r
130 #define ISO15765_TPCI_FF 0x10 /* First Frame */
\r
131 #define ISO15765_TPCI_CF 0x20 /* Consecutive Frame */
\r
132 #define ISO15765_TPCI_FC 0x30 /* Flow Control */
\r
133 #define ISO15765_TPCI_DL 0x7 /* Single frame data length mask */
\r
134 #define ISO15765_TPCI_FS_MASK 0x0F /* Flowcontrol status mask */
\r
136 // - - - - - - - - - - - - - -
\r
138 #define MAX_PAYLOAD_SF_STD_ADDR 7
\r
139 #define MAX_PAYLOAD_SF_EXT_ADDR 6
\r
141 #define MAX_PAYLOAD_FF_STD_ADDR 6
\r
142 #define MAX_PAYLOAD_FF_EXT_ADDR 5
\r
144 #define MAX_PAYLOAD_CF_STD_ADDR 7
\r
145 #define MAX_PAYLOAD_CF_EXT_ADDR 6
\r
147 #define SEGMENT_NUMBER_MASK 0x0f
\r
149 #define MAX_SEGMENT_DATA_SIZE 8 // Size of a CAN frame data bytes.
\r
155 UNINITIALIZED, IDLE, SF_OR_FF_RECEIVED_WAITING_PDUR_BUFFER, /** @req CANTP079 */
\r
156 RX_WAIT_CONSECUTIVE_FRAME, RX_WAIT_SDU_BUFFER,
\r
158 TX_WAIT_CAN_TP_TRANSMIT_CAN_TP_PROVIDE_TX_BUFFER, /** @req CANTP226 */
\r
159 TX_WAIT_CAN_TP_TRANSMIT_PENDING, /* CanTP_Transmit was called but no buffer was received (BUSY). */
\r
160 TX_WAIT_SEND_CONSECUTIVE_FRAME, TX_WAIT_FLOW_CONTROL,
\r
161 TX_WAIT_TX_CONFIRMATION, TX_WAIT_TX_CONFIRMATION_CF
\r
162 } ISO15765TransferStateTypes;
\r
165 INVALID_FRAME, /* Not specified by ISO15765 - used as error return type when decoding frame. */
\r
166 SINGLE_FRAME, FIRST_FRAME, CONSECUTIVE_FRAME, FLOW_CONTROL_CTS_FRAME, /* Clear to send */
\r
167 FLOW_CONTROL_WAIT_FRAME, FLOW_CONTROL_OVERFLOW_FRAME
\r
168 } ISO15765FrameType;
\r
171 SEND_NEXT_CONSECUTIVE_FRAME, WAIT_FLOW_CONTROL, TRANSFER_FINISHED
\r
172 } ISO15765TxStateTypes;
\r
175 * In case no buffer is available at some cases the data needs to be
\r
176 * temporarly stored away.
\r
180 uint8 data[MAX_SEGMENT_DATA_SIZE];
\r
181 PduLengthType byteCount;
\r
185 * Structure that is keeping track on the run-time variables for the ongoing
\r
189 uint16 nextFlowControlCount; // Count down to next Flow Control.
\r
190 uint16 framesHandledCount; // Counter keeping track total frames handled.
\r
191 uint8 extendedAddress; // Not always used but need to be available.
\r
192 uint32 stateTimeoutCount; // Counter for timeout.
\r
193 uint8 STmin; // In case we are transmitters the remote node can configure this value (only valid for TX).
\r
194 uint8 BS; // Blocksize (only valid for TX).
\r
195 boolean NasNarPending;
\r
196 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
197 boolean txConfirmed;
\r
199 uint32 NasNarTimeoutCount; // CanTpNas, CanTpNar.
\r
200 ISO15765TransferStateTypes state; // Transfer state machine. TODO: Can this be initialized here?
\r
201 } ISO15765TransferControlType;
\r
204 * Container for TX or RX runtime paramters (TX/RX are identical?)
\r
207 ISO15765TransferControlType iso15765;
\r
208 PduInfoType *pdurBuffer; // The PDUR make an instance of this.
\r
209 PduLengthType pdurBufferCount; // Number of bytes in PDUR buffer.
\r
210 PduLengthType transferTotal; // Total length of the PDU.
\r
211 PduLengthType transferCount; // Counter ongoing transfer.
\r
212 CanIfSduType canFrameBuffer; // Temp storage of SDU data.
\r
213 CanTp_TransferInstanceMode mode; // CanTp030.
\r
214 } CanTp_ChannelPrivateType;
\r
217 #define CANIF_PDU_MAX_LENGTH 0x08 // Max length is 8 (it is CAN dlc=8).
\r
221 uint8 SduData[CANIF_PDU_MAX_LENGTH];
\r
222 PduLengthType SduLength;
\r
223 } CanTpFifoQueueItem;
\r
225 #define FIFO_QUEUE_DEPTH 10
\r
228 int fifoQueueReadIndex;
\r
229 int fifoQueueWriteIndex;
\r
230 CanTpFifoQueueItem queueList[FIFO_QUEUE_DEPTH];
\r
233 // - - - - - - - - - - - - - -
\r
238 CanTp_StateType internalState; /** @req CANTP027 */
\r
239 CanTp_ChannelPrivateType runtimeDataList[CANTP_NSDU_RUNTIME_LIST_SIZE];
\r
240 } CanTp_RunTimeDataType;
\r
242 // - - - - - - - - - - - - - -
\r
244 CanTp_RunTimeDataType CanTpRunTimeData = { .initRun = FALSE,
\r
245 .internalState = CANTP_OFF }; /** @req CANTP168 */
\r
247 static inline void fifoQueueInit( CanTpFifo *fifoQueue ) {
\r
248 fifoQueue->fifoQueueReadIndex = 0;
\r
249 fifoQueue->fifoQueueWriteIndex = 0;
\r
252 // - - - - - - - - - - - - - -
\r
254 static inline boolean fifoQueueRead( CanTpFifo *fifoQueue, CanTpFifoQueueItem *item ) {
\r
255 boolean ret = FALSE;
\r
257 readIndex = fifoQueue->fifoQueueReadIndex;
\r
258 if ( fifoQueue->fifoQueueReadIndex != fifoQueue->fifoQueueWriteIndex ) {
\r
260 if (++readIndex == FIFO_QUEUE_DEPTH) {
\r
263 item->PduId = fifoQueue->queueList[fifoQueue->fifoQueueReadIndex].PduId;
\r
264 item->SduLength = fifoQueue->queueList[fifoQueue->fifoQueueReadIndex].SduLength;
\r
265 for (int i=0; i<item->SduLength; i++) {
\r
266 item->SduData[i] = fifoQueue->queueList[fifoQueue->fifoQueueReadIndex].SduData[i];
\r
268 fifoQueue->fifoQueueReadIndex = readIndex;
\r
276 // - - - - - - - - - - - - - -
\r
278 static inline boolean fifoQueueWrite( CanTpFifo *fifoQueue, CanTpFifoQueueItem *item ) {
\r
279 boolean ret = FALSE;
\r
281 writeIndex = fifoQueue->fifoQueueWriteIndex;
\r
282 if (++writeIndex == FIFO_QUEUE_DEPTH) {
\r
285 if ( writeIndex != fifoQueue->fifoQueueReadIndex ) { // Check if space left.
\r
286 fifoQueue->queueList[fifoQueue->fifoQueueWriteIndex].PduId = item->PduId;
\r
287 fifoQueue->queueList[fifoQueue->fifoQueueWriteIndex].SduLength = item->SduLength;
\r
288 for (int i=0; i<item->SduLength;i++) {
\r
289 fifoQueue->queueList[fifoQueue->fifoQueueWriteIndex].SduData[i] = item->SduData[i];
\r
291 fifoQueue->fifoQueueWriteIndex = writeIndex;
\r
297 // - - - - - - - - - - - - - -
\r
299 static inline ISO15765FrameType getFrameType(
\r
300 const CanTp_AddressingFormantType *formatType,
\r
301 const PduInfoType *CanTpRxPduPtr) {
\r
302 ISO15765FrameType res = INVALID_FRAME;
\r
305 switch (*formatType) {
\r
306 case CANTP_STANDARD:
\r
307 DEBUG( DEBUG_MEDIUM, "CANTP_STANDARD\n");
\r
308 tpci = CanTpRxPduPtr->SduDataPtr[0];
\r
310 case CANTP_EXTENDED:
\r
311 DEBUG( DEBUG_MEDIUM, "CANTP_EXTENDED\n");
\r
312 tpci = CanTpRxPduPtr->SduDataPtr[1];
\r
318 switch (tpci & ISO15765_TPCI_MASK) {
\r
319 case ISO15765_TPCI_SF:
\r
320 res = SINGLE_FRAME;
\r
322 case ISO15765_TPCI_FF:
\r
325 case ISO15765_TPCI_CF:
\r
326 res = CONSECUTIVE_FRAME;
\r
328 case ISO15765_TPCI_FC: // Some kind of flow control.
\r
329 switch (tpci & ISO15765_TPCI_FS_MASK) {
\r
330 case ISO15765_FLOW_CONTROL_STATUS_CTS:
\r
331 res = FLOW_CONTROL_CTS_FRAME;
\r
333 case ISO15765_FLOW_CONTROL_STATUS_WAIT:
\r
334 res = FLOW_CONTROL_CTS_FRAME;
\r
336 case ISO15765_FLOW_CONTROL_STATUS_OVFLW:
\r
337 res = FLOW_CONTROL_CTS_FRAME;
\r
344 // - - - - - - - - - - - - - -
\r
346 static inline PduLengthType getPduLength(
\r
347 const CanTp_AddressingFormantType *formatType,
\r
348 const ISO15765FrameType iso15765Frame, const PduInfoType *CanTpRxPduPtr) {
\r
349 PduLengthType res = 0;
\r
350 uint8 tpci_offset = 0;
\r
352 switch (*formatType) {
\r
353 case CANTP_STANDARD:
\r
356 case CANTP_EXTENDED:
\r
363 switch (iso15765Frame) {
\r
365 // Parse the data length from the single frame header.
\r
366 res = CanTpRxPduPtr->SduDataPtr[tpci_offset] & ISO15765_TPCI_DL;
\r
369 // Parse the data length form the first frame.
\r
370 res = CanTpRxPduPtr->SduDataPtr[tpci_offset + 1] + ((PduLengthType)((CanTpRxPduPtr->SduDataPtr[tpci_offset]) & 0xf) << 8);
\r
373 res = 0; // TODO: maybe we should have an error code here.
\r
379 // - - - - - - - - - - - - - -
\r
381 static void initRx15765RuntimeData(const CanTp_RxNSduType *rxConfigParams,
\r
382 CanTp_ChannelPrivateType *rxRuntimeParams) {
\r
384 rxRuntimeParams->iso15765.state = IDLE;
\r
385 rxRuntimeParams->iso15765.NasNarPending = FALSE;
\r
386 rxRuntimeParams->iso15765.framesHandledCount = 0;
\r
387 rxRuntimeParams->iso15765.nextFlowControlCount = 0;
\r
388 rxRuntimeParams->pdurBufferCount = 0;
\r
389 rxRuntimeParams->transferTotal = 0;
\r
390 rxRuntimeParams->transferCount = 0;
\r
391 rxRuntimeParams->mode = CANTP_RX_WAIT; /** @req CANTP030 */
\r
392 rxRuntimeParams->pdurBuffer = NULL;
\r
395 // - - - - - - - - - - - - - -
\r
397 static void initTx15765RuntimeData(const CanTp_TxNSduType *txConfigParams,
\r
398 CanTp_ChannelPrivateType *txRuntimeParams) {
\r
400 txRuntimeParams->iso15765.state = IDLE;
\r
401 txRuntimeParams->iso15765.NasNarPending = FALSE;
\r
402 txRuntimeParams->iso15765.framesHandledCount = 0;
\r
403 txRuntimeParams->iso15765.nextFlowControlCount = 0;
\r
404 txRuntimeParams->pdurBufferCount = 0;
\r
405 txRuntimeParams->transferTotal = 0;
\r
406 txRuntimeParams->transferCount = 0;
\r
407 txRuntimeParams->mode = CANTP_TX_WAIT; /** @req CANTP030 */
\r
408 txRuntimeParams->pdurBuffer = NULL;
\r
412 // - - - - - - - - - - - - - -
\r
414 static inline BufReq_ReturnType copySegmentToPduRRxBuffer(const CanTp_RxNSduType *rxConfig,
\r
415 CanTp_ChannelPrivateType *rxRuntime, uint8 *segment,
\r
416 PduLengthType segmentSize, PduLengthType *bytesWrittenSuccessfully) {
\r
418 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
419 boolean endLoop = FALSE;
\r
420 *bytesWrittenSuccessfully = 0;
\r
422 while ((*bytesWrittenSuccessfully < segmentSize) && (!endLoop)) {
\r
423 // Copy the data that resides in the buffer.
\r
424 if (rxRuntime->pdurBuffer != NULL) {
\r
425 while ((*bytesWrittenSuccessfully < segmentSize ) && (rxRuntime->pdurBuffer->SduLength > rxRuntime->pdurBufferCount)) {
\r
426 rxRuntime->pdurBuffer->SduDataPtr[rxRuntime->pdurBufferCount++] = segment[(*bytesWrittenSuccessfully)++];
\r
429 if (*bytesWrittenSuccessfully < segmentSize ) {
\r
430 // We need to request a new buffer from the SDUR.
\r
431 // TODO: We should do a timeout here.
\r
432 ret = PduR_CanTpProvideRxBuffer(rxConfig->PduR_PduId, rxRuntime->transferTotal, &rxRuntime->pdurBuffer); /** @req CANTP079 */ /** @req CANTP080 */ /** @req CANTP064 */
\r
433 if (ret == BUFREQ_OK) {
\r
434 VALIDATE( rxRuntime->pdurBuffer->SduDataPtr != NULL,
\r
435 SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_RX_BUFFER );
\r
436 rxRuntime->pdurBufferCount = 0; // The buffer is emptied.
\r
437 } else if (ret == BUFREQ_BUSY) {
\r
438 rxRuntime->transferCount += *bytesWrittenSuccessfully;
\r
441 endLoop = TRUE; // Let calling function handle this error.
\r
444 rxRuntime->transferCount += segmentSize; //== bytesWrittenSuccessfully
\r
452 // - - - - - - - - - - - - - -
\r
454 static inline boolean copySegmentToLocalRxBuffer /*writeDataSegmentToLocalBuffer*/(
\r
455 CanTp_ChannelPrivateType *rxRuntime, uint8 *segment,
\r
456 PduLengthType segmentSize) {
\r
457 boolean ret = FALSE;
\r
459 if ( segmentSize < MAX_SEGMENT_DATA_SIZE ) {
\r
460 for (int i=0; i < segmentSize; i++) {
\r
461 rxRuntime->canFrameBuffer.data[i] = segment[i];
\r
463 rxRuntime->canFrameBuffer.byteCount = segmentSize;
\r
469 // - - - - - - - - - - - - - -
\r
471 static inline Std_ReturnType canReceivePaddingHelper(
\r
472 const CanTp_RxNSduType *rxConfig, CanTp_ChannelPrivateType *rxRuntime,
\r
473 PduInfoType *PduInfoPtr) {
\r
474 if (rxConfig->CanTpRxPaddingActivation == CANTP_ON) {
\r
475 for (int i = PduInfoPtr->SduLength; i < CANIF_PDU_MAX_LENGTH; i++) {
\r
476 PduInfoPtr->SduDataPtr[i] = 0x0; // TODO: Does it have to be padded with zeroes?
\r
478 PduInfoPtr->SduLength = CANIF_PDU_MAX_LENGTH;
\r
480 rxRuntime->iso15765.NasNarTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNar); /** @req CANTP075 */
\r
481 rxRuntime->iso15765.NasNarPending = TRUE;
\r
482 return CanIf_Transmit(rxConfig->CanIf_FcPduId, PduInfoPtr);
\r
485 // - - - - - - - - - - - - - -
\r
487 static inline Std_ReturnType canTansmitPaddingHelper(
\r
488 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime,
\r
489 PduInfoType *PduInfoPtr) {
\r
491 /** @req CANTP114 */
\r
492 /** @req CANTP040 */
\r
493 /** @req CANTP098 */
\r
494 /** @req CANTP116 */
\r
495 /** @req CANTP059 */
\r
497 if (txConfig->CanTpTxPaddingActivation == CANTP_ON) { /** @req CANTP225 */
\r
498 for (int i = PduInfoPtr->SduLength; i < CANIF_PDU_MAX_LENGTH; i++) {
\r
499 PduInfoPtr->SduDataPtr[i] = 0x0; // TODO: Does it have to be padded with zeroes?
\r
501 PduInfoPtr->SduLength = CANIF_PDU_MAX_LENGTH;
\r
503 txRuntime->iso15765.NasNarTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNas); /** @req CANTP075 */
\r
504 txRuntime->iso15765.NasNarPending = TRUE;
\r
505 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
506 txRuntime->iso15765.txConfirmed = FALSE;
\r
508 return CanIf_Transmit(txConfig->CanIf_PduId, PduInfoPtr);
\r
511 // - - - - - - - - - - - - - -
\r
513 static inline void sendFlowControlFrame(const CanTp_RxNSduType *rxConfig, CanTp_ChannelPrivateType *rxRuntime, BufReq_ReturnType flowStatus) {
\r
514 uint8 indexCount = 0;
\r
515 Std_ReturnType ret = E_NOT_OK;
\r
516 PduInfoType pduInfo;
\r
517 uint8 sduData[8]; // Note that buffer in declared on the stack.
\r
518 uint16 spaceFreePduRBuffer = 0;
\r
519 uint16 computedBs = 0;
\r
521 DEBUG( DEBUG_MEDIUM, "sendFlowControlFrame called!\n");
\r
522 pduInfo.SduDataPtr = &sduData[0];
\r
523 if (rxConfig->CanTpAddressingFormant == CANTP_EXTENDED) {
\r
524 sduData[indexCount++] = rxRuntime->iso15765.extendedAddress;
\r
526 switch (flowStatus) {
\r
529 sduData[indexCount++] = ISO15765_TPCI_FC | ISO15765_FLOW_CONTROL_STATUS_CTS;
\r
530 spaceFreePduRBuffer = rxRuntime->pdurBuffer->SduLength - rxRuntime->pdurBufferCount;
\r
531 if (rxConfig->CanTpAddressingFormant == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
532 computedBs = (spaceFreePduRBuffer / MAX_PAYLOAD_SF_EXT_ADDR) + 1; // + 1 is for local buffer.
\r
534 computedBs = (spaceFreePduRBuffer / MAX_PAYLOAD_SF_STD_ADDR) + 1; // + 1 is for local buffer.
\r
536 if (computedBs > rxConfig->CanTpBs) { // /** @req CANTP091 *//** @req CANTP084 */
\r
537 computedBs = rxConfig->CanTpBs;
\r
539 DEBUG( DEBUG_MEDIUM, "computedBs:%d\n", computedBs);
\r
540 sduData[indexCount++] = computedBs; // 734 PC-lint: Okej att casta till uint8?
\r
541 sduData[indexCount++] = (uint8) rxConfig->CanTpSTmin;
\r
542 rxRuntime->iso15765.nextFlowControlCount = computedBs;
\r
543 pduInfo.SduLength = indexCount;
\r
546 case BUFREQ_NOT_OK:
\r
549 sduData[indexCount++] = ISO15765_TPCI_FC | ISO15765_FLOW_CONTROL_STATUS_WAIT;
\r
550 pduInfo.SduLength = indexCount;
\r
552 case BUFREQ_OVFL: /** @req CANTP081 */
\r
553 sduData[indexCount++] = ISO15765_TPCI_FC | ISO15765_FLOW_CONTROL_STATUS_OVFLW;
\r
554 pduInfo.SduLength = indexCount;
\r
559 ret = canReceivePaddingHelper(rxConfig, rxRuntime, &pduInfo);
\r
561 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP084 */
\r
562 rxRuntime->iso15765.state = IDLE;
\r
563 rxRuntime->mode = CANTP_RX_WAIT;
\r
567 // - - - - - - - - - - - - - -
\r
570 static inline void handleConsecutiveFrame(const CanTp_RxNSduType *rxConfig,
\r
571 CanTp_ChannelPrivateType *rxRuntime, const PduInfoType *rxPduData) {
\r
572 uint8 indexCount = 0;
\r
573 uint8 segmentNumber = 0;
\r
574 uint8 extendedAddress = 0;
\r
575 PduLengthType bytesLeftToCopy = 0;
\r
576 PduLengthType bytesLeftToTransfer = 0;
\r
577 PduLengthType currentSegmentSize = 0;
\r
578 PduLengthType currentSegmentMaxSize = 0;
\r
579 PduLengthType bytesCopiedToPdurRxBuffer = 0;
\r
580 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
582 if (rxRuntime->iso15765.state == RX_WAIT_CONSECUTIVE_FRAME) {
\r
583 if (rxConfig->CanTpAddressingFormant == CANTP_EXTENDED) {
\r
584 extendedAddress = rxPduData->SduDataPtr[indexCount++];
\r
586 segmentNumber = rxPduData->SduDataPtr[indexCount++] & SEGMENT_NUMBER_MASK;
\r
587 if (segmentNumber != (rxRuntime->iso15765.framesHandledCount & SEGMENT_NUMBER_MASK)) {
\r
588 DEBUG(DEBUG_MEDIUM,"Segmentation number error detected - is the sending"
\r
589 "unit too fast? Increase STmin (cofig) to slow it down!\n");
\r
590 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_WRONG_SN); /** @req CANTP084 */
\r
591 rxRuntime->iso15765.state = IDLE;
\r
592 rxRuntime->mode = CANTP_RX_WAIT;
\r
594 currentSegmentMaxSize = CANIF_PDU_MAX_LENGTH - indexCount;
\r
595 bytesLeftToCopy = rxRuntime->transferTotal - rxRuntime->transferCount;
\r
596 if (bytesLeftToCopy < currentSegmentMaxSize) {
\r
597 currentSegmentSize = bytesLeftToCopy; // 1-5.
\r
599 currentSegmentSize = currentSegmentMaxSize; // 6 or 7, depends on addressing format used.
\r
601 // Copy received data to buffer provided by SDUR.
\r
602 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime,
\r
603 &rxPduData->SduDataPtr[indexCount],
\r
604 currentSegmentSize,
\r
605 &bytesCopiedToPdurRxBuffer);
\r
606 if (ret == BUFREQ_NOT_OK) {
\r
607 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NO_BUFFER); /** @req CANTP084 */
\r
608 rxRuntime->iso15765.state = IDLE;
\r
609 rxRuntime->mode = CANTP_RX_WAIT;
\r
610 } else if (ret == BUFREQ_BUSY) {
\r
611 boolean dataCopyFailure = FALSE;
\r
612 PduLengthType bytesNotCopiedToPdurRxBuffer = currentSegmentSize - bytesCopiedToPdurRxBuffer;
\r
613 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
614 if ( copySegmentToLocalRxBuffer(rxRuntime, /** @req CANTP067 */
\r
615 &rxPduData->SduDataPtr[1 + bytesCopiedToPdurRxBuffer],
\r
616 bytesNotCopiedToPdurRxBuffer ) != TRUE ) {
\r
617 rxRuntime->iso15765.state = IDLE;
\r
618 rxRuntime->mode = CANTP_RX_WAIT;
\r
619 dataCopyFailure = TRUE;
\r
620 DEBUG( DEBUG_MEDIUM, "Unexpected error, could not copy 'unaligned leftover' " "data to local buffer!\n");
\r
623 if ( copySegmentToLocalRxBuffer(rxRuntime, /** @req CANTP067 */
\r
624 &rxPduData->SduDataPtr[2 + bytesCopiedToPdurRxBuffer],
\r
625 bytesNotCopiedToPdurRxBuffer) != TRUE ) {
\r
626 rxRuntime->iso15765.state = IDLE;
\r
627 rxRuntime->mode = CANTP_RX_WAIT;
\r
628 dataCopyFailure = TRUE;
\r
629 DEBUG( DEBUG_MEDIUM, "Unexpected error, could not copy 'unaligned leftover' " "data to local buffer!\n");
\r
632 if ( !dataCopyFailure ) {
\r
633 rxRuntime->iso15765.framesHandledCount++;
\r
634 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr);
\r
635 rxRuntime->iso15765.state = RX_WAIT_SDU_BUFFER;
\r
636 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
637 sendFlowControlFrame(rxConfig, rxRuntime, ret); /** @req CANTP082 */
\r
639 } else if (ret == BUFREQ_OK) {
\r
640 bytesLeftToTransfer = rxRuntime->transferTotal - rxRuntime->transferCount;
\r
641 if (bytesLeftToTransfer > 0) {
\r
642 rxRuntime->iso15765.framesHandledCount++;
\r
643 COUNT_DECREMENT(rxRuntime->iso15765.nextFlowControlCount);
\r
644 if (rxRuntime->iso15765.nextFlowControlCount == 0) {
\r
645 sendFlowControlFrame(rxConfig, rxRuntime, BUFREQ_OK);
\r
647 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNcr); //UH
\r
650 DEBUG( DEBUG_MEDIUM,"ISO15765-Rx session finished, going back to IDLE!\n");
\r
651 rxRuntime->iso15765.state = IDLE;
\r
652 rxRuntime->mode = CANTP_RX_WAIT;
\r
653 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_OK); /** @req CANTP084 */
\r
658 } // 438, 550 PC-lint: extendedAdress not accessed. Extended adress needs to be implemented. Ticket #136
\r
660 // - - - - - - - - - - - - - -
\r
662 static inline Std_ReturnType sendConsecutiveFrame(
\r
663 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime) {
\r
664 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
665 uint8 sduData[CANIF_PDU_MAX_LENGTH];
\r
666 PduLengthType consecutiveFrameMaxPayload = 0;
\r
667 PduLengthType consecutiveFrameActualPayload = 0;
\r
668 PduLengthType remaningSduDataSize = 0;
\r
669 PduInfoType pduInfo;
\r
670 uint16 copyCount = 0;
\r
671 uint16 indexCount = 0;
\r
673 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
674 sduData[indexCount++] = (uint8) txConfig->CanTpNTa->CanTpNTa; // Target address.
\r
676 sduData[indexCount++] = ISO15765_TPCI_CF | (uint8)(
\r
677 (txRuntime->iso15765.framesHandledCount + 1) & ISO15765_TPCI_FS_MASK); // + 1 is because the consecutive frame numbering begins with 1 and not 0.
\r
679 // Always copy from the PDUR buffer data to the canFrameBuffer because if
\r
680 // we are unlucky the application give us very small buffers.
\r
681 consecutiveFrameMaxPayload = CANIF_PDU_MAX_LENGTH - indexCount;
\r
682 remaningSduDataSize = txRuntime->transferTotal - txRuntime->transferCount;
\r
684 // Calculate number of valid bytes that reside in this CF.
\r
685 if ( remaningSduDataSize < consecutiveFrameMaxPayload ) {
\r
686 consecutiveFrameActualPayload = remaningSduDataSize; // Last frame.
\r
688 consecutiveFrameActualPayload = consecutiveFrameMaxPayload;
\r
690 copyCount = txRuntime->canFrameBuffer.byteCount; // maybe some bytes already reside in the local buffer before we proceed asking for more data from application.
\r
691 while (copyCount < consecutiveFrameActualPayload) {
\r
692 if ( txRuntime->pdurBuffer->SduLength > txRuntime->pdurBufferCount ) {
\r
693 txRuntime->canFrameBuffer.data[copyCount] = txRuntime->pdurBuffer->SduDataPtr[txRuntime->pdurBufferCount++];
\r
695 txRuntime->canFrameBuffer.byteCount++;
\r
697 BufReq_ReturnType pdurResp = PduR_CanTpProvideTxBuffer(txConfig->PduR_PduId, &txRuntime->pdurBuffer, 0); /** @req CANTP226 */ /** @req CANTP086 */ /** @req CANTP117 */
\r
698 if (pdurResp == BUFREQ_OK) {
\r
699 txRuntime->pdurBufferCount = 0;
\r
701 } else if (pdurResp == BUFREQ_BUSY) {
\r
702 ret = E_OK; // We will remain in this state, called again later, not data lost/destroyed?
\r
704 /** @req CANTP087 */
\r
705 DEBUG( DEBUG_MEDIUM, "sendConsecutiveFrame failed, no buffer provided!\n");
\r
706 ret = E_NOT_OK; // Serious malfunction, function caller should cancel this transfer.
\r
711 if (copyCount == consecutiveFrameActualPayload) {
\r
712 for (int i=0; i<txRuntime->canFrameBuffer.byteCount; i++) {
\r
713 sduData[indexCount++] = txRuntime->canFrameBuffer.data[i];
\r
715 pduInfo.SduDataPtr = sduData;
\r
716 pduInfo.SduLength = indexCount; // also includes consecutive frame header.
\r
717 ret = canTansmitPaddingHelper(txConfig, txRuntime, &pduInfo);
\r
719 // Now we consider this frame sent and we can not handle
\r
720 // the scenario where the CAN queue is full.
\r
721 txRuntime->iso15765.framesHandledCount++;
\r
722 COUNT_DECREMENT(txRuntime->iso15765.nextFlowControlCount);
\r
723 txRuntime->transferCount += txRuntime->canFrameBuffer.byteCount;
\r
724 txRuntime->canFrameBuffer.byteCount = 0;
\r
725 DEBUG( DEBUG_MEDIUM, "transferCount:%d\n", txRuntime->transferCount);
\r
728 DEBUG( DEBUG_MEDIUM, "Unexpected error, should not happen!\n");
\r
733 // - - - - - - - - - - - - - -
\r
735 static inline void handleConsecutiveFrameSent(
\r
736 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime) {
\r
738 if (txRuntime->transferTotal <= txRuntime->transferCount) {
\r
739 // Transfer finished!
\r
740 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
741 txRuntime->iso15765.state = TX_WAIT_TX_CONFIRMATION;
\r
743 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_OK); /** @req CANTP074 *//** @req CANTP09 *//** @req CANTP204 */
\r
744 txRuntime->iso15765.state = IDLE;
\r
745 txRuntime->mode = CANTP_TX_WAIT;
\r
747 } else if (txRuntime->iso15765.nextFlowControlCount == 0) {
\r
748 if (txRuntime->iso15765.BS) { // Check if receiver expects flow control.
\r
749 // Time to send flow control!
\r
750 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNbs); /** @req CANTP264 */
\r
751 txRuntime->iso15765.state = TX_WAIT_FLOW_CONTROL;
\r
753 // Send next consecutive frame!
\r
754 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txRuntime->iso15765.STmin);
\r
755 txRuntime->iso15765.state = TX_WAIT_TX_CONFIRMATION_CF;
\r
758 // Send next consecutive frame!
\r
759 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txRuntime->iso15765.STmin);
\r
760 txRuntime->iso15765.state = TX_WAIT_TX_CONFIRMATION_CF;
\r
764 // - - - - - - - - - - - - - -
\r
766 static inline void handleFlowControlFrame(const CanTp_TxNSduType *txConfig,
\r
767 CanTp_ChannelPrivateType *txRuntime, const PduInfoType *txPduData) {
\r
768 int indexCount = 0;
\r
769 uint8 extendedAddress = 0;
\r
770 Std_ReturnType ret;
\r
773 if ( txRuntime->iso15765.state == TX_WAIT_FLOW_CONTROL ) {
\r
774 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
775 extendedAddress = txPduData->SduDataPtr[indexCount++];
\r
777 switch (txPduData->SduDataPtr[indexCount++] & ISO15765_TPCI_FS_MASK) {
\r
778 case ISO15765_FLOW_CONTROL_STATUS_CTS:
\r
780 { // This construction is added to make the hcs12 compiler happy.
\r
781 const uint8 bs = txPduData->SduDataPtr[indexCount++];
\r
782 txRuntime->iso15765.BS = bs;
\r
783 txRuntime->iso15765.nextFlowControlCount = bs;
\r
785 txRuntime->iso15765.STmin = txPduData->SduDataPtr[indexCount++];
\r
787 txRuntime->iso15765.BS = txPduData->SduDataPtr[indexCount++];
\r
788 txRuntime->iso15765.nextFlowControlCount = txRuntime->iso15765.BS;
\r
789 txRuntime->iso15765.STmin = txPduData->SduDataPtr[indexCount++];
\r
791 DEBUG( DEBUG_MEDIUM, "txRuntime->iso15765.STmin = %d\n", txRuntime->iso15765.STmin);
\r
792 ret = sendConsecutiveFrame(txConfig, txRuntime);
\r
794 handleConsecutiveFrameSent(txConfig, txRuntime);
\r
796 PduR_CanTpRxIndication(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP177 */ /** @req CANTP084 */
\r
797 txRuntime->iso15765.state = IDLE;
\r
798 txRuntime->mode = CANTP_TX_WAIT;
\r
801 case ISO15765_FLOW_CONTROL_STATUS_WAIT:
\r
802 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNbs); /*CanTp: 264*/
\r
803 txRuntime->iso15765.state = TX_WAIT_FLOW_CONTROL;
\r
805 case ISO15765_FLOW_CONTROL_STATUS_OVFLW:
\r
806 PduR_CanTpRxIndication(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK);
\r
807 txRuntime->iso15765.state = IDLE;
\r
808 txRuntime->mode = CANTP_TX_WAIT;
\r
812 DEBUG( DEBUG_MEDIUM, "Ignoring flow control, we do not expect it!");
\r
814 } // 438, 550 PC-lint: extendAdress används inte. EN BUG? Behöver fixas
\r
817 // - - - - - - - - - - - - - -
\r
819 static inline void handleSingleFrame(const CanTp_RxNSduType *rxConfig,
\r
820 CanTp_ChannelPrivateType *rxRuntime, const PduInfoType *rxPduData) {
\r
821 BufReq_ReturnType ret;
\r
822 PduLengthType pduLength;
\r
823 uint8 *data = NULL;
\r
824 PduLengthType bytesWrittenToSduRBuffer;
\r
827 if (rxRuntime->iso15765.state != IDLE) {
\r
828 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NOT_OK); // Abort current reception, we need to tell the current receiver it has been aborted.
\r
829 DEBUG( DEBUG_MEDIUM, "Single frame received and channel not IDLE!\n");
\r
831 (void) initRx15765RuntimeData(rxConfig, rxRuntime); /** @req CANTP124 */
\r
832 pduLength = getPduLength(&rxConfig->CanTpAddressingFormant, SINGLE_FRAME, rxPduData);
\r
834 if (rxRuntime->pdurBuffer != NULL) {
\r
835 VALIDATE_NO_RV( rxRuntime->pdurBuffer->SduDataPtr != NULL,
\r
836 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_INVALID_RX_LENGTH );
\r
839 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) { /** @req CANTP094 *//** @req CANTP095 */
\r
840 data = &rxPduData->SduDataPtr[1];
\r
842 data = &rxPduData->SduDataPtr[2];
\r
844 rxRuntime->transferTotal = pduLength;
\r
845 rxRuntime->iso15765.state = SF_OR_FF_RECEIVED_WAITING_PDUR_BUFFER;
\r
846 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
847 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr); /** @req CANTP166 */
\r
849 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime, data, pduLength, &bytesWrittenToSduRBuffer);
\r
851 if (ret == BUFREQ_OK) {
\r
852 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_OK);
\r
853 rxRuntime->iso15765.state = IDLE;
\r
854 rxRuntime->mode = CANTP_RX_WAIT;
\r
855 } else if (ret == BUFREQ_BUSY) {
\r
856 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
857 data = &rxPduData->SduDataPtr[1];
\r
859 data = &rxPduData->SduDataPtr[2];
\r
861 (void)copySegmentToLocalRxBuffer(rxRuntime, data, pduLength ); /** @req CANTP067 */
\r
862 rxRuntime->iso15765.state = RX_WAIT_SDU_BUFFER;
\r
863 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
865 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NO_BUFFER);
\r
866 rxRuntime->iso15765.state = IDLE;
\r
867 rxRuntime->mode = CANTP_RX_WAIT;
\r
871 // - - - - - - - - - - - - - -
\r
874 static inline void handleFirstFrame(const CanTp_RxNSduType *rxConfig,
\r
875 CanTp_ChannelPrivateType *rxRuntime, const PduInfoType *rxPduData) {
\r
876 BufReq_ReturnType ret;
\r
877 PduLengthType pduLength = 0;
\r
878 PduLengthType bytesWrittenToSduRBuffer;
\r
880 if (rxRuntime->iso15765.state != IDLE) {
\r
881 DEBUG( DEBUG_MEDIUM, "First frame received during Rx-session!\n" );
\r
882 PduR_CanTpRxIndication(rxConfig->PduR_PduId, NTFRSLT_E_NOT_OK); // Abort current reception, we need to tell the current receiver it has been aborted.
\r
885 (void) initRx15765RuntimeData(rxConfig, rxRuntime); /** @req CANTP124 */
\r
886 pduLength = getPduLength(&rxConfig->CanTpAddressingFormant, FIRST_FRAME,
\r
888 rxRuntime->transferTotal = pduLength;
\r
890 VALIDATE_NO_RV( rxRuntime->transferTotal != 0,
\r
891 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_INVALID_RX_LENGTH );
\r
893 // Validate that that there is a reason for using the segmented transfers and
\r
894 // if not simply skip (single frame should have been used).
\r
895 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) { /** @req CANTP094 *//** @req CANTP095 */
\r
896 if (pduLength <= MAX_PAYLOAD_SF_STD_ADDR){
\r
900 if (pduLength <= MAX_PAYLOAD_SF_EXT_ADDR){
\r
904 // Validate that the SDU is full length in this first frame.
\r
905 if (rxPduData->SduLength < CANIF_PDU_MAX_LENGTH) {
\r
909 rxRuntime->iso15765.framesHandledCount = 1; // Segment count begins with 1 (FirstFrame has the 0).
\r
910 rxRuntime->iso15765.state = SF_OR_FF_RECEIVED_WAITING_PDUR_BUFFER;
\r
911 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
912 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr); /** @req CANTP166 */
\r
914 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
915 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime,
\r
916 &rxPduData->SduDataPtr[2],
\r
917 MAX_PAYLOAD_FF_STD_ADDR,
\r
918 &bytesWrittenToSduRBuffer);
\r
920 ret = copySegmentToPduRRxBuffer(rxConfig, rxRuntime,
\r
921 &rxPduData->SduDataPtr[3],
\r
922 MAX_PAYLOAD_FF_EXT_ADDR,
\r
923 &bytesWrittenToSduRBuffer);
\r
925 if (ret == BUFREQ_OK) {
\r
926 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNcr);
\r
927 rxRuntime->iso15765.state = RX_WAIT_CONSECUTIVE_FRAME;
\r
928 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
929 sendFlowControlFrame(rxConfig, rxRuntime, ret);
\r
930 } else if (ret == BUFREQ_BUSY) {
\r
931 /** @req CANTP222 */
\r
932 if (rxConfig->CanTpAddressingFormant == CANTP_STANDARD) {
\r
933 (void)copySegmentToLocalRxBuffer(rxRuntime, &rxPduData->SduDataPtr[2], MAX_PAYLOAD_FF_STD_ADDR );
\r
935 (void)copySegmentToLocalRxBuffer(rxRuntime, &rxPduData->SduDataPtr[3], MAX_PAYLOAD_FF_EXT_ADDR );
\r
937 rxRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfig->CanTpNbr);
\r
938 rxRuntime->iso15765.state = RX_WAIT_SDU_BUFFER;
\r
939 rxRuntime->mode = CANTP_RX_PROCESSING;
\r
940 sendFlowControlFrame(rxConfig, rxRuntime, ret); /** @req CANTP082 */
\r
941 } else if (ret == BUFREQ_OVFL) {
\r
942 sendFlowControlFrame(rxConfig, rxRuntime, ret); /** @req CANTP081 */
\r
943 rxRuntime->iso15765.state = IDLE;
\r
944 rxRuntime->mode = CANTP_RX_WAIT;
\r
948 // - - - - - - - - - - - - - -
\r
950 static inline ISO15765FrameType calcRequiredProtocolFrameType(
\r
951 const CanTp_TxNSduType *txConfig, CanTp_ChannelPrivateType *txRuntime) {
\r
953 ISO15765FrameType ret = INVALID_FRAME;
\r
954 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) {
\r
955 if (txRuntime->transferTotal <= MAX_PAYLOAD_CF_EXT_ADDR) {
\r
956 ret = SINGLE_FRAME;
\r
958 if (txConfig->CanTpTxTaType == CANTP_PHYSICAL) {
\r
961 DET_REPORTERROR( MODULE_ID_CANTP, 0, SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TATYPE );
\r
964 } else { // CANTP_STANDARD
\r
965 if (txRuntime->transferTotal <= MAX_PAYLOAD_CF_STD_ADDR) {
\r
966 ret = SINGLE_FRAME;
\r
968 if (txConfig->CanTpTxTaType == CANTP_PHYSICAL) {
\r
971 DET_REPORTERROR( MODULE_ID_CANTP, 0, SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TATYPE );
\r
979 // - - - - - - - - - - - - - -
\r
982 static inline Std_ReturnType sendSingleFrame(const CanTp_TxNSduType *txConfig,
\r
983 CanTp_ChannelPrivateType *txRuntime) {
\r
984 Std_ReturnType ret;
\r
985 uint16 indexCount = 0;
\r
986 PduInfoType pduInfo;
\r
987 uint8 sduData[CANIF_PDU_MAX_LENGTH];
\r
990 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
991 sduData[indexCount++] = (uint8) txConfig->CanTpNTa->CanTpNTa; // Target address.
\r
993 sduData[indexCount++] = ISO15765_TPCI_SF | txRuntime->transferTotal; // 734 PC-lint: Okej att casta till uint8?
\r
994 for (int i = 0; i < txRuntime->transferTotal; i++) {
\r
995 sduData[indexCount++] = txRuntime->pdurBuffer->SduDataPtr[i];
\r
998 pduInfo.SduDataPtr = sduData;
\r
999 pduInfo.SduLength = indexCount;
\r
1000 ret = canTansmitPaddingHelper(txConfig, txRuntime, &pduInfo);
\r
1004 // - - - - - - - - - - - - - -
\r
1006 static inline Std_ReturnType sendFirstFrame(const CanTp_TxNSduType *txConfig,
\r
1007 CanTp_ChannelPrivateType *txRuntime) {
\r
1008 Std_ReturnType ret;
\r
1009 uint8 indexCount = 0;
\r
1011 PduInfoType pduInfo;
\r
1012 uint8 sduData[CANIF_PDU_MAX_LENGTH];
\r
1014 DEBUG( DEBUG_MEDIUM, "sendFirstFrame called!\n");
\r
1016 if (txConfig->CanTpAddressingMode == CANTP_EXTENDED) { /** @req CANTP094 *//** @req CANTP095 */
\r
1017 sduData[indexCount++] = (uint8) txConfig->CanTpNTa->CanTpNTa; // Target address.
\r
1019 sduData[indexCount++] = ISO15765_TPCI_FF | (uint8)(
\r
1020 (txRuntime->transferTotal & 0xf00) >> 8);
\r
1021 sduData[indexCount++] = (uint8)(txRuntime->transferTotal & 0xff);
\r
1022 for (i = 0; indexCount < CANIF_PDU_MAX_LENGTH; i++) {
\r
1023 sduData[indexCount++] = txRuntime->pdurBuffer->SduDataPtr[i];
\r
1024 txRuntime->pdurBufferCount++;
\r
1025 if (txRuntime->pdurBufferCount > txRuntime->pdurBuffer->SduLength) {
\r
1026 // TODO: Report failure - this is unexpected.
\r
1028 txRuntime->transferCount++;
\r
1030 pduInfo.SduDataPtr = sduData;
\r
1031 pduInfo.SduLength = indexCount;
\r
1032 ret = canTansmitPaddingHelper(txConfig, txRuntime, &pduInfo);
\r
1036 // - - - - - - - - - - - - - -
\r
1038 static inline BufReq_ReturnType canTpTransmitHelper(const CanTp_TxNSduType *txConfig,
\r
1039 CanTp_ChannelPrivateType *txRuntime) {
\r
1041 BufReq_ReturnType pdurResp = BUFREQ_NOT_OK;
\r
1042 Std_ReturnType res = E_NOT_OK;
\r
1043 ISO15765FrameType iso15765Frame = INVALID_FRAME;
\r
1045 pdurResp = PduR_CanTpProvideTxBuffer(txConfig->PduR_PduId, &txRuntime->pdurBuffer, 0); /** @req CANTP226 */ /** @req CANTP186 */
\r
1046 //if (txRuntime->iso15765.stateTimeoutCount != 0) { TODO: WHY WAS THIS DONE?
\r
1047 VALIDATE( txRuntime->pdurBuffer->SduDataPtr != NULL,
\r
1048 SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TX_BUFFER );
\r
1049 if (pdurResp == BUFREQ_OK) {
\r
1050 iso15765Frame = calcRequiredProtocolFrameType(txConfig, txRuntime);
\r
1051 switch (iso15765Frame) {
\r
1052 case SINGLE_FRAME:
\r
1053 res = sendSingleFrame(txConfig, txRuntime); /** @req CANTP231 */
\r
1054 if (res == E_OK) {
\r
1055 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
1056 txRuntime->iso15765.state = TX_WAIT_TX_CONFIRMATION;
\r
1058 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_OK); /** @req CANTP204 */
\r
1059 txRuntime->iso15765.state = IDLE;
\r
1060 txRuntime->mode = CANTP_TX_WAIT;
\r
1063 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1064 txRuntime->iso15765.state = IDLE;
\r
1065 txRuntime->mode = CANTP_TX_WAIT;
\r
1068 case FIRST_FRAME: {
\r
1069 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNbs); /** @req CANTP264 */
\r
1070 if ( txRuntime->iso15765.stateTimeoutCount == 0 ) {
\r
1071 DEBUG( DEBUG_MEDIUM, "WARNING! Too low CanTpNbs timeout!\n" );
\r
1073 txRuntime->iso15765.state = TX_WAIT_FLOW_CONTROL; // We will always expect a flow control at this stage.
\r
1074 res = sendFirstFrame(txConfig, txRuntime); /** @req CANTP231 */
\r
1075 if (res == E_OK) {
\r
1076 txRuntime->mode = CANTP_TX_PROCESSING;
\r
1080 case INVALID_FRAME:
\r
1082 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1083 txRuntime->iso15765.state = IDLE;
\r
1084 txRuntime->mode = CANTP_TX_WAIT;
\r
1087 } else if (pdurResp == BUFREQ_NOT_OK) {
\r
1088 PduR_CanTpTxConfirmation(txConfig->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1089 txRuntime->iso15765.state = IDLE;
\r
1090 txRuntime->mode = CANTP_TX_WAIT;
\r
1091 } else if (pdurResp == BUFREQ_BUSY) {
\r
1092 /** @req CANTP184 */
\r
1093 txRuntime->iso15765.state = TX_WAIT_CAN_TP_TRANSMIT_PENDING; // We have to issue this request later from main until timeout.
\r
1094 txRuntime->mode = CANTP_TX_PROCESSING;
\r
1097 // TDDO: Put this in a logfile? Error response should have been sent from main.
\r
1103 // - - - - - - - - - - - - - -
\r
1106 Std_ReturnType CanTp_Transmit(PduIdType CanTpTxSduId,
\r
1107 const PduInfoType *CanTpTxInfoPtr) /** @req CANTP176 */
\r
1109 const CanTp_TxNSduType *txConfig = NULL;
\r
1110 CanTp_ChannelPrivateType *txRuntime = NULL;
\r
1111 BufReq_ReturnType res = BUFREQ_NOT_OK;
\r
1112 Std_ReturnType ret = 0;
\r
1113 PduIdType CanTp_InternalTxNSduId;
\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_RXID_LIST_SIZE, SERVICE_ID_CANTP_TRANSMIT, CANTP_E_INVALID_TX_ID );
\r
1123 if( CanTpConfig.CanTpRxIdList[CanTpTxSduId].CanTpNSduIndex != 0xFFFF ) {
\r
1124 CanTp_InternalTxNSduId = CanTpConfig.CanTpRxIdList[CanTpTxSduId].CanTpNSduIndex;
\r
1126 txConfig =&CanTpConfig.CanTpNSduList[CanTp_InternalTxNSduId].configData.CanTpTxNSdu;
\r
1128 txRuntime = &CanTpRunTimeData.runtimeDataList[txConfig->CanTpTxChannel]; // Runtime data.
\r
1129 if (txRuntime->iso15765.state == IDLE) {
\r
1130 txRuntime->pdurBufferCount = 0;
\r
1131 txRuntime->pdurBufferCount = 0;
\r
1132 txRuntime->transferCount = 0;
\r
1133 txRuntime->iso15765.framesHandledCount = 0;
\r
1134 txRuntime->transferTotal = CanTpTxInfoPtr->SduLength; /** @req CANTP225 */
\r
1135 txRuntime->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(txConfig->CanTpNcs);
\r
1136 txRuntime->mode = CANTP_TX_PROCESSING;
\r
1137 txRuntime->iso15765.state = TX_WAIT_CAN_TP_TRANSMIT_CAN_TP_PROVIDE_TX_BUFFER;
\r
1139 res = canTpTransmitHelper(txConfig, txRuntime);
\r
1145 case BUFREQ_NOT_OK:
\r
1146 ret = E_NOT_OK; /** @req CANTP072 */
\r
1153 DEBUG( DEBUG_MEDIUM, "CanTp can't transmit, it is already occupied!\n", CanTpTxSduId);
\r
1154 ret = E_NOT_OK; /** @req CANTP123 *//** @req CANTP206 */
\r
1158 return ret; // CAN level error code.
\r
1161 // - - - - - - - - - - - - - -
\r
1163 #if FRTP_CANCEL_TRANSMIT_REQUEST
\r
1164 Std_ReturnType FrTp_CancelTransmitRequest(PduIdType FrTpTxPduId,
\r
1165 FrTp_CancelReasonType FrTpCancelReason)
\r
1171 // - - - - - - - - - - - - - -
\r
1174 void CanTp_Init(void)
\r
1176 CanTp_ChannelPrivateType *runtimeData;
\r
1177 const CanTp_TxNSduType *txConfigParams;
\r
1178 const CanTp_RxNSduType *rxConfigParams;
\r
1180 for (int i=0; i < CANTP_NSDU_CONFIG_LIST_SIZE; i++) {
\r
1181 if ( CanTpConfig.CanTpNSduList[i].direction == IS015765_TRANSMIT ) {
\r
1182 txConfigParams = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1183 if (txConfigParams->CanTpTxChannel < CANTP_NSDU_RUNTIME_LIST_SIZE) {
\r
1184 runtimeData = &CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel];
\r
1186 runtimeData = &CanTpRunTimeData.runtimeDataList[CANTP_NSDU_RUNTIME_LIST_SIZE-1];
\r
1188 initTx15765RuntimeData( txConfigParams, runtimeData);
\r
1190 rxConfigParams = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1191 if (rxConfigParams->CanTpRxChannel < CANTP_NSDU_RUNTIME_LIST_SIZE) {
\r
1192 runtimeData = &CanTpRunTimeData.runtimeDataList[rxConfigParams->CanTpRxChannel];
\r
1194 runtimeData = &CanTpRunTimeData.runtimeDataList[CANTP_NSDU_RUNTIME_LIST_SIZE-1];
\r
1196 initRx15765RuntimeData( rxConfigParams, runtimeData);
\r
1199 fifoQueueInit( &CanTpRunTimeData.fifo );
\r
1200 CanTpRunTimeData.internalState = CANTP_ON; /** @req CANTP170 */
\r
1203 // - - - - - - - - - - - - - -
\r
1205 void CanTp_RxIndication(PduIdType CanTpRxPduId, /** @req CANTP078 */ /** @req CANTP035 */
\r
1206 const PduInfoType *CanTpRxPduPtr)
\r
1208 CanTpFifoQueueItem item;
\r
1210 if( CanTpRunTimeData.internalState != CANTP_ON ) {
\r
1211 DET_REPORTERROR(MODULE_ID_CANTP, 0, SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_UNINIT ); /** @req CANTP238 */ /** @req CANTP031 */
\r
1215 item.PduId = CanTpRxPduId;
\r
1216 item.SduLength = CanTpRxPduPtr->SduLength;
\r
1217 for (int i=0; i<item.SduLength; i++) {
\r
1218 item.SduData[i] = CanTpRxPduPtr->SduDataPtr[i];
\r
1220 if ( fifoQueueWrite( &CanTpRunTimeData.fifo, &item ) == FALSE ) { /** @req CANTP077 *//** @req CANTP235 */
\r
1221 DEBUG( DEBUG_MEDIUM, "WARNING!: Frames are lost!\n");
\r
1225 // - - - - - - - - - - - - - -
\r
1227 void CanTp_RxIndication_Main(PduIdType CanTpRxPduId,
\r
1228 const PduInfoType *CanTpRxPduPtr)
\r
1230 const CanTp_RxNSduType *rxConfigParams; // Params reside in ROM.
\r
1231 const CanTp_TxNSduType *txConfigParams;
\r
1232 const CanTp_AddressingFormantType *addressingFormat; // Configured
\r
1233 CanTp_ChannelPrivateType *runtimeParams; // Params reside in RAM.
\r
1234 ISO15765FrameType frameType;
\r
1235 PduIdType CanTpTxNSduId, CanTpRxNSduId;
\r
1237 DEBUG( DEBUG_MEDIUM, "CanTp_RxIndication: PduId=%d, [", CanTpRxPduId);
\r
1238 for (int i=0; i<CanTpRxPduPtr->SduLength; i++) {
\r
1239 DEBUG( DEBUG_MEDIUM, "%x, ", CanTpRxPduPtr->SduDataPtr[i]);
\r
1241 DEBUG( DEBUG_MEDIUM, "]");
\r
1243 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1244 SERVICE_ID_CANTP_RX_INDICATION, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1246 addressingFormat = &CanTpConfig.CanTpRxIdList[CanTpRxPduId].CanTpAddressingMode;
\r
1248 /* TODO John - Use a different indication of not set than 0xFFFF? */
\r
1249 frameType = getFrameType(addressingFormat, CanTpRxPduPtr); /** @req CANTP094 *//** @req CANTP095 */
\r
1250 if( frameType == FLOW_CONTROL_CTS_FRAME ) {
\r
1251 if( CanTpConfig.CanTpRxIdList[CanTpRxPduId].CanTpReferringTxIndex != 0xFFFF ) {
\r
1252 CanTpTxNSduId = CanTpConfig.CanTpRxIdList[CanTpRxPduId].CanTpReferringTxIndex;
\r
1253 txConfigParams = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[CanTpTxNSduId].configData;
\r
1254 runtimeParams = &CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel];
\r
1257 txConfigParams = NULL;
\r
1259 rxConfigParams = NULL;
\r
1262 if( CanTpConfig.CanTpRxIdList[CanTpRxPduId].CanTpNSduIndex != 0xFFFF ) {
\r
1263 CanTpRxNSduId = CanTpConfig.CanTpRxIdList[CanTpRxPduId].CanTpNSduIndex;
\r
1264 rxConfigParams = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[CanTpRxNSduId].configData; /** @req CANTP120 */
\r
1265 runtimeParams = &CanTpRunTimeData.runtimeDataList[rxConfigParams->CanTpRxChannel]; /** @req CANTP096 *//** @req CANTP121 *//** @req CANTP122 *//** @req CANTP190 */
\r
1268 rxConfigParams = NULL;
\r
1270 txConfigParams = NULL;
\r
1275 switch (frameType) {
\r
1276 case SINGLE_FRAME: {
\r
1277 if (rxConfigParams != NULL) {
\r
1278 DEBUG( DEBUG_MEDIUM, "calling handleSingleFrame!\n");
\r
1279 handleSingleFrame(rxConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1282 DEBUG( DEBUG_MEDIUM, "Single frame received on ISO15765-Tx - is ignored!\n");
\r
1286 case FIRST_FRAME: {
\r
1287 if (rxConfigParams != NULL) {
\r
1288 DEBUG( DEBUG_MEDIUM, "calling handleFirstFrame!\n");
\r
1289 handleFirstFrame(rxConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1291 DEBUG( DEBUG_MEDIUM, "First frame received on ISO15765-Tx - is ignored!\n");
\r
1295 case CONSECUTIVE_FRAME: {
\r
1296 if (rxConfigParams != NULL) {
\r
1297 DEBUG( DEBUG_MEDIUM, "calling handleConsecutiveFrame!\n");
\r
1298 handleConsecutiveFrame(rxConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1300 DEBUG( DEBUG_MEDIUM, "Consecutive frame received on ISO15765-Tx - is ignored!\n");
\r
1304 case FLOW_CONTROL_CTS_FRAME: {
\r
1305 if (txConfigParams != NULL) {
\r
1306 DEBUG( DEBUG_MEDIUM, "calling handleFlowControlFrame!\n");
\r
1307 handleFlowControlFrame(txConfigParams, runtimeParams, CanTpRxPduPtr);
\r
1309 DEBUG( DEBUG_MEDIUM, "Flow control frame received on ISO15765-Rx - is ignored!\n");
\r
1313 case INVALID_FRAME: {
\r
1314 DEBUG( DEBUG_MEDIUM, "INVALID_FRAME received - is ignored!\n!\n");
\r
1320 DEBUG( DEBUG_LOW, "CanTp_RxIndication_Main exit!\n");
\r
1323 // - - - - - - - - - - - - - -
\r
1325 void CanTp_TxConfirmation(PduIdType CanTpTxPduId) /** @req CANTP076 */
\r
1327 PduIdType CanTpNSduId;
\r
1328 const CanTp_RxNSduType *rxConfigParams = NULL;
\r
1329 const CanTp_TxNSduType *txConfigParams = NULL;
\r
1331 DEBUG( DEBUG_MEDIUM, "CanTp_TxConfirmation called.\n" );
\r
1333 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1334 SERVICE_ID_CANTP_TX_CONFIRMATION, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1335 VALIDATE_NO_RV( CanTpTxPduId < CANTP_RXID_LIST_SIZE,
\r
1336 SERVICE_ID_CANTP_TX_CONFIRMATION, CANTP_E_INVALID_TX_ID ); /** @req CANTP158 */
\r
1338 /** @req CANTP236 */
\r
1339 if( CanTpConfig.CanTpRxIdList[CanTpTxPduId].CanTpNSduIndex != 0xFFFF ) {
\r
1340 CanTpNSduId = CanTpConfig.CanTpRxIdList[CanTpTxPduId].CanTpNSduIndex;
\r
1341 if ( CanTpConfig.CanTpNSduList[CanTpNSduId].direction == IS015765_TRANSMIT ) {
\r
1342 txConfigParams = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[CanTpNSduId].configData;
\r
1343 CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel].iso15765.NasNarPending = FALSE;
\r
1344 #if (CANTP_IMMEDIATE_TX_CONFIRMATION == STD_OFF)
\r
1345 CanTpRunTimeData.runtimeDataList[txConfigParams->CanTpTxChannel].iso15765.txConfirmed = TRUE;
\r
1348 rxConfigParams = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[CanTpNSduId].configData;
\r
1349 CanTpRunTimeData.runtimeDataList[rxConfigParams->CanTpRxChannel].iso15765.NasNarPending = FALSE;
\r
1356 // - - - - - - - - - - - - - -
\r
1358 void CanTp_Shutdown(void) /** @req CANTP202 *//** @req CANTP200 *//** @req CANTP010 */
\r
1360 VALIDATE_NO_RV( CanTpRunTimeData.internalState == CANTP_ON,
\r
1361 SERVICE_ID_CANTP_SHUTDOWN, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1363 CanTpRunTimeData.internalState = CANTP_OFF;
\r
1366 // - - - - - - - - - - - - - -
\r
1369 static inline boolean checkNasNarTimeout(CanTp_ChannelPrivateType *runtimeData) {
\r
1370 boolean ret = FALSE;
\r
1371 if (runtimeData->iso15765.NasNarPending) {
\r
1372 TIMER_DECREMENT(runtimeData->iso15765.NasNarTimeoutCount);
\r
1373 if (runtimeData->iso15765.NasNarTimeoutCount == 0) {
\r
1374 DEBUG( DEBUG_MEDIUM, "NAS timed out.\n" );
\r
1375 runtimeData->iso15765.state = IDLE;
\r
1376 runtimeData->iso15765.NasNarPending = FALSE;
\r
1383 // - - - - - - - - - - - - - -
\r
1386 void CanTp_MainFunction(void)
\r
1388 BufReq_ReturnType ret;
\r
1389 CanTpFifoQueueItem item;
\r
1390 PduLengthType bytesWrittenToSduRBuffer;
\r
1392 CanTp_ChannelPrivateType *txRuntimeListItem = NULL;
\r
1393 CanTp_ChannelPrivateType *rxRuntimeListItem = NULL;
\r
1395 const CanTp_TxNSduType *txConfigListItem = NULL;
\r
1396 const CanTp_RxNSduType *rxConfigListItem = NULL;
\r
1398 if( CanTpRunTimeData.internalState != CANTP_ON ) {
\r
1399 DET_REPORTERROR(MODULE_ID_CANTP, 0, SERVICE_ID_CANTP_MAIN_FUNCTION, CANTP_E_UNINIT ); /** @req CANTP031 */
\r
1403 // Dispatch the messages that resides in the FIFO to CanTp_RxIndication_Main.
\r
1404 while ( fifoQueueRead( &CanTpRunTimeData.fifo, &item ) == TRUE ) {
\r
1405 PduInfoType pduInfo;
\r
1406 pduInfo.SduDataPtr = item.SduData;
\r
1407 pduInfo.SduLength = item.SduLength;
\r
1408 CanTp_RxIndication_Main( item.PduId, &pduInfo );
\r
1411 for( int i=0; i < CANTP_NSDU_CONFIG_LIST_SIZE; i++ ) {
\r
1412 #if 0 // TODO: Not tested yet
\r
1413 if (checkNasNarTimeout( txRuntimeListItem )) { /** @req CANTP075 */
\r
1414 PduR_CanTpTxConfirmation(txConfigListItem->PduR_CanTpTxPduId, NTFRSLT_NOT_OK); /** @req CANTP074 */ /** @req CANTP204 */
\r
1418 if ( CanTpConfig.CanTpNSduList[i].direction == IS015765_TRANSMIT ) {
\r
1419 txConfigListItem = (CanTp_TxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1420 txRuntimeListItem = &CanTpRunTimeData.runtimeDataList[txConfigListItem->CanTpTxChannel];
\r
1422 switch (txRuntimeListItem->iso15765.state) {
\r
1423 case TX_WAIT_CAN_TP_TRANSMIT_CAN_TP_PROVIDE_TX_BUFFER:
\r
1425 TIMER_DECREMENT(txRuntimeListItem->iso15765.stateTimeoutCount); /** @req CANTP185 */
\r
1426 if (txRuntimeListItem->iso15765.stateTimeoutCount == 0){
\r
1427 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 *//** @req CANTP185 */
\r
1429 txRuntimeListItem->iso15765.state = IDLE;
\r
1430 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1433 case TX_WAIT_CAN_TP_TRANSMIT_PENDING: {
\r
1434 (void) canTpTransmitHelper(txConfigListItem, txRuntimeListItem);/** @req CANTP184 */ /** @req CANTP089 */
\r
1437 case TX_WAIT_SEND_CONSECUTIVE_FRAME: {
\r
1438 TIMER_DECREMENT(txRuntimeListItem->iso15765.stateTimeoutCount); // Make sure that STmin timer has expired.
\r
1439 if (txRuntimeListItem->iso15765.stateTimeoutCount == 0) {
\r
1440 ret = sendConsecutiveFrame(txConfigListItem, txRuntimeListItem);
\r
1441 if ( ret == E_OK ) {
\r
1442 handleConsecutiveFrameSent(txConfigListItem, txRuntimeListItem);
\r
1444 DEBUG( DEBUG_MEDIUM, "ERROR: Consecutive frame could not be sent!\n");
\r
1445 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1446 txRuntimeListItem->iso15765.state = IDLE;
\r
1447 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1450 DEBUG( DEBUG_MEDIUM, "Waiting for STmin timer to expire!\n");
\r
1454 case TX_WAIT_FLOW_CONTROL:
\r
1455 //DEBUG( DEBUG_MEDIUM, "Waiting for flow control!\n");
\r
1456 TIMER_DECREMENT(txRuntimeListItem->iso15765.stateTimeoutCount);
\r
1457 if (txRuntimeListItem->iso15765.stateTimeoutCount == 0) {
\r
1458 DEBUG( DEBUG_MEDIUM, "State TX_WAIT_FLOW_CONTROL timed out!\n");
\r
1459 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */ /** @req CANTP185 */
\r
1460 txRuntimeListItem->iso15765.state = IDLE;
\r
1461 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1464 case TX_WAIT_TX_CONFIRMATION_CF:
\r
1465 if (txRuntimeListItem->iso15765.txConfirmed) {
\r
1466 txRuntimeListItem->iso15765.state = TX_WAIT_SEND_CONSECUTIVE_FRAME;
\r
1468 checkNasNarTimeout( txRuntimeListItem );
\r
1471 case TX_WAIT_TX_CONFIRMATION:
\r
1472 if (txRuntimeListItem->iso15765.txConfirmed) {
\r
1473 PduR_CanTpTxConfirmation(txConfigListItem->PduR_PduId, NTFRSLT_OK); /** @req CANTP074 *//** @req CANTP09 *//** @req CANTP204 */
\r
1474 txRuntimeListItem->iso15765.state = IDLE;
\r
1475 txRuntimeListItem->mode = CANTP_TX_WAIT;
\r
1477 checkNasNarTimeout( txRuntimeListItem );
\r
1484 rxConfigListItem = (CanTp_RxNSduType*)&CanTpConfig.CanTpNSduList[i].configData;
\r
1485 rxRuntimeListItem = &CanTpRunTimeData.runtimeDataList[rxConfigListItem->CanTpRxChannel];
\r
1486 switch (rxRuntimeListItem->iso15765.state) {
\r
1487 case RX_WAIT_CONSECUTIVE_FRAME: {
\r
1488 TIMER_DECREMENT (rxRuntimeListItem->iso15765.stateTimeoutCount);
\r
1489 if (rxRuntimeListItem->iso15765.stateTimeoutCount == 0) {
\r
1490 DEBUG( DEBUG_MEDIUM, "TIMEOUT!\n");
\r
1491 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK);
\r
1492 rxRuntimeListItem->iso15765.state = IDLE;
\r
1493 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1497 case RX_WAIT_SDU_BUFFER: {
\r
1498 TIMER_DECREMENT (rxRuntimeListItem->iso15765.stateTimeoutCount);
\r
1499 /* We end up here if we have requested a buffer from the
\r
1500 * PDUR but the response have been BUSY. We assume
\r
1501 * we have data in our local buffer and we are expected
\r
1502 * to send a flow-control clear to send (CTS).
\r
1504 if (rxRuntimeListItem->iso15765.stateTimeoutCount == 0) { /** @req CANTP223 */
\r
1505 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP204 */
\r
1506 rxRuntimeListItem->iso15765.state = IDLE;
\r
1507 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1508 } else { /** @req CANTP222 */
\r
1509 PduLengthType bytesRemaining = 0;
\r
1510 ret = copySegmentToPduRRxBuffer(rxConfigListItem, /** @req CANTP067, copies from local buffer to PDUR buffer. */
\r
1511 rxRuntimeListItem,
\r
1512 rxRuntimeListItem->canFrameBuffer.data,
\r
1513 rxRuntimeListItem->canFrameBuffer.byteCount,
\r
1514 &bytesWrittenToSduRBuffer);
\r
1515 bytesRemaining = rxRuntimeListItem->transferTotal -
\r
1516 rxRuntimeListItem->transferCount;
\r
1517 if (bytesRemaining > 0) {
\r
1518 sendFlowControlFrame( rxConfigListItem, rxRuntimeListItem, ret ); /** @req CANTP224 (Busy or CTS) */
\r
1520 if (ret == BUFREQ_OK) {
\r
1521 if ( bytesRemaining > 0 ) {
\r
1522 rxRuntimeListItem->iso15765.stateTimeoutCount = CANTP_CONVERT_MS_TO_MAIN_CYCLES(rxConfigListItem->CanTpNcr); //UH
\r
1523 rxRuntimeListItem->iso15765.state = RX_WAIT_CONSECUTIVE_FRAME;
\r
1525 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_OK);
\r
1526 rxRuntimeListItem->iso15765.state = IDLE;
\r
1527 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1529 } else if (ret == BUFREQ_NOT_OK ) {
\r
1530 PduR_CanTpRxIndication(rxConfigListItem->PduR_PduId, NTFRSLT_E_NOT_OK); /** @req CANTP205 */
\r
1531 rxRuntimeListItem->iso15765.state = IDLE;
\r
1532 rxRuntimeListItem->mode = CANTP_RX_WAIT;
\r
1533 } else if ( ret == BUFREQ_BUSY ) {
\r
1534 DEBUG( DEBUG_MEDIUM, "Still busy!\n");
\r