10#if HAL_USE_CAN || EFI_UNIT_TEST
39 int dlc =
offset + numBytes;
66 if (data !=
nullptr) {
67 for (
int i = 0; i < numBytes; i++) {
68 txmsg[i +
offset] = data[i];
73 if (
transmit(txmsg, timeout) == CAN_MSG_OK) {
96 efiPrintf(
"receiveFrame frameType=%d", frameType);
101 int numBytesAvailable, frameIdx;
102 const uint8_t *srcBuf;
161 int numBytesToCopy = minI(availableAtBuffer, numBytesAvailable);
162 if (destinationBuff !=
nullptr) {
163 memcpy(destinationBuff, srcBuf, numBytesToCopy);
165 srcBuf += numBytesToCopy;
168 numBytesAvailable -= numBytesToCopy;
170 for (
int i = 0; i < numBytesAvailable; i++) {
179 return numBytesToCopy;
192 PRINT(
"*** INFO: sendDataTimeout %d" PRINT_EOL, numBytes);
219 for (
size_t numFcReceived = 0; ; numFcReceived++) {
221#ifdef SERIAL_CAN_DEBUG
222 PRINT(
"*** ERROR: CAN Flow Control frame not received" PRINT_EOL);
236#ifdef SERIAL_CAN_DEBUG
237 efiPrintf(
"*** ERROR: CAN Flow Control mode not supported");
244 if (blockSize != 0 || minSeparationTime != 0) {
246#ifdef SERIAL_CAN_DEBUG
247 efiPrintf(
"*** ERROR: CAN Flow Control fields not supported");
257 while (numBytes > 0) {
261 header.
index = ((idx++) & 0x0f);
275 int numReadFromFifo = minI(numBytes,
rxFifoBuf.getCount());
278 for (i = 0; !
rxFifoBuf.isEmpty() && i < numReadFromFifo; i++) {
290 PRINT(
"*** INFO: streamAddToTxTimeout adding %d, in buffer %d" PRINT_EOL, numBytes,
txFifoBuf.getCount());
300 PRINT(
"*** INFO: streamAddToTxTimeout numBytesToAdd %d / numSent %d / numBytes %d" PRINT_EOL, numBytesToAdd, numSent, numBytes);
307 numBytes -= numBytesToAdd;
311 PRINT(
"*** INFO: streamAddToTxTimeout remaining goes to buffer %d" PRINT_EOL, numBytes);
319 PRINT(
"*** INFO: in buffer %d" PRINT_EOL,
txFifoBuf.getCount());
336 size_t availableBufferSpace = *np;
342 while (availableBufferSpace > 0) {
345 int numReceived =
receiveFrame(rxmsg, rxbuf + receivedSoFar, availableBufferSpace, timeout);
349 availableBufferSpace -= numReceived;
350 receivedSoFar += numReceived;
355 *np -= availableBufferSpace;
357#ifdef SERIAL_CAN_DEBUG
358 efiPrintf(
"* ret: %d %d (%d)", i, *np, availableBufferSpace);
359 for (
int j = 0; j < receivedSoFar; j++) {
360 efiPrintf(
"* [%d]: %02x", j, rxbuf[j]);
370 bool overflow =
false;
371 bool isFirstFrame =
true;
372 size_t availableAtBuffer = *
size;
373 uint8_t *buf = rxbuf;
395 efiPrintf(
"receiveFrame frameType=%d", frameType);
400 size_t numBytesAvailable;
402 const uint8_t *srcBuf;
427 efiPrintf(
"received frame index %d is not what expected %d",
447 efiPrintf(
"receive buffer is not enough %d > %d",
waitingForNumBytes, availableAtBuffer);
449 isFirstFrame =
false;
452 if (buf !=
nullptr) {
453 int numBytesToCopy = minI(availableAtBuffer, numBytesAvailable);
455 memcpy(buf, srcBuf, numBytesToCopy);
456 buf += numBytesToCopy;
457 availableAtBuffer -= numBytesToCopy;
460 if (numBytesAvailable > numBytesToCopy) {
476 return overflow ? 1 : 0;
480#if EFI_PROD_CODE || SIMULATOR
496 PRINT(
"*** INFO: sendDataTimeout %d" PRINT_EOL,
size);
523 size_t numFcReceived = 0;
524 int separationTimeUs = 0;
525 while (numFcReceived < 3) {
528 efiPrintf(
"IsoTp: Flow Control frame not received");
544 if (flowStatus == CAN_FLOW_STATUS_ABORT) {
545 efiPrintf(
"IsoTp: Flow Control ABORT");
550 if (flowStatus == CAN_FLOW_STATUS_WAIT_MORE) {
552 if (numFcReceived < 3) {
559 if (flowStatus != CAN_FLOW_STATUS_OK) {
560 efiPrintf(
"IsoTp: Flow Control unknown Status %d", flowStatus);
567 if (blockSize != 0) {
569 efiPrintf(
"IsoTp: Flow Control blockSize is not supported %d", blockSize);
574 if (minSeparationTime <= 0x7f) {
576 separationTimeUs = minSeparationTime * 1000;
577 }
else if ((minSeparationTime >= 0xf1) && (minSeparationTime <= 0xf9)) {
579 separationTimeUs = (minSeparationTime - 0xf0) * 100;
592 header.
index = ((idx++) & 0x0f);
601 if (separationTimeUs) {
602 chThdSleepMicroseconds(separationTimeUs);
int32_t can_sysinterval_t
void printCANRxFrame(const size_t busIndex, const CANRxFrame &rx)
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > txFifoBuf
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > rxFifoBuf
can_msg_t streamFlushTx(can_sysinterval_t timeout)
int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout)
int receiveFrame(const CANRxFrame &rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout)
ICanReceiver * rxTransport
can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout)
int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes)
can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout)
virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout)=0
virtual void onTpFirstFrame()=0
can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout)
int sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
void sendFlowControl(can_sysinterval_t timeout)
size_t isoHeaderByteIndex
int readTimeout(uint8_t *rxbuf, size_t *size, sysinterval_t timeout)
uint8_t waitingForFrameIndex
fifo_buffer_sync< CANRxFrame, ISOTP_RX_QUEUE_LEN > rxFifoBuf
int writeTimeout(const uint8_t *txbuf, size_t size, sysinterval_t timeout)
static EngineAccessor engine
static constexpr engine_configuration_s * engineConfiguration
static const size_t maxDlc
@ ISO_TP_FRAME_CONSECUTIVE
@ ISO_TP_FRAME_FLOW_CONTROL
uint8_t data8[8]
Frame data.