Example #1
0
//
// 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);
  }