VirtualWire.cpp


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