Skip to content

MorseCodeLED_v0.9.5

Latest

Choose a tag to compare

@Chris-70 Chris-70 released this 13 Mar 04:31

Improvement to the FlashProsignWord() method.

  • Rewrite method to use hash values of the strings instead of a series of string comparisons.
  • The case statements are a compile time hash of the string
    Example:
case hashWordConst("START"):

Where hashWordConst() is defined as follows:

   static constexpr uint16_t hashWordConst(const char* text, uint16_t hash = STARTING_PRIME)
      { return *text ? hashWordConst(text + 1, (uint16_t)((hash ^ (uint8_t)(*text)) * MULTIPLIER_PRIME)) : hash; }

The runtime hash calculation does not use recursion, instead it uses a simple loop over the string to calculate the hash. This is done for both speed and RAM (stack) usage. The compile time hash calculation has the resources of the computer running the compiler where as at runtime it's just the MCU doing the calculations.

A compile-time test method was added to validate that the two hash methods always produced the same results and that the hash never produced a collision with the strings used. #define TESTING true and compile for validation. This needs to be done just ONCE after any changes were made to the strings and/or hash functions.

To ensure that the test and FlashProsignWord() methods are always in sync, macros are defined to produce the necessary case statements for each method.
Example:

#define FLASH_PROSIGN_CASE(keywordToken, prosignToken) \
   case hashWordConst(#keywordToken):                  \
      FlashProsign(Prosign::prosignToken);             \
      break;

Then the case macro is used as an input to the main macro that maps the keyword string to the prosign value.
Example:

   #define FLASH_PROSIGN_KEYWORD_MAP(X) \
      X(START, Start)                   \
      X(END, End)                       \
      X(OUT, Out)                       \
      // Repeats for each keyword-prosign pair.

This ensures that there is only one keyword-prosign mapping source and method specific macros will generate the correct case statements.

Changes to the keyword - prosign mapping are done in one location and a compile-time test can be run once to validate the correctness, catching errors at compile-time.