Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for universal fan controller #3142

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

marcelrv
Copy link

Adding support for universal (reversable) fan controller 24V incl the non standard CRC

@zuckschwerdt
Copy link
Collaborator

Thanks. Btw, the "CRC" is not CRC but actually a nibble sum without carry (xor), right?

@marcelrv
Copy link
Author

Thanks. Btw, the "CRC" is not CRC but actually a nibble sum without carry (xor), right?

:-) i directly believe you.... The formula works I know.. sum of each 4 bits xor'ed

It is not documented anywhere, I figured it out from looking to the occurring value...
As the rotating counter is only 3 bits I tested out all possible values

If it is not a true crc...Should I rename it to checksum?

@zuckschwerdt
Copy link
Collaborator

Preferably rename crc to chk.
The formular crc ^= (b[j / 8] >> (4 * (1 - (j % 8) / 4))) & 0x0F; seems strange, e.g. the first 8 counts b[0] will be shifted, the first 4 times by 4 then 4 times by 0, right? That's a no-op with xor as each two xor's cancel out?

@marcelrv
Copy link
Author

Preferably rename crc to chk. The formular crc ^= (b[j / 8] >> (4 * (1 - (j % 8) / 4))) & 0x0F; seems strange, e.g. the first 8 counts b[0] will be shifted, the first 4 times by 4 then 4 times by 0, right? That's a no-op with xor as each two xor's cancel out?

no, not really, the idea is that you xor eacht time 4 bits.
As the array is in bytes, b[j / 8] makes that we 2x select byte 0, 2x byte 1 , etc. The (4 * (1 - (j % 8) / 4))) piece makes we either shift by 4 or we don't shift.. the final & 0F makes we always only take the 4 bits. for the xor' ing

@zuckschwerdt
Copy link
Collaborator

Yes! I Missed the j += 4 :)
We usually write this with a byte-wise stepping and fold the nibbles, e.g chk ^= (b[j] >> 4) ^ (b[j] & 0xf), the last incomplete byte then needs a last chk ^= (b[3] >> 4).
There is a utility function for this, e.g. int sum = add_nibbles(b, 3) + (b[3] >> 4);

@zuckschwerdt
Copy link
Collaborator

You need to run ./maintainer_update.py to get the build system changes. Commit those changes too.

@marcelrv
Copy link
Author

int sum = add_nibbles(b, 3) + (b[3] >> 4); did not work well, as it does not apply the xor.
I added a new function to do that, indeed in a more readable way based on the add_nibbles.

@zuckschwerdt
Copy link
Collaborator

int sum = add_nibbles(b, 3) + (b[3] >> 4); did not work well, as it does not apply the xor.

Oops. Confused myself there. I should have given a different example. Also sum == chk for xor is the same as full xor and then sum == 0 ;)

int sum = xor_bytes(b, 4); // xor message bytes, last byte also has the checksum
sum = (sum >> 4) ^ (sum & 0xf); // fold nibbles
if (sum != 0xa) …

The xor_nibbles is a nice addition. Remove the init, sum full bytes then fold after the loop. Again sorry for the add-with-carry mixup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants