COSA
An Object-Oriented Platform for Arduino Programming
VWI.hh
Go to the documentation of this file.
1 
23 #ifndef COSA_VWI_HH
24 #define COSA_VWI_HH
25 
26 #include "Cosa/InputPin.hh"
27 #include "Cosa/OutputPin.hh"
28 #include "Cosa/Wireless.hh"
29 
64 class VWI : public Wireless::Driver {
65 public:
73  class Codec {
74  public:
76  const uint8_t BITS_PER_SYMBOL;
77 
79  const uint16_t START_SYMBOL;
80 
85  const uint8_t PREAMBLE_MAX;
86 
88  const uint8_t SYMBOL_MASK;
89 
91  const uint16_t BITS_MSB;
92 
101  Codec(uint8_t bits_per_symbol,
102  uint16_t start_symbol,
103  uint8_t preamble_max = VWI::Transmitter::PREAMBLE_MAX);
104 
111  virtual const uint8_t* preamble() = 0;
112 
119  virtual uint8_t encode4(uint8_t nibble) = 0;
120 
127  virtual uint8_t decode4(uint8_t symbol) = 0;
128 
136  virtual uint8_t decode8(uint16_t symbol)
137  {
138  return ((decode4(symbol) << 4) | (decode4(symbol >> BITS_PER_SYMBOL)));
139  }
140  };
141 
142 protected:
146  struct header_t {
147  int16_t network;
148  uint8_t dest;
149  uint8_t src;
150  uint8_t port;
151  };
152 
153 public:
158  static const uint8_t PAYLOAD_MAX = 30 + sizeof(header_t);
159 
160 protected:
162  static const uint8_t MESSAGE_MAX = PAYLOAD_MAX + 3;
163 
165  static const uint8_t MESSAGE_MIN = sizeof(header_t);
166 
168  static const uint8_t SAMPLES_PER_BIT = 8;
169 
170 public:
174  class Receiver : private InputPin {
175  public:
182  InputPin(pin),
183  m_codec(codec)
184  {
185  }
186 
191  void begin()
192  {
193  m_enabled = true;
194  m_active = false;
195  }
196 
202  void end()
203  {
204  m_enabled = false;
205  }
206 
212  bool available() const
213  {
214  return (m_done);
215  }
216 
229  int recv(uint8_t& src, uint8_t& port, void* buf, size_t len,
230  uint32_t ms = 0L);
231 
244 
245  private:
247  static const uint8_t RAMP_MAX = 160;
248 
250  static const uint8_t INTEGRATOR_THRESHOLD = 5;
251 
259  static const uint8_t RAMP_INC = RAMP_MAX / SAMPLES_PER_BIT;
260 
262  static const uint8_t RAMP_TRANSITION = RAMP_MAX / 2;
263 
265  static const uint8_t RAMP_ADJUST = 9;
266 
268  static const uint8_t RAMP_INC_RETARD = (RAMP_INC - RAMP_ADJUST);
269 
271  static const uint8_t RAMP_INC_ADVANCE = (RAMP_INC + RAMP_ADJUST);
272 
274  Codec* m_codec;
275 
277  uint8_t m_sample;
278 
280  uint8_t m_last_sample;
281 
287  uint8_t m_pll_ramp;
288 
293  uint8_t m_integrator;
294 
299  uint8_t m_active;
300 
302  volatile bool m_done;
303 
305  uint8_t m_enabled;
306 
308  uint16_t m_bits;
309 
311  uint8_t m_bit_count;
312 
314  uint8_t m_buffer[MESSAGE_MAX];
315 
317  uint8_t m_count;
318 
320  volatile uint8_t m_length;
321 
327  void PLL();
328 
330  friend void TIMER1_COMPA_vect(void);
331  };
332 
336  class Transmitter : private OutputPin {
337  public:
345  OutputPin(pin),
346  m_codec(codec)
347  {
348  memcpy_P(m_buffer, codec->preamble(), codec->PREAMBLE_MAX);
349  }
350 
354  void begin()
355  {
356  TIMSK1 |= _BV(OCIE1A);
357  m_index = 0;
358  m_bit = 0;
359  m_sample = 0;
360  m_enabled = true;
361  }
362 
366  void end()
367  {
368  clear();
369  m_enabled = false;
370  }
371 
376  bool is_active() const
377  {
378  return (m_enabled);
379  }
380 
394  int send(uint8_t dest, uint8_t port, const iovec_t* vec);
395 
408  int send(uint8_t dest, uint8_t port, const void* buf, size_t len);
409 
410  private:
412  static const uint8_t PREAMBLE_MAX = 8;
413 
415  uint8_t m_buffer[(MESSAGE_MAX * 2) + PREAMBLE_MAX];
416 
418  Codec* m_codec;
419 
421  uint8_t m_length;
422 
424  uint8_t m_index;
425 
427  uint8_t m_bit;
428 
430  uint8_t m_sample;
431 
433  volatile uint8_t m_enabled;
434 
436  friend void TIMER1_COMPA_vect(void);
437 
439  friend class Codec;
440  };
441 
446  VWI(int16_t net, uint8_t dev, uint16_t speed, Receiver* rx) :
447  Wireless::Driver(net, dev),
448  m_rx(rx),
449  m_tx(NULL),
450  m_speed(speed)
451  {
452  s_rf = this;
453  }
454 
459  VWI(int16_t net, uint8_t dev, uint16_t speed, Transmitter* tx) :
460  Wireless::Driver(net, dev),
461  m_rx(NULL),
462  m_tx(tx),
463  m_speed(speed)
464  {
465  s_rf = this;
466  }
467 
472  VWI(int16_t net, uint8_t dev,
473  uint16_t speed,
474  Receiver* rx,
475  Transmitter* tx) :
476  Wireless::Driver(net, dev),
477  m_rx(rx),
478  m_tx(tx),
479  m_speed(speed)
480  {
481  s_rf = this;
482  }
483 
491  virtual bool begin(const void* config = NULL);
492 
499  virtual bool end();
500 
505  virtual void powerup();
506 
511  virtual void powerdown();
512 
518  virtual bool available()
519  {
520  if (m_rx == NULL) return (false);
521  return (m_rx->available());
522  }
523 
535  virtual int send(uint8_t dest, uint8_t port, const iovec_t* vec)
536  {
537  if (m_tx == NULL) return (-1);
538  return (m_tx->send(dest, port, vec));
539  }
540 
553  virtual int send(uint8_t dest, uint8_t port, const void* buf, size_t len)
554  {
555  if (m_tx == NULL) return (-1);
556  return (m_tx->send(dest, port, buf, len));
557  }
558 
575  virtual int recv(uint8_t& src, uint8_t& port,
576  void* buf, size_t len,
577  uint32_t ms = 0L)
578  {
579  if (m_rx == NULL) return (-1);
580  return (m_rx->recv(src, port, buf, len, ms));
581  }
582 
588  {
589  if (m_rx == NULL) return (0);
590  return (m_rx->link_quality_indicator());
591  }
592 
593 private:
595  static VWI* s_rf;
596 
598  Receiver* m_rx;
599 
601  Transmitter* m_tx;
602 
604  uint16_t m_speed;
605 
607  friend void TIMER1_COMPA_vect(void);
608 };
609 #endif
Definition: VWI.hh:64
static const uint8_t MESSAGE_MAX
Definition: VWI.hh:162
bool available() const
Definition: VWI.hh:212
virtual int link_quality_indicator()
Definition: VWI.hh:587
#define NULL
Definition: Types.h:101
static const uint8_t SAMPLES_PER_BIT
Definition: VWI.hh:168
virtual uint8_t encode4(uint8_t nibble)=0
const uint8_t BITS_PER_SYMBOL
Definition: VWI.hh:76
virtual bool begin(const void *config=NULL)
Definition: VWI.cpp:74
const uint16_t START_SYMBOL
Definition: VWI.hh:79
static const uint8_t PAYLOAD_MAX
Definition: VWI.hh:158
virtual void powerdown()
Definition: VWI.cpp:143
#define TIMSK1
Definition: ATtinyX5.hh:229
Definition: Types.h:391
virtual uint8_t decode4(uint8_t symbol)=0
VWI(int16_t net, uint8_t dev, uint16_t speed, Receiver *rx)
Definition: VWI.hh:446
bool is_active() const
Definition: VWI.hh:376
Transmitter(Board::DigitalPin pin, Codec *codec)
Definition: VWI.hh:344
Receiver(Board::DigitalPin pin, Codec *codec)
Definition: VWI.hh:181
VWI(int16_t net, uint8_t dev, uint16_t speed, Receiver *rx, Transmitter *tx)
Definition: VWI.hh:472
uint8_t dest
Destination device address.
Definition: VWI.hh:148
virtual uint8_t decode8(uint16_t symbol)
Definition: VWI.hh:136
uint8_t src
Source device address.
Definition: VWI.hh:149
virtual int recv(uint8_t &src, uint8_t &port, void *buf, size_t len, uint32_t ms=0L)
Definition: VWI.hh:575
friend void TIMER1_COMPA_vect(void)
void begin()
Definition: VWI.hh:191
uint8_t port
Port or message type.
Definition: VWI.hh:150
static const uint8_t MESSAGE_MIN
Definition: VWI.hh:165
virtual bool available()
Definition: VWI.hh:518
virtual int send(uint8_t dest, uint8_t port, const void *buf, size_t len)
Definition: VWI.hh:553
void begin()
Definition: VWI.hh:354
const uint8_t PREAMBLE_MAX
Definition: VWI.hh:85
Driver(int16_t network, uint8_t device)
Definition: Wireless.hh:66
Codec(uint8_t bits_per_symbol, uint16_t start_symbol, uint8_t preamble_max=VWI::Transmitter::PREAMBLE_MAX)
Definition: VWI.cpp:59
virtual const uint8_t * preamble()=0
int16_t network
Network address.
Definition: VWI.hh:147
virtual bool end()
Definition: VWI.cpp:128
IOStream & clear(IOStream &outs)
Definition: IOStream.hh:841
void end()
Definition: VWI.hh:202
const uint8_t SYMBOL_MASK
Definition: VWI.hh:88
void end()
Definition: VWI.hh:366
const uint16_t BITS_MSB
Definition: VWI.hh:91
virtual void powerup()
Definition: VWI.cpp:136
virtual int send(uint8_t dest, uint8_t port, const iovec_t *vec)
Definition: VWI.hh:535
VWI(int16_t net, uint8_t dev, uint16_t speed, Transmitter *tx)
Definition: VWI.hh:459