Hi all, I have a new piece of code to post.
This library can calculate a running CRC32 on a stream object.
Here are some other objects I have recently worked on, these are all part of a new library I'm planning to release.
Dual Writer
Base64Writer
URI Encoder
Below is the test code I wrote for it. The code will take anything and on a new line or carriage return the CRC of what has streamed in & out will be printed.
Like the tools posted above, they take a reference to a Print or Stream object, in this example, I use Serial.
The main functions ( apart from the print functionality ) are:
- getCRC
- resetCRC
Each one takes a value specifying the CRC to use. The options are CRC_INPUT and CRC_OUTPUT
This library is built off the CRC32 code I found here, linked from here.
Test code for StreamCRC:
#include <StreamCRC.h>
StreamCRC s_CRC( Serial );
void setup(){
Serial.begin( 9600 );
Serial.println( F("Type anything to get started, on a new line or carriage return the CRC of what has streamed in & out will be printed.") );
}
void loop(){
if( s_CRC.available() > 0x00 ){
switch( s_CRC.peek() ){
case '\r':
case '\n':
//Only print CRC if something has been recieved other than a new line char.
if( s_CRC.getCRC( CRC_INPUT ) != 0 ){
Serial.print( "\r\nOUT CRC: " );
Serial.println( s_CRC.getCRC( CRC_OUTPUT ), HEX );
s_CRC.print( "IN CRC: " );
s_CRC.println( s_CRC.getCRC( CRC_INPUT ), HEX );
}
s_CRC.read();
s_CRC.resetCRC( CRC_OUTPUT );
s_CRC.resetCRC( CRC_INPUT );
break;
default:
s_CRC.write( s_CRC.read() );
}
}
}
A test typing HELLO printed a CRC verifyable with PHP.
Type anything to get started, on a new line or carriage return the CRC of what has streamed in & out will be printed.
HELLO
OUT CRC: C1446436
IN CRC: C1446436
I will add the code here for people not logged on, also the files are attached.
#include "Arduino.h"
#ifndef HEADER_CRCSTREAM
#define HEADER_CRCSTREAM
enum CRC_STREAM_ID{ CRC_INPUT, CRC_OUTPUT };
class StreamCRC : public Stream{
public:
StreamCRC( Stream &s_Stream ) : stream( s_Stream ), CRCIN( ~0L ), CRCOUT( CRCIN ) { return; }
int available( void ) { return stream.available(); }
void flush( void ) { stream.flush(); }
unsigned long getCRC( CRC_STREAM_ID c_ID ) { return ~( c_ID ? CRCOUT : CRCIN ); }
int peek( void ) { return stream.peek(); }
int read( void );
void resetCRC( CRC_STREAM_ID c_ID ) { ( c_ID ? CRCOUT : CRCIN ) = ~0L; }
size_t write( uint8_t u_Data );
protected:
Stream &stream;
unsigned long CRCIN;
unsigned long CRCOUT;
};
#endif
#include "StreamCRC.h"
uint32_t crc_table[ 0x10 ] PROGMEM = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
void crc32Byte( unsigned long &u_CRC, uint8_t u_Data )
{
uint8_t u_Idx;
u_Idx = u_CRC ^ u_Data;
u_CRC = pgm_read_dword( crc_table + ( u_Idx & 0x0F ) ) ^ ( u_CRC >> 4 );
u_Idx = u_CRC ^ ( u_Data >> 4 );
u_CRC = pgm_read_dword( crc_table + ( u_Idx & 0x0F ) ) ^ ( u_CRC >> 4 );
}
int StreamCRC::read( void )
{
const int i_Read = stream.read();
if( i_Read != -1 ) crc32Byte( CRCIN, ( uint8_t ) i_Read );
return i_Read;
}
size_t StreamCRC::write( uint8_t u_Data )
{
crc32Byte( CRCOUT, u_Data );
return stream.write( u_Data );
}
Hope someone can get some use out of this, and as always any comments are appreciated.
StreamCRC.h (854 Bytes)
StreamCRC.cpp (883 Bytes)