Hello.
I hope I am asking my questions here in the correct forum. Please let me know if this needs to be somewhere else.
I am developing a device driver library where a contiguous number of pins for the device is defined by the sketch author, by specifying the minimum and maximum Arduino pin numbers to which the device is connected.
I would like to check AT BUILD TIME (or pre-processor time) that the sketch author is adhering to a number of rules about the minimum and maximum Arduino pin numbers, and fail the build (with a #error pre-processor directive) if not. (For example, the minimum has to be less than the maximum, and the total number of pins must be between 2 and 6, inclusive).
Therefore, my library header file ("MyDeviceLib.h" for example) requires the sketch author to #define two constants before #including it. Something like:
#define MYDEVICE_MIN_PIN 2
#define MYDEVICE_MAX_PIN 5
#include "MyDeviceLib.h"
Then, in the MyDeviceLib.h header file, pre-processor directives (conditionals, etc.) will test to ensure that the minimum and maximum Arduino pin numbers do not break the rules for the library. I have most of these checks working (the build will fail if these two parameters break some of my rules; for example if MIN is greater than or equal to MAX).
For now, at least, I want to limit this library for use with 8-bit ATmega and ATtiny processors - not for SAM (ARM) processors, ESP8266 processors, etc. (I only have UNO, Nano, Digispark, and "bare naked" ATtiny85 chips to test with. I DO have a couple of ESP-01's to play with, but I have not written sketches for those yet and, anyway, only a couple of port pins are available on the '01. I have some ESP-12's on order.)
Question 1: How do I check to ensure the sketch is being built for 8-bit ATmega/ATtiny devices? How would I change this if I eventually want to include other processors?
(Although, I am not sure I could get other processors to work with my device driver - I may have to do a total re-write for bigger processors like ARM based, etc.)
One of the rules is that the maximum and minimum Arduino pin numbers (and of course, all pins in between) must be on the same processor I/O port register. (Because the library functions will be performing manipulations on parallel data bits that are read from or written to the external device.)
Question 2: How do I check (at build time) to ensure that the specified (#define'd) minimum and maximum Arduino pin numbers are in the same processor port register? Does the Arduino IDE define some macros to easily get (at build time) the AVR port register name, for any given Arduino pin number?
As a very "rough-and-dirty" method for question number 2, I am masking off the three LS bits of the Arduino pin numbers (clearing those 3 bits to 0 in each number), and checking that the results (pin numbers with 3 LSBs set to 0) are the same. For example, if the minimum pin number is less than 8 and the maximum is greater than or equal to 8, then I spit out a pre-processor #warning directive:
//TODO: Somehow check to ensure that MYDEVICE_MIN_PIN and MYDEVICE_MAX_PIN are in the same
// I/O port. Issue an error message, if not.
// Following is a VERY ROUGH check which probably does not work with some
// boards.
#if ((MYDEVICE_MIN_PIN) & ~7) != ((MYDEVICE_MAX_PIN) & ~7)
#warning Specified minimum and maximum pin numbers appear to be on different ports.
#warning All MyDevice pins must be on the same port for this library to work correctly.
#endif
This is making an assumption (probably incorrect) that Arduino pin numbers (for ATmega and ATtiny boards) are always in groups of 8, and that each group of 8 is associated with one specific port. (And, yes, I do realise that some Arduino boards have devices where port C only has 5 bits available.) So it would be best for my purposes to try to get the port register letter for a given Arduino pin number, hopefully by using already-defined macros in the Arduino IDE for whatever device the sketch is being built.
So, the following is what I have for now on build-time checking of these Arduino pin parameters:
/*
MyDeviceLib.h
*/
#ifndef _MYDEVICE_LIB_HEADER_INCLUDED
#define _MYDEVICE_LIB_HEADER_INCLUDED
// LAW ENFORCEMENT ;-)
// TODO: Check to ensure the build is for 8-bit ATmega/ATtiny device (How do I do this?)
#if !(defined(MYDEVICE_MIN_PIN) && defined(MYDEVICE_MAX_PIN))
#error I need something to work with, here. Please define BOTH of MYDEVICE_MIN_PIN and MYDEVICE_MAX_PIN before includin MyDeviceLib.h
#endif
#if (MYDEVICE_MIN_PIN) < 0
#error Stop being so negative! I just cannot handle negative pin numbers!
#endif
#if (MYDEVICE_MIN_PIN) >= (MYDEVICE_MAX_PIN)
// This also ensures that 2 is the minimum number of pins.
#error MYDEVICE_MIN_PIN must be STRICTLY less than MYDEVICE_MAX_PIN.
#endif
#if (MYDEVICE_MAX_PIN) > (5 + (MYDEVICE_MIN_PIN))
#error Hey! I am no Superman! I can only handle up to 6 pins, max.
#endif
//TODO: Somehow check to ensure that MYDEVICE_MIN_PIN and MYDEVICE_MAX_PIN are in the same
// I/O port. Issue an error message, if not.
// FOllowing is a VERY ROUGH check which probably does not work with some
// boards.
#if ((MYDEVICE_MIN_PIN) & ~7) != ((MYDEVICE_MAX_PIN) & ~7)
#warning Specified minimum and maximum pin numbers appear to be on different ports.
#warning All MyDevice pins must be on the same port for this library to work correctly.
#endif
// End of "LAW ENFORCEMENT" ;-)
/*
... PUT LIBRARY GLOBAL DEFININTIONS, PROTOTYPES, ETC. HERE
*/
#endif // _MYDEVICE_LIB_HEADER_INCLUDED
Thanks for any help with this.
Best regards,
"DuinoSoar"