A library to send and receive packets over serial, uses MODSERIAL
Dependents: SimpleSerialProtocolExample SerialFileReceiver
Protocol.cpp@3:5caff50e14a7, 2014-09-19 (annotated)
- 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?
User | Revision | Line number | New contents of line |
---|---|---|---|
p3p | 0:1639507580d5 | 1 | #include "Protocol.h" |
p3p | 0:1639507580d5 | 2 | |
p3p | 0:1639507580d5 | 3 | namespace SimpleSerialProtocol { |
p3p | 0:1639507580d5 | 4 | |
p3p | 1:98ad30934a71 | 5 | Protocol::Protocol(PinName tx, PinName rx, PinName led_pin) : MODSERIAL(tx, rx, 64, 512), _receive_led(led_pin), _send_buffer(512){ |
p3p | 2:43794e0b738f | 6 | _receive_timeout.start(); |
p3p | 3:5caff50e14a7 | 7 | codec = &default_codec; |
p3p | 0:1639507580d5 | 8 | } |
p3p | 0:1639507580d5 | 9 | |
p3p | 0:1639507580d5 | 10 | Protocol::~Protocol() { |
p3p | 2:43794e0b738f | 11 | codec = 0; |
p3p | 0:1639507580d5 | 12 | } |
p3p | 0:1639507580d5 | 13 | |
p3p | 0:1639507580d5 | 14 | void Protocol::blockUntilTxEmpty(){ |
p3p | 0:1639507580d5 | 15 | while(_send_buffer.available()){ |
p3p | 0:1639507580d5 | 16 | MODSERIAL::putc(_send_buffer.read()); |
p3p | 0:1639507580d5 | 17 | } |
p3p | 2:43794e0b738f | 18 | while(!MODSERIAL::txBufferEmpty()); |
p3p | 0:1639507580d5 | 19 | return; |
p3p | 0:1639507580d5 | 20 | } |
p3p | 0:1639507580d5 | 21 | |
p3p | 0:1639507580d5 | 22 | void Protocol::update() { |
p3p | 0:1639507580d5 | 23 | for (uint16_t j = 0; j < _transmit_callback.size(); j++) { |
p3p | 0:1639507580d5 | 24 | if (_transmit_callback[j].trigger()) { |
p3p | 1:98ad30934a71 | 25 | _transmit_callback[j]._callback.call(this, &_packet_transmit); |
p3p | 2:43794e0b738f | 26 | send(&_packet_transmit); |
p3p | 0:1639507580d5 | 27 | _packet_transmit.reset(); |
p3p | 0:1639507580d5 | 28 | } |
p3p | 0:1639507580d5 | 29 | } |
p3p | 0:1639507580d5 | 30 | |
p3p | 2:43794e0b738f | 31 | transmit(); |
p3p | 0:1639507580d5 | 32 | receive(); |
p3p | 0:1639507580d5 | 33 | |
p3p | 0:1639507580d5 | 34 | if (packetWaiting()) { |
p3p | 0:1639507580d5 | 35 | _receive_led = 1; |
p3p | 0:1639507580d5 | 36 | if (_callback.count(_packet._type)) { |
p3p | 0:1639507580d5 | 37 | for (uint16_t i = 0; i < _callback[_packet._type].size(); i++) { |
p3p | 1:98ad30934a71 | 38 | _callback[_packet._type][i].call(this, &_packet); |
p3p | 0:1639507580d5 | 39 | } |
p3p | 0:1639507580d5 | 40 | } |
p3p | 0:1639507580d5 | 41 | _packet.reset(); |
p3p | 3:5caff50e14a7 | 42 | _receive_led = 0; |
p3p | 0:1639507580d5 | 43 | } |
p3p | 0:1639507580d5 | 44 | } |
p3p | 0:1639507580d5 | 45 | |
p3p | 0:1639507580d5 | 46 | void Protocol::send(uint8_t byte) { |
p3p | 0:1639507580d5 | 47 | _send_buffer.write(byte); |
p3p | 0:1639507580d5 | 48 | } |
p3p | 0:1639507580d5 | 49 | |
p3p | 2:43794e0b738f | 50 | void Protocol::transmit() { |
p3p | 0:1639507580d5 | 51 | |
p3p | 0:1639507580d5 | 52 | uint16_t buffer_size = _send_buffer.available(); |
p3p | 0:1639507580d5 | 53 | uint16_t send_length = 0; |
p3p | 0:1639507580d5 | 54 | |
p3p | 0:1639507580d5 | 55 | if (buffer_size < SEND_CHUNK_SIZE) { |
p3p | 0:1639507580d5 | 56 | send_length = buffer_size; |
p3p | 0:1639507580d5 | 57 | } else { |
p3p | 0:1639507580d5 | 58 | send_length = SEND_CHUNK_SIZE; |
p3p | 0:1639507580d5 | 59 | } |
p3p | 0:1639507580d5 | 60 | |
p3p | 0:1639507580d5 | 61 | if ( buffer_size ) { |
p3p | 0:1639507580d5 | 62 | for (int i = 0; i < send_length; i++) { |
p3p | 0:1639507580d5 | 63 | MODSERIAL::putc(_send_buffer.read()); |
p3p | 0:1639507580d5 | 64 | } |
p3p | 0:1639507580d5 | 65 | } |
p3p | 0:1639507580d5 | 66 | } |
p3p | 0:1639507580d5 | 67 | |
p3p | 0:1639507580d5 | 68 | void Protocol::receive() { |
p3p | 0:1639507580d5 | 69 | _receive_timeout.reset(); |
p3p | 3:5caff50e14a7 | 70 | while ((MODSERIAL::rxBufferGetCount() > 0 && _receive_timeout.read_us() < 50) && !_packet._valid) { |
p3p | 2:43794e0b738f | 71 | if(codec){ |
p3p | 2:43794e0b738f | 72 | codec->decode(&_packet, MODSERIAL::getc()); |
p3p | 0:1639507580d5 | 73 | } |
p3p | 0:1639507580d5 | 74 | } |
p3p | 0:1639507580d5 | 75 | } |
p3p | 0:1639507580d5 | 76 | |
p3p | 2:43794e0b738f | 77 | void Protocol::send(Packet* packet) { |
p3p | 2:43794e0b738f | 78 | if (packet != 0) { |
p3p | 2:43794e0b738f | 79 | if(codec){ |
p3p | 2:43794e0b738f | 80 | codec->encode(packet, &_send_buffer); |
p3p | 2:43794e0b738f | 81 | } |
p3p | 0:1639507580d5 | 82 | } |
p3p | 0:1639507580d5 | 83 | } |
p3p | 0:1639507580d5 | 84 | |
p3p | 0:1639507580d5 | 85 | } |