These functions are related to the up-to 49 buttons on the KontroLIR remote control. In general only the last function below needs to be changed and only if you are changing the number of devices or modes supported from the default of 5. It is OK to leave as is even if you are using less than 5 devices.
This function is called during setup, to initialise the GPIOs for all of the row/col matrix pins. Each row/col combination represents one button on the remote. There are 7 rows and 7 columns for a total of up-to 49 buttons on the KontroLIR remote control. COLs are set to INPUT_PULLUP which presents a HIGH on these pins. Rows are set to OUTPUT/LOW such that when a button is pressed a PCINT interrupt is generated on a col pin which wakes the MCU from sleep to allow processing of the functionality programmed for that button press. (Note: After a button is pressed the pinMode of the rows is temporarily changed to figure out which particular button has been pressed.)
If any button is pressed the row will pull the associated col down to LOW, which in turn triggers a PCINT to wake the system up from sleep In most cases this will be a unique row/col pairing. However, it is possible to press multiple buttons at the same time, in which case the first scanned will be the button deemed to have been pressed
When the MCU wakes from sleep this function is called to determine if a button has been pressed. The logic as written sets the first button detected as the only button that has been pressed and ignores other buttons when multiple buttons have been pressed together. (Users could extend the logic to support multiple simultaneous button presses if desired).
The first part of this function determines which button has been pressed by setting all ROW pins to INPUT and then setting each row in-turn to LOW to determine which row/col combination (i.e. button) has been pressed. Once detected all of the ROWS are reset to OUTPUT/LOW for the next button press.
If no button press is detected then it is ignored. (Theoretically this could occur if a brief press occurred, of the order of uSecs or less. Under normal circumstances this should not occur.)
Finaly, the scanCode is calculated based on the Row, Col and Device Mode. Once the scanCode is set the function exits.
In the main loop, if a button press is detected, the indicator LED is turned ON and this function is called to process the button press. Once this function is completed the LED is turned OFF.
This is where the main logic of your device is configured.
Inside this function we define a flash based array of function pointers, pointing to the function to be called for each button press in each of the configured modes. So for the default 5 modes we have 5*49 pointer entries. This array is laid out in blocks separated by comments for easy editing. There is one block for each configured device mode (49 entries each). The block for mode1 uses FN1, mode 2 uses FN2 etc. If you want to add a 6th block then add in an extra block using FN6 etc. Also, make sure to define FN6 etc. for any additional blocks. (You will also need to add an additional mode file for any extra mode)
IMPORTANT: It is imperative that if you make any changes here that no mistakes are made. The big risk is that a function pointer is called beyond the end of the function pointer array, which results in random code being called - possibly resulting in Flash corruption. If this happens you may need to burn the bootloader again. We highlight this because it happened to us and left us scratching our heads for a very long time trying to figure out why the flash was being corrupted randomly and infrequently. Accordingly, we have added in several checks to ensure the scanCode & the function being called are not invalid.
We also take care of repeating signals here. If a particular button is defined with a rptCount, then the signal will be repeated up to that number of times, as long the button is kept pressed. If the button is kept pressed too long, the device will just go to sleep after all configured repeats are sent. This serves to preserve the battery, if say, the remote is caught down the side of a couch with the button pressed.
Finally, we reset the bootFlag as required. (if we are not in MODE1 or a button other than 1, 3, 7, 9 is pressed.). This ensures that if the boot loader button sequence is out of order, it will be reset to start again at the next press of button 1 in MODE1.