blob: 42057bca3a55f27248c747b35abe3440bcb9c651 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
/*
* CanDriversData.h
*
* Created on: 23 Dec 2021
* Author: David
*/
#ifndef SRC_CAN_CANDRIVERSDATA_H_
#define SRC_CAN_CANDRIVERSDATA_H_
#include "RepRapFirmware.h"
#if SUPPORT_CAN_EXPANSION
typedef Bitmap<uint16_t> CanDriversBitmap;
// Class to accumulate a set of values relating to CAN-connected drivers
template<class T> class CanDriversData
{
public:
CanDriversData() noexcept;
void AddEntry(DriverId id, T val) noexcept;
size_t GetNumEntries() const noexcept { return numEntries; }
CanAddress GetNextBoardDriverBitmap(size_t& startFrom, CanDriversBitmap& driversBitmap) const noexcept;
T GetElement(size_t n) const pre(n < GetnumEntries()) noexcept { return data[n].val; }
private:
struct DriverDescriptor
{
DriverId driver;
T val;
};
size_t numEntries;
DriverDescriptor data[MaxCanDrivers];
};
// Class to represent a set of CAN-connected drivers with no associated data
class CanDriversList
{
public:
CanDriversList() noexcept : numEntries(0) { }
void Clear() noexcept { numEntries = 0; }
void AddEntry(DriverId id) noexcept;
size_t GetNumEntries() const noexcept { return numEntries; }
bool IsEmpty() const noexcept { return numEntries == 0; }
CanAddress GetNextBoardDriverBitmap(size_t& startFrom, CanDriversBitmap& driversBitmap) const noexcept;
private:
size_t numEntries;
DriverId drivers[MaxCanDrivers];
};
// Members of template class CanDriversData
template<class T> CanDriversData<T>::CanDriversData() noexcept
{
numEntries = 0;
}
// Insert a new entry, keeping the list ordered by driver ID
template<class T> void CanDriversData<T>::AddEntry(DriverId driver, T val) noexcept
{
if (numEntries < ARRAY_SIZE(data))
{
// We could do a binary search here but the number of CAN drivers supported isn't huge, so linear search instead
size_t insertPoint = 0;
while (insertPoint < numEntries && data[insertPoint].driver < driver)
{
++insertPoint;
}
memmove(data + (insertPoint + 1), data + insertPoint, (numEntries - insertPoint) * sizeof(data[0]));
data[insertPoint].driver = driver;
data[insertPoint].val = val;
++numEntries;
}
}
// Get the details of the drivers on the next board and advance startFrom beyond the entries for this board
template<class T> CanAddress CanDriversData<T>::GetNextBoardDriverBitmap(size_t& startFrom, CanDriversBitmap& driversBitmap) const noexcept
{
driversBitmap.Clear();
if (startFrom >= numEntries)
{
return CanId::NoAddress;
}
const CanAddress boardAddress = data[startFrom].driver.boardAddress;
do
{
driversBitmap.SetBit(data[startFrom].driver.localDriver);
++startFrom;
} while (startFrom < numEntries && data[startFrom].driver.boardAddress == boardAddress);
return boardAddress;
}
#endif
#endif /* SRC_CAN_CANDRIVERSDATA_H_ */
|