added VirtualWire from http://www.airspayce.com/mikem/arduino/VirtualWire/
authorDobrica Pavlinusic <dpavlin@rot13.org>
Fri, 6 Sep 2013 21:39:34 +0000 (23:39 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Fri, 6 Sep 2013 21:40:11 +0000 (23:40 +0200)
13 files changed:
libraries/VirtualWire/CHANGES [new file with mode: 0644]
libraries/VirtualWire/LICENSE [new file with mode: 0644]
libraries/VirtualWire/MANIFEST [new file with mode: 0644]
libraries/VirtualWire/Makefile [new file with mode: 0644]
libraries/VirtualWire/README [new file with mode: 0644]
libraries/VirtualWire/VirtualWire.cpp [new file with mode: 0644]
libraries/VirtualWire/VirtualWire.h [new file with mode: 0644]
libraries/VirtualWire/examples/client/client.pde [new file with mode: 0644]
libraries/VirtualWire/examples/receiver/receiver.pde [new file with mode: 0644]
libraries/VirtualWire/examples/server/server.pde [new file with mode: 0644]
libraries/VirtualWire/examples/transmitter/transmitter.pde [new file with mode: 0644]
libraries/VirtualWire/keywords.txt [new file with mode: 0644]
libraries/VirtualWire/util/crc16.h [new file with mode: 0644]

diff --git a/libraries/VirtualWire/CHANGES b/libraries/VirtualWire/CHANGES
new file mode 100644 (file)
index 0000000..592d0e0
--- /dev/null
@@ -0,0 +1 @@
+See VirtulWire.h for latest change log
diff --git a/libraries/VirtualWire/LICENSE b/libraries/VirtualWire/LICENSE
new file mode 100644 (file)
index 0000000..da124e1
--- /dev/null
@@ -0,0 +1,17 @@
+This software is Copyright (C) 2008 Mike McCauley. Use is subject to license
+conditions. The main licensing options available are GPL V2 or Commercial:
+
+Open Source Licensing GPL V2
+
+This is the appropriate option if you want to share the source code of your
+application with everyone you distribute it to, and you also want to give them
+the right to share who uses it. If you wish to use this software under Open
+Source Licensing, you must contribute all your source code to the open source
+community in accordance with the GPL Version 2 when your application is
+distributed. See http://www.gnu.org/copyleft/gpl.html
+
+Commercial Licensing
+
+This is the appropriate option if you are creating proprietary applications
+and you are not prepared to distribute and share the source code of your
+application. Contact info@open.com.au for details.
diff --git a/libraries/VirtualWire/MANIFEST b/libraries/VirtualWire/MANIFEST
new file mode 100644 (file)
index 0000000..805a14e
--- /dev/null
@@ -0,0 +1,14 @@
+VirtualWire/doc
+VirtualWire/LICENSE
+VirtualWire/README
+VirtualWire/Makefile
+VirtualWire/VirtualWire.cpp
+VirtualWire/VirtualWire.h
+VirtualWire/CHANGES
+VirtualWire/MANIFEST
+VirtualWire/keywords.txt
+VirtualWire/util/crc16.h
+VirtualWire/examples/client/client.pde
+VirtualWire/examples/transmitter/transmitter.pde
+VirtualWire/examples/receiver/receiver.pde
+VirtualWire/examples/server/server.pde
diff --git a/libraries/VirtualWire/Makefile b/libraries/VirtualWire/Makefile
new file mode 100644 (file)
index 0000000..269f210
--- /dev/null
@@ -0,0 +1,26 @@
+# Makefile
+#
+# Makefile for the Arduino VirtualWire project
+#
+# Author: Mike McCauley (mikem@airspayce.com)
+# Copyright (C) 2011 Mike McCauley
+# $Id: Makefile,v 1.1 2013/01/14 06:49:29 mikem Exp mikem $
+
+PROJNAME = VirtualWire
+# Dont forget to also change the version at the top of RF22.h:
+DISTFILE = $(PROJNAME)-1.19.zip
+
+all:   doxygen dist upload
+
+doxygen: 
+       doxygen project.cfg
+
+ci:
+       (cd ..;ci -l `cat $(PROJNAME)/MANIFEST`)
+
+dist:  
+       (cd ..; zip $(PROJNAME)/$(DISTFILE) `cat $(PROJNAME)/MANIFEST`)
+
+upload:
+       rsync -avz $(DISTFILE) doc/ www.airspayce.com:public_html/mikem/arduino/$(PROJNAME)
+       rsync -avz ../../doc/VirtualWire.pdf doc/ www.airspayce.com:public_html/mikem/arduino/
diff --git a/libraries/VirtualWire/README b/libraries/VirtualWire/README
new file mode 100644 (file)
index 0000000..1ea8627
--- /dev/null
@@ -0,0 +1,8 @@
+Virtual Wire
+
+This is the VirtualWire library for Arduino
+It provides a simple message passing protocol for a range of inexpensive
+transmitter and receiver modules.
+
+See http://www.open.com.au/mikem/arduino/VirtualWire.pdf for full documentation.
+
diff --git a/libraries/VirtualWire/VirtualWire.cpp b/libraries/VirtualWire/VirtualWire.cpp
new file mode 100644 (file)
index 0000000..3190a28
--- /dev/null
@@ -0,0 +1,715 @@
+// VirtualWire.cpp
+//
+// Virtual Wire implementation for Arduino
+// See the README file in this directory fdor documentation
+// See also
+// ASH Transceiver Software Designer's Guide of 2002.08.07
+//   http://www.rfm.com/products/apnotes/tr_swg05.pdf
+//
+// Changes:
+// 1.5 2008-05-25: fixed a bug that could prevent messages with certain
+//  bytes sequences being received (false message start detected)
+// 1.6 2011-09-10: Patch from David Bath to prevent unconditional reenabling of the receiver
+//  at end of transmission.
+//
+// Author: Mike McCauley (mikem@airspayce.com)
+// Copyright (C) 2008 Mike McCauley
+// $Id: VirtualWire.cpp,v 1.13 2013/08/06 23:43:41 mikem Exp mikem $
+
+
+#if defined(ARDUINO)
+ #if (ARDUINO < 100)
+  #include "WProgram.h"
+ #endif
+#elif defined(__MSP430G2452__) || defined(__MSP430G2553__) // LaunchPad specific
+ #include "legacymsp430.h"
+ #include "Energia.h"
+#elif defined(MCU_STM32F103RE) // Maple etc
+#include <string.h>
+#else // error
+ #error Platform not defined
+#endif
+
+#include "VirtualWire.h"
+#include <util/crc16.h>
+
+
+static uint8_t vw_tx_buf[(VW_MAX_MESSAGE_LEN * 2) + VW_HEADER_LEN] 
+     = {0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x38, 0x2c};
+
+// Number of symbols in vw_tx_buf to be sent;
+static uint8_t vw_tx_len = 0;
+
+// Index of the next symbol to send. Ranges from 0 to vw_tx_len
+static uint8_t vw_tx_index = 0;
+
+// Bit number of next bit to send
+static uint8_t vw_tx_bit = 0;
+
+// Sample number for the transmitter. Runs 0 to 7 during one bit interval
+static uint8_t vw_tx_sample = 0;
+
+// Flag to indicated the transmitter is active
+static volatile uint8_t vw_tx_enabled = 0;
+
+// Total number of messages sent
+static uint16_t vw_tx_msg_count = 0;
+
+// The digital IO pin number of the press to talk, enables the transmitter hardware
+static uint8_t vw_ptt_pin = 10;
+static uint8_t vw_ptt_inverted = 0;
+
+// The digital IO pin number of the receiver data
+static uint8_t vw_rx_pin = 11;
+static uint8_t vw_rx_inverted = 0;
+
+// The digital IO pin number of the transmitter data
+static uint8_t vw_tx_pin = 12;
+
+// Current receiver sample
+static uint8_t vw_rx_sample = 0;
+
+// Last receiver sample
+static uint8_t vw_rx_last_sample = 0;
+
+// PLL ramp, varies between 0 and VW_RX_RAMP_LEN-1 (159) over 
+// VW_RX_SAMPLES_PER_BIT (8) samples per nominal bit time. 
+// When the PLL is synchronised, bit transitions happen at about the
+// 0 mark. 
+static uint8_t vw_rx_pll_ramp = 0;
+
+// This is the integrate and dump integral. If there are <5 0 samples in the PLL cycle
+// the bit is declared a 0, else a 1
+static uint8_t vw_rx_integrator = 0;
+
+// Flag indictate if we have seen the start symbol of a new message and are
+// in the processes of reading and decoding it
+static uint8_t vw_rx_active = 0;
+
+// Flag to indicate that a new message is available
+static volatile uint8_t vw_rx_done = 0;
+
+// Flag to indicate the receiver PLL is to run
+static uint8_t vw_rx_enabled = 0;
+
+// Last 12 bits received, so we can look for the start symbol
+static uint16_t vw_rx_bits = 0;
+
+// How many bits of message we have received. Ranges from 0 to 12
+static uint8_t vw_rx_bit_count = 0;
+
+// The incoming message buffer
+static uint8_t vw_rx_buf[VW_MAX_MESSAGE_LEN];
+
+// The incoming message expected length
+static uint8_t vw_rx_count = 0;
+
+// The incoming message buffer length received so far
+static volatile uint8_t vw_rx_len = 0;
+
+// Number of bad messages received and dropped due to bad lengths
+static uint8_t vw_rx_bad = 0;
+
+// Number of good messages received
+static uint8_t vw_rx_good = 0;
+
+// 4 bit to 6 bit symbol converter table
+// Used to convert the high and low nybbles of the transmitted data
+// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s 
+// with at most 3 consecutive identical bits
+static uint8_t symbols[] =
+{
+    0xd,  0xe,  0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 
+    0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34
+};
+
+// Cant really do this as a real C++ class, since we need to have 
+// an ISR
+extern "C"
+{
+
+// Compute CRC over count bytes.
+// This should only be ever called at user level, not interrupt level
+uint16_t vw_crc(uint8_t *ptr, uint8_t count)
+{
+    uint16_t crc = 0xffff;
+
+    while (count-- > 0) 
+       crc = _crc_ccitt_update(crc, *ptr++);
+    return crc;
+}
+
+// Convert a 6 bit encoded symbol into its 4 bit decoded equivalent
+uint8_t vw_symbol_6to4(uint8_t symbol)
+{
+    uint8_t i;
+    
+    // Linear search :-( Could have a 64 byte reverse lookup table?
+    for (i = 0; i < 16; i++)
+       if (symbol == symbols[i]) return i;
+    return 0; // Not found
+}
+
+// Set the output pin number for transmitter data
+void vw_set_tx_pin(uint8_t pin)
+{
+    vw_tx_pin = pin;
+}
+
+// Set the pin number for input receiver data
+void vw_set_rx_pin(uint8_t pin)
+{
+    vw_rx_pin = pin;
+}
+
+// Set the rx pin inverted 
+void vw_set_rx_inverted(uint8_t inverted)
+{
+    vw_rx_inverted = inverted;
+}
+
+// Set the output pin number for transmitter PTT enable
+void vw_set_ptt_pin(uint8_t pin)
+{
+    vw_ptt_pin = pin;
+}
+
+// Set the ptt pin inverted (low to transmit)
+void vw_set_ptt_inverted(uint8_t inverted)
+{
+    vw_ptt_inverted = inverted;
+}
+
+// Called 8 times per bit period
+// Phase locked loop tries to synchronise with the transmitter so that bit 
+// transitions occur at about the time vw_rx_pll_ramp is 0;
+// Then the average is computed over each bit period to deduce the bit value
+void vw_pll()
+{
+    // Integrate each sample
+    if (vw_rx_sample)
+       vw_rx_integrator++;
+
+    if (vw_rx_sample != vw_rx_last_sample)
+    {
+       // Transition, advance if ramp > 80, retard if < 80
+       vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION) 
+                          ? VW_RAMP_INC_RETARD 
+                          : VW_RAMP_INC_ADVANCE);
+       vw_rx_last_sample = vw_rx_sample;
+    }
+    else
+    {
+       // No transition
+       // Advance ramp by standard 20 (== 160/8 samples)
+       vw_rx_pll_ramp += VW_RAMP_INC;
+    }
+    if (vw_rx_pll_ramp >= VW_RX_RAMP_LEN)
+    {
+       // Add this to the 12th bit of vw_rx_bits, LSB first
+       // The last 12 bits are kept
+       vw_rx_bits >>= 1;
+
+       // Check the integrator to see how many samples in this cycle were high.
+       // If < 5 out of 8, then its declared a 0 bit, else a 1;
+       if (vw_rx_integrator >= 5)
+           vw_rx_bits |= 0x800;
+
+       vw_rx_pll_ramp -= VW_RX_RAMP_LEN;
+       vw_rx_integrator = 0; // Clear the integral for the next cycle
+
+       if (vw_rx_active)
+       {
+           // We have the start symbol and now we are collecting message bits,
+           // 6 per symbol, each which has to be decoded to 4 bits
+           if (++vw_rx_bit_count >= 12)
+           {
+               // Have 12 bits of encoded message == 1 byte encoded
+               // Decode as 2 lots of 6 bits into 2 lots of 4 bits
+               // The 6 lsbits are the high nybble
+               uint8_t this_byte = 
+                   (vw_symbol_6to4(vw_rx_bits & 0x3f)) << 4 
+                   | vw_symbol_6to4(vw_rx_bits >> 6);
+
+               // The first decoded byte is the byte count of the following message
+               // the count includes the byte count and the 2 trailing FCS bytes
+               // REVISIT: may also include the ACK flag at 0x40
+               if (vw_rx_len == 0)
+               {
+                   // The first byte is the byte count
+                   // Check it for sensibility. It cant be less than 4, since it
+                   // includes the bytes count itself and the 2 byte FCS
+                   vw_rx_count = this_byte;
+                   if (vw_rx_count < 4 || vw_rx_count > VW_MAX_MESSAGE_LEN)
+                   {
+                       // Stupid message length, drop the whole thing
+                       vw_rx_active = false;
+                       vw_rx_bad++;
+                        return;
+                   }
+               }
+               vw_rx_buf[vw_rx_len++] = this_byte;
+
+               if (vw_rx_len >= vw_rx_count)
+               {
+                   // Got all the bytes now
+                   vw_rx_active = false;
+                   vw_rx_good++;
+                   vw_rx_done = true; // Better come get it before the next one starts
+               }
+               vw_rx_bit_count = 0;
+           }
+       }
+       // Not in a message, see if we have a start symbol
+       else if (vw_rx_bits == 0xb38)
+       {
+           // Have start symbol, start collecting message
+           vw_rx_active = true;
+           vw_rx_bit_count = 0;
+           vw_rx_len = 0;
+           vw_rx_done = false; // Too bad if you missed the last message
+       }
+    }
+}
+
+#if defined(__arm__) && defined(CORE_TEENSY)
+  // This allows the AVR interrupt code below to be run from an
+  // IntervalTimer object.  It must be above vw_setup(), so the
+  // the TIMER1_COMPA_vect function name is defined.
+  #ifdef SIGNAL
+  #undef SIGNAL
+  #endif
+  #define SIGNAL(f) void f(void)
+  #ifdef TIMER1_COMPA_vect
+  #undef TIMER1_COMPA_vect
+  #endif
+  void TIMER1_COMPA_vect(void);
+#endif
+
+
+// Speed is in bits per sec RF rate
+#if defined(__MSP430G2452__) || defined(__MSP430G2553__) // LaunchPad specific
+void vw_setup(uint16_t speed)
+{
+       // Calculate the counter overflow count based on the required bit speed
+       // and CPU clock rate
+       uint16_t ocr1a = (F_CPU / 8UL) / speed;
+               
+       // This code is for Energia/MSP430
+       TA0CCR0 = ocr1a;                                // Ticks for 62,5 us
+       TA0CTL = TASSEL_2 + MC_1;       // SMCLK, up mode
+       TA0CCTL0 |= CCIE;               // CCR0 interrupt enabled
+               
+       // Set up digital IO pins
+       pinMode(vw_tx_pin, OUTPUT);
+       pinMode(vw_rx_pin, INPUT);
+       pinMode(vw_ptt_pin, OUTPUT);
+       digitalWrite(vw_ptt_pin, vw_ptt_inverted);
+}      
+
+#elif defined (ARDUINO) // Arduino specific
+
+// Common function for setting timer ticks @ prescaler values for speed
+// Returns prescaler index into {0, 1, 8, 64, 256, 1024} array
+// and sets nticks to compare-match value if lower than max_ticks
+// returns 0 & nticks = 0 on fault
+static uint8_t _timer_calc(uint16_t speed, uint16_t max_ticks, uint16_t *nticks)
+{
+    // Clock divider (prescaler) values - 0/3333: error flag
+    uint16_t prescalers[] = {0, 1, 8, 64, 256, 1024, 3333};
+    uint8_t prescaler=0; // index into array & return bit value
+    unsigned long ulticks; // calculate by ntick overflow
+
+    // Div-by-zero protection
+    if (speed == 0)
+    {
+        // signal fault
+        *nticks = 0;
+        return 0;
+    }
+
+    // test increasing prescaler (divisor), decreasing ulticks until no overflow
+    for (prescaler=1; prescaler < 7; prescaler += 1)
+    {
+        // Amount of time per CPU clock tick (in seconds)
+        float clock_time = (1.0 / (float(F_CPU) / float(prescalers[prescaler])));
+        // Fraction of second needed to xmit one bit
+        float bit_time = ((1.0 / float(speed)) / 8.0);
+        // number of prescaled ticks needed to handle bit time @ speed
+        ulticks = long(bit_time / clock_time);
+        // Test if ulticks fits in nticks bitwidth (with 1-tick safety margin)
+        if ((ulticks > 1) && (ulticks < max_ticks))
+        {
+            break; // found prescaler
+        }
+        // Won't fit, check with next prescaler value
+    }
+
+    // Check for error
+    if ((prescaler == 6) || (ulticks < 2) || (ulticks > max_ticks))
+    {
+        // signal fault
+        *nticks = 0;
+        return 0;
+    }
+
+    *nticks = ulticks;
+    return prescaler;
+}
+
+void vw_setup(uint16_t speed)
+{
+    uint16_t nticks; // number of prescaled ticks needed
+    uint8_t prescaler; // Bit values for CS0[2:0]
+
+#ifdef __AVR_ATtiny85__
+    // figure out prescaler value and counter match value
+    prescaler = _timer_calc(speed, (uint8_t)-1, &nticks);
+    if (!prescaler)
+    {
+        return; // fault
+    }
+
+    TCCR0A = 0;
+    TCCR0A = _BV(WGM01); // Turn on CTC mode / Output Compare pins disconnected
+
+    // convert prescaler index to TCCRnB prescaler bits CS00, CS01, CS02
+    TCCR0B = 0;
+    TCCR0B = prescaler; // set CS00, CS01, CS02 (other bits not needed)
+
+    // Number of ticks to count before firing interrupt
+    OCR0A = uint8_t(nticks);
+
+    // Set mask to fire interrupt when OCF0A bit is set in TIFR0
+    TIMSK |= _BV(OCIE0A);
+
+#elif defined(__arm__) && defined(CORE_TEENSY)
+    // on Teensy 3.0 (32 bit ARM), use an interval timer
+    IntervalTimer *t = new IntervalTimer();
+    t->begin(TIMER1_COMPA_vect, 125000.0 / (float)(speed));
+
+#else // ARDUINO
+    // This is the path for most Arduinos
+    // figure out prescaler value and counter match value
+    prescaler = _timer_calc(speed, (uint16_t)-1, &nticks);
+    if (!prescaler)
+    {
+        return; // fault
+    }
+
+    TCCR1A = 0; // Output Compare pins disconnected
+    TCCR1B = _BV(WGM12); // Turn on CTC mode
+
+    // convert prescaler index to TCCRnB prescaler bits CS10, CS11, CS12
+    TCCR1B |= prescaler;
+
+    // Caution: special procedures for setting 16 bit regs
+    // is handled by the compiler
+    OCR1A = nticks;
+    // Enable interrupt
+#ifdef TIMSK1
+    // atmega168
+    TIMSK1 |= _BV(OCIE1A);
+#else
+    // others
+    TIMSK |= _BV(OCIE1A);
+#endif // TIMSK1
+
+#endif // __AVR_ATtiny85__
+
+    // Set up digital IO pins
+    pinMode(vw_tx_pin, OUTPUT);
+    pinMode(vw_rx_pin, INPUT);
+    pinMode(vw_ptt_pin, OUTPUT);
+    digitalWrite(vw_ptt_pin, vw_ptt_inverted);
+}
+
+#elif defined(MCU_STM32F103RE) // Maple etc
+HardwareTimer timer(MAPLE_TIMER);
+void vw_setup(uint16_t speed)
+{
+    // Set up digital IO pins
+    pinMode(vw_tx_pin, OUTPUT);
+    pinMode(vw_rx_pin, INPUT);
+    pinMode(vw_ptt_pin, OUTPUT);
+    digitalWrite(vw_ptt_pin, vw_ptt_inverted);
+
+    // Pause the timer while we're configuring it
+    timer.pause();
+    timer.setPeriod((1000000/8)/speed);
+    // Set up an interrupt on channel 1
+    timer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
+    timer.setCompare(TIMER_CH1, 1);  // Interrupt 1 count after each update
+    void vw_Int_Handler(); // defined below
+    timer.attachCompare1Interrupt(vw_Int_Handler);
+
+    // Refresh the timer's count, prescale, and overflow
+    timer.refresh();
+
+    // Start the timer counting
+    timer.resume();
+}
+
+#endif
+
+// Start the transmitter, call when the tx buffer is ready to go and vw_tx_len is
+// set to the total number of symbols to send
+void vw_tx_start()
+{
+    vw_tx_index = 0;
+    vw_tx_bit = 0;
+    vw_tx_sample = 0;
+
+    // Enable the transmitter hardware
+    digitalWrite(vw_ptt_pin, true ^ vw_ptt_inverted);
+
+    // Next tick interrupt will send the first bit
+    vw_tx_enabled = true;
+}
+
+// Stop the transmitter, call when all bits are sent
+void vw_tx_stop()
+{
+    // Disable the transmitter hardware
+    digitalWrite(vw_ptt_pin, false ^ vw_ptt_inverted);
+    digitalWrite(vw_tx_pin, false);
+
+    // No more ticks for the transmitter
+    vw_tx_enabled = false;
+}
+
+// Enable the receiver. When a message becomes available, vw_rx_done flag
+// is set, and vw_wait_rx() will return.
+void vw_rx_start()
+{
+    if (!vw_rx_enabled)
+    {
+       vw_rx_enabled = true;
+       vw_rx_active = false; // Never restart a partial message
+    }
+}
+
+// Disable the receiver
+void vw_rx_stop()
+{
+    vw_rx_enabled = false;
+}
+
+// Return true if the transmitter is active
+uint8_t vw_tx_active()
+{
+    return vw_tx_enabled;
+}
+
+// Wait for the transmitter to become available
+// Busy-wait loop until the ISR says the message has been sent
+void vw_wait_tx()
+{
+    while (vw_tx_enabled)
+       ;
+}
+
+// Wait for the receiver to get a message
+// Busy-wait loop until the ISR says a message is available
+// can then call vw_get_message()
+void vw_wait_rx()
+{
+    while (!vw_rx_done)
+       ;
+}
+
+// Wait at most max milliseconds for the receiver to receive a message
+// Return the truth of whether there is a message
+uint8_t vw_wait_rx_max(unsigned long milliseconds)
+{
+    unsigned long start = millis();
+
+    while (!vw_rx_done && ((millis() - start) < milliseconds))
+       ;
+    return vw_rx_done;
+}
+
+// Wait until transmitter is available and encode and queue the message
+// into vw_tx_buf
+// The message is raw bytes, with no packet structure imposed
+// It is transmitted preceded a byte count and followed by 2 FCS bytes
+uint8_t vw_send(uint8_t* buf, uint8_t len)
+{
+    uint8_t i;
+    uint8_t index = 0;
+    uint16_t crc = 0xffff;
+    uint8_t *p = vw_tx_buf + VW_HEADER_LEN; // start of the message area
+    uint8_t count = len + 3; // Added byte count and FCS to get total number of bytes
+
+    if (len > VW_MAX_PAYLOAD)
+       return false;
+
+    // Wait for transmitter to become available
+    vw_wait_tx();
+
+    // Encode the message length
+    crc = _crc_ccitt_update(crc, count);
+    p[index++] = symbols[count >> 4];
+    p[index++] = symbols[count & 0xf];
+
+    // Encode the message into 6 bit symbols. Each byte is converted into 
+    // 2 6-bit symbols, high nybble first, low nybble second
+    for (i = 0; i < len; i++)
+    {
+       crc = _crc_ccitt_update(crc, buf[i]);
+       p[index++] = symbols[buf[i] >> 4];
+       p[index++] = symbols[buf[i] & 0xf];
+    }
+
+    // Append the fcs, 16 bits before encoding (4 6-bit symbols after encoding)
+    // Caution: VW expects the _ones_complement_ of the CCITT CRC-16 as the FCS
+    // VW sends FCS as low byte then hi byte
+    crc = ~crc;
+    p[index++] = symbols[(crc >> 4)  & 0xf];
+    p[index++] = symbols[crc & 0xf];
+    p[index++] = symbols[(crc >> 12) & 0xf];
+    p[index++] = symbols[(crc >> 8)  & 0xf];
+
+    // Total number of 6-bit symbols to send
+    vw_tx_len = index + VW_HEADER_LEN;
+
+    // Start the low level interrupt handler sending symbols
+    vw_tx_start();
+
+    return true;
+}
+
+// Return true if there is a message available
+uint8_t vw_have_message()
+{
+    return vw_rx_done;
+}
+
+// Get the last message received (without byte count or FCS)
+// Copy at most *len bytes, set *len to the actual number copied
+// Return true if there is a message and the FCS is OK
+uint8_t vw_get_message(uint8_t* buf, uint8_t* len)
+{
+    uint8_t rxlen;
+    
+    // Message available?
+    if (!vw_rx_done)
+       return false;
+    
+    // Wait until vw_rx_done is set before reading vw_rx_len
+    // then remove bytecount and FCS
+    rxlen = vw_rx_len - 3;
+    
+    // Copy message (good or bad)
+    if (*len > rxlen)
+       *len = rxlen;
+    memcpy(buf, vw_rx_buf + 1, *len);
+    
+    vw_rx_done = false; // OK, got that message thanks
+    
+    // Check the FCS, return goodness
+    return (vw_crc(vw_rx_buf, vw_rx_len) == 0xf0b8); // FCS OK?
+}
+
+uint8_t vw_get_rx_good()
+{
+    return vw_rx_good;
+}
+
+uint8_t vw_get_rx_bad()
+{
+    return vw_rx_bad;
+}
+
+// This is the interrupt service routine called when timer1 overflows
+// Its job is to output the next bit from the transmitter (every 8 calls)
+// and to call the PLL code if the receiver is enabled
+//ISR(SIG_OUTPUT_COMPARE1A)
+#if defined (ARDUINO) // Arduino specific
+
+#ifdef __AVR_ATtiny85__
+SIGNAL(TIM0_COMPA_vect)
+#else // Assume Arduino Uno (328p or similar)
+SIGNAL(TIMER1_COMPA_vect)
+#endif // __AVR_ATtiny85__
+
+{
+    if (vw_rx_enabled && !vw_tx_enabled)
+       vw_rx_sample = digitalRead(vw_rx_pin) ^ vw_rx_inverted;
+    
+    // Do transmitter stuff first to reduce transmitter bit jitter due 
+    // to variable receiver processing
+    if (vw_tx_enabled && vw_tx_sample++ == 0)
+    {
+       // Send next bit
+       // Symbols are sent LSB first
+       // Finished sending the whole message? (after waiting one bit period 
+       // since the last bit)
+       if (vw_tx_index >= vw_tx_len)
+       {
+           vw_tx_stop();
+           vw_tx_msg_count++;
+       }
+       else
+       {
+           digitalWrite(vw_tx_pin, vw_tx_buf[vw_tx_index] & (1 << vw_tx_bit++));
+           if (vw_tx_bit >= 6)
+           {
+               vw_tx_bit = 0;
+               vw_tx_index++;
+           }
+       }
+    }
+    if (vw_tx_sample > 7)
+       vw_tx_sample = 0;
+    
+    if (vw_rx_enabled && !vw_tx_enabled)
+       vw_pll();
+}
+ // LaunchPad or Maple:
+#elif defined(__MSP430G2452__) || defined(__MSP430G2553__) || defined(MCU_STM32F103RE)
+void vw_Int_Handler()
+{
+    if (vw_rx_enabled && !vw_tx_enabled)
+       vw_rx_sample = digitalRead(vw_rx_pin) ^ vw_rx_inverted;
+    
+    // Do transmitter stuff first to reduce transmitter bit jitter due 
+    // to variable receiver processing
+    if (vw_tx_enabled && vw_tx_sample++ == 0)
+    {
+       // Send next bit
+       // Symbols are sent LSB first
+       // Finished sending the whole message? (after waiting one bit period 
+       // since the last bit)
+       if (vw_tx_index >= vw_tx_len)
+       {
+           vw_tx_stop();
+           vw_tx_msg_count++;
+       }
+       else
+       {
+           digitalWrite(vw_tx_pin, vw_tx_buf[vw_tx_index] & (1 << vw_tx_bit++));
+           if (vw_tx_bit >= 6)
+           {
+               vw_tx_bit = 0;
+               vw_tx_index++;
+           }
+       }
+    }
+    if (vw_tx_sample > 7)
+       vw_tx_sample = 0;
+    
+    if (vw_rx_enabled && !vw_tx_enabled)
+       vw_pll();
+}
+#if defined(__MSP430G2452__) || defined(__MSP430G2553__)
+interrupt(TIMER0_A0_VECTOR) Timer_A_int(void) 
+{
+    vw_Int_Handler();
+};
+#endif
+
+#endif
+
+
+}
diff --git a/libraries/VirtualWire/VirtualWire.h b/libraries/VirtualWire/VirtualWire.h
new file mode 100644 (file)
index 0000000..5afde38
--- /dev/null
@@ -0,0 +1,342 @@
+// VirtualWire.h
+//
+// Virtual Wire implementation for Arduino and other boards
+// See the README file in this directory for documentation
+// 
+// Author: Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
+// Copyright (C) 2008 Mike McCauley
+// $Id: VirtualWire.h,v 1.10 2013/08/06 23:43:41 mikem Exp mikem $
+
+/// \mainpage VirtualWire library for Arduino and other boards
+///
+/// This is the VirtualWire library.
+///
+/// VirtualWire is an library for Arduino, Maple and others that provides features to send short
+/// messages, without addressing, retransmit or acknowledgment, a bit like UDP
+/// over wireless, using ASK (amplitude shift keying). Supports a number of
+/// inexpensive radio transmitters and receivers. All that is required is
+/// transmit data, receive data and (for transmitters, optionally) a PTT
+/// transmitter enable. Can also be used over various analog connections (not just a data radio), 
+/// such as the audio channel of an A/V sender
+///
+/// It is intended to be compatible with the RF Monolithics (www.rfm.com)
+/// Virtual Wire protocol, but this has not been tested.
+///
+/// Does not use the Arduino UART. Messages are sent with a training preamble,
+/// message length and checksum. Messages are sent with 4-to-6 bit encoding
+/// for good DC balance, and a CRC checksum for message integrity.
+///
+/// Why not just use a UART connected directly to the
+/// transmitter/receiver? As discussed in the RFM documentation, ASK receivers
+/// require a burst of training pulses to synchronize the transmitter and
+/// receiver, and also requires good balance between 0s and 1s in the message
+/// stream in order to maintain the DC balance of the message. UARTs do not
+/// provide these. They work a bit with ASK wireless, but not as well as this
+/// code.
+///
+/// This library provides classes for 
+/// - VirtualWire: unaddressed, unreliable messages
+///
+/// Example Arduino programs are included to show the main modes of use.
+///
+/// The version of the package that this documentation refers to can be downloaded 
+/// from http://www.airspayce.com/mikem/arduino/VirtualWire/VirtualWire-1.19.zip
+/// You can find the latest version at http://www.airspayce.com/mikem/arduino/VirtualWire
+///
+/// You can also find online help and disussion at http://groups.google.com/group/virtualwire
+/// Please use that group for all questions and discussions on this topic. 
+/// Do not contact the author directly, unless it is to discuss commercial licensing.
+///
+/// \par Supported Hardware
+/// A range of communications hardware is supported. The ones listed below are
+/// available in common retail outlets in Australian and other countries for
+/// under $10 per unit. Many other modules may also work with this software.
+/// Runs on ATmega8/168 (Arduino Diecimila, Uno etc) and ATmega328 and possibly
+/// others. Also runs on on Energia with MSP430G2553 / G2452 and Arduino with 
+/// ATMega328 (courtesy Yannick DEVOS - XV4Y), but untested by us.
+/// It also runs on Teensy 3.0 (courtesy of Paul Stoffregen), but untested by us.
+/// Also compiles and runs on ATtiny85 in Arduino environment, courtesy r4z0r7o3.
+/// Also compiles on maple-ide-v0.0.12, and runs on Maple, flymaple 1.1 etc.
+///
+/// - Receivers
+///  - RX-B1 (433.92MHz) (also known as ST-RX04-ASK)
+/// - Transmitters: 
+///  - TX-C1 (433.92MHz)
+/// - Transceivers
+///  - DR3100 (433.92MHz)
+///
+/// For testing purposes you can connect 2 VirtualWire instances directly, by
+/// connecting pin 12 of one to 11 of the other and vice versa, like this for a duplex connection:
+///
+/// <code>
+/// Arduino 1         wires         Arduino 1
+///  D11-----------------------------D12
+///  D12-----------------------------D11
+///  GND-----------------------------GND
+/// </code>
+///
+/// You can also connect 2 VirtualWire instances over a suitable analog
+/// transmitter/receiver, such as the audio channel of an A/V transmitter/receiver. You may need
+/// buffers at each end of the connection to convert the 0-5V digital output to a suitable analog voltage.
+///
+/// \par Installation
+/// To install, unzip the library into the libraries sub-directory of your
+/// Arduino application directory. Then launch the Arduino environment; you
+/// should see the library in the Sketch->Import Library menu, and example
+/// code in
+/// File->Sketchbook->Examples->VirtualWire menu.
+///
+/// \par Open Source Licensing GPL V2
+///
+/// This is the appropriate option if you want to share the source code of your
+/// application with everyone you distribute it to, and you also want to give them
+/// the right to share who uses it. If you wish to use this software under Open
+/// Source Licensing, you must contribute all your source code to the open source
+/// community in accordance with the GPL Version 2 when your application is
+/// distributed. See http://www.gnu.org/copyleft/gpl.html
+/// 
+/// \par Commercial Licensing
+///
+/// This is the appropriate option if you are creating proprietary applications
+/// and you are not prepared to distribute and share the source code of your
+/// application. Contact info@airspayce.com for details.
+///
+/// \par Revision History
+/// \version 1.0 Original release
+/// 
+/// \version 1.1 2008-06-24
+///    Now can compile for atmega8
+///    Reported by creatrope
+/// \version 1.2 2009-03-30
+///    Fixed a problem that prevented compiling with arduino-0015
+///    Reported by Jaime Castro
+/// \version 1.3 2009-04-01
+///    Fixed a compatibility problem with ATMEGA328 of the new arduino
+///    Now use SIGNAL(TIMER1_COMPA_vect) instead of ISR(SIG_OUTPUT_COMPARE1A)
+///    as discussed in
+///    http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237714550/11
+///    and reported by Jaime Castro.
+/// \version 1.4 2010-01-29
+///    Added vx_tx_active(), suggested by Alan Burlison.
+/// \version 1.5 2011-09-09
+///    Added vx_tx_active() function.
+/// \version 1.6 2012-01-10
+///    Fixed a problem where the receiver was always reenabled after
+///    transmission. Reported by David Bath
+/// \version 1.9 2012-02-07 Documentation updates
+///    Documentation updates
+/// \version 1.10 Updated CHANGES file with changes since 1.4.
+/// \version 1.11 Converted documentation to Doxygen. Moved CHANGES log to this version history.
+///     Ensure vw_rx_pin is not accessed unless receiver is enabled
+/// \version 1.12 Compiles and runs on on Energia with MSP430G2553 / G2452 and Arduino with ATMega328. 
+///     Patches contributed by Yannick DEVOS - XV4Y
+/// \version 1.13 util/crc16.h needed for compiling on  Energia with MSP430G2553 / G2452 was accidentally
+///     left out of the distribution
+/// \version 1.14 Added support ATtiny85 on Arduino, patch provided by r4z0r7o3.
+/// \version 1.15 Updated author and distribution location details to airspayce.com
+/// \version 1.16 Added support for Teensy 3.0, contributed by Paul Stoffregen.
+/// \version 1.17 Increase default MAX_MESSAGE_LENGTH to 80. Added vw_get_rx_good() and vw_get_rx_bad()
+///               functions.
+/// \version 1.18 Added support for Maple, Flymaple etc with STM32F103RE processor using timer 1.
+///               Tested with Flymaple 1.1 and maple-ide-v0.0.12
+/// \version 1.19 Added new function vw_rx_inverted(), to allow the incoming RX to be inverted (normally high).
+///               Minor improvements to timer setup for Maple. Name vw_tx_active() changed from incorrect
+///               vx_tx_active()
+///
+/// \par Implementation Details
+/// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
+///
+/// \par Performance
+/// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
+///
+/// \par Connections
+/// See: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
+///
+/// \file VirtualWire.h
+/// \brief VirtualWire API
+///
+/// To use the VirtualWire library, you must have
+/// \code
+/// #include <VirtualWire.h>
+/// \endcode
+/// At the top of your sketch.
+/// 
+
+#ifndef VirtualWire_h
+#define VirtualWire_h
+
+#include <stdlib.h>
+#if defined(ARDUINO)
+ #if ARDUINO >= 100
+  #include <Arduino.h>
+ #else
+  #include <wiring.h>
+ #endif
+#elif defined(__MSP430G2452__) || defined(__MSP430G2553__) // LaunchPad specific
+ #include "legacymsp430.h"
+ #include "Energia.h"
+#elif defined(MCU_STM32F103RE) // Maple etc
+ #include <wirish.h>
+ #include <string.h>
+ #include <stdint.h>
+// Defines which timer to use on Maple
+#define MAPLE_TIMER 1
+#else // error
+ #error Platform not defined
+#endif
+
+// These defs cause trouble on some versions of Arduino
+#undef abs
+#undef double
+#undef round
+
+/// Maximum number of bytes in a message, counting the byte count and FCS
+#define VW_MAX_MESSAGE_LEN 80
+
+/// The maximum payload length
+#define VW_MAX_PAYLOAD VW_MAX_MESSAGE_LEN-3
+
+/// The size of the receiver ramp. Ramp wraps modulu this number
+#define VW_RX_RAMP_LEN 160
+
+/// Number of samples per bit
+#define VW_RX_SAMPLES_PER_BIT 8
+
+// Ramp adjustment parameters
+// Standard is if a transition occurs before VW_RAMP_TRANSITION (80) in the ramp,
+// the ramp is retarded by adding VW_RAMP_INC_RETARD (11)
+// else by adding VW_RAMP_INC_ADVANCE (29)
+// If there is no transition it is adjusted by VW_RAMP_INC (20)
+/// Internal ramp adjustment parameter
+#define VW_RAMP_INC (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
+/// Internal ramp adjustment parameter
+#define VW_RAMP_TRANSITION VW_RX_RAMP_LEN/2
+/// Internal ramp adjustment parameter
+#define VW_RAMP_ADJUST 9
+/// Internal ramp adjustment parameter
+#define VW_RAMP_INC_RETARD (VW_RAMP_INC-VW_RAMP_ADJUST)
+/// Internal ramp adjustment parameter
+#define VW_RAMP_INC_ADVANCE (VW_RAMP_INC+VW_RAMP_ADJUST)
+
+/// Outgoing message bits grouped as 6-bit words
+/// 36 alternating 1/0 bits, followed by 12 bits of start symbol
+/// Followed immediately by the 4-6 bit encoded byte count, 
+/// message buffer and 2 byte FCS
+/// Each byte from the byte count on is translated into 2x6-bit words
+/// Caution, each symbol is transmitted LSBit first, 
+/// but each byte is transmitted high nybble first
+#define VW_HEADER_LEN 8
+
+// Cant really do this as a real C++ class, since we need to have 
+// an ISR
+extern "C"
+{
+    /// Set the digital IO pin to be for transmit data. 
+    /// This pin will only be accessed if
+    /// the transmitter is enabled
+    /// \param[in] pin The Arduino pin number for transmitting data. Defaults to 12.
+    extern void vw_set_tx_pin(uint8_t pin);
+
+    /// Set the digital IO pin to be for receive data.
+    /// This pin will only be accessed if
+    /// the receiver is enabled
+    /// \param[in] pin The Arduino pin number for receiving data. Defaults to 11.
+    extern void vw_set_rx_pin(uint8_t pin);
+
+    /// By default the RX pin is expected to be low when idle, and to pulse high 
+    /// for each data pulse.
+    /// This flag forces it to be inverted. This may be necessary if your transport medium
+    /// inverts the logic of your signal, such as happens with some types of A/V tramsmitter.
+    /// \param[in] inverted True to invert sense of receiver input
+    extern void vw_set_rx_inverted(uint8_t inverted);
+
+    // Set the digital IO pin to enable the transmitter (press to talk, PTT)'
+    /// This pin will only be accessed if
+    /// the transmitter is enabled
+    /// \param[in] pin The Arduino pin number to enable the transmitter. Defaults to 10.
+    extern void vw_set_ptt_pin(uint8_t pin);
+
+    /// By default the PTT pin goes high when the transmitter is enabled.
+    /// This flag forces it low when the transmitter is enabled.
+    /// \param[in] inverted True to invert PTT
+    extern void vw_set_ptt_inverted(uint8_t inverted);
+
+    /// Initialise the VirtualWire software, to operate at speed bits per second
+    /// Call this one in your setup() after any vw_set_* calls
+    /// Must call vw_rx_start() before you will get any messages
+    /// \param[in] speed Desired speed in bits per second
+    extern void vw_setup(uint16_t speed);
+
+    /// Start the Phase Locked Loop listening to the receiver
+    /// Must do this before you can receive any messages
+    /// When a message is available (good checksum or not), vw_have_message();
+    /// will return true.
+    extern void vw_rx_start();
+
+    /// Stop the Phase Locked Loop listening to the receiver
+    /// No messages will be received until vw_rx_start() is called again
+    /// Saves interrupt processing cycles
+    extern void vw_rx_stop();
+
+    /// Returns the state of the
+    /// transmitter
+    /// \return true if the transmitter is active else false
+    extern uint8_t vw_tx_active();
+
+    /// Block until the transmitter is idle
+    /// then returns
+    extern void vw_wait_tx();
+
+    /// Block until a message is available
+    /// then returns
+    extern void vw_wait_rx();
+
+    /// Block until a message is available or for a max time
+    /// \param[in] milliseconds Maximum time to wait in milliseconds.
+    /// \return true if a message is available, false if the wait timed out.
+    extern uint8_t vw_wait_rx_max(unsigned long milliseconds);
+
+    /// Send a message with the given length. Returns almost immediately,
+    /// and message will be sent at the right timing by interrupts
+    /// \param[in] buf Pointer to the data to transmit
+    /// \param[in] len Number of octetes to transmit
+    /// \return true if the message was accepted for transmission, false if the message is too long (>VW_MAX_MESSAGE_LEN - 3)
+    extern uint8_t vw_send(uint8_t* buf, uint8_t len);
+
+    /// Returns true if an unread message is available
+    /// \return true if a message is available to read
+    extern uint8_t vw_have_message();
+
+    /// If a message is available (good checksum or not), copies
+    /// up to *len octets to buf.
+    /// \param[in] buf Pointer to location to save the read data (must be at least *len bytes.
+    /// \param[in,out] len Available space in buf. Will be set to the actual number of octets read
+    /// \return true if there was a message and the checksum was good
+    extern uint8_t vw_get_message(uint8_t* buf, uint8_t* len);
+
+    /// Returns the count of good messages received
+    /// Caution,: this is an 8 bit count and can easily overflow
+    /// \return Count of good messages received
+    extern uint8_t vw_get_rx_good();
+
+    /// Returns the count of bad messages received, ie
+    /// messages with bogus lengths, indicating corruption
+    /// or lost octets.
+    /// Caution,: this is an 8 bit count and can easily overflow
+    /// \return Count of bad messages received
+    extern uint8_t vw_get_rx_bad();
+}
+
+/// @example client.pde
+/// Client side of simple client/server pair using VirtualWire
+
+/// @example server.pde
+/// Server side of simple client/server pair using VirtualWire
+
+/// @example transmitter.pde
+/// Transmitter side of simple one-way transmitter->receiver pair using VirtualWire
+
+/// @example receiver.pde
+/// Transmitter side of simple one-way transmitter->receiver pair using VirtualWire
+
+#endif
diff --git a/libraries/VirtualWire/examples/client/client.pde b/libraries/VirtualWire/examples/client/client.pde
new file mode 100644 (file)
index 0000000..018cb01
--- /dev/null
@@ -0,0 +1,59 @@
+// client.pde
+//
+// Simple example of how to use VirtualWire to send and receive messages
+// with a DR3100 module.
+// Send a message to another arduino running the 'server' example, which
+// should send a reply, which we will check
+//
+// See VirtualWire.h for detailed API docs
+// Author: Mike McCauley (mikem@airspayce.com)
+// Copyright (C) 2008 Mike McCauley
+// $Id: client.pde,v 1.1 2008/04/20 09:24:17 mikem Exp $
+
+#include <VirtualWire.h>
+
+void setup()
+{
+    Serial.begin(9600);        // Debugging only
+    Serial.println("setup");
+
+    // Initialise the IO and ISR
+    vw_set_ptt_inverted(true); // Required for DR3100
+    vw_setup(2000);     // Bits per sec
+    vw_rx_start();       // Start the receiver PLL running
+}
+
+void loop()
+{
+    const char *msg = "hello";
+    uint8_t buf[VW_MAX_MESSAGE_LEN];
+    uint8_t buflen = VW_MAX_MESSAGE_LEN;
+
+    digitalWrite(13, true); // Flash a light to show transmitting
+    vw_send((uint8_t *)msg, strlen(msg));
+    vw_wait_tx(); // Wait until the whole message is gone
+    Serial.println("Sent");
+    digitalWrite(13, false);
+
+    // Wait at most 200ms for a reply
+    if (vw_wait_rx_max(200))
+    {
+       if (vw_get_message(buf, &buflen)) // Non-blocking
+       {
+           int i;
+           
+           // Message with a good checksum received, dump it.
+           Serial.print("Got: ");
+           
+           for (i = 0; i < buflen; i++)
+           {
+               Serial.print(buf[i], HEX);
+               Serial.print(" ");
+           }
+           Serial.println("");
+       }
+    }
+    else
+       Serial.println("Timout");
+       
+}
diff --git a/libraries/VirtualWire/examples/receiver/receiver.pde b/libraries/VirtualWire/examples/receiver/receiver.pde
new file mode 100644 (file)
index 0000000..a5cb420
--- /dev/null
@@ -0,0 +1,46 @@
+// receiver.pde
+//
+// Simple example of how to use VirtualWire to receive messages
+// Implements a simplex (one-way) receiver with an Rx-B1 module
+//
+// See VirtualWire.h for detailed API docs
+// Author: Mike McCauley (mikem@airspayce.com)
+// Copyright (C) 2008 Mike McCauley
+// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
+
+#include <VirtualWire.h>
+
+void setup()
+{
+    Serial.begin(9600);        // Debugging only
+    Serial.println("setup");
+
+    // Initialise the IO and ISR
+    vw_set_ptt_inverted(true); // Required for DR3100
+    vw_setup(2000);     // Bits per sec
+
+    vw_rx_start();       // Start the receiver PLL running
+}
+
+void loop()
+{
+    uint8_t buf[VW_MAX_MESSAGE_LEN];
+    uint8_t buflen = VW_MAX_MESSAGE_LEN;
+
+    if (vw_get_message(buf, &buflen)) // Non-blocking
+    {
+       int i;
+
+        digitalWrite(13, true); // Flash a light to show received good message
+       // Message with a good checksum received, dump it.
+       Serial.print("Got: ");
+       
+       for (i = 0; i < buflen; i++)
+       {
+           Serial.print(buf[i], HEX);
+           Serial.print(" ");
+       }
+       Serial.println("");
+        digitalWrite(13, false);
+    }
+}
diff --git a/libraries/VirtualWire/examples/server/server.pde b/libraries/VirtualWire/examples/server/server.pde
new file mode 100644 (file)
index 0000000..ead67f0
--- /dev/null
@@ -0,0 +1,55 @@
+// server.pde
+//
+// Simple example of how to use VirtualWire to send and receive messages
+// with a DR3100 module.
+// Wait for a message from another arduino running the 'client' example,
+// and send a reply.
+// You can use this as the basis of a remote control/remote sensing system
+//
+// See VirtualWire.h for detailed API docs
+// Author: Mike McCauley (mikem@airspayce.com)
+// Copyright (C) 2008 Mike McCauley
+// $Id: server.pde,v 1.1 2008/04/20 09:24:17 mikem Exp $
+
+#include <VirtualWire.h>
+
+void setup()
+{
+    Serial.begin(9600);        // Debugging only
+    Serial.println("setup");
+
+    // Initialise the IO and ISR
+    vw_set_ptt_inverted(true); // Required for DR3100
+    vw_setup(2000);     // Bits per sec
+    vw_rx_start();       // Start the receiver PLL running
+}
+
+void loop()
+{
+    const char *msg = "hello";
+    uint8_t buf[VW_MAX_MESSAGE_LEN];
+    uint8_t buflen = VW_MAX_MESSAGE_LEN;
+
+    // Wait for a message
+    vw_wait_rx();
+    if (vw_get_message(buf, &buflen)) // Non-blocking
+    {
+       int i;
+       const char *msg = "goodbye";
+
+        digitalWrite(13, true); // Flash a light to show received good message
+       // Message with a good checksum received, dump it.
+       Serial.print("Got: ");
+       
+       for (i = 0; i < buflen; i++)
+       {
+           Serial.print(buf[i], HEX);
+           Serial.print(" ");
+       }
+       Serial.println("");
+
+       // Send a reply
+       vw_send((uint8_t *)msg, strlen(msg));
+        digitalWrite(13, false);
+    }
+}
diff --git a/libraries/VirtualWire/examples/transmitter/transmitter.pde b/libraries/VirtualWire/examples/transmitter/transmitter.pde
new file mode 100644 (file)
index 0000000..dd8d4d2
--- /dev/null
@@ -0,0 +1,32 @@
+// transmitter.pde
+//
+// Simple example of how to use VirtualWire to transmit messages
+// Implements a simplex (one-way) transmitter with an TX-C1 module
+//
+// See VirtualWire.h for detailed API docs
+// Author: Mike McCauley (mikem@airspayce.com)
+// Copyright (C) 2008 Mike McCauley
+// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
+
+#include <VirtualWire.h>
+
+void setup()
+{
+    Serial.begin(9600);          // Debugging only
+    Serial.println("setup");
+
+    // Initialise the IO and ISR
+    vw_set_ptt_inverted(true); // Required for DR3100
+    vw_setup(2000);     // Bits per sec
+}
+
+void loop()
+{
+    const char *msg = "hello";
+
+    digitalWrite(13, true); // Flash a light to show transmitting
+    vw_send((uint8_t *)msg, strlen(msg));
+    vw_wait_tx(); // Wait until the whole message is gone
+    digitalWrite(13, false);
+    delay(200);
+}
diff --git a/libraries/VirtualWire/keywords.txt b/libraries/VirtualWire/keywords.txt
new file mode 100644 (file)
index 0000000..1d8a5bf
--- /dev/null
@@ -0,0 +1,2 @@
+VirtualWire    KEYWORD1
+
diff --git a/libraries/VirtualWire/util/crc16.h b/libraries/VirtualWire/util/crc16.h
new file mode 100644 (file)
index 0000000..18c173c
--- /dev/null
@@ -0,0 +1,103 @@
+/* Copyright (c) 2002, 2003, 2004  Marek Michalkiewicz
+   Copyright (c) 2005, 2007 Joerg Wunsch
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+//     Port to Energia / MPS430 by Yannick DEVOS XV4Y - (c) 2013
+//     http://xv4y.radioclub.asia/
+//     
+
+/* $Id: crc16.h 2136 2010-06-08 12:03:38Z joerg_wunsch $ */
+
+#ifndef _UTIL_CRC16_H_
+#define _UTIL_CRC16_H_
+
+#include <stdint.h>
+
+#define lo8(x) ((x)&0xff) 
+#define hi8(x) ((x)>>8)
+
+    uint16_t crc16_update(uint16_t crc, uint8_t a)
+    {
+       int i;
+
+       crc ^= a;
+       for (i = 0; i < 8; ++i)
+       {
+           if (crc & 1)
+               crc = (crc >> 1) ^ 0xA001;
+           else
+               crc = (crc >> 1);
+       }
+
+       return crc;
+    }
+
+    uint16_t crc_xmodem_update (uint16_t crc, uint8_t data)
+    {
+        int i;
+
+        crc = crc ^ ((uint16_t)data << 8);
+        for (i=0; i<8; i++)
+        {
+            if (crc & 0x8000)
+                crc = (crc << 1) ^ 0x1021;
+            else
+                crc <<= 1;
+        }
+
+        return crc;
+    }
+    uint16_t _crc_ccitt_update (uint16_t crc, uint8_t data)
+    {
+        data ^= lo8 (crc);
+        data ^= data << 4;
+
+        return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4) 
+                ^ ((uint16_t)data << 3));
+    }
+
+    uint8_t _crc_ibutton_update(uint8_t crc, uint8_t data)
+    {
+       uint8_t i;
+
+       crc = crc ^ data;
+       for (i = 0; i < 8; i++)
+       {
+           if (crc & 0x01)
+               crc = (crc >> 1) ^ 0x8C;
+           else
+               crc >>= 1;
+       }
+
+       return crc;
+    }
+
+
+#endif /* _UTIL_CRC16_H_ */