zigbee-herdsman
Version:
An open source ZigBee gateway solution with node.js.
74 lines (65 loc) • 3.22 kB
text/typescript
/* v8 ignore start */
//--------------------------------------------------------------
// Define macros for handling 3-bit frame numbers modulo 8
/** mask to frame number modulus */
export const mod8 = (n: number): number => n & 7;
/** increment in frame number modulus */
export const inc8 = (n: number): number => mod8(n + 1);
/** Return true if n is within the range lo through hi, computed (mod 8) */
export const withinRange = (lo: number, n: number, hi: number): boolean => mod8(n - lo) <= mod8(hi - lo);
//--------------------------------------------------------------
// CRC
/**
* Calculates 16-bit cyclic redundancy code (CITT CRC 16).
*
* Applies the standard CITT CRC 16 polynomial to a
* single byte. It should support being called first with an initial
* value, then repeatedly until all data is processed.
*
* @param newByte The new byte to be run through CRC.
* @param prevResult The previous CRC result.
* @returns The new CRC result.
*/
export const halCommonCrc16 = (newByte: number, prevResult: number): number => {
/*
* 16bit CRC notes:
* "CRC-CCITT"
* poly is g(X) = X^16 + X^12 + X^5 + 1 (0x1021)
* used in the FPGA (green boards and 15.4)
* initial remainder should be 0xFFFF
*/
prevResult = ((prevResult >> 8) & 0xffff) | ((prevResult << 8) & 0xffff);
prevResult ^= newByte;
prevResult ^= (prevResult & 0xff) >> 4;
prevResult ^= (((prevResult << 8) & 0xffff) << 4) & 0xffff;
prevResult ^= (((prevResult & 0xff) << 5) & 0xff) | (((((prevResult & 0xff) >> 3) & 0xffff) << 8) & 0xffff);
return prevResult;
};
//--------------------------------------------------------------
// Byte manipulation
/** Returns the low bits of the 8-bit value 'n' as uint8_t. */
export const lowBits = (n: number): number => n & 0xf;
/** Returns the high bits of the 8-bit value 'n' as uint8_t. */
export const highBits = (n: number): number => lowBits(n >> 4) & 0xf;
/** Returns the low byte of the 16-bit value 'n' as uint8_t. */
export const lowByte = (n: number): number => n & 0xff;
/** Returns the high byte of the 16-bit value 'n' as uint8_t. */
export const highByte = (n: number): number => lowByte(n >> 8) & 0xff;
/** Returns the value built from the two uint8_t values high and low. */
export const highLowToInt = (high: number, low: number): number => ((high & 0xffff) << 8) + (low & 0xffff & 0xff);
/** Useful to reference a single bit of a byte. */
export const bit = (x: number): number => 1 << x;
/** Useful to reference a single bit of an uint32_t type. */
export const bit32 = (x: number): number => 1 << x;
/** Returns both the low and high bytes (in that order) of the same 16-bit value 'n' as uint8_t. */
export const lowHighBytes = (n: number): [number, highByte: number] => [lowByte(n), highByte(n)];
/** Returns both the low and high bits (in that order) of the same 8-bit value 'n' as uint8_t. */
export const lowHighBits = (n: number): [number, highBits: number] => [lowBits(n), highBits(n)];
/**
* Get byte as an 8-bit string (`n` assumed of proper range).
* @param n
* @returns
*/
export const byteToBits = (n: number): string => {
return (n >>> 0).toString(2).padStart(8, "0");
};