18 #define PRINT_EOL "\n"
20 #define PRINT efiPrintf
25 #if HAL_USE_CAN || EFI_UNIT_TEST
38 #if HAL_USE_CAN || EFI_UNIT_TEST
45 txmsg[0] = (uint8_t)((header.
frameType & 0xf) << 4);
46 int offset, maxNumBytes;
50 maxNumBytes = minI(header.
numBytes, dlc - offset);
51 txmsg[0] |= maxNumBytes;
54 txmsg[0] |= (header.
numBytes >> 8) & 0xf;
55 txmsg[1] = (uint8_t)(header.
numBytes & 0xff);
57 maxNumBytes = minI(header.
numBytes, dlc - offset);
60 txmsg[0] |= header.
index & 0xf;
63 maxNumBytes = dlc - offset;
66 txmsg[0] |= header.
fcFlag & 0xf;
77 int numBytes = minI(maxNumBytes, num);
79 if (data !=
nullptr) {
80 for (
int i = 0; i < numBytes; i++) {
81 txmsg[i + offset] = data[i];
93 if (rxmsg ==
nullptr || rxmsg->
DLC < 1)
96 int frameType = (rxmsg->
data8[0] >> 4) & 0xf;
97 int numBytesAvailable, frameIdx;
98 uint8_t *srcBuf = rxmsg->
data8;
101 numBytesAvailable = rxmsg->
data8[0] & 0xf;
102 srcBuf = rxmsg->
data8 + 1;
109 srcBuf = rxmsg->
data8 + 2;
112 frameIdx = rxmsg->
data8[0] & 0xf;
118 srcBuf = rxmsg->
data8 + 1;
129 #if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME)
132 uint32_t crc = crc32((
void *) srcBuf, numBytesAvailable);
134 uint8_t crcBuffer[
sizeof(uint32_t)];
140 if (numBytesAvailable > 0)
141 memcpy(
tmpRxBuf +
sizeof(uint16_t), srcBuf, numBytesAvailable);
143 memcpy(
tmpRxBuf +
sizeof(uint16_t) + numBytesAvailable, crcBuffer,
sizeof(crcBuffer));
148 numBytesAvailable +=
sizeof(uint16_t) +
sizeof(crcBuffer);
152 int numBytesToCopy = minI(num, numBytesAvailable);
153 if (buf !=
nullptr) {
154 memcpy(buf, srcBuf, numBytesToCopy);
156 srcBuf += numBytesToCopy;
158 numBytesAvailable -= numBytesToCopy;
160 for (
int i = 0; i < numBytesAvailable; i++) {
174 return numBytesToCopy;
181 PRINT(
"*** INFO: sendDataTimeout %d" PRINT_EOL, numBytes);
192 return sendFrame(header, txbuf, numBytes, timeout);
201 int numSent =
sendFrame(header, txbuf + offset, numBytes, timeout);
204 int totalNumSent = numSent;
209 for (
int numFcReceived = 0; ; numFcReceived++) {
210 if (
streamer->
receive(CAN_ANY_MAILBOX, &rxmsg, timeout) != CAN_MSG_OK) {
211 #ifdef SERIAL_CAN_DEBUG
212 PRINT(
"*** ERROR: CAN Flow Control frame not received" PRINT_EOL);
218 int flowStatus = rxmsg.
data8[0] & 0xf;
220 if (flowStatus != CAN_FLOW_STATUS_OK) {
222 if (flowStatus == CAN_FLOW_STATUS_WAIT_MORE && numFcReceived < 3) {
225 #ifdef SERIAL_CAN_DEBUG
226 efiPrintf(
"*** ERROR: CAN Flow Control mode not supported");
231 int blockSize = rxmsg.
data8[1];
232 int minSeparationTime = rxmsg.
data8[2];
233 if (blockSize != 0 || minSeparationTime != 0) {
235 #ifdef SERIAL_CAN_DEBUG
236 efiPrintf(
"*** ERROR: CAN Flow Control fields not supported");
246 while (numBytes > 0) {
247 int len = minI(numBytes, 7);
250 header.
index = ((idx++) & 0x0f);
252 numSent =
sendFrame(header, txbuf + offset, len, timeout);
255 totalNumSent += numSent;
265 int numReadFromFifo = minI(numBytes,
rxFifoBuf.getCount());
268 for (i = 0; !
rxFifoBuf.isEmpty() && i < numReadFromFifo; i++) {
280 PRINT(
"*** INFO: streamAddToTxTimeout adding %d, in buffer %d" PRINT_EOL, numBytes,
txFifoBuf.getCount());
286 txFifoBuf.put(txbuf + offset, numBytesToAdd);
290 PRINT(
"*** INFO: streamAddToTxTimeout numBytesToAdd %d / numSent %d / numBytes %d" PRINT_EOL, numBytesToAdd, numSent, numBytes);
296 offset += numBytesToAdd;
297 numBytes -= numBytesToAdd;
301 PRINT(
"*** INFO: streamAddToTxTimeout remaining goes to buffer %d" PRINT_EOL, numBytes);
309 PRINT(
"*** INFO: in buffer %d" PRINT_EOL,
txFifoBuf.getCount());
326 size_t availableBufferSpace = *np;
332 while (availableBufferSpace > 0) {
334 if (
streamer->
receive(CAN_ANY_MAILBOX, &rxmsg, timeout) == CAN_MSG_OK) {
335 int numReceived =
receiveFrame(&rxmsg, rxbuf + receivedSoFar, availableBufferSpace, timeout);
339 availableBufferSpace -= numReceived;
340 receivedSoFar += numReceived;
345 *np -= availableBufferSpace;
347 #ifdef SERIAL_CAN_DEBUG
348 efiPrintf(
"* ret: %d %d (%d)", i, *np, availableBufferSpace);
349 for (
int j = 0; j < receivedSoFar; j++) {
350 efiPrintf(
"* [%d]: %02x", j, rxbuf[j]);
391 return CAN_MSG_TIMEOUT;
399 return state.streamAddToTxTimeout(np, txbuf, timeout);
403 return state.streamFlushTx(timeout);
410 return state.streamReceiveTimeout(np, rxbuf, timeout);
void registerCanListener(CanListener &listener)
int32_t can_sysinterval_t
virtual can_msg_t receive(canmbx_t mailbox, CANRxFrame *crfp, can_sysinterval_t timeout) override
virtual can_msg_t transmit(canmbx_t mailbox, const CanTxMessage *ctfp, can_sysinterval_t timeout) override
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > txFifoBuf
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > rxFifoBuf
int receiveFrame(CANRxFrame *rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout)
can_msg_t streamFlushTx(can_sysinterval_t timeout)
int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout)
int sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
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)
bool get(CanRxMessage &item, int timeout)
fifo_buffer_sync< CanRxMessage, CAN_FIFO_FRAME_SIZE > rxFifo
virtual void decodeFrame(const CANRxFrame &frame, efitick_t nowNt)
virtual can_msg_t transmit(canmbx_t mailbox, const CanTxMessage *ctfp, can_sysinterval_t timeout)=0
virtual can_msg_t receive(canmbx_t mailbox, CANRxFrame *crfp, can_sysinterval_t timeout)=0
uint32_t SWAP_UINT32(uint32_t x)
uint16_t SWAP_UINT16(uint16_t x)
bool warning(ObdCode code, const char *fmt,...)
@ CUSTOM_ERR_CAN_COMMUNICATION
engine_configuration_s * engineConfiguration
msg_t canStreamReceiveTimeout(size_t *np, uint8_t *rxbuf, sysinterval_t timeout)
static int isoTpPacketCounter
static CanStreamer streamer
static CanTsListener listener
msg_t canStreamAddToTxTimeout(size_t *np, const uint8_t *txbuf, sysinterval_t timeout)
msg_t canStreamFlushTx(sysinterval_t timeout)
@ ISO_TP_FRAME_CONSECUTIVE
@ ISO_TP_FRAME_FLOW_CONTROL
uint8_t data8[8]
Frame data.