1// VirtualWire.cpp 2// 3// Virtual Wire implementation for Arduino 4// See the README file in this directory fdor documentation 5// See also 6// ASH Transceiver Software Designer's Guide of 2002.08.07 7// http://www.rfm.com/products/apnotes/tr_swg05.pdf 8// 9// Changes: 10// 1.5 2008-05-25: fixed a bug that could prevent messages with certain 11// bytes sequences being received (false message start detected) 12// 1.6 2011-09-10: Patch from David Bath to prevent unconditional reenabling of the receiver 13// at end of transmission. 14// 15// Author: Mike McCauley (mikem@airspayce.com) 16// Copyright (C) 2008 Mike McCauley 17// $Id: VirtualWire.cpp,v 1.9 2013/02/14 22:02:11 mikem Exp mikem $ 18 19 20#if defined(ARDUINO) 21#if (ARDUINO < 100) 22#include"WProgram.h" 23#endif 24#elif defined(__MSP430G2452__) || defined(__MSP430G2553__)// LaunchPad specific 25#include"legacymsp430.h" 26#include"Energia.h" 27#else// error 28#error Platform not defined 29#endif 30 31#include"VirtualWire.h" 32#include <util/crc16.h> 33 34 35static uint8_t vw_tx_buf[(VW_MAX_MESSAGE_LEN *2) + VW_HEADER_LEN] 36= {0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x38,0x2c}; 37 38// Number of symbols in vw_tx_buf to be sent; 39static uint8_t vw_tx_len =0; 40 41// Index of the next symbol to send. Ranges from 0 to vw_tx_len 42static uint8_t vw_tx_index =0; 43 44// Bit number of next bit to send 45static uint8_t vw_tx_bit =0; 46 47// Sample number for the transmitter. Runs 0 to 7 during one bit interval 48static uint8_t vw_tx_sample =0; 49 50// Flag to indicated the transmitter is active 51staticvolatileuint8_t vw_tx_enabled =0; 52 53// Total number of messages sent 54static uint16_t vw_tx_msg_count =0; 55 56// The digital IO pin number of the press to talk, enables the transmitter hardware 57static uint8_t vw_ptt_pin =10; 58static uint8_t vw_ptt_inverted =0; 59 60// The digital IO pin number of the receiver data 61static uint8_t vw_rx_pin =11; 62 63// The digital IO pin number of the transmitter data 64static uint8_t vw_tx_pin =12; 65 66// Current receiver sample 67static uint8_t vw_rx_sample =0; 68 69// Last receiver sample 70static uint8_t vw_rx_last_sample =0; 71 72// PLL ramp, varies between 0 and VW_RX_RAMP_LEN-1 (159) over 73// VW_RX_SAMPLES_PER_BIT (8) samples per nominal bit time. 74// When the PLL is synchronised, bit transitions happen at about the 75// 0 mark. 76static uint8_t vw_rx_pll_ramp =0; 77 78// This is the integrate and dump integral. If there are <5 0 samples in the PLL cycle 79// the bit is declared a 0, else a 1 80static uint8_t vw_rx_integrator =0; 81 82// Flag indictate if we have seen the start symbol of a new message and are 83// in the processes of reading and decoding it 84static uint8_t vw_rx_active =0; 85 86// Flag to indicate that a new message is available 87staticvolatileuint8_t vw_rx_done =0; 88 89// Flag to indicate the receiver PLL is to run 90static uint8_t vw_rx_enabled =0; 91 92// Last 12 bits received, so we can look for the start symbol 93static uint16_t vw_rx_bits =0; 94 95// How many bits of message we have received. Ranges from 0 to 12 96static uint8_t vw_rx_bit_count =0; 97 98// The incoming message buffer 99static uint8_t vw_rx_buf[VW_MAX_MESSAGE_LEN]; 100 101// The incoming message expected length 102static uint8_t vw_rx_count =0; 103 104// The incoming message buffer length received so far 105staticvolatileuint8_t vw_rx_len =0; 106 107// Number of bad messages received and dropped due to bad lengths 108static uint8_t vw_rx_bad =0; 109 110// Number of good messages received 111static uint8_t vw_rx_good =0; 112 113// 4 bit to 6 bit symbol converter table 114// Used to convert the high and low nybbles of the transmitted data 115// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s 116// with at most 3 consecutive identical bits 117static uint8_t symbols[] = 118{ 1190xd,0xe,0x13,0x15,0x16,0x19,0x1a,0x1c, 1200x23,0x25,0x26,0x29,0x2a,0x2c,0x32,0x34 121}; 122 123// Cant really do this as a real C++ class, since we need to have 124// an ISR 125extern"C" 126{ 127 128// Compute CRC over count bytes. 129// This should only be ever called at user level, not interrupt level 130uint16_tvw_crc(uint8_t*ptr,uint8_t count) 131{ 132uint16_t crc =0xffff; 133 134while(count-- >0) 135 crc =_crc_ccitt_update(crc, *ptr++); 136return crc; 137} 138 139// Convert a 6 bit encoded symbol into its 4 bit decoded equivalent 140uint8_tvw_symbol_6to4(uint8_t symbol) 141{ 142uint8_t i; 143 144// Linear search :-( Could have a 64 byte reverse lookup table? 145for(i =0; i <16; i++) 146if(symbol == symbols[i])return i; 147return0;// Not found 148} 149 150// Set the output pin number for transmitter data 151voidvw_set_tx_pin(uint8_t pin) 152{ 153 vw_tx_pin = pin; 154} 155 156// Set the pin number for input receiver data 157voidvw_set_rx_pin(uint8_t pin) 158{ 159 vw_rx_pin = pin; 160} 161 162// Set the output pin number for transmitter PTT enable 163voidvw_set_ptt_pin(uint8_t pin) 164{ 165 vw_ptt_pin = pin; 166} 167 168// Set the ptt pin inverted (low to transmit) 169voidvw_set_ptt_inverted(uint8_t inverted) 170{ 171 vw_ptt_inverted = inverted; 172} 173 174// Called 8 times per bit period 175// Phase locked loop tries to synchronise with the transmitter so that bit 176// transitions occur at about the time vw_rx_pll_ramp is 0; 177// Then the average is computed over each bit period to deduce the bit value 178voidvw_pll() 179{ 180// Integrate each sample 181if(vw_rx_sample) 182 vw_rx_integrator++; 183 184if(vw_rx_sample != vw_rx_last_sample) 185{ 186// Transition, advance if ramp > 80, retard if < 80 187 vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION) 188? VW_RAMP_INC_RETARD 189: VW_RAMP_INC_ADVANCE); 190 vw_rx_last_sample = vw_rx_sample; 191} 192else 193{ 194// No transition 195// Advance ramp by standard 20 (== 160/8 samples) 196 vw_rx_pll_ramp += VW_RAMP_INC; 197} 198if(vw_rx_pll_ramp >= VW_RX_RAMP_LEN) 199{ 200// Add this to the 12th bit of vw_rx_bits, LSB first 201// The last 12 bits are kept 202 vw_rx_bits >>=1; 203 204// Check the integrator to see how many samples in this cycle were high. 205// If < 5 out of 8, then its declared a 0 bit, else a 1; 206if(vw_rx_integrator >=5) 207 vw_rx_bits |=0x800; 208 209 vw_rx_pll_ramp -= VW_RX_RAMP_LEN; 210 vw_rx_integrator =0;// Clear the integral for the next cycle 211 212if(vw_rx_active) 213{ 214// We have the start symbol and now we are collecting message bits, 215// 6 per symbol, each which has to be decoded to 4 bits 216if(++vw_rx_bit_count >=12) 217{ 218// Have 12 bits of encoded message == 1 byte encoded 219// Decode as 2 lots of 6 bits into 2 lots of 4 bits 220// The 6 lsbits are the high nybble 221uint8_t this_byte = 222(vw_symbol_6to4(vw_rx_bits &0x3f)) <<4 223|vw_symbol_6to4(vw_rx_bits >>6); 224 225// The first decoded byte is the byte count of the following message 226// the count includes the byte count and the 2 trailing FCS bytes 227// REVISIT: may also include the ACK flag at 0x40 228if(vw_rx_len ==0) 229{ 230// The first byte is the byte count 231// Check it for sensibility. It cant be less than 4, since it 232// includes the bytes count itself and the 2 byte FCS 233 vw_rx_count = this_byte; 234if(vw_rx_count <4|| vw_rx_count > VW_MAX_MESSAGE_LEN) 235{ 236// Stupid message length, drop the whole thing 237 vw_rx_active =false; 238 vw_rx_bad++; 239return; 240} 241} 242 vw_rx_buf[vw_rx_len++] = this_byte; 243 244if(vw_rx_len >= vw_rx_count) 245{ 246// Got all the bytes now 247 vw_rx_active =false; 248 vw_rx_good++; 249 vw_rx_done =true;// Better come get it before the next one starts 250} 251 vw_rx_bit_count =0; 252} 253} 254// Not in a message, see if we have a start symbol 255else if(vw_rx_bits ==0xb38) 256{ 257// Have start symbol, start collecting message 258 vw_rx_active =true; 259 vw_rx_bit_count =0; 260 vw_rx_len =0; 261 vw_rx_done =false;// Too bad if you missed the last message 262} 263} 264} 265 266// Common function for setting timer ticks @ prescaler values for speed 267// Returns prescaler index into {0, 1, 8, 64, 256, 1024} array 268// and sets nticks to compare-match value if lower than max_ticks 269// returns 0 & nticks = 0 on fault 270static uint8_t_timer_calc(uint16_t speed,uint16_t max_ticks,uint16_t*nticks) 271{ 272// Clock divider (prescaler) values - 0/3333: error flag 273uint16_t prescalers[] = {0,1,8,64,256,1024,3333}; 274uint8_t prescaler=0;// index into array & return bit value 275unsigned long ulticks;// calculate by ntick overflow 276 277// Div-by-zero protection 278if(speed ==0) 279{ 280// signal fault 281*nticks =0; 282return0; 283} 284 285// test increasing prescaler (divisor), decreasing ulticks until no overflow 286for(prescaler=1; prescaler <7; prescaler +=1) 287{ 288// Amount of time per CPU clock tick (in seconds) 289float clock_time = (1.0/ (float(F_CPU) /float(prescalers[prescaler]))); 290// Fraction of second needed to xmit one bit 291float bit_time = ((1.0/float(speed)) /8.0); 292// number of prescaled ticks needed to handle bit time @ speed 293 ulticks =long(bit_time / clock_time); 294// Test if ulticks fits in nticks bitwidth (with 1-tick safety margin) 295if((ulticks >1) && (ulticks < max_ticks)) 296{ 297break;// found prescaler 298} 299// Won't fit, check with next prescaler value 300} 301 302// Check for error 303if((prescaler ==6) || (ulticks <2) || (ulticks > max_ticks)) 304{ 305// signal fault 306*nticks =0; 307return0; 308} 309 310*nticks = ulticks; 311return prescaler; 312} 313 314#if defined(__arm__) && defined(CORE_TEENSY) 315// This allows the AVR interrupt code below to be run from an 316// IntervalTimer object. It must be above vw_setup(), so the 317// the TIMER1_COMPA_vect function name is defined. 318#ifdef SIGNAL 319#undef SIGNAL 320#endif 321#define SIGNAL(f) void f(void) 322#ifdef TIMER1_COMPA_vect 323#undef TIMER1_COMPA_vect 324#endif 325voidTIMER1_COMPA_vect(void); 326#endif 327 328 329// Speed is in bits per sec RF rate 330#if defined(__MSP430G2452__) || defined(__MSP430G2553__)// LaunchPad specific 331voidvw_setup(uint16_t speed) 332{ 333// Calculate the counter overflow count based on the required bit speed 334// and CPU clock rate 335uint16_t ocr1a = (F_CPU /8UL) / speed; 336 337// This code is for Energia/MSP430 338 TA0CCR0 = ocr1a;// Ticks for 62,5 us 339 TA0CTL = TASSEL_2 + MC_1;// SMCLK, up mode 340 TA0CCTL0 |= CCIE;// CCR0 interrupt enabled 341 342// Set up digital IO pins 343pinMode(vw_tx_pin, OUTPUT); 344pinMode(vw_rx_pin, INPUT); 345pinMode(vw_ptt_pin, OUTPUT); 346digitalWrite(vw_ptt_pin, vw_ptt_inverted); 347} 348 349#elif defined (ARDUINO)// Arduino specific 350voidvw_setup(uint16_t speed) 351{ 352uint16_t nticks;// number of prescaled ticks needed 353uint8_t prescaler;// Bit values for CS0[2:0] 354 355#ifdef __AVR_ATtiny85__ 356// figure out prescaler value and counter match value 357 prescaler =_timer_calc(speed, (uint8_t)-1, &nticks); 358if(!prescaler) 359{ 360return;// fault 361} 362 363 TCCR0A =0; 364 TCCR0A =_BV(WGM01);// Turn on CTC mode / Output Compare pins disconnected 365 366// convert prescaler index to TCCRnB prescaler bits CS00, CS01, CS02 367 TCCR0B =0; 368 TCCR0B = prescaler;// set CS00, CS01, CS02 (other bits not needed) 369 370// Number of ticks to count before firing interrupt 371 OCR0A =uint8_t(nticks); 372 373// Set mask to fire interrupt when OCF0A bit is set in TIFR0 374 TIMSK |=_BV(OCIE0A); 375 376#elif defined(__arm__) && defined(CORE_TEENSY) 377// on Teensy 3.0 (32 bit ARM), use an interval timer 378 IntervalTimer *t =newIntervalTimer(); 379 t->begin(TIMER1_COMPA_vect,125000.0/ (float)(speed)); 380 381#else// ARDUINO 382// This is the path for most Arduinos 383// figure out prescaler value and counter match value 384 prescaler =_timer_calc(speed, (uint16_t)-1, &nticks); 385if(!prescaler) 386{ 387return;// fault 388} 389 390 TCCR1A =0;// Output Compare pins disconnected 391 TCCR1B =_BV(WGM12);// Turn on CTC mode 392 393// convert prescaler index to TCCRnB prescaler bits CS10, CS11, CS12 394 TCCR1B |= prescaler; 395 396// Caution: special procedures for setting 16 bit regs 397// is handled by the compiler 398 OCR1A = nticks; 399// Enable interrupt 400#ifdef TIMSK1 401// atmega168 402 TIMSK1 |=_BV(OCIE1A); 403#else 404// others 405 TIMSK |=_BV(OCIE1A); 406#endif// TIMSK1 407 408#endif// __AVR_ATtiny85__ 409 410// Set up digital IO pins 411pinMode(vw_tx_pin, OUTPUT); 412pinMode(vw_rx_pin, INPUT); 413pinMode(vw_ptt_pin, OUTPUT); 414digitalWrite(vw_ptt_pin, vw_ptt_inverted); 415} 416 417#endif// ARDUINO 418 419// Start the transmitter, call when the tx buffer is ready to go and vw_tx_len is 420// set to the total number of symbols to send 421voidvw_tx_start() 422{ 423 vw_tx_index =0; 424 vw_tx_bit =0; 425 vw_tx_sample =0; 426 427// Enable the transmitter hardware 428digitalWrite(vw_ptt_pin,true^ vw_ptt_inverted); 429 430// Next tick interrupt will send the first bit 431 vw_tx_enabled =true; 432} 433 434// Stop the transmitter, call when all bits are sent 435voidvw_tx_stop() 436{ 437// Disable the transmitter hardware 438digitalWrite(vw_ptt_pin,false^ vw_ptt_inverted); 439digitalWrite(vw_tx_pin,false); 440 441// No more ticks for the transmitter 442 vw_tx_enabled =false; 443} 444 445// Enable the receiver. When a message becomes available, vw_rx_done flag 446// is set, and vw_wait_rx() will return. 447voidvw_rx_start() 448{ 449if(!vw_rx_enabled) 450{ 451 vw_rx_enabled =true; 452 vw_rx_active =false;// Never restart a partial message 453} 454} 455 456// Disable the receiver 457voidvw_rx_stop() 458{ 459 vw_rx_enabled =false; 460} 461 462// Return true if the transmitter is active 463uint8_tvx_tx_active() 464{ 465return vw_tx_enabled; 466} 467 468// Wait for the transmitter to become available 469// Busy-wait loop until the ISR says the message has been sent 470voidvw_wait_tx() 471{ 472while(vw_tx_enabled) 473; 474} 475 476// Wait for the receiver to get a message 477// Busy-wait loop until the ISR says a message is available 478// can then call vw_get_message() 479voidvw_wait_rx() 480{ 481while(!vw_rx_done) 482; 483} 484 485// Wait at most max milliseconds for the receiver to receive a message 486// Return the truth of whether there is a message 487uint8_tvw_wait_rx_max(unsigned long milliseconds) 488{ 489unsigned long start =millis(); 490 491while(!vw_rx_done && ((millis() - start) < milliseconds)) 492; 493return vw_rx_done; 494} 495 496// Wait until transmitter is available and encode and queue the message 497// into vw_tx_buf 498// The message is raw bytes, with no packet structure imposed 499// It is transmitted preceded a byte count and followed by 2 FCS bytes 500uint8_tvw_send(uint8_t* buf,uint8_t len) 501{ 502uint8_t i; 503uint8_t index =0; 504uint16_t crc =0xffff; 505uint8_t*p = vw_tx_buf + VW_HEADER_LEN;// start of the message area 506uint8_t count = len +3;// Added byte count and FCS to get total number of bytes 507 508if(len > VW_MAX_PAYLOAD) 509return false; 510 511// Wait for transmitter to become available 512vw_wait_tx(); 513 514// Encode the message length 515 crc =_crc_ccitt_update(crc, count); 516 p[index++] = symbols[count >>4]; 517 p[index++] = symbols[count &0xf]; 518 519// Encode the message into 6 bit symbols. Each byte is converted into 520// 2 6-bit symbols, high nybble first, low nybble second 521for(i =0; i < len; i++) 522{ 523 crc =_crc_ccitt_update(crc, buf[i]); 524 p[index++] = symbols[buf[i] >>4]; 525 p[index++] = symbols[buf[i] &0xf]; 526} 527 528// Append the fcs, 16 bits before encoding (4 6-bit symbols after encoding) 529// Caution: VW expects the _ones_complement_ of the CCITT CRC-16 as the FCS 530// VW sends FCS as low byte then hi byte 531 crc = ~crc; 532 p[index++] = symbols[(crc >>4) &0xf]; 533 p[index++] = symbols[crc &0xf]; 534 p[index++] = symbols[(crc >>12) &0xf]; 535 p[index++] = symbols[(crc >>8) &0xf]; 536 537// Total number of 6-bit symbols to send 538 vw_tx_len = index + VW_HEADER_LEN; 539 540// Start the low level interrupt handler sending symbols 541vw_tx_start(); 542 543return true; 544} 545 546// Return true if there is a message available 547uint8_tvw_have_message() 548{ 549return vw_rx_done; 550} 551 552// Get the last message received (without byte count or FCS) 553// Copy at most *len bytes, set *len to the actual number copied 554// Return true if there is a message and the FCS is OK 555uint8_tvw_get_message(uint8_t* buf,uint8_t* len) 556{ 557uint8_t rxlen; 558 559// Message available? 560if(!vw_rx_done) 561return false; 562 563// Wait until vw_rx_done is set before reading vw_rx_len 564// then remove bytecount and FCS 565 rxlen = vw_rx_len -3; 566 567// Copy message (good or bad) 568if(*len > rxlen) 569*len = rxlen; 570memcpy(buf, vw_rx_buf +1, *len); 571 572 vw_rx_done =false;// OK, got that message thanks 573 574// Check the FCS, return goodness 575return(vw_crc(vw_rx_buf, vw_rx_len) ==0xf0b8);// FCS OK? 576} 577 578// This is the interrupt service routine called when timer1 overflows 579// Its job is to output the next bit from the transmitter (every 8 calls) 580// and to call the PLL code if the receiver is enabled 581//ISR(SIG_OUTPUT_COMPARE1A) 582#if defined (ARDUINO)// Arduino specific 583 584#ifdef __AVR_ATtiny85__ 585SIGNAL(TIM0_COMPA_vect) 586#else// Assume Arduino Uno (328p or similar) 587 588SIGNAL(TIMER1_COMPA_vect) 589#endif// __AVR_ATtiny85__ 590 591{ 592if(vw_rx_enabled && !vw_tx_enabled) 593 vw_rx_sample =digitalRead(vw_rx_pin); 594 595// Do transmitter stuff first to reduce transmitter bit jitter due 596// to variable receiver processing 597if(vw_tx_enabled && vw_tx_sample++ ==0) 598{ 599// Send next bit 600// Symbols are sent LSB first 601// Finished sending the whole message? (after waiting one bit period 602// since the last bit) 603if(vw_tx_index >= vw_tx_len) 604{ 605vw_tx_stop(); 606 vw_tx_msg_count++; 607} 608else 609{ 610digitalWrite(vw_tx_pin, vw_tx_buf[vw_tx_index] & (1<< vw_tx_bit++)); 611if(vw_tx_bit >=6) 612{ 613 vw_tx_bit =0; 614 vw_tx_index++; 615} 616} 617} 618if(vw_tx_sample >7) 619 vw_tx_sample =0; 620 621if(vw_rx_enabled && !vw_tx_enabled) 622vw_pll(); 623} 624#elif defined(__MSP430G2452__) || defined(__MSP430G2553__)// LaunchPad specific 625voidvw_Int_Handler() 626{ 627if(vw_rx_enabled && !vw_tx_enabled) 628 vw_rx_sample =digitalRead(vw_rx_pin); 629 630// Do transmitter stuff first to reduce transmitter bit jitter due 631// to variable receiver processing 632if(vw_tx_enabled && vw_tx_sample++ ==0) 633{ 634// Send next bit 635// Symbols are sent LSB first 636// Finished sending the whole message? (after waiting one bit period 637// since the last bit) 638if(vw_tx_index >= vw_tx_len) 639{ 640vw_tx_stop(); 641 vw_tx_msg_count++; 642} 643else 644{ 645digitalWrite(vw_tx_pin, vw_tx_buf[vw_tx_index] & (1<< vw_tx_bit++)); 646if(vw_tx_bit >=6) 647{ 648 vw_tx_bit =0; 649 vw_tx_index++; 650} 651} 652} 653if(vw_tx_sample >7) 654 vw_tx_sample =0; 655 656if(vw_rx_enabled && !vw_tx_enabled) 657vw_pll(); 658} 659 660interrupt(TIMER0_A0_VECTOR)Timer_A_int(void) 661{ 662vw_Int_Handler(); 663}; 664 665#endif 666 667 668}