WizziLab's serial protocol library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

WizziCom.h

Committer:
Jeej
Date:
2017-09-20
Revision:
5:a06d239f3b3e
Parent:
4:a37e42de1ba7
Child:
8:42e00820df36

File content as of revision 5:a06d239f3b3e:

#ifndef _WIZZICOM_H_
#define _WIZZICOM_H_

#include "mbed.h"
#include "rtos.h"
#include "CBuffer.h"
#include "WizziDebug.h"


typedef enum
{
    HAL_ERROR_NONE                      =    0,
    HAL_ERROR_DEFAULT                   =   -1,
    HAL_ERROR_MEM_FULL                  =   -2,
    HAL_ERROR_MEM_EMPTY                 =   -3,
    HAL_ERROR_MODULE_BUSY               =   -4,
    HAL_ERROR_MODULE_OFF                =   -5,
    HAL_ERROR_SERIAL_BAD_SYNC           = -100,
    HAL_ERROR_SERIAL_BAD_SEQ            = -101,
    HAL_ERROR_I2C_BAD_DEVID             = -200,
    HAL_ERROR_I2C_NACK                  = -201,
    HAL_ERROR_I2C_ARB_LOST              = -202,

} hal_error_t;


typedef enum {
    // Default printf type
    WizziComPacketPrintf,
    // Substitute the string by a codeword
    // interpreted by the PC com tool
    WizziComPacketPrintfCompressed,
    // Display the payload as hex data
    WizziComPacketPrintHex,

    // AT command
    WizziComPacketAlpCmd,
    // AT command response
    WizziComPacketAlpResp,
    // AT unsolicited message
    WizziComPacketAlpUns,
    // AT unsolicited error
    WizziComPacketAlpErr,

    // Remote Commands
    WizziComPacketCmd,
    
    // Remote System reset
    WizziComPacketSysReset,
    // Button Emulator
    WizziComPacketSysButton,
    // Dump Debug parameters
    WizziComPacketSysInfo,
    // CUP signalisation
    WizziComPacketSysCup,
    // Ping distant COM
    WizziComPacketSysPing,
    // Pong from distant COM
    WizziComPacketSysPong,
    // Enable system config from distant COM
    WizziComPacketSysConfig,
    // Configure Output Trace level from distant COM
    WizziComPacketSysTlev,
    // Configure COM port redirection
    WizziComPacketSysRedir,
    // Flow control signalling
    WizziComPacketSysXon,
    WizziComPacketSysXoff,
    WizziComPacketSysXack,

    // File System Command/Response
    WizziComPacketFsCmd,
    WizziComPacketFsResp,
    
    WIZZICOM_PKT_QTY,
    
    // Special flag to redirect all undirected packets to this callback
    WizziComPacketUntreated = WIZZICOM_PKT_QTY,
} WizziComPacketType;

typedef struct {
    uint8_t type;
    uint8_t length;
    uint8_t data[1];
} WizziComPacket_t;

//======================================================================
// wizzi_com_tx_msg_t
//----------------------------------------------------------------------
// Transmit message structure
//======================================================================
typedef struct
{
    // identifier wizzi_com_flow_t
    uint8_t  id;
    // length of the string buffer defined by a pointer
    uint8_t  plen;
    // length of the allocated buffer
    uint8_t  alen;
    // pointer to a string buffer that does not need to be freed
    uint8_t* pbuf;
    // pointer to argument that does not need to be freed
    uint8_t* abuf;

} wizzi_com_tx_msg_t;

//======================================================================
// wizzi_com_rx_msg_t
//----------------------------------------------------------------------
// Receive message structure
//======================================================================
typedef struct
{
    // error message
    hal_error_t err;
    // length of the log (string) buffer
    uint8_t  blen;
    // identifier wizzi_com_flow_t
    uint8_t  id;
    // Com port where the message came from
    uint8_t com_id;
    // pointer to the log buffer
    uint8_t  buffer[1];

} wizzi_com_rx_msg_t;

typedef struct {
    uint32_t len;
    uint8_t buf[1];
} wizzi_com_tx_buf_t;

uint8_t wizzicom_type_to_flow(uint8_t packet_type);
uint8_t wizzicom_flow_to_type(uint8_t flow_id);

class WizziCom {
    typedef void (*WizziComCallback)(WizziCom*, WizziComPacket_t*);

private:
    volatile uint8_t                _state;
    wizzi_com_rx_msg_t              _msg;
    uint16_t                        _skipped_bytes;
    uint8_t                         _tx_seq;
    uint8_t                         _rx_seq;
    
    DigitalOut*                     _irq_out;
    InterruptIn*                    _irq_in;
    RawSerial*                      _serial;
    
    CBuffer<uint8_t, 512>           _rx_buf;
    
    Semaphore                       _data_parsing;
    Semaphore                       _irq_in_int;
    Thread                          _rx_thread;
    Thread                          _tx_thread;
    Thread                          _callback_thread;
    Queue<wizzi_com_tx_buf_t, 8>    _tx_queue;
    Queue<WizziComPacket_t, 8>      _rx_queue;
    
    Callback<void(WizziCom*, WizziComPacket_t*)> _callback[WIZZICOM_PKT_QTY+1];
    
    void                            _rx_isr();
    void                            _irq_in_isr();
    void                            _send_raw(uint8_t* data, uint32_t len);
    void                            _sys_xack(void);
    wizzi_com_tx_buf_t*             _new_msg(wizzi_com_tx_msg_t* msg);
    void                            _post_msg(wizzi_com_tx_msg_t* msg);
    void                            _new_pkt(WizziComPacket_t* pkt);
    void                            _parse_packet_header(void);
    void                            _parse_packet_body(void);
    void                            _thread_rx(void);
    void                            _thread_tx(void);
    void                            _thread_callback(void);
    
public:
    WizziCom(PinName tx, PinName rx, PinName irq_out = NC, PinName irq_in = NC);
    ~WizziCom();
    
    void attach(WizziComCallback function, WizziComPacketType packet_type);
    
    template<class T>
    void attach(T* object, void (T::*member)(WizziCom*, WizziComPacket_t*), WizziComPacketType packet_type)
    {
        _callback[packet_type] = callback(object, member);
    }
    
    void reset(void);
    void send(WizziComPacketType type, uint8_t length, uint8_t* data);
    void send(WizziComPacket_t* packet);
    void print_raw(char* str);
    void send_raw(uint8_t* data, uint32_t len);
    
    uint8_t type_to_flow(WizziComPacketType packet_type);
};

#endif // _WIZZICOM_H_