title: Manchester-L (Biphase-L) implementation with finite state machines in GNU Radio
body: <p>I'm in the process of implementing line coding blocks as there are limited choices in GnuRadio. I have finished implementing and testing NRZ (L\M\S) using finite state machines (FSM) and they seem to work fine. Now, I'm trying to implement Manchester (L\M\S), starting with L as a baseline. The waveform can be seen in the diagram below Extracted from NASA's Deep Space Network Telemetry Data Decoding (208)</p>
  
  <p><a href="https://i.stack.imgur.com/sDX3V.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sDX3V.png" alt="Modulation waveforms"></a></p>
  
  <p>A finite state machine was constructed as shown below. I have decided to use FSMs since it is, in my opinion, a very standardized way of implementing a line code. 
  <a href="https://i.stack.imgur.com/Ub9o0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Ub9o0.png" alt="Manchester-L FSM"></a></p>
  
  <p>Below is the gnuradio flowgraph used to test the implementation. The tests are conducted by sending a BPSK signal (with CCSDS Reed-Solomon + Scrambler) to an external device capable of receiving the signal and processing the telemetry. This implementation has been tested successfully with NRZ-L\M\S. The CCSDS frames are read from a file, unpacked and sent to the OOT block debug_linecode_bp for Manchester encoding (Code 0 for Manchester-L). Following Manchester encoding is the OOT block debug_pulseshape_pam_2 block which takes filter taps and number of samples per symbol as arguments. Following that is an OOT block debug_bpsk_modulator which does simple BPSK mapping (Inphase = in[i], quadrature = 0).
  <a href="https://i.stack.imgur.com/TyiHC.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TyiHC.png" alt="enter image description here"></a>
  The code for the header file is shown below</p>
  
  <pre><code>#ifndef INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H
  #define INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H
  
  #include &lt;baseband/debug_linecode_bp.h&gt;
  
  namespace gr {
  namespace baseband {
  
  class debug_linecode_bp_impl : public debug_linecode_bp
  {
   private:
    char last_state;
    int d_code;
    void fsm_decode_state(char state, unsigned char &amp;bit0, unsigned char &amp;bit1);
    void fsm_encode_state(int code, unsigned char input, char last_state, char &amp;next_state);
   public:
    debug_linecode_bp_impl(int code);
    ~debug_linecode_bp_impl();
  
    // Where all the action really happens
    int work(int noutput_items,
       gr_vector_const_void_star &amp;input_items,
       gr_vector_void_star &amp;output_items);
  };
  
   } // namespace baseband
   } // namespace gr
  
  #endif /* INCLUDED_BASEBAND_DEBUG_LINECODE_BP_IMPL_H */
  </code></pre>
  
  <p>And here is the implementation file</p>
  
  <pre><code>#ifdef HAVE_CONFIG_H
  #include "config.h"
  #endif
  
  #include &lt;gnuradio/io_signature.h&gt;
  #include "debug_linecode_bp_impl.h"
  #include &lt;iostream&gt;
  using namespace std;
  namespace gr {
  namespace baseband {
  
  debug_linecode_bp::sptr
  debug_linecode_bp::make(int code)
  {
    return gnuradio::get_initial_sptr
      (new debug_linecode_bp_impl(code));
  }
  
  /*
   * The private constructor
   */
  debug_linecode_bp_impl::debug_linecode_bp_impl(int code)
    : gr::sync_interpolator("debug_linecode_bp",
                gr::io_signature::make(1, 1, sizeof(unsigned char)),
                gr::io_signature::make(1, 1, sizeof(unsigned char)), 2),
  d_code(code),last_state('a')
  {}
  
  /*
   * Our virtual destructor.
   */
  debug_linecode_bp_impl::~debug_linecode_bp_impl()
  {
  }
  void
  debug_linecode_bp_impl::fsm_decode_state(char state, unsigned char &amp;bit0, unsigned char &amp;bit1)
  {
    switch(state)
  {
  case 'a':
    bit0 = 0x00;
    bit1 = 0x00;
    break;
  case 'b':
    bit0 = 0x00;
    bit1 = 0x01;
    break;
  case 'c':
    bit0 = 0x01;
    bit1 = 0x01;
    break;
  case 'd':
    bit0 = 0x01;
    bit1 = 0x00;
    break;
  }
  }
  
  void
  debug_linecode_bp_impl::fsm_encode_state(int code, unsigned char input, char last_state, char &amp;next_state)
  {
    switch(code)
  {
  case 0://Biphae-L
    switch(last_state)
      {
      case 'a': //Illegal state
        next_state = 'b';
        cout &lt;&lt; "Illegal state [a] encountered" &lt;&lt; endl;
        break;
      case 'b':
        next_state = (input &amp; 0x01) ? 'd' : 'b';
        break;
      case 'c': //Illegal state
        next_state = 'b';
        cout &lt;&lt; "Illegal state [b] encountered" &lt;&lt; endl;
        break;
      case 'd':
        next_state = (input &amp; 0x01) ? 'd' : 'b';
        break;
      }
    break;
  case 1://Biphase-S
    switch(last_state)
      {
      case 'a':
        next_state = (input &amp; 0x01) ? 'c' : 'd';
        break;
      case 'b':
        next_state = (input &amp; 0x01) ? 'a' : 'b';
        break;
      case 'c': 
        next_state = (input &amp; 0x01) ? 'a' : 'b';
        break;
      case 'd':
        next_state = (input &amp; 0x01) ? 'c' : 'd';
        break;
      }
    break;
  case 2://Biphase-M
    switch(last_state)
      {
      case 'a':
        next_state = (input &amp; 0x01) ? 'd' : 'c';
        break;
      case 'b':
        next_state = (input &amp; 0x01) ? 'b' : 'a';
        break;
      case 'c': 
        next_state = (input &amp; 0x01) ? 'b' : 'a';
        break;
      case 'd':
        next_state = (input &amp; 0x01) ? 'd' : 'c';
        break;
      }
    break;
  }
  }
  
  int
  debug_linecode_bp_impl::work(int noutput_items,
               gr_vector_const_void_star &amp;input_items,
               gr_vector_void_star &amp;output_items)
  {
    const unsigned char *in = (const unsigned char *) input_items[0];
    unsigned char *out = (unsigned char *) output_items[0];
  
    char next_state;
    unsigned char bit0;
    unsigned char bit1;
    for (int i = 0; i &lt; noutput_items/2; i++) {
  fsm_encode_state(d_code,in[i],last_state, next_state);
  fsm_decode_state(next_state, bit0, bit1);
  for (int j = 0; j &lt; 2; j++) {
    out[i + j]     = bit0;
    out[i + j + 1] = bit1;
  }
  last_state = next_state;
    }
  
    // Tell runtime system how many output items we produced.
    return noutput_items;
  }
  
  } /* namespace baseband */
  } /* namespace gr */
  </code></pre>
  
  <p>The tests haven't been a success so far. The device I use to receive signals from this flowgraph hasnt been able to pick even a single packet. My conclusion is that the error is coming from the Manchester encoder. Any thoughts on the code above is highly welcomed. </p>
  
  <p>Thanks.</p>