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

Dependents:   SimpleSerialProtocolExample SerialFileReceiver

Protocol.h

Committer:
p3p
Date:
2014-09-19
Revision:
3:5caff50e14a7
Parent:
2:43794e0b738f

File content as of revision 3:5caff50e14a7:

#ifndef SIMPLE_SERIAL_PROTOCOL
#define SIMPLE_SERIAL_PROTOCOL

#include <map>
#include <vector>

#include "mbed.h"
#include "MODSERIAL.h"
#include "Packet.h"
#include "Codec.h"
#include "FPointer.h"
#include "Ringbuffer.h"

namespace SimpleSerialProtocol {

#define SEND_CHUNK_SIZE 512

class Protocol : public MODSERIAL {
public:
    enum {
        PACKET_START,
        HEADER_RECEIVE,
        DATA_RECEIVE,
        DATA_VALIDATE,
    };
    
    Protocol(PinName tx, PinName rx, PinName led_pin);
    virtual ~Protocol();

    virtual void initialise(uint32_t baud) {
        MODSERIAL::baud(baud);
    }
    
    void setCodec(ICodec* stream_codec){
        codec = stream_codec;
    }
    
    virtual void update();
    
    void send(uint8_t byte);
    void blockUntilTxEmpty();
    
    void baud(uint32_t baud_rate) {
        blockUntilTxEmpty();
        MODSERIAL::baud(baud_rate);
    }

    bool packetWaiting() {
        return _packet._valid;
    }

    uint32_t _corrupt_packets;
    uint32_t _invalid_bytes;
    
    uint32_t droppedBytes(){
        return _send_buffer.droppedBytes();
    }
    
    uint32_t sendBufferSize(){
        return _send_buffer.available();
    }

    template<class T> void receiveCallback(uint8_t type, T* item, void (T::*method)(Protocol*, Packet*)) {
        FPointer callback;
        callback.attach(item, (void (T::*)(Packet*))method);
        _callback[type].push_back(callback);
    }

    template<class T> void transmitCallback(float frequency, T* item, void (T::*method)(Protocol*, Packet*)) {
        FPointer callback;
        callback.attach(item, (void (T::*)(Packet*))method);
        _transmit_callback.push_back(TimerData(frequency, callback));
    }

    virtual void send(Packet* packet);

    void transmit();
    void receive();

    DigitalOut _receive_led;
    Packet _packet;
    Packet _packet_transmit;
    
    Timer _receive_timeout;
    Timer _throttle_transfer;
    
    struct TimerData {
        TimerData(float frequency, FPointer callback) {
            _timer.start();
            _frequency = frequency;
            _callback = callback;
        }
        bool trigger() {
            if (_timer.read_us() > _frequency) {
                _timer.reset();
                return true;
            }
            return false;
        }
        Timer _timer;
        float _frequency;
        FPointer _callback;
    };

    RingBuffer _send_buffer;
    std::map<uint8_t, std::vector<FPointer> > _callback;
    std::vector<TimerData> _transmit_callback;
    ICodec* codec;
    Codec default_codec;
};

}

#endif