#ifndef KEYCONTROL_ENCODING_H
#define KEYCONTROL_ENCODING_H
    #include <stdint.h>  // uint32_t
    // -----------------------------------------------------------------------------
    // KeySwitch LowLevel Control Word Encoding in 32-bit unsigned integer
    // -----------------------------------------------------------------------------
    // There two modes supported - parallel control and serial control.
    // Only one mode can be selected in single template.
    //
    #define CONTROL_TYPE_REGISTER_1                           (1UL<<31)
    #define CONTROL_TYPE_REGISTER_2                           (1UL<<30)
    #define CONTROL_TYPE_REGISTER_1_2                         (3UL<<30)
    #define CONTROL_TYPE_PARALLEL                             (0UL<<30)
    // -----------------------------------------------------------------------------
    // Check if the control code uses parallel control
    //
    #define CHECK_CONTROL_TYPE_PARALLEL( u32code )            (! ((u32code) & CONTROL_TYPE_REGISTER_1_2 ))

    // Check if the control code uses serial control
    //
    #define CHECK_CONTROL_TYPE_REGISTER( u32code )            (  ((u32code) & CONTROL_TYPE_REGISTER_1_2 ))
    // -----------------------------------------------------------------------------
    #define CHECK_CONTROL_REGISTER_1( u32code )               (  ((u32code) & CONTROL_TYPE_REGISTER_1 ))
    #define CHECK_CONTROL_REGISTER_2( u32code )               (  ((u32code) & CONTROL_TYPE_REGISTER_2 ))
    // -----------------------------------------------------------------------------
    // Extract the Register 1 control code
    //
    #define GET_CONTROL_REGISTER_1( u32code )                 (  ((u32code) & 0x00FF ) >> 0 )

    // Extract the Register 2 control code
    //
    #define GET_CONTROL_REGISTER_2( u32code )                 (  ((u32code) & 0xFF00 ) >> 8 )

    // Extract the ENABLE contol pin state
    //
    #define GET_CONTROL_ENABLEPIN(  u32code )                 (  ((u32code) & 0x10000 ))

    // Packing the control word into the 32-bit unsigned integer
    //
    #define MAKE_KEYSTATE_CONTROL( TYPE, A_8bit, B_8bit, C_8bit, D_6bit )   ((uint32_t)( \
                                                                ((A_8bit) & 0x000000FF) <<  0\
                                                               |\
                                                                ((B_8bit) & 0x000000FF) <<  8\
                                                               |\
                                                                ((C_8bit) & 0x000000FF) << 16\
                                                               |\
                                                                ((D_6bit) & 0x0000007F) << 24\
                                                               |\
                                                                ((TYPE) & 0x80000000) \
                                                              ))

    // Create KeySwitch control template using serial control (Register 1)
    //
    #define MAKE_KEYSTATE_REGISTER_1( REG1, EN )                 \
                                         MAKE_KEYSTATE_CONTROL( CONTROL_TYPE_REGISTER_1, \
                                                                 ((REG1)&0xFF),\
                                                                 0x00,\
                                                                 ((EN)&0x1),\
                                                                 0x00 )

    // Create KeySwitch control template using serial control (Register 2)
    //
    #define MAKE_KEYSTATE_REGISTER_2( REG2, EN )                 \
                                         MAKE_KEYSTATE_CONTROL( CONTROL_TYPE_REGISTER_2, \
                                                                 0x00,\
                                                                 ((REG2)&0xFF),\
                                                                 ((EN)&0x1),\
                                                                 0x00 )

    // Create KeySwitch control template using serial control (Registers 1 and 2)
    //
    #define MAKE_KEYSTATE_REGISTER_1_2( REG1, REG2, EN )               \
                                         MAKE_KEYSTATE_CONTROL( CONTROL_TYPE_REGISTER_1_2, \
                                                                 ((REG1)&0xFF),\
                                                                 ((REG2)&0xFF),\
                                                                 ((EN)&0x1),\
                                                                 0x00 )

    // Create KeySwitch control template using parallel control
    //
    #define MAKE_KEYSTATE_PARALLEL( REG1, REG2, REG3, REG4 )  \
                                         MAKE_KEYSTATE_CONTROL( CONTROL_TYPE_PARALLEL, \
                                                                 ((REG1)&0xFF),\
                                                                 ((REG2)&0xFF),\
                                                                 ((REG3)&0xFF),\
                                                                 ((REG4)&0x3F) )
#endif