Skip to content

Commit

Permalink
build(arduino): Check for compatible hardware at runtime.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ZZ-Cat committed Apr 5, 2023
1 parent 7d7dfa2 commit df3022c
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/lib/CRSFforArduino/CRSFforArduino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
*
*/

#include "CompatibilityTable.h"
#include "CRSFforArduino.h"

/**
CompatibilityTable CT = CompatibilityTable();

/**
* @par CRSF Protocol
*
* CRSF is a full duplex serial protocol. It is the bus protocol used by both TBS Crossfire & ExpressLRS receivers to
Expand Down Expand Up @@ -83,6 +86,25 @@ CRSFforArduino::~CRSFforArduino()
*/
bool CRSFforArduino::begin()
{

/* Check at runtime if the devboard is compatible with CRSF for Arduino. */
const char *devboardName = CT.getDevboardName();
#ifdef CRSF_DEBUG
Serial.print("[CRSF for Arduino | INFO] Devboard Name: ");
Serial.println(devboardName);
#endif

// Incompatible devboards will be caught here.
if (CT.isDevboardCompatible(devboardName) != true)
{
#ifdef CRSF_DEBUG
Serial.println("[CRSF for Arduino | ERROR] Devboard is not compatible with CRSF for Arduino.");
#endif
// Stop here, instead of returning false, because CRSF for Arduino is not compatible with this devboard.
while (1)
;
}

/* CRSF is 420000 baud 8-bit data, no parity, 1 stop bit. */
_serial->begin(420000, SERIAL_8N1);
_serial->setTimeout(10);
Expand Down
72 changes: 72 additions & 0 deletions src/lib/CompatibilityTable/CompatibilityTable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "CompatibilityTable.h"

CompatibilityTable::CompatibilityTable()
{
#if defined(ARDUINO_ARCH_SAMD)
#if defined(ADAFRUIT_FEATHER_M0)
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M0;
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M0_EXPRESS;
#elif defined(ADAFRUIT_ITSYBITSY_M0)
device.type.devboard = DEVBOARD_ADAFRUIT_ITSYBITSY_M0_EXPRESS;
#elif defined(ADAFRUIT_METRO_M0_EXPRESS)
device.type.devboard = DEVBOARD_ADAFRUIT_METRO_M0_EXPRESS;
#elif defined(ADAFRUIT_QTPY_M0)
device.type.devboard = DEVBOARD_ADAFRUIT_QTPY_M0;
#elif defined(ADAFRUIT_TRINKET_M0)
device.type.devboard = DEVBOARD_ADAFRUIT_TRINKET_M0;
#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS)
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M4_EXPRESS;
#elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
device.type.devboard = DEVBOARD_ADAFRUIT_GRAND_CENTRAL_M4;
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
device.type.devboard = DEVBOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS;
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
device.type.devboard = DEVBOARD_ADAFRUIT_METRO_M4_AIRLIFT_LITE;
#elif defined(ADAFRUIT_METRO_M4_EXPRESS)
device.type.devboard = DEVBOARD_ADAFRUIT_METRO_M4_EXPRESS;
#elif defined(ADAFRUIT_FEATHER_M4_CAN)
device.type.devboard = DEVBOARD_ADAFRUIT_FEATHER_M4_CAN;
#elif defined(ARDUINO_SAMD_MKR1000)
device.type.devboard = DEVBOARD_ARDUINO_MKR1000;
#elif defined(ARDUINO_SAMD_MKRFox1200)
device.type.devboard = DEVBOARD_ARDUINO_MKRFox1200;
#elif defined(ARDUINO_SAMD_MKRGSM1400)
device.type.devboard = DEVBOARD_ARDUINO_MKRGSM1400;
#elif defined(ARDUINO_SAMD_MKRNB1500)
device.type.devboard = DEVBOARD_ARDUINO_MKRNB1500;
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
device.type.devboard = DEVBOARD_ARDUINO_MKRVIDOR4000;
#elif defined(ARDUINO_SAMD_MKRWAN1300)
device.type.devboard = DEVBOARD_ARDUINO_MKRWAN1300;
#elif defined(ARDUINO_SAMD_MKRWAN1310)
device.type.devboard = DEVBOARD_ARDUINO_MKRWAN1310;
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
device.type.devboard = DEVBOARD_ARDUINO_MKRWIFI1010;
#elif defined(ARDUINO_SAMD_MKRZERO)
device.type.devboard = DEVBOARD_ARDUINO_MKRZERO;
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
device.type.devboard = DEVBOARD_ARDUINO_NANO_33_IOT;
#elif defined(ARDUINO_SAMD_ZERO)
device.type.devboard = DEVBOARD_ARDUINO_ZERO;
#else
device.type.devboard = DEVBOARD_IS_INCOMPATIBLE;
#warning "Devboard not supported. Please check the compatibility table."
#endif // ADAFRUIT_FEATHER_M0 etc
#endif // ARDUINO_ARCH_SAMD
}

bool CompatibilityTable::isDevboardCompatible(const char *name)
{
return strcmp(name, deviceNames[DEVBOARD_IS_INCOMPATIBLE]) != 0 ? true : false;
}

const char *CompatibilityTable::getDevboardName()
{
if (device.type.devboard > DEVBOARD_COUNT)
{
return deviceNames[DEVBOARD_IS_INCOMPATIBLE];
}

return deviceNames[device.type.devboard];
}
93 changes: 93 additions & 0 deletions src/lib/CompatibilityTable/CompatibilityTable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#pragma once

#include "Arduino.h"

class CompatibilityTable
{
public:
CompatibilityTable();

bool isDevboardCompatible(const char *name);
const char *getDevboardName();

protected:
typedef enum __ct_devboards_e
{
// Unknown device.
DEVBOARD_IS_INCOMPATIBLE = 0,

// Adafruit SAMD21 boards.
DEVBOARD_ADAFRUIT_FEATHER_M0,
DEVBOARD_ADAFRUIT_FEATHER_M0_EXPRESS,
DEVBOARD_ADAFRUIT_ITSYBITSY_M0_EXPRESS,
DEVBOARD_ADAFRUIT_METRO_M0_EXPRESS,
DEVBOARD_ADAFRUIT_QTPY_M0,
DEVBOARD_ADAFRUIT_TRINKET_M0,

// Adafruit SAMD51 boards.
DEVBOARD_ADAFRUIT_FEATHER_M4_EXPRESS,
DEVBOARD_ADAFRUIT_GRAND_CENTRAL_M4,
DEVBOARD_ADAFRUIT_ITSYBITSY_M4_EXPRESS,
DEVBOARD_ADAFRUIT_METRO_M4_AIRLIFT_LITE,
DEVBOARD_ADAFRUIT_METRO_M4_EXPRESS,

// Adafruit SAME51 boards.
DEVBOARD_ADAFRUIT_FEATHER_M4_CAN,

// Arduino SAMD21 boards.
DEVBOARD_ARDUINO_MKR1000,
DEVBOARD_ARDUINO_MKRFOX1200,
DEVBOARD_ARDUINO_MKRGSM1400,
DEVBOARD_ARDUINO_MKRNB1500,
DEVBOARD_ARDUINO_MKRVIDOR4000,
DEVBOARD_ARDUINO_MKRWAN1300,
DEVBOARD_ARDUINO_MKRWAN1310,
DEVBOARD_ARDUINO_MKRWIFI1010,
DEVBOARD_ARDUINO_MKRZERO,
DEVBOARD_ARDUINO_NANO_33_IOT,
DEVBOARD_ARDUINO_ZERO,

DEVBOARD_COUNT
} __ct_devboards_t;

typedef struct __ct_devicetypes_s
{
__ct_devboards_t devboard;
} __ct_devicetypes_t;

typedef struct __ct_devices_s
{
__ct_devicetypes_t type;
} __ct_devices_t;

__ct_devices_t device;

const char *deviceNames[DEVBOARD_COUNT] = {
"Incompatible device",
"Adafruit Feather M0",
"Adafruit Feather M0 Express",
"Adafruit ItsyBitsy M0 Express",
"Adafruit Metro M0 Express",
"Adafruit QT Py M0",
"Adafruit Trinket M0",
"Adafruit Feather M4 Express",
"Adafruit Grand Central M4",
"Adafruit ItsyBitsy M4 Express",
"Adafruit Metro M4 AirLift Lite",
"Adafruit Metro M4 Express",
"Adafruit Feather M4 CAN",
"Arduino MKR1000",
"Arduino MKRFOX1200",
"Arduino MKRGSM1400",
"Arduino MKRNB1500",
"Arduino MKRVIDOR4000",
"Arduino MKRWAN1300",
"Arduino MKRWAN1310",
"Arduino MKRWIFI1010",
"Arduino MKRZERO",
"Arduino Nano 33 IoT",
"Arduino Zero"
};
};

// CompatibilityTable CT = CompatibilityTable();

0 comments on commit df3022c

Please sign in to comment.