COSA
An Object-Oriented Platform for Arduino Programming
VWI_Receiver.cpp
Go to the documentation of this file.
1 
23 #include "VWI.hh"
24 #include "Cosa/RTT.hh"
25 #include "Cosa/Power.hh"
26 #include <util/crc16.h>
27 
36 static bool
37 is_valid_crc(uint8_t* ptr, uint8_t count)
38 {
39  uint16_t crc = 0xffff;
40  while (count-- > 0)
41  crc = _crc_ccitt_update(crc, *ptr++);
42  return (crc == 0xf0b8);
43 }
44 
45 void
46 VWI::Receiver::PLL()
47 {
48  // Integrate each sample
49  if (m_sample) m_integrator++;
50 
51  if (m_sample != m_last_sample) {
52  // Transition, advance if ramp > TRANSITION otherwise retard
53  m_pll_ramp +=
54  ((m_pll_ramp < RAMP_TRANSITION) ? RAMP_INC_RETARD : RAMP_INC_ADVANCE);
55  m_last_sample = m_sample;
56  }
57  else {
58  // No transition: Advance ramp by standard INC (== MAX/BITS samples)
59  m_pll_ramp += RAMP_INC;
60  }
61  if (m_pll_ramp >= RAMP_MAX) {
62  // Add this to the MSB bit of rx_bits, LSB first. The last bits are kept
63  m_bits >>= 1;
64 
65  // Check the integrator to see how many samples in this cycle were
66  // high. If < 5 out of 8, then its declared a 0 bit, else a 1;
67  if (m_integrator >= INTEGRATOR_THRESHOLD)
68  m_bits |= m_codec->BITS_MSB;
69 
70  m_pll_ramp -= RAMP_MAX;
71 
72  // Clear the integral for the next cycle
73  m_integrator = 0;
74 
75  if (m_active) {
76  // We have the start symbol and now we are collecting message
77  // bits for two symbols before decoding to a byte
78  if (++m_bit_count >= (m_codec->BITS_PER_SYMBOL * 2)) {
79  uint8_t data = m_codec->decode8(m_bits);
80 
81  // The first decoded byte is the byte count of the following
82  // message the count includes the byte count and the 2
83  // trailing FCS bytes.
84  if (m_length == 0) {
85  // The first byte is the byte count. Check it for
86  // sensibility. It cant be less than min, since it includes
87  // the bytes count itself and the 2 byte FCS
88  m_count = data;
89  if (m_count < MESSAGE_MIN || m_count > MESSAGE_MAX) {
90  // Stupid message length, drop the whole thing
91  m_active = false;
92  return;
93  }
94  }
95  m_buffer[m_length++] = data;
96  if (m_length >= m_count) {
97  // Got all the bytes now
98  m_active = false;
99  // Better come get it before the next one starts
100  m_done = true;
101  }
102  m_bit_count = 0;
103  }
104  }
105 
106  // Not in a message, see if we have a start symbol
107  else if (m_bits == m_codec->START_SYMBOL) {
108  // Have start symbol, start collecting message
109  m_active = true;
110  m_bit_count = 0;
111  m_length = 0;
112  // Too bad if you missed the last message
113  m_done = false;
114  }
115  }
116 }
117 
118 int
119 VWI::Receiver::recv(uint8_t& src, uint8_t& port,
120  void* buf, size_t len,
121  uint32_t ms)
122 {
123  // Wait until a valid message is available or timeout
124  uint32_t start = RTT::millis();
125  header_t* hp = (header_t*) (m_buffer + 1);
126  do {
127  while (!m_done && (ms == 0 || (RTT::since(start) < ms))) yield();
128  if (!m_done) return (ETIME);
129 
130  // Check the crc and the network and device destination address
131  if (!is_valid_crc(m_buffer, m_length)
132  || (hp->network != s_rf->m_addr.network)
133  || ((hp->dest != BROADCAST) && (hp->dest != s_rf->m_addr.device))) {
134  m_done = false;
135  }
136  } while (!m_done);
137 
138  // Sanity check message length
139  size_t rxlen = m_length - sizeof(header_t) - 3;
140  if (rxlen > len) return (EMSGSIZE);
141 
142  // Copy payload and source device address
143  memcpy(buf, m_buffer + sizeof(header_t) + 1, rxlen);
144  s_rf->m_dest = hp->dest;
145  src = hp->src;
146  port = hp->port;
147 
148  // OK, got that message thanks
149  m_done = false;
150 
151  // Return actual number of bytes received
152  return (rxlen);
153 }
154 
155 int
157 {
158  uint32_t start = RTT::millis();
159  while (is_clear());
160  return (RTT::millis() - start);
161 }
static const uint8_t MESSAGE_MAX
Definition: VWI.hh:162
#define EMSGSIZE
Definition: Errno.h:117
const uint8_t BITS_PER_SYMBOL
Definition: VWI.hh:76
const uint16_t START_SYMBOL
Definition: VWI.hh:79
#define ETIME
Definition: Errno.h:89
static uint32_t since(uint32_t start)
Definition: RTT.hh:107
static bool is_valid_crc(uint8_t *ptr, uint8_t count)
uint8_t dest
Destination device address.
Definition: VWI.hh:148
virtual uint8_t decode8(uint16_t symbol)
Definition: VWI.hh:136
static uint32_t millis()
Definition: RTT.cpp:121
uint8_t src
Source device address.
Definition: VWI.hh:149
void(* yield)()
int link_quality_indicator()
uint8_t port
Port or message type.
Definition: VWI.hh:150
bool is_clear() const
Definition: Pin.hh:142
static const uint8_t BROADCAST
Definition: Wireless.hh:58
int16_t network
Network address.
Definition: VWI.hh:147
const uint16_t BITS_MSB
Definition: VWI.hh:91
int recv(uint8_t &src, uint8_t &port, void *buf, size_t len, uint32_t ms=0L)