Skip to content

Instantly share code, notes, and snippets.

@andresv
Last active July 16, 2024 15:59
Show Gist options
  • Save andresv/4611897 to your computer and use it in GitHub Desktop.
Save andresv/4611897 to your computer and use it in GitHub Desktop.
AX25 CRC16 implementation
uint16_t ax25crc16(unsigned char *data_p, uint16_t length) {
uint16_t crc = 0xFFFF;
uint32_t data;
uint16_t crc16_table[] = {
0x0000, 0x1081, 0x2102, 0x3183,
0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xa50a, 0xb58b,
0xc60c, 0xd68d, 0xe70e, 0xf78f
};
while(length--){
crc = ( crc >> 4 ) ^ crc16_table[(crc & 0xf) ^ (*data_p & 0xf)];
crc = ( crc >> 4 ) ^ crc16_table[(crc & 0xf) ^ (*data_p++ >> 4)];
}
data = crc;
crc = (crc << 8) | (data >> 8 & 0xff); // do byte swap here that is needed by AX25 standard
return (~crc);
}
@qwedgh
Copy link

qwedgh commented Dec 5, 2023

thanks, misspell -> length

@andresv
Copy link
Author

andresv commented Dec 5, 2023

Typo fixed.

@rhoward99
Copy link

Thanks for the implementation! In return, here is a version of it converted to Matlab:
...
function [CRC] = ax25crc16(msg, len)
% AX25CRC16 calculates the CRC-16 value for a message using the X.25 polynomial
% Source Implementation: https://gist.github.com/andresv/4611897
% Input:
% msg: A row vector containing the message data
% Output:
% CRC: The calculated CRC-16 value (uint16)

% Pre-defined CRC-16 table
crc16_table = [ ...
0x0000, 0x1081, 0x2102, 0x3183, ...
0x4204, 0x5285, 0x6306, 0x7387, ...
0x8408, 0x9489, 0xa50a, 0xb58b, ...
0xc60c, 0xd68d, 0xe70e, 0xf78f
];

crc = 0xffff; % initial value
ptr = 1;
while len > 0
crc = bitxor(bitshift(crc, -4), crc16_table(bitxor(bitand(crc, uint16(0x0f)),bitand(uint16(msg(ptr)), uint16(0x0f))) + 1));
crc = bitxor(bitshift(crc, -4), crc16_table(bitxor(bitand(crc, uint16(0x0f)),bitshift(uint16(msg(ptr)), -4)) + 1));
ptr = ptr + 1;
len = len - 1;
end

CRC = bitcmp(crc);
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment