Skip to content

Commit df3022c

Browse files
committed
build(arduino): Check for compatible hardware at runtime.
Before CRSF for Arduino can be initialised, the library checks whether-or-not it has been flashed onto compatible hardware. If the hardware is compatible, CRSF for Arduino will initialise & carry on with normal operation. If CRSF for Arduino is flashed onto incompatible hardware, it will halt the setup process indefinitely. If the ```CRSF_DEBUG``` flag is enabled at compile time, the name of the development board is visible in the Serial Monitor. If the development board is incompatible, you will see "Unknown device" in the Serial Monitor.
1 parent 7d7dfa2 commit df3022c

File tree

3 files changed

+188
-1
lines changed

3 files changed

+188
-1
lines changed

src/lib/CRSFforArduino/CRSFforArduino.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@
2424
*
2525
*/
2626

27+
#include "CompatibilityTable.h"
2728
#include "CRSFforArduino.h"
2829

29-
/**
30+
CompatibilityTable CT = CompatibilityTable();
31+
32+
/**
3033
* @par CRSF Protocol
3134
*
3235
* CRSF is a full duplex serial protocol. It is the bus protocol used by both TBS Crossfire & ExpressLRS receivers to
@@ -83,6 +86,25 @@ CRSFforArduino::~CRSFforArduino()
8386
*/
8487
bool CRSFforArduino::begin()
8588
{
89+
90+
/* Check at runtime if the devboard is compatible with CRSF for Arduino. */
91+
const char *devboardName = CT.getDevboardName();
92+
#ifdef CRSF_DEBUG
93+
Serial.print("[CRSF for Arduino | INFO] Devboard Name: ");
94+
Serial.println(devboardName);
95+
#endif
96+
97+
// Incompatible devboards will be caught here.
98+
if (CT.isDevboardCompatible(devboardName) != true)
99+
{
100+
#ifdef CRSF_DEBUG
101+
Serial.println("[CRSF for Arduino | ERROR] Devboard is not compatible with CRSF for Arduino.");
102+
#endif
103+
// Stop here, instead of returning false, because CRSF for Arduino is not compatible with this devboard.
104+
while (1)
105+
;
106+
}
107+
86108
/* CRSF is 420000 baud 8-bit data, no parity, 1 stop bit. */
87109
_serial->begin(420000, SERIAL_8N1);
88110
_serial->setTimeout(10);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "CompatibilityTable.h"
2+
3+
CompatibilityTable::CompatibilityTable()
4+
{
5+
#if defined(ARDUINO_ARCH_SAMD)
6+
#if defined(ADAFRUIT_FEATHER_M0)
7+
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M0;
8+
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
9+
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M0_EXPRESS;
10+
#elif defined(ADAFRUIT_ITSYBITSY_M0)
11+
device.type.devboard = DEVBOARD_ADAFRUIT_ITSYBITSY_M0_EXPRESS;
12+
#elif defined(ADAFRUIT_METRO_M0_EXPRESS)
13+
device.type.devboard = DEVBOARD_ADAFRUIT_METRO_M0_EXPRESS;
14+
#elif defined(ADAFRUIT_QTPY_M0)
15+
device.type.devboard = DEVBOARD_ADAFRUIT_QTPY_M0;
16+
#elif defined(ADAFRUIT_TRINKET_M0)
17+
device.type.devboard = DEVBOARD_ADAFRUIT_TRINKET_M0;
18+
#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS)
19+
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M4_EXPRESS;
20+
#elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
21+
device.type.devboard = DEVBOARD_ADAFRUIT_GRAND_CENTRAL_M4;
22+
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
23+
device.type.devboard = DEVBOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS;
24+
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
25+
device.type.devboard = DEVBOARD_ADAFRUIT_METRO_M4_AIRLIFT_LITE;
26+
#elif defined(ADAFRUIT_METRO_M4_EXPRESS)
27+
device.type.devboard = DEVBOARD_ADAFRUIT_METRO_M4_EXPRESS;
28+
#elif defined(ADAFRUIT_FEATHER_M4_CAN)
29+
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M4_CAN;
30+
#elif defined(ARDUINO_SAMD_MKR1000)
31+
device.type.devboard = DEVBOARD_ARDUINO_MKR1000;
32+
#elif defined(ARDUINO_SAMD_MKRFox1200)
33+
device.type.devboard = DEVBOARD_ARDUINO_MKRFox1200;
34+
#elif defined(ARDUINO_SAMD_MKRGSM1400)
35+
device.type.devboard = DEVBOARD_ARDUINO_MKRGSM1400;
36+
#elif defined(ARDUINO_SAMD_MKRNB1500)
37+
device.type.devboard = DEVBOARD_ARDUINO_MKRNB1500;
38+
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
39+
device.type.devboard = DEVBOARD_ARDUINO_MKRVIDOR4000;
40+
#elif defined(ARDUINO_SAMD_MKRWAN1300)
41+
device.type.devboard = DEVBOARD_ARDUINO_MKRWAN1300;
42+
#elif defined(ARDUINO_SAMD_MKRWAN1310)
43+
device.type.devboard = DEVBOARD_ARDUINO_MKRWAN1310;
44+
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
45+
device.type.devboard = DEVBOARD_ARDUINO_MKRWIFI1010;
46+
#elif defined(ARDUINO_SAMD_MKRZERO)
47+
device.type.devboard = DEVBOARD_ARDUINO_MKRZERO;
48+
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
49+
device.type.devboard = DEVBOARD_ARDUINO_NANO_33_IOT;
50+
#elif defined(ARDUINO_SAMD_ZERO)
51+
device.type.devboard = DEVBOARD_ARDUINO_ZERO;
52+
#else
53+
device.type.devboard = DEVBOARD_IS_INCOMPATIBLE;
54+
#warning "Devboard not supported. Please check the compatibility table."
55+
#endif // ADAFRUIT_FEATHER_M0 etc
56+
#endif // ARDUINO_ARCH_SAMD
57+
}
58+
59+
bool CompatibilityTable::isDevboardCompatible(const char *name)
60+
{
61+
return strcmp(name, deviceNames[DEVBOARD_IS_INCOMPATIBLE]) != 0 ? true : false;
62+
}
63+
64+
const char *CompatibilityTable::getDevboardName()
65+
{
66+
if (device.type.devboard > DEVBOARD_COUNT)
67+
{
68+
return deviceNames[DEVBOARD_IS_INCOMPATIBLE];
69+
}
70+
71+
return deviceNames[device.type.devboard];
72+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#pragma once
2+
3+
#include "Arduino.h"
4+
5+
class CompatibilityTable
6+
{
7+
public:
8+
CompatibilityTable();
9+
10+
bool isDevboardCompatible(const char *name);
11+
const char *getDevboardName();
12+
13+
protected:
14+
typedef enum __ct_devboards_e
15+
{
16+
// Unknown device.
17+
DEVBOARD_IS_INCOMPATIBLE = 0,
18+
19+
// Adafruit SAMD21 boards.
20+
DEVBOARD_ADAFRUIT_FEATHER_M0,
21+
DEVBOARD_ADAFRUIT_FEATHER_M0_EXPRESS,
22+
DEVBOARD_ADAFRUIT_ITSYBITSY_M0_EXPRESS,
23+
DEVBOARD_ADAFRUIT_METRO_M0_EXPRESS,
24+
DEVBOARD_ADAFRUIT_QTPY_M0,
25+
DEVBOARD_ADAFRUIT_TRINKET_M0,
26+
27+
// Adafruit SAMD51 boards.
28+
DEVBOARD_ADAFRUIT_FEATHER_M4_EXPRESS,
29+
DEVBOARD_ADAFRUIT_GRAND_CENTRAL_M4,
30+
DEVBOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS,
31+
DEVBOARD_ADAFRUIT_METRO_M4_AIRLIFT_LITE,
32+
DEVBOARD_ADAFRUIT_METRO_M4_EXPRESS,
33+
34+
// Adafruit SAME51 boards.
35+
DEVBOARD_ADAFRUIT_FEATHER_M4_CAN,
36+
37+
// Arduino SAMD21 boards.
38+
DEVBOARD_ARDUINO_MKR1000,
39+
DEVBOARD_ARDUINO_MKRFOX1200,
40+
DEVBOARD_ARDUINO_MKRGSM1400,
41+
DEVBOARD_ARDUINO_MKRNB1500,
42+
DEVBOARD_ARDUINO_MKRVIDOR4000,
43+
DEVBOARD_ARDUINO_MKRWAN1300,
44+
DEVBOARD_ARDUINO_MKRWAN1310,
45+
DEVBOARD_ARDUINO_MKRWIFI1010,
46+
DEVBOARD_ARDUINO_MKRZERO,
47+
DEVBOARD_ARDUINO_NANO_33_IOT,
48+
DEVBOARD_ARDUINO_ZERO,
49+
50+
DEVBOARD_COUNT
51+
} __ct_devboards_t;
52+
53+
typedef struct __ct_devicetypes_s
54+
{
55+
__ct_devboards_t devboard;
56+
} __ct_devicetypes_t;
57+
58+
typedef struct __ct_devices_s
59+
{
60+
__ct_devicetypes_t type;
61+
} __ct_devices_t;
62+
63+
__ct_devices_t device;
64+
65+
const char *deviceNames[DEVBOARD_COUNT] = {
66+
"Incompatible device",
67+
"Adafruit Feather M0",
68+
"Adafruit Feather M0 Express",
69+
"Adafruit ItsyBitsy M0 Express",
70+
"Adafruit Metro M0 Express",
71+
"Adafruit QT Py M0",
72+
"Adafruit Trinket M0",
73+
"Adafruit Feather M4 Express",
74+
"Adafruit Grand Central M4",
75+
"Adafruit ItsyBitsy M4 Express",
76+
"Adafruit Metro M4 AirLift Lite",
77+
"Adafruit Metro M4 Express",
78+
"Adafruit Feather M4 CAN",
79+
"Arduino MKR1000",
80+
"Arduino MKRFOX1200",
81+
"Arduino MKRGSM1400",
82+
"Arduino MKRNB1500",
83+
"Arduino MKRVIDOR4000",
84+
"Arduino MKRWAN1300",
85+
"Arduino MKRWAN1310",
86+
"Arduino MKRWIFI1010",
87+
"Arduino MKRZERO",
88+
"Arduino Nano 33 IoT",
89+
"Arduino Zero"
90+
};
91+
};
92+
93+
// CompatibilityTable CT = CompatibilityTable();

0 commit comments

Comments
 (0)