-
-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Working with ATtinyx61 #43
base: master
Are you sure you want to change the base?
Changes from all commits
b93af7e
74e0fdd
94f7738
3c2bcc9
0337774
2c7a9fc
6b5d48e
d129ff5
7ef2dbe
4a28a87
4877616
13219eb
e8bf710
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,6 +121,29 @@ void enablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcint | |
#endif | ||
} | ||
|
||
// Special case for Attiny x61 where PCMSK0 and PCMSK1 registers | ||
// have initial values of 1 for some reason. | ||
// See datasheet section 9.3.4 and 9.3.5 | ||
// https://ww1.microchip.com/downloads/en/devicedoc/atmel-2588-8-bit-avr-microcontrollers-tinyavr-attiny261-attiny461-attiny861_datasheet.pdf | ||
#if defined(GIMSK) && (defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__)) | ||
#if (PCINT_USE_PORT1 == true) | ||
// PCIE0 case | ||
if (!(GIMSK & (1 << PCIE0))) { | ||
// Clear PCINT11:8 | ||
PCMSK1 &= ~0x0F; | ||
} | ||
// PCIE1 case | ||
#endif | ||
if (!(GIMSK & (1 << PCIE1))) { | ||
#if (PCINT_USE_PORT1 == true) | ||
// Clear PCINT15:12 | ||
PCMSK1 &= ~0xF0; | ||
#endif | ||
// Clear PCINT7:0 | ||
PCMSK0 = 0x00; | ||
} | ||
#endif | ||
|
||
// Pin change mask registers decide which pins are ENABLE as triggers | ||
#ifdef PCMSK0 | ||
#ifdef PCMSK1 | ||
|
@@ -165,6 +188,21 @@ void enablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcint | |
PCICR |= (1 << (pcintPort + PCIE0)); | ||
#elif defined(GICR) /* e.g. ATmega162 */ | ||
GICR |= (1 << (pcintPort + PCIE0)); | ||
#elif defined(GIMSK) && (defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__)) | ||
// This is a special case for Attiny x61 series which was very weird PCINT mapping. | ||
// See datasheet section 9.3.2: http://ww1.microchip.com/downloads/en/devicedoc/atmel-2588-8-bit-avr-microcontrollers-tinyavr-attiny261-attiny461-attiny861_datasheet.pdf | ||
#if (PCINT_USE_PORT1 == true) | ||
if (pcintPort == 1 && pcintMask < (1 << 4)) { | ||
// PCINT11:8 will be enabled with PCIE0 | ||
GIMSK |= (1 << PCIE0); | ||
} | ||
else { | ||
#endif | ||
// PCINT7:0 and PCINT15:12 will be enabled with PCIE1 | ||
GIMSK |= (1 << PCIE1); | ||
#if (PCINT_USE_PORT1 == true) | ||
} | ||
#endif | ||
#elif defined(GIMSK) && defined(PCIE0) /* e.g. ATtiny X4 */ | ||
GIMSK |= (1 << (pcintPort + PCIE0)); | ||
#elif defined(GIMSK) && defined(PCIE) /* e.g. ATtiny X5 */ | ||
|
@@ -247,9 +285,31 @@ void disablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcin | |
// if that's the last one, disable the interrupt. | ||
if (*(&PCMSK + pcintPort) == 0) { | ||
disable = true; | ||
} | ||
#endif // ifdef PCMSK0 | ||
|
||
// This is a special case for Attiny x61 series which was very weird PCINT mapping. | ||
// See datasheet section 9.3.2: | ||
// http://ww1.microchip.com/downloads/en/devicedoc/atmel-2588-8-bit-avr-microcontrollers-tinyavr-attiny261-attiny461-attiny861_datasheet.pdf | ||
#if defined(GIMSK) && (defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__)) | ||
#if (PCINT_USE_PORT1 == true) | ||
if (pcintPort == 1 && pcintMask < (1 << 4)) { | ||
//PCINT11:8 will be disabled with PCIE0 | ||
if (!(PCMSK1 & 0x0F)) { | ||
GIMSK &= ~(1 << PCIE0); | ||
} | ||
} | ||
else { | ||
//PCINT7:0 and PCINT15:12 will be disabled with PCIE1 | ||
if (!PCMSK0 && !(PCMSK1 & 0xF0)) { | ||
#else | ||
if (!PCMSK0) { | ||
#endif | ||
GIMSK &= ~(1 << PCIE1); | ||
} | ||
#if (PCINT_USE_PORT1 == true) | ||
} | ||
#endif | ||
#else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not need this else path, if you add the return statement, that I've added in my original code snipped. That would be much clearer to separate this special use case. |
||
if(disable) | ||
{ | ||
#ifdef PCICR | ||
|
@@ -264,6 +324,7 @@ void disablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcin | |
#error MCU has no such a register | ||
#endif | ||
} | ||
#endif | ||
} | ||
|
||
/* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -371,12 +371,14 @@ Serial.println(); | |
// Hardware Definitions | ||
//================================================================================ | ||
|
||
#if defined(PCINT0_vect) | ||
//special case for the x61 where a single interrupt vector is used for multiple ports | ||
#if defined(PCINT0_vect) || (defined(PCINT_vect) && (defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about placing this last? // Special check for combined ports, such as on Attiny x61
#if defined(PCINT_vect)
#ifdef PCINT_COMBINE_PORT0_PORT1
#define PCINT_HAS_PORT0 true
#define PCINT_HAS_PORT1 true
#else
#error Unknown Combined Port Configuration
#endif
#endif This way it is more flexible. I am also wondering if we can automate combined port detection by using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wasn't sure whether PCINT_vect comes up anywhere else currently or might in the future that would make this check incorrect. The only reference I can find to it on other chips is for the ATtiny2313 but I'm not sure that reference is correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well if it comes up, the code compilation will fail. That is good, so I can fix the issue later on. I also think it would be a good idea to fail like this, as this gives us better detection of new, unsupported MCUs. Meaning if it uses such weird port combination we will be notified faster with this error message. Speaking of ATtiny2313, I remember that I had lots of problems with this MCU. I might need to revisit that. But that for another PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just checked the Attiny 2313, and I am wondering why it works with |
||
#define PCINT_HAS_PORT0 true | ||
#else | ||
#define PCINT_HAS_PORT0 false | ||
#endif | ||
#if defined(PCINT1_vect) | ||
//special case for the x61 where a single interrupt vector is used for multiple ports | ||
#if defined(PCINT1_vect) || (defined(PCINT_vect) && (defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__))) | ||
#define PCINT_HAS_PORT1 true | ||
#else | ||
#define PCINT_HAS_PORT1 false | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That bracket is missing. I guess the code will not compile now.