Skip to content

Commit

Permalink
Hack for ATmega 644.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArminJo committed Oct 8, 2024
1 parent 2d6448c commit fac1fd3
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 48 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/LibraryBuild.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ jobs:
- arduino:avr:leonardo
- arduino:avr:mega
- digistump:avr:digispark-pro
# - ATTinyCore:avr:attinyx5:chip=85,clock=1internal
# - ATTinyCore:avr:attinyx7micr:sketchclock=1external16
- ATTinyCore:avr:attinyx5:chip=85,clock=1internal
- ATTinyCore:avr:attinyx7micr:sketchclock=1external16

# Choose the right platform for the boards we want to test. (maybe in the future Arduino will automatically do this for you)
# With sketches-exclude you may exclude specific examples for a board. Use a comma separated list.
Expand All @@ -52,15 +52,15 @@ jobs:
- arduino-boards-fqbn: digistump:avr:digispark-pro
platform-url: https://raw.githubusercontent.com/ArminJo/DigistumpArduino/master/package_digistump_index.json

# - arduino-boards-fqbn: ATTinyCore:avr:attinyx5:chip=85,clock=1internal # ATtiny85 board @1 MHz / Digispark
# platform-url: http://drazzy.com/package_drazzy.com_index.json
# build-properties:
# TwoButtons: -DTX_PIN=PB0
- arduino-boards-fqbn: ATTinyCore:avr:attinyx5:chip=85,clock=1internal # ATtiny85 board @1 MHz / Digispark
platform-url: http://drazzy.com/package_drazzy.com_index.json
build-properties:
TwoButtons: -DTX_PIN=PB0

# - arduino-boards-fqbn: ATTinyCore:avr:attinyx7micr:sketchclock=1external16 # Digispark pro
# platform-url: http://drazzy.com/package_drazzy.com_index.json
# build-properties:
# TwoButtons: -DTX_PIN=PB0
- arduino-boards-fqbn: ATTinyCore:avr:attinyx7micr:sketchclock=1external16 # Digispark pro
platform-url: http://drazzy.com/package_drazzy.com_index.json
build-properties:
TwoButtons: -DTX_PIN=PB0


# Do not cancel all jobs / architectures if one job fails
Expand All @@ -77,4 +77,4 @@ jobs:
platform-url: ${{ matrix.platform-url }}
# sketches-exclude: ${{ matrix.sketches-exclude }}
build-properties: ${{ toJson(matrix.build-properties) }}
cli-version: 0.33.0 # to avoid errors for ATTinyCore
# cli-version: 0.33.0 # to avoid errors for ATTinyCore
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Available as [Arduino library "EasyButtonAtInt01"](https://www.arduinolibraries.

[![Button Install](https://img.shields.io/badge/Install-brightgreen?logoColor=white&logo=GitBook)](https://www.ardu-badge.com/EasyButtonAtInt01)
   
[![Button Changelog](https://img.shields.io/badge/Changelog-blue?logoColor=white&logo=AzureArtifacts)](https://github.com/ArminJo/EasyButtonAtInt01#revision-history)
[![Button Changelog](https://img.shields.io/badge/Changelog-blue?logoColor=white&logo=AzureArtifacts)](https://github.com/ArminJo/EasyButtonAtInt01?tab=readme-ov-file#revision-history)

</div>

Expand Down Expand Up @@ -211,6 +211,7 @@ Modify them by enabling / disabling them, or change the values if applicable.
| `BUTTON_LED_FEEDBACK` | disabled | This activates LED_BUILTIN as long as button is pressed. |
| `BUTTON_LED_FEEDBACK_PIN` | disabled | The pin to use for button LED feedback. |
| `INTENTIONALLY_USE_PCI0_FOR_BUTTON1` | disabled | Activate it to suppress the warning: "Using PCINT0 interrupt for button 1". |
| `USE_INT2_FOR_BUTTON_0` | disabled | Hack, especially for ATmega644 etc, where INT0 and INT1 are occupied by 2. USART. |

The exact pin numbers of the buttons used internally are available by the macros INT0_PIN and INT1_PIN, which are set after the include.

Expand Down Expand Up @@ -240,6 +241,7 @@ bool checkForForButtonNotPressedTime(uint16_t aTimeoutMillis);
# Revision History
### Version 3.4.1 - work in progress
- Avoid wrong double press detection if calling checkForDoublePress() after release of button.
- Hack for ATmega 644.
### Version 3.4.0
- Added `NO_INITIALIZE_IN_CONSTRUCTOR` macro to enable late initializing.
Expand Down
3 changes: 2 additions & 1 deletion examples/Callback/Callback.ino
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ void setup() {
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \
|| defined(SERIALUSB_PID) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
#endif
// Just to know which program is running on my Arduino
Expand Down
3 changes: 2 additions & 1 deletion examples/DebounceTest/DebounceTest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ void setup() {
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \
|| defined(SERIALUSB_PID) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
#endif
// Just to know which program is running on my Arduino
Expand Down
3 changes: 2 additions & 1 deletion examples/OneButton/OneButton.ino
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ void setup() {
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \
|| defined(SERIALUSB_PID) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
#endif
// Just to know which program is running on my Arduino
Expand Down
12 changes: 6 additions & 6 deletions examples/TwoButtons/ATtinySerialOut.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* ATtinySerialOut.h
*
* Copyright (C) 2015-2023 Armin Joachimsmeyer
* Copyright (C) 2015-2024 Armin Joachimsmeyer
* Email: armin.joachimsmeyer@gmail.com
*
* This file is part of TinySerialOut https://github.com/ArminJo/ATtinySerialOut.
Expand Down Expand Up @@ -70,16 +70,16 @@
#ifndef _ATTINY_SERIAL_OUT_H
#define _ATTINY_SERIAL_OUT_H

#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) \
#if defined(__AVR_ATtiny13__) || defined(__AVR_ATtiny13A__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) \
|| defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) \
|| defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) \
|| defined(__AVR_ATtiny88__)
#include <Arduino.h>

#define VERSION_ATTINY_SERIAL_OUT "2.2.0"
#define VERSION_ATTINY_SERIAL_OUT "2.3.1"
#define VERSION_ATTINY_SERIAL_OUT_MAJOR 2
#define VERSION_ATTINY_SERIAL_OUT_MINOR 2
#define VERSION_ATTINY_SERIAL_OUT_PATCH 0
#define VERSION_ATTINY_SERIAL_OUT_MINOR 3
#define VERSION_ATTINY_SERIAL_OUT_PATCH 1
// The change log is at the bottom of the file

/*
Expand Down Expand Up @@ -195,7 +195,7 @@ class TinySerialOut

// virtual functions of Print class
size_t write(uint8_t aByte);
operator bool(); // To support "while (!Serial); // wait for serial port to connect. Required for Leonardo only
operator bool() { return true; } // To support "while (!Serial); // wait for serial port to connect. Required for Leonardo only

#if !defined(TINY_SERIAL_INHERIT_FROM_PRINT)
void print(const __FlashStringHelper *aStringPtr);
Expand Down
32 changes: 24 additions & 8 deletions examples/TwoButtons/ATtinySerialOut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Using the Serial.print commands needs 4 bytes extra for each call.
*
*
* Copyright (C) 2015-2023 Armin Joachimsmeyer
* Copyright (C) 2015-2024 Armin Joachimsmeyer
* Email: armin.joachimsmeyer@gmail.com
*
* This file is part of TinySerialOut https://github.com/ArminJo/ATtinySerialOut.
Expand All @@ -36,7 +36,7 @@
#ifndef _ATTINY_SERIAL_OUT_HPP
#define _ATTINY_SERIAL_OUT_HPP

#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) \
#if defined(__AVR_ATtiny13__) || defined(__AVR_ATtiny13A__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) \
|| defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) \
|| defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) \
|| defined(__AVR_ATtiny88__)
Expand All @@ -52,24 +52,40 @@
#endif

#if defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // For use with ATTinyCore
# if !defined(TX_PORT)
# if TX_PIN == PIN_PA0 || TX_PIN == PIN_PA1 || TX_PIN == PIN_PA2 || TX_PIN == PIN_PA3 \
# if TX_PIN == PIN_PA0 || TX_PIN == PIN_PA1 || TX_PIN == PIN_PA2 || TX_PIN == PIN_PA3 \
|| TX_PIN == PIN_PA4 || TX_PIN == PIN_PA5 || TX_PIN == PIN_PA6 || TX_PIN == PIN_PA7
#define TX_PORT PORTA
#define TX_PORT_ADDR 0x02 // from #define PORTA _SFR_IO8(0x02)
#define TX_DDR DDRA
# else
# else
#define TX_PORT PORTB
#define TX_PORT_ADDR 0x05 // from #define PORTB _SFR_IO8(0x05)
#define TX_DDR DDRB
# endif
# endif

#elif defined(__AVR_ATtiny88__)
// MH-ET LIVE Tiny88(16.0MHz) board
# if TX_PIN <= 7
#define TX_PORT PORTD
#define TX_PORT_ADDR 0x0B // PORTD
#define TX_PORT_ADDR 0x0B // from #define PORTD _SFR_IO8(0x0B)
#define TX_DDR DDRD
# elif TX_PIN <= 15
#define TX_PORT PORTB
#define TX_PORT_ADDR 0x05
#define TX_DDR DDRB
# elif TX_PIN <= 22
#define TX_PORT PORTC
#define TX_PORT_ADDR 0x08
#define TX_DDR DDRC
# elif TX_PIN <= 26
#define TX_PORT PORTA
#define TX_PORT_ADDR 0x0E
#define TX_DDR DDRA
# else
#define TX_PORT PORTC
#define TX_PORT_ADDR 0x08
#define TX_DDR DDRC
# endif

#elif defined(__AVR_ATtiny84__) // For use with ATTinyCore
# if TX_PIN == PIN_PA0 || TX_PIN == PIN_PA1 || TX_PIN == PIN_PA2 || TX_PIN == PIN_PA3 \
Expand Down Expand Up @@ -550,7 +566,7 @@ inline void delay4CyclesExact(uint16_t a4Microseconds) {
);
}

#if (F_CPU == 1000000) && defined(_USE_115200BAUD) // else smaller code, but only 38400 baud at 1 MHz
#if (F_CPU == 1000000) && defined(_USE_115200BAUD) // else around 120 bytes smaller code, but only 38400 baud at 1 MHz
/*
* 115200 baud - 8,680 cycles per bit, 86,8 per byte at 1 MHz
*
Expand Down
3 changes: 2 additions & 1 deletion examples/TwoButtons/TwoButtons.ino
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ void setup() {
pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \
|| defined(SERIALUSB_PID) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
#endif
// Just to know which program is running on my Arduino
Expand Down
19 changes: 17 additions & 2 deletions src/EasyButtonAtInt01.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* EasyButtonAtInt01.hpp
* EasyButtonAtInt01.h
*
* Arduino library for handling push buttons connected between ground and INT0 and / or INT1 pin.
* INT0 and INT1 are connected to Pin 2 / 3 on most Arduinos (ATmega328), to PB6 / PA3 on ATtiny167 and on ATtinyX5 we have only INT0 at PB2.
Expand All @@ -13,7 +13,7 @@
* EasyButton Button0AtPin2(true);
* The macros INT0_PIN and INT1_PIN are set after the include.
*
* Copyright (C) 2018-2022 Armin Joachimsmeyer
* Copyright (C) 2018-2024 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of EasyButtonAtInt01 https://github.com/ArminJo/EasyButtonAtInt01.
Expand Down Expand Up @@ -63,6 +63,10 @@
*
*/

// Return values for button state
#define BUTTON_IS_ACTIVE true
#define BUTTON_IS_INACTIVE false

/*
* Enable this if you buttons are active high.
*/
Expand Down Expand Up @@ -166,6 +170,16 @@
#define INT1_OUT_PORT (PORTB)
# endif // defined(USE_BUTTON_1)

#elif defined(USE_INT2_FOR_BUTTON_0) // Hack for ATmega 644
# if defined(USE_BUTTON_1)
#error If USE_INT2_FOR_BUTTON_0 is defined, only USE_BUTTON_0 is allowed, USE_BUTTON_1 must be disabled!
# endif
// dirty hack, but INT0 and INT1 are occupied by second USART
#define INT0_PIN 2 // PB2 / INT2
#define INT0_DDR_PORT (DDRB)
#define INT0_IN_PORT (PINB)
#define INT0_OUT_PORT (PORTB)

#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
// from here we use only ATtinyCore / PAx / PBx numbers, since on Digispark board and core library there is used a strange enumeration of pins
#define INT0_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards and labeled with 3 (D3)
Expand Down Expand Up @@ -379,6 +393,7 @@ void __attribute__ ((weak)) handleINT1Interrupt();

/* Version 3.4.1 - 12/2023
* - Avoid wrong double press detection if calling checkForDoublePress() after release of button.
* - Hack for ATmega 644.
*
* Version 3.4.0 - 10/2023
* - Added NO_INITIALIZE_IN_CONSTRUCTOR macro to enable late initializing.
Expand Down
44 changes: 34 additions & 10 deletions src/EasyButtonAtInt01.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* #include "EasyButtonAtInt01.hpp"
* EasyButton Button0AtPin2(true);
*
* Copyright (C) 2018-2022 Armin Joachimsmeyer
* Copyright (C) 2018-2024 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of EasyButtonAtInt01 https://github.com/ArminJo/EasyButtonAtInt01.
Expand Down Expand Up @@ -222,6 +222,12 @@ void EasyButton::init(bool aIsButtonAtINT0) {
sPointerToButton0ForISR = this;
# if defined(USE_ATTACH_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(INT0_PIN), &handleINT0Interrupt, CHANGE);

# elif defined(USE_INT2_FOR_BUTTON_0)
EICRA |= _BV(ISC20); // interrupt on any logical change
EIFR |= _BV(INTF2);// clear interrupt bit
EIMSK |= _BV(INT2);// enable interrupt on next change

# else
EICRA |= _BV(ISC00); // interrupt on any logical change
EIFR |= _BV(INTF0);// clear interrupt bit
Expand Down Expand Up @@ -340,7 +346,9 @@ void EasyButton::init(bool aIsButtonAtINT0) {
}

/*
* Negative logic for readButtonState() true means button pin is LOW, if button is active low (default)
* if NOT defined BUTTON_IS_ACTIVE_HIGH we have negative logic for readButtonState()!
* In this case BUTTON_IS_ACTIVE (true) means button pin is LOW
* @return BUTTON_IS_ACTIVE (true) or BUTTON_IS_INACTIVE (false)
*/
bool EasyButton::readButtonState() {
#if defined(USE_BUTTON_0) && not defined(USE_BUTTON_1)
Expand Down Expand Up @@ -384,11 +392,14 @@ bool EasyButton::getButtonStateIsActive() {
}
/*
* Returns stored state if in debouncing period otherwise current state of button
* If button is in bouncing period, we do not know button state, so it is only save to return BUTTON_IS_INACTIVE
* @return BUTTON_IS_ACTIVE (true) or BUTTON_IS_INACTIVE (false)
*/
bool EasyButton::readDebouncedButtonState() {
// Check for bouncing period
// Check if we are in bouncing period
if (millis() - ButtonLastChangeMillis <= BUTTON_DEBOUNCING_MILLIS) {
return ButtonStateIsActive;
// If button is in bouncing period, we do not know button state, so it is only save to return BUTTON_IS_INACTIVE
return BUTTON_IS_INACTIVE;
}
return readButtonState();
}
Expand Down Expand Up @@ -445,14 +456,15 @@ uint16_t EasyButton::updateButtonPressDuration() {
*/
uint8_t EasyButton::checkForLongPress(uint16_t aLongPressThresholdMillis) {
uint8_t tRetvale = EASY_BUTTON_LONG_PRESS_ABORT;
if (readDebouncedButtonState()) {
// noInterrupts() is required, since otherwise we may get wrong results if interrupted during processing by button ISR
noInterrupts();
if (readDebouncedButtonState() != BUTTON_IS_INACTIVE) {
// Button still active -> update current ButtonPressDurationMillis
// noInterrupts() is required, since otherwise we may get wrong results if interrupted during load of long value by button ISR
noInterrupts();

ButtonPressDurationMillis = millis() - ButtonLastChangeMillis;
interrupts();
tRetvale = EASY_BUTTON_LONG_PRESS_STILL_POSSIBLE; // if not detected, you may try again
}
interrupts();
if (ButtonPressDurationMillis >= aLongPressThresholdMillis) {
// long press detected
return EASY_BUTTON_LONG_PRESS_DETECTED;
Expand Down Expand Up @@ -716,8 +728,8 @@ void __attribute__ ((weak)) handleINT1Interrupt() {
// ISR for PIN PD2
// Cannot make the vector itself weak, since the vector table is already filled by weak vectors resulting in ignoring my weak one:-(
//ISR(INT0_vect, __attribute__ ((weak))) {
# if defined(USE_BUTTON_0)
ISR(INT0_vect) {
# if defined(USE_INT2_FOR_BUTTON_0)
ISR(INT2_vect) {
# if defined(MEASURE_EASY_BUTTON_INTERRUPT_TIMING)
digitalWriteFast(INTERRUPT_TIMING_OUTPUT_PIN, HIGH);
# endif
Expand All @@ -726,6 +738,18 @@ ISR(INT0_vect) {
digitalWriteFast(INTERRUPT_TIMING_OUTPUT_PIN, LOW);
# endif
}
# else
# if defined(USE_BUTTON_0)
ISR(INT0_vect) {
# if defined(MEASURE_EASY_BUTTON_INTERRUPT_TIMING)
digitalWriteFast(INTERRUPT_TIMING_OUTPUT_PIN, HIGH);
# endif
handleINT0Interrupt();
# if defined(MEASURE_EASY_BUTTON_INTERRUPT_TIMING)
digitalWriteFast(INTERRUPT_TIMING_OUTPUT_PIN, LOW);
# endif
}
# endif
# endif

# if defined(USE_BUTTON_1)
Expand Down
Loading

0 comments on commit fac1fd3

Please sign in to comment.