1// VirtualWire.cpp 2// 3// Virtual Wire implementation for Arduino 4// See the README file in this directory fdor documentation 5// 6// Changes: 7// 2008-05-25: fixed a bug that could prevent messages with certain 8// bytes sequences being received (false message start detected) 9// 10// Author: Mike McCauley (mikem@open.com.au) 11// Copyright (C) 2008 Mike McCauley 12// $Id: VirtualWire.cpp,v 1.4 2009/03/31 20:49:41 mikem Exp mikem $ 13 14#include"WProgram.h" 15#include"VirtualWire.h" 16#include <util/crc16.h> 17 18static uint8_t vw_tx_buf[(VW_MAX_MESSAGE_LEN *2) + VW_HEADER_LEN] 19= {0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x38,0x2c}; 20 21// Number of symbols in vw_tx_buf to be sent; 22static uint8_t vw_tx_len =0; 23 24// Index of the next symbol to send. Ranges from 0 to vw_tx_len 25static uint8_t vw_tx_index =0; 26 27// Bit number of next bit to send 28static uint8_t vw_tx_bit =0; 29 30// Sample number for the transmitter. Runs 0 to 7 during one bit interval 31static uint8_t vw_tx_sample =0; 32 33// Flag to indicated the transmitter is active 34staticvolatileuint8_t vw_tx_enabled =0; 35 36// Total number of messages sent 37static uint16_t vw_tx_msg_count =0; 38 39// The digital IO pin number of the press to talk, enables the transmitter hardware 40static uint8_t vw_ptt_pin =10; 41static uint8_t vw_ptt_inverted =0; 42 43// The digital IO pin number of the receiver data 44static uint8_t vw_rx_pin =11; 45 46// The digital IO pin number of the transmitter data 47static uint8_t vw_tx_pin =12; 48 49// Current receiver sample 50static uint8_t vw_rx_sample =0; 51 52// Last receiver sample 53static uint8_t vw_rx_last_sample =0; 54 55// PLL ramp, varies between 0 and VW_RX_RAMP_LEN-1 (159) over 56// VW_RX_SAMPLES_PER_BIT (8) samples per nominal bit time. 57// When the PLL is synchronised, bit transitions happen at about the 58// 0 mark. 59static uint8_t vw_rx_pll_ramp =0; 60 61// This is the integrate and dump integral. If there are <5 0 samples in the PLL cycle 62// the bit is declared a 0, else a 1 63static uint8_t vw_rx_integrator =0; 64 65// Flag indictate if we have seen the start symbol of a new message and are 66// in the processes of reading and decoding it 67static uint8_t vw_rx_active =0; 68 69// Flag to indicate that a new message is available 70staticvolatileuint8_t vw_rx_done =0; 71 72// Flag to indicate the receiver PLL is to run 73static uint8_t vw_rx_enabled =0; 74 75// Last 12 bits received, so we can look for the start symbol 76static uint16_t vw_rx_bits =0; 77 78// How many bits of message we have received. Ranges from 0 to 12 79static uint8_t vw_rx_bit_count =0; 80 81// The incoming message buffer 82static uint8_t vw_rx_buf[VW_MAX_MESSAGE_LEN]; 83 84// The incoming message expected length 85static uint8_t vw_rx_count =0; 86 87// The incoming message buffer length received so far 88staticvolatileuint8_t vw_rx_len =0; 89 90// Number of bad messages received and dropped due to bad lengths 91static uint8_t vw_rx_bad =0; 92 93// Number of good messages received 94static uint8_t vw_rx_good =0; 95 96// 4 bit to 6 bit symbol converter table 97// Used to convert the high and low nybbles of the transmitted data 98// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s 99// with at most 2 consecutive identical bits 100static uint8_t symbols[] = 101{ 1020xd,0xe,0x13,0x15,0x16,0x19,0x1a,0x1c, 1030x23,0x25,0x26,0x29,0x2a,0x2c,0x32,0x34 104}; 105 106// Cant really do this as a real C++ class, since we need to have 107// an ISR 108extern"C" 109{ 110 111// Compute CRC over count bytes. 112// This should only be ever called at user level, not interrupt level 113uint16_tvw_crc(uint8_t*ptr,uint8_t count) 114{ 115uint16_t crc =0xffff; 116 117while(count-- >0) 118 crc =_crc_ccitt_update(crc, *ptr++); 119return crc; 120} 121 122// Convert a 6 bit encoded symbol into its 4 bit decoded equivalent 123uint8_tvw_symbol_6to4(uint8_t symbol) 124{ 125uint8_t i; 126 127// Linear search :-( Could have a 64 byte reverse lookup table? 128for(i =0; i <16; i++) 129if(symbol == symbols[i])return i; 130return0;// Not found 131} 132 133// Set the output pin number for transmitter data 134voidvw_set_tx_pin(uint8_t pin) 135{ 136 vw_tx_pin = pin; 137} 138 139// Set the pin number for input receiver data 140voidvw_set_rx_pin(uint8_t pin) 141{ 142 vw_rx_pin = pin; 143} 144 145// Set the output pin number for transmitter PTT enable 146voidvw_set_ptt_pin(uint8_t pin) 147{ 148 vw_ptt_pin = pin; 149} 150 151// Set the ptt pin inverted (low to transmit) 152voidvw_set_ptt_inverted(uint8_t inverted) 153{ 154 vw_ptt_inverted = inverted; 155} 156 157// Called 8 times per bit period 158// Phase locked loop tries to synchronise with the transmitter so that bit 159// transitions occur at about the time vw_rx_pll_ramp is 0; 160// Then the average is computed over each bit period to deduce the bit value 161voidvw_pll() 162{ 163// Integrate each sample 164if(vw_rx_sample) 165 vw_rx_integrator++; 166 167if(vw_rx_sample != vw_rx_last_sample) 168{ 169// Transition, advance if ramp > 80, retard if < 80 170 vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION) 171? VW_RAMP_INC_RETARD 172: VW_RAMP_INC_ADVANCE); 173 vw_rx_last_sample = vw_rx_sample; 174} 175else 176{ 177// No transition 178// Advance ramp by standard 20 (== 160/8 samples) 179 vw_rx_pll_ramp += VW_RAMP_INC; 180} 181if(vw_rx_pll_ramp >= VW_RX_RAMP_LEN) 182{ 183// Add this to the 12th bit of vw_rx_bits, LSB first 184// The last 12 bits are kept 185 vw_rx_bits >>=1; 186 187// Check the integrator to see how many samples in this cycle were high. 188// If < 5 out of 8, then its declared a 0 bit, else a 1; 189if(vw_rx_integrator >=5) 190 vw_rx_bits |=0x800; 191 192 vw_rx_pll_ramp -= VW_RX_RAMP_LEN; 193 vw_rx_integrator =0;// Clear the integral for the next cycle 194 195if(vw_rx_active) 196{ 197// We have the start symbol and now we are collecting message bits, 198// 6 per symbol, each which has to be decoded to 4 bits 199if(++vw_rx_bit_count >=12) 200{ 201// Have 12 bits of encoded message == 1 byte encoded 202// Decode as 2 lots of 6 bits into 2 lots of 4 bits 203// The 6 lsbits are the high nybble 204uint8_t this_byte = 205(vw_symbol_6to4(vw_rx_bits &0x3f)) <<4 206|vw_symbol_6to4(vw_rx_bits >>6); 207 208// The first decoded byte is the byte count of the following message 209// the count includes the byte count and the 2 trailing FCS bytes 210// REVISIT: may also include the ACK flag at 0x40 211if(vw_rx_len ==0) 212{ 213// The first byte is the byte count 214// Check it for sensibility. It cant be less than 4, since it 215// includes the bytes count itself and the 2 byte FCS 216 vw_rx_count = this_byte; 217if(vw_rx_count <4|| vw_rx_count > VW_MAX_MESSAGE_LEN) 218{ 219// Stupid message length, drop the whole thing 220 vw_rx_active =false; 221 vw_rx_bad++; 222return; 223} 224} 225 vw_rx_buf[vw_rx_len++] = this_byte; 226 227if(vw_rx_len >= vw_rx_count) 228{ 229// Got all the bytes now 230 vw_rx_active =false; 231 vw_rx_good++; 232 vw_rx_done =true;// Better come get it before the next one starts 233} 234 vw_rx_bit_count =0; 235} 236} 237// Not in a message, see if we have a start symbol 238else if(vw_rx_bits ==0xb38) 239{ 240// Have start symbol, start collecting message 241 vw_rx_active =true; 242 vw_rx_bit_count =0; 243 vw_rx_len =0; 244 vw_rx_done =false;// Too bad if you missed the last message 245} 246} 247} 248 249// Speed is in bits per sec RF rate 250voidvw_setup(uint16_t speed) 251{ 252// Calculate the OCR1A overflow count based on the required bit speed 253// and CPU clock rate 254uint16_t ocr1a = (F_CPU /8UL) / speed; 255 256#ifndef TEST 257// Set up timer1 for a tick every 62.50 microseconds 258// for 2000 bits per sec 259 TCCR1A =0; 260 TCCR1B =_BV(WGM12) |_BV(CS10); 261// Caution: special procedures for setting 16 bit regs 262 OCR1A = ocr1a; 263// Enable interrupt 264#ifdef TIMSK1 265// atmega168 266 TIMSK1 |=_BV(OCIE1A); 267#else 268// others 269 TIMSK |=_BV(OCIE1A); 270#endif 271 272#endif 273 274// Set up digital IO pins 275pinMode(vw_tx_pin, OUTPUT); 276pinMode(vw_rx_pin, INPUT); 277pinMode(vw_ptt_pin, OUTPUT); 278digitalWrite(vw_ptt_pin, vw_ptt_inverted); 279} 280 281// Start the transmitter, call when the tx buffer is ready to go and vw_tx_len is 282// set to the total number of symbols to send 283voidvw_tx_start() 284{ 285 vw_tx_index =0; 286 vw_tx_bit =0; 287 vw_tx_sample =0; 288 289// Disable the receiver PLL 290 vw_rx_enabled =false; 291 292// Enable the transmitter hardware 293digitalWrite(vw_ptt_pin,true^ vw_ptt_inverted); 294 295// Next tick interrupt will send the first bit 296 vw_tx_enabled =true; 297} 298 299// Stop the transmitter, call when all bits are sent 300voidvw_tx_stop() 301{ 302// Disable the transmitter hardware 303digitalWrite(vw_ptt_pin,false^ vw_ptt_inverted); 304digitalWrite(vw_tx_pin,false); 305 306// No more ticks for the transmitter 307 vw_tx_enabled =false; 308 309// Enable the receiver PLL 310 vw_rx_enabled =true; 311} 312 313// Enable the receiver. When a message becomes available, vw_rx_done flag 314// is set, and vw_wait_rx() will return. 315voidvw_rx_start() 316{ 317if(!vw_rx_enabled) 318{ 319 vw_rx_enabled =true; 320 vw_rx_active =false;// Never restart a partial message 321} 322} 323 324// Disable the receiver 325voidvw_rx_stop() 326{ 327 vw_rx_enabled =false; 328} 329 330// Wait for the transmitter to become available 331// Busy-wait loop until the ISR says the message has been sent 332voidvw_wait_tx() 333{ 334while(vw_tx_enabled) 335; 336} 337 338// Wait for the receiver to get a message 339// Busy-wait loop until the ISR says a message is available 340// can then call vw_get_message() 341voidvw_wait_rx() 342{ 343while(!vw_rx_done) 344; 345} 346 347// Wait at most max milliseconds for the receiver to receive a message 348// Return the truth of whether there is a message 349uint8_tvw_wait_rx_max(unsigned long milliseconds) 350{ 351unsigned long start =millis(); 352 353while(!vw_rx_done && ((millis() - start) < milliseconds)) 354; 355return vw_rx_done; 356} 357 358// Wait until transmitter is available and encode and queue the message 359// into vw_tx_buf 360// The message is raw bytes, with no packet structure imposed 361// It is transmitted preceded a byte count and followed by 2 FCS bytes 362uint8_tvw_send(uint8_t* buf,uint8_t len) 363{ 364uint8_t i; 365uint8_t index =0; 366uint16_t crc =0xffff; 367uint8_t*p = vw_tx_buf + VW_HEADER_LEN;// start of the message area 368uint8_t count = len +3;// Added byte count and FCS to get total number of bytes 369 370if(len > VW_MAX_PAYLOAD) 371return false; 372 373// Wait for transmitter to become available 374vw_wait_tx(); 375 376// Encode the message length 377 crc =_crc_ccitt_update(crc, count); 378 p[index++] = symbols[count >>4]; 379 p[index++] = symbols[count &0xf]; 380 381// Encode the message into 6 bit symbols. Each byte is converted into 382// 2 6-bit symbols, high nybble first, low nybble second 383for(i =0; i < len; i++) 384{ 385 crc =_crc_ccitt_update(crc, buf[i]); 386 p[index++] = symbols[buf[i] >>4]; 387 p[index++] = symbols[buf[i] &0xf]; 388} 389 390// Append the fcs, 16 bits before encoding (4 6-bit symbols after encoding) 391// Caution: VW expects the _ones_complement_ of the CCITT CRC-16 as the FCS 392// VW sends FCS as low byte then hi byte 393 crc = ~crc; 394 p[index++] = symbols[(crc >>4) &0xf]; 395 p[index++] = symbols[crc &0xf]; 396 p[index++] = symbols[(crc >>12) &0xf]; 397 p[index++] = symbols[(crc >>8) &0xf]; 398 399// Total number of 6-bit symbols to send 400 vw_tx_len = index + VW_HEADER_LEN; 401 402// Start the low level interrupt handler sending symbols 403vw_tx_start(); 404 405return true; 406} 407 408// This is the interrupt service routine called when timer1 overflows 409// Its job is to output the next bit from the transmitter (every 8 calls) 410// and to call the PLL code if the receiver is enabled 411//ISR(SIG_OUTPUT_COMPARE1A) 412SIGNAL(TIMER1_COMPA_vect) 413{ 414 vw_rx_sample =digitalRead(vw_rx_pin); 415 416// Do transmitter stuff first to reduce transmitter bit jitter due 417// to variable receiver processing 418if(vw_tx_enabled && vw_tx_sample++ ==0) 419{ 420// Send next bit 421// Symbols are sent LSB first 422// Finished sending the whole message? (after waiting one bit period 423// since the last bit) 424if(vw_tx_index >= vw_tx_len) 425{ 426vw_tx_stop(); 427 vw_tx_msg_count++; 428} 429else 430{ 431digitalWrite(vw_tx_pin, vw_tx_buf[vw_tx_index] & (1<< vw_tx_bit++)); 432if(vw_tx_bit >=6) 433{ 434 vw_tx_bit =0; 435 vw_tx_index++; 436} 437} 438} 439if(vw_tx_sample >7) 440 vw_tx_sample =0; 441 442if(vw_rx_enabled) 443vw_pll(); 444} 445 446// Return true if there is a message available 447uint8_tvw_have_message() 448{ 449return vw_rx_done; 450} 451 452// Get the last message received (without byte count or FCS) 453// Copy at most *len bytes, set *len to the actual number copied 454// Return true if there is a message and the FCS is OK 455uint8_tvw_get_message(uint8_t* buf,uint8_t* len) 456{ 457uint8_t rxlen; 458 459// Message available? 460if(!vw_rx_done) 461return false; 462 463// Wait until vw_rx_done is set before reading vw_rx_len 464// then remove bytecount and FCS 465 rxlen = vw_rx_len -3; 466 467// Copy message (good or bad) 468if(*len > rxlen) 469*len = rxlen; 470memcpy(buf, vw_rx_buf +1, *len); 471 472 vw_rx_done =false;// OK, got that message thanks 473 474// Check the FCS, return goodness 475return(vw_crc(vw_rx_buf, vw_rx_len) ==0xf0b8);// FCS OK? 476} 477 478}