From 0056717986175f32398b4826c5c9c86c350998c3 Mon Sep 17 00:00:00 2001
From: "Christian I. Nilsson" <nikize@gmail.com>
Date: Tue, 10 Sep 2024 00:11:21 +0200
Subject: [PATCH] auto_analyse_raw_data Add kXxMsbFirst to easy change MSBFirst
 for the full protocol (#2143)

---
 tools/auto_analyse_raw_data.py      | 11 +++--
 tools/auto_analyse_raw_data_test.py | 77 ++++++++++++++++++-----------
 2 files changed, 54 insertions(+), 34 deletions(-)

diff --git a/tools/auto_analyse_raw_data.py b/tools/auto_analyse_raw_data.py
index 69149215d..0d5ebabc9 100755
--- a/tools/auto_analyse_raw_data.py
+++ b/tools/auto_analyse_raw_data.py
@@ -105,7 +105,7 @@ def add_data_code(self, bin_str, name="", footer=True):
     code.append(f"    // Data Section #{self.section_count}")
     code.append(f"    // e.g. data = 0x{int(bin_str, 2):X}, nbits = {nbits}")
     code.append(f"    sendData(k{name}BitMark, k{name}OneSpace, k{name}BitMark,"
-                f" k{name}ZeroSpace, send_data, {nbits}, true);")
+                f" k{name}ZeroSpace, send_data, {nbits}, k{name}MsbFirst);")
     code.append(f"    send_data >>= {nbits};")
     if footer:
       code.append("    // Footer")
@@ -122,7 +122,8 @@ def add_data_decode_code(self, bin_str, name="", footer=True):
         f"  // e.g. data_result.data = 0x{int(bin_str, 2):X}, nbits = {nbits}",
         f"  data_result = matchData(&(results->rawbuf[offset]), {nbits},",
         f"                          k{name}BitMark, k{name}OneSpace,",
-        f"                          k{name}BitMark, k{name}ZeroSpace);",
+        f"                          k{name}BitMark, k{name}ZeroSpace,",
+        f"                          kUseDefTol, kMarkExcess, k{name}MsbFirst);",
         "  offset += data_result.used;",
         "  if (data_result.success == false) return false;  // Fail",
         f"  data <<= {nbits};  // Make room for the new bits of data.",
@@ -163,7 +164,8 @@ def add_data_byte_code(self, bin_str, name="", ambles=None):
         f"                k{name}BitMark, k{name}ZeroSpace,",
         f"                {lastmark}, {lastspace},",
         f"                data + pos, {int(nbytes)},  // Bytes",
-        f"                k{name}Freq, true, kNoRepeat, kDutyDefault);",
+        f"                k{name}Freq, k{name}MsbFirst, kNoRepeat,"
+        " kDutyDefault);",
         f"    pos += {int(nbytes)};"
         f"  // Adjust by how many bytes of data we sent"])
     return code
@@ -198,7 +200,7 @@ def add_data_byte_decode_code(self, bin_str, name="", ambles=None):
         f"                      {firstmark}, {firstspace},",
         f"                      k{name}BitMark, k{name}OneSpace,",
         f"                      k{name}BitMark, k{name}ZeroSpace,",
-        f"                      {lastmark}, {lastspace}, true);",
+        f"                      {lastmark}, {lastspace}, k{name}MsbFirst);",
         "  if (used == 0) return false;  // We failed to find any data.",
         "  offset += used;  // Adjust for how much of the message we read.",
         f"  pos += {int(nbytes)};"
@@ -351,6 +353,7 @@ def dump_constants(message, defines, name="", output=sys.stdout):
       defines.append(f"const uint16_t k{name}SpaceGap{count} = {gap};")
   defines.append(f"const uint16_t k{name}Freq = 38000;  "
                  "// Hz. (Guessing the most common frequency.)")
+  defines.append(f"const bool k{name}MsbFirst = true; // default assumption")
 
 
 def parse_and_report(rawdata_str, margin, gen_code=False, name="",
diff --git a/tools/auto_analyse_raw_data_test.py b/tools/auto_analyse_raw_data_test.py
index 1b080c5a8..724fbfe2e 100755
--- a/tools/auto_analyse_raw_data_test.py
+++ b/tools/auto_analyse_raw_data_test.py
@@ -76,7 +76,8 @@ def test_dump_constants_simple(self):
         'const uint16_t kBAROneSpace = 1485;',
         'const uint16_t kBARZeroSpace = 520;',
         'const uint16_t kBARFreq = 38000;  // Hz. (Guessing the most common '
-        'frequency.)'
+        'frequency.)',
+        'const bool kBARMsbFirst = true; // default assumption'
     ])
     self.assertEqual(
         output.getvalue(), 'Guessing key value:\n'
@@ -113,7 +114,8 @@ def test_dump_constants_aircon(self):
         'const uint16_t kTESTZeroSpace = 554;',
         'const uint16_t kTESTSpaceGap = 19990;',
         'const uint16_t kTESTFreq = 38000;  // Hz. (Guessing the most common '
-        'frequency.)'
+        'frequency.)',
+        'const bool kTESTMsbFirst = true; // default assumption'
     ])
     self.assertEqual(
         output.getvalue(), 'Guessing key value:\n'
@@ -302,6 +304,7 @@ def test_parse_and_report(self):
         'const uint16_t kFOOZeroSpace = 520;\n'
         'const uint16_t kFOOFreq = 38000;  // Hz. (Guessing the most common'
         ' frequency.)\n'
+        'const bool kFOOMsbFirst = true; // default assumption\n'
         'const uint16_t kFOOBits = 16;  // Move to IRremoteESP8266.h\n'
         'const uint16_t kFOOOverhead = 5;\n'
         '\n'
@@ -323,7 +326,7 @@ def test_parse_and_report(self):
         '    // Data Section #1\n'
         '    // e.g. data = 0xEB, nbits = 8\n'
         '    sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,'
-        ' send_data, 8, true);\n'
+        ' send_data, 8, kFOOMsbFirst);\n'
         '    send_data >>= 8;\n'
         '    // Footer\n'
         '    mark(kFOOBitMark);\n'
@@ -331,7 +334,7 @@ def test_parse_and_report(self):
         '    // Data Section #2\n'
         '    // e.g. data = 0x1, nbits = 8\n'
         '    sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,'
-        ' send_data, 8, true);\n'
+        ' send_data, 8, kFOOMsbFirst);\n'
         '    send_data >>= 8;\n'
         '    // Footer\n'
         '    mark(kFOOBitMark);\n'
@@ -374,7 +377,8 @@ def test_parse_and_report(self):
         '  // e.g. data_result.data = 0xEB, nbits = 8\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 8,\n'
         '                          kFOOBitMark, kFOOOneSpace,\n'
-        '                          kFOOBitMark, kFOOZeroSpace);\n'
+        '                          kFOOBitMark, kFOOZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kFOOMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 8;  // Make room for the new bits of data.\n'
@@ -390,7 +394,8 @@ def test_parse_and_report(self):
         '  // e.g. data_result.data = 0x1, nbits = 8\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 8,\n'
         '                          kFOOBitMark, kFOOOneSpace,\n'
-        '                          kFOOBitMark, kFOOZeroSpace);\n'
+        '                          kFOOBitMark, kFOOZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kFOOMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 8;  // Make room for the new bits of data.\n'
@@ -585,6 +590,7 @@ def test_leader_marks(self):
         'const uint16_t kHitachiSpaceGap = 49290;\n'
         'const uint16_t kHitachiFreq = 38000;  // Hz. (Guessing the most'
         ' common frequency.)\n'
+        'const bool kHitachiMsbFirst = true; // default assumption\n'
         'const uint16_t kHitachiBits = 424;  // Move to IRremoteESP8266.h\n'
         'const uint16_t kHitachiStateLength = 53;  // Move to IRremoteESP8266.h'
         '\n'
@@ -616,7 +622,7 @@ def test_leader_marks(self):
         'FFCA358F7000FF00FF01FEC03F807F11EE00FF00FFFF00FF00FF00FF00,'
         ' nbits = 424\n'
         '    sendData(kHitachiBitMark, kHitachiOneSpace, kHitachiBitMark,'
-        ' kHitachiZeroSpace, send_data, 424, true);\n'
+        ' kHitachiZeroSpace, send_data, 424, kHitachiMsbFirst);\n'
         '    send_data >>= 424;\n'
         '    // Footer\n'
         '    mark(kHitachiBitMark);\n'
@@ -663,7 +669,8 @@ def test_leader_marks(self):
         '                kHitachiBitMark, kHitachiZeroSpace,\n'
         '                kHitachiBitMark, kHitachiSpaceGap,\n'
         '                data + pos, 53,  // Bytes\n'
-        '                kHitachiFreq, true, kNoRepeat, kDutyDefault);\n'
+        '                kHitachiFreq, kHitachiMsbFirst, kNoRepeat,'
+        ' kDutyDefault);\n'
         '    pos += 53;  // Adjust by how many bytes of data we sent\n'
         '  }\n'
         '}\n'
@@ -714,7 +721,9 @@ def test_leader_marks(self):
         ' nbits = 424\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 424,\n'
         '                          kHitachiBitMark, kHitachiOneSpace,\n'
-        '                          kHitachiBitMark, kHitachiZeroSpace);\n'
+        '                          kHitachiBitMark, kHitachiZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess,'
+        ' kHitachiMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 424;  // Make room for the new bits of data.\n'
@@ -772,7 +781,8 @@ def test_leader_marks(self):
         '                      kHitachiHdrMark, kHitachiHdrSpace,\n'
         '                      kHitachiBitMark, kHitachiOneSpace,\n'
         '                      kHitachiBitMark, kHitachiZeroSpace,\n'
-        '                      kHitachiBitMark, kHitachiSpaceGap, true);\n'
+        '                      kHitachiBitMark, kHitachiSpaceGap,'
+        ' kHitachiMsbFirst);\n'
         '  if (used == 0) return false;  // We failed to find any data.\n'
         '  offset += used;  // Adjust for how much of the message we read.\n'
         '  pos += 53;  // Adjust by how many bytes of data we read\n'
@@ -898,6 +908,7 @@ def test_unusual_gaps(self):
         'const uint16_t kFOOSpaceGap = 13996;\n'
         'const uint16_t kFOOFreq = 38000;  // Hz. (Guessing the most common'
         ' frequency.)\n'
+        'const bool kFOOMsbFirst = true; // default assumption\n'
         'const uint16_t kFOOBits = 128;  // Move to IRremoteESP8266.h\n'
         'const uint16_t kFOOStateLength = 16;  // Move to IRremoteESP8266.h\n'
         'const uint16_t kFOOOverhead = 16;\n'
@@ -922,7 +933,7 @@ def test_unusual_gaps(self):
         '    // Data Section #1\n'
         '    // e.g. data = 0x5F5F4040, nbits = 32\n'
         '    sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,'
-        ' send_data, 32, true);\n'
+        ' send_data, 32, kFOOMsbFirst);\n'
         '    send_data >>= 32;\n'
         '    // Header\n'
         '    mark(kFOOHdrMark);\n'
@@ -930,7 +941,7 @@ def test_unusual_gaps(self):
         '    // Data Section #2\n'
         '    // e.g. data = 0x5F5F4040, nbits = 32\n'
         '    sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,'
-        ' send_data, 32, true);\n'
+        ' send_data, 32, kFOOMsbFirst);\n'
         '    send_data >>= 32;\n'
         '    // Header\n'
         '    mark(kFOOHdrMark);\n'
@@ -944,7 +955,7 @@ def test_unusual_gaps(self):
         '    // Data Section #3\n'
         '    // e.g. data = 0x2F2F6C6C, nbits = 32\n'
         '    sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,'
-        ' send_data, 32, true);\n'
+        ' send_data, 32, kFOOMsbFirst);\n'
         '    send_data >>= 32;\n'
         '    // Header\n'
         '    mark(kFOOHdrMark);\n'
@@ -952,7 +963,7 @@ def test_unusual_gaps(self):
         '    // Data Section #4\n'
         '    // e.g. data = 0x2F2F6C6C, nbits = 32\n'
         '    sendData(kFOOBitMark, kFOOOneSpace, kFOOBitMark, kFOOZeroSpace,'
-        ' send_data, 32, true);\n'
+        ' send_data, 32, kFOOMsbFirst);\n'
         '    send_data >>= 32;\n'
         '    // Header\n'
         '    mark(kFOOHdrMark);\n'
@@ -994,7 +1005,7 @@ def test_unusual_gaps(self):
         '                kFOOBitMark, kFOOZeroSpace,\n'
         '                kFOOHdrMark, kFOOHdrSpace,\n'
         '                data + pos, 4,  // Bytes\n'
-        '                kFOOFreq, true, kNoRepeat, kDutyDefault);\n'
+        '                kFOOFreq, kFOOMsbFirst, kNoRepeat, kDutyDefault);\n'
         '    pos += 4;  // Adjust by how many bytes of data we sent\n'
         '    // Data Section #2\n'
         '    // e.g.\n'
@@ -1005,7 +1016,7 @@ def test_unusual_gaps(self):
         '                kFOOBitMark, kFOOZeroSpace,\n'
         '                kFOOHdrMark, kFOOHdrSpace,\n'
         '                data + pos, 4,  // Bytes\n'
-        '                kFOOFreq, true, kNoRepeat, kDutyDefault);\n'
+        '                kFOOFreq, kFOOMsbFirst, kNoRepeat, kDutyDefault);\n'
         '    pos += 4;  // Adjust by how many bytes of data we sent\n'
         '    // Data Section #3\n'
         '    // e.g.\n'
@@ -1016,7 +1027,7 @@ def test_unusual_gaps(self):
         '                kFOOBitMark, kFOOZeroSpace,\n'
         '                kFOOHdrMark, kFOOHdrSpace,\n'
         '                data + pos, 4,  // Bytes\n'
-        '                kFOOFreq, true, kNoRepeat, kDutyDefault);\n'
+        '                kFOOFreq, kFOOMsbFirst, kNoRepeat, kDutyDefault);\n'
         '    pos += 4;  // Adjust by how many bytes of data we sent\n'
         '    // Data Section #4\n'
         '    // e.g.\n'
@@ -1027,7 +1038,7 @@ def test_unusual_gaps(self):
         '                kFOOBitMark, kFOOZeroSpace,\n'
         '                kFOOHdrMark, kFOOHdrSpace,\n'
         '                data + pos, 4,  // Bytes\n'
-        '                kFOOFreq, true, kNoRepeat, kDutyDefault);\n'
+        '                kFOOFreq, kFOOMsbFirst, kNoRepeat, kDutyDefault);\n'
         '    pos += 4;  // Adjust by how many bytes of data we sent\n'
         '  }\n'
         '}\n'
@@ -1068,7 +1079,8 @@ def test_unusual_gaps(self):
         '  // e.g. data_result.data = 0x5F5F4040, nbits = 32\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 32,\n'
         '                          kFOOBitMark, kFOOOneSpace,\n'
-        '                          kFOOBitMark, kFOOZeroSpace);\n'
+        '                          kFOOBitMark, kFOOZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kFOOMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 32;  // Make room for the new bits of data.\n'
@@ -1084,7 +1096,8 @@ def test_unusual_gaps(self):
         '  // e.g. data_result.data = 0x5F5F4040, nbits = 32\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 32,\n'
         '                          kFOOBitMark, kFOOOneSpace,\n'
-        '                          kFOOBitMark, kFOOZeroSpace);\n'
+        '                          kFOOBitMark, kFOOZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kFOOMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 32;  // Make room for the new bits of data.\n'
@@ -1112,7 +1125,8 @@ def test_unusual_gaps(self):
         '  // e.g. data_result.data = 0x2F2F6C6C, nbits = 32\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 32,\n'
         '                          kFOOBitMark, kFOOOneSpace,\n'
-        '                          kFOOBitMark, kFOOZeroSpace);\n'
+        '                          kFOOBitMark, kFOOZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kFOOMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 32;  // Make room for the new bits of data.\n'
@@ -1128,7 +1142,8 @@ def test_unusual_gaps(self):
         '  // e.g. data_result.data = 0x2F2F6C6C, nbits = 32\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 32,\n'
         '                          kFOOBitMark, kFOOOneSpace,\n'
-        '                          kFOOBitMark, kFOOZeroSpace);\n'
+        '                          kFOOBitMark, kFOOZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kFOOMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 32;  // Make room for the new bits of data.\n'
@@ -1189,7 +1204,7 @@ def test_unusual_gaps(self):
         '                      kFOOHdrMark, kFOOHdrSpace,\n'
         '                      kFOOBitMark, kFOOOneSpace,\n'
         '                      kFOOBitMark, kFOOZeroSpace,\n'
-        '                      kFOOHdrMark, kFOOHdrSpace, true);\n'
+        '                      kFOOHdrMark, kFOOHdrSpace, kFOOMsbFirst);\n'
         '  if (used == 0) return false;  // We failed to find any data.\n'
         '  offset += used;  // Adjust for how much of the message we read.\n'
         '  pos += 4;  // Adjust by how many bytes of data we read\n'
@@ -1204,7 +1219,7 @@ def test_unusual_gaps(self):
         '                      kFOOHdrMark, kFOOHdrSpace,\n'
         '                      kFOOBitMark, kFOOOneSpace,\n'
         '                      kFOOBitMark, kFOOZeroSpace,\n'
-        '                      kFOOHdrMark, kFOOHdrSpace, true);\n'
+        '                      kFOOHdrMark, kFOOHdrSpace, kFOOMsbFirst);\n'
         '  if (used == 0) return false;  // We failed to find any data.\n'
         '  offset += used;  // Adjust for how much of the message we read.\n'
         '  pos += 4;  // Adjust by how many bytes of data we read\n'
@@ -1219,7 +1234,7 @@ def test_unusual_gaps(self):
         '                      kFOOHdrMark, kFOOHdrSpace,\n'
         '                      kFOOBitMark, kFOOOneSpace,\n'
         '                      kFOOBitMark, kFOOZeroSpace,\n'
-        '                      kFOOHdrMark, kFOOHdrSpace, true);\n'
+        '                      kFOOHdrMark, kFOOHdrSpace, kFOOMsbFirst);\n'
         '  if (used == 0) return false;  // We failed to find any data.\n'
         '  offset += used;  // Adjust for how much of the message we read.\n'
         '  pos += 4;  // Adjust by how many bytes of data we read\n'
@@ -1234,7 +1249,7 @@ def test_unusual_gaps(self):
         '                      kFOOHdrMark, kFOOHdrSpace,\n'
         '                      kFOOBitMark, kFOOOneSpace,\n'
         '                      kFOOBitMark, kFOOZeroSpace,\n'
-        '                      kFOOHdrMark, kFOOHdrSpace, true);\n'
+        '                      kFOOHdrMark, kFOOHdrSpace, kFOOMsbFirst);\n'
         '  if (used == 0) return false;  // We failed to find any data.\n'
         '  offset += used;  // Adjust for how much of the message we read.\n'
         '  pos += 4;  // Adjust by how many bytes of data we read\n'
@@ -1333,6 +1348,7 @@ def test_no_headers(self):
         'const uint16_t kZeroSpace = 547;\n'
         'const uint16_t kFreq = 38000;  // Hz. (Guessing the most common'
         ' frequency.)\n'
+        'const bool kMsbFirst = true; // default assumption\n'
         'const uint16_t kBits = 128;  // Move to IRremoteESP8266.h\n'
         'const uint16_t kStateLength = 16;  // Move to IRremoteESP8266.h\n'
         'const uint16_t kOverhead = 1;\n'
@@ -1354,7 +1370,7 @@ def test_no_headers(self):
         '    // Data Section #1\n'
         '    // e.g. data = 0xA55A0000400000000000000000000080, nbits = 128\n'
         '    sendData(kBitMark, kOneSpace, kBitMark, kZeroSpace, send_data,'
-        ' 128, true);\n'
+        ' 128, kMsbFirst);\n'
         '    send_data >>= 128;\n'
         '    // Footer\n'
         '    mark(kBitMark);\n'
@@ -1393,7 +1409,7 @@ def test_no_headers(self):
         '                kBitMark, kZeroSpace,\n'
         '                kBitMark, kDefaultMessageGap,\n'
         '                data + pos, 16,  // Bytes\n'
-        '                kFreq, true, kNoRepeat, kDutyDefault);\n'
+        '                kFreq, kMsbFirst, kNoRepeat, kDutyDefault);\n'
         '    pos += 16;  // Adjust by how many bytes of data we sent\n'
         '  }\n'
         '}\n'
@@ -1429,7 +1445,8 @@ def test_no_headers(self):
         ' = 128\n'
         '  data_result = matchData(&(results->rawbuf[offset]), 128,\n'
         '                          kBitMark, kOneSpace,\n'
-        '                          kBitMark, kZeroSpace);\n'
+        '                          kBitMark, kZeroSpace,\n'
+        '                          kUseDefTol, kMarkExcess, kMsbFirst);\n'
         '  offset += data_result.used;\n'
         '  if (data_result.success == false) return false;  // Fail\n'
         '  data <<= 128;  // Make room for the new bits of data.\n'
@@ -1483,7 +1500,7 @@ def test_no_headers(self):
         '                      0, 0,\n'
         '                      kBitMark, kOneSpace,\n'
         '                      kBitMark, kZeroSpace,\n'
-        '                      kBitMark, kDefaultMessageGap, true);\n'
+        '                      kBitMark, kDefaultMessageGap, kMsbFirst);\n'
         '  if (used == 0) return false;  // We failed to find any data.\n'
         '  offset += used;  // Adjust for how much of the message we read.\n'
         '  pos += 16;  // Adjust by how many bytes of data we read\n'