Skip to content

Commit 7463cbd

Browse files
committed
Abstract the CRC lookup map
1 parent edcdf3b commit 7463cbd

File tree

3 files changed

+67
-43
lines changed

3 files changed

+67
-43
lines changed

boards/XCORE/board_utils.cpp

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "board_utils.hpp"
22

3-
#include <etl/crc16_genibus.h>
3+
#include <crc_lookup_map.hpp>
44

55
#pragma pack(push, 1)
66
struct LineParams {
@@ -10,10 +10,6 @@ struct LineParams {
1010
};
1111
#pragma pack(pop)
1212

13-
constexpr uint16_t crc16(const char* str) {
14-
return etl::crc16_genibus(str, str + strlen(str)).value();
15-
}
16-
1713
constexpr uint32_t ports[] = {GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE,
1814
GPIOE_BASE, GPIOF_BASE, GPIOG_BASE, GPIOH_BASE};
1915

@@ -123,28 +119,11 @@ constexpr LineParams lines[] = {
123119
{crc16("OSC_OUT"), port_idx('H'), 1},
124120
};
125121

126-
static_assert(
127-
[] {
128-
constexpr size_t count = sizeof(lines) / sizeof(LineParams);
129-
for (size_t i = 0; i < count; i++) {
130-
for (size_t j = i + 1; j < count; j++) {
131-
if (lines[i].crc == lines[j].crc) {
132-
return false;
133-
}
134-
}
135-
}
136-
return true;
137-
}(),
138-
"CRC16 values are not unique");
122+
static_assert(HasUniqueCrcs(lines), "CRC16 values are not unique");
139123

140124
ioline_t GetIoLineByName(const char* name) {
141-
uint16_t crc = crc16(name);
142-
for (const auto& line : lines) {
143-
if (line.crc == crc) {
144-
return PAL_LINE(ports[line.port], line.pad);
145-
}
146-
}
147-
return PAL_NOLINE;
125+
auto* line = LookupByName(name, lines);
126+
return line != nullptr ? PAL_LINE(ports[line->port], line->pad) : PAL_NOLINE;
148127
}
149128

150129
UARTDriver* GetUARTDriverByIndex(uint8_t index) {

src/crc_lookup_map.hpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef LOOKUP_HPP
2+
#define LOOKUP_HPP
3+
4+
#include <etl/crc16_genibus.h>
5+
6+
#include <cstdint>
7+
#include <cstring>
8+
9+
constexpr uint16_t crc16(const char* str) {
10+
return etl::crc16_genibus(str, str + strlen(str)).value();
11+
}
12+
13+
template <typename T, size_t N>
14+
constexpr bool HasUniqueCrcs(const T (&arr)[N]) {
15+
for (size_t i = 0; i < N; i++) {
16+
for (size_t j = i + 1; j < N; j++) {
17+
if (arr[i].crc == arr[j].crc) {
18+
return false;
19+
}
20+
}
21+
}
22+
return true;
23+
}
24+
25+
template <typename T, size_t N>
26+
const T* LookupByName(const char* name, const T (&arr)[N]) {
27+
uint16_t crc = crc16(name);
28+
for (const auto& item : arr) {
29+
if (item.crc == crc) {
30+
return &item;
31+
}
32+
}
33+
return nullptr;
34+
}
35+
36+
#endif // LOOKUP_HPP

src/drivers/input/worx_input_driver.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,51 @@
11
#include "worx_input_driver.hpp"
22

33
#include <etl/crc16_genibus.h>
4-
#include <etl/flat_map.h>
5-
#include <etl/string.h>
64
#include <ulog.h>
75

6+
#include <crc_lookup_map.hpp>
87
#include <json_stream.hpp>
98

109
#define IS_BIT_SET(x, bit) ((x & (1 << bit)) != 0)
1110

1211
namespace xbot::driver::input {
1312

14-
static const etl::flat_map<etl::string<13>, uint8_t, 8> INPUT_BITS = {
13+
#pragma pack(push, 1)
14+
namespace {
15+
struct InputParams {
16+
uint16_t crc;
17+
uint8_t bit;
18+
};
19+
} // namespace
20+
#pragma pack(pop)
21+
22+
static constexpr InputParams available_inputs[] = {
1523
// Keys
16-
{"start", 1},
17-
{"home", 2},
18-
{"back", 3},
24+
{crc16("start"), 1},
25+
{crc16("home"), 2},
26+
{crc16("back"), 3},
1927

2028
// Halls
21-
{"battery_cover", 9},
22-
{"stop1", 10},
23-
{"trapped1", 12},
24-
{"trapped2", 13},
25-
{"stop2", 15},
29+
{crc16("battery_cover"), 9},
30+
{crc16("stop1"), 10},
31+
{crc16("trapped1"), 12},
32+
{crc16("trapped2"), 13},
33+
{crc16("stop2"), 15},
2634
};
2735

36+
static_assert(HasUniqueCrcs(available_inputs), "CRC16 values are not unique");
37+
2838
bool WorxInputDriver::OnInputConfigValue(lwjson_stream_parser_t* jsp, const char* key, lwjson_stream_type_t type,
2939
Input& input) {
3040
if (strcmp(key, "id") == 0) {
3141
JsonExpectType(STRING);
32-
decltype(INPUT_BITS)::key_type input_id{jsp->data.str.buff};
33-
auto bit_it = INPUT_BITS.find(input_id);
34-
if (bit_it == INPUT_BITS.end()) {
35-
ULOG_ERROR("Unknown Worx input ID \"%s\"", input_id.c_str());
36-
return false;
42+
const auto* id = jsp->data.str.buff;
43+
if (auto* params = LookupByName(id, available_inputs)) {
44+
input.worx.bit = params->bit;
45+
return true;
3746
}
38-
input.worx.bit = bit_it->second;
39-
return true;
47+
ULOG_ERROR("Unknown ID \"%s\"", id);
48+
return false;
4049
}
4150
ULOG_ERROR("Unknown attribute \"%s\"", key);
4251
return false;

0 commit comments

Comments
 (0)