From e9941abc1bfabb492cb95793df9e5c63d9e8150a Mon Sep 17 00:00:00 2001 From: Katherine Whitlock Date: Tue, 23 Nov 2021 15:16:56 -0500 Subject: [PATCH] Switch to using pin change interrupts --- .../Libraries/PinChangeInterrupt/Readme.md | 385 ++++++++ .../PinChangeInterrupt_HowItWorks.ino | 122 +++ .../PinChangeInterrupt_Led.ino | 55 ++ .../PinChangeInterrupt_LowLevel.ino | 60 ++ .../PinChangeInterrupt_TickTock.ino | 98 ++ .../Libraries/PinChangeInterrupt/header.png | Bin 0 -> 23975 bytes .../Libraries/PinChangeInterrupt/keywords.txt | 32 + .../PinChangeInterrupt/library.properties | 10 + .../src/PinChangeInterrupt.cpp | 336 +++++++ .../src/PinChangeInterrupt.h | 898 +++++++++++++++++ .../src/PinChangeInterrupt0.cpp | 149 +++ .../src/PinChangeInterrupt1.cpp | 149 +++ .../src/PinChangeInterrupt2.cpp | 149 +++ .../src/PinChangeInterrupt3.cpp | 149 +++ .../src/PinChangeInterruptBoards.h | 174 ++++ .../src/PinChangeInterruptPins.h | 926 ++++++++++++++++++ .../src/PinChangeInterruptSettings.h | 230 +++++ Display Code/mbraidsv3/mbraidsv3.ino | 36 +- 18 files changed, 3952 insertions(+), 6 deletions(-) create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/header.png create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h create mode 100644 Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md new file mode 100644 index 0000000..cce1f76 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md @@ -0,0 +1,385 @@ +PinChangeInterrupt Library 1.2.9 +================================ + +![Header Picture](header.png) + +PinChangeInterrupt library with a resource friendly implementation (API and LowLevel). +PinChangeInterrupts are different than normal Interrupts. See detail below. + +##### Features: +* PinChangeInterrupt for a lot of pins +* Rising, Falling or Change detection for every pin separately +* Usable on a lot Arduino compatible boards +* Implementation is fast, compact and resource friendly +* Ports/Pins can be manually deactivated in the Settings file +* API and LowLevel option +* Full Port0-3 support +* .a linkage optimization (Arduino IDE) + +Buy Me A Coffee + +#### Supported pins for PinChangeInterrupt: +See [PCINT pin table](https://github.com/NicoHood/PinChangeInterrupt/#pinchangeinterrupt-table) at the bottom for more details. + +``` +Arduino Uno/Nano/Mini: All pins are usable +Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), + A11 (65), A12 (66), A13 (67), A14 (68), A15 (69) +Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) +HoodLoader2: All (broken out 1-7) pins are usable +Attiny24/44/84: All pins are usable +Attiny25/45/85: All pins are usable +Attiny13: All pins are usable +Attiny441/841: All pins are usable +Attiny261/461/861: All pins are usable +Attiny2313/2313A/4313: PORTB is usable +ATmega644/ATmega644P/ATmega1284P: All pins are usable +ATmega162: PORTA and PORTC usable +ATmega48/88/168/328/328PB: All pins are usable +``` + +Contact information can be found here: + +www.nicohood.de + +Installation +============ + +Download the zip, extract and remove the "-master" of the folder. +Install the library [as described here](http://arduino.cc/en/pmwiki.php?n=Guide/Libraries). + +This library can also be used with the [DMBS AVR Library Collection](https://github.com/NicoHood/avr) and a pure makefile. + +How to use +========== + +It is important that you know at least the basic difference between **PinInterrupts** and **PinChangeInterrupts**. +I will explain the basics of **PinChangeInterrupts** (PCINTs) based on an Arduino Uno. + +On a standard Arduino Uno Pin 2 and 3 have **PinInterrupts**. Those are exclusively for a single pin and can detect RISING, FALLING and CHANGE. + +**PinChangeInterrupts** instead are used for a whole port (they should have better named them PortChangeInterrupts) and can only detect CHANGE for a whole port. +Each pin row (0-7, 8-13, A0-A5) represents a port. If an interrupt (ISR) occurs on one pin of a port +it is still unclear what pin of the port caused this interrupt. Therefore this library saves the state of the whole port and compares with the last state. +This way we can also see if it was a RISING or FALLING edge instead of only knowing the CHANGE. + +A **PinChangeInterrupt** will only be triggered for the attached pins per port. +Meaning if you set PCINT for a pin and another pin on the same port is changing a lot +it will not interrupt your code. + +**PinChangeInterrupts** might be a tiny bit slower and not that reliable because of that detection overhead (talking about micro seconds). +Make sure to not use longer function calls inside the ISR or Serial print. +You have the same issues on normal **PinInterrupts** and interrupts in general. + +The library is coded to get maximum speed and minimum code size. The LowLevel example without the API takes 4uS to enter the interrupt function in the worst case +which is pretty good and might be even better than the **PinInterrupt** code from the official Arduino core due to high optimization. +If you need very precise interrupts you better use **PinInterrupts** without the Arduino IDE at all. + +### Examples +To see how the code works just check the Led and TickTock example. +The LowLevel example is for advanced users with more optimization and more direct access. +The HowItWorks example shows the basic PinChangeInterrupt setup and decoding routine, similar to the library. +See the notes in the examples about more details. + +An useful "real use" example of the PinChangeInterrupt library can be found here: +https://github.com/NicoHood/IRLremote + +### API Reference + +##### Attach a PinChangeInterrupt +```cpp +// The pin has to be a PCINT number. Use the makro to convert a pin to a PCINT number. +// Enables event functions which need to be defined in the sketch. +// Valid interrupt modes are: RISING, FALLING or CHANGE +attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick), tick, RISING); + +// You can also input the PCINT number (see table below) +attachPinChangeInterrupt(5, tock, FALLING); + +// PinChangeInterrupt can always be abbreviated with PCINT +attachPCINT(digitalPinToPCINT(pinBlink), blinkLed, CHANGE); +``` + +##### Detach a PinChangeInterrupt +```cpp +// Similar usage as the attachPCINT function. +// Interrupts will no longer occur. +detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); +detachPinChangeInterrupt(5); +detachPCINT(digitalPinToPCINT(pinTock)); +``` + +##### Enable/Disable a PinChangeInterrupt +```cpp +// Similar usage as the attachPCINT function. +// Use this to temporary enable/disable the Interrupt +disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); +disablePinChangeInterrupt(5); +disablePCINT(digitalPinToPCINT(pinBlink)); + +// Enable the PCINT with the old settings again (function + mode) +enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); +enablePinChangeInterrupt(5); +enablePCINT(digitalPinToPCINT(pinBlink)); +``` + +##### Get Trigger on mode CHANGE +```cpp +// Differenciate between RISING and FALLING on mode CHANGE. +// Only use this in the attached interrupt function. +uint8_t trigger = getPinChangeInterruptTrigger(digitalPinToPCINT(pinTick)); +if(trigger == RISING) + // Do something +else if(trigger == FALLING) + // Do something +else + // Wrong usage (trigger == CHANGE) +``` + +##### LowLevel API +See [LowLevel example](examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino) for more details. +```cpp +// Use the attach function as you are used to, just leave out the function name +attachPinChangeInterrupt(interruptBlink, CHANGE); + +// LowLevel function that is called when an interrupt occurs for a specific PCINT. +// It is required to know the exact PCINT number, no Arduino pin number will work here. +void PinChangeInterruptEvent(5)(void) { + // Do something +} +``` + +PinchangeInterrupt Table +======================== +Pins with * are not broken out/deactivated by default. +You may activate them in the [setting file](https://github.com/NicoHood/PinChangeInterrupt/blob/master/src/PinChangeInterruptSettings.h#L98) (advanced). + +Each row section represents a port(0-3). +Not all MCUs have all Ports/Pins physically available. + +**Note: Not all supported AVRs are listed here. There are way more supported, please refer to the shorter list above.** + +#### Official Arduinos +``` +| PCINT | Uno/Nano/Mini | Mega/2560 | Leonardo/Micro | HL2 (8/16/32u2) | +| ----- | --------------- | -------------- | -------------- | --------------- | +| 0 | 8 (PB0) | 53 SS (PB0) | SS (PB0)* | 0 SS (PB0)* | +| 1 | 9 (PB1) | 52 SCK (PB1) | SCK (PB1) | 1 SCK (PB1) | +| 2 | 10 SS (PB2) | 51 MOSI (PB2) | MOSI (PB2) | 2 MOSI (PB2) | +| 3 | 11 MISO (PB3) | 50 MISO (PB3) | MISO (PB3) | 3 MISO (PB3) | +| 4 | 12 MOSI (PB4) | 10 (PB4) | 8/A8 (PB4) | 4 (PB4) | +| 5 | 13 SCK (PB5) | 11 (PB5) | 9/A9 (PB5) | 5 (PB5) | +| 6 | XTAL1 (PB6)* | 12 (PB6) | 10/A10 (PB6) | 6 (PB6) | +| 7 | XTAL2 (PB7)* | 13 (PB7) | 11 (PB7) | 7 (PB7) | +| ----- | --------------- | -------------- | -------------- | --------------- | +| 8 | A0 (PC0) | 0 RX (PE0)* | | (PC6)* | +| 9 | A1 (PC1) | 15 RX3 (PJ0)* | | (PC5)* | +| 10 | A2 (PC2) | 14 TX3 (PJ1)* | | (PC4)* | +| 11 | A3 (PC3) | NC (PJ2)* | | (PC2)* | +| 12 | A4 SDA (PC4) | NC (PJ3)* | | (PD5)* | +| 13 | A5 SDC (PC5) | NC (PJ4)* | | | +| 14 | RST (PC6)* | NC (PJ5)* | | | +| 15 | | NC (PJ6)* | | | +| ----- | --------------- | -------------- | -------------- | --------------- | +| 16 | 0 RX (PD0) | A8 (PK0) | | | +| 17 | 1 TX (PD1) | A9 (PK1) | | | +| 18 | 2 INT0 (PD2) | A10 (PK2) | | | +| 19 | 3 INT1 (PD3) | A11 (PK3) | | | +| 20 | 4 (PD4) | A12 (PK4) | | | +| 21 | 5 (PD5) | A13 (PK5) | | | +| 22 | 6 (PD6) | A14 (PK6) | | | +| 23 | 7 (PD7) | A15 (PK7) | | | +| ----- | --------------- | -------------- | -------------- | --------------- | +``` + +#### Atmel Attinys +``` +| PCINT | Attiny13 | Attiny x4 | Attiny x5 | Attiny x41 | +| ----- | ------------ | --------------- | ------------- | ------------------- | +| 0 | 0 MOSI (PB0) | 0 (PA0) | 0 MOSI (PB0) | A0/D0 (PA0) | +| 1 | 1 MISO (PB1) | 1 (PA1) | 1 MISO (PB1) | A1/D1 (PA1) | +| 2 | 2 SCK (PB2) | 2 (PA2) | 2 SCK (PB2) | A2/D2 (PA2) | +| 3 | 3 (PB3) | 3 (PA3) | 3 XTAL1 (PB3) | A3/D3 (PA3) | +| 4 | 4 (PB4) | 4 SCK (PA4) | 4 XTAL2 (PB4) | A4/D4 (PA4) | +| 5 | 5 RST (PB5) | 5 MISO (PA5) | 5 RST (PB5) | A5/D5 PWM (PA5) | +| 6 | | 6 MOSI (PA6) | | A7/D7 PWM (PA6) | +| 7 | | 7 (PA7) | | A6/D6 PWM (PA7) | +| ----- | ------------ | --------------- | ------------- | ------------------- | +| 8 | | 10 XTAL1 (PB0)* | | A10/D10 XTAL1 (PB0) | +| 9 | | 9 XTAL2 (PB1)* | | A9/D9 XTAL2 (PB1) | +| 10 | | 8 INT0 (PB2)* | | A8/D8 PWM (PB2) | +| 11 | | RST (PB3)* | | RST (PB3) | +| 12 | | | | | +| 13 | | | | | +| 14 | | | | | +| 15 | | | | | +| ----- | ------------ | --------------- | ------------- | ------------------- | +``` + +#### Other Atmel MCUs +``` +| PCINT | ATmega644P/1284P | +| ----- | ----------------- | +| 0 | A0/D24 (PA0) | +| 1 | A1/D25 (PA1) | +| 2 | A2/D26 (PA2) | +| 3 | A3/D27 (PA3) | +| 4 | A4/D28 (PA4) | +| 5 | A5/D29 (PA5) | +| 6 | A6/D30 (PA6) | +| 7 | A7/D31 (PA7) | +| ----- | ----------------- | +| 8 | 0 (PB0) | +| 9 | 1 (PB1) | +| 10 | 2 INT2 (PB2) | +| 11 | 3 PWM (PB3) | +| 12 | 4 SS/PWM (PB4) | +| 13 | 5 MOSI/PWM (PB5) | +| 14 | 6 MISO/PWM (PB6) | +| 15 | 7 SCK (PB7) | +| ----- | ----------------- | +| 16 | 16 SCL (PC0) | +| 17 | 17 SDA (PC1) | +| 18 | 18 TCK (PC2) | +| 19 | 19 TMS (PC3) | +| 20 | 20 TDO (PC4) | +| 21 | 21 TDI (PC5) | +| 22 | 22 (PC6) | +| 23 | 23 (PC7) | +| ----- | ----------------- | +| 24 | 8 RX0 (PD0) | +| 25 | 9 TX0 (PD1) | +| 26 | 10 RX1/INT0 (PD2) | +| 27 | 11 TX1/INT1 (PD3) | +| 28 | 12 PWM (PD4) | +| 29 | 13 PWM (PD5) | +| 30 | 14 PWM (PD6) | +| 31 | 15 PWM (PD7) | +| ----- | ----------------- | +``` + +Developer Information +===================== +If a PinChangeInterrupt occurs it will determine the triggered pin(s). +The library uses weak callback functions that are called for the triggered pins(s). +This way we can easily skip not triggered pins (I looked at the assembler) and also implement a fast LowLevel version. + +Also the order of the function execution is (normally) ordered from the lower pin number to the higher. +Meaning pin 8 will be checked faster as pin 13 (Arduino Uno). Talking about micro seconds here! You can change the order in the settings. +For example by default pin 0-3 have a low priority order than pin 4-7 (Arduino Uno). Because they are used for Serial and normal PinInterrupts. +I don't expect anyone to use those pins at all with PCINT but at least the priority is lowered compared to the other pins. + +The API takes those weak functions and just overwrites all of them and call the function pointers of the attached functions instead. +This way the function can be changed at runtime and its also easier to integrate into other libraries. +The function pointers take a bit flash though (LowLevel: 1526/18, API: 1790/58 for Led example). + +You can get better performance and less code size if you deactivate the not used pins/ports manually in the settings file. +This way only the needed pins get compiled and the code is optimized by the preprocessor. +For a bit more comfortable/automatic optimization you can [install the library into the core](https://github.com/NicoHood/PinChangeInterrupt/#optional-installation) +to get use of the .a linkage. This way only the used ports get compiled. +So if you only use pins on a single port (eg 8-13) then only this port gets compiled. This only works with the core installation. + + +That's it! I hope you like the library. I tried to make it as simple and small as possible. +Keep in mind that PCINTs are not useful for every project but in most cases +the new PinChangeInterrupts may help you a lot. + + +Version History +=============== +``` +1.2.9 Release (18.05.2021) +* Added Attiny261/461/861 support #39 +* Added Attiny2313/2313A/4313 support #37 +* Added ATMega328PB support #30 +* Added ATMega48 support #38 +* Fixed ATMega88/168 support #38 + +1.2.8 Release (22.11.2020) +* Add support for ATmega644 #34 + +1.2.7 Release (07.10.2018) +* Add support for ATmega162 #21 + +1.2.6 Release (10.02.2018) +* Fix makefile compilation problems + +1.2.5 Release (02.09.2017) +* Fixed makefile compilation +* Added support to disable pcint/port via -DPCINT_DISABLE_PORT0 etc. +* Added ATtinyX313 support +* Fix ATmega1284P + +1.2.4 Release (16.04.2016) +* Fixed Attinyx4/x5 Issue #8 + +1.2.3 Release (24.12.2015) +* Added Attiny441/841 support + +1.2.2 Release (05.12.2015) +* Fixed initial value when enabled issue +* Enabled official dot_a_linkage +* Added Attiny13 support Issue #4 +* Updated documentation +* Improved detaching function +* Improved attaching and enabling + +1.2.1 Release (24.05.2015) +* Fix Attiny Issue #1 +* Added enable/disable function +* Added getPinChangeInterruptTrigger() function +* Added to Arduino IDE library manager + +1.2 Release (19.04.2015) +* Added weak interrupt function +* Improved interrupt function calls +* Fixed attach/detach array position when ports are deactivated +* Improved manual PCINT deactivation by user +* Improved definitions for different boards +* HoodLoader2 definition fixes +* Improved speed +* Improved specific boards +* Moved attach function to .cpp file +* Updated examples +* Added API and LowLevel +* Added Port3 support (ATmega644P/ATmega1284P) +* Added PCINT_VERSION definition + +1.1 Release (06.12.2014) +* Added port deactivation +* Ram usage improvements for AVRs with <3 PCINT ports + +1.0 Release (04.12.2014) +* Added general PinChangeInterrupt functions +* Added support for most Arduino boards +* Added basic example +* Added an example with IRLremote +``` + + +License and Copyright +===================== +If you use this library for any cool project let me know! + +``` +Copyright (c) 2014-2021 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +``` diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino new file mode 100644 index 0000000..e23743e --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino @@ -0,0 +1,122 @@ +/* + Copyright (c) 2014-2015 NicoHood + See the readme for credit to other people. + + PinChangeInterrupt_HowItWorks + Shows how to manually setup a single PCINT function with a few helper functions. + + Connect a button/cable to pin 7 and ground. + The led will change its state if pin 7 changes. + + PinChangeInterrupts are different than normal Interrupts. + See readme for more information. + Dont use Serial or delay inside interrupts! + This library is not compatible with SoftSerial. + + The following pins are usable for PinChangeInterrupt: + Arduino Uno/Nano/Mini: All pins are usable + Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), + A11 (65), A12 (66), A13 (67), A14 (68), A15 (69) + Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) + HoodLoader2: All (broken out 1-7) pins are usable + Attiny 24/44/84: All pins are usable + Attiny 25/45/85: All pins are usable + Attiny 13: All pins are usable + Attiny 441/841: All pins are usable + ATmega644P/ATmega1284P: All pins are usable + */ + +//================================================================================ +// User Settings +//================================================================================ + +// choose a valid PinChangeInterrupt pin of your Arduino board +#define PCINT_PIN 7 +#define PCINT_MODE CHANGE +#define PCINT_FUNCTION blinkLed + +void setup() +{ + // set pins to input with a pullup, led to output + pinMode(PCINT_PIN, INPUT_PULLUP); + pinMode(LED_BUILTIN, OUTPUT); + + // attach the new PinChangeInterrupt + attachPinChangeInterrupt(); +} + +void loop() { + // empty +} + +void blinkLed(void) { + // switch Led state + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +} + +//================================================================================ +// PCINT Definitions +//================================================================================ + +#define PCMSK *digitalPinToPCMSK(PCINT_PIN) +#define PCINT digitalPinToPCMSKbit(PCINT_PIN) +#define PCIE digitalPinToPCICRbit(PCINT_PIN) +#define PCPIN *portInputRegister(digitalPinToPort(PCINT_PIN)) + +#if (PCIE == 0) +#define PCINT_vect PCINT0_vect +#elif (PCIE == 1) +#define PCINT_vect PCINT1_vect +#elif (PCIE == 2) +#define PCINT_vect PCINT2_vect +#else +#error This board doesnt support PCINT ? +#endif + +volatile uint8_t oldPort = 0x00; + +void attachPinChangeInterrupt(void) { + // update the old state to the actual state + oldPort = PCPIN; + + // pin change mask registers decide which pins are enabled as triggers + PCMSK |= (1 << PCINT); + + // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors + PCICR |= (1 << PCIE); +} + +void detachPinChangeInterrupt(void) { + // disable the mask. + PCMSK &= ~(1 << PCINT); + + // if that's the last one, disable the interrupt. + if (PCMSK == 0) + PCICR &= ~(0x01 << PCIE); +} + +ISR(PCINT_vect) { + // get the new and old pin states for port + uint8_t newPort = PCPIN; + + // compare with the old value to detect a rising or falling + uint8_t change = newPort ^ oldPort; + + // check which pins are triggered, compared with the settings + uint8_t trigger = 0x00; +#if (PCINT_MODE == RISING) || (PCINT_MODE == CHANGE) + uint8_t rising = change & newPort; + trigger |= (rising & (1 << PCINT)); +#endif +#if (PCINT_MODE == FALLING) || (PCINT_MODE == CHANGE) + uint8_t falling = change & oldPort; + trigger |= (falling & (1 << PCINT)); +#endif + + // save the new state for next comparison + oldPort = newPort; + + // if our needed pin has changed, call the IRL interrupt function + if (trigger & (1 << PCINT)) + PCINT_FUNCTION(); +} diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino new file mode 100644 index 0000000..21a7cb4 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014-2015 NicoHood + See the readme for credit to other people. + + PinChangeInterrupt_TickTock + Demonstrates how to use the library + + Connect a button/cable to pin 7 and ground. + The Led state will change if the pin state does. + + PinChangeInterrupts are different than normal Interrupts. + See readme for more information. + Dont use Serial or delay inside interrupts! + This library is not compatible with SoftSerial. + + The following pins are usable for PinChangeInterrupt: + Arduino Uno/Nano/Mini: All pins are usable + Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), + A11 (65), A12 (66), A13 (67), A14 (68), A15 (69) + Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) + HoodLoader2: All (broken out 1-7) pins are usable + Attiny 24/44/84: All pins are usable + Attiny 25/45/85: All pins are usable + Attiny 13: All pins are usable + Attiny 441/841: All pins are usable + ATmega644P/ATmega1284P: All pins are usable +*/ + +#include "PinChangeInterrupt.h" + +// Choose a valid PinChangeInterrupt pin of your Arduino board +#define pinBlink 7 + +void setup() { + // set pin to input with a pullup, led to output + pinMode(pinBlink, INPUT_PULLUP); + pinMode(LED_BUILTIN, OUTPUT); + + // Manually blink once to test if LED is functional + blinkLed(); + delay(1000); + blinkLed(); + + // Attach the new PinChangeInterrupt and enable event function below + attachPCINT(digitalPinToPCINT(pinBlink), blinkLed, CHANGE); +} + +void blinkLed(void) { + // Switch Led state + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +} + +void loop() { + // Nothing to do here +} diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino new file mode 100644 index 0000000..615f3bb --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino @@ -0,0 +1,60 @@ +/* + Copyright (c) 2014-2015 NicoHood + See the readme for credit to other people. + + PinChangeInterrupt_LowLevel + Demonstrates how to use the library without the API + + Make sure to comment "//#define PCINT_API" in the settings file. + + To maximize speed and size also uncomment all not used pins above. + Then you could also uncomment "#define PCINT_COMPILE_ENABLED_ISR" + to get away the .a linkage overhead. + + Connect a button/cable to pin 7 and ground (Uno). + Strong overwritten callback functions are called when an interrupt occurs. + The Led state will change if the pin state does. + + PinChangeInterrupts are different than normal Interrupts. + See readme for more information. + Dont use Serial or delay inside interrupts! + This library is not compatible with SoftSerial. + + The following pins are usable for PinChangeInterrupt: + Arduino Uno/Nano/Mini: All pins are usable + Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), + A11 (65), A12 (66), A13 (67), A14 (68), A15 (69) + Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) + HoodLoader2: All (broken out 1-7) pins are usable + Attiny 24/44/84: All pins are usable + Attiny 25/45/85: All pins are usable + Attiny 13: All pins are usable + Attiny 441/841: All pins are usable + ATmega644P/ATmega1284P: All pins are usable + */ + +#include "PinChangeInterrupt.h" + +// choose a valid PinChangeInterrupt pin of your Arduino board +// manually defined pcint number +#define pinBlink 7 +#define interruptBlink 23 + +void setup() +{ + // set pin to input with a pullup, led to output + pinMode(pinBlink, INPUT_PULLUP); + pinMode(LED_BUILTIN, OUTPUT); + + // attach the new PinChangeInterrupts and enable event functions below + attachPinChangeInterrupt(interruptBlink, CHANGE); +} + +void PinChangeInterruptEvent(interruptBlink)(void) { + // switch Led state + digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); +} + +void loop() { + // nothing to do here +} diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino new file mode 100644 index 0000000..622c34d --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino @@ -0,0 +1,98 @@ +/* + Copyright (c) 2014-2015 NicoHood + See the readme for credit to other people. + + PinChangeInterrupt_TickTock + Demonstrates how to use the library + + Connect a button/cable to pin 10/11 and ground. + The value printed on the serial port will increase + if pin 10 is rising and decrease if pin 11 is falling. + + PinChangeInterrupts are different than normal Interrupts. + See readme for more information. + Dont use Serial or delay inside interrupts! + This library is not compatible with SoftSerial. + + The following pins are usable for PinChangeInterrupt: + Arduino Uno/Nano/Mini: All pins are usable + Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), + A11 (65), A12 (66), A13 (67), A14 (68), A15 (69) + Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI) + HoodLoader2: All (broken out 1-7) pins are usable + Attiny 24/44/84: All pins are usable + Attiny 25/45/85: All pins are usable + Attiny 13: All pins are usable + Attiny 441/841: All pins are usable + ATmega644P/ATmega1284P: All pins are usable +*/ + +#include "PinChangeInterrupt.h" + +// choose a valid PinChangeInterrupt pin of your Arduino board +#define pinTick 10 +#define pinTock 11 + +volatile long ticktocks = 0; + +void setup() +{ + // start serial debug output + Serial.begin(115200); + Serial.println(F("Startup")); + + // set pins to input with a pullup + pinMode(pinTick, INPUT_PULLUP); + pinMode(pinTock, INPUT_PULLUP); + + // attach the new PinChangeInterrupts and enable event functions below + attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick), tick, RISING); + attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock), tock, FALLING); +} + +void loop() { + // integer to count the number of prints + static int i = 0; + delay(1000); + + // print values + Serial.print(i, DEC); + Serial.print(F(" ")); + Serial.println(ticktocks); + + // abort if we printed 100 times + if (i >= 100) { + Serial.println(F("Detaching Interrupts.")); + detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); + detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock)); + return; + } + else + i++; + + // Temporary pause interrupts + if (ticktocks > 500) { + Serial.println(F("Disabling Tick Interrupt.")); + disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); + enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock)); + } + else if (ticktocks < -500) { + Serial.println(F("Disabling Tock Interrupt.")); + disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock)); + enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); + } + else { + enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick)); + enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock)); + } +} + +void tick(void) { + // increase value + ticktocks++; +} + +void tock(void) { + // decrease value + ticktocks--; +} diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/header.png b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/header.png new file mode 100644 index 0000000000000000000000000000000000000000..67818fc1010f80ec4b9922970aceaa6032df8513 GIT binary patch literal 23975 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 literal 0 HcmV?d00001 diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt new file mode 100644 index 0000000..1af2b5d --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt @@ -0,0 +1,32 @@ +####################################### +# Syntax Coloring Map For PinChangeInterrupt +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +attachPinChangeInterrupt KEYWORD2 +detachPinChangeInterrupt KEYWORD2 +attachPCINT KEYWORD2 +detachPCINT KEYWORD2 +PinChangeInterruptEvent KEYWORD2 +PCINTEvent KEYWORD2 +enablePCINT KEYWORD2 +enablePinChangeInterrupt KEYWORD2 +disablePCINT KEYWORD2 +disablePinChangeInterrupt KEYWORD2 +getPCINTTrigger KEYWORD2 +getPinChangeInterruptTrigger KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties new file mode 100644 index 0000000..bb3a6e0 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties @@ -0,0 +1,10 @@ +name=PinChangeInterrupt +version=1.2.9 +author=NicoHood +maintainer=NicoHood +sentence=A simple & compact PinChangeInterrupt library for Arduino. +paragraph=PinChangeInterrupt library with a resource friendly implementation (API and LowLevel). PinChangeInterrupts are different than normal Interrupts. See readme for more information. +category=Signal Input/Output +url=https://github.com/NicoHood/PinChangeInterrupt +architectures=avr +dot_a_linkage=true diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp new file mode 100644 index 0000000..d83ef6b --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp @@ -0,0 +1,336 @@ +/* +Copyright (c) 2014-2015 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "PinChangeInterrupt.h" + +// manually include cpp files here to save flash if only 1 ISR is present +// or if the user knows he just wants to compile all enabled ports. +#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) +#define PCINT_INCLUDE_FROM_CPP +#include "PinChangeInterrupt0.cpp" +#include "PinChangeInterrupt1.cpp" +#include "PinChangeInterrupt2.cpp" +#include "PinChangeInterrupt3.cpp" +#else + +//================================================================================ +// Weak Callbacks +//================================================================================ + +// create all weak functions which are all (if not used) alias of the pcint_null_callback above +/* +for (int i = 0; i < 32; i++) { +Serial.print("void PinChangeInterruptEventPCINT"); +Serial.print(i); +Serial.println("(void) __attribute__((weak, alias(\"pcint_null_callback\")));"); +} +*/ +void PinChangeInterruptEventPCINT0(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT1(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT2(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT3(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT4(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT5(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT6(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT7(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT8(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT9(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT10(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT11(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT12(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT13(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT14(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT15(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT16(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT17(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT18(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT19(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT20(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT21(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT22(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT23(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT24(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT25(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT26(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT27(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT28(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT29(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT30(void) __attribute__((weak, alias("pcint_null_callback"))); +void PinChangeInterruptEventPCINT31(void) __attribute__((weak, alias("pcint_null_callback"))); + +#endif // PCINT_INCLUDE_FROM_CPP + +// useless function for weak implemented/not used functions, extern c needed for the alias +extern "C" { + void pcint_null_callback(void) { + // useless + } +} + +//================================================================================ +// PinChangeInterrupt User Functions +//================================================================================ + +// variables to save the last port states and the interrupt settings +uint8_t oldPorts[PCINT_NUM_USED_PORTS] = { 0 }; +uint8_t fallingPorts[PCINT_NUM_USED_PORTS] = { 0 }; +uint8_t risingPorts[PCINT_NUM_USED_PORTS] = { 0 }; + +void enablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask, const uint8_t arrayPos){ + // Update the old state to the actual state + switch(pcintPort){ +#ifdef PCINT_INPUT_PORT0_USED + case 0: + oldPorts[arrayPos] = PCINT_INPUT_PORT0; + break; +#endif +#ifdef PCINT_INPUT_PORT1_USED + case 1: + oldPorts[arrayPos] = PCINT_INPUT_PORT1; + break; +#endif +#ifdef PCINT_INPUT_PORT2_USED + case 2: + oldPorts[arrayPos] = PCINT_INPUT_PORT2; + break; +#endif +#ifdef PCINT_INPUT_PORT3_USED + case 3: + oldPorts[arrayPos] = PCINT_INPUT_PORT3; + break; +#endif + } + + // Pin change mask registers decide which pins are ENABLE as triggers +#ifdef PCMSK0 +#ifdef PCMSK1 +#ifdef PCMSK3 + // Special case for ATmega1284P where PCMSK3 is not directly after PCMSK2 + if(false){ +#else + // Special case for Attinyx4 where PCMSK1 and PCMSK0 are not next to each other + if(&PCMSK1 - &PCMSK0 == 1){ +#endif +#endif + *(&PCMSK0 + pcintPort) |= pcintMask; +#ifdef PCMSK1 + } + else{ + switch(pcintPort){ + case 0: + PCMSK0 |= pcintMask; + break; + case 1: + PCMSK1 |= pcintMask; + break; +#ifdef PCMSK2 + case 2: + PCMSK2 |= pcintMask; + break; +#endif +#ifdef PCMSK3 + case 3: + PCMSK3 |= pcintMask; + break; +#endif + } + } +#endif +#elif defined(PCMSK) + *(&PCMSK + pcintPort) |= pcintMask; +#endif + + // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors +#ifdef PCICR + PCICR |= (1 << (pcintPort + PCIE0)); +#elif defined(GICR) /* e.g. ATmega162 */ + GICR |= (1 << (pcintPort + PCIE0)); +#elif defined(GIMSK) && defined(PCIE0) /* e.g. ATtiny X4 */ + GIMSK |= (1 << (pcintPort + PCIE0)); +#elif defined(GIMSK) && defined(PCIE) /* e.g. ATtiny X5 */ + GIMSK |= (1 << (pcintPort + PCIE)); +#else +#error MCU has no such a register +#endif +} + +void disablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask) { + bool disable = false; +#ifdef PCMSK0 +#ifdef PCMSK1 + // Special case for Attinyx4 where PCMSK1 and PCMSK0 are not next to each other + if(&PCMSK1 - &PCMSK0 == 1){ +#endif + // disable the mask. + *(&PCMSK0 + pcintPort) &= ~pcintMask; + + // if that's the last one, disable the interrupt. + if (*(&PCMSK0 + pcintPort) == 0) + disable = true; +#ifdef PCMSK1 + } + else{ + switch(pcintPort){ + case 0: + // disable the mask. + PCMSK0 &= ~pcintMask; + + // if that's the last one, disable the interrupt. + if (!PCMSK0) + disable = true; + break; + case 1: + // disable the mask. + PCMSK1 &= ~pcintMask; + + // if that's the last one, disable the interrupt. + if (!PCMSK1) + disable = true; + break; +#ifdef PCMSK2 + case 2: + // disable the mask. + PCMSK2 &= ~pcintMask; + + // if that's the last one, disable the interrupt. + if (!PCMSK2) + disable = true; + break; +#endif +#ifdef PCMSK3 + case 3: + // disable the mask. + PCMSK3 &= ~pcintMask; + + // if that's the last one, disable the interrupt. + if (!PCMSK3) + disable = true; + break; +#endif + } + } +#endif +#elif defined(PCMSK) + // disable the mask. + *(&PCMSK + pcintPort) &= ~pcintMask; + + // if that's the last one, disable the interrupt. + if (*(&PCMSK + pcintPort) == 0) + disable = true; +#endif + if(disable) + { +#ifdef PCICR + PCICR &= ~(1 << (pcintPort + PCIE0)); +#elif defined(GICR) /* e.g. ATmega162 */ + GICR &= ~(1 << (pcintPort + PCIE0)); +#elif defined(GIMSK) && defined(PCIE0) /* e.g. ATtiny X4 */ + GIMSK &= ~(1 << (pcintPort + PCIE0)); +#elif defined(GIMSK) && defined(PCIE) /* e.g. ATtiny X5 */ + GIMSK &= ~(1 << (pcintPort + PCIE)); +#else +#error MCU has no such a register +#endif + } +} + +/* +asm output (nothing to optimize here) + +ISR(PCINT0_vect) { +push r1 +push r0 +in r0, 0x3f ; 63 +push r0 +eor r1, r1 +push r18 +push r19 +push r20 +push r21 +push r22 +push r23 +push r24 +push r25 +push r26 +push r27 +push r28 +push r30 +push r31 + +// get the new and old pin states for port +// uint8_t newPort = pinChangeInterruptPortToInput(port); +in r24, 0x03; 3 //(1) loads byte into newPort from I/O register + +// loads old port and high + low setting +lds r18, 0x011E //(1 or 2) loads oldPorts into register +lds r28, 0x011B //(1 or 2) loads fallingPorts into register +lds r25, 0x0118 //(1 or 2) loads risingPorts into register + +and r28, r18 // oldPorts & fallingPorts +and r25, r24 // newPort & risingPorts +or r28, r25 // (oldPorts & fallingPorts) | (newPort & risingPorts) +eor r18, r24 // oldPorts^newPort +and r28, r18 // ((oldPorts & fallingPorts) | (newPort & risingPorts)) & (oldPorts^newPort) + +// save the new state for next comparison +// oldPorts[arrayPos] = newPort; +sts 0x011E, r24 + +// Execute all functions that should be triggered +sbrc r28, 0 +call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v> +sbrc r28, 1 +call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v> +sbrc r28, 2 +call 0x318 ; 0x318 <_Z20PinChangeInterruptEventPCINT2v> +sbrc r28, 3 +call 0x340 ; 0x340 <_Z20PinChangeInterruptEventPCINT3v> +sbrc r28, 4 +call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v> +sbrc r28, 5 +call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v> +sbrc r28, 6 +call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v> +sbrc r28, 7 +call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v> + +pop r31 +pop r30 +pop r28 +pop r27 +pop r26 +pop r25 +pop r24 +pop r23 +pop r22 +pop r21 +pop r20 +pop r19 +pop r18 +pop r0 +out 0x3f, r0 ; 63 +pop r0 +pop r1 +reti +} +*/ diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h new file mode 100644 index 0000000..b30fb62 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h @@ -0,0 +1,898 @@ +/* +Copyright (c) 2014-2021 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Include Guard +#pragma once + +// Software Version +#define PCINT_VERSION 129 + +#include +#include + +#ifdef ARDUINO +#include "Arduino.h" + +#ifndef ARDUINO_ARCH_AVR +#error This library can only be used with AVR +#endif + +#else + +#ifndef LOW +#define LOW 0x0 +#endif +#ifndef CHANGE +#define CHANGE 0x1 +#endif +#ifndef FALLING +#define FALLING 0x2 +#endif +#ifndef RISING +#define RISING 0x3 +#endif + +#endif + +//================================================================================ +// General Helper Definitions and Mappings +//================================================================================ + +// Settings and Board definitions are seperated to get an better overview. +// The order and position of the inclusion is important! +#include "PinChangeInterruptSettings.h" +#include "PinChangeInterruptBoards.h" +#include "PinChangeInterruptPins.h" + +#if !PCINT_NUM_USED_PORTS +#error Please enable at least one PCINT port and pin! +#endif + +// manually include cpp files to save flash if only 1 ISR is present +// it includes all ISR files but only the 1 available ISR will/can be compiled +#if (PCINT_NUM_USED_PORTS == 1) +#ifndef PCINT_COMPILE_ENABLED_ISR +#define PCINT_COMPILE_ENABLED_ISR +#endif +#endif + +//================================================================================ +// Makro Definitions +//================================================================================ + +// generates the callback for easier reordering in Settings +#define PCINT_MACRO_BRACKETS () +#define PCINT_MACRO_TRUE == true) +#define PCINT_CALLBACK(bit, pcint) \ +if (PCINT_USE_PCINT ## pcint PCINT_MACRO_TRUE \ +if (trigger & (1 << bit)) \ +PinChangeInterruptEventPCINT ## pcint PCINT_MACRO_BRACKETS + +// definition used by the user to create custom LowLevel PCINT Events +#define PinChangeInterruptEvent_Wrapper(n) PinChangeInterruptEventPCINT ## n +#define PinChangeInterruptEvent(n) PinChangeInterruptEvent_Wrapper(n) + +// missing 1.0.6 definition workaround +#ifndef NOT_AN_INTERRUPT +#define NOT_AN_INTERRUPT -1 +#endif + +// convert a normal pin to its PCINT number (0 - max 23), used by the user +// calculates the pin by the Arduino definitions +#if defined(PCIE0) +#define digitalPinToPinChangeInterrupt(p) (digitalPinToPCICR(p) ? ((8 * (digitalPinToPCICRbit(p) - PCIE0)) + digitalPinToPCMSKbit(p)) : NOT_AN_INTERRUPT) +#elif defined(PCIE) +#define digitalPinToPinChangeInterrupt(p) (digitalPinToPCICR(p) ? ((8 * (digitalPinToPCICRbit(p) - PCIE)) + digitalPinToPCMSKbit(p)) : NOT_AN_INTERRUPT) +#else +#error MCU has no such a register +#endif + +// alias for shorter writing +#define PCINTEvent(n) PinChangeInterruptEvent_Wrapper(n) +#define digitalPinToPCINT digitalPinToPinChangeInterrupt +#define attachPCINT attachPinChangeInterrupt +#define enablePCINT enablePinChangeInterrupt +#define detachPCINT detachPinChangeInterrupt +#define disablePCINT disablePinChangeInterrupt +#define getPCINTTrigger getPinChangeInterruptTrigger + +//================================================================================ +// Function Prototypes + Variables +//================================================================================ + +// typedef for our callback function pointers +typedef void(*callback)(void); + +// useless function for weak implemented/not used functions, extern c needed for the alias +#ifdef __cplusplus +extern "C" { +#endif + void pcint_null_callback(void); +#ifdef __cplusplus +} +#endif + +void PinChangeInterruptEventPCINT0(void); +void PinChangeInterruptEventPCINT1(void); +void PinChangeInterruptEventPCINT2(void); +void PinChangeInterruptEventPCINT3(void); +void PinChangeInterruptEventPCINT4(void); +void PinChangeInterruptEventPCINT5(void); +void PinChangeInterruptEventPCINT6(void); +void PinChangeInterruptEventPCINT7(void); +void PinChangeInterruptEventPCINT8(void); +void PinChangeInterruptEventPCINT9(void); +void PinChangeInterruptEventPCINT10(void); +void PinChangeInterruptEventPCINT11(void); +void PinChangeInterruptEventPCINT12(void); +void PinChangeInterruptEventPCINT13(void); +void PinChangeInterruptEventPCINT14(void); +void PinChangeInterruptEventPCINT15(void); +void PinChangeInterruptEventPCINT16(void); +void PinChangeInterruptEventPCINT17(void); +void PinChangeInterruptEventPCINT18(void); +void PinChangeInterruptEventPCINT19(void); +void PinChangeInterruptEventPCINT20(void); +void PinChangeInterruptEventPCINT21(void); +void PinChangeInterruptEventPCINT22(void); +void PinChangeInterruptEventPCINT23(void); +void PinChangeInterruptEventPCINT24(void); +void PinChangeInterruptEventPCINT25(void); +void PinChangeInterruptEventPCINT26(void); +void PinChangeInterruptEventPCINT27(void); +void PinChangeInterruptEventPCINT28(void); +void PinChangeInterruptEventPCINT29(void); +void PinChangeInterruptEventPCINT30(void); +void PinChangeInterruptEventPCINT31(void); + +extern uint8_t oldPorts[PCINT_NUM_USED_PORTS]; +extern uint8_t fallingPorts[PCINT_NUM_USED_PORTS]; +extern uint8_t risingPorts[PCINT_NUM_USED_PORTS]; + + +static inline uint8_t getArrayPosPCINT(uint8_t pcintPort) __attribute__((always_inline)); +uint8_t getArrayPosPCINT(uint8_t pcintPort) { + /* + Maps the port to the array. + This is needed since you can deactivate ports + and the array will dynamically resize to save ram. + + The function does not need that much flash since the if and else + are known at compile time, so the compiler removes all the complex logic. + The return is is the input if all pins are activated for example. + That's why the function is inline. + */ + + if (PCINT_NUM_USED_PORTS == 1) { + // only the first element is used for a single port + return 0; + } + else if (PCINT_NUM_USED_PORTS == PCINT_NUM_PORTS) { + // use all ports and down remap the array position. + return pcintPort; + } + else if (PCINT_NUM_PORTS - PCINT_NUM_USED_PORTS == 1) { + // one port is not used + if (PCINT_USE_PORT0 == 0) { + // first port is not used, decrease all port numbers + return (pcintPort - 1); + } + else if (PCINT_HAS_PORT3 == 0) { + // 3 ports (standard) + if (PCINT_USE_PORT2 == 0) { + // last port not used, no mapping needed + return pcintPort; + } + else { + // worst case, port in the middle not used, remap + return ((pcintPort >> 1) & 0x01); + //if (pcintPort == 0) return 0; + //else return 1; + } + } + else { + // 4 ports (special case for a few AVRs) + if (PCINT_USE_PORT3 == 0) { + // last port not used, no mapping needed + return pcintPort; + } + else { + // worst case, one of two ports in the middle not used, remap + if (PCINT_USE_PORT1 == 0) { + // port1 not used, mapping needed + if (pcintPort == 0) + return 0; + else + return pcintPort - 1; + } + else if (PCINT_USE_PORT2 == 0) { + // port2 not used, mapping needed + if (pcintPort == 3) + return 2; + else + return pcintPort; + } + } + } + + // use all ports and down remap the array position. + return pcintPort; + } + else if (PCINT_NUM_PORTS - PCINT_NUM_USED_PORTS == 2) { + if (PCINT_USE_PORT2 == 0 && PCINT_USE_PORT3 == 0) { + // no need for mapping + return pcintPort; + } + else if (PCINT_USE_PORT0 == 0 && PCINT_USE_PORT3 == 0) { + // 1 offset + return (pcintPort - 1); + } + else if (PCINT_USE_PORT0 == 0 && PCINT_USE_PORT1 == 0) { + // 2 offset + return (pcintPort - 2); + } + else if (PCINT_USE_PORT0 == 0 && PCINT_USE_PORT2 == 0) { + // 2 -> 1 + return (pcintPort >> 1); + } + else if (PCINT_USE_PORT1 == 0 && PCINT_USE_PORT2 == 0) { + // 3 -> 1 + return (pcintPort >> 1); + } + else if (PCINT_USE_PORT1 == 0 && PCINT_USE_PORT3 == 0) { + // 3 -> 1, 1 -> 0 + return (pcintPort >> 1); + } + } + + // error + return 0; +} + +//================================================================================ +// Attach Function (partly inlined) +//================================================================================ + +void enablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask, const uint8_t arrayPos); +void attachPinChangeInterrupt0(void); +void attachPinChangeInterrupt1(void); +void attachPinChangeInterrupt2(void); +void attachPinChangeInterrupt3(void); + +#if defined(PCINT_API) + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" == true)"); +Serial.print("extern volatile callback callbackPCINT"); +Serial.print(i); +Serial.println(";"); +Serial.println("#endif"); +} +*/ +#if (PCINT_USE_PCINT0 == true) +extern volatile callback callbackPCINT0; +#endif +#if (PCINT_USE_PCINT1 == true) +extern volatile callback callbackPCINT1; +#endif +#if (PCINT_USE_PCINT2 == true) +extern volatile callback callbackPCINT2; +#endif +#if (PCINT_USE_PCINT3 == true) +extern volatile callback callbackPCINT3; +#endif +#if (PCINT_USE_PCINT4 == true) +extern volatile callback callbackPCINT4; +#endif +#if (PCINT_USE_PCINT5 == true) +extern volatile callback callbackPCINT5; +#endif +#if (PCINT_USE_PCINT6 == true) +extern volatile callback callbackPCINT6; +#endif +#if (PCINT_USE_PCINT7 == true) +extern volatile callback callbackPCINT7; +#endif +#if (PCINT_USE_PCINT8 == true) +extern volatile callback callbackPCINT8; +#endif +#if (PCINT_USE_PCINT9 == true) +extern volatile callback callbackPCINT9; +#endif +#if (PCINT_USE_PCINT10 == true) +extern volatile callback callbackPCINT10; +#endif +#if (PCINT_USE_PCINT11 == true) +extern volatile callback callbackPCINT11; +#endif +#if (PCINT_USE_PCINT12 == true) +extern volatile callback callbackPCINT12; +#endif +#if (PCINT_USE_PCINT13 == true) +extern volatile callback callbackPCINT13; +#endif +#if (PCINT_USE_PCINT14 == true) +extern volatile callback callbackPCINT14; +#endif +#if (PCINT_USE_PCINT15 == true) +extern volatile callback callbackPCINT15; +#endif +#if (PCINT_USE_PCINT16 == true) +extern volatile callback callbackPCINT16; +#endif +#if (PCINT_USE_PCINT17 == true) +extern volatile callback callbackPCINT17; +#endif +#if (PCINT_USE_PCINT18 == true) +extern volatile callback callbackPCINT18; +#endif +#if (PCINT_USE_PCINT19 == true) +extern volatile callback callbackPCINT19; +#endif +#if (PCINT_USE_PCINT20 == true) +extern volatile callback callbackPCINT20; +#endif +#if (PCINT_USE_PCINT21 == true) +extern volatile callback callbackPCINT21; +#endif +#if (PCINT_USE_PCINT22 == true) +extern volatile callback callbackPCINT22; +#endif +#if (PCINT_USE_PCINT23 == true) +extern volatile callback callbackPCINT23; +#endif +#if (PCINT_USE_PCINT24 == true) +extern volatile callback callbackPCINT24; +#endif +#if (PCINT_USE_PCINT25 == true) +extern volatile callback callbackPCINT25; +#endif +#if (PCINT_USE_PCINT26 == true) +extern volatile callback callbackPCINT26; +#endif +#if (PCINT_USE_PCINT27 == true) +extern volatile callback callbackPCINT27; +#endif +#if (PCINT_USE_PCINT28 == true) +extern volatile callback callbackPCINT28; +#endif +#if (PCINT_USE_PCINT29 == true) +extern volatile callback callbackPCINT29; +#endif +#if (PCINT_USE_PCINT30 == true) +extern volatile callback callbackPCINT30; +#endif +#if (PCINT_USE_PCINT31 == true) +extern volatile callback callbackPCINT31; +#endif + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" == true)"); +Serial.print("if (pcintNum == "); +Serial.print(i); +Serial.println(")"); +Serial.print("callbackPCINT"); +Serial.print(i); +Serial.println(" = userFunc;"); +Serial.println("#endif"); +} +*/ + +// API attach function +static inline void attachPinChangeInterrupt(const uint8_t pcintNum, void(*userFunc)(void), const uint8_t mode) __attribute__((always_inline)); +void attachPinChangeInterrupt(const uint8_t pcintNum, void(*userFunc)(void), const uint8_t mode) { +#else // no API attach function +static inline void attachPinChangeInterrupt(const uint8_t pcintNum, const uint8_t mode) __attribute__((always_inline)); +void attachPinChangeInterrupt(const uint8_t pcintNum, const uint8_t mode) { +#endif // PCINT_API + + // check if pcint is a valid pcint, exclude deactivated ports + uint8_t pcintPort = pcintNum / 8; + uint8_t pcintBit = pcintNum % 8; + + // port 0 + if (pcintPort == 0 && PCINT_USE_PORT0 == true) { + // use fake functions to make the ISRs compile with .a linkage +#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR) + attachPinChangeInterrupt0(); +#endif + + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT0 == true) + if (pcintNum == 0) + callbackPCINT0 = userFunc; +#endif +#if (PCINT_USE_PCINT1 == true) + if (pcintNum == 1) + callbackPCINT1 = userFunc; +#endif +#if (PCINT_USE_PCINT2 == true) + if (pcintNum == 2) + callbackPCINT2 = userFunc; +#endif +#if (PCINT_USE_PCINT3 == true) + if (pcintNum == 3) + callbackPCINT3 = userFunc; +#endif +#if (PCINT_USE_PCINT4 == true) + if (pcintNum == 4) + callbackPCINT4 = userFunc; +#endif +#if (PCINT_USE_PCINT5 == true) + if (pcintNum == 5) + callbackPCINT5 = userFunc; +#endif +#if (PCINT_USE_PCINT6 == true) + if (pcintNum == 6) + callbackPCINT6 = userFunc; +#endif +#if (PCINT_USE_PCINT7 == true) + if (pcintNum == 7) + callbackPCINT7 = userFunc; +#endif +#endif // PCINT_API + } + + // port 1 + else if (pcintPort == 1 && PCINT_USE_PORT1 == true) { + // use fake functions to make the ISRs compile with .a linkage +#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR) + attachPinChangeInterrupt1(); +#endif + + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT8 == true) + if (pcintNum == 8) + callbackPCINT8 = userFunc; +#endif +#if (PCINT_USE_PCINT9 == true) + if (pcintNum == 9) + callbackPCINT9 = userFunc; +#endif +#if (PCINT_USE_PCINT10 == true) + if (pcintNum == 10) + callbackPCINT10 = userFunc; +#endif +#if (PCINT_USE_PCINT11 == true) + if (pcintNum == 11) + callbackPCINT11 = userFunc; +#endif +#if (PCINT_USE_PCINT12 == true) + if (pcintNum == 12) + callbackPCINT12 = userFunc; +#endif +#if (PCINT_USE_PCINT13 == true) + if (pcintNum == 13) + callbackPCINT13 = userFunc; +#endif +#if (PCINT_USE_PCINT14 == true) + if (pcintNum == 14) + callbackPCINT14 = userFunc; +#endif +#if (PCINT_USE_PCINT15 == true) + if (pcintNum == 15) + callbackPCINT15 = userFunc; +#endif +#endif // PCINT_API + } + + // port 2 + else if (pcintPort == 2 && PCINT_USE_PORT2 == true) { + // use fake functions to make the ISRs compile with .a linkage +#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR) + attachPinChangeInterrupt2(); +#endif + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT16 == true) + if (pcintNum == 16) + callbackPCINT16 = userFunc; +#endif +#if (PCINT_USE_PCINT17 == true) + if (pcintNum == 17) + callbackPCINT17 = userFunc; +#endif +#if (PCINT_USE_PCINT18 == true) + if (pcintNum == 18) + callbackPCINT18 = userFunc; +#endif +#if (PCINT_USE_PCINT19 == true) + if (pcintNum == 19) + callbackPCINT19 = userFunc; +#endif +#if (PCINT_USE_PCINT20 == true) + if (pcintNum == 20) + callbackPCINT20 = userFunc; +#endif +#if (PCINT_USE_PCINT21 == true) + if (pcintNum == 21) + callbackPCINT21 = userFunc; +#endif +#if (PCINT_USE_PCINT22 == true) + if (pcintNum == 22) + callbackPCINT22 = userFunc; +#endif +#if (PCINT_USE_PCINT23 == true) + if (pcintNum == 23) + callbackPCINT23 = userFunc; +#endif +#endif // PCINT_API + } + + // port 3 + else if (pcintPort == 3 && PCINT_USE_PORT3 == true) { + // use fake functions to make the ISRs compile with .a linkage +#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR) + attachPinChangeInterrupt3(); +#endif + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT24 == true) + if (pcintNum == 24) + callbackPCINT24 = userFunc; +#endif +#if (PCINT_USE_PCINT25 == true) + if (pcintNum == 25) + callbackPCINT25 = userFunc; +#endif +#if (PCINT_USE_PCINT26 == true) + if (pcintNum == 26) + callbackPCINT26 = userFunc; +#endif +#if (PCINT_USE_PCINT27 == true) + if (pcintNum == 27) + callbackPCINT27 = userFunc; +#endif +#if (PCINT_USE_PCINT28 == true) + if (pcintNum == 28) + callbackPCINT28 = userFunc; +#endif +#if (PCINT_USE_PCINT29 == true) + if (pcintNum == 29) + callbackPCINT29 = userFunc; +#endif +#if (PCINT_USE_PCINT30 == true) + if (pcintNum == 30) + callbackPCINT30 = userFunc; +#endif +#if (PCINT_USE_PCINT31 == true) + if (pcintNum == 31) + callbackPCINT31 = userFunc; +#endif +#endif // PCINT_API + } + else return; + + // get bitmask and array position + uint8_t pcintMask = (1 << pcintBit); + uint8_t arrayPos = getArrayPosPCINT(pcintPort); + + // save settings related to mode and registers + if (mode == CHANGE || mode == RISING) + risingPorts[arrayPos] |= pcintMask; + if (mode == CHANGE || mode == FALLING) + fallingPorts[arrayPos] |= pcintMask; + + // call the actual hardware attach function + enablePinChangeInterruptHelper(pcintPort, pcintMask, arrayPos); +} + +// enable interrupt again if temporary disabled +static inline void enablePinChangeInterrupt(const uint8_t pcintNum) __attribute__((always_inline)); +void enablePinChangeInterrupt(const uint8_t pcintNum) { + // get PCINT registers + uint8_t pcintPort = pcintNum / 8; + uint8_t pcintBit = pcintNum % 8; + + // check if pcint is a valid pcint, exclude deactivated ports + if (pcintPort == 0) { + if (PCINT_USE_PORT0 == false) + return; + } + else if (pcintPort == 1) { + if (PCINT_USE_PORT1 == false) + return; + } + else if (pcintPort == 2) { + if (PCINT_USE_PORT2 == false) + return; + } + else if (pcintPort == 3) { + if (PCINT_USE_PORT3 == false) + return; + } + else return; + + // call the actual hardware attach function + uint8_t pcintMask = (1 << pcintBit); + uint8_t arrayPos = getArrayPosPCINT(pcintPort); + enablePinChangeInterruptHelper(pcintPort, pcintMask, arrayPos); +} + + +//================================================================================ +// Detach Function (partly inlined) +//================================================================================ + +void disablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask); +static inline void detachPinChangeInterrupt(const uint8_t pcintNum) __attribute__((always_inline)); + +void detachPinChangeInterrupt(const uint8_t pcintNum) { + // get PCINT registers + uint8_t pcintPort = pcintNum / 8; + uint8_t pcintBit = pcintNum % 8; + + // check if pcint is a valid pcint, exclude deactivated ports + // port 0 + if (pcintPort == 0 && PCINT_USE_PORT0 == true) { + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT0 == true) + if (pcintNum == 0) + callbackPCINT0 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT1 == true) + if (pcintNum == 1) + callbackPCINT1 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT2 == true) + if (pcintNum == 2) + callbackPCINT2 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT3 == true) + if (pcintNum == 3) + callbackPCINT3 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT4 == true) + if (pcintNum == 4) + callbackPCINT4 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT5 == true) + if (pcintNum == 5) + callbackPCINT5 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT6 == true) + if (pcintNum == 6) + callbackPCINT6 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT7 == true) + if (pcintNum == 7) + callbackPCINT7 = pcint_null_callback; +#endif +#endif // PCINT_API + } + + // port 1 + else if (pcintPort == 1 && PCINT_USE_PORT1 == true) { + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT8 == true) + if (pcintNum == 8) + callbackPCINT8 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT9 == true) + if (pcintNum == 9) + callbackPCINT9 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT10 == true) + if (pcintNum == 10) + callbackPCINT10 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT11 == true) + if (pcintNum == 11) + callbackPCINT11 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT12 == true) + if (pcintNum == 12) + callbackPCINT12 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT13 == true) + if (pcintNum == 13) + callbackPCINT13 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT14 == true) + if (pcintNum == 14) + callbackPCINT14 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT15 == true) + if (pcintNum == 15) + callbackPCINT15 = pcint_null_callback; +#endif +#endif // PCINT_API + } + + // port 2 + else if (pcintPort == 2 && PCINT_USE_PORT2 == true) { + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT16 == true) + if (pcintNum == 16) + callbackPCINT16 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT17 == true) + if (pcintNum == 17) + callbackPCINT17 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT18 == true) + if (pcintNum == 18) + callbackPCINT18 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT19 == true) + if (pcintNum == 19) + callbackPCINT19 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT20 == true) + if (pcintNum == 20) + callbackPCINT20 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT21 == true) + if (pcintNum == 21) + callbackPCINT21 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT22 == true) + if (pcintNum == 22) + callbackPCINT22 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT23 == true) + if (pcintNum == 23) + callbackPCINT23 = pcint_null_callback; +#endif +#endif // PCINT_API + } + + // port 3 + else if (pcintPort == 3 && PCINT_USE_PORT3 == true) { + // attache the function pointers for the API +#if defined(PCINT_API) +#if (PCINT_USE_PCINT24 == true) + if (pcintNum == 24) + callbackPCINT24 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT25 == true) + if (pcintNum == 25) + callbackPCINT25 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT26 == true) + if (pcintNum == 26) + callbackPCINT26 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT27 == true) + if (pcintNum == 27) + callbackPCINT27 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT28 == true) + if (pcintNum == 28) + callbackPCINT28 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT29 == true) + if (pcintNum == 29) + callbackPCINT29 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT30 == true) + if (pcintNum == 30) + callbackPCINT30 = pcint_null_callback; +#endif +#if (PCINT_USE_PCINT31 == true) + if (pcintNum == 31) + callbackPCINT31 = pcint_null_callback; +#endif +#endif // PCINT_API + } + else return; + + // get bitmask and array position + uint8_t pcintMask = (1 << pcintBit); + uint8_t arrayPos = getArrayPosPCINT(pcintPort); + + // delete setting + risingPorts[arrayPos] &= ~pcintMask; + fallingPorts[arrayPos] &= ~pcintMask; + + // call the actual hardware disable function + disablePinChangeInterruptHelper(pcintPort, pcintMask); +} + +static inline void disablePinChangeInterrupt(const uint8_t pcintNum) __attribute__((always_inline)); +void disablePinChangeInterrupt(const uint8_t pcintNum) { + // get PCINT registers + uint8_t pcintPort = pcintNum / 8; + uint8_t pcintBit = pcintNum % 8; + + // check if pcint is a valid pcint, exclude deactivated ports + if (pcintPort == 0) { + if (PCINT_USE_PORT0 == false) + return; + } + else if (pcintPort == 1) { + if (PCINT_USE_PORT1 == false) + return; + } + else if (pcintPort == 2) { + if (PCINT_USE_PORT2 == false) + return; + } + else if (pcintPort == 3) { + if (PCINT_USE_PORT3 == false) + return; + } + else return; + + // get bitmask + uint8_t pcintMask = (1 << pcintBit); + + // Do not delete mode settings nor detach the user function + // Just turn off interrupts + + // call the actual hardware disable function + disablePinChangeInterruptHelper(pcintPort, pcintMask); +} + +//================================================================================ +// getTrigger Function (inlined) +//================================================================================ + +static inline uint8_t getPinChangeInterruptTrigger(const uint8_t pcintNum) __attribute__((always_inline)); +uint8_t getPinChangeInterruptTrigger(const uint8_t pcintNum) { + // get PCINT registers + uint8_t pcintPort = pcintNum / 8; + uint8_t pcintBit = pcintNum % 8; + + // check if pcint is a valid pcint, exclude deactivated ports + if (pcintPort == 0) { + if (PCINT_USE_PORT0 == false) + return CHANGE; + } + else if (pcintPort == 1) { + if (PCINT_USE_PORT1 == false) + return CHANGE; + } + else if (pcintPort == 2) { + if (PCINT_USE_PORT2 == false) + return CHANGE; + } + else if (pcintPort == 3) { + if (PCINT_USE_PORT3 == false) + return CHANGE; + } + else return CHANGE; + + uint8_t arrayPos = getArrayPosPCINT(pcintPort); + + // Check if no mode was set, return an error + if(!(risingPorts[arrayPos] & (1 << pcintBit)) && !(fallingPorts[arrayPos] & (1 << pcintBit))) + return CHANGE; + + // specify the CHANGE mode + if (oldPorts[arrayPos] & (1 << pcintBit)) + return RISING; + else + return FALLING; +} diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp new file mode 100644 index 0000000..c8dfba8 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp @@ -0,0 +1,149 @@ +/* +Copyright (c) 2014-2015 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "PinChangeInterrupt.h" + +//================================================================================ +// Interrupt Handler +//================================================================================ + +// prevent compilation twice if included from the .cpp to force compile all ISRs +#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \ + || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR) + +#if (PCINT_USE_PORT0 == true) + +void attachPinChangeInterrupt0(void) { + // fake function to make the IDE link this file +} + +ISR(PCINT0_vect) { + // get the new and old pin states for port + uint8_t newPort = PCINT_INPUT_PORT0; + + // compare with the old value to detect a rising or falling + uint8_t arrayPos = getArrayPosPCINT(0); + uint8_t change = newPort ^ oldPorts[arrayPos]; + uint8_t rising = change & newPort; + uint8_t falling = change & oldPorts[arrayPos]; + + // check which pins are triggered, compared with the settings + uint8_t risingTrigger = rising & risingPorts[arrayPos]; + uint8_t fallingTrigger = falling & fallingPorts[arrayPos]; + uint8_t trigger = risingTrigger | fallingTrigger; + + // save the new state for next comparison + oldPorts[arrayPos] = newPort; + + // Execute all functions that should be triggered + // This way we can exclude a single function + // and the calling is also much faster + // We may also reorder the pins for different priority +#if !defined(PCINT_CALLBACK_PORT0) + PCINT_CALLBACK(0, 0); + PCINT_CALLBACK(1, 1); + PCINT_CALLBACK(2, 2); + PCINT_CALLBACK(3, 3); + PCINT_CALLBACK(4, 4); + PCINT_CALLBACK(5, 5); + PCINT_CALLBACK(6, 6); + PCINT_CALLBACK(7, 7); +#else + PCINT_CALLBACK_PORT0 +#endif +} + +#if defined(PCINT_API) + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" == true)"); +Serial.print("volatile callback callbackPCINT"); +Serial.print(i); +Serial.println(" = pcint_null_callback;"); +Serial.print("void PinChangeInterruptEventPCINT"); +Serial.print(i); +Serial.println("(void){"); +Serial.print(" callbackPCINT"); +Serial.print(i); +Serial.println("();"); +Serial.println("}"); +Serial.println("#endif"); +} +*/ +#if (PCINT_USE_PCINT0 == true) +volatile callback callbackPCINT0 = pcint_null_callback; +void PinChangeInterruptEventPCINT0(void) { + callbackPCINT0(); +} +#endif +#if (PCINT_USE_PCINT1 == true) +volatile callback callbackPCINT1 = pcint_null_callback; +void PinChangeInterruptEventPCINT1(void) { + callbackPCINT1(); +} +#endif +#if (PCINT_USE_PCINT2 == true) +volatile callback callbackPCINT2 = pcint_null_callback; +void PinChangeInterruptEventPCINT2(void) { + callbackPCINT2(); +} +#endif +#if (PCINT_USE_PCINT3 == true) +volatile callback callbackPCINT3 = pcint_null_callback; +void PinChangeInterruptEventPCINT3(void) { + callbackPCINT3(); +} +#endif +#if (PCINT_USE_PCINT4 == true) +volatile callback callbackPCINT4 = pcint_null_callback; +void PinChangeInterruptEventPCINT4(void) { + callbackPCINT4(); +} +#endif +#if (PCINT_USE_PCINT5 == true) +volatile callback callbackPCINT5 = pcint_null_callback; +void PinChangeInterruptEventPCINT5(void) { + callbackPCINT5(); +} +#endif +#if (PCINT_USE_PCINT6 == true) +volatile callback callbackPCINT6 = pcint_null_callback; +void PinChangeInterruptEventPCINT6(void) { + callbackPCINT6(); +} +#endif +#if (PCINT_USE_PCINT7 == true) +volatile callback callbackPCINT7 = pcint_null_callback; +void PinChangeInterruptEventPCINT7(void) { + callbackPCINT7(); +} +#endif + +#endif // PCINT_API + +#endif // PCINT_USE_PORT0 + +#endif // PCINT_INCLUDE_FROM_CPP diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp new file mode 100644 index 0000000..e9953cd --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp @@ -0,0 +1,149 @@ +/* +Copyright (c) 2014-2015 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "PinChangeInterrupt.h" + +//================================================================================ +// Interrupt Handler +//================================================================================ + +// prevent compilation twice if included from the .cpp to force compile all ISRs +#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \ + || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR) + +#if (PCINT_USE_PORT1 == true) + +void attachPinChangeInterrupt1(void) { + // fake function to make the IDE link this file +} + +ISR(PCINT1_vect) { + // get the new and old pin states for port + uint8_t newPort = PCINT_INPUT_PORT1; + + // compare with the old value to detect a rising or falling + uint8_t arrayPos = getArrayPosPCINT(1); + uint8_t change = newPort ^ oldPorts[arrayPos]; + uint8_t rising = change & newPort; + uint8_t falling = change & oldPorts[arrayPos]; + + // check which pins are triggered, compared with the settings + uint8_t risingTrigger = rising & risingPorts[arrayPos]; + uint8_t fallingTrigger = falling & fallingPorts[arrayPos]; + uint8_t trigger = risingTrigger | fallingTrigger; + + // save the new state for next comparison + oldPorts[arrayPos] = newPort; + + // Execute all functions that should be triggered + // This way we can exclude a single function + // and the calling is also much faster + // We may also reorder the pins for different priority +#if !defined(PCINT_CALLBACK_PORT1) + PCINT_CALLBACK(0, 8); + PCINT_CALLBACK(1, 9); + PCINT_CALLBACK(2, 10); + PCINT_CALLBACK(3, 11); + PCINT_CALLBACK(4, 12); + PCINT_CALLBACK(5, 13); + PCINT_CALLBACK(6, 14); + PCINT_CALLBACK(7, 15); +#else + PCINT_CALLBACK_PORT1 +#endif +} + +#if defined(PCINT_API) + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" == true)"); +Serial.print("volatile callback callbackPCINT"); +Serial.print(i); +Serial.println(" = pcint_null_callback;"); +Serial.print("void PinChangeInterruptEventPCINT"); +Serial.print(i); +Serial.println("(void){"); +Serial.print(" callbackPCINT"); +Serial.print(i); +Serial.println("();"); +Serial.println("}"); +Serial.println("#endif"); +} +*/ +#if (PCINT_USE_PCINT8 == true) +volatile callback callbackPCINT8 = pcint_null_callback; +void PinChangeInterruptEventPCINT8(void) { + callbackPCINT8(); +} +#endif +#if (PCINT_USE_PCINT9 == true) +volatile callback callbackPCINT9 = pcint_null_callback; +void PinChangeInterruptEventPCINT9(void) { + callbackPCINT9(); +} +#endif +#if (PCINT_USE_PCINT10 == true) +volatile callback callbackPCINT10 = pcint_null_callback; +void PinChangeInterruptEventPCINT10(void) { + callbackPCINT10(); +} +#endif +#if (PCINT_USE_PCINT11 == true) +volatile callback callbackPCINT11 = pcint_null_callback; +void PinChangeInterruptEventPCINT11(void) { + callbackPCINT11(); +} +#endif +#if (PCINT_USE_PCINT12 == true) +volatile callback callbackPCINT12 = pcint_null_callback; +void PinChangeInterruptEventPCINT12(void) { + callbackPCINT12(); +} +#endif +#if (PCINT_USE_PCINT13 == true) +volatile callback callbackPCINT13 = pcint_null_callback; +void PinChangeInterruptEventPCINT13(void) { + callbackPCINT13(); +} +#endif +#if (PCINT_USE_PCINT14 == true) +volatile callback callbackPCINT14 = pcint_null_callback; +void PinChangeInterruptEventPCINT14(void) { + callbackPCINT14(); +} +#endif +#if (PCINT_USE_PCINT15 == true) +volatile callback callbackPCINT15 = pcint_null_callback; +void PinChangeInterruptEventPCINT15(void) { + callbackPCINT15(); +} +#endif + +#endif // PCINT_API + +#endif // PCINT_USE_PORT1 + +#endif // PCINT_INCLUDE_FROM_CPP diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp new file mode 100644 index 0000000..a3bd72e --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp @@ -0,0 +1,149 @@ +/* +Copyright (c) 2014-2015 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "PinChangeInterrupt.h" + +//================================================================================ +// Interrupt Handler +//================================================================================ + +// prevent compilation twice if included from the .cpp to force compile all ISRs +#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \ + || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR) + +#if (PCINT_USE_PORT2 == true) + +void attachPinChangeInterrupt2(void) { + // fake function to make the IDE link this file +} + +ISR(PCINT2_vect) { + // get the new and old pin states for port + uint8_t newPort = PCINT_INPUT_PORT2; + + // compare with the old value to detect a rising or falling + uint8_t arrayPos = getArrayPosPCINT(2); + uint8_t change = newPort ^ oldPorts[arrayPos]; + uint8_t rising = change & newPort; + uint8_t falling = change & oldPorts[arrayPos]; + + // check which pins are triggered, compared with the settings + uint8_t risingTrigger = rising & risingPorts[arrayPos]; + uint8_t fallingTrigger = falling & fallingPorts[arrayPos]; + uint8_t trigger = risingTrigger | fallingTrigger; + + // save the new state for next comparison + oldPorts[arrayPos] = newPort; + + // Execute all functions that should be triggered + // This way we can exclude a single function + // and the calling is also much faster + // We may also reorder the pins for different priority +#if !defined(PCINT_CALLBACK_PORT2) + PCINT_CALLBACK(0, 16); + PCINT_CALLBACK(1, 17); + PCINT_CALLBACK(2, 18); + PCINT_CALLBACK(3, 19); + PCINT_CALLBACK(4, 20); + PCINT_CALLBACK(5, 21); + PCINT_CALLBACK(6, 22); + PCINT_CALLBACK(7, 23); +#else + PCINT_CALLBACK_PORT2 +#endif +} + +#if defined(PCINT_API) + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" == true)"); +Serial.print("volatile callback callbackPCINT"); +Serial.print(i); +Serial.println(" = pcint_null_callback;"); +Serial.print("void PinChangeInterruptEventPCINT"); +Serial.print(i); +Serial.println("(void){"); +Serial.print(" callbackPCINT"); +Serial.print(i); +Serial.println("();"); +Serial.println("}"); +Serial.println("#endif"); +} +*/ +#if (PCINT_USE_PCINT16 == true) +volatile callback callbackPCINT16 = pcint_null_callback; +void PinChangeInterruptEventPCINT16(void) { + callbackPCINT16(); +} +#endif +#if (PCINT_USE_PCINT17 == true) +volatile callback callbackPCINT17 = pcint_null_callback; +void PinChangeInterruptEventPCINT17(void) { + callbackPCINT17(); +} +#endif +#if (PCINT_USE_PCINT18 == true) +volatile callback callbackPCINT18 = pcint_null_callback; +void PinChangeInterruptEventPCINT18(void) { + callbackPCINT18(); +} +#endif +#if (PCINT_USE_PCINT19 == true) +volatile callback callbackPCINT19 = pcint_null_callback; +void PinChangeInterruptEventPCINT19(void) { + callbackPCINT19(); +} +#endif +#if (PCINT_USE_PCINT20 == true) +volatile callback callbackPCINT20 = pcint_null_callback; +void PinChangeInterruptEventPCINT20(void) { + callbackPCINT20(); +} +#endif +#if (PCINT_USE_PCINT21 == true) +volatile callback callbackPCINT21 = pcint_null_callback; +void PinChangeInterruptEventPCINT21(void) { + callbackPCINT21(); +} +#endif +#if (PCINT_USE_PCINT22 == true) +volatile callback callbackPCINT22 = pcint_null_callback; +void PinChangeInterruptEventPCINT22(void) { + callbackPCINT22(); +} +#endif +#if (PCINT_USE_PCINT23 == true) +volatile callback callbackPCINT23 = pcint_null_callback; +void PinChangeInterruptEventPCINT23(void) { + callbackPCINT23(); +} +#endif + +#endif // PCINT_API + +#endif // PCINT_USE_PORT2 + +#endif // PCINT_INCLUDE_FROM_CPP \ No newline at end of file diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp new file mode 100644 index 0000000..71d2ea6 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp @@ -0,0 +1,149 @@ +/* +Copyright (c) 2014-2015 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "PinChangeInterrupt.h" + +//================================================================================ +// Interrupt Handler +//================================================================================ + +// prevent compilation twice if included from the .cpp to force compile all ISRs +#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \ + || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR) + +#if (PCINT_USE_PORT3 == true) + +void attachPinChangeInterrupt3(void) { + // fake function to make the IDE link this file +} + +ISR(PCINT3_vect) { + // get the new and old pin states for port + uint8_t newPort = PCINT_INPUT_PORT3; + + // compare with the old value to detect a rising or falling + uint8_t arrayPos = getArrayPosPCINT(3); + uint8_t change = newPort ^ oldPorts[arrayPos]; + uint8_t rising = change & newPort; + uint8_t falling = change & oldPorts[arrayPos]; + + // check which pins are triggered, compared with the settings + uint8_t risingTrigger = rising & risingPorts[arrayPos]; + uint8_t fallingTrigger = falling & fallingPorts[arrayPos]; + uint8_t trigger = risingTrigger | fallingTrigger; + + // save the new state for next comparison + oldPorts[arrayPos] = newPort; + + // Execute all functions that should be triggered + // This way we can exclude a single function + // and the calling is also much faster + // We may also reorder the pins for different priority +#if !defined(PCINT_CALLBACK_PORT3) + PCINT_CALLBACK(0, 24); + PCINT_CALLBACK(1, 25); + PCINT_CALLBACK(2, 26); + PCINT_CALLBACK(3, 27); + PCINT_CALLBACK(4, 28); + PCINT_CALLBACK(5, 29); + PCINT_CALLBACK(6, 30); + PCINT_CALLBACK(7, 31); +#else + PCINT_CALLBACK_PORT3 +#endif +} + +#if defined(PCINT_API) + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" == true)"); +Serial.print("volatile callback callbackPCINT"); +Serial.print(i); +Serial.println(" = pcint_null_callback;"); +Serial.print("void PinChangeInterruptEventPCINT"); +Serial.print(i); +Serial.println("(void){"); +Serial.print(" callbackPCINT"); +Serial.print(i); +Serial.println("();"); +Serial.println("}"); +Serial.println("#endif"); +} +*/ +#if (PCINT_USE_PCINT24 == true) +volatile callback callbackPCINT24 = pcint_null_callback; +void PinChangeInterruptEventPCINT24(void) { + callbackPCINT24(); +} +#endif +#if (PCINT_USE_PCINT25 == true) +volatile callback callbackPCINT25 = pcint_null_callback; +void PinChangeInterruptEventPCINT25(void) { + callbackPCINT25(); +} +#endif +#if (PCINT_USE_PCINT26 == true) +volatile callback callbackPCINT26 = pcint_null_callback; +void PinChangeInterruptEventPCINT26(void) { + callbackPCINT26(); +} +#endif +#if (PCINT_USE_PCINT27 == true) +volatile callback callbackPCINT27 = pcint_null_callback; +void PinChangeInterruptEventPCINT27(void) { + callbackPCINT27(); +} +#endif +#if (PCINT_USE_PCINT28 == true) +volatile callback callbackPCINT28 = pcint_null_callback; +void PinChangeInterruptEventPCINT28(void) { + callbackPCINT28(); +} +#endif +#if (PCINT_USE_PCINT29 == true) +volatile callback callbackPCINT29 = pcint_null_callback; +void PinChangeInterruptEventPCINT29(void) { + callbackPCINT29(); +} +#endif +#if (PCINT_USE_PCINT30 == true) +volatile callback callbackPCINT30 = pcint_null_callback; +void PinChangeInterruptEventPCINT30(void) { + callbackPCINT30(); +} +#endif +#if (PCINT_USE_PCINT31 == true) +volatile callback callbackPCINT31 = pcint_null_callback; +void PinChangeInterruptEventPCINT31(void) { + callbackPCINT31(); +} +#endif + +#endif // PCINT_API + +#endif // PCINT_USE_PORT3 + +#endif // PCINT_INCLUDE_FROM_CPP \ No newline at end of file diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h new file mode 100644 index 0000000..fdcfa65 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h @@ -0,0 +1,174 @@ +/* +Copyright (c) 2014-2021 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// include guard +#pragma once + +//================================================================================ +// Board Definitions +//================================================================================ + +// Microcontroller specific definitions +// Avr Variants are defined here: https://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/include/avr/io.h?view=markup + +#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328A__) || defined(__AVR_ATmega328PA__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) \ + || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PB__) \ + || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \ + || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__) +// Arduino Uno +#define PCINT_INPUT_PORT0 PINB +#define PCINT_INPUT_PORT1 PINC +#define PCINT_INPUT_PORT2 PIND + +#if defined(__AVR_ATmega328PB__) +#define PCINT_INPUT_PORT3 PINE +#endif + +#elif defined(__AVR_ATmega162__) + +#define PCINT_INPUT_PORT0 PINA +#define PCINT_INPUT_PORT1 PINC + +#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega640__) +// Arduino Mega/Mega2560 +#define PCINT_INPUT_PORT0 PINB +#define PCINT_INPUT_PORT2 PINK + +// special Port1 case, pins are on 2 HW Pin Ports (E,J) +#if defined(PCINT_ENABLE_PCINT16) // PortE +#if defined(PCINT_ENABLE_PCINT17) || defined(PCINT_ENABLE_PCINT18) \ + || defined(PCINT_ENABLE_PCINT19) || defined(PCINT_ENABLE_PCINT20) \ +|| defined(PCINT_ENABLE_PCINT21) || defined(PCINT_ENABLE_PCINT22) \ +|| defined(PCINT_ENABLE_PCINT23) // PortJ +// PortE and PortJ selected +#define PCINT_INPUT_PORT1 ((PINE & 0x01) | (PINJ << 1)) +#else +// PortE only selected +#define PCINT_INPUT_PORT1 PINE +#endif +#else +// PortJ only selected +// we still have to do the shift because the attach +// function is not designed for this optimization +#define PCINT_INPUT_PORT1 (PINJ << 1) +#endif + +#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) +// Arduino Leonardo/Micro +#define PCINT_INPUT_PORT0 PINB + +#elif defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) +// u2 Series/HoodLoader2 +// u2 Series has crappy pin mappings for port 1 +#define PCINT_INPUT_PORT0 PINB +#define PCINT_INPUT_PORT1 (((PINC >> 6) & (1 << 0)) | ((PINC >> 4) & (1 << 1)) | ((PINC >> 2) & (1 << 2)) | ((PINC << 1) & (1 << 3)) | ((PIND >> 1) & (1 << 4))) + +#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) +// Attiny x5 +#define PCINT_INPUT_PORT0 PINB + +#elif defined(__AVR_ATtiny13__) +// Attiny 13A +#define PCINT_INPUT_PORT0 PINB +// This is just a workaround for the missing definition in the following core: https://sourceforge.net/projects/ard-core13/ +// It should work fine with: https://github.com/MCUdude/MicroCore +#ifndef portInputRegister +#define portInputRegister(P) ( (volatile uint8_t *)(PINB) ) +#endif + +#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) +// Attiny x4 +#define PCINT_INPUT_PORT0 PINA +#define PCINT_INPUT_PORT1 PINB + +#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +// 1284p and 644p, special 4 port case +#define PCINT_INPUT_PORT0 PINA +#define PCINT_INPUT_PORT1 PINB +#define PCINT_INPUT_PORT2 PINC +#define PCINT_INPUT_PORT3 PIND + +#elif defined(__AVR_ATtinyX41__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__) +// Attiny x41 +#define PCINT_INPUT_PORT0 PINA +#define PCINT_INPUT_PORT1 PINB + +// "iotn841.h" is missing those definitions, so we add them here +#define PCINT0 0 +#define PCINT1 1 +#define PCINT2 2 +#define PCINT3 3 +#define PCINT4 4 +#define PCINT5 5 +#define PCINT6 6 +#define PCINT7 7 + +#define PCINT8 0 +#define PCINT9 1 +#define PCINT10 2 +#define PCINT11 3 + +#elif defined(__AVR_ATtiny2313__) +#define PCINT_INPUT_PORT0 PINB + +#elif defined(__AVR_ATtiny2313A__) || defined(__AVR_ATtiny4313__) +// All 8 pins +#define PCINT_INPUT_PORT0 PINB +// PinA has 3 PCINTs on the reset and clock lines, we do not use this port +// PIND has 7 pins available, but the pin ordering is so messed up, +// that it does not work with the current library structure. + +#elif defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__) +// PORTB has Reset, clock and SPI while PORTA has I2C and Analog Pins. We just enable all pins. +#define PCINT_INPUT_PORT0 PINA +#define PCINT_INPUT_PORT1 PINB + +#else // Microcontroller not supported +#error PinChangeInterrupt library does not support this MCU. +#endif + +//================================================================================ +// Add missing definitions +//================================================================================ + +// add fakes if ports are not used +#ifndef PCINT_INPUT_PORT0 +#define PCINT_INPUT_PORT0 0 +#else +#define PCINT_INPUT_PORT0_USED +#endif +#ifndef PCINT_INPUT_PORT1 +#define PCINT_INPUT_PORT1 0 +#else +#define PCINT_INPUT_PORT1_USED +#endif +#ifndef PCINT_INPUT_PORT2 +#define PCINT_INPUT_PORT2 0 +#else +#define PCINT_INPUT_PORT2_USED +#endif +#ifndef PCINT_INPUT_PORT3 +#define PCINT_INPUT_PORT3 0 +#else +#define PCINT_INPUT_PORT3_USED +#endif diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h new file mode 100644 index 0000000..832b6bd --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h @@ -0,0 +1,926 @@ +/* +Copyright (c) 2014-2017 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// include guard +#pragma once + +/* +The strategy in this file: + +0. Makefile optimization: + To disable PCINT/PORTs via makefile use -DPCINT_DISABLE_PORT0 etc. + This will undef a previously defined PCINT_ENABLE_PORT0. + +1. Reduce the user settings to the enabled pins. + If the whole port is deactivated, also disable all pins on this port. + +2. Define the hardware available pins/ports. + +3. Compare the hardware definition with the enabled pin definitions. + If the pin is available and enabled, create a makro to use the pin. + +4. Count all used pins (for each port). + +5. If there are no pins used on a port, do not use the port + +6. Finally we have a clear defintion of the used pins/ports like this: +PCINT_USE_PCINT0 (true/false) +PCINT_USE_PORT0 (true/false) + +Other definitions that can be used: +PCINT_HAS_PORT0 (true/false) +PCINT_HAS_PCINT0 (true/false) +PCINT_NUM_PINS_PORT0 (0-8) +PCINT_NUM_USED_PINS_PORT0 (0-8) +EXTERNAL_NUM_PINCHANGEINTERRUPT (0-24) +EXTERNAL_NUM_USED_PINCHANGEINTERRUPT (0-24) +PCINT_NUM_PORTS (0-3) +PCINT_NUM_USED_PORTS (0-3) +*/ + +//================================================================================ +// Disabled Pins +//================================================================================ +/* +for (int port = 0; port < 4; port++) { + Serial.print("#if defined(PCINT_ENABLE_PORT"); + Serial.print(port); + Serial.print(") && defined(PCINT_DISABLE_PORT"); + Serial.print(port); + Serial.println(")"); + Serial.print("#undef PCINT_ENABLE_PORT"); + Serial.println(port); + Serial.println("#endif"); + Serial.println(); +} + +for (int i = 0; i < 32; i++) { + Serial.print("#if defined(PCINT_ENABLE_PCINT"); + Serial.print(i); + Serial.print(") && defined(PCINT_DISABLE_PCINT"); + Serial.print(i); + Serial.println(")"); + Serial.print("#undef PCINT_ENABLE_PCINT"); + Serial.println(i); + Serial.println("#endif"); + Serial.println(); +} +*/ +#if defined(PCINT_ENABLE_PORT0) && defined(PCINT_DISABLE_PORT0) +#undef PCINT_ENABLE_PORT0 +#endif + +#if defined(PCINT_ENABLE_PORT1) && defined(PCINT_DISABLE_PORT1) +#undef PCINT_ENABLE_PORT1 +#endif + +#if defined(PCINT_ENABLE_PORT2) && defined(PCINT_DISABLE_PORT2) +#undef PCINT_ENABLE_PORT2 +#endif + +#if defined(PCINT_ENABLE_PORT3) && defined(PCINT_DISABLE_PORT3) +#undef PCINT_ENABLE_PORT3 +#endif + +#if defined(PCINT_ENABLE_PCINT0) && defined(PCINT_DISABLE_PCINT0) +#undef PCINT_ENABLE_PCINT0 +#endif + +#if defined(PCINT_ENABLE_PCINT1) && defined(PCINT_DISABLE_PCINT1) +#undef PCINT_ENABLE_PCINT1 +#endif + +#if defined(PCINT_ENABLE_PCINT2) && defined(PCINT_DISABLE_PCINT2) +#undef PCINT_ENABLE_PCINT2 +#endif + +#if defined(PCINT_ENABLE_PCINT3) && defined(PCINT_DISABLE_PCINT3) +#undef PCINT_ENABLE_PCINT3 +#endif + +#if defined(PCINT_ENABLE_PCINT4) && defined(PCINT_DISABLE_PCINT4) +#undef PCINT_ENABLE_PCINT4 +#endif + +#if defined(PCINT_ENABLE_PCINT5) && defined(PCINT_DISABLE_PCINT5) +#undef PCINT_ENABLE_PCINT5 +#endif + +#if defined(PCINT_ENABLE_PCINT6) && defined(PCINT_DISABLE_PCINT6) +#undef PCINT_ENABLE_PCINT6 +#endif + +#if defined(PCINT_ENABLE_PCINT7) && defined(PCINT_DISABLE_PCINT7) +#undef PCINT_ENABLE_PCINT7 +#endif + +#if defined(PCINT_ENABLE_PCINT8) && defined(PCINT_DISABLE_PCINT8) +#undef PCINT_ENABLE_PCINT8 +#endif + +#if defined(PCINT_ENABLE_PCINT9) && defined(PCINT_DISABLE_PCINT9) +#undef PCINT_ENABLE_PCINT9 +#endif + +#if defined(PCINT_ENABLE_PCINT10) && defined(PCINT_DISABLE_PCINT10) +#undef PCINT_ENABLE_PCINT10 +#endif + +#if defined(PCINT_ENABLE_PCINT11) && defined(PCINT_DISABLE_PCINT11) +#undef PCINT_ENABLE_PCINT11 +#endif + +#if defined(PCINT_ENABLE_PCINT12) && defined(PCINT_DISABLE_PCINT12) +#undef PCINT_ENABLE_PCINT12 +#endif + +#if defined(PCINT_ENABLE_PCINT13) && defined(PCINT_DISABLE_PCINT13) +#undef PCINT_ENABLE_PCINT13 +#endif + +#if defined(PCINT_ENABLE_PCINT14) && defined(PCINT_DISABLE_PCINT14) +#undef PCINT_ENABLE_PCINT14 +#endif + +#if defined(PCINT_ENABLE_PCINT15) && defined(PCINT_DISABLE_PCINT15) +#undef PCINT_ENABLE_PCINT15 +#endif + +#if defined(PCINT_ENABLE_PCINT16) && defined(PCINT_DISABLE_PCINT16) +#undef PCINT_ENABLE_PCINT16 +#endif + +#if defined(PCINT_ENABLE_PCINT17) && defined(PCINT_DISABLE_PCINT17) +#undef PCINT_ENABLE_PCINT17 +#endif + +#if defined(PCINT_ENABLE_PCINT18) && defined(PCINT_DISABLE_PCINT18) +#undef PCINT_ENABLE_PCINT18 +#endif + +#if defined(PCINT_ENABLE_PCINT19) && defined(PCINT_DISABLE_PCINT19) +#undef PCINT_ENABLE_PCINT19 +#endif + +#if defined(PCINT_ENABLE_PCINT20) && defined(PCINT_DISABLE_PCINT20) +#undef PCINT_ENABLE_PCINT20 +#endif + +#if defined(PCINT_ENABLE_PCINT21) && defined(PCINT_DISABLE_PCINT21) +#undef PCINT_ENABLE_PCINT21 +#endif + +#if defined(PCINT_ENABLE_PCINT22) && defined(PCINT_DISABLE_PCINT22) +#undef PCINT_ENABLE_PCINT22 +#endif + +#if defined(PCINT_ENABLE_PCINT23) && defined(PCINT_DISABLE_PCINT23) +#undef PCINT_ENABLE_PCINT23 +#endif + +#if defined(PCINT_ENABLE_PCINT24) && defined(PCINT_DISABLE_PCINT24) +#undef PCINT_ENABLE_PCINT24 +#endif + +#if defined(PCINT_ENABLE_PCINT25) && defined(PCINT_DISABLE_PCINT25) +#undef PCINT_ENABLE_PCINT25 +#endif + +#if defined(PCINT_ENABLE_PCINT26) && defined(PCINT_DISABLE_PCINT26) +#undef PCINT_ENABLE_PCINT26 +#endif + +#if defined(PCINT_ENABLE_PCINT27) && defined(PCINT_DISABLE_PCINT27) +#undef PCINT_ENABLE_PCINT27 +#endif + +#if defined(PCINT_ENABLE_PCINT28) && defined(PCINT_DISABLE_PCINT28) +#undef PCINT_ENABLE_PCINT28 +#endif + +#if defined(PCINT_ENABLE_PCINT29) && defined(PCINT_DISABLE_PCINT29) +#undef PCINT_ENABLE_PCINT29 +#endif + +#if defined(PCINT_ENABLE_PCINT30) && defined(PCINT_DISABLE_PCINT30) +#undef PCINT_ENABLE_PCINT30 +#endif + +#if defined(PCINT_ENABLE_PCINT31) && defined(PCINT_DISABLE_PCINT31) +#undef PCINT_ENABLE_PCINT31 +#endif + + +//================================================================================ +// Enabled Pins +//================================================================================ + +/* Disable all pins on a port, if port is deactivated +We could then check every pin -> port definition +But that'd be a mess and doesnt help +Users who deactivate stuff should know +what the are doing. +So we use the enabled pins for all next definitions*/ +/* +for (int port = 0; port < 4; port++) { +Serial.print("#if !defined(PCINT_ENABLE_PORT"); +Serial.print(port); +Serial.println(")"); +for (int i = 0; i < 8; i++) { +Serial.print("#if defined(PCINT_ENABLE_PCINT"); +Serial.print(port * 8 + i); +Serial.println(")"); +Serial.print("#undef PCINT_ENABLE_PCINT"); +Serial.println(port * 8 + i); +Serial.println("#endif"); +} +Serial.println("#endif"); +Serial.println(); +} +*/ +#if !defined(PCINT_ENABLE_PORT0) +#if defined(PCINT_ENABLE_PCINT0) +#undef PCINT_ENABLE_PCINT0 +#endif +#if defined(PCINT_ENABLE_PCINT1) +#undef PCINT_ENABLE_PCINT1 +#endif +#if defined(PCINT_ENABLE_PCINT2) +#undef PCINT_ENABLE_PCINT2 +#endif +#if defined(PCINT_ENABLE_PCINT3) +#undef PCINT_ENABLE_PCINT3 +#endif +#if defined(PCINT_ENABLE_PCINT4) +#undef PCINT_ENABLE_PCINT4 +#endif +#if defined(PCINT_ENABLE_PCINT5) +#undef PCINT_ENABLE_PCINT5 +#endif +#if defined(PCINT_ENABLE_PCINT6) +#undef PCINT_ENABLE_PCINT6 +#endif +#if defined(PCINT_ENABLE_PCINT7) +#undef PCINT_ENABLE_PCINT7 +#endif +#endif + +#if !defined(PCINT_ENABLE_PORT1) +#if defined(PCINT_ENABLE_PCINT8) +#undef PCINT_ENABLE_PCINT8 +#endif +#if defined(PCINT_ENABLE_PCINT9) +#undef PCINT_ENABLE_PCINT9 +#endif +#if defined(PCINT_ENABLE_PCINT10) +#undef PCINT_ENABLE_PCINT10 +#endif +#if defined(PCINT_ENABLE_PCINT11) +#undef PCINT_ENABLE_PCINT11 +#endif +#if defined(PCINT_ENABLE_PCINT12) +#undef PCINT_ENABLE_PCINT12 +#endif +#if defined(PCINT_ENABLE_PCINT13) +#undef PCINT_ENABLE_PCINT13 +#endif +#if defined(PCINT_ENABLE_PCINT14) +#undef PCINT_ENABLE_PCINT14 +#endif +#if defined(PCINT_ENABLE_PCINT15) +#undef PCINT_ENABLE_PCINT15 +#endif +#endif + +#if !defined(PCINT_ENABLE_PORT2) +#if defined(PCINT_ENABLE_PCINT16) +#undef PCINT_ENABLE_PCINT16 +#endif +#if defined(PCINT_ENABLE_PCINT17) +#undef PCINT_ENABLE_PCINT17 +#endif +#if defined(PCINT_ENABLE_PCINT18) +#undef PCINT_ENABLE_PCINT18 +#endif +#if defined(PCINT_ENABLE_PCINT19) +#undef PCINT_ENABLE_PCINT19 +#endif +#if defined(PCINT_ENABLE_PCINT20) +#undef PCINT_ENABLE_PCINT20 +#endif +#if defined(PCINT_ENABLE_PCINT21) +#undef PCINT_ENABLE_PCINT21 +#endif +#if defined(PCINT_ENABLE_PCINT22) +#undef PCINT_ENABLE_PCINT22 +#endif +#if defined(PCINT_ENABLE_PCINT23) +#undef PCINT_ENABLE_PCINT23 +#endif +#endif + +#if !defined(PCINT_ENABLE_PORT3) +#if defined(PCINT_ENABLE_PCINT24) +#undef PCINT_ENABLE_PCINT24 +#endif +#if defined(PCINT_ENABLE_PCINT25) +#undef PCINT_ENABLE_PCINT25 +#endif +#if defined(PCINT_ENABLE_PCINT26) +#undef PCINT_ENABLE_PCINT26 +#endif +#if defined(PCINT_ENABLE_PCINT27) +#undef PCINT_ENABLE_PCINT27 +#endif +#if defined(PCINT_ENABLE_PCINT28) +#undef PCINT_ENABLE_PCINT28 +#endif +#if defined(PCINT_ENABLE_PCINT29) +#undef PCINT_ENABLE_PCINT29 +#endif +#if defined(PCINT_ENABLE_PCINT30) +#undef PCINT_ENABLE_PCINT30 +#endif +#if defined(PCINT_ENABLE_PCINT31) +#undef PCINT_ENABLE_PCINT31 +#endif +#endif + + +//================================================================================ +// Hardware Definitions +//================================================================================ + +#if defined(PCINT0_vect) +#define PCINT_HAS_PORT0 true +#else +#define PCINT_HAS_PORT0 false +#endif +#if defined(PCINT1_vect) +#define PCINT_HAS_PORT1 true +#else +#define PCINT_HAS_PORT1 false +#endif +#if defined(PCINT2_vect) +#define PCINT_HAS_PORT2 true +#else +#define PCINT_HAS_PORT2 false +#endif +#if defined(PCINT3_vect) +#define PCINT_HAS_PORT3 true +#else +#define PCINT_HAS_PORT3 false +#endif + +// number of available ports +#define PCINT_NUM_PORTS ( \ +PCINT_HAS_PORT0 + \ +PCINT_HAS_PORT1 + \ +PCINT_HAS_PORT2 + \ +PCINT_HAS_PORT3) + +/* +for (int i = 0; i < 32; i++) { +Serial.print("#ifdef PCINT"); +Serial.println(i); +Serial.print("#define PCINT_HAS_PCINT"); +Serial.print(i); +Serial.println(" true"); +Serial.println("#else"); +Serial.print("#define PCINT_HAS_PCINT"); +Serial.print(i); +Serial.println(" false"); +Serial.println("#endif"); +} +*/ +#ifdef PCINT0 +#define PCINT_HAS_PCINT0 true +#else +#define PCINT_HAS_PCINT0 false +#endif +#ifdef PCINT1 +#define PCINT_HAS_PCINT1 true +#else +#define PCINT_HAS_PCINT1 false +#endif +#ifdef PCINT2 +#define PCINT_HAS_PCINT2 true +#else +#define PCINT_HAS_PCINT2 false +#endif +#ifdef PCINT3 +#define PCINT_HAS_PCINT3 true +#else +#define PCINT_HAS_PCINT3 false +#endif +#ifdef PCINT4 +#define PCINT_HAS_PCINT4 true +#else +#define PCINT_HAS_PCINT4 false +#endif +#ifdef PCINT5 +#define PCINT_HAS_PCINT5 true +#else +#define PCINT_HAS_PCINT5 false +#endif +#ifdef PCINT6 +#define PCINT_HAS_PCINT6 true +#else +#define PCINT_HAS_PCINT6 false +#endif +#ifdef PCINT7 +#define PCINT_HAS_PCINT7 true +#else +#define PCINT_HAS_PCINT7 false +#endif +#ifdef PCINT8 +#define PCINT_HAS_PCINT8 true +#else +#define PCINT_HAS_PCINT8 false +#endif +#ifdef PCINT9 +#define PCINT_HAS_PCINT9 true +#else +#define PCINT_HAS_PCINT9 false +#endif +#ifdef PCINT10 +#define PCINT_HAS_PCINT10 true +#else +#define PCINT_HAS_PCINT10 false +#endif +#ifdef PCINT11 +#define PCINT_HAS_PCINT11 true +#else +#define PCINT_HAS_PCINT11 false +#endif +#ifdef PCINT12 +#define PCINT_HAS_PCINT12 true +#else +#define PCINT_HAS_PCINT12 false +#endif +#ifdef PCINT13 +#define PCINT_HAS_PCINT13 true +#else +#define PCINT_HAS_PCINT13 false +#endif +#ifdef PCINT14 +#define PCINT_HAS_PCINT14 true +#else +#define PCINT_HAS_PCINT14 false +#endif +#ifdef PCINT15 +#define PCINT_HAS_PCINT15 true +#else +#define PCINT_HAS_PCINT15 false +#endif +#ifdef PCINT16 +#define PCINT_HAS_PCINT16 true +#else +#define PCINT_HAS_PCINT16 false +#endif +#ifdef PCINT17 +#define PCINT_HAS_PCINT17 true +#else +#define PCINT_HAS_PCINT17 false +#endif +#ifdef PCINT18 +#define PCINT_HAS_PCINT18 true +#else +#define PCINT_HAS_PCINT18 false +#endif +#ifdef PCINT19 +#define PCINT_HAS_PCINT19 true +#else +#define PCINT_HAS_PCINT19 false +#endif +#ifdef PCINT20 +#define PCINT_HAS_PCINT20 true +#else +#define PCINT_HAS_PCINT20 false +#endif +#ifdef PCINT21 +#define PCINT_HAS_PCINT21 true +#else +#define PCINT_HAS_PCINT21 false +#endif +#ifdef PCINT22 +#define PCINT_HAS_PCINT22 true +#else +#define PCINT_HAS_PCINT22 false +#endif +#ifdef PCINT23 +#define PCINT_HAS_PCINT23 true +#else +#define PCINT_HAS_PCINT23 false +#endif +#ifdef PCINT24 +#define PCINT_HAS_PCINT24 true +#else +#define PCINT_HAS_PCINT24 false +#endif +#ifdef PCINT25 +#define PCINT_HAS_PCINT25 true +#else +#define PCINT_HAS_PCINT25 false +#endif +#ifdef PCINT26 +#define PCINT_HAS_PCINT26 true +#else +#define PCINT_HAS_PCINT26 false +#endif +#ifdef PCINT27 +#define PCINT_HAS_PCINT27 true +#else +#define PCINT_HAS_PCINT27 false +#endif +#ifdef PCINT28 +#define PCINT_HAS_PCINT28 true +#else +#define PCINT_HAS_PCINT28 false +#endif +#ifdef PCINT29 +#define PCINT_HAS_PCINT29 true +#else +#define PCINT_HAS_PCINT29 false +#endif +#ifdef PCINT30 +#define PCINT_HAS_PCINT30 true +#else +#define PCINT_HAS_PCINT30 false +#endif +#ifdef PCINT31 +#define PCINT_HAS_PCINT31 true +#else +#define PCINT_HAS_PCINT31 false +#endif + + +// count numbers of available pins on each port +/* +for (int port = 0; port < 4; port++) { +Serial.print("#define PCINT_NUM_PINS_PORT"); +Serial.print(port); +Serial.println(" ( \\"); +for (int i = 0; i < 8; i++) { +Serial.print("PCINT_HAS_PCINT"); +Serial.print(port * 8 + i); +if (i != 7) +Serial.println(" + \\"); +} +Serial.println(")"); +Serial.println(); +} +*/ +#define PCINT_NUM_PINS_PORT0 ( \ +PCINT_HAS_PCINT0 + \ +PCINT_HAS_PCINT1 + \ +PCINT_HAS_PCINT2 + \ +PCINT_HAS_PCINT3 + \ +PCINT_HAS_PCINT4 + \ +PCINT_HAS_PCINT5 + \ +PCINT_HAS_PCINT6 + \ +PCINT_HAS_PCINT7) + +#define PCINT_NUM_PINS_PORT1 ( \ +PCINT_HAS_PCINT8 + \ +PCINT_HAS_PCINT9 + \ +PCINT_HAS_PCINT10 + \ +PCINT_HAS_PCINT11 + \ +PCINT_HAS_PCINT12 + \ +PCINT_HAS_PCINT13 + \ +PCINT_HAS_PCINT14 + \ +PCINT_HAS_PCINT15) + +#define PCINT_NUM_PINS_PORT2 ( \ +PCINT_HAS_PCINT16 + \ +PCINT_HAS_PCINT17 + \ +PCINT_HAS_PCINT18 + \ +PCINT_HAS_PCINT19 + \ +PCINT_HAS_PCINT20 + \ +PCINT_HAS_PCINT21 + \ +PCINT_HAS_PCINT22 + \ +PCINT_HAS_PCINT23) + +#define PCINT_NUM_PINS_PORT3 ( \ +PCINT_HAS_PCINT24 + \ +PCINT_HAS_PCINT25 + \ +PCINT_HAS_PCINT26 + \ +PCINT_HAS_PCINT27 + \ +PCINT_HAS_PCINT28 + \ +PCINT_HAS_PCINT29 + \ +PCINT_HAS_PCINT30 + \ +PCINT_HAS_PCINT31) + + +// number of available hardware pins +#define EXTERNAL_NUM_PINCHANGEINTERRUPT ( \ +PCINT_NUM_PINS_PORT0 + \ +PCINT_NUM_PINS_PORT1 + \ +PCINT_NUM_PINS_PORT2 + \ +PCINT_NUM_PINS_PORT3) + + +//================================================================================ +// Used Pins +//================================================================================ + +// check if pins are physically available and enabled +/* +for (int i = 0; i < 32; i++) { +Serial.print("#if (PCINT_HAS_PCINT"); +Serial.print(i); +Serial.print(" == true) && defined(PCINT_ENABLE_PCINT"); +Serial.print(i); +Serial.println(")"); +Serial.print("#define PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" true"); +Serial.println("#else"); +Serial.print("#define PCINT_USE_PCINT"); +Serial.print(i); +Serial.println(" false"); +Serial.println("#endif"); +} +*/ +#if (PCINT_HAS_PCINT0 == true) && defined(PCINT_ENABLE_PCINT0) +#define PCINT_USE_PCINT0 true +#else +#define PCINT_USE_PCINT0 false +#endif +#if (PCINT_HAS_PCINT1 == true) && defined(PCINT_ENABLE_PCINT1) +#define PCINT_USE_PCINT1 true +#else +#define PCINT_USE_PCINT1 false +#endif +#if (PCINT_HAS_PCINT2 == true) && defined(PCINT_ENABLE_PCINT2) +#define PCINT_USE_PCINT2 true +#else +#define PCINT_USE_PCINT2 false +#endif +#if (PCINT_HAS_PCINT3 == true) && defined(PCINT_ENABLE_PCINT3) +#define PCINT_USE_PCINT3 true +#else +#define PCINT_USE_PCINT3 false +#endif +#if (PCINT_HAS_PCINT4 == true) && defined(PCINT_ENABLE_PCINT4) +#define PCINT_USE_PCINT4 true +#else +#define PCINT_USE_PCINT4 false +#endif +#if (PCINT_HAS_PCINT5 == true) && defined(PCINT_ENABLE_PCINT5) +#define PCINT_USE_PCINT5 true +#else +#define PCINT_USE_PCINT5 false +#endif +#if (PCINT_HAS_PCINT6 == true) && defined(PCINT_ENABLE_PCINT6) +#define PCINT_USE_PCINT6 true +#else +#define PCINT_USE_PCINT6 false +#endif +#if (PCINT_HAS_PCINT7 == true) && defined(PCINT_ENABLE_PCINT7) +#define PCINT_USE_PCINT7 true +#else +#define PCINT_USE_PCINT7 false +#endif +#if (PCINT_HAS_PCINT8 == true) && defined(PCINT_ENABLE_PCINT8) +#define PCINT_USE_PCINT8 true +#else +#define PCINT_USE_PCINT8 false +#endif +#if (PCINT_HAS_PCINT9 == true) && defined(PCINT_ENABLE_PCINT9) +#define PCINT_USE_PCINT9 true +#else +#define PCINT_USE_PCINT9 false +#endif +#if (PCINT_HAS_PCINT10 == true) && defined(PCINT_ENABLE_PCINT10) +#define PCINT_USE_PCINT10 true +#else +#define PCINT_USE_PCINT10 false +#endif +#if (PCINT_HAS_PCINT11 == true) && defined(PCINT_ENABLE_PCINT11) +#define PCINT_USE_PCINT11 true +#else +#define PCINT_USE_PCINT11 false +#endif +#if (PCINT_HAS_PCINT12 == true) && defined(PCINT_ENABLE_PCINT12) +#define PCINT_USE_PCINT12 true +#else +#define PCINT_USE_PCINT12 false +#endif +#if (PCINT_HAS_PCINT13 == true) && defined(PCINT_ENABLE_PCINT13) +#define PCINT_USE_PCINT13 true +#else +#define PCINT_USE_PCINT13 false +#endif +#if (PCINT_HAS_PCINT14 == true) && defined(PCINT_ENABLE_PCINT14) +#define PCINT_USE_PCINT14 true +#else +#define PCINT_USE_PCINT14 false +#endif +#if (PCINT_HAS_PCINT15 == true) && defined(PCINT_ENABLE_PCINT15) +#define PCINT_USE_PCINT15 true +#else +#define PCINT_USE_PCINT15 false +#endif +#if (PCINT_HAS_PCINT16 == true) && defined(PCINT_ENABLE_PCINT16) +#define PCINT_USE_PCINT16 true +#else +#define PCINT_USE_PCINT16 false +#endif +#if (PCINT_HAS_PCINT17 == true) && defined(PCINT_ENABLE_PCINT17) +#define PCINT_USE_PCINT17 true +#else +#define PCINT_USE_PCINT17 false +#endif +#if (PCINT_HAS_PCINT18 == true) && defined(PCINT_ENABLE_PCINT18) +#define PCINT_USE_PCINT18 true +#else +#define PCINT_USE_PCINT18 false +#endif +#if (PCINT_HAS_PCINT19 == true) && defined(PCINT_ENABLE_PCINT19) +#define PCINT_USE_PCINT19 true +#else +#define PCINT_USE_PCINT19 false +#endif +#if (PCINT_HAS_PCINT20 == true) && defined(PCINT_ENABLE_PCINT20) +#define PCINT_USE_PCINT20 true +#else +#define PCINT_USE_PCINT20 false +#endif +#if (PCINT_HAS_PCINT21 == true) && defined(PCINT_ENABLE_PCINT21) +#define PCINT_USE_PCINT21 true +#else +#define PCINT_USE_PCINT21 false +#endif +#if (PCINT_HAS_PCINT22 == true) && defined(PCINT_ENABLE_PCINT22) +#define PCINT_USE_PCINT22 true +#else +#define PCINT_USE_PCINT22 false +#endif +#if (PCINT_HAS_PCINT23 == true) && defined(PCINT_ENABLE_PCINT23) +#define PCINT_USE_PCINT23 true +#else +#define PCINT_USE_PCINT23 false +#endif +#if (PCINT_HAS_PCINT24 == true) && defined(PCINT_ENABLE_PCINT24) +#define PCINT_USE_PCINT24 true +#else +#define PCINT_USE_PCINT24 false +#endif +#if (PCINT_HAS_PCINT25 == true) && defined(PCINT_ENABLE_PCINT25) +#define PCINT_USE_PCINT25 true +#else +#define PCINT_USE_PCINT25 false +#endif +#if (PCINT_HAS_PCINT26 == true) && defined(PCINT_ENABLE_PCINT26) +#define PCINT_USE_PCINT26 true +#else +#define PCINT_USE_PCINT26 false +#endif +#if (PCINT_HAS_PCINT27 == true) && defined(PCINT_ENABLE_PCINT27) +#define PCINT_USE_PCINT27 true +#else +#define PCINT_USE_PCINT27 false +#endif +#if (PCINT_HAS_PCINT28 == true) && defined(PCINT_ENABLE_PCINT28) +#define PCINT_USE_PCINT28 true +#else +#define PCINT_USE_PCINT28 false +#endif +#if (PCINT_HAS_PCINT29 == true) && defined(PCINT_ENABLE_PCINT29) +#define PCINT_USE_PCINT29 true +#else +#define PCINT_USE_PCINT29 false +#endif +#if (PCINT_HAS_PCINT30 == true) && defined(PCINT_ENABLE_PCINT30) +#define PCINT_USE_PCINT30 true +#else +#define PCINT_USE_PCINT30 false +#endif +#if (PCINT_HAS_PCINT31 == true) && defined(PCINT_ENABLE_PCINT31) +#define PCINT_USE_PCINT31 true +#else +#define PCINT_USE_PCINT31 false +#endif + + +//================================================================================ +// Number Used Pins +//================================================================================ + +// count numbers of used pins on each port +/* +for (int port = 0; port < 4; port++) { +Serial.print("#define PCINT_NUM_USED_PINS_PORT"); +Serial.print(port); +Serial.println(" ( \\"); +for (int i = 0; i < 8; i++) { +Serial.print("PCINT_USE_PCINT"); +Serial.print(port * 8 + i); +if (i != 7) +Serial.println(" + \\"); +} +Serial.println(")"); +Serial.println(); +} +*/ +#define PCINT_NUM_USED_PINS_PORT0 ( \ +PCINT_USE_PCINT0 + \ +PCINT_USE_PCINT1 + \ +PCINT_USE_PCINT2 + \ +PCINT_USE_PCINT3 + \ +PCINT_USE_PCINT4 + \ +PCINT_USE_PCINT5 + \ +PCINT_USE_PCINT6 + \ +PCINT_USE_PCINT7) + +#define PCINT_NUM_USED_PINS_PORT1 ( \ +PCINT_USE_PCINT8 + \ +PCINT_USE_PCINT9 + \ +PCINT_USE_PCINT10 + \ +PCINT_USE_PCINT11 + \ +PCINT_USE_PCINT12 + \ +PCINT_USE_PCINT13 + \ +PCINT_USE_PCINT14 + \ +PCINT_USE_PCINT15) + +#define PCINT_NUM_USED_PINS_PORT2 ( \ +PCINT_USE_PCINT16 + \ +PCINT_USE_PCINT17 + \ +PCINT_USE_PCINT18 + \ +PCINT_USE_PCINT19 + \ +PCINT_USE_PCINT20 + \ +PCINT_USE_PCINT21 + \ +PCINT_USE_PCINT22 + \ +PCINT_USE_PCINT23) + +#define PCINT_NUM_USED_PINS_PORT3 ( \ +PCINT_USE_PCINT24 + \ +PCINT_USE_PCINT25 + \ +PCINT_USE_PCINT26 + \ +PCINT_USE_PCINT27 + \ +PCINT_USE_PCINT28 + \ +PCINT_USE_PCINT29 + \ +PCINT_USE_PCINT30 + \ +PCINT_USE_PCINT31) + + +// number of used hardware pins +#define EXTERNAL_NUM_USED_PINCHANGEINTERRUPT ( \ +PCINT_NUM_USED_PINS_PORT0 + \ +PCINT_NUM_USED_PINS_PORT1 + \ +PCINT_NUM_USED_PINS_PORT2 + \ +PCINT_NUM_USED_PINS_PORT3) + +//================================================================================ +// Used Ports +//================================================================================ + +// check if ports are used +#if PCINT_NUM_USED_PINS_PORT0 +#define PCINT_USE_PORT0 true +#else +#define PCINT_USE_PORT0 false +#endif +#if PCINT_NUM_USED_PINS_PORT1 +#define PCINT_USE_PORT1 true +#else +#define PCINT_USE_PORT1 false +#endif +#if PCINT_NUM_USED_PINS_PORT2 +#define PCINT_USE_PORT2 true +#else +#define PCINT_USE_PORT2 false +#endif +#if PCINT_NUM_USED_PINS_PORT3 +#define PCINT_USE_PORT3 true +#else +#define PCINT_USE_PORT3 false +#endif + +// number of used ports +#define PCINT_NUM_USED_PORTS ( \ +PCINT_USE_PORT0 + \ +PCINT_USE_PORT1 + \ +PCINT_USE_PORT2 + \ +PCINT_USE_PORT3) diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h new file mode 100644 index 0000000..c485b84 --- /dev/null +++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h @@ -0,0 +1,230 @@ +/* +Copyright (c) 2014-2015 NicoHood +See the readme for credit to other people. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// include guard +#pragma once + +//================================================================================ +// General Settings +//================================================================================ + +/* Settings to de/activate ports/pins +This will save you flash and ram because the arrays +are managed dynamically with the definitions below. +Make sure you still have all needed ports activated. +Each deactivated port saves 3 bytes of ram. +If you deactivate the whole port, +you dont need to deactivate the pins. +Same for the port if you deactivate all 8 pins. +You dont have to deactivate pins/ports that dont exist. +That is done by the macros. */ + +#ifndef PCINT_ENABLE_MANUAL + +#define PCINT_ENABLE_PORT0 +#define PCINT_ENABLE_PORT1 +#define PCINT_ENABLE_PORT2 +#define PCINT_ENABLE_PORT3 + +#define PCINT_ENABLE_PCINT0 +#define PCINT_ENABLE_PCINT1 +#define PCINT_ENABLE_PCINT2 +#define PCINT_ENABLE_PCINT3 +#define PCINT_ENABLE_PCINT4 +#define PCINT_ENABLE_PCINT5 +#define PCINT_ENABLE_PCINT6 +#define PCINT_ENABLE_PCINT7 +#define PCINT_ENABLE_PCINT8 +#define PCINT_ENABLE_PCINT9 +#define PCINT_ENABLE_PCINT10 +#define PCINT_ENABLE_PCINT11 +#define PCINT_ENABLE_PCINT12 +#define PCINT_ENABLE_PCINT13 +#define PCINT_ENABLE_PCINT14 +#define PCINT_ENABLE_PCINT15 +#define PCINT_ENABLE_PCINT16 +#define PCINT_ENABLE_PCINT17 +#define PCINT_ENABLE_PCINT18 +#define PCINT_ENABLE_PCINT19 +#define PCINT_ENABLE_PCINT20 +#define PCINT_ENABLE_PCINT21 +#define PCINT_ENABLE_PCINT22 +#define PCINT_ENABLE_PCINT23 +#define PCINT_ENABLE_PCINT24 +#define PCINT_ENABLE_PCINT25 +#define PCINT_ENABLE_PCINT26 +#define PCINT_ENABLE_PCINT27 +#define PCINT_ENABLE_PCINT28 +#define PCINT_ENABLE_PCINT29 +#define PCINT_ENABLE_PCINT30 +#define PCINT_ENABLE_PCINT31 + +#endif + +#ifdef ARDUINO +// use API with function pointers (better optimized with .a linkage) +#define PCINT_API + +// is the library compiled via .a file? +// see readme for more information +#define PCINT_ALINKAGE + +// force compile all enabled port ISRs (with .a linkage) +//#define PCINT_COMPILE_ENABLED_ISR + +#endif + +//================================================================================ +// Suggested Settings +//================================================================================ + +// Arduino Uno (328) +#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega88__) +/* Reordering interrupt callbacks priority +Port0 has SPI on higher pins, ordering is fine +Port1 has I2C on higher pins, ordering is fine +Port2 has USART and Pin Interrupt on lower pins, +move the priority down +Its more likely the user will use pin 4-7 +*/ +#if !defined(PCINT_CALLBACK_PORT2) +#define PCINT_CALLBACK_PORT2 \ +PCINT_CALLBACK(4, 20); \ +PCINT_CALLBACK(5, 21); \ +PCINT_CALLBACK(6, 22); \ +PCINT_CALLBACK(7, 23); \ +PCINT_CALLBACK(0, 16); /* USART RX */ \ +PCINT_CALLBACK(1, 17); /* USART TX */ \ +PCINT_CALLBACK(2, 18); /* Pin Interrupt 0 */ \ +PCINT_CALLBACK(3, 19); /* Pin Interrupt 1 */ +#endif + +// deactivate crystal and reset pins by default +#if defined(PCINT_ENABLE_PCINT6) +#undef PCINT_ENABLE_PCINT6 // crystal +#endif +#if defined(PCINT_ENABLE_PCINT7) +#undef PCINT_ENABLE_PCINT7 // crystal +#endif +#if defined(PCINT_ENABLE_PCINT14) +#undef PCINT_ENABLE_PCINT14 // reset +#endif +#endif + +// Arduino Mega (2560) +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA) +/* Port1 is structured a bit more complicated +Also only 3 pins are connected on standard boards +Seeeduino Mega has these pins optional! +Disabling Port1 gives more speed and uses less flash +Pins: 0(RX0), 14(TX3), 15(RX3) */ +#if defined(PCINT_ENABLE_PORT1) +#undef PCINT_ENABLE_PORT1 // better performence +#endif + +/* Reordering interrupt callbacks priority +Port2 has SPI on lower pins, move the priority down +Its more likely the user will use pin 10-13 +Port1 by default deactivated, ordering is fine +Port2 only has ADCs, ordering is fine +*/ +#if !defined(PCINT_CALLBACK_PORT0) +#define PCINT_CALLBACK_PORT0 \ +PCINT_CALLBACK(4, 4); \ +PCINT_CALLBACK(5, 5); \ +PCINT_CALLBACK(6, 6); \ +PCINT_CALLBACK(7, 7); \ +PCINT_CALLBACK(0, 0); /* SPI SS */ \ +PCINT_CALLBACK(1, 1); /* SPI SCK */ \ +PCINT_CALLBACK(2, 2); /* SPI MISO */ \ +PCINT_CALLBACK(3, 3); /* SPI MOSI */ +#endif +#endif + +// Arduino Leonardo/Micro (32u4) +#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) +/* Reordering interrupt callbacks priority +Port0 has SPI on lower pins, move the priority down +Its more likely the user will use pin 8-11 */ +#if !defined(PCINT_CALLBACK_PORT0) +#define PCINT_CALLBACK_PORT0 \ +PCINT_CALLBACK(4, 4); \ +PCINT_CALLBACK(5, 5); \ +PCINT_CALLBACK(6, 6); \ +PCINT_CALLBACK(7, 7); \ +PCINT_CALLBACK(0, 0); /* SPI SS / RX LED */ \ +PCINT_CALLBACK(1, 1); /* SPI SCK */ \ +PCINT_CALLBACK(2, 2); /* SPI MISO */ \ +PCINT_CALLBACK(3, 3); /* SPI MOSI */ +#endif + +// RX LED on normal leonardo/micro +#if defined(PCINT_ENABLE_PCINT0) && (defined(ARDUINO_AVR_LEONARDO) || defined(ARDUINO_AVR_MICRO)) +#undef PCINT_ENABLE_PCINT0 +#endif +#endif + +// Hoodloader2 (u2 Series) +#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) +#if defined(ARDUINO_HOODLOADER2) +// on HoodLoader2 Arduino boards only PB1-7 (port0) is broken out, save this flash +#if defined(PCINT_ENABLE_PORT1) +#undef PCINT_ENABLE_PORT1 +#endif + +// SS (PB0) is not connected on normal Arduino boards +#if defined(PCINT_ENABLE_PCINT0) +#undef PCINT_ENABLE_PCINT0 +#endif + +/* Reordering interrupt callbacks priority +Port0 has SPI on lower pins, move the priority down +Its more likely the user will use PB4-7 +Pretend the User has not soldered the 4 Pinheader +so only do this for non Arduino boards. */ +#else +#if !defined(PCINT_CALLBACK_PORT0) +#define PCINT_CALLBACK_PORT0 \ +PCINT_CALLBACK(4, 4); \ +PCINT_CALLBACK(5, 5); \ +PCINT_CALLBACK(6, 6); \ +PCINT_CALLBACK(7, 7); \ +PCINT_CALLBACK(0, 0); /* SPI SS */ \ +PCINT_CALLBACK(1, 1); /* SPI SCK */ \ +PCINT_CALLBACK(2, 2); /* SPI MISO */ \ +PCINT_CALLBACK(3, 3); /* SPI MOSI */ +#endif +#endif +#endif + +/* Attiny 25/45/85 only has a very few pins +activate all by default +The order is also okay. */ + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) +// Port1 is connected to reset, crystal and Pin Interrupt 0 +// Deactivate it by default +#if defined(PCINT_ENABLE_PORT1) +#undef PCINT_ENABLE_PORT1 +#endif +#endif diff --git a/Display Code/mbraidsv3/mbraidsv3.ino b/Display Code/mbraidsv3/mbraidsv3.ino index 9ec54a9..b54d613 100644 --- a/Display Code/mbraidsv3/mbraidsv3.ino +++ b/Display Code/mbraidsv3/mbraidsv3.ino @@ -1,5 +1,5 @@ #include - +#include #include #include #include @@ -22,12 +22,17 @@ elapsedMillis sinceMux; #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif +constexpr int NUM_SEGMENTS = 14; void setup() { //char select inputs - pinMode(2, INPUT); - pinMode(3, INPUT); - pinMode(4, INPUT); - pinMode(5, INPUT); + pinMode(readIndex[0], INPUT); + attachPCINT(digitalPinToPCINT(readIndex[0]), dispcharISR0, RISING); + pinMode(readIndex[1], INPUT); + attachPCINT(digitalPinToPCINT(readIndex[1]), dispcharISR1, RISING); + pinMode(readIndex[2], INPUT); + attachPCINT(digitalPinToPCINT(readIndex[2]), dispcharISR2, RISING); + pinMode(readIndex[3], INPUT); + attachPCINT(digitalPinToPCINT(readIndex[3]), dispcharISR3, RISING); // pinMode(A0, INPUT); //mux in pinMode(A1, OUTPUT); //s0 @@ -43,7 +48,6 @@ void setup() { void loop() { - multiplexer(); if (sinceDisplay > 20) { testOutput(); @@ -149,4 +153,24 @@ void multiplexer() digitalWrite(A4, muxCount & 0b1000); inputDetect(); muxCount = (muxCount + 1) % 14; +} + +inline void dispcharISR(int selected) { + for (uint8_t mux_count = 0; mux_count < NUM_SEGMENTS; mux_count++) { + PORTC = mux_count << 1; + bitWrite(character[selected], mux_count, PINC & 0b1); + } +} + +void dispcharISR0(){ + dispcharISR(0); +} +void dispcharISR1(){ + dispcharISR(1); +} +void dispcharISR2(){ + dispcharISR(2); +} +void dispcharISR3(){ + dispcharISR(3); }