CRC-8

Some popular 8 bit CRC calculations



\ *****************************************************************************
\ CRC-8.4th V0.1.0 2020 Sep 04  ANS Forth 
\ CRC-8 calculation using a table loaded at run time
\ *****************************************************************************

0 [IF]

From : https://en.wikipedia.org/wiki/Cyclic_redundancy_check
"A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data."

Note : the Polynomial is often specified in reverse bit order, e.g. $F1 is shown as $07 .
The CRC calculation can either be in normal order, following the Big Endian description of the polynomial,
or in "reverse" order where the bits are reversed (which can be calculated more efficiently on Little Endian processors).
There is some confusion online about which of these is "reverse".

Usage
=====

Define your CRC8 parameters and create a definition line like :
\      Name                  Poly Init  Xor Rev   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16   Name
create CRC-8/_         lineC,  07   00   00  FF  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " CRC-8/_"

Run
   0 v_Silent !            \ do not show test details
   CRC-8/_ CRC8table_Init  Show_CRC8_test
To show the results of the test, which will mostly fail :

\      Name                  Poly Init  Xor Rev   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16   Name
create CRC-8/_         lineC,  07   00   00  FF  00 F4 6C 34 90 6E 68 42 ED 83 B1 CA A0 BD D7 00 30 " CRC-8/_"

Copy the results of the test back into the CRC-8/_ definition line and repeat the test.

The test results should be checked using an external reference :
e.g. https://crccalc.com/ or http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

To display all test results :
   empty include crc8  Show_CRC8tests_all
the output is the CRC8 definitions lines used to create the tests.

CRC tables can be generated for use in systems with limited RAM, for Forth :
   CRC-8/_  CRC8table_Init  Show_CRC8table
or for C code :
   CRC-8/_  CRC8table_Init  Show_CRC8table_C

The word  lineC,  is defined to parse the text following it and add hex numbers, strings
and counted strings to the table. This makes the source code easier to read.

[THEN]

\ *****************************************************************************
\ Create CRC8 parameter definitions
\ *****************************************************************************

[UNDEFINED] 2.hex [IF]
: 2.hex ( c -- )   base @ >r  hex  0 <#  # #  #> type  r> base ! ;
[THEN]

[UNDEFINED] 4.hex [IF]
: 4.hex ( c -- )   base @ >r  hex  0 <#  # # # #  #> type  r> base ! ;
[THEN]

[UNDEFINED] ToColumn [IF]
: ToColumn ( u -- )   get-xy drop - 1 max 200 min  spaces ;    \ move to the given column number
[THEN]

[UNDEFINED] dumpL [IF]
\ dump on the same line
: dumpL ( a n -- )   0 max  $100 min  space  dup 2.hex ."  |  " over + swap ?do  i c@  2.hex space  loop ;
[THEN]

[UNDEFINED] lineC, [IF]
\ Add up to 128 bytes to a structure, using the 128 hex ASCII words following, then ignore the rest of the line.
: lineC, ( -- )
   base @ >r  hex                                     \ save the current number base on the return stack and change to hexadecimal
   $80 0 do                                           \ loop up to 128 times, or until something makes us "leave"
      bl word  count
      dup 0= if  2drop  leave  then                   \ there are no more words on the line, so leave the loop
      2dup s" \" compare 0= if  2drop  leave  then    \ we have found a "comment until end of line" character, so leave the loop
      2dup NUMBER? case      \ NUMBER? returns 0, 1 or 2 plus 0, 1 or 2 cells on the stack
         0 of
            dup 1 = if
               over c@ [char] " = if  [CHAR] " STRING  then \  " AAAA" will be added as a counted string AAAA with null terminator
               over c@ [char] % = if  [CHAR] % STRING  then \  % BBBB% will be added as a counted string BBBB with null terminator
               2drop
            else
               \ "AAAA" will be added as the string AAAA , %BBBB% will be added as the string BBBB
               over c@ [CHAR] " = if  1 /string  over + swap ?do  i c@ dup [CHAR] " = if  drop  leave  else  c,  then  loop  then
               over c@ [CHAR] % = if  1 /string  over + swap ?do  i c@ dup [CHAR] % = if  drop  leave  else  c,  then  loop  then
            then
         endof
         1 of  c,  2drop  endof
         2 of  ,   2drop  endof
      endcase
   loop
   r> base !                                          \ restore the number base from the return stack
   postpone \                                         \ perform the action of "\", ignore everything until the end of the line
                                                      \ "postpone"  means don't do this now, but when  lineC,  is called
;
[THEN]

\                                               |                 ... Test results ...             |
\      Name                  Poly Init  Xor Rev   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16   Name
create CRC-8/_         lineC,  07   00   00  FF  00 F4 6C 34 90 6E 68 42 ED 83 B1 CA A0 BD D7 00 30 " CRC-8/_"
create CRC-8/CDMA2000  lineC,  9B   FF   00  FF  FF DA B7 BC 2D EA 58 06 7D D9 99 77 C9 39 87 AC F6 " CRC-8/CDMA2000"
create CRC-8/DARC      lineC,  39   00   00  00  00 15 A3 6F A8 BA 5C 4A F3 81 73 84 AE F9 D3 00 8F " CRC-8/DARC"
create CRC-8/DVB-S2    lineC,  D5   00   00  FF  00 BC B8 EF F6 26 BA 06 AF E6 E4 F0 D2 06 24 00 2E " CRC-8/DVB-S2"
create CRC-8/EBU       lineC,  1D   FF   00  00  FF 97 04 34 1A 31 C5 A7 7D FB 16 1E FE D7 37 A1 94 " CRC-8/EBU"
create CRC-8/I-CODE    lineC,  1D   FD   00  FF  FD 7E 87 E7 B4 4F 5B E8 B3 9C 5E 63 4A 8F A6 27 BC " CRC-8/I-CODE"
create CRC-8/ITU       lineC,  07   00   55  FF  55 A1 39 61 C5 3B 3D 17 B8 D6 E4 9F F5 E8 82 55 65 " CRC-8/ITU"
create CRC-8/MAXIM     lineC,  31   00   00  00  00 A1 E8 85 BE CD 9E 55 2B 83 12 90 41 18 C9 00 06 " CRC-8/MAXIM"
create CRC-8/ROHC      lineC,  07   FF   00  00  FF D0 50 80 EB 61 73 C9 3C 0E E8 4D B1 39 C5 5A BB " CRC-8/ROHC"
create CRC-8/WCDMA     lineC,  9B   00   00  00  00 25 BD F1 1B DC 02 56 88 13 E8 22 CC D4 3A 00 BE " CRC-8/WCDMA"

$04 constant o_OFFSET_TESTS   \ fixed offset in bytes to the Test Results
$15 constant o_OFFSET_NAME    \ fixed offset in bytes to the counted name string at the end

\ *****************************************************************************
\ Calculate the CRC8 using a table
\ *****************************************************************************

$100 constant |CRC8table|
|CRC8table| Buffer: CRC8table[] ( -- a )

variable p_CRC8:        \ pointer to the current CRC8:x definition

\ The CRC8table[] must be initialised using CRC8table_Init . C-code \ crc = table[crc ^ data[i]];
: CRC8 ( a n -- c )   \ calculates the CRC8 of the given string using the parameters in the CRC8: definition string stored in p_CRC8:
   ( Init ) p_CRC8: @ 1 + c@  -rot  \ v_CRC8 c!      \ initialises the output CRC value in the required way
   over + swap ?do
      i c@
      xor CRC8table[] + c@
   loop
   ( Xor ) p_CRC8: @ 2 + c@ xor 
;

\ 12 PAD !  PAD 1 CRC8 PAD 1+ c!  PAD 2 CRC8 constant CRC_VALID

\ *****************************************************************************
\ Create the CRC8table
\ *****************************************************************************

variable BRin
variable BRout

: BitReverse8 ( c -- c )   \ slow version, used to constuct the table
   BRin !
   0 BRout !
   #08 0 do
      BRout @ 2* BRout !
      BRin @ 1 and if  BRout @ 1 or  BRout !  then
      BRin @ U2/ BRin !
   loop
   BRout @
;

variable v_polynomial

: CRC8calculateRev ( c -- c )   \ calculates the CRC value for table element n , slow method, Reversed
   p_CRC8: @ c@ BitReverse8 v_polynomial !
   8 0 do
      dup $01 and if
         1 rshift
         v_polynomial @ xor
      else
         1 rshift
      then
      $FF and
   loop
;

: CRC8calculateForward ( c -- c )   \ calculates the CRC value for table element n , slow method
   p_CRC8: @ c@ v_polynomial !
   8 0 do
      dup $80 and if
         1 lshift
         v_polynomial @ xor
      else
         1 lshift
      then
      $FF and
   loop
;

: CRC8calculate ( c -- c )   \ calculates the CRC value for table element n , slow method
   p_CRC8: @ 3 + c@ if        \ check to see if the bit order should be reversed
      CRC8calculateForward    \ "Normal" bit order
   else
      CRC8calculateRev        \ Reversed bit order - is more efficient on Little Endian processors
   then
;

: CRC8table_Init ( CRC8: -- )   \ Initialises the CRC8 table using the given CRC8 definition
   p_CRC8: !                     \ save the CRC8: definition line's address
   |CRC8table| 0 do
      i CRC8calculate CRC8table[] i  + c!
   loop
;

\ *****************************************************************************
\ Export a CRC8 table as compilable source code
\ *****************************************************************************

$20 constant c_LINE_LENGTH    \ how many bytes to display on each line

: Show_CRC8table ( -- )    \ show the current table as Forth source code
   cr  ." create CRC8table_" p_CRC8: @ o_OFFSET_NAME + count type  ."  ( -- a )   "
   ." \ Poly = $" p_CRC8: @ c@ 2.hex  ."  (rev $"  p_CRC8: @ c@ BitReverse8 2.hex ." )"
   ."   Init = $" p_CRC8: @ 1 + c@ 2.hex  ."   Xor = $" p_CRC8: @ 2 + c@ 2.hex   ."   Rev = $" p_CRC8: @ 3 + c@ 2.hex
   |CRC8table| 0 do
      i c_LINE_LENGTH 1- and 0= if  cr  ."    lineC, "  then  \ the text at the start of each line
      i CRC8table[] + c@ 2.hex space
      i c_LINE_LENGTH 1- and c_LINE_LENGTH 1- = if  ."  \ " i c_LINE_LENGTH 1- - 2.hex  then \ the text at the end of each line
   loop
   cr
;

: Show_CRCtables_all ( -- )
   CRC-8/_         CRC8table_Init  Show_CRC8table
   CRC-8/CDMA2000  CRC8table_Init  Show_CRC8table
   CRC-8/DARC      CRC8table_Init  Show_CRC8table
   CRC-8/DVB-S2    CRC8table_Init  Show_CRC8table
   CRC-8/EBU       CRC8table_Init  Show_CRC8table
   CRC-8/I-CODE    CRC8table_Init  Show_CRC8table
   CRC-8/ITU       CRC8table_Init  Show_CRC8table
   CRC-8/MAXIM     CRC8table_Init  Show_CRC8table
   CRC-8/ROHC      CRC8table_Init  Show_CRC8table
   CRC-8/WCDMA     CRC8table_Init  Show_CRC8table
   cr
;

: Show_CRC8table_C ( CRC8:x -- )    \ show the current table as C source code
   cr  ." create CRC8table_" p_CRC8: @ o_OFFSET_NAME + count type  ."  ( -- a )   "
   ." // Poly = 0x" p_CRC8: @ c@ 2.hex
   ."  (rev 0x"  p_CRC8: @ c@ BitReverse8 2.hex ." )"
   ."   Init = 0x" p_CRC8: @ 1 + c@ 2.hex  ."   Xor = 0x" p_CRC8: @ 2 + c@ 2.hex   ."   Rev = 0x" p_CRC8: @ 3 + c@ 2.hex
   ."   Please remove the final ',' before the '}' .
   cr ." { "
   |CRC8table| 0 do
      i c_LINE_LENGTH 1- and 0= if  cr  ."    "  then  \ the text at the start of each line
      i CRC8table[] + c@  0 <# [char] , hold # #  [char] x hold  [char] 0 hold  bl hold #> type  \ C format - please remove the final ,
      i c_LINE_LENGTH 1- and c_LINE_LENGTH 1- = if  ."  // " i c_LINE_LENGTH 1- - 2.hex  then \ the text at the end of each line
   loop
   cr ." } "
   cr
;

: Show_CRCtables_all_C ( -- )
   CRC-8/_         CRC8table_Init  Show_CRC8table_C
   CRC-8/CDMA2000  CRC8table_Init  Show_CRC8table_C
   CRC-8/DARC      CRC8table_Init  Show_CRC8table_C
   CRC-8/DVB-S2    CRC8table_Init  Show_CRC8table_C
   CRC-8/EBU       CRC8table_Init  Show_CRC8table_C
   CRC-8/I-CODE    CRC8table_Init  Show_CRC8table_C
   CRC-8/ITU       CRC8table_Init  Show_CRC8table_C
   CRC-8/MAXIM     CRC8table_Init  Show_CRC8table_C
   CRC-8/ROHC      CRC8table_Init  Show_CRC8table_C
   CRC-8/WCDMA     CRC8table_Init  Show_CRC8table_C
   cr
;

0 [IF]

Show_CRCtables_all

create CRC8table_CRC-8/_ ( -- a )   \ Poly = $07 (rev $E0)  Init = $00  Xor = $00  Rev = $FF
   lineC, 00 07 0E 09 1C 1B 12 15 38 3F 36 31 24 23 2A 2D 70 77 7E 79 6C 6B 62 65 48 4F 46 41 54 53 5A 5D  \ 00
   lineC, E0 E7 EE E9 FC FB F2 F5 D8 DF D6 D1 C4 C3 CA CD 90 97 9E 99 8C 8B 82 85 A8 AF A6 A1 B4 B3 BA BD  \ 20
   lineC, C7 C0 C9 CE DB DC D5 D2 FF F8 F1 F6 E3 E4 ED EA B7 B0 B9 BE AB AC A5 A2 8F 88 81 86 93 94 9D 9A  \ 40
   lineC, 27 20 29 2E 3B 3C 35 32 1F 18 11 16 03 04 0D 0A 57 50 59 5E 4B 4C 45 42 6F 68 61 66 73 74 7D 7A  \ 60
   lineC, 89 8E 87 80 95 92 9B 9C B1 B6 BF B8 AD AA A3 A4 F9 FE F7 F0 E5 E2 EB EC C1 C6 CF C8 DD DA D3 D4  \ 80
   lineC, 69 6E 67 60 75 72 7B 7C 51 56 5F 58 4D 4A 43 44 19 1E 17 10 05 02 0B 0C 21 26 2F 28 3D 3A 33 34  \ A0
   lineC, 4E 49 40 47 52 55 5C 5B 76 71 78 7F 6A 6D 64 63 3E 39 30 37 22 25 2C 2B 06 01 08 0F 1A 1D 14 13  \ C0
   lineC, AE A9 A0 A7 B2 B5 BC BB 96 91 98 9F 8A 8D 84 83 DE D9 D0 D7 C2 C5 CC CB E6 E1 E8 EF FA FD F4 F3  \ E0

create CRC8table_CRC-8/CDMA2000 ( -- a )   \ Poly = $9B (rev $D9)  Init = $FF  Xor = $00  Rev = $FF
   lineC, 00 9B AD 36 C1 5A 6C F7 19 82 B4 2F D8 43 75 EE 32 A9 9F 04 F3 68 5E C5 2B B0 86 1D EA 71 47 DC  \ 00
   lineC, 64 FF C9 52 A5 3E 08 93 7D E6 D0 4B BC 27 11 8A 56 CD FB 60 97 0C 3A A1 4F D4 E2 79 8E 15 23 B8  \ 20
   lineC, C8 53 65 FE 09 92 A4 3F D1 4A 7C E7 10 8B BD 26 FA 61 57 CC 3B A0 96 0D E3 78 4E D5 22 B9 8F 14  \ 40
   lineC, AC 37 01 9A 6D F6 C0 5B B5 2E 18 83 74 EF D9 42 9E 05 33 A8 5F C4 F2 69 87 1C 2A B1 46 DD EB 70  \ 60
   lineC, 0B 90 A6 3D CA 51 67 FC 12 89 BF 24 D3 48 7E E5 39 A2 94 0F F8 63 55 CE 20 BB 8D 16 E1 7A 4C D7  \ 80
   lineC, 6F F4 C2 59 AE 35 03 98 76 ED DB 40 B7 2C 1A 81 5D C6 F0 6B 9C 07 31 AA 44 DF E9 72 85 1E 28 B3  \ A0
   lineC, C3 58 6E F5 02 99 AF 34 DA 41 77 EC 1B 80 B6 2D F1 6A 5C C7 30 AB 9D 06 E8 73 45 DE 29 B2 84 1F  \ C0
   lineC, A7 3C 0A 91 66 FD CB 50 BE 25 13 88 7F E4 D2 49 95 0E 38 A3 54 CF F9 62 8C 17 21 BA 4D D6 E0 7B  \ E0

create CRC8table_CRC-8/DARC ( -- a )   \ Poly = $39 (rev $9C)  Init = $00  Xor = $00  Rev = $00
   lineC, 00 72 E4 96 F1 83 15 67 DB A9 3F 4D 2A 58 CE BC 8F FD 6B 19 7E 0C 9A E8 54 26 B0 C2 A5 D7 41 33  \ 00
   lineC, 27 55 C3 B1 D6 A4 32 40 FC 8E 18 6A 0D 7F E9 9B A8 DA 4C 3E 59 2B BD CF 73 01 97 E5 82 F0 66 14  \ 20
   lineC, 4E 3C AA D8 BF CD 5B 29 95 E7 71 03 64 16 80 F2 C1 B3 25 57 30 42 D4 A6 1A 68 FE 8C EB 99 0F 7D  \ 40
   lineC, 69 1B 8D FF 98 EA 7C 0E B2 C0 56 24 43 31 A7 D5 E6 94 02 70 17 65 F3 81 3D 4F D9 AB CC BE 28 5A  \ 60
   lineC, 9C EE 78 0A 6D 1F 89 FB 47 35 A3 D1 B6 C4 52 20 13 61 F7 85 E2 90 06 74 C8 BA 2C 5E 39 4B DD AF  \ 80
   lineC, BB C9 5F 2D 4A 38 AE DC 60 12 84 F6 91 E3 75 07 34 46 D0 A2 C5 B7 21 53 EF 9D 0B 79 1E 6C FA 88  \ A0
   lineC, D2 A0 36 44 23 51 C7 B5 09 7B ED 9F F8 8A 1C 6E 5D 2F B9 CB AC DE 48 3A 86 F4 62 10 77 05 93 E1  \ C0
   lineC, F5 87 11 63 04 76 E0 92 2E 5C CA B8 DF AD 3B 49 7A 08 9E EC 8B F9 6F 1D A1 D3 45 37 50 22 B4 C6  \ E0

create CRC8table_CRC-8/DVB-S2 ( -- a )   \ Poly = $D5 (rev $AB)  Init = $00  Xor = $00  Rev = $FF
   lineC, 00 D5 7F AA FE 2B 81 54 29 FC 56 83 D7 02 A8 7D 52 87 2D F8 AC 79 D3 06 7B AE 04 D1 85 50 FA 2F  \ 00
   lineC, A4 71 DB 0E 5A 8F 25 F0 8D 58 F2 27 73 A6 0C D9 F6 23 89 5C 08 DD 77 A2 DF 0A A0 75 21 F4 5E 8B  \ 20
   lineC, 9D 48 E2 37 63 B6 1C C9 B4 61 CB 1E 4A 9F 35 E0 CF 1A B0 65 31 E4 4E 9B E6 33 99 4C 18 CD 67 B2  \ 40
   lineC, 39 EC 46 93 C7 12 B8 6D 10 C5 6F BA EE 3B 91 44 6B BE 14 C1 95 40 EA 3F 42 97 3D E8 BC 69 C3 16  \ 60
   lineC, EF 3A 90 45 11 C4 6E BB C6 13 B9 6C 38 ED 47 92 BD 68 C2 17 43 96 3C E9 94 41 EB 3E 6A BF 15 C0  \ 80
   lineC, 4B 9E 34 E1 B5 60 CA 1F 62 B7 1D C8 9C 49 E3 36 19 CC 66 B3 E7 32 98 4D 30 E5 4F 9A CE 1B B1 64  \ A0
   lineC, 72 A7 0D D8 8C 59 F3 26 5B 8E 24 F1 A5 70 DA 0F 20 F5 5F 8A DE 0B A1 74 09 DC 76 A3 F7 22 88 5D  \ C0
   lineC, D6 03 A9 7C 28 FD 57 82 FF 2A 80 55 01 D4 7E AB 84 51 FB 2E 7A AF 05 D0 AD 78 D2 07 53 86 2C F9  \ E0

create CRC8table_CRC-8/EBU ( -- a )   \ Poly = $1D (rev $B8)  Init = $FF  Xor = $00  Rev = $00
   lineC, 00 64 C8 AC E1 85 29 4D B3 D7 7B 1F 52 36 9A FE 17 73 DF BB F6 92 3E 5A A4 C0 6C 08 45 21 8D E9  \ 00
   lineC, 2E 4A E6 82 CF AB 07 63 9D F9 55 31 7C 18 B4 D0 39 5D F1 95 D8 BC 10 74 8A EE 42 26 6B 0F A3 C7  \ 20
   lineC, 5C 38 94 F0 BD D9 75 11 EF 8B 27 43 0E 6A C6 A2 4B 2F 83 E7 AA CE 62 06 F8 9C 30 54 19 7D D1 B5  \ 40
   lineC, 72 16 BA DE 93 F7 5B 3F C1 A5 09 6D 20 44 E8 8C 65 01 AD C9 84 E0 4C 28 D6 B2 1E 7A 37 53 FF 9B  \ 60
   lineC, B8 DC 70 14 59 3D 91 F5 0B 6F C3 A7 EA 8E 22 46 AF CB 67 03 4E 2A 86 E2 1C 78 D4 B0 FD 99 35 51  \ 80
   lineC, 96 F2 5E 3A 77 13 BF DB 25 41 ED 89 C4 A0 0C 68 81 E5 49 2D 60 04 A8 CC 32 56 FA 9E D3 B7 1B 7F  \ A0
   lineC, E4 80 2C 48 05 61 CD A9 57 33 9F FB B6 D2 7E 1A F3 97 3B 5F 12 76 DA BE 40 24 88 EC A1 C5 69 0D  \ C0
   lineC, CA AE 02 66 2B 4F E3 87 79 1D B1 D5 98 FC 50 34 DD B9 15 71 3C 58 F4 90 6E 0A A6 C2 8F EB 47 23  \ E0

create CRC8table_CRC-8/I-CODE ( -- a )   \ Poly = $1D (rev $B8)  Init = $FD  Xor = $00  Rev = $FF
   lineC, 00 1D 3A 27 74 69 4E 53 E8 F5 D2 CF 9C 81 A6 BB CD D0 F7 EA B9 A4 83 9E 25 38 1F 02 51 4C 6B 76  \ 00
   lineC, 87 9A BD A0 F3 EE C9 D4 6F 72 55 48 1B 06 21 3C 4A 57 70 6D 3E 23 04 19 A2 BF 98 85 D6 CB EC F1  \ 20
   lineC, 13 0E 29 34 67 7A 5D 40 FB E6 C1 DC 8F 92 B5 A8 DE C3 E4 F9 AA B7 90 8D 36 2B 0C 11 42 5F 78 65  \ 40
   lineC, 94 89 AE B3 E0 FD DA C7 7C 61 46 5B 08 15 32 2F 59 44 63 7E 2D 30 17 0A B1 AC 8B 96 C5 D8 FF E2  \ 60
   lineC, 26 3B 1C 01 52 4F 68 75 CE D3 F4 E9 BA A7 80 9D EB F6 D1 CC 9F 82 A5 B8 03 1E 39 24 77 6A 4D 50  \ 80
   lineC, A1 BC 9B 86 D5 C8 EF F2 49 54 73 6E 3D 20 07 1A 6C 71 56 4B 18 05 22 3F 84 99 BE A3 F0 ED CA D7  \ A0
   lineC, 35 28 0F 12 41 5C 7B 66 DD C0 E7 FA A9 B4 93 8E F8 E5 C2 DF 8C 91 B6 AB 10 0D 2A 37 64 79 5E 43  \ C0
   lineC, B2 AF 88 95 C6 DB FC E1 5A 47 60 7D 2E 33 14 09 7F 62 45 58 0B 16 31 2C 97 8A AD B0 E3 FE D9 C4  \ E0

create CRC8table_CRC-8/ITU ( -- a )   \ Poly = $07 (rev $E0)  Init = $00  Xor = $55  Rev = $FF
   lineC, 00 07 0E 09 1C 1B 12 15 38 3F 36 31 24 23 2A 2D 70 77 7E 79 6C 6B 62 65 48 4F 46 41 54 53 5A 5D  \ 00
   lineC, E0 E7 EE E9 FC FB F2 F5 D8 DF D6 D1 C4 C3 CA CD 90 97 9E 99 8C 8B 82 85 A8 AF A6 A1 B4 B3 BA BD  \ 20
   lineC, C7 C0 C9 CE DB DC D5 D2 FF F8 F1 F6 E3 E4 ED EA B7 B0 B9 BE AB AC A5 A2 8F 88 81 86 93 94 9D 9A  \ 40
   lineC, 27 20 29 2E 3B 3C 35 32 1F 18 11 16 03 04 0D 0A 57 50 59 5E 4B 4C 45 42 6F 68 61 66 73 74 7D 7A  \ 60
   lineC, 89 8E 87 80 95 92 9B 9C B1 B6 BF B8 AD AA A3 A4 F9 FE F7 F0 E5 E2 EB EC C1 C6 CF C8 DD DA D3 D4  \ 80
   lineC, 69 6E 67 60 75 72 7B 7C 51 56 5F 58 4D 4A 43 44 19 1E 17 10 05 02 0B 0C 21 26 2F 28 3D 3A 33 34  \ A0
   lineC, 4E 49 40 47 52 55 5C 5B 76 71 78 7F 6A 6D 64 63 3E 39 30 37 22 25 2C 2B 06 01 08 0F 1A 1D 14 13  \ C0
   lineC, AE A9 A0 A7 B2 B5 BC BB 96 91 98 9F 8A 8D 84 83 DE D9 D0 D7 C2 C5 CC CB E6 E1 E8 EF FA FD F4 F3  \ E0

create CRC8table_CRC-8/MAXIM ( -- a )   \ Poly = $31 (rev $8C)  Init = $00  Xor = $00  Rev = $00
   lineC, 00 5E BC E2 61 3F DD 83 C2 9C 7E 20 A3 FD 1F 41 9D C3 21 7F FC A2 40 1E 5F 01 E3 BD 3E 60 82 DC  \ 00
   lineC, 23 7D 9F C1 42 1C FE A0 E1 BF 5D 03 80 DE 3C 62 BE E0 02 5C DF 81 63 3D 7C 22 C0 9E 1D 43 A1 FF  \ 20
   lineC, 46 18 FA A4 27 79 9B C5 84 DA 38 66 E5 BB 59 07 DB 85 67 39 BA E4 06 58 19 47 A5 FB 78 26 C4 9A  \ 40
   lineC, 65 3B D9 87 04 5A B8 E6 A7 F9 1B 45 C6 98 7A 24 F8 A6 44 1A 99 C7 25 7B 3A 64 86 D8 5B 05 E7 B9  \ 60
   lineC, 8C D2 30 6E ED B3 51 0F 4E 10 F2 AC 2F 71 93 CD 11 4F AD F3 70 2E CC 92 D3 8D 6F 31 B2 EC 0E 50  \ 80
   lineC, AF F1 13 4D CE 90 72 2C 6D 33 D1 8F 0C 52 B0 EE 32 6C 8E D0 53 0D EF B1 F0 AE 4C 12 91 CF 2D 73  \ A0
   lineC, CA 94 76 28 AB F5 17 49 08 56 B4 EA 69 37 D5 8B 57 09 EB B5 36 68 8A D4 95 CB 29 77 F4 AA 48 16  \ C0
   lineC, E9 B7 55 0B 88 D6 34 6A 2B 75 97 C9 4A 14 F6 A8 74 2A C8 96 15 4B A9 F7 B6 E8 0A 54 D7 89 6B 35  \ E0

create CRC8table_CRC-8/ROHC ( -- a )   \ Poly = $07 (rev $E0)  Init = $FF  Xor = $00  Rev = $00
   lineC, 00 91 E3 72 07 96 E4 75 0E 9F ED 7C 09 98 EA 7B 1C 8D FF 6E 1B 8A F8 69 12 83 F1 60 15 84 F6 67  \ 00
   lineC, 38 A9 DB 4A 3F AE DC 4D 36 A7 D5 44 31 A0 D2 43 24 B5 C7 56 23 B2 C0 51 2A BB C9 58 2D BC CE 5F  \ 20
   lineC, 70 E1 93 02 77 E6 94 05 7E EF 9D 0C 79 E8 9A 0B 6C FD 8F 1E 6B FA 88 19 62 F3 81 10 65 F4 86 17  \ 40
   lineC, 48 D9 AB 3A 4F DE AC 3D 46 D7 A5 34 41 D0 A2 33 54 C5 B7 26 53 C2 B0 21 5A CB B9 28 5D CC BE 2F  \ 60
   lineC, E0 71 03 92 E7 76 04 95 EE 7F 0D 9C E9 78 0A 9B FC 6D 1F 8E FB 6A 18 89 F2 63 11 80 F5 64 16 87  \ 80
   lineC, D8 49 3B AA DF 4E 3C AD D6 47 35 A4 D1 40 32 A3 C4 55 27 B6 C3 52 20 B1 CA 5B 29 B8 CD 5C 2E BF  \ A0
   lineC, 90 01 73 E2 97 06 74 E5 9E 0F 7D EC 99 08 7A EB 8C 1D 6F FE 8B 1A 68 F9 82 13 61 F0 85 14 66 F7  \ C0
   lineC, A8 39 4B DA AF 3E 4C DD A6 37 45 D4 A1 30 42 D3 B4 25 57 C6 B3 22 50 C1 BA 2B 59 C8 BD 2C 5E CF  \ E0

create CRC8table_CRC-8/WCDMA ( -- a )   \ Poly = $9B (rev $D9)  Init = $00  Xor = $00  Rev = $00
   lineC, 00 D0 13 C3 26 F6 35 E5 4C 9C 5F 8F 6A BA 79 A9 98 48 8B 5B BE 6E AD 7D D4 04 C7 17 F2 22 E1 31  \ 00
   lineC, 83 53 90 40 A5 75 B6 66 CF 1F DC 0C E9 39 FA 2A 1B CB 08 D8 3D ED 2E FE 57 87 44 94 71 A1 62 B2  \ 20
   lineC, B5 65 A6 76 93 43 80 50 F9 29 EA 3A DF 0F CC 1C 2D FD 3E EE 0B DB 18 C8 61 B1 72 A2 47 97 54 84  \ 40
   lineC, 36 E6 25 F5 10 C0 03 D3 7A AA 69 B9 5C 8C 4F 9F AE 7E BD 6D 88 58 9B 4B E2 32 F1 21 C4 14 D7 07  \ 60
   lineC, D9 09 CA 1A FF 2F EC 3C 95 45 86 56 B3 63 A0 70 41 91 52 82 67 B7 74 A4 0D DD 1E CE 2B FB 38 E8  \ 80
   lineC, 5A 8A 49 99 7C AC 6F BF 16 C6 05 D5 30 E0 23 F3 C2 12 D1 01 E4 34 F7 27 8E 5E 9D 4D A8 78 BB 6B  \ A0
   lineC, 6C BC 7F AF 4A 9A 59 89 20 F0 33 E3 06 D6 15 C5 F4 24 E7 37 D2 02 C1 11 B8 68 AB 7B 9E 4E 8D 5D  \ C0
   lineC, EF 3F FC 2C C9 19 DA 0A A3 73 B0 60 85 55 96 46 77 A7 64 B4 51 81 42 92 3B EB 28 F8 1D CD 0E DE  \ E0

[THEN]

\ ***************************************************************************
\ Known Answer Tests ( KAT )
\ ***************************************************************************

variable v_NextKAT_ptr
variable #failed
variable #failed_total
variable #tested
variable #tested_total

: GetNextKAT ( -- c )
   p_CRC8: @ o_OFFSET_TESTS + v_NextKAT_ptr @ + c@
   1 v_NextKAT_ptr +!
;

$40 constant |TestResults|
|TestResults| Buffer: TestResults[]
variable v_TestResultPtr

: TestResultsC! ( c -- )
   TestResults[] v_TestResultPtr @ |TestResults| 1- and + c!
   1 v_TestResultPtr +!
;

variable v_Silent

\ CRCtest  tests the CRC8 of a string given its correct result u.
: CRCtest_Verbose ( a n -- )
   cr  2 spaces  2dup type  $30 over - 0 max spaces
   CRC8  dup TestResultsC!
   dup 2.hex
   GetNextKAT 2dup = if
      2drop ."  ok"
   else
      ."  <-- should be " 2.hex ."  failed!"  drop  1 #failed +!
   then
   1 #tested +!
;

: CRCtest_Silent ( a n -- )
   CRC8  dup TestResultsC!
   GetNextKAT = not if
      1 #failed +!
   then
   1 #tested +!
;

: CRCtest ( a n -- )
   v_Silent @ if
      CRCtest_Silent
   else
      CRCtest_Verbose
   then
;

: Show_TestSetup ( -- )
   cr ." create " p_CRC8: @ o_OFFSET_NAME + count type
   $17 ToColumn
   ." lineC,  "
   p_CRC8: @     c@ 2.hex 3 spaces
   p_CRC8: @ 1 + c@ 2.hex 3 spaces
   p_CRC8: @ 2 + c@ 2.hex 2 spaces
   p_CRC8: @ 3 + c@ 2.hex 2 spaces
   TestResults[] v_TestResultPtr @ over + swap ?do  i c@ 2.hex space  loop
   [char] " emit space  p_CRC8: @ o_OFFSET_NAME + count type [char] " emit
;

\ some scratchpad contents from the DS18B20                                      \ CRC8
create KAT0[] $08 c,   $38 c, $01 c, $1F c, $1F c, $1F c, $FF c, $1F c, $10 c,   \ $9E c,
create KAT1[] $08 c,   $50 c, $01 c, $1F c, $1F c, $1F c, $FF c, $1F c, $10 c,   \ $55 c,
create KAT2[] $08 c,   $48 c, $01 c, $1F c, $1F c, $1F c, $FF c, $1F c, $10 c,   \ $2B c,
create KAT3[] $08 c,   $68 c, $01 c, $1F c, $1F c, $1F c, $FF c, $1F c, $10 c,   \ $83 c,

\ ttcrc  tests a selection of strings against the known answers listed in the current CRC8: definition line.
: Show_CRC8_test ( n -- )
   >r
   0 v_NextKAT_ptr !
   0 v_TestResultPtr !
   0 #failed !
   0 #tested !
   v_Silent @ not if  cr ." CRC8 tests : "  then
   0 0                                                   CRCtest  v_Silent @ not if  ."  ( 0 length string )"  then
   s" 123456789"                                         CRCtest
   s" the quick brown fox jumps over the lazy dog"       CRCtest
   s" THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG"       CRCtest
   s" 0"                                                 CRCtest
   s" 01"                                                CRCtest
   KAT0[] count                                          CRCtest
   KAT1[] count                                          CRCtest
   KAT2[] count                                          CRCtest
   KAT3[] count                                          CRCtest
   s" An Arbitrary String 012345"                        CRCtest
   s" ABCDEFGHIJKLMNOPQRSTUVWXYZ"                        CRCtest
   s" ZYXWVUTSRQPONMLKJIHGFEDBCA"                        CRCtest
   s" abcdefghijklmnopqrstuvwxyz"                        CRCtest
   s" zyxwvutsrqponmlkjihgfedbca"                        CRCtest
   pad #26 $00 fill pad #26                              CRCtest  v_Silent @ not if  ."  ( 26 bytes of 0 )"  then
   pad #26 $11 fill pad #26                              CRCtest  v_Silent @ not if  ."  ( 26 bytes of hex 11 )"  then
   v_Silent @ not if
      cr  #failed @ if
         ." !!!! Tested " #tested @ . ." strings, of which "  #failed @ . ." failed !!!!"
      else
         ." All " #tested @ . ." tests passed"
      then
   then
   r> Show_TestSetup
   #failed @ #failed_total +!
   #tested @ #tested_total +!
;

: Show_Title ( -- )
   cr ." \                                               |                 ... Test results ...             |"
   cr ." \      Name                  Poly Init  Xor Rev   0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16   Name"
;

: Show_CRC8tests_all ( -- )
   -1 v_Silent !     \ change to 0 to see more detailed results
   decimal
   0 #failed_total !
   0 #tested_total !
   Show_Title
   CRC-8/_             CRC8table_Init  Show_CRC8_test
   CRC-8/CDMA2000      CRC8table_Init  Show_CRC8_test
   CRC-8/DARC          CRC8table_Init  Show_CRC8_test
   CRC-8/DVB-S2        CRC8table_Init  Show_CRC8_test
   CRC-8/EBU           CRC8table_Init  Show_CRC8_test
   CRC-8/I-CODE        CRC8table_Init  Show_CRC8_test
   CRC-8/ITU           CRC8table_Init  Show_CRC8_test
   CRC-8/MAXIM         CRC8table_Init  Show_CRC8_test
   CRC-8/ROHC          CRC8table_Init  Show_CRC8_test
   CRC-8/WCDMA         CRC8table_Init  Show_CRC8_test
   cr  #failed_total @ if
      ." !!!! Tested " #tested_total @ . ." strings, of which "  #failed_total @ . ." failed !!!!"
   else
      ." All " #tested_total @ . ." tests passed"
   then
   cr ."
;

: ttCRC8 ( -- )   \ test to view one CRC-8 calculation in "silent" mode
   page Show_Title
   -1 v_Silent !
   CRC-8/_ CRC8table_Init
   Show_CRC8_test 
   cr
   Show_CRC8table
\   Show_CRC8table_C
;

: ttCRC8V ( -- )  \ test to view one CRC-8 calculation in verbose mode
   cr Show_Title
   0 v_Silent !
   CRC-8/_ CRC8table_Init
   Show_CRC8_test 
   cr
   Show_CRC8table
\   Show_CRC8table_C
;

\ *****************************************************************************
\ CRC-8 calculation using a pre-defined table
\ *****************************************************************************

create CRC8table_CRC-8/_ ( -- a )   \ Poly = $07 (rev $E0)  Init = $00  Xor = $00  Rev = $FF
   lineC, 00 07 0E 09 1C 1B 12 15 38 3F 36 31 24 23 2A 2D 70 77 7E 79 6C 6B 62 65 48 4F 46 41 54 53 5A 5D  \ 00
   lineC, E0 E7 EE E9 FC FB F2 F5 D8 DF D6 D1 C4 C3 CA CD 90 97 9E 99 8C 8B 82 85 A8 AF A6 A1 B4 B3 BA BD  \ 20
   lineC, C7 C0 C9 CE DB DC D5 D2 FF F8 F1 F6 E3 E4 ED EA B7 B0 B9 BE AB AC A5 A2 8F 88 81 86 93 94 9D 9A  \ 40
   lineC, 27 20 29 2E 3B 3C 35 32 1F 18 11 16 03 04 0D 0A 57 50 59 5E 4B 4C 45 42 6F 68 61 66 73 74 7D 7A  \ 60
   lineC, 89 8E 87 80 95 92 9B 9C B1 B6 BF B8 AD AA A3 A4 F9 FE F7 F0 E5 E2 EB EC C1 C6 CF C8 DD DA D3 D4  \ 80
   lineC, 69 6E 67 60 75 72 7B 7C 51 56 5F 58 4D 4A 43 44 19 1E 17 10 05 02 0B 0C 21 26 2F 28 3D 3A 33 34  \ A0
   lineC, 4E 49 40 47 52 55 5C 5B 76 71 78 7F 6A 6D 64 63 3E 39 30 37 22 25 2C 2B 06 01 08 0F 1A 1D 14 13  \ C0
   lineC, AE A9 A0 A7 B2 B5 BC BB 96 91 98 9F 8A 8D 84 83 DE D9 D0 D7 C2 C5 CC CB E6 E1 E8 EF FA FD F4 F3  \ E0

\ CRC-8 calculation using a pre-defined table
: CRC8_const ( a n -- c )   \ calculates the CRC8 of the given string using the parameters in the CRC8: definition string stored in p_CRC8:
   ( Init ) $00  -rot  \ v_CRC8 c!      \ initialises the output CRC value in the required way
   over + swap ?do
      i c@
      xor CRC8table_CRC-8/_ + c@
   loop
  \ ( Xor ) $00 xor     \ no need to do this if the value is 0
;

: tt_CRC8_const ( -- )
   cr ." tt_CRC8_const : " 
   s" 123456789" CRC8_const $F4 = if  ." Passed "  else  ." Failed!!!"  then 
;

\ *****************************************************************************
\ *****************************************************************************

cr .( Show_CRCtables_all , Show_CRCtables_all_C or Show_CRC8tests_all )
cr .( Also tt_CRC8_const, ttCRC8 or ttCRC8V )
cr

by HowerdOakford

avatar of HowerdOakford

Versions

0.1.0

Download current as zip

Tags

None

Dependencies

None

Dependents

None