Attempting to reverse-engineer a checksum for a serial timing device that updates a display. Protocol is partly understood, however the checksum calculation specified does not produce the expected value. I would like to understand what is happening in this protocol, as I would like to write to the display with my own software and not just sniff the data. Known parameters: ==================== - RS-485 half duplex - 8n1 - DATA0...n transmitted unchanged, low nibbles are BCD (0-9) - ADDR byte and CSUM byte split into two bytes each, hi and lo nibbles might be split between the two bytes, however I'm confused as to why it appears that the ADDR byte is a start flag byte. sub_ADDR matches the protocol specification. - One-way communication - FEC appears to be "repeat the message" as all packets are immediately duplicated in the recorded stream, i.e. 1,1,2,2,3,3..etc. - Receiver likely "pretends it never happened" if packets are mangled as past data is irrelevant **First question:** If the FEC is indeed "repeat", does it follow that the designer would incorporate a CSUM? Perhaps the packets that appear to be CSUM are something else not documented? ---- Packet format: ------------------ as described in protocol spec, possibly incorrect or outdated. **"X"** denotes a nibble that takes a value. **"?"** denotes a nibble that is used for flag bits. | lo_ADDR | hi_ADDR | sub_ADDR | DATA_0 | DATA_1 | DATA_2 | DATA_3 | lo_CSUM | hi_CSUM | | 0x8X | 0x9X | 0x0c | 0x?X | 0x?X | 0x?X | 0x?X | 0xAX | 0xBX | Some of the fields seem to match; others don't. As seen below, lo and hi ADDR and lo and hi CSUM don't seem to match the description. Most packets in the stream appear to start with **0x0a** and end with **0x0b**, although some packets observed don't follow that pattern. Are they flag bytes? An example of two packets of interest, bytes that work as specified marked **ok**, ones that don't with **!k** !k ok ok ok ok ok !k !k !k ok ok ok ok ok !k 0a 0c 02 00 60 00 80 0b 28 0c 02 00 60 00 80 Straight from Pyserial, appears as follows: b'\n\x0c\x02\x00`\x00\x80\x0b(\x0c\x02\x00 \x00\x80' Ten lines of packets, two neighboring packets shown, repeats removed: A1 A2 A3 A4 A5 A6 A7 A8 B1 B2 B3 B4 B5 B6 B7 ------------------------------------------------ 0a 0c 01 09 65 09 d8 0b 28 0c 01 09 65 09 e0 0a 0c 01 09 65 08 c0 0b 28 0c 01 09 65 08 80 0a 0c 01 09 65 07 a8 0b 28 0c 01 09 65 07 a0 0a 0c 01 09 65 06 90 0b 28 0c 01 09 65 06 c0 0a 0c 01 09 65 05 f8 0b 28 0c 01 09 65 05 e0 0a 0c 01 09 65 04 e0 0b 28 0c 01 09 65 04 80 0a 0c 01 09 65 03 c8 0b 28 0c 01 09 65 03 a0 0a 0c 01 09 65 02 b0 0b 28 0c 01 09 65 02 c0 0a 0c 01 09 65 01 98 0b 28 0c 01 09 65 01 e0 0a 0c 01 09 65 00 80 0b 28 0c 01 09 65 00 80 *0x0a << 2 == 0x28. Is that just coincidence? Or are some bits handled improperly?* It would appear that A7 and B7 are 8 bit CSUM values. However, when the following CSUM calculation is done as specified in the documentation: CSUM = lo_ADDR ^ hi_ADDR ^ sub_ADDR ^ DATA_0 ^ DATA_1 ^ DATA_2 ^ DATA_3 0x62 = 0xa ^ 0x0 ^ 0x0c ^ 0x01 ^ 0x09 ^ 0x65 ^ 0x09 0x62 = 0x8 ^ 0x2 ^ 0x0c ^ 0x01 ^ 0x09 ^ 0x65 ^ 0x09 The calculated value doesn't match A7 or B7. However: *"The CSUM byte is then split into 2 bytes, 0xAX (low nibble) and 0xBX (high nibble)"* I've tried https://crccalc.com as well as others, thinking that the calculation in the specification is incorrect, however I can't get any matches on any 8-bit CSUMs that I've tried. I think I'm missing something obvious, as I'm quite an amateur. I'm really trying to understand what's happening, where I've gone wrong, and not just get my problem solved. I'm now two days into trying to figure this out, and I just can't get it. **Quesion two:** Are those fields actually checksums, if they are, how are they calculated? **Question three:** If they're not, what are they? **Question four:** Why would some packets appear to be missing (or have a different) start and stop flag bytes?