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

Dependents:   SimpleSerialProtocolExample SerialFileReceiver

Committer:
p3p
Date:
Thu Sep 18 17:37:04 2014 +0000
Revision:
2:43794e0b738f
Parent:
1:98ad30934a71
Child:
3:5caff50e14a7
Refactored Protocol format into a separate codec class, implementing multiple codecs is now simple

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 2:43794e0b738f 30 virtual void initialise(uint32_t baud, ICodec* stream_codec) {
p3p 2:43794e0b738f 31 codec = stream_codec;
p3p 1:98ad30934a71 32 MODSERIAL::baud(baud);
p3p 0:1639507580d5 33 }
p3p 0:1639507580d5 34
p3p 1:98ad30934a71 35 virtual void update();
p3p 0:1639507580d5 36
p3p 0:1639507580d5 37 void send(uint8_t byte);
p3p 0:1639507580d5 38 void blockUntilTxEmpty();
p3p 0:1639507580d5 39
p3p 0:1639507580d5 40 void baud(uint32_t baud_rate) {
p3p 0:1639507580d5 41 blockUntilTxEmpty();
p3p 0:1639507580d5 42 MODSERIAL::baud(baud_rate);
p3p 0:1639507580d5 43 }
p3p 0:1639507580d5 44
p3p 0:1639507580d5 45 bool packetWaiting() {
p3p 0:1639507580d5 46 return _packet._valid;
p3p 0:1639507580d5 47 }
p3p 0:1639507580d5 48
p3p 0:1639507580d5 49 uint32_t _corrupt_packets;
p3p 0:1639507580d5 50 uint32_t _invalid_bytes;
p3p 0:1639507580d5 51
p3p 0:1639507580d5 52 uint32_t droppedBytes(){
p3p 0:1639507580d5 53 return _send_buffer.droppedBytes();
p3p 0:1639507580d5 54 }
p3p 0:1639507580d5 55
p3p 0:1639507580d5 56 uint32_t sendBufferSize(){
p3p 0:1639507580d5 57 return _send_buffer.available();
p3p 0:1639507580d5 58 }
p3p 0:1639507580d5 59
p3p 1:98ad30934a71 60 template<class T> void receiveCallback(uint8_t type, T* item, void (T::*method)(Protocol*, Packet*)) {
p3p 0:1639507580d5 61 FPointer callback;
p3p 0:1639507580d5 62 callback.attach(item, (void (T::*)(Packet*))method);
p3p 0:1639507580d5 63 _callback[type].push_back(callback);
p3p 0:1639507580d5 64 }
p3p 0:1639507580d5 65
p3p 1:98ad30934a71 66 template<class T> void transmitCallback(float frequency, T* item, void (T::*method)(Protocol*, Packet*)) {
p3p 0:1639507580d5 67 FPointer callback;
p3p 0:1639507580d5 68 callback.attach(item, (void (T::*)(Packet*))method);
p3p 0:1639507580d5 69 _transmit_callback.push_back(TimerData(frequency, callback));
p3p 0:1639507580d5 70 }
p3p 0:1639507580d5 71
p3p 2:43794e0b738f 72 virtual void send(Packet* packet);
p3p 2:43794e0b738f 73
p3p 2:43794e0b738f 74 void transmit();
p3p 2:43794e0b738f 75 void receive();
p3p 0:1639507580d5 76
p3p 0:1639507580d5 77 DigitalOut _receive_led;
p3p 0:1639507580d5 78 Packet _packet;
p3p 0:1639507580d5 79 Packet _packet_transmit;
p3p 0:1639507580d5 80
p3p 0:1639507580d5 81 Timer _receive_timeout;
p3p 0:1639507580d5 82 Timer _throttle_transfer;
p3p 0:1639507580d5 83
p3p 0:1639507580d5 84 struct TimerData {
p3p 0:1639507580d5 85 TimerData(float frequency, FPointer callback) {
p3p 0:1639507580d5 86 _timer.start();
p3p 0:1639507580d5 87 _frequency = frequency;
p3p 0:1639507580d5 88 _callback = callback;
p3p 0:1639507580d5 89 }
p3p 0:1639507580d5 90 bool trigger() {
p3p 0:1639507580d5 91 if (_timer.read_us() > _frequency) {
p3p 0:1639507580d5 92 _timer.reset();
p3p 0:1639507580d5 93 return true;
p3p 0:1639507580d5 94 }
p3p 0:1639507580d5 95 return false;
p3p 0:1639507580d5 96 }
p3p 0:1639507580d5 97 Timer _timer;
p3p 0:1639507580d5 98 float _frequency;
p3p 0:1639507580d5 99 FPointer _callback;
p3p 0:1639507580d5 100 };
p3p 0:1639507580d5 101
p3p 0:1639507580d5 102 RingBuffer _send_buffer;
p3p 0:1639507580d5 103 std::map<uint8_t, std::vector<FPointer> > _callback;
p3p 0:1639507580d5 104 std::vector<TimerData> _transmit_callback;
p3p 2:43794e0b738f 105 ICodec* codec;
p3p 0:1639507580d5 106 };
p3p 0:1639507580d5 107
p3p 0:1639507580d5 108 }
p3p 0:1639507580d5 109
p3p 0:1639507580d5 110 #endif