adafruit / Adafruit_BusIO

Arduino library for I2C & SPI abstractions
MIT License
290 stars 265 forks source link

BusIO library won't build unless a serial device is configured #127

Open davidgiven opened 6 months ago

davidgiven commented 6 months ago

Adafruit_BusIO_Register.h contains these prototypes:

  void print(Stream *s = &Serial);
  void println(Stream *s = &Serial);

If I try to configure my platform without a generic Serial instance, then compilation of the BusIO libraries fails with a 'Serial not declared' error. I feel like these two prototypes (and the implementation in the .cpp file, of course) should probably be guarded with something so that they're only included if a Serial instance is present, but I don't know what that would be.

(Alternatively, this might be an STM32Duino issue where it's not doing the right thing if you disable the automatic serial port --- please let me know.)

#include <Adafruit_SPIDevice.h>

void setup() {}
void loop() {}

Disable the serial port via the Tools menu, and compile. You get:

In file included from /home/dg/Arduino/libraries/Adafruit_BusIO/Adafruit_BusIO_Register.cpp:1:
/home/dg/Arduino/libraries/Adafruit_BusIO/Adafruit_BusIO_Register.h:75:27: error: 'Serial' was not declared in this scope; did you mean 'Serial3'?
   75 |   void print(Stream *s = &Serial);
      |                           ^~~~~~
      |                           Serial3
/home/dg/Arduino/libraries/Adafruit_BusIO/Adafruit_BusIO_Register.h:76:29: error: 'Serial' was not declared in this scope; did you mean 'Serial3'?
   76 |   void println(Stream *s = &Serial);
      |                             ^~~~~~
      |                             Serial3
caternuson commented 6 months ago

That's probably expected behavior for the scenario. Not having Serial is pretty rare, since that's a pretty basic Arduino feature.

As a work around, can try just deleting Adafruit_BusIO_Register.h and Adafruit_BusIO_Register.cpp from the library. The "register" classes are additional convenience features not required for basic SPIDevice usage.

caternuson commented 6 months ago

This looks like a dupe of #111

davidgiven commented 6 months ago

Disabling the serial device is a supported configuration; having to edit the library to make it work is very much unexpected behaviour...

What I'm specifically trying to do here is to use SoftwareSerial instead of the hard-coded Serial, as the pins that Serial uses by default are in use for something else. I couldn't find any way to configure this that would make BusIO compile; there don't seem to be any user hooks to allow me to declare my own Serial device before the BusIO headers get included. The obvious trick of just defining Adafruit_BusIO_Register_h to suppress the inclusion doesn't work. I suspect some kind of .ino preprocessing magic is reordering things.

Regarding deleting the Register classes: I am not using these directly; they're getting included by Adafruit_GFX, which I don't have any control over.

caternuson commented 6 months ago

Is there a known way to check for this across all platforms? The preprocessor logic in this PR doesn't seem to work in the case of STM32 BSP: https://github.com/adafruit/Adafruit_BusIO/pull/112

Adding that to your basic test sketch:

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#include <Adafruit_SPIDevice.h>
#endif

void setup() {}
void loop() {}

still produces the compile time fail.

This works however:

#if !defined(NDEBUG)
#include <Adafruit_SPIDevice.h>
#endif

void setup() {}
void loop() {}

since that is what the STM32 BSP seems to add via a -D on the command line.

It seems like each BSP does their own thing?