title: ISO/IEC 14443a CRC Calcuation
body: <p>Hello everyone I am finishing the last section of my firmware for my NFC project. I am attempting to communicate with an AD-740 NFC Tag which uses NXP's MF0ULx1 MIFARE Ultralight EV1 - Contactless ticket IC. The NFC reader that I am using is NXP's CLRC663. I am controlling the NFC reader with a PSOC5LP device over SPI.</p>
  
  <p>Now that you have all of the background information I will now ask my question.</p>
  
  <p>For this particular <a href="https://i.stack.imgur.com/FWrxy.png" rel="nofollow noreferrer">NXP Read Method</a> I need to encode my Cmd and Addr into a CRC of length 2 bytes. The datasheet, which I can link to, references ISO/IEC 14443. Searching that in Google brings me to the Wikipedia page, which then shows four sections of a PDF. I am assuming that I need section 4 the transmission protocol section. The only problem is this PDF is blocked by a pay wall. Is this intentional??</p>
  
  <p>Scrounging around on the internet I have found a few code examples that may prevent me from purchasing a 170$ PDF just to look at a polynomial...</p>
  
  <p>Code example 1 - I can post source link in comments. Don't have rep to do it in main post.</p>
  
  <pre><code>    // Calculate an ISO 14443a CRC. Code translated from the code in
      // iso14443a_crc().
      func ISO14443aCRC(data []byte) [2]byte {
          crc := uint32(0x6363)
          for _, bt := range data 
          {
              bt ^= uint8(crc &amp; 0xff)
              bt ^= bt &lt;&lt; 4
              bt32 := uint32(bt)
              crc = (crc &gt;&gt; 8) ^ (bt32 &lt;&lt; 8) ^ (bt32 &lt;&lt; 3) ^ (bt32 &gt;&gt; 4)
           }
  
         return [2]byte{byte(crc &amp; 0xff), byte((crc &gt;&gt; 8) &amp; 0xff)}
      }
  </code></pre>
  
  <p>Code example 2 - I can post source link in comments. Don't have rep to do it in main post.</p>
  
  <pre><code>    void iso14443a_crc(byte_t* pbtData, size_t szLen, byte_t* pbtCrc)
      {
        byte_t bt;
        uint32_t wCrc = 0x6363;
  
        do {
          bt = *pbtData++;
          bt = (bt^(byte_t)(wCrc &amp; 0x00FF));
          bt = (bt^(bt&lt;&lt;4));
          wCrc = (wCrc &gt;&gt; 8)^((uint32_t)bt &lt;&lt; 8)^((uint32_t)bt&lt;&lt;3)^((uint32_t)bt&gt;&gt;4);
        } while (--szLen);
  
        *pbtCrc++ = (byte_t) (wCrc &amp; 0xFF);
        *pbtCrc = (byte_t) ((wCrc &gt;&gt; 8) &amp; 0xFF);
      }
  </code></pre>
  
  <p><strong>And now on to my final question</strong> with all of this information... Would it be safe to assume that: </p>
  
  <p><strong>CRC polynomial is: 0x6363</strong> </p>
  
  <p><strong>Seed Value is: 0x00FF</strong></p>
  
  <p>A visual representation can be seen <a href="https://i.stack.imgur.com/hbGGC.png" rel="nofollow noreferrer">here</a></p>