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@0:1639507580d5, 2012-06-28 (annotated)
- Committer:
- p3p
- Date:
- Thu Jun 28 21:19:58 2012 +0000
- Revision:
- 0:1639507580d5
- Child:
- 1:98ad30934a71
minor tweak
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 | HEADER_DECODE, |
| p3p | 0:1639507580d5 | 23 | DATA_RECEIVE, |
| p3p | 0:1639507580d5 | 24 | FOOTER_RECEIVE, |
| p3p | 0:1639507580d5 | 25 | DATA_VALIDATE, |
| p3p | 0:1639507580d5 | 26 | PACKET_VALID, |
| p3p | 0:1639507580d5 | 27 | PACKET_RESET |
| p3p | 0:1639507580d5 | 28 | }; |
| p3p | 0:1639507580d5 | 29 | |
| p3p | 0:1639507580d5 | 30 | Timer testDma; |
| p3p | 0:1639507580d5 | 31 | uint32_t testDmaTime; |
| p3p | 0:1639507580d5 | 32 | |
| p3p | 0:1639507580d5 | 33 | Protocol(PinName tx, PinName rx, PinName led_pin); |
| p3p | 0:1639507580d5 | 34 | virtual ~Protocol(); |
| p3p | 0:1639507580d5 | 35 | |
| p3p | 0:1639507580d5 | 36 | virtual void initialise() { |
| p3p | 0:1639507580d5 | 37 | MODSERIAL::baud(115200); |
| p3p | 0:1639507580d5 | 38 | } |
| p3p | 0:1639507580d5 | 39 | |
| p3p | 0:1639507580d5 | 40 | void update(); |
| p3p | 0:1639507580d5 | 41 | |
| p3p | 0:1639507580d5 | 42 | int printf( const char * format, ...); |
| p3p | 0:1639507580d5 | 43 | int puts( const char * str); |
| p3p | 0:1639507580d5 | 44 | int putc( int character); |
| p3p | 0:1639507580d5 | 45 | void send(uint8_t byte); |
| p3p | 0:1639507580d5 | 46 | void blockUntilTxEmpty(); |
| p3p | 0:1639507580d5 | 47 | |
| p3p | 0:1639507580d5 | 48 | void baud(uint32_t baud_rate) { |
| p3p | 0:1639507580d5 | 49 | blockUntilTxEmpty(); |
| p3p | 0:1639507580d5 | 50 | MODSERIAL::baud(baud_rate); |
| p3p | 0:1639507580d5 | 51 | } |
| p3p | 0:1639507580d5 | 52 | |
| p3p | 0:1639507580d5 | 53 | bool packetWaiting() { |
| p3p | 0:1639507580d5 | 54 | return _packet._valid; |
| p3p | 0:1639507580d5 | 55 | } |
| p3p | 0:1639507580d5 | 56 | |
| p3p | 0:1639507580d5 | 57 | uint32_t _corrupt_packets; |
| p3p | 0:1639507580d5 | 58 | uint32_t _invalid_bytes; |
| p3p | 0:1639507580d5 | 59 | |
| p3p | 0:1639507580d5 | 60 | uint32_t droppedBytes(){ |
| p3p | 0:1639507580d5 | 61 | return _send_buffer.droppedBytes(); |
| p3p | 0:1639507580d5 | 62 | } |
| p3p | 0:1639507580d5 | 63 | |
| p3p | 0:1639507580d5 | 64 | uint32_t sendBufferSize(){ |
| p3p | 0:1639507580d5 | 65 | return _send_buffer.available(); |
| p3p | 0:1639507580d5 | 66 | } |
| p3p | 0:1639507580d5 | 67 | |
| p3p | 0:1639507580d5 | 68 | template<class T> void receiveCallback(uint8_t type, T* item, void (T::*method)(Packet*)) { |
| p3p | 0:1639507580d5 | 69 | FPointer callback; |
| p3p | 0:1639507580d5 | 70 | callback.attach(item, (void (T::*)(Packet*))method); |
| p3p | 0:1639507580d5 | 71 | _callback[type].push_back(callback); |
| p3p | 0:1639507580d5 | 72 | } |
| p3p | 0:1639507580d5 | 73 | |
| p3p | 0:1639507580d5 | 74 | template<class T> void transmitCallback(float frequency, T* item, void (T::*method)(Packet*)) { |
| p3p | 0:1639507580d5 | 75 | FPointer callback; |
| p3p | 0:1639507580d5 | 76 | callback.attach(item, (void (T::*)(Packet*))method); |
| p3p | 0:1639507580d5 | 77 | _transmit_callback.push_back(TimerData(frequency, callback)); |
| p3p | 0:1639507580d5 | 78 | } |
| p3p | 0:1639507580d5 | 79 | |
| p3p | 0:1639507580d5 | 80 | protected: |
| p3p | 0:1639507580d5 | 81 | virtual void sendPacket(Packet* packet) { |
| p3p | 0:1639507580d5 | 82 | if (packet!=0) { |
| p3p | 0:1639507580d5 | 83 | send(255); |
| p3p | 0:1639507580d5 | 84 | send(127); |
| p3p | 0:1639507580d5 | 85 | send(packet->_size); |
| p3p | 0:1639507580d5 | 86 | for (int i = 0; i < packet->_size; i++) { |
| p3p | 0:1639507580d5 | 87 | send(packet->_data[i]); |
| p3p | 0:1639507580d5 | 88 | } |
| p3p | 0:1639507580d5 | 89 | send(checksum(packet->_data, packet->_size)); |
| p3p | 0:1639507580d5 | 90 | } |
| p3p | 0:1639507580d5 | 91 | } |
| p3p | 0:1639507580d5 | 92 | |
| p3p | 0:1639507580d5 | 93 | DigitalOut _receive_led; |
| p3p | 0:1639507580d5 | 94 | Packet _packet; |
| p3p | 0:1639507580d5 | 95 | Packet _packet_transmit; |
| p3p | 0:1639507580d5 | 96 | |
| p3p | 0:1639507580d5 | 97 | Timer _receive_timeout; |
| p3p | 0:1639507580d5 | 98 | Timer _throttle_transfer; |
| p3p | 0:1639507580d5 | 99 | |
| p3p | 0:1639507580d5 | 100 | void send(); |
| p3p | 0:1639507580d5 | 101 | virtual void receive(); |
| p3p | 0:1639507580d5 | 102 | static uint8_t checksum(uint8_t* packet, uint16_t packet_size); |
| p3p | 0:1639507580d5 | 103 | |
| p3p | 0:1639507580d5 | 104 | struct TimerData { |
| p3p | 0:1639507580d5 | 105 | TimerData(float frequency, FPointer callback) { |
| p3p | 0:1639507580d5 | 106 | _timer.start(); |
| p3p | 0:1639507580d5 | 107 | _frequency = frequency; |
| p3p | 0:1639507580d5 | 108 | _callback = callback; |
| p3p | 0:1639507580d5 | 109 | } |
| p3p | 0:1639507580d5 | 110 | bool trigger() { |
| p3p | 0:1639507580d5 | 111 | if (_timer.read_us() > _frequency) { |
| p3p | 0:1639507580d5 | 112 | _timer.reset(); |
| p3p | 0:1639507580d5 | 113 | return true; |
| p3p | 0:1639507580d5 | 114 | } |
| p3p | 0:1639507580d5 | 115 | return false; |
| p3p | 0:1639507580d5 | 116 | } |
| p3p | 0:1639507580d5 | 117 | Timer _timer; |
| p3p | 0:1639507580d5 | 118 | float _frequency; |
| p3p | 0:1639507580d5 | 119 | FPointer _callback; |
| p3p | 0:1639507580d5 | 120 | }; |
| p3p | 0:1639507580d5 | 121 | |
| p3p | 0:1639507580d5 | 122 | uint8_t _header[2]; |
| p3p | 0:1639507580d5 | 123 | uint8_t _header_read; |
| p3p | 0:1639507580d5 | 124 | uint8_t _data_read; |
| p3p | 0:1639507580d5 | 125 | uint8_t _footer[4]; |
| p3p | 0:1639507580d5 | 126 | uint8_t _footer_read; |
| p3p | 0:1639507580d5 | 127 | uint8_t _state; |
| p3p | 0:1639507580d5 | 128 | uint8_t _last_byte; |
| p3p | 0:1639507580d5 | 129 | |
| p3p | 0:1639507580d5 | 130 | bool _transfer_in_progress; |
| p3p | 0:1639507580d5 | 131 | uint8_t _dma_buffer[SEND_CHUNK_SIZE]; |
| p3p | 0:1639507580d5 | 132 | |
| p3p | 0:1639507580d5 | 133 | RingBuffer _send_buffer; |
| p3p | 0:1639507580d5 | 134 | std::map<uint8_t, std::vector<FPointer> > _callback; |
| p3p | 0:1639507580d5 | 135 | std::vector<TimerData> _transmit_callback; |
| p3p | 0:1639507580d5 | 136 | }; |
| p3p | 0:1639507580d5 | 137 | |
| p3p | 0:1639507580d5 | 138 | } |
| p3p | 0:1639507580d5 | 139 | |
| p3p | 0:1639507580d5 | 140 | #endif |