36 #pragma warning(disable : 4996) 39 #define KV_MAX_DLC ((uint16_t)8) 42 static const uint8_t GET_SLAVE_ID_ECHO[] = {UINT8(0x58), UINT8(0x43), UINT8(0x50)};
43 static const uint8_t GET_SLAVE_ID_INVERSE_ECHO[] = {UINT8(0xA7), UINT8(0xBC), UINT8(0xAF)};
51 extern Xcp_PduType Xcp_CtoIn;
52 extern Xcp_PduType Xcp_CtoOut;
56 static uint16_t XcpTl_SetDLC(uint16_t len);
57 static void XcpTl_SetCANFilter(
void);
58 static void Kv_Notification(
int hnd,
void *context,
unsigned int notifyEvent);
59 static bool XcpTl_MatchingAddress(uint32_t id0, uint32_t id1, uint16_t flag);
61 void Kv_Error(
const char *msg) { printf(
"ERROR[Kvaser]:: %s\n", msg); }
63 void Kv_Info(
const char *msg) { printf(
"INFO[Kvaser]:: %s\n", msg); }
65 void Kv_Check(
char *
id, canStatus stat) {
71 canGetErrorText(stat, err_buf,
sizeof(err_buf));
72 sprintf(msg_buf,
"%s: failed, stat=%d (%s)\n",
id, (
int)stat, err_buf);
77 static bool XcpTl_MatchingAddress(uint32_t id0, uint32_t id1, uint16_t flag) {
82 ext0 = XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(id0);
83 identifier = XCP_ON_CAN_STRIP_IDENTIFIER(id0);
84 ext1 = (flag == canMSG_EXT) ? 1 : 0;
86 return (identifier == id1) && (ext0 == ext1);
89 static void Kv_Notification(
int hnd,
void *context,
unsigned int notifyEvent) {
92 static uint8_t msg[64];
99 stat = canReadStatus(hnd, &status);
100 Kv_Check(
"canReadStatus", stat);
102 switch (notifyEvent) {
108 stat = canRead(hnd, &
id, msg, &dlc, &flag, &time);
109 Kv_Check(
"canRead", stat);
110 #if XCP_ON_CAN_MAX_DLC_REQUIRED == XCP_ON 111 if (dlc != XCP_MAX_CTO) {
116 if (XcpTl_MatchingAddress(XCP_ON_CAN_INBOUND_IDENTIFIER,
id, flag)) {
118 Xcp_CtoIn.data = msg + XCP_TRANSPORT_LAYER_BUFFER_OFFSET;
119 Xcp_DispatchCommand(&Xcp_CtoIn);
120 }
else if (XcpTl_MatchingAddress(XCP_ON_CAN_BROADCAST_IDENTIFIER,
id,
122 printf(
"BROADCAST request!!!\n");
126 #define canMSG_MASK 0x00ff 127 #define canMSG_RTR 0x0001 128 #define canMSG_STD 0x0002 129 #define canMSG_EXT 0x0004 130 #define canMSG_WAKEUP 0x0008 131 #define canMSG_NERR 0x0010 132 #define canMSG_ERROR_FRAME 0x0020 133 #define canMSG_TXACK 0x0040 134 #define canMSG_TXRQ 0x0080 138 case canNOTIFY_STATUS:
141 case canNOTIFY_ERROR:
142 Kv_Error(
"Error frame received");
144 case canNOTIFY_BUSONOFF:
145 if (status & canSTAT_ERROR_PASSIVE) {
146 Kv_Info(
"Error-Passive");
147 }
else if (status & canSTAT_BUS_OFF) {
149 }
else if (status & canSTAT_ERROR_WARNING) {
150 Kv_Info(
"Error-Warning");
151 }
else if (status & canSTAT_ERROR_ACTIVE) {
154 printf(
"BusOn/BusOff %lu\n", status);
159 printf(
"Unknown event %d\n", notifyEvent);
164 void XcpTl_Init(
void) {
171 canInitializeLibrary();
172 hnd = canOpenChannel(
173 0, canOPEN_ACCEPT_VIRTUAL |
174 canOPEN_NO_INIT_ACCESS );
176 Kv_Check(
"canOpenChannel", hnd);
180 XcpTl_Connection.handle = hnd;
182 stat = kvSetNotifyCallback(hnd, (kvCallback_t)&Kv_Notification, NULL,
183 canNOTIFY_RX | canNOTIFY_TX | canNOTIFY_ERROR |
184 canNOTIFY_STATUS | canNOTIFY_BUSONOFF);
185 Kv_Check(
"kvSetNotifyCallback", stat);
188 canSetBusParams(hnd, XCP_ON_CAN_FREQ, XCP_ON_CAN_TSEG1, XCP_ON_CAN_TSEG2,
189 XCP_ON_CAN_SJW, XCP_ON_CAN_NOSAMP, 0);
190 Kv_Check(
"SetBusParams", stat);
193 stat = canIoCtl(hnd, canIOCTL_SET_TIMER_SCALE, &ts, 4);
194 Kv_Check(
"SET_TIME_SCALE", stat);
196 XcpTl_SetCANFilter();
198 canFlushReceiveQueue(hnd);
199 canFlushTransmitQueue(hnd);
201 stat = canBusOn(hnd);
202 Kv_Check(
"canBusOn", stat);
205 void XcpTl_DeInit(
void) {
208 Kv_Info(
"Going off bus and closing channel");
209 stat = canBusOff(XcpTl_Connection.handle);
210 Kv_Check(
"canBusOff", stat);
216 int16_t XcpTl_FrameAvailable(uint32_t sec, uint32_t usec)
222 static uint16_t XcpTl_SetDLC(uint16_t len) {
223 static const uint16_t FD_DLCS[] = {12, 16, 20, 24, 32, 48, 64};
229 for (idx = 0; idx <
sizeof(FD_DLCS); ++idx) {
230 if (len <= FD_DLCS[idx]) {
237 static void XcpTl_SetCANFilter(
void) {
245 i0 = XCP_ON_CAN_STRIP_IDENTIFIER(XCP_ON_CAN_INBOUND_IDENTIFIER);
246 i1 = XCP_ON_CAN_STRIP_IDENTIFIER(XCP_ON_CAN_BROADCAST_IDENTIFIER);
249 mask = (i0 | i1) ^ filter;
251 if ((XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_INBOUND_IDENTIFIER)) ||
252 (XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_BROADCAST_IDENTIFIER))) {
259 stat = canSetAcceptanceFilter(XcpTl_Connection.handle, filter, mask, ext);
260 Kv_Check(
"canSetAcceptanceFilter", stat);
263 void XcpTl_Send(uint8_t
const *buf, uint16_t len) {
270 XCP_TL_ENTER_CRITICAL();
271 if (len > KV_MAX_DLC) {
272 sprintf(msg_buf,
"XcpTl_Send -- at most %d bytes supported, got %d.\n",
274 Kv_Error((
const char *)msg_buf);
278 id = XCP_ON_CAN_STRIP_IDENTIFIER(XCP_ON_CAN_OUTBOUND_IDENTIFIER);
279 ext = XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_OUTBOUND_IDENTIFIER);
280 flag = ext ? canMSG_EXT : canMSG_STD;
281 stat = canWrite(XcpTl_Connection.handle,
id, (
void *)buf, len, flag);
282 Kv_Check(
"canWrite", stat);
283 XCP_TL_LEAVE_CRITICAL();
286 void XcpTl_MainFunction(
void) {
289 if (XcpTl_FrameAvailable(0, 1000) > 0) {
296 void XcpTl_RxHandler(
void)
302 void XcpTl_SaveConnection(
void) {}
304 void XcpTl_ReleaseConnection(
void) {}
306 void XcpTl_PostQuitMessage(
void) {}
308 bool XcpTl_VerifyConnection(
void) {
return XCP_TRUE; }
310 void XcpTl_FeedReceiver(uint8_t octet) {}
312 void XcpTl_TransportLayerCmd_Res(Xcp_PduType
const *
const pdu) {}
314 void XcpTl_SetOptions(Xcp_OptionsType
const *options) {
315 CopyMemory(&Xcp_Options, options,
sizeof(Xcp_OptionsType));
318 void XcpTl_PrintConnectionInformation(
void) {
324 ext = XCP_ON_CAN_IS_EXTENDED_IDENTIFIER(XCP_ON_CAN_INBOUND_IDENTIFIER);
325 stat = canGetChannelData(XcpTl_Connection.handle,
326 canCHANNELDATA_CHAN_NO_ON_CARD, &num,
sizeof(num));
327 Kv_Check(
"canGetChannelData", stat);
328 stat = canGetChannelData(XcpTl_Connection.handle,
329 canCHANNELDATA_DEVDESCR_ASCII, &name,
sizeof(name));
330 Kv_Check(
"canGetChannelData", stat);
331 printf(
"\nXCPonCAN -- %s (channel %d), listening on 0x%X [%s]\n", name, num,
332 XCP_ON_CAN_STRIP_IDENTIFIER(XCP_ON_CAN_INBOUND_IDENTIFIER),
333 ext ?
"EXT" :
"STD");