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.
Dependents: SimpleSerialProtocolExample SerialFileReceiver
Protocol.h@1:98ad30934a71, 2014-08-27 (annotated)
- Committer:
- p3p
- Date:
- Wed Aug 27 17:35:30 2014 +0000
- Revision:
- 1:98ad30934a71
- Parent:
- 0:1639507580d5
- Child:
- 2:43794e0b738f
Fixed the packet state machine, and added access to the protocol from callbacks
Who changed what in which revision?
| User | Revision | Line number | New 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 | 0:1639507580d5 | 10 | #include "FPointer.h" | 
| p3p | 0:1639507580d5 | 11 | #include "Ringbuffer.h" | 
| p3p | 0:1639507580d5 | 12 | |
| p3p | 0:1639507580d5 | 13 | namespace SimpleSerialProtocol { | 
| p3p | 0:1639507580d5 | 14 | |
| p3p | 0:1639507580d5 | 15 | #define SEND_CHUNK_SIZE 512 | 
| p3p | 0:1639507580d5 | 16 | |
| p3p | 0:1639507580d5 | 17 | class Protocol : public MODSERIAL { | 
| p3p | 0:1639507580d5 | 18 | public: | 
| p3p | 0:1639507580d5 | 19 | enum { | 
| p3p | 0:1639507580d5 | 20 | PACKET_START, | 
| p3p | 0:1639507580d5 | 21 | HEADER_RECEIVE, | 
| p3p | 0:1639507580d5 | 22 | DATA_RECEIVE, | 
| p3p | 0:1639507580d5 | 23 | DATA_VALIDATE, | 
| p3p | 0:1639507580d5 | 24 | }; | 
| p3p | 0:1639507580d5 | 25 | |
| p3p | 0:1639507580d5 | 26 | Protocol(PinName tx, PinName rx, PinName led_pin); | 
| p3p | 0:1639507580d5 | 27 | virtual ~Protocol(); | 
| p3p | 0:1639507580d5 | 28 | |
| p3p | 1:98ad30934a71 | 29 | virtual void initialise(uint32_t baud) { | 
| p3p | 1:98ad30934a71 | 30 | MODSERIAL::baud(baud); | 
| p3p | 0:1639507580d5 | 31 | } | 
| p3p | 0:1639507580d5 | 32 | |
| p3p | 1:98ad30934a71 | 33 | virtual void update(); | 
| p3p | 0:1639507580d5 | 34 | |
| p3p | 0:1639507580d5 | 35 | void send(uint8_t byte); | 
| p3p | 0:1639507580d5 | 36 | void blockUntilTxEmpty(); | 
| p3p | 0:1639507580d5 | 37 | |
| p3p | 0:1639507580d5 | 38 | void baud(uint32_t baud_rate) { | 
| p3p | 0:1639507580d5 | 39 | blockUntilTxEmpty(); | 
| p3p | 0:1639507580d5 | 40 | MODSERIAL::baud(baud_rate); | 
| p3p | 0:1639507580d5 | 41 | } | 
| p3p | 0:1639507580d5 | 42 | |
| p3p | 0:1639507580d5 | 43 | bool packetWaiting() { | 
| p3p | 0:1639507580d5 | 44 | return _packet._valid; | 
| p3p | 0:1639507580d5 | 45 | } | 
| p3p | 0:1639507580d5 | 46 | |
| p3p | 0:1639507580d5 | 47 | uint32_t _corrupt_packets; | 
| p3p | 0:1639507580d5 | 48 | uint32_t _invalid_bytes; | 
| p3p | 0:1639507580d5 | 49 | |
| p3p | 0:1639507580d5 | 50 | uint32_t droppedBytes(){ | 
| p3p | 0:1639507580d5 | 51 | return _send_buffer.droppedBytes(); | 
| p3p | 0:1639507580d5 | 52 | } | 
| p3p | 0:1639507580d5 | 53 | |
| p3p | 0:1639507580d5 | 54 | uint32_t sendBufferSize(){ | 
| p3p | 0:1639507580d5 | 55 | return _send_buffer.available(); | 
| p3p | 0:1639507580d5 | 56 | } | 
| p3p | 0:1639507580d5 | 57 | |
| p3p | 1:98ad30934a71 | 58 | template<class T> void receiveCallback(uint8_t type, T* item, void (T::*method)(Protocol*, Packet*)) { | 
| p3p | 0:1639507580d5 | 59 | FPointer callback; | 
| p3p | 0:1639507580d5 | 60 | callback.attach(item, (void (T::*)(Packet*))method); | 
| p3p | 0:1639507580d5 | 61 | _callback[type].push_back(callback); | 
| p3p | 0:1639507580d5 | 62 | } | 
| p3p | 0:1639507580d5 | 63 | |
| p3p | 1:98ad30934a71 | 64 | template<class T> void transmitCallback(float frequency, T* item, void (T::*method)(Protocol*, Packet*)) { | 
| p3p | 0:1639507580d5 | 65 | FPointer callback; | 
| p3p | 0:1639507580d5 | 66 | callback.attach(item, (void (T::*)(Packet*))method); | 
| p3p | 0:1639507580d5 | 67 | _transmit_callback.push_back(TimerData(frequency, callback)); | 
| p3p | 0:1639507580d5 | 68 | } | 
| p3p | 0:1639507580d5 | 69 | |
| p3p | 0:1639507580d5 | 70 | virtual void sendPacket(Packet* packet) { | 
| p3p | 0:1639507580d5 | 71 | if (packet!=0) { | 
| p3p | 0:1639507580d5 | 72 | send(255); | 
| p3p | 0:1639507580d5 | 73 | send(127); | 
| p3p | 0:1639507580d5 | 74 | send(packet->_size); | 
| p3p | 0:1639507580d5 | 75 | for (int i = 0; i < packet->_size; i++) { | 
| p3p | 0:1639507580d5 | 76 | send(packet->_data[i]); | 
| p3p | 0:1639507580d5 | 77 | } | 
| p3p | 0:1639507580d5 | 78 | send(checksum(packet->_data, packet->_size)); | 
| p3p | 0:1639507580d5 | 79 | } | 
| p3p | 0:1639507580d5 | 80 | } | 
| p3p | 0:1639507580d5 | 81 | |
| p3p | 0:1639507580d5 | 82 | DigitalOut _receive_led; | 
| p3p | 0:1639507580d5 | 83 | Packet _packet; | 
| p3p | 0:1639507580d5 | 84 | Packet _packet_transmit; | 
| p3p | 0:1639507580d5 | 85 | |
| p3p | 0:1639507580d5 | 86 | Timer _receive_timeout; | 
| p3p | 0:1639507580d5 | 87 | Timer _throttle_transfer; | 
| p3p | 0:1639507580d5 | 88 | |
| p3p | 0:1639507580d5 | 89 | void send(); | 
| p3p | 0:1639507580d5 | 90 | virtual void receive(); | 
| p3p | 0:1639507580d5 | 91 | static uint8_t checksum(uint8_t* packet, uint16_t packet_size); | 
| p3p | 0:1639507580d5 | 92 | |
| p3p | 0:1639507580d5 | 93 | struct TimerData { | 
| p3p | 0:1639507580d5 | 94 | TimerData(float frequency, FPointer callback) { | 
| p3p | 0:1639507580d5 | 95 | _timer.start(); | 
| p3p | 0:1639507580d5 | 96 | _frequency = frequency; | 
| p3p | 0:1639507580d5 | 97 | _callback = callback; | 
| p3p | 0:1639507580d5 | 98 | } | 
| p3p | 0:1639507580d5 | 99 | bool trigger() { | 
| p3p | 0:1639507580d5 | 100 | if (_timer.read_us() > _frequency) { | 
| p3p | 0:1639507580d5 | 101 | _timer.reset(); | 
| p3p | 0:1639507580d5 | 102 | return true; | 
| p3p | 0:1639507580d5 | 103 | } | 
| p3p | 0:1639507580d5 | 104 | return false; | 
| p3p | 0:1639507580d5 | 105 | } | 
| p3p | 0:1639507580d5 | 106 | Timer _timer; | 
| p3p | 0:1639507580d5 | 107 | float _frequency; | 
| p3p | 0:1639507580d5 | 108 | FPointer _callback; | 
| p3p | 0:1639507580d5 | 109 | }; | 
| p3p | 0:1639507580d5 | 110 | |
| p3p | 0:1639507580d5 | 111 | uint8_t _header[2]; | 
| p3p | 0:1639507580d5 | 112 | uint8_t _header_read; | 
| p3p | 0:1639507580d5 | 113 | uint8_t _data_read; | 
| p3p | 0:1639507580d5 | 114 | uint8_t _footer[4]; | 
| p3p | 0:1639507580d5 | 115 | uint8_t _footer_read; | 
| p3p | 0:1639507580d5 | 116 | uint8_t _state; | 
| p3p | 0:1639507580d5 | 117 | uint8_t _last_byte; | 
| p3p | 0:1639507580d5 | 118 | |
| p3p | 0:1639507580d5 | 119 | |
| p3p | 0:1639507580d5 | 120 | RingBuffer _send_buffer; | 
| p3p | 0:1639507580d5 | 121 | std::map<uint8_t, std::vector<FPointer> > _callback; | 
| p3p | 0:1639507580d5 | 122 | std::vector<TimerData> _transmit_callback; | 
| p3p | 0:1639507580d5 | 123 | }; | 
| p3p | 0:1639507580d5 | 124 | |
| p3p | 0:1639507580d5 | 125 | } | 
| p3p | 0:1639507580d5 | 126 | |
| p3p | 0:1639507580d5 | 127 | #endif |