// // The receive routine called by the interrupt handler // void SoftwareSerial::recv() { DebugPulse(_DEBUG_PIN2, 1); 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; } DebugPulse(_DEBUG_PIN2, 1); 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); }
// // The receive routine called by the interrupt handler // void SoftwareSerial::recv() { noInterrupts(); 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 (invertedLogic ? digitalRead(_rxPin) : !digitalRead(_rxPin)) { // The very first start bit the sketch receives takes about 5us longer if(firstStartBit && !isSOCGpio) { delayTicks(initRxCenteringDelay); } else { delayTicks(rxCenteringDelay); } for (uint8_t i=8; i > 0; --i) { // compensate for the centering delay if the ISR was too late and missed the center of the start bit. if(i == 8) { if(firstStartBit && !isSOCGpio) { delayTicks(initRxIntraBitDelay); } else { delayTicks(firstIntraBitDelay); } } else { delayTicks(rxIntraBitDelay); } d >>= 1; if (digitalRead(_rxPin)) d |= 0x80; firstStartBit = false; } if (invertedLogic) d = ~d; 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); bufferOverflow = true; } // wait until we see a stop bit/s or timeout; uint8_t loopTimeout = 32; if(invertedLogic) { while(digitalRead(_rxPin) && (loopTimeout >0)) { delayTicks(bitDelay >> 4); loopTimeout--; } } else { while(!digitalRead(_rxPin) && (loopTimeout >0)) { delayTicks(bitDelay >> 4); loopTimeout--; } } DebugPulse(_DEBUG_PIN1, 1); }