def _crc_update(crc, data, mask, const):
    """
    CRC8/16 update function taken from _crc_ibutton_update() function
    found in "Atmel Toolchain/AVR8 GCC/Native/3.4.1061/
    avr8-gnu-toolchain/avr/include/util/crc16.h" documentation.
    @param[in] crc current CRC value
    @param[in] data next byte of data
    @param[in] mask CRC mask, must be 0xff for CRC8 and 0xffff for CRC16
    @param[in] const CRC polynomial constant
    @returns Next CRC value either 8 or 16 bit depending on mask
    """
    crc = (crc & mask) ^ (data & 0xff)
    for _ in range(8):
        if crc & 1:
            crc = (crc >> 1) ^ const
        else:
            crc >>= 1
    return crc & mask