XCP_SIM
arduino_can.cpp
1 /*
2  * BlueParrot XCP
3  *
4  * (C) 2022 by Christoph Schueler <github.com/Christoph2,
5  * cpu12.gems@googlemail.com>
6  *
7  * All Rights Reserved
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  *
23  * s. FLOSS-EXCEPTION.txt
24  */
25 
26 #include "xcp_config.h"
27 
28 #if XCP_TRANSPORT_LAYER == XCP_ON_CAN
29 
30 #include <stdint.h>
31 
32 #include <CAN.h>
33 
35 #include "xcp.h"
36 #include "xcp_hw.h"
39 static bool connected = false;
40 
41 void XcpTl_Init(void) {
42  Serial.begin(9600);
43  while (!Serial) {
44  }
45 
46  Serial.println("Starting Blueparrot XCP...");
47 
48  // start the CAN bus at 500 kbps
49  if (!CAN.begin(250E3)) {
50  Serial.println("Starting CAN failed!");
51  while (1) {
52  }
53  }
54  CAN.setTimeout(1000);
55 }
56 
57 void XcpTl_DeInit(void) {}
58 
59 void *XcpTl_Thread(void *param) {
60  XCP_FOREVER { XcpTl_MainFunction(); }
61  return NULL;
62 }
63 
64 void XcpTl_MainFunction(void) {
65  if (XcpTl_FrameAvailable(0, 1000) > 0) {
66  XcpTl_RxHandler();
67  }
68 }
69 
70 void XcpTl_RxHandler(void) {
71  static byte buffer[64];
72  byte dlc;
73 
74  digitalWrite(LED_BUILTIN, HIGH);
75  Serial.print("Received ");
76 
77  dlc = CAN.packetDlc();
78  if (CAN.packetExtended()) {
79  Serial.print("extended ");
80  }
81 
82  if (CAN.packetRtr()) {
83  // Remote transmission request, packet contains no data
84  Serial.print("RTR ");
85  }
86 
87  Serial.print("packet with id 0x");
88  Serial.print(CAN.packetId(), HEX);
89 
90  if (CAN.packetRtr()) {
91  Serial.print(" and requested length ");
92  Serial.println(dlc);
93  return;
94  } else {
95  Serial.print(" and length ");
96  Serial.println(dlc);
97 
98  int actual = CAN.readBytes(buffer, dlc);
99  Serial.print("actual length: ");
100  Serial.print(actual);
101  Serial.println();
102 
103  Xcp_CtoIn.len = dlc;
104  // Xcp_CtoIn.data = buffer + XCP_TRANSPORT_LAYER_BUFFER_OFFSET;
105 
106  XcpUtl_MemCopy(Xcp_CtoIn.data, &buffer, dlc);
107 
108  Xcp_DispatchCommand(&Xcp_CtoIn);
109  // only print packet data for non-RTR packets
110  // while (CAN.available()) {
111  // Serial.print((char)CAN.read());
112  //}
113  Serial.println();
114  }
115 
116  Serial.println();
117  digitalWrite(LED_BUILTIN, LOW);
118 }
119 
120 void XcpTl_TxHandler(void) {}
121 
122 int16_t XcpTl_FrameAvailable(uint32_t sec, uint32_t usec) {
123  int res;
124  XCP_UNREFERENCED_PARAMETER(sec);
125  XCP_UNREFERENCED_PARAMETER(usec);
126 
127  res = CAN.parsePacket();
128  if (res != 0) {
129  Serial.print("Frames avail!!!");
130  Serial.println();
131  }
132 
133  return res;
134 }
135 
136 void XcpTl_Send(uint8_t const *buf, uint16_t len) {
137  uint32_t can_id;
138 
139  can_id = XCP_ON_CAN_STRIP_IDENTIFIER(XCP_ON_CAN_OUTBOUND_IDENTIFIER);
140 
141  if (XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_OUTBOUND_IDENTIFIER)) {
142  CAN.beginExtendedPacket(can_id, len);
143  } else {
144  CAN.beginPacket(can_id);
145  }
146 
147  CAN.write(buf, len);
148  CAN.endPacket();
149 }
150 
151 void XcpTl_SaveConnection(void) { connected = XCP_TRUE; }
152 
153 void XcpTl_ReleaseConnection(void) { connected = XCP_FALSE; }
154 
155 bool XcpTl_VerifyConnection(void) { return connected; }
156 
157 void XcpTl_PrintConnectionInformation(void) {}
158 
159 #endif /* XCP_TRANSPORT_LAYER == XCP_ON_CAN */