Guest User

Untitled

a guest
Aug 2nd, 2021
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.77 KB | None | 0 0
  1. //
  2. // The receive routine called by the interrupt handler
  3. //
  4. void SoftwareSerial::recv()
  5. {
  6.  
  7. #if GCC_VERSION < 40302
  8. // Work-around for avr-gcc 4.3.0 OSX version bug
  9. // Preserve the registers that the compiler misses
  10. // (courtesy of Arduino forum user *etracer*)
  11.   asm volatile(
  12.     "push r18 \n\t"
  13.     "push r19 \n\t"
  14.     "push r20 \n\t"
  15.     "push r21 \n\t"
  16.     "push r22 \n\t"
  17.     "push r23 \n\t"
  18.     "push r26 \n\t"
  19.     "push r27 \n\t"
  20.     ::);
  21. #endif  
  22.  
  23.   uint8_t d = 0;
  24.  
  25.   // If RX line is high, then we don't see any start bit
  26.   // so interrupt is probably not for us
  27.   if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
  28.   {
  29.     // Disable further interrupts during reception, this prevents
  30.     // triggering another interrupt directly after we return, which can
  31.     // cause problems at higher baudrates.
  32.     setRxIntMsk(false);
  33.  
  34.     // Wait approximately 1/2 of a bit width to "center" the sample
  35.     tunedDelay(_rx_delay_centering);
  36.     DebugPulse(_DEBUG_PIN2, 1);
  37.  
  38.     // Read each of the 8 bits
  39.     for (uint8_t i=8; i > 0; --i)
  40.     {
  41.       tunedDelay(_rx_delay_intrabit);
  42.       d >>= 1;
  43.       DebugPulse(_DEBUG_PIN2, 1);
  44.       if (rx_pin_read())
  45.         d |= 0x80;
  46.     }
  47.  
  48.     if (_inverse_logic)
  49.       d = ~d;
  50.  
  51.     // if buffer full, set the overflow flag and return
  52.     uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
  53.     if (next != _receive_buffer_head)
  54.     {
  55.       // save new data in buffer: tail points to where byte goes
  56.       _receive_buffer[_receive_buffer_tail] = d; // save new byte
  57.       _receive_buffer_tail = next;
  58.     }
  59.     else
  60.     {
  61.       DebugPulse(_DEBUG_PIN1, 1);
  62.       _buffer_overflow = true;
  63.     }
  64.  
  65.     // skip the stop bit
  66.     tunedDelay(_rx_delay_stopbit);
  67.     DebugPulse(_DEBUG_PIN1, 1);
  68.  
  69.     // Re-enable interrupts when we're sure to be inside the stop bit
  70.     setRxIntMsk(true);
  71.  
  72.   }
  73.  
  74. #if GCC_VERSION < 40302
  75. // Work-around for avr-gcc 4.3.0 OSX version bug
  76. // Restore the registers that the compiler misses
  77.   asm volatile(
  78.     "pop r27 \n\t"
  79.     "pop r26 \n\t"
  80.     "pop r23 \n\t"
  81.     "pop r22 \n\t"
  82.     "pop r21 \n\t"
  83.     "pop r20 \n\t"
  84.     "pop r19 \n\t"
  85.     "pop r18 \n\t"
  86.     ::);
  87. #endif
  88. }
  89.  
  90. uint8_t SoftwareSerial::rx_pin_read()
  91. {
  92.   return *_receivePortRegister & _receiveBitMask;
  93. }
  94.  
  95. //
  96. // Interrupt handling
  97. //
  98.  
  99. /* static */
  100. inline void SoftwareSerial::handle_interrupt()
  101. {
  102.   if (active_object)
  103.   {
  104.     active_object->recv();
  105.   }
  106. }
  107.  
  108. #if defined(PCINT0_vect)
  109. ISR(PCINT0_vect)
  110. {
  111.   SoftwareSerial::handle_interrupt();
  112. }
  113. #endif
  114.  
  115. #if defined(PCINT1_vect)
  116. ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
  117. #endif
  118.  
  119. #if defined(PCINT2_vect)
  120. ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
  121. #endif
  122.  
  123. #if defined(PCINT3_vect)
  124. ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
  125. #endif
Advertisement
Add Comment
Please, Sign In to add comment