Skip to content

Commit c6780bf

Browse files
committed
Add HardwareCAN - a abstract base class for implementing CAN interfaces across Arduino cores.
1 parent 844e4bf commit c6780bf

File tree

4 files changed

+293
-0
lines changed

4 files changed

+293
-0
lines changed

Diff for: api/CanMsg.h

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <[email protected]>
3+
* CAN library for Arduino.
4+
*
5+
* This file is free software; you can redistribute it and/or modify
6+
* it under the terms of either the GNU General Public License version 2
7+
* or the GNU Lesser General Public License version 2.1, both as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#ifndef ARDUINOCORE_API_CAN_MSG_H_
12+
#define ARDUINOCORE_API_CAN_MSG_H_
13+
14+
/**************************************************************************************
15+
* INCLUDE
16+
**************************************************************************************/
17+
18+
#include <cstdlib>
19+
#include <cstdint>
20+
#include <cstring>
21+
22+
#include <Arduino.h>
23+
24+
/**************************************************************************************
25+
* NAMESPACE
26+
**************************************************************************************/
27+
28+
namespace arduino
29+
{
30+
31+
/**************************************************************************************
32+
* CLASS DECLARATION
33+
**************************************************************************************/
34+
35+
class CanMsg : public Printable
36+
{
37+
public:
38+
static size_t constexpr MAX_DATA_LENGTH = 8;
39+
40+
CanMsg(uint32_t const can_id, uint8_t const can_data_len, uint8_t const * can_data_ptr)
41+
: id{can_id}
42+
, data_length{can_data_len}
43+
, data{0}
44+
{
45+
memcpy(data, can_data_ptr, min(can_data_len, MAX_DATA_LENGTH));
46+
}
47+
48+
CanMsg() : CanMsg(0, 0, nullptr) { }
49+
50+
CanMsg(CanMsg const & other)
51+
{
52+
this->id = other.id;
53+
this->data_length = other.data_length;
54+
memcpy(this->data, other.data, this->data_length);
55+
}
56+
57+
virtual ~CanMsg() { }
58+
59+
void operator = (CanMsg const & other)
60+
{
61+
if (this == &other)
62+
return;
63+
64+
this->id = other.id;
65+
this->data_length = other.data_length;
66+
memcpy(this->data, other.data, this->data_length);
67+
}
68+
69+
virtual size_t printTo(Print & p) const override
70+
{
71+
char buf[20] = {0};
72+
size_t len = 0;
73+
74+
/* Print the header. */
75+
len = snprintf(buf, sizeof(buf), "[%08X] (%d) : ", id, data_length);
76+
size_t n = p.write(buf, len);
77+
78+
/* Print the data. */
79+
for (size_t d = 0; d < data_length; d++)
80+
{
81+
len = snprintf(buf, sizeof(buf), "%02X", data[d]);
82+
n += p.write(buf, len);
83+
}
84+
85+
/* Wrap up. */
86+
return n;
87+
}
88+
89+
uint32_t id;
90+
uint8_t data_length;
91+
uint8_t data[MAX_DATA_LENGTH];
92+
};
93+
94+
/**************************************************************************************
95+
* NAMESPACE
96+
**************************************************************************************/
97+
98+
} /* arduino */
99+
100+
#endif /* ARDUINOCORE_API_CAN_MSG_H_ */

Diff for: api/CanMsgRingbuffer.cpp

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <[email protected]>
3+
* CAN library for Arduino.
4+
*
5+
* This file is free software; you can redistribute it and/or modify
6+
* it under the terms of either the GNU General Public License version 2
7+
* or the GNU Lesser General Public License version 2.1, both as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
/**************************************************************************************
12+
* INCLUDE
13+
**************************************************************************************/
14+
15+
#include "CanMsgRingbuffer.h"
16+
17+
/**************************************************************************************
18+
* NAMESPACE
19+
**************************************************************************************/
20+
21+
namespace arduino
22+
{
23+
24+
/**************************************************************************************
25+
* CTOR/DTOR
26+
**************************************************************************************/
27+
28+
CanMsgRingbuffer::CanMsgRingbuffer()
29+
: _head{0}
30+
, _tail{0}
31+
, _num_elems{0}
32+
{
33+
}
34+
35+
/**************************************************************************************
36+
* PUBLIC MEMBER FUNCTIONS
37+
**************************************************************************************/
38+
39+
void CanMsgRingbuffer::enqueue(CanMsg const & msg)
40+
{
41+
if (isFull())
42+
return;
43+
44+
_buf[_head] = msg;
45+
_head = next(_head);
46+
_num_elems++;
47+
}
48+
49+
CanMsg CanMsgRingbuffer::dequeue()
50+
{
51+
if (isEmpty())
52+
return CanMsg();
53+
54+
CanMsg const msg = _buf[_tail];
55+
_tail = next(_tail);
56+
_num_elems--;
57+
58+
return msg;
59+
}
60+
61+
/**************************************************************************************
62+
* NAMESPACE
63+
**************************************************************************************/
64+
65+
} /* arduino */

Diff for: api/CanMsgRingbuffer.h

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <[email protected]>
3+
* CAN library for Arduino.
4+
*
5+
* This file is free software; you can redistribute it and/or modify
6+
* it under the terms of either the GNU General Public License version 2
7+
* or the GNU Lesser General Public License version 2.1, both as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#ifndef ARDUINOCORE_API_CAN_MSG_RING_BUFFER_H_
12+
#define ARDUINOCORE_API_CAN_MSG_RING_BUFFER_H_
13+
14+
/**************************************************************************************
15+
* INCLUDE
16+
**************************************************************************************/
17+
18+
#include <cstdint>
19+
20+
#include "CanMsg.h"
21+
22+
/**************************************************************************************
23+
* NAMESPACE
24+
**************************************************************************************/
25+
26+
namespace arduino
27+
{
28+
29+
/**************************************************************************************
30+
* CLASS DECLARATION
31+
**************************************************************************************/
32+
33+
class CanMsgRingbuffer
34+
{
35+
public:
36+
static size_t constexpr RING_BUFFER_SIZE = 32U;
37+
38+
CanMsgRingbuffer();
39+
40+
inline bool isFull() const { return (_num_elems == RING_BUFFER_SIZE); }
41+
void enqueue(CanMsg const & msg);
42+
43+
inline bool isEmpty() const { return (_num_elems == 0); }
44+
CanMsg dequeue();
45+
46+
inline size_t available() const { return _num_elems; }
47+
48+
private:
49+
CanMsg _buf[RING_BUFFER_SIZE];
50+
volatile size_t _head;
51+
volatile size_t _tail;
52+
volatile size_t _num_elems;
53+
54+
inline size_t next(size_t const idx) const { return ((idx + 1) % RING_BUFFER_SIZE); }
55+
};
56+
57+
/**************************************************************************************
58+
* NAMESPACE
59+
**************************************************************************************/
60+
61+
} /* arduino */
62+
63+
#endif /* ARDUINOCORE_API_CAN_MSG_RING_BUFFER_H_ */

Diff for: api/HardwareCAN.h

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <[email protected]>
3+
* CAN library for Arduino.
4+
*
5+
* This file is free software; you can redistribute it and/or modify
6+
* it under the terms of either the GNU General Public License version 2
7+
* or the GNU Lesser General Public License version 2.1, both as
8+
* published by the Free Software Foundation.
9+
*/
10+
11+
#ifndef ARDUINOCORE_API_HARDWARECAN_H
12+
#define ARDUINOCORE_API_HARDWARECAN_H
13+
14+
/**************************************************************************************
15+
* INCLUDE
16+
**************************************************************************************/
17+
18+
#include "CanMsg.h"
19+
#include "CanMsgRingbuffer.h"
20+
21+
/**************************************************************************************
22+
* TYPEDEF
23+
**************************************************************************************/
24+
25+
enum class CanBitRate : int
26+
{
27+
BR_125k = 125000,
28+
BR_250k = 250000,
29+
BR_500k = 500000,
30+
BR_1000k = 1000000,
31+
};
32+
33+
/**************************************************************************************
34+
* NAMESPACE
35+
**************************************************************************************/
36+
37+
namespace arduino
38+
{
39+
40+
/**************************************************************************************
41+
* CLASS DECLARATION
42+
**************************************************************************************/
43+
44+
class HardwareCAN
45+
{
46+
public:
47+
virtual ~HardwareCAN() {}
48+
49+
50+
virtual bool begin(CanBitRate const can_bitrate) = 0;
51+
virtual void end() = 0;
52+
53+
54+
virtual int write(CanMsg const &msg) = 0;
55+
virtual size_t available() = 0;
56+
virtual CanMsg read() = 0;
57+
};
58+
59+
/**************************************************************************************
60+
* NAMESPACE
61+
**************************************************************************************/
62+
63+
} /* arduino */
64+
65+
#endif /* ARDUINOCORE_API_HARDWARECAN_H */

0 commit comments

Comments
 (0)