Basic MAC data interface for LoRa transceiver

Dependencies:   L2Frame crc

Dependents:   LoRaBaseStation LoRaTerminal

Committer:
rba90
Date:
Sat Sep 03 02:02:22 2016 +0000
Revision:
27:463688e3bd12
Parent:
26:e87c8d345644
Child:
28:2c0e115b4f72
fix display text

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rba90 0:e2ccabf3f30c 1 #include "AlohaTransceiver.h"
rba90 0:e2ccabf3f30c 2 #include "mbed.h"
rba90 0:e2ccabf3f30c 3 #include "radio.h"
rba90 18:3e6483550f25 4 #include "debug.h"
rba90 0:e2ccabf3f30c 5 #include "AlohaFrame.h"
rba90 15:0dc9df48687a 6 #include "RingBuffer.h"
rba90 0:e2ccabf3f30c 7
rba90 18:3e6483550f25 8
rba90 27:463688e3bd12 9
rba90 0:e2ccabf3f30c 10 // declear the type of radio state
rba90 0:e2ccabf3f30c 11 typedef enum
rba90 0:e2ccabf3f30c 12 {
rba90 0:e2ccabf3f30c 13 LOWPOWER = 0,
rba90 0:e2ccabf3f30c 14 IDLE,
rba90 0:e2ccabf3f30c 15
rba90 0:e2ccabf3f30c 16 RX,
rba90 0:e2ccabf3f30c 17 RX_TIMEOUT,
rba90 0:e2ccabf3f30c 18 RX_ERROR,
rba90 0:e2ccabf3f30c 19
rba90 0:e2ccabf3f30c 20 TX,
rba90 0:e2ccabf3f30c 21 TX_TIMEOUT,
rba90 0:e2ccabf3f30c 22
rba90 0:e2ccabf3f30c 23 CAD,
rba90 0:e2ccabf3f30c 24 CAD_DONE
rba90 0:e2ccabf3f30c 25 }AppStates_t;
rba90 0:e2ccabf3f30c 26
rba90 0:e2ccabf3f30c 27 // radio driver related variables
rba90 0:e2ccabf3f30c 28 static int16_t RssiValue;
rba90 0:e2ccabf3f30c 29 static int8_t SnrValue;
rba90 0:e2ccabf3f30c 30
rba90 0:e2ccabf3f30c 31 static volatile AppStates_t State;
rba90 0:e2ccabf3f30c 32 static RadioEvents_t RadioEvents;
rba90 0:e2ccabf3f30c 33
rba90 27:463688e3bd12 34 // rx queue
rba90 27:463688e3bd12 35 CircularBuffer<AlohaFrame *> AlohaRxQueue(10);
rba90 17:c6e2e2cd6e5f 36
rba90 0:e2ccabf3f30c 37 // callback functions for radio driver
rba90 0:e2ccabf3f30c 38 void OnTxDone();
rba90 0:e2ccabf3f30c 39 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
rba90 0:e2ccabf3f30c 40 void OnTxTimeout();
rba90 0:e2ccabf3f30c 41 void OnRxTimeout();
rba90 0:e2ccabf3f30c 42 void OnRxError();
rba90 0:e2ccabf3f30c 43 void OnFhssChangeChannel( uint8_t channelIndex );
rba90 0:e2ccabf3f30c 44 void OnCadDone();
rba90 0:e2ccabf3f30c 45
rba90 0:e2ccabf3f30c 46 // radio driver
rba90 20:bd26d3cbc0bd 47 #ifdef DRIVER_SX1276
rba90 0:e2ccabf3f30c 48 SX1276MB1xAS Radio( NULL );
rba90 0:e2ccabf3f30c 49 #endif
rba90 0:e2ccabf3f30c 50
rba90 20:bd26d3cbc0bd 51 #ifdef DRIVER_INAIR
rba90 0:e2ccabf3f30c 52 SX1276inAir Radio( NULL );
rba90 0:e2ccabf3f30c 53 #endif
rba90 0:e2ccabf3f30c 54
rba90 0:e2ccabf3f30c 55
rba90 0:e2ccabf3f30c 56 /*
rba90 0:e2ccabf3f30c 57 * Abstract interface for accessing radio driver
rba90 0:e2ccabf3f30c 58 */
rba90 0:e2ccabf3f30c 59
rba90 27:463688e3bd12 60 AlohaTransceiver::AlohaTransceiver(uint8_t id):
rba90 27:463688e3bd12 61 AlohaTxQueue(10)
rba90 0:e2ccabf3f30c 62 {
rba90 11:3e1ff29da71a 63 // store unique device id
rba90 11:3e1ff29da71a 64 deviceId = id;
rba90 11:3e1ff29da71a 65
rba90 17:c6e2e2cd6e5f 66 // initialize sequenceid
rba90 17:c6e2e2cd6e5f 67 memset(seqid, 0x0, sizeof(seqid));
rba90 17:c6e2e2cd6e5f 68
rba90 0:e2ccabf3f30c 69 // configure properties
rba90 0:e2ccabf3f30c 70 #if USE_MODEM_LORA == 1
rba90 0:e2ccabf3f30c 71 Settings.Power = TX_OUTPUT_POWER;
rba90 0:e2ccabf3f30c 72 Settings.Bandwidth = LORA_BANDWIDTH;
rba90 0:e2ccabf3f30c 73 Settings.Datarate = LORA_SPREADING_FACTOR;
rba90 0:e2ccabf3f30c 74 Settings.Coderate = LORA_CODINGRATE;
rba90 0:e2ccabf3f30c 75 Settings.PreambleLen = LORA_PREAMBLE_LENGTH;
rba90 0:e2ccabf3f30c 76 Settings.SymbolTimeout = LORA_SYMBOL_TIMEOUT;
rba90 0:e2ccabf3f30c 77 Settings.FixLen = LORA_FIX_LENGTH_PAYLOAD_ON;
rba90 0:e2ccabf3f30c 78 Settings.PayloadLen = 0;
rba90 0:e2ccabf3f30c 79 Settings.CrcOn = LORA_CRC_ENABLED;
rba90 0:e2ccabf3f30c 80 Settings.FreqHopOn = LORA_FHSS_ENABLED;
rba90 0:e2ccabf3f30c 81 Settings.HopPeriod = LORA_NB_SYMB_HOP;
rba90 0:e2ccabf3f30c 82 Settings.IqInverted = LORA_IQ_INVERSION_ON;
rba90 0:e2ccabf3f30c 83 Settings.RxContinuous = true;
rba90 0:e2ccabf3f30c 84 Settings.TxTimeout = TX_TIMEOUT_VALUE;
rba90 0:e2ccabf3f30c 85
rba90 0:e2ccabf3f30c 86 #elif USE_MODEM_FSK == 1
rba90 0:e2ccabf3f30c 87 // TODO: Complete settings for FSK mode
rba90 0:e2ccabf3f30c 88 #error "FSK not implemented"
rba90 0:e2ccabf3f30c 89 #else
rba90 0:e2ccabf3f30c 90 #error "Please define a modem in the compiler options."
rba90 0:e2ccabf3f30c 91 #endif
rba90 0:e2ccabf3f30c 92 }
rba90 0:e2ccabf3f30c 93
rba90 0:e2ccabf3f30c 94 AlohaTransceiver::~AlohaTransceiver()
rba90 0:e2ccabf3f30c 95 {
rba90 0:e2ccabf3f30c 96
rba90 0:e2ccabf3f30c 97 }
rba90 0:e2ccabf3f30c 98
rba90 6:f545f5aa7de3 99 void AlohaTransceiver::boardInit()
rba90 0:e2ccabf3f30c 100 {
rba90 0:e2ccabf3f30c 101 // configure callback functions
rba90 0:e2ccabf3f30c 102 RadioEvents.TxDone = OnTxDone;
rba90 0:e2ccabf3f30c 103 RadioEvents.RxDone = OnRxDone;
rba90 0:e2ccabf3f30c 104 RadioEvents.RxError = OnRxError;
rba90 0:e2ccabf3f30c 105 RadioEvents.TxTimeout = OnTxTimeout;
rba90 0:e2ccabf3f30c 106 RadioEvents.RxTimeout = OnRxTimeout;
rba90 0:e2ccabf3f30c 107 Radio.Init( &RadioEvents );
rba90 0:e2ccabf3f30c 108
rba90 0:e2ccabf3f30c 109 // verify the connection with the board
rba90 0:e2ccabf3f30c 110 while( Radio.Read( REG_VERSION ) == 0x00 )
rba90 0:e2ccabf3f30c 111 {
rba90 18:3e6483550f25 112 #ifdef DEBUG_ALOHA
rba90 18:3e6483550f25 113 debug( "Radio could not be detected!\n\r" );
rba90 18:3e6483550f25 114 #endif
rba90 0:e2ccabf3f30c 115 wait( 1 );
rba90 0:e2ccabf3f30c 116 }
rba90 18:3e6483550f25 117 #ifdef DEBUG_ALOHA
rba90 0:e2ccabf3f30c 118 printf("RadioRegVersion: %d\r\n", Radio.Read( REG_VERSION ));
rba90 18:3e6483550f25 119 #endif
rba90 0:e2ccabf3f30c 120 }
rba90 0:e2ccabf3f30c 121
rba90 0:e2ccabf3f30c 122 void AlohaTransceiver::updateSettings()
rba90 0:e2ccabf3f30c 123 {
rba90 6:f545f5aa7de3 124 Radio.SetChannel( RF_FREQUENCY );
rba90 0:e2ccabf3f30c 125 #if USE_MODEM_LORA == 1
rba90 0:e2ccabf3f30c 126
rba90 0:e2ccabf3f30c 127 Radio.SetTxConfig( MODEM_LORA, Settings.Power, 0, Settings.Bandwidth,
rba90 0:e2ccabf3f30c 128 Settings.Datarate, Settings.Coderate,
rba90 0:e2ccabf3f30c 129 Settings.PreambleLen, Settings.FixLen,
rba90 0:e2ccabf3f30c 130 Settings.CrcOn, Settings.FreqHopOn, Settings.HopPeriod,
rba90 0:e2ccabf3f30c 131 Settings.IqInverted, Settings.TxTimeout );
rba90 0:e2ccabf3f30c 132
rba90 0:e2ccabf3f30c 133 Radio.SetRxConfig( MODEM_LORA, Settings.Bandwidth, Settings.Datarate,
rba90 0:e2ccabf3f30c 134 Settings.Coderate, 0, Settings.PreambleLen,
rba90 0:e2ccabf3f30c 135 Settings.SymbolTimeout, Settings.FixLen, Settings.PayloadLen,
rba90 0:e2ccabf3f30c 136 Settings.CrcOn, Settings.FreqHopOn, Settings.HopPeriod,
rba90 0:e2ccabf3f30c 137 Settings.IqInverted, Settings.RxContinuous );
rba90 0:e2ccabf3f30c 138
rba90 0:e2ccabf3f30c 139 #elif USE_MODEM_FSK == 1
rba90 0:e2ccabf3f30c 140 #error "FSK not implemented"
rba90 0:e2ccabf3f30c 141 #else
rba90 0:e2ccabf3f30c 142 #error "Please define a modem in the compiler options."
rba90 0:e2ccabf3f30c 143 #endif
rba90 0:e2ccabf3f30c 144 }
rba90 0:e2ccabf3f30c 145
rba90 6:f545f5aa7de3 146 void AlohaTransceiver::enable()
rba90 6:f545f5aa7de3 147 {
rba90 6:f545f5aa7de3 148 // entering passive receiver mode
rba90 10:065a4b58c6ff 149 Radio.Rx( 0 );
rba90 6:f545f5aa7de3 150 }
rba90 6:f545f5aa7de3 151
rba90 0:e2ccabf3f30c 152 void AlohaTransceiver::poll()
rba90 0:e2ccabf3f30c 153 {
rba90 0:e2ccabf3f30c 154 switch( State )
rba90 0:e2ccabf3f30c 155 {
rba90 0:e2ccabf3f30c 156 case RX:
rba90 5:c3741633dc6f 157 {
rba90 27:463688e3bd12 158 // process packet if received
rba90 27:463688e3bd12 159 while (AlohaRxQueue.getCounter() > 0)
rba90 25:bcd1cee4e5a8 160 {
rba90 27:463688e3bd12 161 // pop from queue
rba90 27:463688e3bd12 162 AlohaFrame *frame = AlohaRxQueue.dequeue();
rba90 27:463688e3bd12 163
rba90 27:463688e3bd12 164 // check destination
rba90 27:463688e3bd12 165 // if the destination is the device id, then processing, otherwise drop the packet and continue
rba90 27:463688e3bd12 166 // listening
rba90 27:463688e3bd12 167 if (frame->getDestinationAddress() == (deviceId & 0x0f))
rba90 26:e87c8d345644 168 {
rba90 27:463688e3bd12 169 uint8_t type = frame->getType();
rba90 27:463688e3bd12 170
rba90 27:463688e3bd12 171 // schedule the ack frame immediatly after the data frame is received
rba90 27:463688e3bd12 172 if (type == AlohaFrame::Aloha_Data)
rba90 27:463688e3bd12 173 {
rba90 27:463688e3bd12 174 sendAck(frame);
rba90 27:463688e3bd12 175 }
rba90 27:463688e3bd12 176 else if (type == AlohaFrame::Aloha_ACK)
rba90 27:463688e3bd12 177 {
rba90 26:e87c8d345644 178 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 179 printf("RXACK::SEQID:0x%x\r\n", frame->getSequenceID());
rba90 26:e87c8d345644 180 #endif
rba90 27:463688e3bd12 181 }
rba90 27:463688e3bd12 182
rba90 27:463688e3bd12 183 // check registered callback function
rba90 27:463688e3bd12 184 // execute callback functions if registered
rba90 27:463688e3bd12 185 if (AlohaTypeCallbackTable[type] != NULL)
rba90 27:463688e3bd12 186 {
rba90 27:463688e3bd12 187 uint8_t payload_length = frame->getPayloadLength();
rba90 27:463688e3bd12 188 uint8_t payload[payload_length];
rba90 27:463688e3bd12 189 uint8_t src_addr = frame->getSourceAddress();
rba90 27:463688e3bd12 190
rba90 27:463688e3bd12 191 // extract payload
rba90 27:463688e3bd12 192 for (uint8_t i = 0; i < payload_length; i++)
rba90 27:463688e3bd12 193 {
rba90 27:463688e3bd12 194 payload[i] = frame->getPayload(i);
rba90 27:463688e3bd12 195 }
rba90 27:463688e3bd12 196
rba90 27:463688e3bd12 197 // execute callback function
rba90 27:463688e3bd12 198 AlohaTypeCallbackTable[type](payload, payload_length, src_addr);
rba90 27:463688e3bd12 199 }
rba90 26:e87c8d345644 200 }
rba90 17:c6e2e2cd6e5f 201
rba90 27:463688e3bd12 202 // free memory
rba90 27:463688e3bd12 203 delete frame;
rba90 0:e2ccabf3f30c 204 }
rba90 0:e2ccabf3f30c 205
rba90 10:065a4b58c6ff 206 Radio.Rx( 0 );
rba90 0:e2ccabf3f30c 207 State = LOWPOWER;
rba90 0:e2ccabf3f30c 208 break;
rba90 0:e2ccabf3f30c 209 }
rba90 0:e2ccabf3f30c 210 case TX:
rba90 0:e2ccabf3f30c 211 {
rba90 10:065a4b58c6ff 212 Radio.Rx( 0 );
rba90 0:e2ccabf3f30c 213 State = LOWPOWER;
rba90 0:e2ccabf3f30c 214 break;
rba90 0:e2ccabf3f30c 215 }
rba90 0:e2ccabf3f30c 216 case RX_TIMEOUT:
rba90 0:e2ccabf3f30c 217 {
rba90 10:065a4b58c6ff 218 Radio.Rx( 0 );
rba90 0:e2ccabf3f30c 219 State = LOWPOWER;
rba90 0:e2ccabf3f30c 220 break;
rba90 0:e2ccabf3f30c 221 }
rba90 0:e2ccabf3f30c 222 case RX_ERROR:
rba90 0:e2ccabf3f30c 223 {
rba90 10:065a4b58c6ff 224 Radio.Rx( 0 );
rba90 0:e2ccabf3f30c 225 State = LOWPOWER;
rba90 0:e2ccabf3f30c 226 break;
rba90 0:e2ccabf3f30c 227 }
rba90 0:e2ccabf3f30c 228 case TX_TIMEOUT:
rba90 0:e2ccabf3f30c 229 {
rba90 10:065a4b58c6ff 230 Radio.Rx( 0 );
rba90 0:e2ccabf3f30c 231 State = LOWPOWER;
rba90 0:e2ccabf3f30c 232 break;
rba90 0:e2ccabf3f30c 233 }
rba90 0:e2ccabf3f30c 234 case LOWPOWER:
rba90 0:e2ccabf3f30c 235 {
rba90 22:2e39f382f782 236 // transmit packet when the radio is free
rba90 23:4b51a8e27f6a 237 if (AlohaTxQueue.getCounter() > 0)
rba90 22:2e39f382f782 238 {
rba90 22:2e39f382f782 239 AlohaFrame *frame = AlohaTxQueue.dequeue();
rba90 22:2e39f382f782 240
rba90 22:2e39f382f782 241 // create a buffer for transmit
rba90 22:2e39f382f782 242 uint8_t frame_length = frame->getPayloadLength() + FIXED_BYTE;
rba90 22:2e39f382f782 243 uint8_t buffer[frame_length]; // 4 fix fields
rba90 22:2e39f382f782 244 memset(buffer, 0x0, sizeof(buffer));
rba90 22:2e39f382f782 245
rba90 22:2e39f382f782 246 // copy content to buffer
rba90 22:2e39f382f782 247 frame->serialize(buffer);
rba90 22:2e39f382f782 248
rba90 22:2e39f382f782 249 // send to radio
rba90 22:2e39f382f782 250 Radio.Send(buffer, frame_length);
rba90 22:2e39f382f782 251
rba90 22:2e39f382f782 252 // free memory
rba90 22:2e39f382f782 253 delete frame;
rba90 22:2e39f382f782 254 }
rba90 0:e2ccabf3f30c 255 break;
rba90 0:e2ccabf3f30c 256 }
rba90 0:e2ccabf3f30c 257 default:
rba90 0:e2ccabf3f30c 258 {
rba90 0:e2ccabf3f30c 259 State = LOWPOWER;
rba90 0:e2ccabf3f30c 260 break;
rba90 0:e2ccabf3f30c 261 }
rba90 0:e2ccabf3f30c 262 }
rba90 0:e2ccabf3f30c 263 }
rba90 0:e2ccabf3f30c 264
rba90 24:8f31c33c7675 265 bool AlohaTransceiver::send(BasicPacket *packet)
rba90 24:8f31c33c7675 266 {
rba90 24:8f31c33c7675 267 // for the reason that we only transmit basic packet format, the
rba90 24:8f31c33c7675 268 // length is always 8
rba90 24:8f31c33c7675 269 uint8_t payload_length = 8;
rba90 24:8f31c33c7675 270
rba90 24:8f31c33c7675 271 // get destination address
rba90 24:8f31c33c7675 272 uint8_t destination_address = findNextHop(packet->getDestinationID());
rba90 24:8f31c33c7675 273
rba90 24:8f31c33c7675 274 // serialize the packet from upper layer
rba90 24:8f31c33c7675 275 uint8_t buffer[payload_length];
rba90 24:8f31c33c7675 276 memset(buffer, 0x0, sizeof(buffer));
rba90 24:8f31c33c7675 277
rba90 24:8f31c33c7675 278 // copy bytes into buffer
rba90 24:8f31c33c7675 279 packet->serialize(buffer);
rba90 17:c6e2e2cd6e5f 280
rba90 17:c6e2e2cd6e5f 281 // create a new frame
rba90 22:2e39f382f782 282 AlohaFrame *frame = new AlohaFrame();
rba90 17:c6e2e2cd6e5f 283
rba90 22:2e39f382f782 284 // set properfies
rba90 24:8f31c33c7675 285 // set payload as data
rba90 22:2e39f382f782 286 frame->setType(AlohaFrame::Aloha_Data);
rba90 24:8f31c33c7675 287
rba90 24:8f31c33c7675 288 // set payload length (8 bytes for BasicPacket)
rba90 22:2e39f382f782 289 frame->setPayloadLength(payload_length);
rba90 24:8f31c33c7675 290
rba90 24:8f31c33c7675 291 // set mac layer device id
rba90 22:2e39f382f782 292 frame->setSourceAddress(deviceId);
rba90 24:8f31c33c7675 293
rba90 24:8f31c33c7675 294 // set mac layer destination id
rba90 24:8f31c33c7675 295 // for multiple hop system, the destination is the next hop
rba90 24:8f31c33c7675 296 // in this case, we use destination id from upper layer
rba90 24:8f31c33c7675 297 frame->setDestinationAddress(packet->getDestinationID());
rba90 24:8f31c33c7675 298
rba90 24:8f31c33c7675 299 // set full message flag (always true in this case)
rba90 22:2e39f382f782 300 frame->setFullMessageFlag(0x1);
rba90 22:2e39f382f782 301
rba90 24:8f31c33c7675 302 // use dest_addr as key for accessing sequence id
rba90 24:8f31c33c7675 303 // the seqid should increase as it successfully transmit the packet
rba90 24:8f31c33c7675 304 frame->setSequenceID(seqid[destination_address]++);
rba90 24:8f31c33c7675 305
rba90 22:2e39f382f782 306 // set payload
rba90 17:c6e2e2cd6e5f 307 for (uint8_t i = 0; i < payload_length; i++)
rba90 17:c6e2e2cd6e5f 308 {
rba90 24:8f31c33c7675 309 frame->setPayload(i, buffer[i]);
rba90 17:c6e2e2cd6e5f 310 }
rba90 17:c6e2e2cd6e5f 311
rba90 17:c6e2e2cd6e5f 312 // calculate crc
rba90 22:2e39f382f782 313 frame->generateCrc();
rba90 17:c6e2e2cd6e5f 314
rba90 22:2e39f382f782 315 // push frame to the back of queue
rba90 22:2e39f382f782 316 AlohaTxQueue.enqueue(frame);
rba90 27:463688e3bd12 317
rba90 27:463688e3bd12 318 // debug
rba90 27:463688e3bd12 319 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 320 printf("\r\nTXDATA::ADDR:0x%x, SEQID:0x%x\r\n", frame->getDestinationAddress(), frame->getSequenceID());
rba90 27:463688e3bd12 321 #endif
rba90 17:c6e2e2cd6e5f 322 return true;
rba90 0:e2ccabf3f30c 323 }
rba90 0:e2ccabf3f30c 324
rba90 25:bcd1cee4e5a8 325 void AlohaTransceiver::sendAck(AlohaFrame *inFrame)
rba90 25:bcd1cee4e5a8 326 {
rba90 25:bcd1cee4e5a8 327 // create a new frame by calling it's constructor
rba90 25:bcd1cee4e5a8 328 AlohaFrame *outFrame = new AlohaFrame();
rba90 25:bcd1cee4e5a8 329
rba90 25:bcd1cee4e5a8 330 // set frame type
rba90 25:bcd1cee4e5a8 331 outFrame->setType(AlohaFrame::Aloha_ACK);
rba90 25:bcd1cee4e5a8 332
rba90 25:bcd1cee4e5a8 333 // set payload length (0 byte payload for ack frame)
rba90 25:bcd1cee4e5a8 334 outFrame->setPayloadLength(0);
rba90 25:bcd1cee4e5a8 335
rba90 25:bcd1cee4e5a8 336 // set mac layer device id
rba90 25:bcd1cee4e5a8 337 outFrame->setSourceAddress(deviceId);
rba90 25:bcd1cee4e5a8 338
rba90 25:bcd1cee4e5a8 339 // set mac layer destination id
rba90 25:bcd1cee4e5a8 340 outFrame->setDestinationAddress(inFrame->getSourceAddress());
rba90 25:bcd1cee4e5a8 341
rba90 25:bcd1cee4e5a8 342 // set full message flag
rba90 25:bcd1cee4e5a8 343 outFrame->setFullMessageFlag(0x1);
rba90 25:bcd1cee4e5a8 344
rba90 25:bcd1cee4e5a8 345 // set seqid
rba90 25:bcd1cee4e5a8 346 // the sequence id is always the source id + 1
rba90 25:bcd1cee4e5a8 347 outFrame->setSequenceID(inFrame->getSequenceID() + 1);
rba90 25:bcd1cee4e5a8 348
rba90 25:bcd1cee4e5a8 349 // no payload
rba90 25:bcd1cee4e5a8 350
rba90 25:bcd1cee4e5a8 351 // generate cec
rba90 25:bcd1cee4e5a8 352 outFrame->generateCrc();
rba90 25:bcd1cee4e5a8 353
rba90 25:bcd1cee4e5a8 354 // push frame to the back of queue
rba90 25:bcd1cee4e5a8 355 AlohaTxQueue.enqueue(outFrame);
rba90 25:bcd1cee4e5a8 356
rba90 25:bcd1cee4e5a8 357 // debug
rba90 25:bcd1cee4e5a8 358 #ifdef DEBUG_ALOHA
rba90 25:bcd1cee4e5a8 359 printf("\r\nTXACK::ADDR:0x%x, SEQID:0x%x\r\n", outFrame->getDestinationAddress(), outFrame->getSequenceID());
rba90 25:bcd1cee4e5a8 360 #endif
rba90 25:bcd1cee4e5a8 361 }
rba90 25:bcd1cee4e5a8 362
rba90 0:e2ccabf3f30c 363 void AlohaTransceiver::registerType(AlohaFrame::AlohaType_t type, aloha_callback_func f)
rba90 0:e2ccabf3f30c 364 {
rba90 0:e2ccabf3f30c 365 AlohaTypeCallbackTable[type] = f;
rba90 0:e2ccabf3f30c 366 }
rba90 0:e2ccabf3f30c 367
rba90 0:e2ccabf3f30c 368 void AlohaTransceiver::deRegisterType(AlohaFrame::AlohaType_t type, aloha_callback_func f)
rba90 0:e2ccabf3f30c 369 {
rba90 0:e2ccabf3f30c 370 AlohaTypeCallbackTable[type] = NULL;
rba90 0:e2ccabf3f30c 371 }
rba90 0:e2ccabf3f30c 372
rba90 2:fa264e48d5f7 373 int16_t AlohaTransceiver::getRssi()
rba90 2:fa264e48d5f7 374 {
rba90 2:fa264e48d5f7 375 return RssiValue;
rba90 2:fa264e48d5f7 376 }
rba90 2:fa264e48d5f7 377
rba90 2:fa264e48d5f7 378 int8_t AlohaTransceiver::getSnr()
rba90 2:fa264e48d5f7 379 {
rba90 2:fa264e48d5f7 380 return SnrValue;
rba90 2:fa264e48d5f7 381 }
rba90 2:fa264e48d5f7 382
rba90 17:c6e2e2cd6e5f 383 uint8_t AlohaTransceiver::getDeviceID()
rba90 11:3e1ff29da71a 384 {
rba90 11:3e1ff29da71a 385 return deviceId;
rba90 11:3e1ff29da71a 386 }
rba90 11:3e1ff29da71a 387
rba90 17:c6e2e2cd6e5f 388 void AlohaTransceiver::setDeviceID(uint8_t id)
rba90 11:3e1ff29da71a 389 {
rba90 11:3e1ff29da71a 390 deviceId = id;
rba90 11:3e1ff29da71a 391 }
rba90 11:3e1ff29da71a 392
rba90 24:8f31c33c7675 393 uint8_t AlohaTransceiver::findNextHop(uint8_t addr)
rba90 24:8f31c33c7675 394 {
rba90 24:8f31c33c7675 395 // TODO: maintain a routing lookup table for choosing shortest path
rba90 24:8f31c33c7675 396 return addr;
rba90 24:8f31c33c7675 397 }
rba90 24:8f31c33c7675 398
rba90 8:4bda842f73d4 399 #if USE_MODEM_LORA == 1
rba90 8:4bda842f73d4 400 AlohaTransceiver::LoRaSettings_t *AlohaTransceiver::getSettings()
rba90 8:4bda842f73d4 401 {
rba90 8:4bda842f73d4 402 return &Settings;
rba90 8:4bda842f73d4 403 }
rba90 8:4bda842f73d4 404
rba90 8:4bda842f73d4 405 #elif USE_MODEM_FSK == 1
rba90 8:4bda842f73d4 406 AlohaTransceiver::FskSettings_t *AlohaTransceiver::getSettings()
rba90 8:4bda842f73d4 407 {
rba90 8:4bda842f73d4 408 return &Settings;
rba90 8:4bda842f73d4 409 }
rba90 8:4bda842f73d4 410 #else
rba90 8:4bda842f73d4 411 #error "Please define a modem in the compiler options."
rba90 8:4bda842f73d4 412 #endif
rba90 8:4bda842f73d4 413
rba90 0:e2ccabf3f30c 414 void OnTxDone( void )
rba90 0:e2ccabf3f30c 415 {
rba90 0:e2ccabf3f30c 416 Radio.Sleep( );
rba90 0:e2ccabf3f30c 417 State = TX;
rba90 18:3e6483550f25 418
rba90 18:3e6483550f25 419 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 420 debug(0, "> OnTxDone\n\r" );
rba90 18:3e6483550f25 421 #endif
rba90 0:e2ccabf3f30c 422 }
rba90 0:e2ccabf3f30c 423
rba90 0:e2ccabf3f30c 424 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
rba90 0:e2ccabf3f30c 425 {
rba90 27:463688e3bd12 426 uint8_t payload_length;
rba90 27:463688e3bd12 427
rba90 0:e2ccabf3f30c 428 Radio.Sleep( );
rba90 0:e2ccabf3f30c 429
rba90 0:e2ccabf3f30c 430 // safeguard: if size exceeded maximum buffer size, it will cause memory overflow
rba90 27:463688e3bd12 431 payload_length = size ? BUFFER_SIZE : size <= BUFFER_SIZE;
rba90 27:463688e3bd12 432
rba90 27:463688e3bd12 433 // create a new frame instance
rba90 27:463688e3bd12 434 AlohaFrame *frame = new AlohaFrame(payload, payload_length);
rba90 27:463688e3bd12 435
rba90 27:463688e3bd12 436 // push onto the end of queue
rba90 27:463688e3bd12 437 AlohaRxQueue.enqueue(frame);
rba90 0:e2ccabf3f30c 438
rba90 0:e2ccabf3f30c 439 RssiValue = rssi;
rba90 0:e2ccabf3f30c 440 SnrValue = snr;
rba90 0:e2ccabf3f30c 441 State = RX;
rba90 18:3e6483550f25 442
rba90 18:3e6483550f25 443 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 444 debug(0, "> OnRxDone\n\r" );
rba90 18:3e6483550f25 445 #endif
rba90 0:e2ccabf3f30c 446 }
rba90 0:e2ccabf3f30c 447
rba90 0:e2ccabf3f30c 448 void OnTxTimeout( void )
rba90 0:e2ccabf3f30c 449 {
rba90 0:e2ccabf3f30c 450 Radio.Sleep( );
rba90 0:e2ccabf3f30c 451 State = TX_TIMEOUT;
rba90 18:3e6483550f25 452
rba90 18:3e6483550f25 453 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 454 debug(0, "> OnTxTimeout\n\r" );
rba90 18:3e6483550f25 455 #endif
rba90 0:e2ccabf3f30c 456 }
rba90 0:e2ccabf3f30c 457
rba90 0:e2ccabf3f30c 458 void OnRxTimeout( void )
rba90 0:e2ccabf3f30c 459 {
rba90 0:e2ccabf3f30c 460 Radio.Sleep( );
rba90 0:e2ccabf3f30c 461 State = RX_TIMEOUT;
rba90 18:3e6483550f25 462
rba90 18:3e6483550f25 463 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 464 debug(0, "> OnRxTimeout\n\r" );
rba90 18:3e6483550f25 465 #endif
rba90 0:e2ccabf3f30c 466 }
rba90 0:e2ccabf3f30c 467
rba90 0:e2ccabf3f30c 468 void OnRxError( void )
rba90 0:e2ccabf3f30c 469 {
rba90 0:e2ccabf3f30c 470 Radio.Sleep( );
rba90 0:e2ccabf3f30c 471 State = RX_ERROR;
rba90 18:3e6483550f25 472
rba90 18:3e6483550f25 473 #ifdef DEBUG_ALOHA
rba90 27:463688e3bd12 474 debug(0, "> OnRxError\n\r" );
rba90 18:3e6483550f25 475 #endif
rba90 0:e2ccabf3f30c 476 }
rba90 24:8f31c33c7675 477