Add extract_bytes_uart_parity utility function
This commit is contained in:
parent
a8d35e3820
commit
4736276bd4
3 changed files with 66 additions and 44 deletions
|
@ -52,7 +52,7 @@ void reflect_nibbles(uint8_t message[], unsigned num_bytes);
|
||||||
/// @param num_bits message length in bits
|
/// @param num_bits message length in bits
|
||||||
/// @param dst target buffer for extracted nibbles, at least num_bits/5 size
|
/// @param dst target buffer for extracted nibbles, at least num_bits/5 size
|
||||||
/// @return number of successfully unstuffed nibbles.
|
/// @return number of successfully unstuffed nibbles.
|
||||||
unsigned extract_nibbles_4b1s(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst);
|
unsigned extract_nibbles_4b1s(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst);
|
||||||
|
|
||||||
/// UART "8n1" (10-to-8) decoder with 1 start bit (0), no parity, 1 stop bit (1), LSB-first bit-order.
|
/// UART "8n1" (10-to-8) decoder with 1 start bit (0), no parity, 1 stop bit (1), LSB-first bit-order.
|
||||||
///
|
///
|
||||||
|
@ -61,7 +61,16 @@ unsigned extract_nibbles_4b1s(uint8_t *message, unsigned offset_bits, unsigned n
|
||||||
/// @param num_bits message length in bits
|
/// @param num_bits message length in bits
|
||||||
/// @param dst target buffer for extracted bytes, at least num_bits/10 size
|
/// @param dst target buffer for extracted bytes, at least num_bits/10 size
|
||||||
/// @return number of successful decoded bytes
|
/// @return number of successful decoded bytes
|
||||||
unsigned extract_bytes_uart(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst);
|
unsigned extract_bytes_uart(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst);
|
||||||
|
|
||||||
|
/// UART "8o1" (11-to-8) decoder with 1 start bit (1), odd parity, 1 stop bit (0), MSB-first bit-order.
|
||||||
|
///
|
||||||
|
/// @param message bytes of message data
|
||||||
|
/// @param offset_bits start offset of message in bits
|
||||||
|
/// @param num_bits message length in bits
|
||||||
|
/// @param dst target buffer for extracted bytes, at least num_bits/11 size
|
||||||
|
/// @return number of successful decoded bytes
|
||||||
|
unsigned extract_bytes_uart_parity(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst);
|
||||||
|
|
||||||
/// Decode symbols to bits.
|
/// Decode symbols to bits.
|
||||||
///
|
///
|
||||||
|
@ -73,7 +82,7 @@ unsigned extract_bytes_uart(uint8_t *message, unsigned offset_bits, unsigned num
|
||||||
/// @param sync symbol for sync bit, ignored at start, terminates at end
|
/// @param sync symbol for sync bit, ignored at start, terminates at end
|
||||||
/// @param dst target buffer for extracted bits, at least num_bits/symbol_x_len size
|
/// @param dst target buffer for extracted bits, at least num_bits/symbol_x_len size
|
||||||
/// @return number of successful decoded bits
|
/// @return number of successful decoded bits
|
||||||
unsigned extract_bits_symbols(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint32_t zero, uint32_t one, uint32_t sync, uint8_t *dst);
|
unsigned extract_bits_symbols(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint32_t zero, uint32_t one, uint32_t sync, uint8_t *dst);
|
||||||
|
|
||||||
/// CRC-4.
|
/// CRC-4.
|
||||||
///
|
///
|
||||||
|
|
|
@ -26,7 +26,7 @@ uint8_t reverse8(uint8_t x)
|
||||||
uint32_t reverse32(uint32_t x)
|
uint32_t reverse32(uint32_t x)
|
||||||
{
|
{
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
uint8_t* xp = (uint8_t*)&x;
|
uint8_t const* xp = (uint8_t*)&x;
|
||||||
ret = (uint32_t) reverse8(xp[0]) << 24 | reverse8(xp[1]) << 16 | reverse8(xp[2]) << 8 | reverse8(xp[3]);
|
ret = (uint32_t) reverse8(xp[0]) << 24 | reverse8(xp[1]) << 16 | reverse8(xp[2]) << 8 | reverse8(xp[3]);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ void reflect_nibbles(uint8_t message[], unsigned num_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned extract_nibbles_4b1s(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst)
|
unsigned extract_nibbles_4b1s(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst)
|
||||||
{
|
{
|
||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ unsigned extract_nibbles_4b1s(uint8_t *message, unsigned offset_bits, unsigned n
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned extract_bytes_uart(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst)
|
unsigned extract_bytes_uart(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst)
|
||||||
{
|
{
|
||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
|
|
||||||
|
@ -97,7 +97,39 @@ unsigned extract_bytes_uart(uint8_t *message, unsigned offset_bits, unsigned num
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned symbol_match(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint32_t symbol)
|
unsigned extract_bytes_uart_parity(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint8_t *dst)
|
||||||
|
{
|
||||||
|
unsigned ret = 0;
|
||||||
|
|
||||||
|
while (num_bits >= 11) {
|
||||||
|
int startb = message[offset_bits / 8] >> (7 - (offset_bits % 8));
|
||||||
|
offset_bits += 1;
|
||||||
|
int datab = message[offset_bits / 8];
|
||||||
|
if (offset_bits % 8) {
|
||||||
|
datab = (message[offset_bits / 8] << 8) | message[offset_bits / 8 + 1];
|
||||||
|
datab >>= 8 - (offset_bits % 8);
|
||||||
|
}
|
||||||
|
offset_bits += 8;
|
||||||
|
int parityb = message[offset_bits / 8] >> (7 - (offset_bits % 8));
|
||||||
|
offset_bits += 1;
|
||||||
|
int stopb = message[offset_bits / 8] >> (7 - (offset_bits % 8));
|
||||||
|
offset_bits += 1;
|
||||||
|
int data_parity = parity8(datab);
|
||||||
|
if ((startb & 1) != 1)
|
||||||
|
break; // start-bit error
|
||||||
|
if ((parityb & 1) != data_parity)
|
||||||
|
break; // parity-bit error
|
||||||
|
if ((stopb & 1) != 0)
|
||||||
|
break; // stop-bit error
|
||||||
|
*dst++ = (datab & 0xff);
|
||||||
|
ret += 1;
|
||||||
|
num_bits -= 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned symbol_match(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint32_t symbol)
|
||||||
{
|
{
|
||||||
unsigned symbol_len = symbol & 0x1f;
|
unsigned symbol_len = symbol & 0x1f;
|
||||||
|
|
||||||
|
@ -119,7 +151,7 @@ static unsigned symbol_match(uint8_t *message, unsigned offset_bits, unsigned nu
|
||||||
return symbol_len;
|
return symbol_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned extract_bits_symbols(uint8_t *message, unsigned offset_bits, unsigned num_bits, uint32_t zero, uint32_t one, uint32_t sync, uint8_t *dst)
|
unsigned extract_bits_symbols(uint8_t const *message, unsigned offset_bits, unsigned num_bits, uint32_t zero, uint32_t one, uint32_t sync, uint8_t *dst)
|
||||||
{
|
{
|
||||||
unsigned zero_len = zero & 0x1f;
|
unsigned zero_len = zero & 0x1f;
|
||||||
unsigned one_len = one & 0x1f;
|
unsigned one_len = one & 0x1f;
|
||||||
|
|
|
@ -18,6 +18,10 @@ Supported Models:
|
||||||
Sundance DCU-6560-131, SD-880 Series, PN 6560-131
|
Sundance DCU-6560-131, SD-880 Series, PN 6560-131
|
||||||
Jacuzzi DCU-2560-131, Jac-J300/J400 and SD-780 series, PN 6560-132/2560-131
|
Jacuzzi DCU-2560-131, Jac-J300/J400 and SD-780 series, PN 6560-132/2560-131
|
||||||
|
|
||||||
|
Data coding:
|
||||||
|
|
||||||
|
UART 8o1: 11 bits/byte: 1 start bit (1), odd parity, 1 stop bit (0).
|
||||||
|
|
||||||
Data layout:
|
Data layout:
|
||||||
|
|
||||||
SS IIII TT CC
|
SS IIII TT CC
|
||||||
|
@ -28,29 +32,8 @@ Data layout:
|
||||||
- C: 8 bit Checksum: Count 1s for each bit of each element:
|
- C: 8 bit Checksum: Count 1s for each bit of each element:
|
||||||
Set bit to 1 if number is even 0 if odd
|
Set bit to 1 if number is even 0 if odd
|
||||||
|
|
||||||
11 bits/byte: 1 start bit, 0 stop bits and odd parity
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uint8_t calculateChecksum(const uint8_t *data, size_t size)
|
|
||||||
{
|
|
||||||
uint8_t checksum = 0;
|
|
||||||
|
|
||||||
for (int bit = 0; bit < 8; bit++) {
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
count += (data[i] >> bit) & 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count % 2 == 0) {
|
|
||||||
checksum |= (1 << bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rosstech_dcu706_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
static int rosstech_dcu706_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||||
{
|
{
|
||||||
uint8_t const preamble_data_transmission[] = {0xDD, 0x40};
|
uint8_t const preamble_data_transmission[] = {0xDD, 0x40};
|
||||||
|
@ -85,23 +68,21 @@ static int rosstech_dcu706_decode(r_device *decoder, bitbuffer_t *bitbuffer)
|
||||||
|
|
||||||
bitbuffer_extract_bytes(bitbuffer, 0, start_pos, msg, sizeof(msg) * 8);
|
bitbuffer_extract_bytes(bitbuffer, 0, start_pos, msg, sizeof(msg) * 8);
|
||||||
|
|
||||||
uint8_t msg_type = (msg[0] << 1) | (msg[1] >> 7); // S
|
uint8_t b[5] = {0};
|
||||||
uint8_t id_high = (msg[1] << 4) | (msg[2] >> 4);
|
unsigned r = extract_bytes_uart_parity(msg, 0, 55, b);
|
||||||
uint8_t id_low = (msg[2] << 7) | (msg[3] >> 1);
|
if (r != 5) {
|
||||||
uint16_t id = (id_high << 8) | id_low; // I
|
decoder_logf(decoder, 2, __func__, "UART decoding failed. Got %d of 5 bytes", r);
|
||||||
uint8_t temp_f = (msg[4] << 2) | (msg[5] >> 6); // T
|
return DECODE_ABORT_LENGTH;
|
||||||
uint8_t checksum = (msg[5] << 5) | (msg[6] >> 3); // C
|
}
|
||||||
|
|
||||||
// Create a uint8_t array to hold the extracted values
|
int msg_type = b[0]; // S
|
||||||
uint8_t extracted_data[4];
|
int id = (b[1] << 8) | (b[2]); // I
|
||||||
extracted_data[0] = msg_type;
|
int temp_f = b[3]; // T
|
||||||
extracted_data[1] = id_high;
|
int checksum = b[4]; // C
|
||||||
extracted_data[2] = id_low;
|
|
||||||
extracted_data[3] = temp_f;
|
|
||||||
|
|
||||||
uint8_t calculated_checksum = calculateChecksum(extracted_data, sizeof(extracted_data) / sizeof(extracted_data[0]));
|
uint8_t calculated = 0xff ^ xor_bytes(b, 4);
|
||||||
if (calculated_checksum != checksum) {
|
if (calculated != checksum) {
|
||||||
decoder_logf(decoder, 2, __func__, "Checksum failed. Expected: %02x, Calculated: %02x.", checksum, calculated_checksum);
|
decoder_logf(decoder, 2, __func__, "Checksum failed. Expected: %02x, Calculated: %02x", checksum, calculated);
|
||||||
return DECODE_FAIL_MIC;
|
return DECODE_FAIL_MIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue