LIN_master  0.1
Arduino LIN master emulation with preemptive background operation
LIN_master.cpp
Go to the documentation of this file.
1 
11 // include files
12 #include "Arduino.h"
13 #include "LIN_master.h"
14 
15 
24 void LIN_Master::begin(uint16_t Baudrate=19200, LIN_version_t Version=LIN_V2, bool Background=true)
25 {
26  // store parameters in class
27  baudrate = Baudrate; // communication baudrate [Baud]
28  version = Version; // LIN version for checksum calculation
29  background = Background; // background or blocking communication
30  if (baudrate < 12000) { // (rough) duration of sync break [ms] and max. frame w/o break [ms]
31  durationBreak = 2;
32  durationFrame = 13;
33  }
34  else {
35  durationBreak = 1;
36  durationFrame = 7;
37  }
38 
39  // reset internal variables
40  error = LIN_SUCCESS; // last LIN error. Is latched
41  state = LIN_STATE_IDLE; // status of LIN state machine
42 
43  // initialize serial interface
44  pSerial->begin(Baudrate); while(!(*pSerial));
45 
46  // set low timeout to avoid bus blocking
47  pSerial->setTimeout(2);
48 
49 } // LIN_Master::begin()
50 
51 
52 
58 
59  // reset internal variables
60  error = LIN_SUCCESS; // revert LIN error
61  state = LIN_STATE_OFF; // revert LIN state machine
62 
63  // close Serial3
64  pSerial->end();
65 
66  // restore default timeout
67  pSerial->setTimeout(1000);
68 
69 } // LIN_Master::end()
70 
71 
72 
79 uint8_t LIN_Master::protectID(uint8_t id)
80 {
81  uint8_t pid; // result = protected ID
82  uint8_t tmp; // temporary variable for calculating parity bits
83 
84  // copy (unprotected) ID
85  pid = id;
86 
87  // protect ID with parity bits
88  pid = (uint8_t) (pid & 0x3F); // clear upper bit 6&7
89  tmp = (uint8_t) ((pid ^ (pid>>1) ^ (pid>>2) ^ (pid>>4)) & 0x01); // -> pid[6] = PI0 = ID0^ID1^ID2^ID4
90  pid |= (uint8_t) (tmp << 6);
91  tmp = (uint8_t) (~((pid>>1) ^ (pid>>3) ^ (pid>>4) ^ (pid>>5)) & 0x01); // -> pid[6] = PI1 = ~(ID1^ID3^ID4^ID5)
92  pid |= (uint8_t) (tmp << 7);
93 
94  // return protected identifier
95  return pid;
96 
97 } // LIN_Master::protectID()
98 
99 
100 
109 uint8_t LIN_Master::checksum(uint8_t id, uint8_t numData, uint8_t *data)
110 {
111  uint16_t chk=0x00;
112 
113  // protect the ID
114  id = protectID(id);
115 
116  // LIN2.x uses extended checksum which includes protected ID, i.e. including parity bits
117  // LIN1.x uses classical checksum only over data bytes
118  // Diagnostic frames with ID 0x3C and 0x3D/0x7D always use classical checksum (see LIN spec "2.3.1.5 Checkum")
119  if (!((version == LIN_V1) || (id == 0x3C) || (id == 0x7D))) // if version 2 & no diagnostic frames (0x3C=60 (PID=0x3C) or 0x3D=61 (PID=0x7D))
120  chk = (uint16_t) id;
121 
122  // loop over data bytes
123  for (uint8_t i = 0; i < numData; i++)
124  {
125  chk += (uint16_t) (data[i]);
126  if (chk>255)
127  chk -= 255;
128  }
129  chk = (uint8_t)(0xFF - ((uint8_t) chk)); // bitwise invert
130 
131  // return frame checksum
132  return chk;
133 
134 } // LIN_Master::checksum()
135 
136 
137 
146 LIN_error_t LIN_Master::sendMasterRequest(uint8_t id, uint8_t numData, uint8_t *data)
147 {
148  // return immediately if LIN state machine not in idle state
149  if (state != LIN_STATE_IDLE)
150  {
151  // for printing error message, set debug level >=1
152  #if (LIN_DEBUG_LEVEL >= 1)
153  LIN_DEBUG_SERIAL.print(millis());
154  LIN_DEBUG_SERIAL.print("ms ");
155  LIN_DEBUG_SERIAL.print(serialName);
156  LIN_DEBUG_SERIAL.print(".sendMasterRequest(): state != LIN_STATE_IDLE (is ");
157  LIN_DEBUG_SERIAL.print(state);
158  LIN_DEBUG_SERIAL.println(")");
159  #endif
160  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_STATE);
162  memset(bufRx, 0, lenRx);
163  return LIN_ERROR_STATE;
164  }
165 
166  // set master request frame type
168 
169  // protect ID
170  id = protectID(id);
171 
172  // construct frame: BREAK + SYNC + ID + DATA + CHK. Note: BREAK is handled outside
173  bufTx[0] = 0x00; // sync break
174  bufTx[1] = 0x55; // sync field
175  bufTx[2] = id; // protected ID
176  memcpy(bufTx+3, data, numData); // data bytes
177  bufTx[3+numData] = checksum(id, numData, data); // frame checksum
178  lenTx = numData+4; // number of bytes to send (BREAK + SYNC + ID + DATA + CHK)
179  lenRx = lenTx; // number of bytes to receive (BREAK + SYNC + ID + DATA + CHK)
180 
181  // for printing data to send, set debug level >=2
182  #if (LIN_DEBUG_LEVEL >= 2)
183  LIN_DEBUG_SERIAL.print(millis());
184  LIN_DEBUG_SERIAL.print("ms ");
185  LIN_DEBUG_SERIAL.print(serialName);
186  LIN_DEBUG_SERIAL.print(".sendMasterRequest(): send ");
187  LIN_DEBUG_SERIAL.print(lenTx);
188  LIN_DEBUG_SERIAL.print(" bytes");
189  for (uint8_t i=0; i<lenTx; i++)
190  {
191  LIN_DEBUG_SERIAL.print(" 0x");
192  LIN_DEBUG_SERIAL.print(bufTx[i], HEX);
193  }
194  LIN_DEBUG_SERIAL.println();
195  #endif
196 
197  // clear receive buffer (required to recover from error)
198  while (pSerial->available())
199  pSerial->read();
200 
201  // set half baudrate for LIN break
202  #if defined(__AVR__)
203  *UCSRA &= ~(1<<U2X0); // on AVR clear "double baudrate"
204  #else
205  pSerial->begin(baudrate/2); while(!(*pSerial)); // else use built-in function
206  #endif
207 
208  // send sync break (=0x00 at 1/2 baudrate)
209  pSerial->write((uint8_t) bufTx[0]);
210 
211  // set new state of LIN state machine
213 
214 
215  // background operation -> use task scheduler
216  if (background)
217  {
218  // attach send handler for frame body
219  Tasks_Add((Task) wrapperSend, 0, durationBreak);
220 
221  } // background operation
222 
223  // blocking operation -> call handlers manually
224  else
225  {
226  // wait until break has been sent
227  pSerial->flush();
228 
229  // call send handler manually
230  wrapperSend();
231 
232  // wait until data has been sent
233  pSerial->flush();
234 
235  // call receive handler manually
236  wrapperReceive();
237 
238  } // blocking operation
239 
240 } // LIN_Master::sendMasterRequest
241 
242 
243 
253 LIN_error_t LIN_Master::receiveSlaveResponse(uint8_t id, uint8_t numData, void (*Rx_handler)(uint8_t, uint8_t*))
254 {
255  // return immediately if LIN state machine not in idle state
256  if (state != LIN_STATE_IDLE)
257  {
258  // for printing error message, set debug level >=1
259  #if (LIN_DEBUG_LEVEL >= 1)
260  LIN_DEBUG_SERIAL.print(millis());
261  LIN_DEBUG_SERIAL.print("ms ");
262  LIN_DEBUG_SERIAL.print(serialName);
263  LIN_DEBUG_SERIAL.print(".receiveSlaveResponse(): state != LIN_STATE_IDLE (is ");
264  LIN_DEBUG_SERIAL.print(state);
265  LIN_DEBUG_SERIAL.println(")");
266  #endif
267  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_STATE);
269  memset(bufRx, 0, lenRx);
270  return LIN_ERROR_STATE;
271  }
272 
273  // set slave response frame type
275 
276  // protect ID
277  id = protectID(id);
278 
279  // construct frame: BREAK + SYNC + ID. Note: BREAK is handled outside
280  bufTx[0] = 0x00; // sync break
281  bufTx[1] = 0x55; // sync field
282  bufTx[2] = id; // protected ID
283  lenTx = 3; // number of bytes to send (BREAK + SYNC + ID)
284  lenRx = 4 + numData; // number of bytes to receive (BREAK + SYNC + ID + DATA + CHK)
285 
286  // for printing data to send, set debug level >=2
287  #if (LIN_DEBUG_LEVEL >= 2)
288  LIN_DEBUG_SERIAL.print(millis());
289  LIN_DEBUG_SERIAL.print("ms ");
290  LIN_DEBUG_SERIAL.print(serialName);
291  LIN_DEBUG_SERIAL.print(".receiveSlaveResponse(): send ");
292  LIN_DEBUG_SERIAL.print(lenTx);
293  LIN_DEBUG_SERIAL.print(" bytes");
294  for (uint8_t i=0; i<lenTx; i++)
295  {
296  LIN_DEBUG_SERIAL.print(" 0x");
297  LIN_DEBUG_SERIAL.print(bufTx[i], HEX);
298  }
299  LIN_DEBUG_SERIAL.println();
300  #endif
301 
302  // clear receive buffer (required to recover from error)
303  while (pSerial->available())
304  pSerial->read();
305 
306  // set half baudrate for LIN break
307  #if defined(__AVR__)
308  *UCSRA &= ~(1<<U2X0); // on AVR clear "double baudrate"
309  #else
310  pSerial->begin(baudrate/2); while(!(*pSerial)); // else use built-in function
311  #endif
312 
313  // set callback function to handle received bytes when finished
314  rx_handler = Rx_handler;
315 
316  // send sync break (=0x00 at 1/2 baudrate)
317  pSerial->write((uint8_t) bufTx[0]);
318 
319  // set new state of LIN state machine
321 
322 
323  // background operation -> use task scheduler
324  if (background)
325  {
326  // attach send handler for frame body
327  Tasks_Add((Task) wrapperSend, 0, durationBreak);
328 
329  } // background operation
330 
331  // blocking operation -> call handlers manually
332  else
333  {
334  // wait until break has been sent
335  pSerial->flush();
336 
337  // call send handler manually
338  wrapperSend();
339 
340  // wait until slave has responded (with timeout)
341  uint32_t tStart = millis();
342  while ((pSerial->available() != lenRx-1) && ((millis() - tStart) < durationFrame));
343 
344  // call receive handler manually
345  wrapperReceive();
346 
347  } // blocking operation
348 
349 } // LIN_Master::receiveSlaveResponse (callback)
350 
351 
352 
362 LIN_error_t LIN_Master::receiveSlaveResponse(uint8_t id, uint8_t numData, uint8_t *data)
363 {
364  // store array pointer for default callback function
365  dataPtr = data;
366 
367  // call receive function with callback for actual transmission
369 
370 } // LIN_Master::receiveSlaveResponse (copy data)
371 
372 
373 
379 {
380  // check state of state machine
381  if (state != LIN_STATE_BREAK)
382  {
383  // for printing error message, set debug level >=1
384  #if (LIN_DEBUG_LEVEL >= 1)
385  LIN_DEBUG_SERIAL.print(millis());
386  LIN_DEBUG_SERIAL.print("ms ");
387  LIN_DEBUG_SERIAL.print(serialName);
388  LIN_DEBUG_SERIAL.print(".handlerSend(): state != LIN_STATE_BREAK (is ");
389  LIN_DEBUG_SERIAL.print(state);
390  LIN_DEBUG_SERIAL.println(")");
391  #endif
392  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_STATE);
394  memset(bufRx, 0, lenRx);
395  return;
396  }
397 
398 
399  // wait until break received (with timeout) before changing baudrate
400  uint32_t tStart = micros();
401  while ((!(pSerial->available())) && ((micros() - tStart) < 500));
402 
403 
404  // assert no timeout
405  if (!(pSerial->available()))
406  {
407  // for printing error message, set debug level >=1
408  #if (LIN_DEBUG_LEVEL >= 1)
409  LIN_DEBUG_SERIAL.print(millis());
410  LIN_DEBUG_SERIAL.print("ms ");
411  LIN_DEBUG_SERIAL.print(serialName);
412  LIN_DEBUG_SERIAL.println(".handlerSend(): receive BREAK timeout");
413  #endif
414  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_TIMEOUT);
416  memset(bufRx, 0, lenRx);
417  return;
418  }
419 
420  // assert correct echo
421  bufRx[0] = pSerial->read();
422  if (bufRx[0] != 0x00)
423  {
424  // for printing error message, set debug level >=1
425  #if (LIN_DEBUG_LEVEL >= 1)
426  LIN_DEBUG_SERIAL.print(millis());
427  LIN_DEBUG_SERIAL.print("ms ");
428  LIN_DEBUG_SERIAL.print(serialName);
429  LIN_DEBUG_SERIAL.print(".handlerSend(): received BREAK != 0x00 (is ");
430  LIN_DEBUG_SERIAL.print(bufRx[0]);
431  LIN_DEBUG_SERIAL.println(")");
432  #endif
433  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_ECHO);
435  memset(bufRx, 0, lenRx);
436  return;
437  }
438 
439  // BREAK echo read successfully
440  else
441  {
442  #if (LIN_DEBUG_LEVEL >= 2)
443  LIN_DEBUG_SERIAL.print(millis());
444  LIN_DEBUG_SERIAL.print("ms ");
445  LIN_DEBUG_SERIAL.print(serialName);
446  LIN_DEBUG_SERIAL.println(".handlerSend(): received BREAK echo");
447  #endif
448  }
449 
450 
451  // restore original baudrate after BREAK
452  #if defined(__AVR__)
453  *UCSRA |= (1<<U2X0); // on AVR restore "double baudrate"
454  #else
455  pSerial->begin(baudrate); while(!(*pSerial)); // else use built-in function
456  #endif
457 
458  // write remainder of frame or header
459  pSerial->write(bufTx+1, lenTx-1);
460 
461  // set new state of LIN state machine
463 
464  // background operation
465  if (background)
466  {
467  // attach receive handler for reading frame echo or header echo + slave response
468  Tasks_Add((Task) wrapperReceive, 0, durationFrame);
469 
470  } // background operation
471 
472 } // LIN_Master::handlerSend
473 
474 
475 
482 {
483  uint8_t i;
484 
485  // check state of state machine
486  if (state != LIN_STATE_FRAME)
487  {
488  // for printing error message, set debug level >=1
489  #if (LIN_DEBUG_LEVEL >= 1)
490  LIN_DEBUG_SERIAL.print(millis());
491  LIN_DEBUG_SERIAL.print("ms ");
492  LIN_DEBUG_SERIAL.print(serialName);
493  LIN_DEBUG_SERIAL.print(".handlerReceive: state != LIN_STATE_FRAME (is ");
494  LIN_DEBUG_SERIAL.print(state);
495  LIN_DEBUG_SERIAL.println(")");
496  #endif
497  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_STATE);
499  memset(bufRx, 0, lenRx);
500  return;
501  }
502 
503 
504  // wait until break received (with timeout) before changing baudrate
505  uint32_t tStart = micros();
506  while ((pSerial->available() != lenRx-1) && ((micros() - tStart) < 500));
507 
508 
509  // check if data was received (-1 because sync break already read)
510  if (pSerial->available() != lenRx-1)
511  {
512  // for printing error message, set debug level >=1
513  #if (LIN_DEBUG_LEVEL >= 1)
514  uint8_t num = pSerial->available();
515  LIN_DEBUG_SERIAL.print(millis());
516  LIN_DEBUG_SERIAL.print("ms ");
517  LIN_DEBUG_SERIAL.print(serialName);
518  LIN_DEBUG_SERIAL.print(".handlerReceive: receive frame timeout (");
519  LIN_DEBUG_SERIAL.print(num+1); LIN_DEBUG_SERIAL.print(" vs. "); LIN_DEBUG_SERIAL.print(lenRx);
520  LIN_DEBUG_SERIAL.println(")");
521  /*
522  for (i=0; i<num+1; i++)
523  {
524  LIN_DEBUG_SERIAL.print(" ");
525  LIN_DEBUG_SERIAL.print(i);
526  LIN_DEBUG_SERIAL.print(": 0x");
527  LIN_DEBUG_SERIAL.println((uint8_t) (bufRx[i]), HEX);
528  }
529  */
530  #endif
531  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_TIMEOUT);
533  memset(bufRx, 0, lenRx);
534  flagTxComplete = true;
535  return;
536  }
537 
538 
539  // copy received bytes to LIN buffer
540  for (i=1; i<lenRx; i++)
541  bufRx[i] = pSerial->read();
542 
543 
544  // for master request FRAME just check LIN echo
546  {
547  // check if sent and received data match
548  if (memcmp(bufRx, bufTx, lenTx) != 0)
549  {
550  // for printing error message, set debug level >=1
551  #if (LIN_DEBUG_LEVEL >= 1)
552  LIN_DEBUG_SERIAL.print(millis());
553  LIN_DEBUG_SERIAL.print("ms ");
554  LIN_DEBUG_SERIAL.print(serialName);
555  LIN_DEBUG_SERIAL.print(".handlerReceive: LIN frame echo mismatch:");
556  for (i=0; i<lenRx; i++)
557  {
558  LIN_DEBUG_SERIAL.print(" ");
559  LIN_DEBUG_SERIAL.print(i);
560  LIN_DEBUG_SERIAL.print(": 0x"); LIN_DEBUG_SERIAL.print((uint8_t) (bufRx[i]), HEX);
561  LIN_DEBUG_SERIAL.print(" vs. ");
562  LIN_DEBUG_SERIAL.print(" 0x"); LIN_DEBUG_SERIAL.print((uint8_t) (bufTx[i]), HEX);
563  LIN_DEBUG_SERIAL.println();
564  }
565  #endif
566  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_ECHO);
568  memset(bufRx, 0, lenRx);
569  flagTxComplete = true;
570  return;
571  } // frame echo mismatch
572 
573  // frame echo read successfully
574  else
575  {
576  #if (LIN_DEBUG_LEVEL >= 2)
577  LIN_DEBUG_SERIAL.print(millis());
578  LIN_DEBUG_SERIAL.print("ms ");
579  LIN_DEBUG_SERIAL.print(serialName);
580  LIN_DEBUG_SERIAL.println(".handlerReceive: received frame echo");
581  #endif
582 
583  // indicate that data transmission is complete
584  flagTxComplete = true;
585  }
586 
587  } // LIN_MASTER_REQUEST
588 
589 
590  // for slave response frame check header echo and frame checksum
591  else
592  {
593  // check if sent and received frame headers (BREAK+SYNC+ID) match
594  if (memcmp(bufRx, bufTx, 3) != 0) {
595  // for printing error message, set debug level >=1
596  #if (LIN_DEBUG_LEVEL >= 1)
597  LIN_DEBUG_SERIAL.print(millis());
598  LIN_DEBUG_SERIAL.print("ms ");
599  LIN_DEBUG_SERIAL.print(serialName);
600  LIN_DEBUG_SERIAL.print(".handlerReceive: LIN header echo mismatch:");
601  for (i=0; i<3; i++)
602  {
603  LIN_DEBUG_SERIAL.print(" ");
604  LIN_DEBUG_SERIAL.print(i);
605  LIN_DEBUG_SERIAL.print(": 0x"); LIN_DEBUG_SERIAL.print((uint8_t) (bufRx[i]), HEX);
606  LIN_DEBUG_SERIAL.print(" vs. ");
607  LIN_DEBUG_SERIAL.print(" 0x"); LIN_DEBUG_SERIAL.print((uint8_t) (bufTx[i]), HEX);
608  LIN_DEBUG_SERIAL.println();
609  }
610  #endif
611  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_ECHO);
613  memset(bufRx, 0, lenRx);
614  flagRxComplete = true;
615  return;
616  } // header echo mismatch
617 
618 
619  // assert checksum
620  uint8_t id = bufRx[2]; // frame ID
621  uint8_t numData = lenRx-4; // received length - (BREAK-SYNC+ID+CHK)
622  uint8_t *data = bufRx+3; // pointer to start of data bytes
623  uint8_t chk = bufRx[lenRx-1]; // received checksum
624  uint8_t chk_calc = checksum(id, numData, data); // calculated checksum
625  if (chk != chk_calc)
626  {
627  // for printing error message, set debug level >=1
628  #if (LIN_DEBUG_LEVEL >= 1)
629  LIN_DEBUG_SERIAL.print(millis());
630  LIN_DEBUG_SERIAL.print("ms ");
631  LIN_DEBUG_SERIAL.print(serialName);
632  LIN_DEBUG_SERIAL.print(".handlerReceive: checksum error (");
633  LIN_DEBUG_SERIAL.print(chk, HEX); LIN_DEBUG_SERIAL.print(" vs. "); LIN_DEBUG_SERIAL.print(chk_calc, HEX);
634  LIN_DEBUG_SERIAL.println(")");
635  #endif
636  error = (LIN_error_t)((uint8_t) error | (uint8_t) LIN_ERROR_CHK);
638  memset(bufRx, 0, lenRx);
639  flagRxComplete = true;
640  return;
641  } // checksum error
642 
643  // use callback function to handle received data. Only data bytes (- BREAK - SYNC - ID - CHK)
644  rx_handler(lenRx-4, bufRx+3);
645 
646  // indicate that data reception is complete
647  flagRxComplete = true;
648 
649  } // LIN_SLAVE_RESPONSE
650 
651 
652  // reset state of LIN state machine
654 
655 } // LIN_Master::handlerReceive
656 
657 
658 
664 void LIN_Master::defaultCallback(uint8_t numData, uint8_t *data)
665 {
666  // copy received data to user buffer
667  memcpy(dataPtr, data, numData);
668 
669 } // LIN_Master::defaultCallback
void defaultCallback(uint8_t numData, uint8_t *data)
receive callback function to copy data to buffer
Definition: LIN_master.cpp:664
bool flagRxComplete
flag to indicate that data reception is complete. Must be cleared manually
Definition: LIN_master.h:142
#define LIN_DEBUG_SERIAL
Serial interface used for debug output.
Definition: LIN_master.h:22
uint8_t checksum(uint8_t id, uint8_t numData, uint8_t *data)
calculate frame checksum
Definition: LIN_master.cpp:109
uint8_t lenRx
receive buffer length (max. 12)
Definition: LIN_master.h:127
void begin(uint16_t Baudrate, LIN_version_t Version, bool Background)
setup UART and LIN framework
Definition: LIN_master.cpp:24
error reading LIN echo
Definition: LIN_master.h:70
error in LIN state machine
Definition: LIN_master.h:69
LIN_error_t
LIN communication error codes.
Definition: LIN_master.h:67
LIN_version_t
LIN version of checksum.
Definition: LIN_master.h:49
uint8_t * dataPtr
pointer to data buffer in LIN_master3_copy()
Definition: LIN_master.h:131
LIN protocol version 2.
Definition: LIN_master.h:60
LIN_error_t receiveSlaveResponse(uint8_t id, uint8_t numData, void(*Rx_handler)(uint8_t, uint8_t *))
receive a slave response frame with callback function
Definition: LIN_master.cpp:253
void(* wrapperDefaultCallback)(uint8_t, uint8_t *)
wrapper for default receive callback function
Definition: LIN_master.h:115
break is being transmitted
Definition: LIN_master.h:83
uint8_t bufRx[12]
receive buffer incl. SYNC, DATA and CHK (max. 11B)
Definition: LIN_master.h:126
uint8_t lenTx
send buffer length (max. 12)
Definition: LIN_master.h:125
Base class for LIN master emulation.
uint8_t durationFrame
duration of frame w/o BREAK [ms]
Definition: LIN_master.h:128
LIN instance inactive.
Definition: LIN_master.h:81
no error
Definition: LIN_master.h:68
bool flagTxComplete
flag to indicate that data transmission is complete. Must be cleared manually
Definition: LIN_master.h:141
void handlerSend(void)
LIN master receive handler for task scheduler.
Definition: LIN_master.cpp:378
void end(void)
end UART communication void end(void); //!< end UART communication
Definition: LIN_master.cpp:57
no LIN transmission ongoing
Definition: LIN_master.h:82
void handlerReceive(void)
send handler for task scheduler
Definition: LIN_master.cpp:481
LIN_error_t error
error state. Is latched until cleared
Definition: LIN_master.h:143
uint16_t baudrate
communication baudrate [Baud]
Definition: LIN_master.h:119
LIN_status_t state
status of LIN state machine
Definition: LIN_master.h:129
LIN protocol version 2.
Definition: LIN_master.h:51
bool background
background or blocking operation
Definition: LIN_master.h:121
LIN_frame_t frameType
LIN frame type.
Definition: LIN_master.h:123
uint8_t durationBreak
duration of sync break [ms]
Definition: LIN_master.h:122
uint8_t protectID(uint8_t id)
calculate protected LIN ID
Definition: LIN_master.cpp:79
LIN_version_t version
LIN version for checksum calculation.
Definition: LIN_master.h:120
void(* wrapperReceive)(void)
wrapper for reception handler (for task scheduler)
Definition: LIN_master.h:114
LIN receive timeout.
Definition: LIN_master.h:71
LIN_error_t sendMasterRequest(uint8_t id, uint8_t numData, uint8_t *data)
send a master request frame
Definition: LIN_master.cpp:146
LIN protocol version 1.
Definition: LIN_master.h:59
void(* rx_handler)(uint8_t, uint8_t *)
handler to decode slave response (for receiveFrame())
Definition: LIN_master.h:130
frame is being transmitted
Definition: LIN_master.h:84
LIN checksum error.
Definition: LIN_master.h:72
void(* wrapperSend)(void)
wrapper for transmission handler (for task scheduler)
Definition: LIN_master.h:113
HardwareSerial * pSerial
pointer to used serial
Definition: LIN_master.h:109
LIN protocol version 1.
Definition: LIN_master.h:50
uint8_t bufTx[12]
send buffer incl. BREAK, SYNC, DATA and CHK (max. 12B)
Definition: LIN_master.h:124