int SoftwareSerial::read()
{
  int val = 0;
  int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
  
  // one byte of serial data (LSB first)
  // ...--\    /--\/--\/--\/--\/--\/--\/--\/--\/--...
  //	 \--/\--/\--/\--/\--/\--/\--/\--/\--/
  //	start  0   1   2   3   4   5   6   7 stop

  while (digitalRead(_receivePin));

  // confirm that this is a real start bit, not line noise
  if (digitalRead(_receivePin) == LOW) {
    // frame start indicated by a falling edge and low start bit
    // jump to the middle of the low start bit
    delayMicroseconds(bitDelay / 2 - clockCyclesToMicroseconds(50));
	
    // offset of the bit in the byte: from 0 (LSB) to 7 (MSB)
    for (int offset = 0; offset < 8; offset++) {
	// jump to middle of next bit
	delayMicroseconds(bitDelay);
	
	// read bit
	val |= digitalRead(_receivePin) << offset;
    }
	
    delayMicroseconds(_bitPeriod);
    
    return val;
  }
  
  return -1;
}
Exemplo n.º 2
0
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
 * or LOW, the type of pulse to measure.  Works on pulses from 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);
	unsigned long width = 0; // keep initialization out of time critical area
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 16 clock cycles per iteration.
	unsigned long numloops = 0;
	unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
	
	// wait for any previous pulse to end
	while ((*portInputRegister(port) & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ((*portInputRegister(port) & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. There will be some error introduced by
	// the interrupt handlers.

	// Conversion constants are compiler-dependent, different compiler versions
	// have different levels of optimization.
#if __GNUC__==4 && __GNUC_MINOR__==3 && __GNUC_PATCHLEVEL__==2
	// avr-gcc 4.3.2
	return clockCyclesToMicroseconds(width * 21 + 16);
#elif __GNUC__==4 && __GNUC_MINOR__==8 && __GNUC_PATCHLEVEL__==1
	// avr-gcc 4.8.1
	return clockCyclesToMicroseconds(width * 24 + 16);
#elif __GNUC__<=4 && __GNUC_MINOR__<=3
	// avr-gcc <=4.3.x
	#warning "pulseIn() results may not be accurate"
	return clockCyclesToMicroseconds(width * 21 + 16);
#else
	// avr-gcc >4.3.x
	#warning "pulseIn() results may not be accurate"
	return clockCyclesToMicroseconds(width * 24 + 16);
#endif

}
Exemplo n.º 3
0
// max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
    const uint32_t max_timeout_us = clockCyclesToMicroseconds(UINT_MAX);
    if (timeout > max_timeout_us) {
        timeout = max_timeout_us;
    }
    const uint32_t timeout_cycles = microsecondsToClockCycles(timeout);
    const uint32_t start_cycle_count = xthal_get_ccount();
    WAIT_FOR_PIN_STATE(!state);
    WAIT_FOR_PIN_STATE(state);
    const uint32_t pulse_start_cycle_count = xthal_get_ccount();
    WAIT_FOR_PIN_STATE(!state);
    return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
}
unsigned int pulseIn(int pin, int state, unsigned int timeout)
{
    const LPC_GPIO_TypeDef* port = gpioPorts[digitalPinToPort(pin)];
    const unsigned int bitMask = digitalPinToBitMask(pin);
    const unsigned int stateMask = state ? bitMask : 0;

    unsigned long width = 0, numloops = 0;
    const unsigned int maxloops = microsecondsToClockCycles(timeout);

    // Wait for any previous pulse to end
    while (port->MASKED_ACCESS[bitMask] == stateMask)
        if (numloops++ == maxloops) return 0;

    // Wait for the pulse to start
    while (port->MASKED_ACCESS[bitMask] != stateMask)
        if (numloops++ == maxloops) return 0;

    // Wait for the pulse to stop
    while (port->MASKED_ACCESS[bitMask] == stateMask)
    {
        if (numloops++ == maxloops) return 0;
        width++;
    }

    // Convert the reading to microseconds. The loop has been determined to be
    // 20 clock cycles long and have about 16 clocks between the edge and the
    // start of the loop. There will be some error introduced by the interrupt
    // handlers.
    return clockCyclesToMicroseconds(width * 21 + 16);
}
Exemplo n.º 5
0
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
 * or LOW, the type of pulse to measure.  Works on pulses from 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	volatile uint8_t *reg = portInputRegister(digitalPinToPort(pin));
	uint8_t stateMask = (state ? bit : 0);
	unsigned long width = 0; // keep initialization out of time critical area
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 16 clock cycles per iteration.
	unsigned long numloops = 0;
	unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;

	// wait for any previous pulse to end
	while ((*reg & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ((*reg & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ((*reg & bit) == stateMask)
		width++;

	// convert the reading to microseconds. The loop has been determined
	// to be 10 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 10 + 16); 
}
Exemplo n.º 6
0
unsigned long Ping::pulseIn(uint8_t pin, uint8_t state, unsigned long timeout, unsigned long timeoutstop)
{
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);
	unsigned long width = 0;

	unsigned long numloops = 0;
	unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
	unsigned long maxloopsstop = microsecondsToClockCycles(timeoutstop) / 16 ;

	// wait for any previous pulse to end
	while ((*portInputRegister(port) & bit) == stateMask)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to start
	while ((*portInputRegister(port) & bit) != stateMask)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask)
                if (width++ == maxloopsstop)
                        return 5000 ;

	return clockCyclesToMicroseconds(width * 20 + 16);
}
Exemplo n.º 7
0
/*
|| @override Print.write 
||
|| @description
|| | Set the cursor at cooridnate x,y of the display
|| #
*/
void SoftwareSerial::write(uint8_t b)
{
  if (baudRate == 0)
    return;
    
  int bitDelay = bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
  byte mask;

  digitalWrite(transmitPin, LOW);
  delayMicroseconds(bitDelay);

  for (mask = 0x01; mask; mask <<= 1) 
  {
    if (b & mask) // choose bit
    { 
      digitalWrite(transmitPin,HIGH); // send 1
    }
    else
    {
      digitalWrite(transmitPin,LOW); // send 1
    }
    delayMicroseconds(bitDelay);
  }

  digitalWrite(transmitPin, HIGH);
  delayMicroseconds(bitDelay);
}
Exemplo n.º 8
0
/**
 * \par Function
 *   poll
 * \par Description
 *   If we used the serial as software serial port, and set the _polling mask true.
 *   we beed use this function to read the serial data.
 * \par Output
 *   None
 * \return
 *   The character read, or -1 if none is available
 * \par Others
 *   None
 */
int16_t MeSerial::poll(void)
{
  int16_t val = 0;
  int16_t bitDelay = _bitPeriod - clockCyclesToMicroseconds(50);
  if (digitalRead(_RxPin) == LOW)
  {
    for (int16_t offset = 0; offset < 8; offset++)
    {
      delayMicroseconds(bitDelay);
      val |= digitalRead(_RxPin) << offset;
    }
    delayMicroseconds(bitDelay);
    return (val & 0xff);
  }
  return (-1);
}
Exemplo n.º 9
0
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	uint8_t volatile& pinreg = pinno2pinreg(pin);
	uint8_t msk = 1 << pinno2bit(pin);
	uint8_t stm = state? msk : 0;

	unsigned long w = 0;
	unsigned long n = 0;
	unsigned long m = microsecondsToClockCycles(timeout) / 16;

	while ((pinreg & msk) == stm)
		if (n++ == m) return 0;
	while ((pinreg & msk) != stm)
		if (n++ == m) return 0;
	while ((pinreg & msk) == stm)
		w++;

	return clockCyclesToMicroseconds(w * 10 + 16); 
}
Exemplo n.º 10
0
// Same as pulseIn, but tweaked for range 1000 - 2000 usec, and reading only HIGH phase.
// Must be compiled in .cpp file, with -Os compiler switch.
unsigned long PulseIn(uint8_t pin, unsigned long timeout){
   const uint8_t bit = digitalPinToBitMask(pin), port = digitalPinToPort(pin);
   unsigned long width = 1;
   
   unsigned long numloops = 0;
   const unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;

   noInterrupts();
                              //wait for the pulse to start
   while((*portInputRegister(port) & bit) != bit){
      if(++numloops == maxloops){
         interrupts();
         return 0;
      }
   }
                              //wait for the pulse to stop
   while((*portInputRegister(port) & bit) == bit)
      width++;
   interrupts();
   return clockCyclesToMicroseconds((width*0xd00L+0x800L)/256L);
}
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
 * or LOW, the type of pulse to measure.  Works on pulses from 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse.
 *
 * This function performs better with short pulses in noInterrupt() context
 */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);

	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes approximately 16 clock cycles per iteration
	unsigned long maxloops = microsecondsToClockCycles(timeout)/16;

	unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);

	// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
	if (width)
		return clockCyclesToMicroseconds(width * 16 + 16);
	else
		return 0;
}
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
 * or LOW, the type of pulse to measure.  Works on pulses from 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
extern uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
{
	//TODO  Correct clock cycle constants.

	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	//PinDescription p = g_APinDescription[pin];
	uint32_t width = 0; // keep initialization out of time critical area
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 22 clock cycles per iteration.
	uint32_t numloops = 0;
	uint32_t maxloops = microsecondsToClockCycles(timeout) / 22;
	
	// wait for any previous pulse to end
	while ( ((u32AHI_DioReadInput()>>pin) & 0x1) == state)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to start
	while ( ((u32AHI_DioReadInput()>>pin) & 0x1) != state)
		if (numloops++ == maxloops)
			return 0;
	
	// wait for the pulse to stop
	while ( ((u32AHI_DioReadInput()>>pin) & 0x1) == state) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. The loop has been determined
	// to be 52 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 52 + 16);
}
Exemplo n.º 13
0
numvar setBaud(numvar pin, unumvar baud) {
	chkpin(pin);

//#ifndef SOFTWARE_SERIAL_TX
	if (pin == DEFAULT_OUTPIN) {
		beginSerial(baud);
		return 0;
	}
//#endif

#ifdef ALTERNATE_OUTPIN
	else if (pin == ALTERNATE_OUTPIN) {
		Serial1.begin(baud);
		return 0;
	}
#endif

	bittime[pin] = (1000000/baud) - clockCyclesToMicroseconds(50);
	pinMode(pin, OUTPUT);				// make it an output
	digitalWrite(pin, HIGH);				// set idle
	delayMicroseconds(bittime[pin]);		// let it quiesce
	return bittime[pin];
}
Exemplo n.º 14
0
void SWSerLCDpa::print(uint8_t b)
{
    if (_baudRate == 0)
        return;

    int bitDelay = _bitPeriod - clockCyclesToMicroseconds(50); // a digitalWrite is about 50 cycles
    byte mask;

    digitalWrite(_transmitPin, LOW);
    delayMicroseconds(bitDelay);

    for (mask = 0x01; mask; mask <<= 1) {
        if (b & mask) { // choose bit
            digitalWrite(_transmitPin,HIGH); // send 1
        }
        else {
            digitalWrite(_transmitPin,LOW); // send 1
        }
        delayMicroseconds(bitDelay);
    }

    digitalWrite(_transmitPin, HIGH);
    delayMicroseconds(bitDelay);
}
Exemplo n.º 15
0
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
 * or LOW, the type of pulse to measure.  Works on pulses from 2-3 microseconds
 * to 3 minutes in length, but must be called at least a few dozen microseconds
 * before the start of the pulse. */
extern uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )

{
	uint32_t width = 0; // keep initialization out of time critical area

	if(pin > 7)
		pin = pin + 4;
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 2 clock cycles per iteration.
	uint32_t numloops = 0;
	uint32_t maxloops = microsecondsToClockCycles(timeout) / 2;

	// wait for any previous pulse to end
  while (((NRF_GPIO->IN >> pin) & 1UL) == state)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to start
  while (((NRF_GPIO->IN >> pin) & 1UL) != state)
		if (numloops++ == maxloops)
			return 0;

	// wait for the pulse to stop
  while (((NRF_GPIO->IN >> pin) & 1UL) == state) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. The loop has been determined
	// to be 17 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 17 + 16);
}