Asynchronous Serial Library with flow control and tag detection.

AsyncSerial/AsyncSerial.h

Committer:
marcuschang
Date:
2015-03-31
Revision:
2:efec63739aa3
Parent:
1:a3f39ec7d5f2
Child:
3:af3caa18e928

File content as of revision 2:efec63739aa3:

#ifndef __ASYNCSERIAL_H__
#define __ASYNCSERIAL_H__

#include "mbed.h"


typedef void (*send_done_t)(uint8_t* sendBuffer, uint16_t sendLength);
typedef void (*receive_done_t)(uint8_t* receiveBuffer, uint16_t receiveLength);


class AsyncSerial : public SerialBase
{
public:
    AsyncSerial(PinName tx, PinName rx, PinName rts, PinName cts);

    void send(send_done_t handler, uint8_t* sendBuffer, uint16_t sendLength);

    template<typename T>
    void send(T* object, void (T::*member)(uint8_t*, uint16_t),
              uint8_t* buffer, uint16_t length)
    {
        if (object && member && buffer && length)
        {
            sendObject = static_cast<void*>(object);
            memcpy(sendMember, &member, sizeof(member));
            sendDoneObject = &AsyncSerial::membercaller<T>;

            sendDoneHandler = 0;
    
            send(buffer, length);
        }
    }

    void receive(receive_done_t handler,
                 uint8_t* receiveBuffer, uint16_t maxLength,
                 const uint8_t* conditionBuffer, uint16_t conditionLength,
                 uint32_t timeoutMilli);

    template<typename T>
    void receive(T* object, void (T::*member)(uint8_t*, uint16_t),
                 uint8_t* receiveBuffer, uint16_t maxLength,
                 const uint8_t* conditionBuffer, uint16_t conditionLength,
                 uint32_t timeoutMilli)
    {
        if (object && member && receiveBuffer && maxLength)
        {
            receiveObject = static_cast<void*>(object);
            memcpy(receiveMember, (uint8_t*) &member, sizeof(member));
            receiveDoneObject = &AsyncSerial::membercaller<T>;

            receiveDoneHandler = NULL;

            receive(receiveBuffer, maxLength, conditionBuffer, conditionLength, timeoutMilli);
        }
    }

    int getc();
    int putc(int c);

private:
    void send(uint8_t* buffer, uint16_t length);
    void receive(uint8_t* receiveBuffer, uint16_t maxLength,
                 const uint8_t* conditionBuffer, uint16_t conditionLength,
                 uint32_t timeoutMilli);
    template<typename T>
    static void membercaller(void* object, uint8_t* member, uint8_t* buffer, uint16_t length)
    {
        T* o = static_cast<T*>(object);
        void (T::*m)(uint8_t*, uint16_t);
        memcpy(&m, member, sizeof(m));
        (o->*m)(buffer, length);
    }

    void putDone();
    void getReady();
    void getDone();

    uint8_t* sendBuffer;
    uint16_t sendLength;
    uint16_t sendIndex;

    send_done_t sendDoneHandler;
    void* sendObject;
    uint8_t sendMember[16];
    void (*sendDoneObject)(void* object, uint8_t* member, uint8_t* buffer, uint16_t length);

    uint8_t* receiveBuffer;
    uint16_t receiveMaxLength;
    uint16_t receiveIndex;

    receive_done_t receiveDoneHandler;
    void* receiveObject;
    uint8_t receiveMember[16];
    void (*receiveDoneObject)(void* object, uint8_t* member, uint8_t* buffer, uint16_t length);

    const uint8_t* conditionBuffer;
    uint16_t conditionLength;
    uint16_t conditionIndex;

    Timeout timeout;
};

#endif // __ASYNCSERIAL_H__