The Behringer DEQ2496 audio device can have commands sent to it via MIDI, however they require a valid CRC code in order for the device to accept them.

I have thus far been unable to work out how the CRC code is calculated. The manual suggests it is CRC8 however I have not been able to configure a CRC8 algorithm to produce matching values.

Here is some sample data, including valid CRC codes:

The DEQ2496 SysEx manual says of the layout of each of the above files:

blockdata: 7/8 coded: blockno_h, blockno_l, crc, data[256].

crc: crc8 checksum of blockno_h, blockno_l, data[256]

blockno: transferred 256 byte data block number (bits 21..15, 14..8 of flash offset); blocks 0-0x1f: boot loader; blocks 0x20..0x5ef: application; blocks 0x5f0-0x5ff: startup screen; blocks 0x600-0x67f: presets; blocks 0x680-0x69f: temporary buffers; blocks 0x6a0-0x7ff: hw configuration; block no 0xff00 shows text message data[0..52] on screen

data: data block

I have taken care of the 7/8 coding, so now I have a block of 3+256 bytes, consisting of:

  • Offset 0: 16-bit big endian integer, block number
  • Offset 2: 8-bit integer, CRC (this is the value I am trying to calculate)
  • Offset 3+: Actual data

I've tried a couple of CRC algorithms (with and without a lookup table), written code to run through all possible 8-bit polynomials, initial and final XOR values, and yet I can't find any parameters that work for more than one block.

Although the manual suggests the CRC byte itself is not included in the CRC calculation, I also tried leaving it in place and setting it to various values like 0x00 and 0xFF however this didn't yield any results either.

Is there anyone with more CRC knowledge than me who is able to figure out what they mean here by "crc8 checksum"?

1 Answer 1


Well thanks to @IgorSkochinsky who suggested in another question of mine to try a disassembler, I found a Docker image that contained a Blackfin toolchain which allowed me to use objdump to disassemble the code:

bfin-elf-objdump -D -b binary -mbfin bootloader.bin > bootloader.disasm

After hastily consulting a manual on Blackfin assembler and poking around a bit, I was able to get a vague idea of what was going on, and I was able to find the CRC function, which turned out not to be a CRC function at all, but a DIY checksum.

Using the disassembly as a reference, I was able to replicate the algorithm in my Javascript code:

function behringer_crc8(data) {
    let crc = 0;
    for (let b of data) {
        for (let j = 0; j < 8; j++) {
            if (!((b ^ crc) & 1)) crc ^= 0x19;
            b >>= 1;
            // Rotate (shift right, move lost LSB to new MSB)
            crc = ((crc & 1) << 7) | (crc >> 1);
    return crc ^ 0xbf;

Comparing this code against the distributed firmware update shows that it is able to reproduce the CRC bytes correctly!

It also turned out that despite the manual saying the two-byte block number prefix was included in the checksum, it turned out it wasn't, and only the 256-byte content is checksummed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.