title: Packet framing for very short serial packets
body: <p>We designed simple fixed-length protocol for embedded device. Every packet is just two bytes:</p>
  
  <pre><code> bits |  15..12  |    11..4     |  3..0   |
        |  OpCode  |     DATA     |  CRC4   |
  </code></pre>
  
  <p>We use "crc-based framing", i.e. receiver collects two bytes, compute CRC4 and if it matches frame is considered valid. As you can see, there is no start-of-frame or end-of-frame.</p>
  
  <p>There is a catch: recommended message length for CRC4 is 11 bits and here it is computed for 12 bits. As far as I understand that means that CRC error-detection properties degrade (but I'm not sure how much).</p>
  
  <p>(By the way, if anybody needs code for CRC4 (or any other) and does not feel skilled enough to write it himself, boost has very nice boost::crc function that can compute any crc )</p>
  
  <p>The problem is: this crc-based framing doesn't work and we get framing errors, i.e. second byte from one message and first byte from the following message sometimes form correct message.</p>
  
  <p>My question is - is there any way to correct framing without adding any more bytes? We spend quite some time squeezing everything in that two bytes and it would be kinda sad to just throw it away like that.
  We do have a spare bit in opcode field though.</p>
  
  <ul>
  <li>Time-based framing will not be very reliable because our radio-channel likes to "spit" several packets at once</li>
  <li>Maybe there is some other error-detection method that will work better than CRC4?</li>
  </ul>
  
  <p>It we have to append more bytes, what would be the best way to do it?</p>
  
  <ul>
  <li>We can use start-of-frame byte and byte-stuffing (such as COBS) ( +2 bytes but I'm not sure what to do with corrupted messages )</li>
  <li>We can use start-of-frame nibble and widen CRC to CRC8 ( +1 byte )</li>
  <li>Something else?</li>
  </ul>