Mercurial > public > ostc4
diff Discovery/Src/crcmodel.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Src/crcmodel.c Sat Apr 28 11:52:34 2018 +0200 @@ -0,0 +1,137 @@ +/******************************************************************************/ +/* Start of crcmodel.c */ +/******************************************************************************/ +/* */ +/* Author : Ross Williams (ross@guest.adelaide.edu.au.). */ +/* Date : 3 June 1993. */ +/* Status : Public domain. */ +/* */ +/* Description : This is the implementation (.c) file for the reference */ +/* implementation of the Rocksoft^tm Model CRC Algorithm. For more */ +/* information on the Rocksoft^tm Model CRC Algorithm, see the document */ +/* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */ +/* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */ +/* "ftp.adelaide.edu.au/pub/rocksoft". */ +/* */ +/* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */ +/* */ +/******************************************************************************/ +/* */ +/* Implementation Notes */ +/* -------------------- */ +/* To avoid inconsistencies, the specification of each function is not echoed */ +/* here. See the header file for a description of these functions. */ +/* This package is light on checking because I want to keep it short and */ +/* simple and portable (i.e. it would be too messy to distribute my entire */ +/* C culture (e.g. assertions package) with this package. */ +/* */ +/******************************************************************************/ + +#include "crcmodel.h" + +/******************************************************************************/ + +/* The following definitions make the code more readable. */ + +#define BITMASK(X) (1L << (X)) +#define MASK32 0xFFFFFFFFL +#define LOCAL static + +/******************************************************************************/ + +LOCAL ulong reflect P_((ulong v,int b)); +LOCAL ulong reflect (ulong v,int b) +/* Returns the value v with the bottom b [0,32] bits reflected. */ +/* Example: reflect(0x3e23L,3) == 0x3e26 */ +{ + int i; + ulong t = v; + for (i=0; i<b; i++) + { + if (t & 1L) + v|= BITMASK((b-1)-i); + else + v&= ~BITMASK((b-1)-i); + t>>=1; + } + return v; +} + +/******************************************************************************/ + +LOCAL ulong widmask P_((p_cm_t)); +LOCAL ulong widmask (p_cm_t p_cm) +/* Returns a longword whose value is (2^p_cm->cm_width)-1. */ +/* The trick is to do this portably (e.g. without doing <<32). */ +{ + return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L; +} + +/******************************************************************************/ + +void cm_ini (p_cm_t p_cm) +{ + p_cm->cm_reg = p_cm->cm_init; +} + +/******************************************************************************/ + +void cm_nxt (p_cm_t p_cm, int ch) +{ + int i; + ulong uch = (ulong) ch; + ulong topbit = BITMASK(p_cm->cm_width-1); + + if (p_cm->cm_refin) uch = reflect(uch,8); + p_cm->cm_reg ^= (uch << (p_cm->cm_width-8)); + for (i=0; i<8; i++) + { + if (p_cm->cm_reg & topbit) + p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly; + else + p_cm->cm_reg <<= 1; + p_cm->cm_reg &= widmask(p_cm); + } +} + +/******************************************************************************/ + +void cm_blk (p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len) +{ + while (blk_len--) cm_nxt(p_cm,*blk_adr++); +} + +/******************************************************************************/ + +ulong cm_crc (p_cm_t p_cm) +{ + if (p_cm->cm_refot) + return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width); + else + return p_cm->cm_xorot ^ p_cm->cm_reg; +} + +/******************************************************************************/ + +ulong cm_tab (p_cm_t p_cm, int index) +{ + int i; + ulong r; + ulong topbit = BITMASK(p_cm->cm_width-1); + ulong inbyte = (ulong) index; + + if (p_cm->cm_refin) inbyte = reflect(inbyte,8); + r = inbyte << (p_cm->cm_width-8); + for (i=0; i<8; i++) + if (r & topbit) + r = (r << 1) ^ p_cm->cm_poly; + else + r<<=1; + if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width); + return r & widmask(p_cm); +} + +/******************************************************************************/ +/* End of crcmodel.c */ +/******************************************************************************/ +