Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // The receive routine called by the interrupt handler
- //
- void SoftwareSerial::recv()
- {
- #if GCC_VERSION < 40302
- // Work-around for avr-gcc 4.3.0 OSX version bug
- // Preserve the registers that the compiler misses
- // (courtesy of Arduino forum user *etracer*)
- asm volatile(
- "push r18 \n\t"
- "push r19 \n\t"
- "push r20 \n\t"
- "push r21 \n\t"
- "push r22 \n\t"
- "push r23 \n\t"
- "push r26 \n\t"
- "push r27 \n\t"
- ::);
- #endif
- uint8_t d = 0;
- // If RX line is high, then we don't see any start bit
- // so interrupt is probably not for us
- if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
- {
- // Disable further interrupts during reception, this prevents
- // triggering another interrupt directly after we return, which can
- // cause problems at higher baudrates.
- setRxIntMsk(false);
- // Wait approximately 1/2 of a bit width to "center" the sample
- tunedDelay(_rx_delay_centering);
- DebugPulse(_DEBUG_PIN2, 1);
- // Read each of the 8 bits
- for (uint8_t i=8; i > 0; --i)
- {
- tunedDelay(_rx_delay_intrabit);
- d >>= 1;
- DebugPulse(_DEBUG_PIN2, 1);
- if (rx_pin_read())
- d |= 0x80;
- }
- if (_inverse_logic)
- d = ~d;
- // if buffer full, set the overflow flag and return
- uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
- if (next != _receive_buffer_head)
- {
- // save new data in buffer: tail points to where byte goes
- _receive_buffer[_receive_buffer_tail] = d; // save new byte
- _receive_buffer_tail = next;
- }
- else
- {
- DebugPulse(_DEBUG_PIN1, 1);
- _buffer_overflow = true;
- }
- // skip the stop bit
- tunedDelay(_rx_delay_stopbit);
- DebugPulse(_DEBUG_PIN1, 1);
- // Re-enable interrupts when we're sure to be inside the stop bit
- setRxIntMsk(true);
- }
- #if GCC_VERSION < 40302
- // Work-around for avr-gcc 4.3.0 OSX version bug
- // Restore the registers that the compiler misses
- asm volatile(
- "pop r27 \n\t"
- "pop r26 \n\t"
- "pop r23 \n\t"
- "pop r22 \n\t"
- "pop r21 \n\t"
- "pop r20 \n\t"
- "pop r19 \n\t"
- "pop r18 \n\t"
- ::);
- #endif
- }
- uint8_t SoftwareSerial::rx_pin_read()
- {
- return *_receivePortRegister & _receiveBitMask;
- }
- //
- // Interrupt handling
- //
- /* static */
- inline void SoftwareSerial::handle_interrupt()
- {
- if (active_object)
- {
- active_object->recv();
- }
- }
- #if defined(PCINT0_vect)
- ISR(PCINT0_vect)
- {
- SoftwareSerial::handle_interrupt();
- }
- #endif
- #if defined(PCINT1_vect)
- ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
- #endif
- #if defined(PCINT2_vect)
- ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
- #endif
- #if defined(PCINT3_vect)
- ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
- #endif
Advertisement
Add Comment
Please, Sign In to add comment