Manchester code (phase encoding) library.

Dependents:   Manchester_Transmitter Manchester_Receiver

Manchester code (phase encoding) library

It implements Manchester code according to both IEEE 802.3 and G.E. Thomas' conventions.

  • A '0' is expressed by a high-to-low transition, a '1' by low-to-high transition in the IEEE 802.3 convention. The reverse is true in the G.E. Thomas' convention.
  • The transitions which signify '0' or '1' occur at the midpoint of a period.
  • Transitions at the start of a period are overhead and don't signify data.
  • Least significant bit is sent first
  • There are synchronization pulses (the number can be set) at the begin of transmission

    Select a convention to be used by commenting or uncommenting the line below in the Manchester.h header file.

Manchester.h

#define G_E_THOMAS 1

The IEEE 802.3 convention is used by default.

A Manchester encoded message (using G.E. Thomas' convention), with one sync pulse in the preamble, carrying four bytes:

/media/uploads/hudakz/manchester01.png

ACKNOWLEDGEMENT: The code in this library was based on this article published by Robert Guastella.

Import programManchester_Transmitter

Manchester transmitter demo.


Import programManchester_Receiver

Manchester receiver demo.

NOTE: To perform a simple test (without radio modules) connect the txPin on transmitter board to the rxPin on the receiver board and make sure that grounds are also connected one another.

Committer:
hudakz
Date:
Sun Oct 14 09:38:33 2018 +0000
Revision:
8:c1b5893191fe
Parent:
7:afd0ee36dcd1
Number of sync pulses in preamble can be set.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:d5c75b0e5708 1 /*
hudakz 0:d5c75b0e5708 2 ******************************************************************************
hudakz 0:d5c75b0e5708 3 * @file Manchester.cpp
hudakz 0:d5c75b0e5708 4 * @author Zoltan Hudak
hudakz 2:de778df5892c 5 * @version
hudakz 6:7454ad91f714 6 * @date 2017-May-16
hudakz 0:d5c75b0e5708 7 * @brief Manchester code for mbed
hudakz 0:d5c75b0e5708 8 ******************************************************************************
hudakz 0:d5c75b0e5708 9 * @attention
hudakz 0:d5c75b0e5708 10 *
hudakz 0:d5c75b0e5708 11 * <h2><center>&copy; COPYRIGHT(c) 2017 Zoltan Hudak <hudakz@outlook.com>
hudakz 0:d5c75b0e5708 12 *
hudakz 0:d5c75b0e5708 13 * All rights reserved.
hudakz 0:d5c75b0e5708 14
hudakz 0:d5c75b0e5708 15 This program is free software: you can redistribute it and/or modify
hudakz 0:d5c75b0e5708 16 it under the terms of the GNU General Public License as published by
hudakz 0:d5c75b0e5708 17 the Free Software Foundation, either version 3 of the License, or
hudakz 0:d5c75b0e5708 18 (at your option) any later version.
hudakz 0:d5c75b0e5708 19
hudakz 0:d5c75b0e5708 20 This program is distributed in the hope that it will be useful,
hudakz 0:d5c75b0e5708 21 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 0:d5c75b0e5708 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 0:d5c75b0e5708 23 GNU General Public License for more details.
hudakz 0:d5c75b0e5708 24
hudakz 0:d5c75b0e5708 25 You should have received a copy of the GNU General Public License
hudakz 0:d5c75b0e5708 26 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 0:d5c75b0e5708 27 */
hudakz 5:3b2c7e9fda3f 28 /*
hudakz 7:afd0ee36dcd1 29 This library implements Manchester code according to both IEEE 802.3
hudakz 7:afd0ee36dcd1 30 and G.E. Thomas' conventions.
hudakz 7:afd0ee36dcd1 31 • A '0' is expressed by a high-to-low transition, a '1' by low-to-high transition
hudakz 5:3b2c7e9fda3f 32 in the IEEE 802.3 convention. The reverse is true in the G.E. Thomas' convention.
hudakz 7:afd0ee36dcd1 33 • The transitions which signify '0' or '1' occur at the midpoint of a period.
hudakz 7:afd0ee36dcd1 34 • Transitions at the start of a period are overhead and don't signify data.
hudakz 7:afd0ee36dcd1 35 • Least significant bit is sent first
hudakz 7:afd0ee36dcd1 36 • There is one synchronization pulse at the begin of transmission
hudakz 7:afd0ee36dcd1 37
hudakz 5:3b2c7e9fda3f 38 The IEEE 802.3 convention is used by default.
hudakz 7:afd0ee36dcd1 39 Select a convention to be used by commenting or uncommenting
hudakz 5:3b2c7e9fda3f 40 the line "#define G_E_THOMAS 1" in the Manchester.h header file.
hudakz 5:3b2c7e9fda3f 41 */
hudakz 0:d5c75b0e5708 42 #include "Manchester.h"
hudakz 0:d5c75b0e5708 43 #include "ManchesterMsg.h"
hudakz 0:d5c75b0e5708 44
hudakz 0:d5c75b0e5708 45 /**
hudakz 0:d5c75b0e5708 46 * @brief Creates a Manchester object
hudakz 0:d5c75b0e5708 47 * @note
hudakz 0:d5c75b0e5708 48 * @param txPin Pin name of transmitter line
hudakz 0:d5c75b0e5708 49 * rxPin Pin name of receiver line
hudakz 0:d5c75b0e5708 50 * speed Communication bit rate in bits per second
hudakz 3:03109c995123 51 * tol Pulse width tolerance in %
hudakz 0:d5c75b0e5708 52 * @retval
hudakz 0:d5c75b0e5708 53 */
hudakz 3:03109c995123 54 Manchester::Manchester
hudakz 8:c1b5893191fe 55 (
hudakz 8:c1b5893191fe 56 PinName txPin,
hudakz 8:c1b5893191fe 57 PinName rxPin,
hudakz 8:c1b5893191fe 58 uint32_t baudrate, /* = 1200 bps */
hudakz 8:c1b5893191fe 59 uint8_t tol, /* = (+/-)25% */
hudakz 8:c1b5893191fe 60 float rxTimeout /* = 5s */
hudakz 8:c1b5893191fe 61 ) :
hudakz 7:afd0ee36dcd1 62 _tx(txPin),
hudakz 8:c1b5893191fe 63 _rx(rxPin)
hudakz 8:c1b5893191fe 64 {
hudakz 0:d5c75b0e5708 65 _state = IDLE;
hudakz 8:c1b5893191fe 66 _midBitTime = 1000000 / baudrate / 2; // mid-bit time [us]
hudakz 0:d5c75b0e5708 67 _minPulseWidth = (_midBitTime * 2 * (100 - tol)) / 100; // [us]
hudakz 0:d5c75b0e5708 68 _maxPulseWidth = (_midBitTime * 2 * (100 + tol)) / 100; // [us]
hudakz 8:c1b5893191fe 69 _rxTimeout = rxTimeout;
hudakz 0:d5c75b0e5708 70 _rx.disable_irq();
hudakz 0:d5c75b0e5708 71 _rx.rise(callback(this, &Manchester::reception));
hudakz 0:d5c75b0e5708 72 _rx.fall(callback(this, &Manchester::reception));
hudakz 8:c1b5893191fe 73 _preamble = 8; // number of synch_start patterns
hudakz 8:c1b5893191fe 74 _error = "no error";
hudakz 8:c1b5893191fe 75 // printf("_midBitTime = %d\r\n", _midBitTime);
hudakz 8:c1b5893191fe 76 // printf("_minPulseWidth = %d\r\n", _minPulseWidth);
hudakz 8:c1b5893191fe 77 // printf("_maxPulseWidth = %d\r\n", _maxPulseWidth);
hudakz 5:3b2c7e9fda3f 78 #ifdef G_E_THOMAS
hudakz 5:3b2c7e9fda3f 79 _tx = 1;
hudakz 5:3b2c7e9fda3f 80 #else
hudakz 5:3b2c7e9fda3f 81 _tx = 0;
hudakz 5:3b2c7e9fda3f 82 #endif
hudakz 0:d5c75b0e5708 83 }
hudakz 0:d5c75b0e5708 84
hudakz 0:d5c75b0e5708 85 /**
hudakz 0:d5c75b0e5708 86 * @brief Transmits message
hudakz 0:d5c75b0e5708 87 * @note
hudakz 0:d5c75b0e5708 88 * @param msg Message to transmit
hudakz 0:d5c75b0e5708 89 * @retval
hudakz 0:d5c75b0e5708 90 */
hudakz 8:c1b5893191fe 91 void Manchester::transmit(ManchesterMsg& msg)
hudakz 8:c1b5893191fe 92 {
hudakz 6:7454ad91f714 93 bool txFinished;
hudakz 0:d5c75b0e5708 94
hudakz 0:d5c75b0e5708 95 _data = msg.data;
hudakz 0:d5c75b0e5708 96 _len = msg.len;
hudakz 0:d5c75b0e5708 97 _state = SYNCH_START;
hudakz 0:d5c75b0e5708 98 _txTicker.attach_us(callback(this, &Manchester::transmission), _midBitTime);
hudakz 0:d5c75b0e5708 99
hudakz 6:7454ad91f714 100 do {
hudakz 0:d5c75b0e5708 101 core_util_critical_section_enter();
hudakz 6:7454ad91f714 102 txFinished = (_state == IDLE);
hudakz 0:d5c75b0e5708 103 core_util_critical_section_exit();
hudakz 8:c1b5893191fe 104 } while (!txFinished);
hudakz 0:d5c75b0e5708 105
hudakz 0:d5c75b0e5708 106 _txTicker.detach();
hudakz 0:d5c75b0e5708 107 }
hudakz 0:d5c75b0e5708 108
hudakz 0:d5c75b0e5708 109 /**
hudakz 0:d5c75b0e5708 110 * @brief ISR handling transmission
hudakz 3:03109c995123 111 * @note Called by _txTicker
hudakz 0:d5c75b0e5708 112 * @param
hudakz 0:d5c75b0e5708 113 * @retval
hudakz 0:d5c75b0e5708 114 */
hudakz 8:c1b5893191fe 115 void Manchester::transmission(void)
hudakz 8:c1b5893191fe 116 {
hudakz 0:d5c75b0e5708 117 static uint8_t encodeByte;
hudakz 2:de778df5892c 118 static size_t byteIndex;
hudakz 0:d5c75b0e5708 119 static uint8_t bitIndex;
hudakz 8:c1b5893191fe 120 static uint8_t counter;
hudakz 0:d5c75b0e5708 121
hudakz 8:c1b5893191fe 122 _timeout.attach_us(callback(this, &Manchester::onTxTimeout), _maxPulseWidth * 4);
hudakz 2:de778df5892c 123
hudakz 8:c1b5893191fe 124 switch (_state)
hudakz 8:c1b5893191fe 125 {
hudakz 8:c1b5893191fe 126 case SYNCH_START:
hudakz 8:c1b5893191fe 127 if (_preamble == 0)
hudakz 8:c1b5893191fe 128 {
hudakz 8:c1b5893191fe 129 byteIndex = 0;
hudakz 8:c1b5893191fe 130 encodeByte = _data[byteIndex];
hudakz 8:c1b5893191fe 131 bitIndex = 0;
hudakz 8:c1b5893191fe 132 _state = SETUP;
hudakz 8:c1b5893191fe 133 break;
hudakz 8:c1b5893191fe 134 }
hudakz 0:d5c75b0e5708 135
hudakz 8:c1b5893191fe 136 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 137 _tx = 0; // pull line low to start synch pulse
hudakz 8:c1b5893191fe 138 #else
hudakz 8:c1b5893191fe 139 _tx = 1; // bring line high to start synch pulse
hudakz 8:c1b5893191fe 140 #endif
hudakz 8:c1b5893191fe 141 counter = 0;
hudakz 8:c1b5893191fe 142 _state = SYNCH_NEXT;
hudakz 8:c1b5893191fe 143 break;
hudakz 0:d5c75b0e5708 144
hudakz 8:c1b5893191fe 145 case SYNCH_NEXT:
hudakz 8:c1b5893191fe 146 counter++;
hudakz 8:c1b5893191fe 147 if ((counter % 4) == 0)
hudakz 8:c1b5893191fe 148 _tx = !_tx;
hudakz 8:c1b5893191fe 149 if (counter < (_preamble * 8))
hudakz 8:c1b5893191fe 150 break;
hudakz 8:c1b5893191fe 151 else
hudakz 8:c1b5893191fe 152 {
hudakz 8:c1b5893191fe 153 byteIndex = 0;
hudakz 8:c1b5893191fe 154 encodeByte = _data[byteIndex];
hudakz 8:c1b5893191fe 155 bitIndex = 0;
hudakz 8:c1b5893191fe 156 _state = SETUP;
hudakz 8:c1b5893191fe 157 break;
hudakz 8:c1b5893191fe 158 }
hudakz 0:d5c75b0e5708 159
hudakz 8:c1b5893191fe 160 case SETUP:
hudakz 8:c1b5893191fe 161 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 162 _tx = encodeByte & 0x01; // setup for next bit to transmit
hudakz 8:c1b5893191fe 163 #else
hudakz 8:c1b5893191fe 164 _tx = !(encodeByte & 0x01); // setup for next bit to transmit
hudakz 8:c1b5893191fe 165 #endif
hudakz 8:c1b5893191fe 166 _state = TRANSITION;
hudakz 8:c1b5893191fe 167 break;
hudakz 0:d5c75b0e5708 168
hudakz 8:c1b5893191fe 169 case TRANSITION:
hudakz 8:c1b5893191fe 170 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 171 _tx = !(encodeByte & 0x01); // set line appropriately for transition
hudakz 8:c1b5893191fe 172 #else
hudakz 8:c1b5893191fe 173 _tx = encodeByte & 0x01; // set line appropriately for transition
hudakz 8:c1b5893191fe 174 #endif
hudakz 8:c1b5893191fe 175 if (++bitIndex < 8)
hudakz 8:c1b5893191fe 176 {
hudakz 8:c1b5893191fe 177 encodeByte = (encodeByte >> 1);
hudakz 0:d5c75b0e5708 178 _state = SETUP;
hudakz 0:d5c75b0e5708 179 }
hudakz 0:d5c75b0e5708 180 else
hudakz 8:c1b5893191fe 181 {
hudakz 8:c1b5893191fe 182 if (++byteIndex < _len)
hudakz 8:c1b5893191fe 183 {
hudakz 8:c1b5893191fe 184 encodeByte = _data[byteIndex];
hudakz 8:c1b5893191fe 185 _state = SETUP;
hudakz 8:c1b5893191fe 186 bitIndex = 0;
hudakz 8:c1b5893191fe 187 }
hudakz 8:c1b5893191fe 188 else
hudakz 8:c1b5893191fe 189 {
hudakz 8:c1b5893191fe 190 counter = 0;
hudakz 8:c1b5893191fe 191 _state = STOP;
hudakz 8:c1b5893191fe 192 }
hudakz 8:c1b5893191fe 193 }
hudakz 8:c1b5893191fe 194 break;
hudakz 0:d5c75b0e5708 195
hudakz 8:c1b5893191fe 196 case STOP:
hudakz 8:c1b5893191fe 197 counter++;
hudakz 8:c1b5893191fe 198 if (counter == 1)
hudakz 8:c1b5893191fe 199 {
hudakz 8:c1b5893191fe 200 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 201 _tx = 1;
hudakz 8:c1b5893191fe 202 #else
hudakz 8:c1b5893191fe 203 _tx = 0;
hudakz 8:c1b5893191fe 204 #endif
hudakz 8:c1b5893191fe 205 }
hudakz 8:c1b5893191fe 206 else
hudakz 8:c1b5893191fe 207 if (counter == 5)
hudakz 8:c1b5893191fe 208 {
hudakz 8:c1b5893191fe 209 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 210 _tx = 0;
hudakz 8:c1b5893191fe 211 #else
hudakz 8:c1b5893191fe 212 _tx = 1;
hudakz 8:c1b5893191fe 213 #endif
hudakz 8:c1b5893191fe 214 }
hudakz 8:c1b5893191fe 215 else
hudakz 8:c1b5893191fe 216 if (counter == 8)
hudakz 8:c1b5893191fe 217 _state = COMPLETE;
hudakz 8:c1b5893191fe 218 break;
hudakz 0:d5c75b0e5708 219
hudakz 8:c1b5893191fe 220 case COMPLETE:
hudakz 8:c1b5893191fe 221 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 222 _tx = 1;
hudakz 8:c1b5893191fe 223 #else
hudakz 8:c1b5893191fe 224 _tx = 0;
hudakz 8:c1b5893191fe 225 #endif
hudakz 8:c1b5893191fe 226 _state = IDLE;
hudakz 8:c1b5893191fe 227 break;
hudakz 8:c1b5893191fe 228
hudakz 8:c1b5893191fe 229 case IDLE:
hudakz 8:c1b5893191fe 230 default:
hudakz 8:c1b5893191fe 231 _timeout.detach();
hudakz 8:c1b5893191fe 232 return;
hudakz 0:d5c75b0e5708 233 }
hudakz 0:d5c75b0e5708 234 }
hudakz 0:d5c75b0e5708 235
hudakz 0:d5c75b0e5708 236 /**
hudakz 2:de778df5892c 237 * @brief ISR handling 'transmission timeout'
hudakz 2:de778df5892c 238 * @note Called when transmitter is stuck.
hudakz 2:de778df5892c 239 * Signals 'end of transmission' by setting state to IDLE
hudakz 7:afd0ee36dcd1 240 * @param
hudakz 7:afd0ee36dcd1 241 * @retval
hudakz 2:de778df5892c 242 */
hudakz 8:c1b5893191fe 243 void Manchester::onTxTimeout(void)
hudakz 8:c1b5893191fe 244 {
hudakz 2:de778df5892c 245 _timeout.detach();
hudakz 2:de778df5892c 246 _state = IDLE;
hudakz 2:de778df5892c 247 }
hudakz 2:de778df5892c 248
hudakz 2:de778df5892c 249 /**
hudakz 0:d5c75b0e5708 250 * @brief Receives message
hudakz 7:afd0ee36dcd1 251 * @note Waits until a message is received or 'reception timeout' occured
hudakz 1:11292d238e50 252 * @param msg Container to store the received message
hudakz 0:d5c75b0e5708 253 * @retval true On success
hudakz 0:d5c75b0e5708 254 * false Otherwise
hudakz 0:d5c75b0e5708 255 */
hudakz 8:c1b5893191fe 256 bool Manchester::receive(ManchesterMsg& msg)
hudakz 8:c1b5893191fe 257 {
hudakz 8:c1b5893191fe 258 bool rxFinished;
hudakz 0:d5c75b0e5708 259
hudakz 0:d5c75b0e5708 260 _data = msg.data;
hudakz 0:d5c75b0e5708 261 _maxLen = msg.maxLen();
hudakz 0:d5c75b0e5708 262 _state = LISTEN;
hudakz 8:c1b5893191fe 263 _timeout.attach(callback(this, &Manchester::onRxTimeout), _rxTimeout);
hudakz 0:d5c75b0e5708 264 _rx.enable_irq();
hudakz 0:d5c75b0e5708 265
hudakz 6:7454ad91f714 266 do {
hudakz 0:d5c75b0e5708 267 core_util_critical_section_enter();
hudakz 0:d5c75b0e5708 268 rxFinished = ((_state == IDLE) || (_state == ERROR));
hudakz 0:d5c75b0e5708 269 core_util_critical_section_exit();
hudakz 8:c1b5893191fe 270 } while (!rxFinished);
hudakz 0:d5c75b0e5708 271
hudakz 0:d5c75b0e5708 272 _rx.disable_irq();
hudakz 8:c1b5893191fe 273 _timer.stop();
hudakz 8:c1b5893191fe 274 _timeout.detach();
hudakz 0:d5c75b0e5708 275
hudakz 8:c1b5893191fe 276 if (_state == ERROR)
hudakz 8:c1b5893191fe 277 {
hudakz 0:d5c75b0e5708 278 msg.len = 0;
hudakz 0:d5c75b0e5708 279 _state = IDLE;
hudakz 0:d5c75b0e5708 280 return false;
hudakz 0:d5c75b0e5708 281 }
hudakz 8:c1b5893191fe 282 else
hudakz 8:c1b5893191fe 283 {
hudakz 0:d5c75b0e5708 284 msg.len = _len;
hudakz 0:d5c75b0e5708 285 return true;
hudakz 0:d5c75b0e5708 286 }
hudakz 0:d5c75b0e5708 287 }
hudakz 0:d5c75b0e5708 288
hudakz 0:d5c75b0e5708 289 /**
hudakz 2:de778df5892c 290 * @brief ISR handling reception
hudakz 2:de778df5892c 291 * @note Called on signal change (rise or fall) on receiver line
hudakz 0:d5c75b0e5708 292 * @param
hudakz 0:d5c75b0e5708 293 * @retval
hudakz 0:d5c75b0e5708 294 */
hudakz 8:c1b5893191fe 295 void Manchester::reception(void)
hudakz 8:c1b5893191fe 296 {
hudakz 0:d5c75b0e5708 297 uint32_t now = us_ticker_read();
hudakz 0:d5c75b0e5708 298 static uint32_t begin;
hudakz 0:d5c75b0e5708 299 uint32_t pulseWidth;
hudakz 0:d5c75b0e5708 300 static uint8_t decodeByte;
hudakz 0:d5c75b0e5708 301 static uint8_t bitIndex;
hudakz 0:d5c75b0e5708 302
hudakz 8:c1b5893191fe 303 switch (_state)
hudakz 8:c1b5893191fe 304 {
hudakz 8:c1b5893191fe 305 case LISTEN:
hudakz 0:d5c75b0e5708 306 begin = now;
hudakz 8:c1b5893191fe 307 if (
hudakz 8:c1b5893191fe 308 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 309 _rx == 0
hudakz 8:c1b5893191fe 310 #else
hudakz 8:c1b5893191fe 311 _rx == 1
hudakz 8:c1b5893191fe 312 #endif
hudakz 8:c1b5893191fe 313 )
hudakz 8:c1b5893191fe 314 {
hudakz 8:c1b5893191fe 315 _state = SYNCH_START;
hudakz 8:c1b5893191fe 316 }
hudakz 8:c1b5893191fe 317 else
hudakz 8:c1b5893191fe 318 {
hudakz 8:c1b5893191fe 319 _error = "SYNCH_START: Isn't a SYNCH pulse";
hudakz 8:c1b5893191fe 320 _state = ERROR;
hudakz 8:c1b5893191fe 321 }
hudakz 8:c1b5893191fe 322 break;
hudakz 8:c1b5893191fe 323
hudakz 8:c1b5893191fe 324 case SYNCH_START:
hudakz 8:c1b5893191fe 325 pulseWidth = now - begin;
hudakz 8:c1b5893191fe 326 //printf("%d <= %d <= %d\r\n", (_midBitTime * 2) + _minPulseWidth, pulseWidth, (_midBitTime * 2) + _maxPulseWidth);
hudakz 8:c1b5893191fe 327 if (((_midBitTime * 2) + _minPulseWidth <= pulseWidth) && (pulseWidth <= (_midBitTime * 2) + _maxPulseWidth))
hudakz 8:c1b5893191fe 328 {
hudakz 8:c1b5893191fe 329 begin = now;
hudakz 8:c1b5893191fe 330 _state = SYNCH_NEXT;
hudakz 8:c1b5893191fe 331 }
hudakz 8:c1b5893191fe 332 else
hudakz 8:c1b5893191fe 333 {
hudakz 8:c1b5893191fe 334 _error = "SYNCH_START: Isn't a SYNCH pulse";
hudakz 8:c1b5893191fe 335 _state = ERROR;
hudakz 8:c1b5893191fe 336 }
hudakz 8:c1b5893191fe 337 break;
hudakz 0:d5c75b0e5708 338
hudakz 8:c1b5893191fe 339 case SYNCH_NEXT:
hudakz 8:c1b5893191fe 340 pulseWidth = now - begin;
hudakz 8:c1b5893191fe 341 //printf("%d <= %d <= %d\r\n", (_midBitTime * 2) + _minPulseWidth, pulseWidth, (_midBitTime * 2) + _maxPulseWidth);
hudakz 8:c1b5893191fe 342 if (((_midBitTime * 2) + _minPulseWidth <= pulseWidth) && (pulseWidth <= (_midBitTime * 2) + _maxPulseWidth))
hudakz 8:c1b5893191fe 343 {
hudakz 8:c1b5893191fe 344 begin = now;
hudakz 8:c1b5893191fe 345 _state = SYNCH_NEXT;
hudakz 8:c1b5893191fe 346 }
hudakz 8:c1b5893191fe 347 else
hudakz 8:c1b5893191fe 348 if ((_minPulseWidth <= pulseWidth) && (pulseWidth <= _maxPulseWidth))
hudakz 8:c1b5893191fe 349 {
hudakz 8:c1b5893191fe 350 begin = now;
hudakz 8:c1b5893191fe 351 decodeByte = 0;
hudakz 8:c1b5893191fe 352 bitIndex = 0;
hudakz 8:c1b5893191fe 353 _len = 0;
hudakz 8:c1b5893191fe 354 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 355 decodeByte |= (((_rx == 0) & 0x01) << bitIndex++);
hudakz 8:c1b5893191fe 356 #else
hudakz 8:c1b5893191fe 357 decodeByte |= (((_rx == 1) & 0x01) << bitIndex++);
hudakz 8:c1b5893191fe 358 #endif
hudakz 8:c1b5893191fe 359 _state = DECODE;
hudakz 8:c1b5893191fe 360 }
hudakz 8:c1b5893191fe 361 break;
hudakz 8:c1b5893191fe 362
hudakz 8:c1b5893191fe 363 case DECODE:
hudakz 8:c1b5893191fe 364 pulseWidth = now - begin;
hudakz 8:c1b5893191fe 365 if ((_minPulseWidth <= pulseWidth) && (pulseWidth <= _maxPulseWidth))
hudakz 8:c1b5893191fe 366 {
hudakz 8:c1b5893191fe 367 begin = now;
hudakz 8:c1b5893191fe 368 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 369 decodeByte |= (((_rx == 0) & 0x01) << bitIndex++);
hudakz 8:c1b5893191fe 370 #else
hudakz 8:c1b5893191fe 371 decodeByte |= (((_rx == 1) & 0x01) << bitIndex++);
hudakz 8:c1b5893191fe 372 #endif
hudakz 8:c1b5893191fe 373 if (bitIndex > 7)
hudakz 8:c1b5893191fe 374 {
hudakz 8:c1b5893191fe 375 _data[_len++] = decodeByte;
hudakz 8:c1b5893191fe 376 if (_len > _maxLen - 1)
hudakz 8:c1b5893191fe 377 _state = ERROR;
hudakz 8:c1b5893191fe 378 else
hudakz 8:c1b5893191fe 379 {
hudakz 8:c1b5893191fe 380 decodeByte = 0;
hudakz 8:c1b5893191fe 381 bitIndex = 0;
hudakz 8:c1b5893191fe 382 }
hudakz 8:c1b5893191fe 383 }
hudakz 8:c1b5893191fe 384 break;
hudakz 8:c1b5893191fe 385 }
hudakz 8:c1b5893191fe 386
hudakz 8:c1b5893191fe 387 if (pulseWidth > _maxPulseWidth)
hudakz 8:c1b5893191fe 388 {
hudakz 8:c1b5893191fe 389 if (
hudakz 8:c1b5893191fe 390 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 391 _rx == 0
hudakz 8:c1b5893191fe 392 #else
hudakz 8:c1b5893191fe 393 _rx == 1
hudakz 8:c1b5893191fe 394 #endif
hudakz 8:c1b5893191fe 395 )
hudakz 8:c1b5893191fe 396 {
hudakz 8:c1b5893191fe 397 begin = now;
hudakz 8:c1b5893191fe 398 _state = COMPLETE; // End of reception
hudakz 0:d5c75b0e5708 399 }
hudakz 0:d5c75b0e5708 400 }
hudakz 8:c1b5893191fe 401 break;
hudakz 0:d5c75b0e5708 402
hudakz 8:c1b5893191fe 403 case COMPLETE:
hudakz 8:c1b5893191fe 404 pulseWidth = now - begin;
hudakz 8:c1b5893191fe 405 if (pulseWidth > _maxPulseWidth)
hudakz 8:c1b5893191fe 406 {
hudakz 8:c1b5893191fe 407 if (
hudakz 8:c1b5893191fe 408 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 409 _rx == 1
hudakz 8:c1b5893191fe 410 #else
hudakz 8:c1b5893191fe 411 _rx == 0
hudakz 8:c1b5893191fe 412 #endif
hudakz 8:c1b5893191fe 413 )
hudakz 8:c1b5893191fe 414 {
hudakz 8:c1b5893191fe 415 _state = IDLE; // End of reception
hudakz 8:c1b5893191fe 416 }
hudakz 8:c1b5893191fe 417 }
hudakz 8:c1b5893191fe 418 break;
hudakz 0:d5c75b0e5708 419
hudakz 8:c1b5893191fe 420 case IDLE:
hudakz 8:c1b5893191fe 421 case ERROR:
hudakz 8:c1b5893191fe 422 default:
hudakz 8:c1b5893191fe 423 _timeout.detach();
hudakz 8:c1b5893191fe 424 break;
hudakz 0:d5c75b0e5708 425 }
hudakz 0:d5c75b0e5708 426 }
hudakz 0:d5c75b0e5708 427
hudakz 0:d5c75b0e5708 428 /**
hudakz 7:afd0ee36dcd1 429 * @brief ISR handling 'reception timeout'
hudakz 3:03109c995123 430 * @note Called when receiver line is idle longer than limit.
hudakz 7:afd0ee36dcd1 431 * Signals 'end of reception' by setting state to IDLE
hudakz 2:de778df5892c 432 * or 'timeout error' by setting state to ERROR.
hudakz 7:afd0ee36dcd1 433 * @param
hudakz 7:afd0ee36dcd1 434 * @retval
hudakz 0:d5c75b0e5708 435 */
hudakz 8:c1b5893191fe 436 void Manchester::onRxTimeout(void)
hudakz 8:c1b5893191fe 437 {
hudakz 2:de778df5892c 438 _timeout.detach();
hudakz 0:d5c75b0e5708 439
hudakz 5:3b2c7e9fda3f 440 #ifdef G_E_THOMAS
hudakz 8:c1b5893191fe 441 if ((_state == DECODE) && (_rx == 1))
hudakz 5:3b2c7e9fda3f 442 #else
hudakz 8:c1b5893191fe 443 if ((_state == DECODE) && (_rx == 0))
hudakz 5:3b2c7e9fda3f 444 #endif
hudakz 8:c1b5893191fe 445 {
hudakz 8:c1b5893191fe 446 _error = "rx timeout";
hudakz 8:c1b5893191fe 447 _state = IDLE; // Reception successful
hudakz 8:c1b5893191fe 448 }
hudakz 8:c1b5893191fe 449 else
hudakz 8:c1b5893191fe 450 {
hudakz 8:c1b5893191fe 451 _error = "reception error";
hudakz 8:c1b5893191fe 452 _state = ERROR; // Reception incomplete
hudakz 8:c1b5893191fe 453 }
hudakz 0:d5c75b0e5708 454 }