Chris Pepper / SimpleSerialProtocol

Dependents:   SimpleSerialProtocolExample SerialFileReceiver

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?

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 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