Hi,
I'm wondering, have you implemented function for CRC calculation in mikroPascal PRO for ARM?
In the datasheet (datasheet for STM32F415xx/STM32F417xx), I have found that STM32F415xx have CRC calculation unit (first page).
Was looking in library manager without success. Need to check CRC from received message - calculate CRC and then compare with CRC in message. If they are equal - can perform other operations.
Using mikroPascal PRO for ARM v420.
Best regards,
Mironso.
CRC calculation
- Aleksandar.Mitrovic
- mikroElektronika team
- Posts: 1697
- Joined: 11 Mar 2015 12:48
Re: CRC calculation
Hi Mironso,
Unfortunately currently we do not have this CRC (Cyclic Redundancy Check) function in our Libraries.
I will suggest our Development team to consider adding this function in our compilers.
Best regards,
Aleksandar
Unfortunately currently we do not have this CRC (Cyclic Redundancy Check) function in our Libraries.
I will suggest our Development team to consider adding this function in our compilers.
Best regards,
Aleksandar
Re: CRC calculation
This can be easily achieved in software. However, unlike the HW CRC unit, there are many ways to calculate CRC (look-up table or bit-by-bit). Also, checksum length can vary. I guess you need CRC32 since it's the most popular one.mironso wrote:I'm wondering, have you implemented function for CRC calculation in mikroPascal PRO for ARM?
Here's the code:
Code: Select all
const _CRC32_POLY_REVERSE : dword = $EDB88320;
function CRC32_Custom(data_in : ^byte; len, poly : dword; ) : dword;
var
lsb, j : byte;
crc : dword;
begin
crc := $FFFFFFFF;
while len > 0 do
begin
crc := crc xor data_in^;
for j := 0 to 7 do
begin
lsb := crc and 1;
crc := crc shr 1;
if lsb = 1 then crc := crc xor poly;
end;
Inc(data_in);
Dec(len);
end;
result := not crc;
end;
function CRC32(data_in : ^byte; len : dword) : dword;
begin
result := CRC32_Custom(data_in, len, _CRC32_POLY_REVERSE);
end;
Code: Select all
var
msg : string[9];
csum : dword;
begin
msg := '123456789';
csum := CRC32(@msg, sizeof(msg) - 1); // exclude terminator
// csum = $CBF43926
end.
Regards
Re: CRC calculation
Hi,
@Aleksandar: if you can suggest 2 types, CRC16 and CRC32. I needed CRC16 (modbus). Found it on net, had some difficulties to implement (lack of programming exp and specification of project), but now its working.
@aCko: thanks for example. Although it's not what I wanted, but was not specific what I wanted, wish you express my gratitude for your effort. Will save your example for further usage.
My goal was to calculate CRC from received msg and compare it against CRC included into msg.
If someone is interested, I can post my example.
Best regards,
Mironso.
@Aleksandar: if you can suggest 2 types, CRC16 and CRC32. I needed CRC16 (modbus). Found it on net, had some difficulties to implement (lack of programming exp and specification of project), but now its working.
@aCko: thanks for example. Although it's not what I wanted, but was not specific what I wanted, wish you express my gratitude for your effort. Will save your example for further usage.
My goal was to calculate CRC from received msg and compare it against CRC included into msg.
If someone is interested, I can post my example.
Best regards,
Mironso.
Re: CRC calculation
Hi,
You have here CRC16 and CRC32, enjoy:
You have here CRC16 and CRC32, enjoy:
Code: Select all
unit crc16_lib;
function get_crc16(var d_in : array[$FFFF] of byte; n : word) : word;
function get_crc16_pt(d_in : ^byte; n : word) : word;
function get_crc32(var d_in : array[$FFFF] of byte; n : word) : dword;
function get_crc32_pt(d_in : ^byte; n : word) : dword;
CONST
Table16: ARRAY[0..255] OF WORD =
($0000,$C0C1,$C181,$0140,$C301,$03C0,$0280,$C241,$C601,$06C0,$0780,
$C741,$0500,$C5C1,$C481,$0440,$CC01,$0CC0,$0D80,$CD41,$0F00,$CFC1,
$CE81,$0E40,$0A00,$CAC1,$CB81,$0B40,$C901,$09C0,$0880,$C841,$D801,
$18C0,$1980,$D941,$1B00,$DBC1,$DA81,$1A40,$1E00,$DEC1,$DF81,$1F40,
$DD01,$1DC0,$1C80,$DC41,$1400,$D4C1,$D581,$1540,$D701,$17C0,$1680,
$D641,$D201,$12C0,$1380,$D341,$1100,$D1C1,$D081,$1040,$F001,$30C0,
$3180,$F141,$3300,$F3C1,$F281,$3240,$3600,$F6C1,$F781,$3740,$F501,
$35C0,$3480,$F441,$3C00,$FCC1,$FD81,$3D40,$FF01,$3FC0,$3E80,$FE41,
$FA01,$3AC0,$3B80,$FB41,$3900,$F9C1,$F881,$3840,$2800,$E8C1,$E981,
$2940,$EB01,$2BC0,$2A80,$EA41,$EE01,$2EC0,$2F80,$EF41,$2D00,$EDC1,
$EC81,$2C40,$E401,$24C0,$2580,$E541,$2700,$E7C1,$E681,$2640,$2200,
$E2C1,$E381,$2340,$E101,$21C0,$2080,$E041,$A001,$60C0,$6180,$A141,
$6300,$A3C1,$A281,$6240,$6600,$A6C1,$A781,$6740,$A501,$65C0,$6480,
$A441,$6C00,$ACC1,$AD81,$6D40,$AF01,$6FC0,$6E80,$AE41,$AA01,$6AC0,
$6B80,$AB41,$6900,$A9C1,$A881,$6840,$7800,$B8C1,$B981,$7940,$BB01,
$7BC0,$7A80,$BA41,$BE01,$7EC0,$7F80,$BF41,$7D00,$BDC1,$BC81,$7C40,
$B401,$74C0,$7580,$B541,$7700,$B7C1,$B681,$7640,$7200,$B2C1,$B381,
$7340,$B101,$71C0,$7080,$B041,$5000,$90C1,$9181,$5140,$9301,$53C0,
$5280,$9241,$9601,$56C0,$5780,$9741,$5500,$95C1,$9481,$5440,$9C01,
$5CC0,$5D80,$9D41,$5F00,$9FC1,$9E81,$5E40,$5A00,$9AC1,$9B81,$5B40,
$9901,$59C0,$5880,$9841,$8801,$48C0,$4980,$8941,$4B00,$8BC1,$8A81,
$4A40,$4E00,$8EC1,$8F81,$4F40,$8D01,$4DC0,$4C80,$8C41,$4400,$84C1,
$8581,$4540,$8701,$47C0,$4680,$8641,$8201,$42C0,$4380,$8341,$4100,
$81C1,$8081,$4040); code;
CONST
Table32: ARRAY[0..255] OF DWORD =
(0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D); code;
implementation
function get_crc16(var d_in : array[$FFFF] of byte; n : word) : word;
var i : word;
begin
result := $FFFF;
i := 0;
while i < n do
begin
result := Hi(result) XOR Table16[d_in[i] XOR Lo(result)];
inc(i);
end;
end;
function get_crc16_pt(d_in : ^byte; n : word) : word;
var i : word;
begin
result := $FFFF;
i := 0;
while i < n do
begin
result := Hi(result) XOR Table16[d_in^ XOR Lo(result)];
inc(d_in);
inc(i);
end;
end;
function get_crc32(var d_in : array[$FFFF] of byte; n : word) : dword;
var i : word;
begin
result := $FFFFFFFF;
i := 0;
while i < n do
begin
result := Table32[d_in[i] XOR Lo(result)] XOR (result shr 8);
inc(i);
end;
result := result XOR $FFFFFFFF;
end;
function get_crc32_pt(d_in : ^byte; n : word) : dword;
var i : word;
begin
result := $FFFFFFFF;
i := 0;
while i < n do
begin
result := Table32[d_in^ XOR Lo(result)] XOR (result shr 8);
inc(i);
end;
result := result XOR $FFFFFFFF;
end;
end.
Best regards, Florin Andrei Medrea.
http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/
mail : florin@microelemente.ro
http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/
mail : florin@microelemente.ro
Re: CRC calculation
The quality of expected answer depends on user's ability to precisely describe the problem. I see that yo2lio already posted the table look-up method. To generate CRC16 MODBUS checksum "manually" you just need to make 2 cosmetic changes to the code I posted: adjust the data types and change the polynomial.mironso wrote:@aCko: thanks for example. Although it's not what I wanted, but was not specific what I wanted, wish you express my gratitude for your effort. Will save your example for further usage.
Here's the complete code:
Code: Select all
const _CRC16_POLY_MODBUS : word = $A001;
function CRC16_Custom(data_in : ^byte; len, poly : word; ) : word;
var
lsb, j : byte;
crc : word;
begin
crc := $FFFF;
while len > 0 do
begin
crc := crc xor data_in^;
for j := 0 to 7 do
begin
lsb := crc and $0001;
crc := crc shr 1;
if lsb = 1 then crc := crc xor poly;
end;
Inc(data_in);
Dec(len);
end;
result := crc;
end;
function CRC16(data_in : ^byte; len : word) : word;
begin
result := CRC16_Custom(data_in, len, _CRC16_POLY_MODBUS);
end;
Code: Select all
var
msg : string[9];
csum : word;
begin
msg := '123456789';
csum := CRC16(@msg, sizeof(msg) - 1); // exclude terminator
// csum = $4B37
end.
Re: CRC calculation
Hi guys,
have been away for a while. Thanks for your effort providing CRC calculation. Have been created some modified version for my needs.
CRC that you give here, will serve me in the future, for sure, and will help other member(s) also.
Thanks to community for fast reply(ies).
have been away for a while. Thanks for your effort providing CRC calculation. Have been created some modified version for my needs.
CRC that you give here, will serve me in the future, for sure, and will help other member(s) also.
Thanks to community for fast reply(ies).
Re: CRC calculation
Many thanks aCkO, using your CRC16 MODBUS.