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

Dependents:   SimpleSerialProtocolExample SerialFileReceiver

Protocol.cpp

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

File content as of revision 3:5caff50e14a7:

#include "Protocol.h"

namespace SimpleSerialProtocol {

Protocol::Protocol(PinName tx, PinName rx, PinName led_pin) : MODSERIAL(tx, rx, 64, 512), _receive_led(led_pin), _send_buffer(512){
    _receive_timeout.start();
    codec = &default_codec;
}

Protocol::~Protocol() {
    codec = 0;
}

void Protocol::blockUntilTxEmpty(){
    while(_send_buffer.available()){
        MODSERIAL::putc(_send_buffer.read());
    }
    while(!MODSERIAL::txBufferEmpty());
    return;
}

void Protocol::update() {
    for (uint16_t j = 0; j < _transmit_callback.size(); j++) {
        if (_transmit_callback[j].trigger()) {
            _transmit_callback[j]._callback.call(this, &_packet_transmit);
            send(&_packet_transmit);
            _packet_transmit.reset();
        }
    }
    
    transmit();
    receive();
    
    if (packetWaiting()) {
        _receive_led = 1;
        if (_callback.count(_packet._type)) {
            for (uint16_t i = 0; i < _callback[_packet._type].size(); i++) {
                _callback[_packet._type][i].call(this, &_packet);
            }
        }
        _packet.reset();
        _receive_led = 0;
    }
}

void Protocol::send(uint8_t byte) {
    _send_buffer.write(byte);
}

void Protocol::transmit() {

    uint16_t buffer_size = _send_buffer.available();
    uint16_t send_length = 0;

    if (buffer_size < SEND_CHUNK_SIZE) {
        send_length = buffer_size;
    } else {
        send_length =  SEND_CHUNK_SIZE;
    }

    if ( buffer_size ) {
        for (int i = 0; i < send_length; i++) {
            MODSERIAL::putc(_send_buffer.read());
        }
    }
}

void Protocol::receive() {
    _receive_timeout.reset();
    while ((MODSERIAL::rxBufferGetCount() > 0 &&  _receive_timeout.read_us() < 50) && !_packet._valid) {
        if(codec){
            codec->decode(&_packet, MODSERIAL::getc());
        }
    }
}

void Protocol::send(Packet* packet) {
    if (packet != 0) {
        if(codec){
            codec->encode(packet, &_send_buffer);
        }
    }
}

}