Fix build: hoist all type declarations above the first function
The Arduino IDE injects generated prototypes immediately before the first function definition in the sketch. clearDesired() sat above struct Hub and struct PortThrottle, so prototypes referencing those types were emitted before the types existed. Moved all structs and enums into one block at the top, and documented the constraint in the header so it does not recur.
This commit is contained in:
@@ -17,6 +17,13 @@
|
|||||||
* first - see docs/BUILD.md. Without it you get:
|
* first - see docs/BUILD.md. Without it you get:
|
||||||
* fatal error: btstack.h: No such file or directory
|
* fatal error: btstack.h: No such file or directory
|
||||||
*
|
*
|
||||||
|
* FILE ORDER MATTERS:
|
||||||
|
* The Arduino IDE generates function prototypes and injects them immediately
|
||||||
|
* before the FIRST function definition in the file. Any type used in a
|
||||||
|
* function signature must therefore be declared above that point. All the
|
||||||
|
* structs and enums live at the top for this reason. Move a function above
|
||||||
|
* them and you get a wall of "'Hub' was not declared in this scope".
|
||||||
|
*
|
||||||
* THREADING - read this before changing anything:
|
* THREADING - read this before changing anything:
|
||||||
* BTstack is not thread-safe. loop() runs in the Arduino task, BTstack runs
|
* BTstack is not thread-safe. loop() runs in the Arduino task, BTstack runs
|
||||||
* in its own task. The only BTstack call allowed from loop() is
|
* in its own task. The only BTstack call allowed from loop() is
|
||||||
@@ -93,12 +100,11 @@ static const uint8_t LWP3_CHAR_UUID[16] = {
|
|||||||
0x00, 0x00, 0x16, 0x24, 0x12, 0x12, 0xef, 0xde,
|
0x00, 0x00, 0x16, 0x24, 0x12, 0x12, 0xef, 0xde,
|
||||||
0x16, 0x23, 0x78, 0x5f, 0xea, 0xbc, 0xd1, 0x23};
|
0x16, 0x23, 0x78, 0x5f, 0xea, 0xbc, 0xd1, 0x23};
|
||||||
|
|
||||||
// ============================================== shared between the 2 tasks
|
// ===================================================================== types
|
||||||
|
//
|
||||||
|
// Everything the Arduino prototype generator might need. Keep this block above
|
||||||
|
// the first function definition in the file - see the note in the header.
|
||||||
|
|
||||||
// Written by loop() (Arduino task), read by the BTstack timer. 32-bit aligned
|
|
||||||
// int stores on the ESP32 are single instructions, so a torn read is not
|
|
||||||
// possible; the worst case is one tick of stale data, which we do not care
|
|
||||||
// about at 40 Hz.
|
|
||||||
struct DesiredState {
|
struct DesiredState {
|
||||||
volatile int leftTrack; // hub 0 port B
|
volatile int leftTrack; // hub 0 port B
|
||||||
volatile int rightTrack; // hub 0 port A
|
volatile int rightTrack; // hub 0 port A
|
||||||
@@ -108,21 +114,6 @@ struct DesiredState {
|
|||||||
volatile int leftArm; // hub 1 port C
|
volatile int leftArm; // hub 1 port C
|
||||||
volatile int rightArm; // hub 1 port D
|
volatile int rightArm; // hub 1 port D
|
||||||
};
|
};
|
||||||
static DesiredState gDesired = {0, 0, 0, 0, 0, 0, 0};
|
|
||||||
|
|
||||||
static volatile bool gHubsReady = false;
|
|
||||||
|
|
||||||
static void clearDesired() {
|
|
||||||
gDesired.leftTrack = 0;
|
|
||||||
gDesired.rightTrack = 0;
|
|
||||||
gDesired.bodyLift = 0;
|
|
||||||
gDesired.headTilt = 0;
|
|
||||||
gDesired.headTurn = 0;
|
|
||||||
gDesired.leftArm = 0;
|
|
||||||
gDesired.rightArm = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================ hub plumbing
|
|
||||||
|
|
||||||
enum HubState {
|
enum HubState {
|
||||||
HUB_IDLE,
|
HUB_IDLE,
|
||||||
@@ -145,13 +136,23 @@ struct Hub {
|
|||||||
uint32_t lastCmdAt; // per-hub rate limit, shared across its ports
|
uint32_t lastCmdAt; // per-hub rate limit, shared across its ports
|
||||||
};
|
};
|
||||||
|
|
||||||
static Hub gHubs[2];
|
|
||||||
static int gActive = -1; // hub currently mid-discovery, -1 if none
|
|
||||||
|
|
||||||
struct PortThrottle {
|
struct PortThrottle {
|
||||||
int lastPower;
|
int lastPower;
|
||||||
uint32_t lastSentAt;
|
uint32_t lastSentAt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ================================================================== globals
|
||||||
|
|
||||||
|
// gDesired is written by loop() (Arduino task) and read by the BTstack timer.
|
||||||
|
// 32-bit aligned int stores on the ESP32 are single instructions, so a torn
|
||||||
|
// read is not possible; the worst case is one tick of stale data, which we do
|
||||||
|
// not care about at 40 Hz.
|
||||||
|
static DesiredState gDesired = {0, 0, 0, 0, 0, 0, 0};
|
||||||
|
static volatile bool gHubsReady = false;
|
||||||
|
|
||||||
|
static Hub gHubs[2];
|
||||||
|
static int gActive = -1; // hub currently mid-discovery, -1 if none
|
||||||
|
|
||||||
static PortThrottle gThrottle[7] = {{999, 0}, {999, 0}, {999, 0}, {999, 0},
|
static PortThrottle gThrottle[7] = {{999, 0}, {999, 0}, {999, 0}, {999, 0},
|
||||||
{999, 0}, {999, 0}, {999, 0}};
|
{999, 0}, {999, 0}, {999, 0}};
|
||||||
|
|
||||||
@@ -159,11 +160,24 @@ static btstack_packet_callback_registration_t gHciRegistration;
|
|||||||
static btstack_context_callback_registration_t gBootstrapRegistration;
|
static btstack_context_callback_registration_t gBootstrapRegistration;
|
||||||
static btstack_timer_source_t gLegoTimer;
|
static btstack_timer_source_t gLegoTimer;
|
||||||
|
|
||||||
// ============================================================== gamepad io
|
|
||||||
|
|
||||||
ControllerPtr myControllers[BP32_MAX_CONTROLLERS];
|
ControllerPtr myControllers[BP32_MAX_CONTROLLERS];
|
||||||
static bool gDiscoveryEnabled = false;
|
static bool gDiscoveryEnabled = false;
|
||||||
|
|
||||||
|
// ============================================================== gamepad io
|
||||||
|
//
|
||||||
|
// First function definition in the file. Everything above this line is types
|
||||||
|
// and data, which is what makes the generated prototypes compile.
|
||||||
|
|
||||||
|
static void clearDesired() {
|
||||||
|
gDesired.leftTrack = 0;
|
||||||
|
gDesired.rightTrack = 0;
|
||||||
|
gDesired.bodyLift = 0;
|
||||||
|
gDesired.headTilt = 0;
|
||||||
|
gDesired.headTurn = 0;
|
||||||
|
gDesired.leftArm = 0;
|
||||||
|
gDesired.rightArm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void onConnectedController(ControllerPtr ctl) {
|
void onConnectedController(ControllerPtr ctl) {
|
||||||
for (int i = 0; i < BP32_MAX_CONTROLLERS; i++) {
|
for (int i = 0; i < BP32_MAX_CONTROLLERS; i++) {
|
||||||
if (myControllers[i] == nullptr) {
|
if (myControllers[i] == nullptr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user