A library to send and receive packets over serial, uses MODSERIAL

Dependents:   SimpleSerialProtocolExample SerialFileReceiver

Committer:
p3p
Date:
Fri Sep 19 15:51:05 2014 +0000
Revision:
3:5caff50e14a7
Parent:
2:43794e0b738f
fixed packet detection when struggling to keep up with data stream

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3p 0:1639507580d5 1 #ifndef SIMPLE_SERIAL_PROTOCOL
p3p 0:1639507580d5 2 #define SIMPLE_SERIAL_PROTOCOL
p3p 0:1639507580d5 3
p3p 0:1639507580d5 4 #include <map>
p3p 0:1639507580d5 5 #include <vector>
p3p 0:1639507580d5 6
p3p 0:1639507580d5 7 #include "mbed.h"
p3p 0:1639507580d5 8 #include "MODSERIAL.h"
p3p 0:1639507580d5 9 #include "Packet.h"
p3p 2:43794e0b738f 10 #include "Codec.h"
p3p 0:1639507580d5 11 #include "FPointer.h"
p3p 0:1639507580d5 12 #include "Ringbuffer.h"
p3p 0:1639507580d5 13
p3p 0:1639507580d5 14 namespace SimpleSerialProtocol {
p3p 0:1639507580d5 15
p3p 0:1639507580d5 16 #define SEND_CHUNK_SIZE 512
p3p 0:1639507580d5 17
p3p 0:1639507580d5 18 class Protocol : public MODSERIAL {
p3p 0:1639507580d5 19 public:
p3p 0:1639507580d5 20 enum {
p3p 0:1639507580d5 21 PACKET_START,
p3p 0:1639507580d5 22 HEADER_RECEIVE,
p3p 0:1639507580d5 23 DATA_RECEIVE,
p3p 0:1639507580d5 24 DATA_VALIDATE,
p3p 0:1639507580d5 25 };
p3p 0:1639507580d5 26
p3p 0:1639507580d5 27 Protocol(PinName tx, PinName rx, PinName led_pin);
p3p 0:1639507580d5 28 virtual ~Protocol();
p3p 0:1639507580d5 29
p3p 3:5caff50e14a7 30 virtual void initialise(uint32_t baud) {
p3p 3:5caff50e14a7 31 MODSERIAL::baud(baud);
p3p 3:5caff50e14a7 32 }
p3p 3:5caff50e14a7 33
p3p 3:5caff50e14a7 34 void setCodec(ICodec* stream_codec){
p3p 2:43794e0b738f 35 codec = stream_codec;
p3p 0:1639507580d5 36 }
p3p 0:1639507580d5 37
p3p 1:98ad30934a71 38 virtual void update();
p3p 0:1639507580d5 39
p3p 0:1639507580d5 40 void send(uint8_t byte);
p3p 0:1639507580d5 41 void blockUntilTxEmpty();
p3p 0:1639507580d5 42
p3p 0:1639507580d5 43 void baud(uint32_t baud_rate) {
p3p 0:1639507580d5 44 blockUntilTxEmpty();
p3p 0:1639507580d5 45 MODSERIAL::baud(baud_rate);
p3p 0:1639507580d5 46 }
p3p 0:1639507580d5 47
p3p 0:1639507580d5 48 bool packetWaiting() {
p3p 0:1639507580d5 49 return _packet._valid;
p3p 0:1639507580d5 50 }
p3p 0:1639507580d5 51
p3p 0:1639507580d5 52 uint32_t _corrupt_packets;
p3p 0:1639507580d5 53 uint32_t _invalid_bytes;
p3p 0:1639507580d5 54
p3p 0:1639507580d5 55 uint32_t droppedBytes(){
p3p 0:1639507580d5 56 return _send_buffer.droppedBytes();
p3p 0:1639507580d5 57 }
p3p 0:1639507580d5 58
p3p 0:1639507580d5 59 uint32_t sendBufferSize(){
p3p 0:1639507580d5 60 return _send_buffer.available();
p3p 0:1639507580d5 61 }
p3p 0:1639507580d5 62
p3p 1:98ad30934a71 63 template<class T> void receiveCallback(uint8_t type, T* item, void (T::*method)(Protocol*, Packet*)) {
p3p 0:1639507580d5 64 FPointer callback;
p3p 0:1639507580d5 65 callback.attach(item, (void (T::*)(Packet*))method);
p3p 0:1639507580d5 66 _callback[type].push_back(callback);
p3p 0:1639507580d5 67 }
p3p 0:1639507580d5 68
p3p 1:98ad30934a71 69 template<class T> void transmitCallback(float frequency, T* item, void (T::*method)(Protocol*, Packet*)) {
p3p 0:1639507580d5 70 FPointer callback;
p3p 0:1639507580d5 71 callback.attach(item, (void (T::*)(Packet*))method);
p3p 0:1639507580d5 72 _transmit_callback.push_back(TimerData(frequency, callback));
p3p 0:1639507580d5 73 }
p3p 0:1639507580d5 74
p3p 2:43794e0b738f 75 virtual void send(Packet* packet);
p3p 2:43794e0b738f 76
p3p 2:43794e0b738f 77 void transmit();
p3p 2:43794e0b738f 78 void receive();
p3p 0:1639507580d5 79
p3p 0:1639507580d5 80 DigitalOut _receive_led;
p3p 0:1639507580d5 81 Packet _packet;
p3p 0:1639507580d5 82 Packet _packet_transmit;
p3p 0:1639507580d5 83
p3p 0:1639507580d5 84 Timer _receive_timeout;
p3p 0:1639507580d5 85 Timer _throttle_transfer;
p3p 0:1639507580d5 86
p3p 0:1639507580d5 87 struct TimerData {
p3p 0:1639507580d5 88 TimerData(float frequency, FPointer callback) {
p3p 0:1639507580d5 89 _timer.start();
p3p 0:1639507580d5 90 _frequency = frequency;
p3p 0:1639507580d5 91 _callback = callback;
p3p 0:1639507580d5 92 }
p3p 0:1639507580d5 93 bool trigger() {
p3p 0:1639507580d5 94 if (_timer.read_us() > _frequency) {
p3p 0:1639507580d5 95 _timer.reset();
p3p 0:1639507580d5 96 return true;
p3p 0:1639507580d5 97 }
p3p 0:1639507580d5 98 return false;
p3p 0:1639507580d5 99 }
p3p 0:1639507580d5 100 Timer _timer;
p3p 0:1639507580d5 101 float _frequency;
p3p 0:1639507580d5 102 FPointer _callback;
p3p 0:1639507580d5 103 };
p3p 0:1639507580d5 104
p3p 0:1639507580d5 105 RingBuffer _send_buffer;
p3p 0:1639507580d5 106 std::map<uint8_t, std::vector<FPointer> > _callback;
p3p 0:1639507580d5 107 std::vector<TimerData> _transmit_callback;
p3p 2:43794e0b738f 108 ICodec* codec;
p3p 3:5caff50e14a7 109 Codec default_codec;
p3p 0:1639507580d5 110 };
p3p 0:1639507580d5 111
p3p 0:1639507580d5 112 }
p3p 0:1639507580d5 113
p3p 0:1639507580d5 114 #endif