Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SX1276PingPong by
Revision 16:c3c6b13c3c42, committed 2016-06-08
- Comitter:
- rba90
- Date:
- Wed Jun 08 22:15:29 2016 +0000
- Parent:
- 15:f790f35839db
- Commit message:
- random stuff
Changed in this revision
diff -r f790f35839db -r c3c6b13c3c42 Aloha.h --- a/Aloha.h Tue May 31 09:52:21 2016 +0000 +++ b/Aloha.h Wed Jun 08 22:15:29 2016 +0000 @@ -3,7 +3,7 @@ #include "mbed.h" -#define ALOHA_MAX_ATTEMPT 3 +#define ALOHA_MAX_ATTEMPT 5 class Aloha { @@ -13,12 +13,13 @@ IDLE = 0, PENDING, RETRANSMIT, - EXPIRED + EXPIRED, + ACK_RESP } AlohaState_t; public: Timeout AlohaAckTimeout; - uint32_t delay; + float delay; int attempts; AlohaState_t state;
diff -r f790f35839db -r c3c6b13c3c42 AlohaPacket.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AlohaPacket.cpp Wed Jun 08 22:15:29 2016 +0000 @@ -0,0 +1,75 @@ +#include "AlohaPacket.h" + +uint8_t crc8(const uint8_t *data, int len) +{ + unsigned int crc = 0; + + for (int j = len; j; j--, data++) + { + crc ^= (*data << 8); + for (int i = 8; i; i--) + { + if (crc & 0x8000) + { + crc ^= (0x1070 << 3); + } + crc <<= 1; + } + } + + return (uint8_t)(crc >> 8); +} + +bool dissectAlohaPacket(uint8_t *input, HeaderStruct *header, DataStruct *data) +{ + // assume user has already prepare memory in *in + + // get header + if (header) + { + header->fid = input[0] >> 4; // higher four bits + header->no = input[0] & 0x0f; // lower four bits + } + + // get data + if (data) + { + data->pd0 = input[1]; + data->pd1 = input[2]; + } + + // check crc + if (header && data) + { + return input[3] == crc8(input, 3); + } + else + { + return false; + } +} + +void createAlohaPacket(uint8_t *output, HeaderStruct *header, DataStruct *data) +{ + // assume user has already allocated memory for output + + // create header + if (header) + { + output[0] = header->no; + output[0] |= header->fid << 4; + } + + // fit data + if (data) + { + output[1] = data->pd0; + output[2] = data->pd1; + } + + // calculate CRC + if (header && data) + { + output[3] = crc8(output, 3); + } +} \ No newline at end of file
diff -r f790f35839db -r c3c6b13c3c42 AlohaPacket.h --- a/AlohaPacket.h Tue May 31 09:52:21 2016 +0000 +++ b/AlohaPacket.h Wed Jun 08 22:15:29 2016 +0000 @@ -2,7 +2,9 @@ #define ALOHAPACKET_H_ #include "stdint.h" -#include "crc.h" + + +// TODO: Move everything to Aloha.h typedef struct { @@ -16,58 +18,8 @@ uint8_t pd1; } DataStruct; -inline void createAlohaPacket(uint8_t *output, HeaderStruct *header, DataStruct *data) -{ - // assume user has already allocated memory for output - - // create header - if (header) - { - output[0] = header->no; - output[0] |= header->fid << 4; - } - - // fit data - if (data) - { - output[1] = data->pd0; - output[2] = data->pd1; - } - - // calculate CRC - if (header && data) - { - output[3] = crc8(output, 3); - } -} +void createAlohaPacket(uint8_t *output, HeaderStruct *header, DataStruct *data); -inline bool dissectAlohaPacket(uint8_t *input, HeaderStruct *header, DataStruct *data) -{ - // assume user has already prepare memory in *in - - // get header - if (header) - { - header->fid = input[0] >> 4; // higher four bits - header->no = input[0] & 0x0f; // lower four bits - } - - // get data - if (data) - { - data->pd0 = input[1]; - data->pd1 = input[2]; - } - - // check crc - if (header && data) - { - return input[3] == crc8(input, 3); - } - else - { - return false; - } -} +bool dissectAlohaPacket(uint8_t *input, HeaderStruct *header, DataStruct *data); #endif \ No newline at end of file
diff -r f790f35839db -r c3c6b13c3c42 Buffer.cpp --- a/Buffer.cpp Tue May 31 09:52:21 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -#include "Buffer.h" - -template <typename T> -CircularBuffer<T>::CircularBuffer(const uint32_t size) - :buffer_size(size) -{ - read_ptr = 0; - write_ptr = 0; - count = 0; - - // mutex lock - mux = false; - - // overflow - is_over_flow = false; - - // container - data = new T[buffer_size]; -} - -template <typename T> -CircularBuffer<T>::~CircularBuffer() -{ - delete[] data; -} - -template <typename T> -bool CircularBuffer<T>::isLocked() -{ - return mux; -} - -template <typename T> -void CircularBuffer<T>::lock() -{ - mux = true; -} - -template <typename T> -void CircularBuffer<T>::unlock() -{ - mux = false; -} - -template <typename T> -void CircularBuffer<T>::enqueue(T in) -{ - data[write_ptr++] = in; - write_ptr %= buffer_size; - - count++; -} - -template <typename T> -T CircularBuffer<T>::dequeue() -{ - T temp = data[read_ptr++]; - read_ptr %= buffer_size; - - count--; - return temp; -} - -template <typename T> -uint32_t CircularBuffer<T>::getReadPtr() -{ - return read_ptr; -} - -template <typename T> -uint32_t CircularBuffer<T>::getWritePtr() -{ - return write_ptr; -} - -template <typename T> -uint32_t CircularBuffer<T>::getCounter() -{ - return count; -} - -template <typename T> -bool CircularBuffer<T>::getOverFlow() -{ - return is_over_flow; -} - -template <typename T> -void CircularBuffer<T>::clearOverFlow() -{ - is_over_flow = false; -} - -template <typename T> -T CircularBuffer<T>::first() -{ - if (read_ptr > 0) - { - return data[read_ptr - 1]; - } - else - { - return data[read_ptr]; - } -} - -template <typename T> -T CircularBuffer<T>::last() -{ - if (write_ptr > 0) - { - return data[write_ptr - 1]; - } - else - { - return data[write_ptr]; - } -} - -template <typename T> -T CircularBuffer<T>::operator[](uint32_t idx) -{ - return data[idx]; -} - -// force compiler to create code for template -template class CircularBuffer<int>; -template class CircularBuffer<uint8_t>; -template class CircularBuffer<uint16_t>; -template class CircularBuffer<uint32_t>; \ No newline at end of file
diff -r f790f35839db -r c3c6b13c3c42 Buffer.h --- a/Buffer.h Tue May 31 09:52:21 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -#ifndef BUFFER_H_ -#define BUFFER_H_ - -#define DEFAULT_MAX_BUFFER_SZ 64 - -#include "stdint.h" - -template <typename T> -class CircularBuffer -{ -private: - const uint32_t buffer_size; - uint32_t read_ptr; - uint32_t write_ptr; - uint32_t count; - - // mutex lock - bool mux; - - // overflow - bool is_over_flow; - - // container - T *data; - - -public: - CircularBuffer(const uint32_t size=DEFAULT_MAX_BUFFER_SZ); - ~CircularBuffer(); - - // psudo mutex - bool isLocked(); - void lock(); - void unlock(); - - // enqueue and dequeue - void enqueue(T in); - T dequeue(); - - // pointer operation - uint32_t getReadPtr(); - uint32_t getWritePtr(); - uint32_t getCounter(); - - // overflow - bool getOverFlow(); - void clearOverFlow(); - - // operation - T first(); - T last(); - - // random access - T operator[](uint32_t idx); -}; - -#endif \ No newline at end of file
diff -r f790f35839db -r c3c6b13c3c42 crc.c --- a/crc.c Tue May 31 09:52:21 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#include "crc.h" - -uint8_t crc8(const uint8_t *data, int len) -{ - unsigned int crc = 0; - - for (int j = len; j; j--, data++) - { - crc ^= (*data << 8); - for (int i = 8; i; i--) - { - if (crc & 0x8000) - { - crc ^= (0x1070 << 3); - } - crc <<= 1; - } - } - - return (uint8_t)(crc >> 8); -} \ No newline at end of file
diff -r f790f35839db -r c3c6b13c3c42 crc.h --- a/crc.h Tue May 31 09:52:21 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -#ifndef CRC_H_ -#define CRC_H_ - -#include "stdint.h" - -/** - * Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. - * Reference: https://chromium.googlesource.com/chromiumos/platform/vboot_reference/+/master/firmware/lib/crc8.c - */ -uint8_t crc8(const uint8_t *data, int len); - -#endif \ No newline at end of file
diff -r f790f35839db -r c3c6b13c3c42 main.cpp --- a/main.cpp Tue May 31 09:52:21 2016 +0000 +++ b/main.cpp Wed Jun 08 22:15:29 2016 +0000 @@ -74,6 +74,49 @@ // aloha protocol Aloha aloha; +// user button +InterruptIn UserButton(USER_BUTTON); +static int seqid = 0; + +void sendMessage() +{ + HeaderStruct header; + DataStruct data; + + memset(&header, 0, sizeof(header)); + memset(&data, 0, sizeof(data)); + + header.fid = 0x0; + header.no = (uint8_t) seqid; + data.pd0 = 0xff; + data.pd1 = 0xff; + + uint8_t buffer[4]; + createAlohaPacket(buffer, &header, &data); + + Radio.Send(buffer, 4); +} + +void sendAck(int id) +{ + HeaderStruct header; + DataStruct data; + + memset(&header, 0, sizeof(header)); + memset(&data, 0, sizeof(data)); + + header.fid = 0x1; + header.no = (uint8_t) id; + data.pd0 = 0x00; + data.pd1 = 0x00; + + uint8_t buffer[4]; + createAlohaPacket(buffer, &header, &data); + + Radio.Send(buffer, 4); +} + + void setExpire() { if (aloha.attempts >= ALOHA_MAX_ATTEMPT) @@ -83,10 +126,15 @@ else { aloha.state = Aloha::RETRANSMIT; - aloha.delay = aloha.delay * aloha.delay; } } +void userButtonHandler() +{ + seqid += 1; + sendMessage(); +} + void RadioInit() { // Initialize Radio driver @@ -126,7 +174,9 @@ int main() { RadioInit(); + UserButton.rise(userButtonHandler); + Radio.Rx( RX_TIMEOUT_VALUE ); while (1) { switch( State ) @@ -135,36 +185,104 @@ // if the receive frame is an ack, then cancel the timer // otherwise process the frame HeaderStruct header; + DataStruct data; + memset(&header, 0, sizeof(header)); + memset(&data, 0, sizeof(data)); + // decode data + dissectAlohaPacket(Buffer, &header, &data); + + // process packet + switch (header.fid) + { + case 0x0: // data packet + sendAck(header.no); + break; + + case 0x1: // ack received + aloha.AlohaAckTimeout.detach(); + aloha.state = Aloha::IDLE; + break; + + default: + break; + } + if (header.fid == 0x01) { aloha.AlohaAckTimeout.detach(); } // TODO: process the frame + + + printf("RECV::fid=0x%x, seqid=0x%x, pd0=0x%x, pd1=0x%x\r\n", header.fid, header.no, data.pd0, data.pd1); + + // enter listening mode + Radio.Rx( RX_TIMEOUT_VALUE ); + + State = LOWPOWER; break; case TX: // transmit done - // then set state to aloha pending and start the timer + // set the state to pending and attach the timer with random delay + + // we dont need ack for ack + if (aloha.state == Aloha::ACK_RESP) + { + aloha.state = Aloha::IDLE; + break; + } + + // set delay time + if (aloha.state == Aloha::IDLE) + { + aloha.delay = (Radio.Random() % 1000) / 1000.0f; + } + else if (aloha.state == Aloha::RETRANSMIT) + { + aloha.delay *= 2; + } + + aloha.AlohaAckTimeout.detach(); + aloha.AlohaAckTimeout.attach(&setExpire, aloha.delay); + + // increase the attempt counter + aloha.attempts += 1; + + // enter listening mode + Radio.Rx( RX_TIMEOUT_VALUE ); + + // state transition aloha.state = Aloha::PENDING; - aloha.delay = Radio.Random(); - aloha.AlohaAckTimeout.detach(); - aloha.AlohaAckTimeout.attach_us(&setExpire, aloha.delay); - aloha.attempts += 1; + + State = LOWPOWER; break; case RX_TIMEOUT: // enter listening mode + Radio.Rx( RX_TIMEOUT_VALUE ); + + State = LOWPOWER; break; case RX_ERROR: // we don't handle crc failed situation + // enter listening mode + Radio.Rx( RX_TIMEOUT_VALUE ); + + State = LOWPOWER; break; case TX_TIMEOUT: // we don't handle hardware error + // enter listening mode + Radio.Rx( RX_TIMEOUT_VALUE ); + + State = LOWPOWER; break; case LOWPOWER: break; default: + State = LOWPOWER; break; } @@ -172,22 +290,31 @@ { case Aloha::IDLE: // transmit packet if any + // printf("Aloha::IDLE\r\n"); break; case Aloha::PENDING: // set rx time + // printf("Aloha::PENDING, delay=%f, attempt=%d\r\n", aloha.delay, aloha.attempts); break; case Aloha::RETRANSMIT: // send the packet again - // and setup the timer with new backoff delay - aloha.AlohaAckTimeout.attach(&setExpire, aloha.delay); - aloha.state = Aloha::PENDING; + sendMessage(); + + // printf("Aloha::RETRANSMIT\r\n"); break; case Aloha::EXPIRED: // give up the transmission // back to idle + aloha.attempts = 0; + aloha.state = Aloha::IDLE; + // printf("Aloha::EXPIRED\r\n"); + break; + case Aloha::ACK_RESP: + break; + default: break; } }