aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/common/lib/crc8.frt
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-08-19 12:15:28 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-08-19 12:15:28 +0200
commit67d25d837ac55f28a366c0a3b262e439a6e75fc3 (patch)
treedf7715c7724c5935ab87c807f3b8b4ef529315e3 /amforth-6.5/common/lib/crc8.frt
parente0d6784e89dba33226c0edb815bb974486fa7c48 (diff)
Add AmForth
Diffstat (limited to 'amforth-6.5/common/lib/crc8.frt')
-rw-r--r--amforth-6.5/common/lib/crc8.frt94
1 files changed, 94 insertions, 0 deletions
diff --git a/amforth-6.5/common/lib/crc8.frt b/amforth-6.5/common/lib/crc8.frt
new file mode 100644
index 0000000..f2d4e17
--- /dev/null
+++ b/amforth-6.5/common/lib/crc8.frt
@@ -0,0 +1,94 @@
+\ -*- Mode: Forth; Coding: utf-8 -*-
+
+\ Copyright (c) 2013 Energy Measurement & Control, NJ, USA.
+\ Software license: AmForth compliant, see http://amforth.sourceforge.net/
+\
+\ (crc8) is a configurable 8-bit table-driven CRC generator/checker. For usage
+\ see below (*). (crc8) was adapted from Linux/lib/crc8.c, See:
+\ http://lxr.free-electrons.com/source/include/linux/crc8.h
+\
+\ fabtab: is a factory function for arbitrary-length byte-wide Flash look-up
+\ tables. Data is read from the pad.
+
+\ #error-on-output
+
+decimal
+
+\ IMPORTANT:
+\ amforth-shell needs the following constants defined in appl_defs.frt
+\ msb-first poly: (1)11010101 = 0xD5
+\ lsb-first poly: 10101011(1) = 0xAB
+\ bit-order: true = msb-first, false = lsb-first
+(
+$d5 constant CRC8MSB
+$ab constant CRC8LSB
+true constant CRC8REV
+)
+
+\ verify having 256 pad bytes to form the crc table
+\ #expect-output-next ^-1 0 $
+s" /pad" environment? . 256 < .
+
+\ pad bytes → flash table factory function
+: fabtab: create ( "table-name" table-byte-count -- )
+ dup , \ table byte count
+ 1+ 2/ 0 do pad i 2* + @ , loop \ table words
+ does> ( table-byte-index -- table-byte )
+ 2dup @i U< if
+ over 2/ + 1+ @i \ ( table-byte-index table-word )
+ swap 1 and \ ( table-word high-byte? )
+ if >< then 255 and \ AVR is little endian
+ else
+ -9 throw \ index out of range
+ then
+;
+
+marker ->crc8
+
+\ populate pad with crc table for CRC8MSB poly in reverse bit order
+: crc8_msb_pad ( -- )
+ 0 pad c! \ "table[0] = 0"
+ 1 $80 begin \ ( 2ˣ "t" ) x: 0→7
+ dup $80 and if CRC8MSB else 0 then
+ swap 2* xor \ update "t"
+ swap dup 0 do \ ( "t" 2ˣ )
+ over pad i + c@ xor \ ( "t" 2ˣ "table[j] ^ t" )
+ over pad + i + c! \ "table[i+j] = ..."
+ loop
+ 2* dup 256 < \ ( "t" 2ˣ⁺¹ flag )
+ while swap \ ( 2ˣ⁺¹ "t" )
+ repeat
+ 2drop
+;
+
+\ populate pad with crc table for CRC8LSB poly in regular bit order
+: crc8_lsb_pad ( -- )
+ 0 pad c! \ "table[0] = 0"
+ 128 $01 begin \ ( 2ˣ "t") x: 7→0
+ dup 1 and if CRC8LSB else 0 then
+ swap 2/ xor \ update "t"
+ swap 256 0 do \ ( "t" 2ˣ )
+ over pad i + c@ xor \ ( "t" 2ˣ "table[j] ^ t" )
+ over pad + i + c! \ "table[i+j] = ..."
+ dup 2* +loop
+ 2/ dup \ ( "t" 2ˣ⁻¹ flag )
+ while swap \ ( 2ˣ⁻¹ "t" )
+ repeat
+ 2drop
+;
+
+\ CRC8REV [if] crc8_msb_pad [else] crc8_lsb_pad [then]
+: crc8_pad CRC8REV if crc8_msb_pad else crc8_lsb_pad then ; crc8_pad
+
+->crc8 \ pad data is preserved
+
+256 fabtab: crc8tb@ \ 256B pad → flash lookup table
+
+\ (*) Using (crc8):
+\ The initial crc-byte should be 255
+\ To the outgoing message append the byte-complement of crc-byte'
+\ The final crc-byte' of a valid incoming message+crc is: 255 crc8tb@
+
+: (crc8) ( crc-byte data-byte -- crc-byte' )
+ xor crc8tb@
+;