RadioHead

Committer:
danjulio
Date:
Sun Jun 11 04:05:05 2017 +0000
Revision:
0:e69d086cb053
Initial commit of minimally ported Radiohead library using swspi

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danjulio 0:e69d086cb053 1 // RHGenericDriver.cpp
danjulio 0:e69d086cb053 2 //
danjulio 0:e69d086cb053 3 // Copyright (C) 2014 Mike McCauley
danjulio 0:e69d086cb053 4 // $Id: RHGenericDriver.cpp,v 1.21 2017/03/04 00:59:41 mikem Exp $
danjulio 0:e69d086cb053 5 //
danjulio 0:e69d086cb053 6 // Ported to mbed - support only a single radio - Dan Julio - 5/2017
danjulio 0:e69d086cb053 7 //
danjulio 0:e69d086cb053 8
danjulio 0:e69d086cb053 9 #include <RHGenericDriver.h>
danjulio 0:e69d086cb053 10
danjulio 0:e69d086cb053 11 RHGenericDriver::RHGenericDriver()
danjulio 0:e69d086cb053 12 :
danjulio 0:e69d086cb053 13 _mode(RHModeInitialising),
danjulio 0:e69d086cb053 14 _thisAddress(RH_BROADCAST_ADDRESS),
danjulio 0:e69d086cb053 15 _txHeaderTo(RH_BROADCAST_ADDRESS),
danjulio 0:e69d086cb053 16 _txHeaderFrom(RH_BROADCAST_ADDRESS),
danjulio 0:e69d086cb053 17 _txHeaderId(0),
danjulio 0:e69d086cb053 18 _txHeaderFlags(0),
danjulio 0:e69d086cb053 19 _rxBad(0),
danjulio 0:e69d086cb053 20 _rxGood(0),
danjulio 0:e69d086cb053 21 _txGood(0),
danjulio 0:e69d086cb053 22 _cad_timeout(0)
danjulio 0:e69d086cb053 23 {
danjulio 0:e69d086cb053 24 }
danjulio 0:e69d086cb053 25
danjulio 0:e69d086cb053 26 bool RHGenericDriver::init()
danjulio 0:e69d086cb053 27 {
danjulio 0:e69d086cb053 28 return true;
danjulio 0:e69d086cb053 29 }
danjulio 0:e69d086cb053 30
danjulio 0:e69d086cb053 31 // Blocks until a valid message is received
danjulio 0:e69d086cb053 32 void RHGenericDriver::waitAvailable()
danjulio 0:e69d086cb053 33 {
danjulio 0:e69d086cb053 34 while (!available())
danjulio 0:e69d086cb053 35 Thread::yield();
danjulio 0:e69d086cb053 36 }
danjulio 0:e69d086cb053 37
danjulio 0:e69d086cb053 38 // Blocks until a valid message is received or timeout expires
danjulio 0:e69d086cb053 39 // Return true if there is a message available
danjulio 0:e69d086cb053 40 // Works correctly even on millis() rollover
danjulio 0:e69d086cb053 41 bool RHGenericDriver::waitAvailableTimeout(uint16_t timeout)
danjulio 0:e69d086cb053 42 {
danjulio 0:e69d086cb053 43 _waitTimer.reset();
danjulio 0:e69d086cb053 44 _waitTimer.start();
danjulio 0:e69d086cb053 45
danjulio 0:e69d086cb053 46 while (_waitTimer.read_ms() < timeout)
danjulio 0:e69d086cb053 47 {
danjulio 0:e69d086cb053 48 if (available())
danjulio 0:e69d086cb053 49 {
danjulio 0:e69d086cb053 50 _waitTimer.stop();
danjulio 0:e69d086cb053 51 return true;
danjulio 0:e69d086cb053 52 }
danjulio 0:e69d086cb053 53 Thread::yield();
danjulio 0:e69d086cb053 54 }
danjulio 0:e69d086cb053 55 _waitTimer.stop();
danjulio 0:e69d086cb053 56 return false;
danjulio 0:e69d086cb053 57 }
danjulio 0:e69d086cb053 58
danjulio 0:e69d086cb053 59 bool RHGenericDriver::waitPacketSent()
danjulio 0:e69d086cb053 60 {
danjulio 0:e69d086cb053 61 while (_mode == RHModeTx)
danjulio 0:e69d086cb053 62 Thread::yield(); // Wait for any previous transmit to finish
danjulio 0:e69d086cb053 63 return true;
danjulio 0:e69d086cb053 64 }
danjulio 0:e69d086cb053 65
danjulio 0:e69d086cb053 66 bool RHGenericDriver::waitPacketSent(uint16_t timeout)
danjulio 0:e69d086cb053 67 {
danjulio 0:e69d086cb053 68 _waitTimer.reset();
danjulio 0:e69d086cb053 69 _waitTimer.start();
danjulio 0:e69d086cb053 70 while (_waitTimer.read_ms() < timeout)
danjulio 0:e69d086cb053 71 {
danjulio 0:e69d086cb053 72 if (_mode != RHModeTx) // Any previous transmit finished?
danjulio 0:e69d086cb053 73 {
danjulio 0:e69d086cb053 74 _waitTimer.stop();
danjulio 0:e69d086cb053 75 return true;
danjulio 0:e69d086cb053 76 }
danjulio 0:e69d086cb053 77 Thread::yield();
danjulio 0:e69d086cb053 78 }
danjulio 0:e69d086cb053 79 _waitTimer.stop();
danjulio 0:e69d086cb053 80 return false;
danjulio 0:e69d086cb053 81 }
danjulio 0:e69d086cb053 82
danjulio 0:e69d086cb053 83 // Wait until no channel activity detected or timeout
danjulio 0:e69d086cb053 84 bool RHGenericDriver::waitCAD()
danjulio 0:e69d086cb053 85 {
danjulio 0:e69d086cb053 86 if (!_cad_timeout)
danjulio 0:e69d086cb053 87 return true;
danjulio 0:e69d086cb053 88
danjulio 0:e69d086cb053 89 // Wait for any channel activity to finish or timeout
danjulio 0:e69d086cb053 90 // Sophisticated DCF function...
danjulio 0:e69d086cb053 91 // DCF : BackoffTime = random() x aSlotTime
danjulio 0:e69d086cb053 92 // 100 - 1000 ms
danjulio 0:e69d086cb053 93 // 10 sec timeout
danjulio 0:e69d086cb053 94 _waitTimer.reset();
danjulio 0:e69d086cb053 95 _waitTimer.start();
danjulio 0:e69d086cb053 96 while (isChannelActive())
danjulio 0:e69d086cb053 97 {
danjulio 0:e69d086cb053 98 if (_waitTimer.read_ms() > _cad_timeout)
danjulio 0:e69d086cb053 99 {
danjulio 0:e69d086cb053 100 _waitTimer.stop();
danjulio 0:e69d086cb053 101 return false;
danjulio 0:e69d086cb053 102 }
danjulio 0:e69d086cb053 103
danjulio 0:e69d086cb053 104 wait_ms(100);
danjulio 0:e69d086cb053 105 }
danjulio 0:e69d086cb053 106
danjulio 0:e69d086cb053 107 _waitTimer.stop();
danjulio 0:e69d086cb053 108 return true;
danjulio 0:e69d086cb053 109 }
danjulio 0:e69d086cb053 110
danjulio 0:e69d086cb053 111 // subclasses are expected to override if CAD is available for that radio
danjulio 0:e69d086cb053 112 bool RHGenericDriver::isChannelActive()
danjulio 0:e69d086cb053 113 {
danjulio 0:e69d086cb053 114 return false;
danjulio 0:e69d086cb053 115 }
danjulio 0:e69d086cb053 116
danjulio 0:e69d086cb053 117 void RHGenericDriver::setPromiscuous(bool promiscuous)
danjulio 0:e69d086cb053 118 {
danjulio 0:e69d086cb053 119 _promiscuous = promiscuous;
danjulio 0:e69d086cb053 120 }
danjulio 0:e69d086cb053 121
danjulio 0:e69d086cb053 122 void RHGenericDriver::setThisAddress(uint8_t address)
danjulio 0:e69d086cb053 123 {
danjulio 0:e69d086cb053 124 _thisAddress = address;
danjulio 0:e69d086cb053 125 }
danjulio 0:e69d086cb053 126
danjulio 0:e69d086cb053 127 void RHGenericDriver::setHeaderTo(uint8_t to)
danjulio 0:e69d086cb053 128 {
danjulio 0:e69d086cb053 129 _txHeaderTo = to;
danjulio 0:e69d086cb053 130 }
danjulio 0:e69d086cb053 131
danjulio 0:e69d086cb053 132 void RHGenericDriver::setHeaderFrom(uint8_t from)
danjulio 0:e69d086cb053 133 {
danjulio 0:e69d086cb053 134 _txHeaderFrom = from;
danjulio 0:e69d086cb053 135 }
danjulio 0:e69d086cb053 136
danjulio 0:e69d086cb053 137 void RHGenericDriver::setHeaderId(uint8_t id)
danjulio 0:e69d086cb053 138 {
danjulio 0:e69d086cb053 139 _txHeaderId = id;
danjulio 0:e69d086cb053 140 }
danjulio 0:e69d086cb053 141
danjulio 0:e69d086cb053 142 void RHGenericDriver::setHeaderFlags(uint8_t set, uint8_t clear)
danjulio 0:e69d086cb053 143 {
danjulio 0:e69d086cb053 144 _txHeaderFlags &= ~clear;
danjulio 0:e69d086cb053 145 _txHeaderFlags |= set;
danjulio 0:e69d086cb053 146 }
danjulio 0:e69d086cb053 147
danjulio 0:e69d086cb053 148 uint8_t RHGenericDriver::headerTo()
danjulio 0:e69d086cb053 149 {
danjulio 0:e69d086cb053 150 return _rxHeaderTo;
danjulio 0:e69d086cb053 151 }
danjulio 0:e69d086cb053 152
danjulio 0:e69d086cb053 153 uint8_t RHGenericDriver::headerFrom()
danjulio 0:e69d086cb053 154 {
danjulio 0:e69d086cb053 155 return _rxHeaderFrom;
danjulio 0:e69d086cb053 156 }
danjulio 0:e69d086cb053 157
danjulio 0:e69d086cb053 158 uint8_t RHGenericDriver::headerId()
danjulio 0:e69d086cb053 159 {
danjulio 0:e69d086cb053 160 return _rxHeaderId;
danjulio 0:e69d086cb053 161 }
danjulio 0:e69d086cb053 162
danjulio 0:e69d086cb053 163 uint8_t RHGenericDriver::headerFlags()
danjulio 0:e69d086cb053 164 {
danjulio 0:e69d086cb053 165 return _rxHeaderFlags;
danjulio 0:e69d086cb053 166 }
danjulio 0:e69d086cb053 167
danjulio 0:e69d086cb053 168 int8_t RHGenericDriver::lastRssi()
danjulio 0:e69d086cb053 169 {
danjulio 0:e69d086cb053 170 return _lastRssi;
danjulio 0:e69d086cb053 171 }
danjulio 0:e69d086cb053 172
danjulio 0:e69d086cb053 173 RHGenericDriver::RHMode RHGenericDriver::mode()
danjulio 0:e69d086cb053 174 {
danjulio 0:e69d086cb053 175 return _mode;
danjulio 0:e69d086cb053 176 }
danjulio 0:e69d086cb053 177
danjulio 0:e69d086cb053 178 void RHGenericDriver::setMode(RHMode mode)
danjulio 0:e69d086cb053 179 {
danjulio 0:e69d086cb053 180 _mode = mode;
danjulio 0:e69d086cb053 181 }
danjulio 0:e69d086cb053 182
danjulio 0:e69d086cb053 183 bool RHGenericDriver::sleep()
danjulio 0:e69d086cb053 184 {
danjulio 0:e69d086cb053 185 return false;
danjulio 0:e69d086cb053 186 }
danjulio 0:e69d086cb053 187
danjulio 0:e69d086cb053 188 // Diagnostic help
danjulio 0:e69d086cb053 189 void RHGenericDriver::printBuffer(const char* prompt, const uint8_t* buf, uint8_t len)
danjulio 0:e69d086cb053 190 {
danjulio 0:e69d086cb053 191 uint8_t i;
danjulio 0:e69d086cb053 192
danjulio 0:e69d086cb053 193 printf("%s", prompt);
danjulio 0:e69d086cb053 194 for (i = 0; i < len; i++)
danjulio 0:e69d086cb053 195 {
danjulio 0:e69d086cb053 196 if (i % 16 == 15)
danjulio 0:e69d086cb053 197 printf("0x%x\n", buf[i]);
danjulio 0:e69d086cb053 198 else
danjulio 0:e69d086cb053 199 {
danjulio 0:e69d086cb053 200 printf("0x%x ", buf[i]);
danjulio 0:e69d086cb053 201 }
danjulio 0:e69d086cb053 202 }
danjulio 0:e69d086cb053 203 printf("\n");
danjulio 0:e69d086cb053 204 }
danjulio 0:e69d086cb053 205
danjulio 0:e69d086cb053 206 uint16_t RHGenericDriver::rxBad()
danjulio 0:e69d086cb053 207 {
danjulio 0:e69d086cb053 208 return _rxBad;
danjulio 0:e69d086cb053 209 }
danjulio 0:e69d086cb053 210
danjulio 0:e69d086cb053 211 uint16_t RHGenericDriver::rxGood()
danjulio 0:e69d086cb053 212 {
danjulio 0:e69d086cb053 213 return _rxGood;
danjulio 0:e69d086cb053 214 }
danjulio 0:e69d086cb053 215
danjulio 0:e69d086cb053 216 uint16_t RHGenericDriver::txGood()
danjulio 0:e69d086cb053 217 {
danjulio 0:e69d086cb053 218 return _txGood;
danjulio 0:e69d086cb053 219 }
danjulio 0:e69d086cb053 220
danjulio 0:e69d086cb053 221 void RHGenericDriver::setCADTimeout(unsigned long cad_timeout)
danjulio 0:e69d086cb053 222 {
danjulio 0:e69d086cb053 223 _cad_timeout = cad_timeout;
danjulio 0:e69d086cb053 224 }
danjulio 0:e69d086cb053 225