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

api/CanMsg.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <a.entinger@arduino.cc>
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_ */

api/CanMsgRingbuffer.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <a.entinger@arduino.cc>
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 */

api/CanMsgRingbuffer.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <a.entinger@arduino.cc>
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_ */

api/HardwareCAN.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2022 by Alexander Entinger <a.entinger@arduino.cc>
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy