MCUdude / MightyCore

Arduino hardware package for ATmega1284, ATmega644, ATmega324, ATmega324PB, ATmega164, ATmega32, ATmega16 and ATmega8535
Other
650 stars 183 forks source link

Using SoftSerial with PB2 as the receive pin at atmega32 #111

Closed Vitalhb closed 6 years ago

Vitalhb commented 6 years ago

ATMega32 does not have CHANGE interrupts on pin PB2 (INT2). Only RISING and FALLING are valid for that pin.

At method SoftSerial::begin() (file SoftSerial.cpp), the interrupt for reception is set as follows:

#if defined(INT_ONLY) || defined(INT_AND_PCINT)
  {
     // Direct interrupts
      attachInterrupt(digitalPinToInterrupt(_receivePin), isr, CHANGE);

but, if _receivePin is 2 (PB2), using CHANGE as mode, the interrupt will be generated for RISING edges only and reception will not work for normal logic. I have changed the code as follows:

#if defined(INT_ONLY) || defined(INT_AND_PCINT)
  {
     // Direct interrupts
#ifdef INT_ONLY
     attachInterrupt(digitalPinToInterrupt(_receivePin), isr, _inverse_logic ? RISING : FALLING);
#else
      attachInterrupt(digitalPinToInterrupt(_receivePin), isr, CHANGE);
#endif //INT_ONLY

Now, it works for PB2 as _receivePin on ATMega32. I have not tested this change with other pins and other microcontrollers.

MCUdude commented 6 years ago

Thanks for pointing this out! I'll fix this soon. BTW this also applies for ATmega8515, ATmega162, ATmega8535 and ATmega16. ATmega162 also has PCINTs, so we can't just check for INT_ONLY.