WizziLab / modem_ref_v5_3_217

Dependents:   modem_ref_helper_for_v5_3_217

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers wc_deserializer.cpp Source File

wc_deserializer.cpp

00001 /// @copyright
00002 /// ========================================================================={{{
00003 /// Copyright (c) 2013-2016 WizziLab                                           /
00004 /// All rights reserved                                                        /
00005 /// =========================================================================}}}
00006 /// @endcopyright
00007 
00008 //  =======================================================================
00009 /// @file       wc_deserializer.c
00010 /// @brief      Exemple of WizziCom serial transport layer parser.
00011 ///             Can be used as entry-point/scheduler for modem_ref
00012 //  =======================================================================
00013 #include "modem_ref.h"
00014 
00015 // Depending on Host needs/capacities, choose variable-size buffer allocation style
00016 #if 1 // static buffer alloc
00017     #define MAX_RX_BUFFER_SIZE              (256)
00018     #define GET_BUFFER(_s)                  rxbuf
00019     #define FREE_BUFFER(_b)
00020     static u8 rxbuf[MAX_RX_BUFFER_SIZE];
00021 #else // Dynamic alloc
00022     #define GET_BUFFER(_s)                  MALLOC(_s);
00023     #define FREE_BUFFER(_b)                 FREE(_b);
00024 #endif
00025 
00026 enum { S_SYNC0, S_SYNC1, S_SIZE, S_SEQU, S_FLOWID, S_DATA };
00027 
00028 //======================================================================
00029 // wc_deserializer
00030 //----------------------------------------------------------------------
00031 /// @brief  Parse serial flow character-wise and extract packets from
00032 ///         WizziCom serial transport layer (WC).
00033 ///         It calls modem_input on complete payloads.
00034 /// @param  c           : received character.
00035 /// @param  init        : 0 when parsing, 1 to init/reinit parser.
00036 /// @return flowid of successfuly parsed packet, 0 otherwise.
00037 /// @note   This function must be called on every received character on
00038 ///         modem serial link
00039 /// @note   This function should not be directly called from (serial)
00040 ///         ISR as it is the entry point for all driver/callback execution.
00041 /// @note   If WC deserialization is performed by other means, and that
00042 ///         full packets are available, one should do direct calls to
00043 ///         modem_input
00044 //======================================================================
00045 public int wc_deserializer(char c, u8 init)
00046 {
00047     static u8 state,rx_ptr,rx_size,rx_flowid;
00048     static u8* rx_data;
00049 
00050     if (init) { state = S_SYNC0; }
00051     // WC Packet decap'
00052     switch(state)
00053     {
00054         case S_SYNC0:
00055             state   = (c == WC_SYNC_BYTE_0)?S_SYNC1:S_SYNC0;
00056             rx_ptr  = 0;
00057             rx_data = (u8*)NULL;
00058             return 0;
00059         case S_SYNC1:
00060             state = (c == WC_SYNC_BYTE_1)?S_SIZE:
00061                     (c == WC_SYNC_BYTE_0)?S_SYNC1:S_SYNC0;
00062             return 0;
00063         case S_SIZE:
00064             state       = S_SEQU;
00065             rx_size     = (u8)c;
00066             if (rx_size) rx_data = GET_BUFFER(rx_size);
00067             return 0;
00068         case S_SEQU:
00069             state       = S_FLOWID;
00070             //rx_sequ     = (u8)c;
00071             return 0;
00072         case S_FLOWID:
00073             state       = (rx_size!=0)?S_DATA:S_SYNC0;
00074             rx_flowid   = (u8)c;
00075             break;
00076         case S_DATA:
00077             state       = (rx_ptr >= rx_size)?S_SYNC0:S_DATA;
00078             rx_data[rx_ptr++]  = (u8)c;
00079             break;
00080         default:
00081             break;
00082     }
00083 
00084     if (rx_size == rx_ptr)
00085     {
00086         modem_input(rx_flowid,rx_data,rx_size);
00087         if (rx_data) { FREE_BUFFER(rx_data); }
00088     }
00089     return rx_flowid;
00090 }