[
  {
    "path": ".github/issue_template.md",
    "content": "---\nname: 🐛 Bug Report\nabout: Only if something isn't working as expected 🤔, otherwise please open a discussion.\nassignees: ArminJo\n---\n\nIf you have handling problems or questions, consider to open a discussion https://github.com/IRMP-org/IRMP/discussions instead of an issue.\n\n## Bug Report\n\n### Board\n* [ ] Arduino ATmega328* board (UNO, Nano)\n* [ ] Arduino ATmega2560 board (Mega)\n* [ ] Arduino ATmega32U4 board (Leonardo)\n* [ ] Arduino megaAVR board (NanoEvery)\n* [ ] Arduino SAM board (Due)\n* [ ] Arduino SAMD board (Zero, MKR*)\n* [ ] ATtiny85 board (ATTinyCore by Spence Conde)\n* [ ] Digispark board\n* [ ] ATtiny3217 board (TinyCore)\n* [ ] ATmega8 board\n* [ ] ESP8266 board\n* [ ] ESP32 board\n* [ ] STM32 board with \"STM32 Boards (selected from submenu)\" core\n* [ ] STM32 board with \"STM32F1 Boards (STM32duino.com)\" core\n* [ ] Apollo3 board\n* [ ] Teensy board\n* [ ] Other - please specify\n\n<!-- Please specify board name if not included in board selection -->\n\n### IDE\n* [ ] Arduino IDE\n* [ ] Arduino Web Editor\n* [ ] Arduino Pro IDE\n* [ ] Sloeber IDE\n* [ ] PlatformIO IDE\n* [ ] Other - please specify\n\n### IR-Protocol\n* [ ] Unknown\n* [ ] Sony\n* [ ] NEC\n* [ ] Samsung\n* [ ] RC5, RC6\n* [ ] Kaseikyo\n* [ ] Denon\n* [ ] JVC\n* [ ] Lego\n* [ ] Matsushita\n* [ ] Mitsubishi\n* [ ] Panasonic\n* [ ] Sanyo\n* [ ] Sharp\n* [ ] Telefunken\n* [ ] Other - please specify\n\n### Example to reproduce the issue\n* [ ] AllProtocols\n* [ ] Callback\n* [ ] Interrupt\n* [ ] OneProtocol\n* [ ] ReceiveAndSend\n* [ ] ReceiveAndSendDynamicPins\n* [ ] RFProtocols\n* [ ] SimpleReceiver\n* [ ] SimpleSender\n* [ ] Other\n\n### Version\n* [ ] Yes I use the [latest repo version](https://github.com/Arduino-IRremote/Arduino-IRremote/archive/master.zip) and verified this!\n* [ ] Other - please specify\n\nPlease delete all unchecked lines above :-)\n\n### Pin(s) used for IR-receive, if not default\n\n### Current behavior\n<!-- Paste the code or repository link, if applicable. -->\n\n<!-- Add a the serial output which indicates the error happened. -->\n\n<!-- Add a clear and concise description of the behavior. -->\n\n### Expected behavior\n<!-- Add a clear and concise description of what you expected to happen. -->\n\n### Additional context\n<!-- (Optional) Add any other context about the problem here. -->\n\n**checklist:**\n- [] I have **read** the README.md file thoroughly.\n- [] I have searched existing issues to see if there is anything I have missed.\n- [] I have browsed the examples for one, that matches my use case.\n- [] Any code referenced is provided and if over 30 lines a gist is linked INSTEAD of it being pasted in here.\n- [] The title of the issue is helpful and relevant.\n- [] I checked, if at least one of the examples was working.\n\n** We will start to close or delete issues that do not follow these guidelines as it doesn't help the contributors who spend time trying to solve issues if the community ignores guidelines!**\n"
  },
  {
    "path": ".github/workflows/LibraryBuild.yml",
    "content": "# LibraryBuild.yml\n# Github workflow script to test compile all examples of an Arduino library repository.\n#\n# Copyright (C) 2020  Armin Joachimsmeyer\n# https://github.com/ArminJo/Github-Actions\n#\n\n# This is the name of the workflow, visible on GitHub UI.\nname: LibraryBuild\non:\n  workflow_dispatch: # To run it manually\n    description: 'manual build check'\n  push: # see: https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request\n    paths:\n    - '**.ino'\n    - '**.cpp'\n    - '**.hpp'\n    - '**.h'\n    - '**LibraryBuild.yml'\n  pull_request:\n    paths:\n    - '**.ino'\n    - '**.cpp'\n    - '**.h'\n    - '**.hpp'\n    - '**LibraryBuild.yml'\n\njobs:\n  build:\n    name: ${{ matrix.arduino-boards-fqbn }} - test compiling examples\n\n    runs-on: ubuntu-latest # I picked Ubuntu to use shell scripts.\n\n    strategy:\n      matrix:\n        # The matrix will produce one job for each configuration parameter of type `arduino-boards-fqbn`\n        # In the Arduino IDE, the fqbn is printed in the first line of the verbose output for compilation as parameter -fqbn=... for the \"arduino-builder -dump-prefs\" command\n        #\n        # Examples: arduino:avr:uno, arduino:avr:leonardo, arduino:avr:nano, arduino:avr:mega\n        # arduino:sam:arduino_due_x, arduino:samd:arduino_zero_native\"\n        # ATTinyCore:avr:attinyx5:chip=85,clock=1internal, digistump:avr:digispark-tiny, digistump:avr:digispark-pro\n        # STMicroelectronics:stm32:GenF1:pnum=BLUEPILL_F103C8\n        # esp8266:esp8266:huzzah:eesz=4M3M,xtal=80, esp32:esp32:featheresp32:FlashFreq=80\n        # You may add a suffix behind the fqbn with \"|\" to specify one board for e.g. different compile options like arduino:avr:uno|trace\n        #############################################################################################################\n        arduino-boards-fqbn:\n          - arduino:avr:uno\n          - arduino:avr:leonardo\n          - arduino:avr:mega\n          - arduino:megaavr:nona4809:mode=off\n          - arduino:samd:arduino_zero_native\n          - arduino:mbed:nano33ble\n          - arduino:mbed_rp2040:pico\n          - rp2040:rp2040:arduino_nano_connect\n#          - digistump:avr:digispark-tiny:clock=clock16\n#          - ATTinyCore:avr:attinyx5micr:LTO=enable,sketchclock=8pll\n#          - ATTinyCore:avr:attinyx7micr:LTO=enable,sketchclock=16external,pinmapping=new,millis=enabled\n#          - ATTinyCore:avr:attinyx8micr:LTO=enable,sketchclock=16external,pinmapping=mhtiny,millis=enabled  # ATtiny88 China clone board @16 MHz\n#          - megaTinyCore:megaavr:atxy6:chip=1616,clock=16internal\n#          - megaTinyCore:megaavr:atxy7:chip=3217,clock=16internal\n          - MiniCore:avr:8:bootloader=uart0,eeprom=keep,BOD=2v7,LTO=Os_flto,clock=16MHz_external # ATmega8\n          - MegaCore:avr:128:bootloader=no_bootloader,eeprom=keep,BOD=2v7,LTO=Os,clock=8MHz_internal # ATmega128\n          - esp8266:esp8266:d1_mini:eesz=4M3M,xtal=80\n          - esp32:esp32:featheresp32:FlashFreq=80\n          - STMicroelectronics:stm32:GenF1:pnum=BLUEPILL_F103C8\n          - STMicroelectronics:stm32:GenL0:pnum=THUNDERPACK_L072\n          - stm32duino:STM32F1:genericSTM32F103C\n#          - SparkFun:apollo3:sfe_artemis_nano\n\n        # Specify parameters for each board.\n        # With sketches-exclude you may exclude specific examples for a board. Use a comma separated list.\n        #############################################################################################################\n        include:\n          - arduino-boards-fqbn: arduino:avr:uno\n            required-libraries: LiquidCrystal I2C\n            build-properties: # the flags were put in compiler.cpp.extra_flags\n              AllProtocols: -DUSE_SERIAL_LCD\n\n          - arduino-boards-fqbn: arduino:avr:leonardo\n            build-properties: # the flags were put in compiler.cpp.extra_flags\n              AllProtocols: -DUSE_NO_LCD\n\n          - arduino-boards-fqbn: arduino:megaavr:nona4809:mode=off\n            sketches-exclude: TinyReceiver,IRDispatcherDemo\n            build-properties: # the flags were put in compiler.cpp.extra_flags\n              All: -DNO_LED_FEEDBACK_CODE\n\n#          - arduino-boards-fqbn: digistump:avr:digispark-tiny:clock=clock16\n#            platform-url: https://raw.githubusercontent.com/ArminJo/DigistumpArduino/master/package_digistump_index.json\n#            required-libraries: ATtinySerialOut\n#            sketches-exclude: AllProtocols,SendAllProtocols,ReceiveAndSendDynamicPins,ReceiverTimingAnalysis # Does not fit in FLASH # Comma separated list of example names to exclude in build\n\n#\n# ATTinyCore\n#\n          - arduino-boards-fqbn: ATTinyCore:avr:attinyx5micr:LTO=enable,sketchclock=8pll\n            platform-url: https://felias-fogg.github.io/downloads/package_debug_enabled_index.json\n            required-libraries: ATtinySerialOut\n            sketches-exclude: AllProtocols,SendAllProtocols,ReceiveAndSendDynamicPins # Does not fit in FLASH\n\n          - arduino-boards-fqbn: ATTinyCore:avr:attinyx8micr:LTO=enable,sketchclock=16external,pinmapping=mhtiny,millis=enabled\n            platform-url: https://felias-fogg.github.io/downloads/package_debug_enabled_index.json\n            required-libraries: ATtinySerialOut\n            sketches-exclude: AllProtocols,SendAllProtocols,ReceiveAndSendDynamicPins # Does not fit in FLASH\n\n          - arduino-boards-fqbn: ATTinyCore:avr:attinyx7micr:LTO=enable,sketchclock=16external,pinmapping=new,millis=enabled\n            platform-url: https://felias-fogg.github.io/downloads/package_debug_enabled_index.json\n            required-libraries: ATtinySerialOut\n            sketches-exclude: AllProtocols,ReceiveAndSendDynamicPins # No Serial.available() function in ATtinySerialOut\n\n#\n# megaTinyCore\n#\n#          - arduino-boards-fqbn: megaTinyCore:megaavr:atxy6:chip=1616,clock=16internal\n#            arduino-platform: megaTinyCore:megaavr\n#            platform-url: https://felias-fogg.github.io/downloads/package_debug_enabled_index.json\n#            sketches-exclude: TinySender,TinyReceiver # PIN_PA6' was not declared etc.\n\n#          - arduino-boards-fqbn: megaTinyCore:megaavr:atxy7:chip=3217,clock=16internal\n#            arduino-platform: megaTinyCore:megaavr\n#            platform-url: https://felias-fogg.github.io/downloads/package_debug_enabled_index.json\n#            sketches-exclude: TinySender,TinyReceiver # PIN_PA6' was not declared etc.\n\n\n          - arduino-boards-fqbn: arduino:mbed_rp2040:pico\n\n          - arduino-boards-fqbn: rp2040:rp2040:arduino_nano_connect\n            platform-url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json\n\n          - arduino-boards-fqbn: MiniCore:avr:8:bootloader=uart0,eeprom=keep,BOD=2v7,LTO=Os_flto,clock=16MHz_external\n            platform-url: https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json\n            arduino-platform: MiniCore:avr,arduino:avr # gcc is taken from arduino:avr\n            sketches-exclude: AllProtocols,ReceiveAndSendDynamicPins,SendAllProtocols,TinyReceiver,IRDispatcherDemo,Interrupt  # Does not fit in FLASH\n\n          - arduino-boards-fqbn: MegaCore:avr:128:bootloader=no_bootloader,eeprom=keep,BOD=2v7,LTO=Os,clock=8MHz_internal\n            platform-url: https://mcudude.github.io/MegaCore/package_MCUdude_MegaCore_index.json\n            arduino-platform: MegaCore:avr,arduino:avr # gcc is taken from arduino:avr\n            sketches-exclude: AllProtocols,ReceiveAndSendDynamicPins # Does not fit in FLASH\n#\n# ESP\n#\n          - arduino-boards-fqbn: esp8266:esp8266:d1_mini:eesz=4M3M,xtal=80\n            platform-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json\n            sketches-exclude: TinyReceiver,AllProtocols # error \".text1' will not fit in region `iram1_0_seg'\"\n\n          - arduino-boards-fqbn: esp32:esp32:featheresp32:FlashFreq=80\n            platform-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json\n            sketches-exclude: TinyReceiver\n\n          - arduino-boards-fqbn: STMicroelectronics:stm32:GenF1:pnum=BLUEPILL_F103C8\n            platform-url: https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json\n            sketches-exclude: TinyReceiver\n\n          - arduino-boards-fqbn: STMicroelectronics:stm32:GenL0:pnum=THUNDERPACK_L072\n            platform-url: https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json\n            sketches-exclude: TinyReceiver,IRDispatcherDemo\n            build-properties: # the flags were put in compiler.cpp.extra_flags\n              All: -DNO_LED_FEEDBACK_CODE\n\n          - arduino-boards-fqbn: stm32duino:STM32F1:genericSTM32F103C # Roger Clark version\n            platform-url: http://dan.drown.org/stm32duino/package_STM32duino_index.json\n            sketches-exclude: TinyReceiver\n\n#          - arduino-boards-fqbn: SparkFun:apollo3:sfe_artemis_nano\n#            platform-url: https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/master/package_sparkfun_apollo3_index.json\n#            sketches-exclude: TinyReceiver\n\n      # Do not cancel all jobs / architectures if one job fails\n#      fail-fast: false\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@master\n\n# gives ERROR: library.properties includes field item(s) Arduino.h not found in library.\n#      - name: Arduino Lint\n#        uses: arduino/arduino-lint-action@v1\n#        with:\n#          library-manager: update\n\n      - name: Compile all examples\n        uses: ArminJo/arduino-test-compile@master\n        with:\n          arduino-board-fqbn: ${{ matrix.arduino-boards-fqbn }}\n          platform-url: ${{ matrix.platform-url }}\n#          arduino-platform: ${{ matrix.arduino-platform }}\n          required-libraries: 'LiquidCrystal,${{ matrix.required-libraries }}'\n          sketches-exclude: ${{ matrix.sketches-exclude }}\n          build-properties: ${{ toJson(matrix.build-properties) }}\n#          debug-install: true\n"
  },
  {
    "path": ".github/workflows/PlatformIoPublish.yml",
    "content": "# PlatformIoPublish.yml\n# Github workflow script to publish a release to PlatformIo.\n#\n# Copyright (C) 2021-2023  Armin Joachimsmeyer\n# https://github.com/ArminJo/Github-Actions\n#\n\n# This is the name of the workflow, visible on GitHub UI.\nname: PlatformIo publishing\non:\n  workflow_dispatch: # To run it manually\n    description: manual PlatformIo publishing\n  release: # see: https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#example-using-multiple-events-with-activity-types-or-configuration\n    types:\n      - created\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n\n    - name: Checkout\n      uses: actions/checkout@master\n\n    - name: Set up Python\n      uses: actions/setup-python@master\n      with:\n        python-version: '3.x'\n\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install platformio\n\n    - name: Build and publish\n      env:\n        PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_TOKEN }}\n      run: |\n        pio package publish --owner IRMP-org --non-interactive\n#      run: |\n#        pio package pack\n#        pio package publish --owner IRMP-org --non-interactive\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.md",
    "content": "<div align = center>\n\n# [IRMP](https://github.com/IRMP-org/IRMP) - Infrared Multi Protocol Decoder + Encoder\nA library enabling the sending & receiving of infra-red signals with a low memory footprint.<br/>\nSupports 50 different protocols.\n\n[![Badge License: GPLv3](https://img.shields.io/badge/License-GPLv3-brightgreen.svg)](https://www.gnu.org/licenses/gpl-3.0)\n &nbsp; &nbsp; \n[![Badge Version](https://img.shields.io/github/v/release/IRMP-org/IRMP?include_prereleases&color=yellow&logo=DocuSign&logoColor=white)](https://github.com/IRMP-org/IRMP/releases/latest)\n &nbsp; &nbsp; \n[![Badge Commits since latest](https://img.shields.io/github/commits-since/IRMP-org/IRMP/latest?color=yellow)](https://github.com/IRMP-org/IRMP/commits/master)\n &nbsp; &nbsp; \n[![Badge Build Status](https://github.com/IRMP-org/IRMP/workflows/LibraryBuild/badge.svg)](https://github.com/IRMP-org/IRMP/actions)\n &nbsp; &nbsp; \n![Badge Hit Counter](https://visitor-badge.laobi.icu/badge?page_id=IRMP-org_IRMP)\n<br/>\n<br/>\n[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)\n\nAvailable as [Arduino library \"IRMP\"](https://www.arduinolibraries.info/libraries/irmp).\n\n[![Button Install](https://img.shields.io/badge/Install-brightgreen?logoColor=white&logo=GitBook)](https://www.ardu-badge.com/IRMP)\n &nbsp; &nbsp; \n[![Button Changelog](https://img.shields.io/badge/Changelog-blue?logoColor=white&logo=AzureArtifacts)](https://github.com/IRMP-org/IRMP?tab=readme-ov-file#revision-history)\n\n</div>\n\n#### If you find this library useful, please give it a star.\n\n&#x1F30E; [Google Translate](https://translate.google.com/translate?sl=en&u=https://github.com/IRMP-org/IRMP)\n\n<br/>\n\n# Features\n- Total of 50 IR protocols supported.\n- Up to 39 protocols can be enabled for receive at the same time, because some of the 50 protocols are quite similar and conflicts with each other.\n- 39 protocols are available for send.\n- Low memory footprint. FLASH usage in bytes: 1500 for one protocol, 4300 for 15 main and 8000 for all 39 protocols.\n- RAM usage in bytes: 52, 73 and 100.\n\n<br/>\n\n| Nano running AllProtocol example | YouTube Video | Instructable |\n|-|-|-|\n| ![Nano running AllProtocol example](pictures/NEC.jpg) | ![YouTube Video](pictures/KASEIKYO+Remote.jpg) | [![Instructable](https://github.com/ArminJo/Arduino-OpenWindowAlarm/blob/master/pictures/instructables-logo-v2.png)](https://www.instructables.com/id/IR-Remote-Analyzer-Receiver-With-Arduino) |\n\n<br/>\n\n# List of protocols\n` Sony SIRCS ` &nbsp; &nbsp; ` NEC + APPLE + ONKYO ` &nbsp; &nbsp; ` Samsung + Samsg32 ` &nbsp; &nbsp; ` Kaseikyo `\n\n` JVC ` &nbsp; &nbsp; ` NEC16 + NEC42 ` &nbsp; &nbsp; ` Matsushita ` &nbsp; &nbsp; ` DENON `\n&nbsp; &nbsp; ` Sharp ` &nbsp; &nbsp; ` RC5 ` &nbsp; &nbsp; ` RC6 & RC6A ` &nbsp; &nbsp; ` IR60 (SDA2008) Grundig `\n&nbsp; &nbsp; ` Siemens Gigaset ` &nbsp; &nbsp; ` Nokia `\n\n` BOSE ` &nbsp; &nbsp; ` Kathrein ` &nbsp; &nbsp; ` NUBERT ` &nbsp; &nbsp; ` FAN (ventilator) `\n&nbsp; &nbsp; ` SPEAKER (~NUBERT) ` &nbsp; &nbsp; ` Bang & Olufsen ` &nbsp; &nbsp; ` RECS80 (SAA3004) `<br/>\n&nbsp; &nbsp; ` RECS80EXT (SAA3008) ` &nbsp; &nbsp; ` Thomson ` &nbsp; &nbsp; ` NIKON camera `\n&nbsp; &nbsp; ` Netbox keyboard ` &nbsp; &nbsp; ` ORTEK (Hama) ` &nbsp; &nbsp; ` Telefunken 1560 `<br/>\n&nbsp; &nbsp; ` FDC3402 keyboard ` &nbsp; &nbsp; ` RC Car ` &nbsp; &nbsp; ` iRobot Roomba `\n&nbsp; &nbsp; ` RUWIDO ` &nbsp; &nbsp; ` T-Home ` &nbsp; &nbsp; ` A1 TV BOX ` &nbsp; &nbsp;` LEGO Power RC `<br/>\n&nbsp; &nbsp; ` RCMM 12,24, or 32 ` &nbsp; &nbsp; ` LG Air Condition ` &nbsp; &nbsp; ` Samsung48 `\n&nbsp; &nbsp; ` Merlin ` &nbsp; &nbsp; ` Pentax ` &nbsp; &nbsp; ` S100 ` &nbsp; &nbsp; ` ACP24 ` &nbsp; &nbsp; ` TECHNICS `<br/>\n&nbsp; &nbsp; ` PANASONIC Beamer ` &nbsp; &nbsp; ` Mitsubishi Aircond ` &nbsp; &nbsp; ` VINCENT `\n&nbsp; &nbsp; ` SAMSUNG AH ` &nbsp; &nbsp; ` GREE CLIMATE `  &nbsp; &nbsp; ` RCII T+A `<br/>\n &nbsp; &nbsp; ` RADIO e.g. TEVION ` &nbsp; &nbsp; ` METZ `\n\n` NEC ` &nbsp; &nbsp; ` Kaseiko ` &nbsp; &nbsp; ` Denon ` &nbsp; &nbsp; ` RC6 ` &nbsp; &nbsp; ` Samsung + Samsg32 ` &nbsp; were successfully tested in **interrupt mode**, but there are many protocols which **in principle cannot be decoded** in this mode.\n\n<br/>\n\n# Features\n- You may use **every pin for input or output**.\n- Interrupt mode for major protocols.\n- Callback after successful receive of a command.\n- Support for inverted feedback LED (for send and receive feedback).\n- Support for inverted IR output for LED connected to VCC.\n- Unmodulated IR signal output enables direct replacment of an IR receiver circuit.\n- Compatible with Arduino tone library.\n- Send can also also wait for trailing space/gap.\n\n# Restrictions\n- Send IR frequency is fixed at 38 kHz.\n<br/>\n\n# Minimal version\nFor applications only requiring NEC protocol, there is a receiver which has very **small codesize of 500 bytes and does NOT require any timer**. See the MinimalReceiver and IRDispatcherDemo example how to use it. Mapping of pins to interrupts can be found [here](https://github.com/Arduino-IRremote/Arduino-IRremote/tree/master/src/TinyIRReceiver.hpp#L259).\n<br/>\n\n# Schematic for Arduino Uno\nThe VS1838B is used as receiver for all examples and tests. This module has a 120 &micro;s on/low and a 100 &micro;s off/high delay between received signal and output. So it shortens the mark and extends the space by 20 &micro;s.\n| IR-Receiver connection | Serial LCD connection |\n|---|---|\n![Fritzing schematic for Arduino Uno](extras/IRMP_UNO_Steckplatine.png) | ![Fritzing schematic for Arduino Uno + LCD](extras/IRMP_UNO_LCD_Steckplatine.png)\n<br/>\n\n# Supported Arduino architectures / CPU's / boards\nFor **ESP8266/ESP32**, [this library](https://github.com/crankyoldgit/IRremoteESP8266) supports an [impressive set of protocols and a lot of air conditioners](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md)<br/>\n<br/>\nATtiny and Digispark boards are tested with the recommended [ATTinyCore](https://github.com/SpenceKonde/ATTinyCore) using `New Style` pin mapping for the pro board.\n| Architecture | CPU | Board |\n|-|-:|-:|\n| avr     | ATmega16, ATmega328P, ATmega32U4, ATtinyX5, ATtinyX7 | Uno, Nano, Leonardo, Sparkfun Pro Micro, Digispark etc. |\n| megaavr | ATmega4809 | Uno WiFi Rev 2, Nano Every |\n| samd    | SAMD21G18A | Zero, MKR*, etc. **but not DUE, which is sam architecture** |\n| esp8266 | All protocols does not fit in IRAM | all |\n| esp32   | % | all |\n| stm32   | STM32F1xx     | BluePill |\n| STM32F1 | STM32F1xx     | BluePill |\n| apollo3 | Ambiq Apollo3 | Sparkfun Apollo3 + Artemis |\n| mbed    | nRF528x       | Nano 33 BLE |\n| Teensiduino | all  - but [limited support](https://forum.pjrc.com/threads/65912-Enable-Continuous-Integration-with-arduino-cli-for-3-party-libraries) | >= Teensy 3 |\n<br/>\n\n# Quick comparison of 5 Arduino IR receiving libraries\n**This is a short comparison and may not be complete or correct.**\n\nI created this comparison matrix for [myself](https://github.com/ArminJo) in order to choose a small IR lib for my project and to have a quick overview, when to choose which library.<br/>\nIt is dated from **24.06.2022** and updated 10/2023. If you have complains about the data or request for extensions, please send a PM or open a discussion.\n\n[Here](https://github.com/crankyoldgit/IRremoteESP8266) you find an **ESP8266/ESP32** version of IRremote with an **[impressive list of supported protocols](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md)**.\n\n| Subject | [IRMP](https://github.com/IRMP-org/IRMP) | [IRLremote](https://github.com/NicoHood/IRLremote) | [IRLib2](https://github.com/cyborg5/IRLib2)<br/>**mostly unmaintained** | [IRremote](https://github.com/Arduino-IRremote/Arduino-IRremote) | [TinyIR](https://github.com/Arduino-IRremote/Arduino-IRremote/tree/master/examples/TinyReceiver/TinyReceiver.ino) | [IRsmallDecoder](https://github.com/LuisMiCa/IRsmallDecoder)\n|-|-|-|-|-|-|-|\n| Number of protocols | **50** | Nec + Panasonic + Hash \\* | 12 + Hash \\* | 17 + PulseDistance + Hash \\* | NEC + FAST | NEC + RC5 + Sony + Samsung |\n| Timing method receive | Timer2 or interrupt for pin 2 or 3 | **Interrupt** | Timer2 or interrupt for pin 2 or 3 | Timer2 | **Interrupt** | **Interrupt** |\n| Timing method send | PWM and timing with Timer2 interrupts | Timer2 interrupts | Timer2 and blocking wait | PWM with Timer2 and/or blocking wait with delay<br/>Microseconds() | blocking wait with delay<br/>Microseconds() | % |\n| Send pins| All | All | All ? | Timer dependent | All | % |\n| Decode method | OnTheFly | OnTheFly | RAM | RAM | OnTheFly | OnTheFly |\n| Encode method | OnTheFly | OnTheFly | OnTheFly | OnTheFly or RAM | OnTheFly | % |\n| Callback suppport | x | % | % | x | x | % |\n| Repeat handling | Receive + Send (partially) | % | ? | Receive + Send | Receive + Send | Receive |\n| LED feedback | x | % | x | x | Receive | % |\n| FLASH usage (simple NEC example with 5 prints) | 1820<br/>(4300 for 15 main / 8000 for all 40 protocols)<br/>(+200 for callback)<br/>(+80 for interrupt at pin 2+3)| 1270<br/>(1400 for pin 2+3) | 4830 | 1770 | **900** | ?1100? |\n| RAM usage | 52<br/>(73 / 100 for 15 (main) / 40 protocols) | 62 | 334 | 227 | **19** | 29 |\n| Supported platforms | **avr, megaavr, attiny, Digispark (Pro), esp8266, ESP32, STM32, SAMD 21, Apollo3<br/>(plus arm and pic for non Arduino IDE)** | avr, esp8266 | avr, SAMD 21, SAMD 51 | avr, attiny, [esp8266](https://github.com/crankyoldgit/IRremoteESP8266), esp32, SAM, SAMD | **All platforms with attach<br/>Interrupt()** | **All platforms with attach<br/>Interrupt()** |\n| Last library update | 5/2023 | 4/2018 | 11/2022 | 9/2023 | 5/2023 | 2/2022 |\n| Remarks | Decodes 40 protocols concurrently.<br/>39 Protocols to send.<br/>Work in progress. | Only one protocol at a time. | Consists of 5 libraries. **Project containing bugs - 63 issues, 10 pull requests.* | Universal decoder and encoder.<br/>Supports **Pronto** codes and sending of raw timing values. | Requires no timer. | Requires no timer. |\n\n\\* The Hash protocol gives you a hash as code, which may be sufficient to distinguish your keys on the remote, but may not work with some protocols like Mitsubishi\n\n<br/>\n\n# Pin usage\nYou may use **every pin for input or output**, just define it like `#define IRMP_INPUT_PIN 2` and `#define IRSND_OUTPUT_PIN 3`. The PWM of the output pin is generated by software bit banging.\n\n# Dynamic pins numbers\nIf you want to use pin numbers for input, output and LED feedback specified at runtime, you must define `IRMP_IRSND_ALLOW_DYNAMIC_PINS`. See [ReceiveAndSendDynamicPins example](examples/ReceiveAndSendDynamicPins/ReceiveAndSendDynamicPins.ino).<br/>\nThe `irmp_init` and `irsnd_init` function then allows up to 3 parameters `uint_fast8_t aIrmpInputPin/aIrsndOutputPin, uint_fast8_t aIrmpFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow`.<br/>\nBe aware, only one pin and enable flag for receive and send feedback LED is supported.\n\n<br/>\n\n# Receiving and sending simultaneously\nReceiving and sending is possible with this library, but since we use only 1 timer, receiving is inhibited while sending the IR signal.<br/>\nSending the IR signal starts with saving current timer configuration, setting the timer to the send configuration / frequency, sending the signal (and waiting for the gap after the signal) and then automatically reset the timer to its previous (receiving) configuration.\n\n<br/>\n\n# API\n### IRMP\n\n```c++\n// Init functions\nvoid irmp_init (void);\nvoid irmp_init(uint_fast8_t aIrmpInputPin);\nvoid irmp_init(uint_fast8_t aIrmpInputPin, uint_fast8_t aIrmpFeedbackLedPin);\nvoid irmp_init(uint_fast8_t aIrmpInputPin, uint_fast8_t aIrmpFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow);\nvoid irmp_register_complete_callback_function(void (*aCompleteCallbackFunction)(void));\n\n// Info function\nbool irmp_IsBusy();\nvoid irmp_print_active_protocols(Print *aSerial);\n\n// Main check for result function used in loop()\nbool irmp_get_data (IRMP_DATA *)\n\n// Result print functions\nvoid irmp_result_print(Print *aSerial, IRMP_DATA * aIRMPDataPtr);\nvoid irmp_result_print(IRMP_DATA *aIRMPDataPtr);\n```\n### IRSND\n\n```c++\n// Init functions\nvoid irsnd_init (void);\n// 3 additional init functions if IRMP_IRSND_ALLOW_DYNAMIC_PINS is defined\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin);\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin, uint_fast8_t aIrmpFeedbackLedPin);\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin, uint_fast8_t aIrmpFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow);\n\n// Send function - sends frame AND trailing space\nbool irsnd_send_data (IRMP_DATA *, uint8_t);\n\n// Info functions\nbool irsnd_is_busy (void);\n\nvoid irsnd_stop (void);\n```\n### IRMP and IRSND\n\n```c++\n// LED feedback function\nvoid irmp_irsnd_LEDFeedback(bool aEnableBlinkLed);\n\n// Timer management functions for \nvoid disableIRTimerInterrupt(void);\nvoid enableIRTimerInterrupt(void);\nvoid storeIRTimer(void);\nvoid restoreIRTimer(void);\n```\n<br/>\n\n# Examples\nThese examples can be found in the Arduino IDE under File > Examples > Examples from Custom Libraries / IRMP.\n\nIn order to fit the examples to the 8K flash of ATtiny85 and ATtiny88, the [Arduino library ATtinySerialOut](https://github.com/ArminJo/ATtinySerialOut) is required for this CPU's.\n\n### AllProtocols\nReceives up to 40 protocols concurrently and **displays the short result on a 1602 LCD**. The LCD can be connected parallel or serial (I2C).<br/>\n\n### SimpleReceiver + SimpleSender\nThis examples are a good starting point.<br/>\nSimpleReceiver can be tested online with [WOKWI](https://wokwi.com/arduino/projects/298945438795432456).\nClick on the receiver while simulation is running to specify individual IR codes.\n\n#### MinimalReceiver + MinimalSender\nIf **code size** matters, look at these examples.<br/>\nThe **MinimalReceiver** example uses the **TinyReceiver** library  which can **only receive NEC and FAST codes, but does not require any timer**.<br/>\nMinimalReceiver can be tested online with [WOKWI](https://wokwi.com/arduino/projects/339264565653013075).\nClick on the receiver while simulation is running to specify individual IR codes.\n\n### SmallReceiver\nIf the protocol is not NEC and code size matters, look at this example.<br/>\nMinimalReceiver can be tested online with [WOKWI](https://wokwi.com/arduino/projects/299034264157028877).\nClick on the receiver while simulation is running to specify individual IR codes.\n\n### ReceiverTimingAnalysis\nThis example analyzes the signal delivered by your IR receiver module.\nValues can be used to determine the stability of the received signal as well as a hint for determining the protocol.<br/>\nIt also computes the MARK_EXCESS_MICROS value, which is the extension of the mark (pulse) duration introduced by the IR receiver module.<br/>\nIt can be tested online with [WOKWI](https://wokwi.com/arduino/projects/299033930562011656).\nClick on the receiver while simulation is running to specify individual IR codes.\n\n<br/>\n\n# Tips and tricks\n- To port the library to another device, you merely have to extend *IRTimer.hpp*.\n- The minimal CPU clock required for receiving is 8MHz.\n- To save power, you can use the interrupt mode or polling mode with no-sending detection and power down sleep.\n This is **not available** for ATtiny85 running with the High Speed PLL clock (as on  Digispark boards) \n because of the high startup time from sleep of 4 to 5 ms for this clock. You have to use the ISP to [rewrite the CKSEL fuses](https://github.com/ArminJo/micronucleus-firmware/blob/master/utils/Write%2085%20Fuses%20E2%20DF%20FF%20-%20ISP%20Mode%20%3D%208MHz%20without%20BOD%20and%20Pin5.cmd) and to load the program.\n - The best way to **increase the IR power** is to use 2 or 3 IR diodes in series. \n One diode requires 1.1 to 1.5 volt so you can supply 3 diodes with a 5 volt output.To keep the current, \n you must reduce the resistor by (5 - 1.3) / (5 - 2.6) = 1.5 e.g. from 150 &ohm; to 100 &ohm; for 25 mA and 2 diodes with 1.3 volt and a 5 volt supply.\n For 3 diodes it requires factor 2.5 e.g. from 150 &ohm; to 60 &ohm;.\n- A lot of recent IR diodes can be powered with max. 200 mA at 50% duty cycle, but for this you will require an external driver / transistor / (mos)fet.\n- In order to fit the examples to the 8K flash of ATtiny85 and ATtiny88, the [Arduino library ATtinySerialOut](https://github.com/ArminJo/ATtinySerialOut) is required for this CPU's.\n- Sending `IRMP_NEC_PROTOCOL` requires a full 16 bit address. Thus for sending plain NEC with 8 bit address, the 16 bit address must be computed with\n`address |= ~((address & 0xFF) << 8);`\n\n<br/>\n\n\n# Compile options / macros for this library\nTo customize the library to different requirements, there are some compile options / macros available, which must be set **before** including the library e.g. with `#include <irmp.hpp>`.<br/>\nModify it by setting the value to 1 or 0. Or define the macro with the -D compiler option for global compile (the latter is not possible with the Arduino IDE, so consider using [Sloeber](https://eclipse.baeyens.it).<br/>\n\n| Name | Default value | Description |\n|-|-:|-|\n| `IRMP_INPUT_PIN` | 2 | The pin number which gets compiled in, if not using `IRMP_IRSND_ALLOW_DYNAMIC_PINS`. See also [PinDefinitionsAndMore.h](https://github.com/IRMP-org/IRMP/master/examples/OneProtocol/PinDefinitionsAndMore.h#L32) |\n| `IRMP_FEEDBACK_LED_PIN` | `LED_BUILTIN` | The pin number for the feedback led which gets compiled in, if not using `IRMP_IRSND_ALLOW_DYNAMIC_PINS`. |\n| `FEEDBACK_LED_IS_ACTIVE_LOW` | disabled | Required on some boards (like my like my BluePill and my ESP8266 board), where the feedback LED is active low. |\n| `NO_LED_FEEDBACK_CODE` | disabled | Enable it to disable the feedback LED function. Saves 30 bytes program memory. |\n| `IRMP_IRSND_ALLOW_DYNAMIC_PINS` | disabled | Allows to specify pin number at irmp_init() - see above. This requires additional program memory. |\n| `IRMP_PROTOCOL_NAMES` | 0 / disabled | Enable protocol number mapping to protocol strings - needs some program memory. |\n| `IRMP_USE_COMPLETE_CALLBACK` | 0 / disabled | Use Callback if complete data was received. Requires call to irmp_register_complete_callback_function(). |\n| `IRMP_ENABLE_PIN_CHANGE_INTERRUPT` | disabled | Use [Arduino attachInterrupt()](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) and do **no polling with timer ISR**. This **restricts the available input pins and protocols**. The results are equivalent to results acquired with a sampling rate of 15625 Hz (chosen to avoid time consuming divisions). For AVR boards an own interrupt handler for  INT0 or INT1 is used instead of Arduino attachInterrupt().  |\n| `IRMP_ENABLE_RELEASE_DETECTION` | 0 / disabled | If user releases a key on the remote control, last protocol/address/command will be returned with flag `IRMP_FLAG_RELEASE` set. |\n| `IRMP_HIGH_ACTIVE` | 0 / disabled | Set to 1 if you use a RF receiver, which has an active HIGH output signal. |\n| `IRMP_32_BIT` | 0 / disabled | This enables MERLIN protocol, but decreases performance for AVR. Enabled by default for 32 bit platforms. |\n| `F_INTERRUPTS` | 15000 | The IRMP sampling frequency.|\n| `USE_ONE_TIMER_FOR_IRMP_AND_IRSND` | disabled | **Must** be defined if you use receiving and sending simultaneously, since both use the same timer resource. **Must not** be enabled if you only use receiving. |\n| `IRSND_USE_CALLBACK` | 0 / disabled | Calls a function if send output signal changes to active (sending the IR signal). |\n| `IR_OUTPUT_IS_ACTIVE_LOW` | disabled | Output LOW for active IR signal. Use it if IR LED is connected between VCC and output pin. |\n| `IRSND_GENERATE_NO_SEND_RF` | disabled | Do not generate the carrier frequency (of 38 kHz), just simulate an active low receiver signal. |\n| `IRSND_IR_FREQUENCY` | 38000 | The modulation frequency for sent signal. The send signal is generated by bit banging, so the internal interrupt frequency is `IRSND_IR_FREQUENCY * 2`. The send control function is called at a rate of `IRSND_IR_FREQUENCY / 2`, resulting in a send packet signal resolution of 2 on/off periods. |\n|-|-|-|\n| `IRMP_MEASURE_TIMING` +  `IR_TIMING_TEST_PIN` | enabled | For development only. The test pin is switched high at the very beginning and low at the end of the ISR. |\n\nThese next macros for **TinyIRReceiver** must be defined in your program before the line `#include <TinyIRReceiver.hpp>` to take effect.\n| Name | Default value | Description |\n|-|-:|-|\n| `IR_RECEIVE_PIN` | 2 | The pin number for TinyIRReceiver IR input, which gets compiled in. |\n| `IR_FEEDBACK_LED_PIN` | `LED_BUILTIN` | The pin number for TinyIRReceiver feedback LED, which gets compiled in. |\n| `NO_LED_FEEDBACK_CODE` | disabled | Enable it to disable the feedback LED function. Saves 14 bytes program memory. |\n\n\n### Changing include (*.h) files with Arduino IDE\nFirst, use *Sketch > Show Sketch Folder (Ctrl+K)*.<br/>\nIf you have not yet saved the example as your own sketch, then you are instantly in the right library folder.<br/>\nOtherwise you have to navigate to the parallel `libraries` folder and select the library you want to access.<br/>\nIn both cases the library source and include files are located in the libraries `src` directory.<br/>\nThe modification must be renewed for each new library version!\n\n### Modifying compile options with Sloeber IDE\nIf you are using [Sloeber](https://eclipse.baeyens.it) as your IDE, you can easily define global symbols with *Properties > Arduino > CompileOptions*.<br/>\n![Sloeber settings](https://github.com/ArminJo/ServoEasing/blob/master/pictures/SloeberDefineSymbols.png)\n\n<br/>\n\n# [Timer usage](https://github.com/IRMP-org/IRMP/blob/master/src/IRTimer.hpp#L39)\nThe IRMP **receive** library works by polling the input pin at a rate of 10 to 20 kHz. Default is 15 kHz.<br/>\nSome protocols (NEC, Kaseiko, Denon, RC6, Samsung + Samsg32) can be received **without timer usage**, just by using interrupts from the input pin by defining `IRMP_ENABLE_PIN_CHANGE_INTERRUPT`. There are many protocols which **in principle cannot be decoded** in this mode. See [Interrupt example](examples/Interrupt/Interrupt.ino).<br/>\n**In interrupt mode, the `micros()` function is used as timebase.**\n\nThe IRMP **send** library works by bit banging the output pin at a frequency of 38 kHz. This **avoids blocking waits** and allows to choose an **arbitrary pin**, you are not restricted to PWM generating pins like pin 3 or 11. The interrupts for send pin bit banging require 50% CPU time on a 16 MHz AVR.<br/>\nIf both receiving and sending is required, the timer is set up for receiving and reconfigured for the duration of sending data, thus preventing receiving in polling mode while sending data.<br/>\nThe **tone library (using timer 2) is still available**. You can use it alternating with IR receive and send, see [ReceiveAndSend example](examples/ReceiveAndSend/ReceiveAndSend.ino).<br/>\n\n- For AVR **timer 2 (Tone timer)** is used for receiving **and** sending.\n For variants, which have no timer 2 like ATtiny85 or ATtiny167, **timer 1** (or timer 0 for digispark core) is used.\n- For SAMD **TC3** is used.\n- For Apollo3 **Timer 3 segment B** is used.\n- For ESP8266 and ESP32 **timer1** is used.\n- For STM32 (BluePill) **timer 3 (Servo timer) channel 1** is used as default.<br/>\n\n<br/>\n\n# [AllProtocols](examples/AllProtocols/AllProtocols.ino) example\n| Serial LCD output | Arduino Serial Monitor output |\n|-|-|\n| ![LCD start](pictures/Start.jpg) | ![Serial Monitor](pictures/AllProtocol_SerialMonitor.png) |\n\n## Sample Protocols\n| | | | |\n|-|-|-|-|\n| ![NEC](pictures/NEC_Parallel.jpg) | ![NEC42](pictures/NEC42.jpg) |![RC5](pictures/RC5.jpg) |![KASEIKYO](pictures/KASEIKYO.jpg) |\n| ![DENON](pictures/DENON.jpg) |![GRUNDIG](pictures/GRUNDIG.jpg) |![IR60](pictures/IR60.jpg) |![MATSUSHITA](pictures/MATSUSHITA.jpg) |\n| ![NUBERT](pictures/NUBERT.jpg) |![ONKYO](pictures/ONKYO.jpg) |![RECS80](pictures/RECS80.jpg) |![RUWIDO](pictures/RUWIDO.jpg) |\n| ![SAMSUNG](pictures/SAMSUNG.jpg) |![SIEMENS](pictures/SIEMENS.jpg) |![TELEFUNKEN](pictures/TELEFUNKEN.jpg) |![TELEFUNKEN](pictures/TELEFUNKEN.jpg) |\n\n<br/>\n\n# Documentation at mikrocontroller.net\n### English\n   http://www.mikrocontroller.net/articles/IRMP_-_english<br/>\n   http://www.mikrocontroller.net/articles/IRSND_-_english\n### German\n   http://www.mikrocontroller.net/articles/IRMP<br/>\n   http://www.mikrocontroller.net/articles/IRSND\n### German Forum\n   https://www.mikrocontroller.net/topic/irmp-infrared-multi-protocol-decoder?goto=6996113#6996137\n\n<br/>\n\n# Revision History\n### Version 3.7.0 - Major content contribution by Jörg Riechardt\n- Support RC6A20 and RC6A28.\n- Sending S100 is not supported.\n- Enable repetition for IR60.\n- Fix for sending on STM32 with standard peripheral library.\n- Includes and initialization for RP2040\n- Allow Lego with 19 kHz.\n\n### Version 3.6.4\n- Support for ESP32 core 3.x.\n- Improved code for MegaTinyCore.\n\n### Version 3.6.3\n- Fixed ESP32 send timer bug.\n\n### Version 3.6.2\n- Fixed FEEDBACK_LED_IS_ACTIVE_LOW bug.\n- Added Kaseikyo Panasonic decode.\n- Added ATtiny88 / AVR timer1 timer support.\n- Fixed unexpected leading space for irsnd_send_data(...,false).\n\n### Version 3.6.1\n- Fixed NO_LED_FEEDBACK_CODE bug.\n\n### Version 3.6.0\n- Improved timings by J�rg R.\n- Support for NEC 8 bit address.\n- Fixed ATmega4809 bug.\n- RP2040 support added.\n\n### Version 3.5.1\n- Fixed ESP8266 `F_CPU` error introduced with 3.4.1.\n\n### Version 3.5.0\n- Renamed *.c.h and *.cpp.h to .hpp. **You must change: #include <irmp.c.h> to: #include <irmp.hpp>!**\n- Fix Timer1 initialization for ATtinyX7 parts for ATTinyCore.\n- Modifying *digitalWriteFast.h* to be compatible with ATTinyCore Digispark Pro default pin mapping.\n- Renamed `initPCIInterrupt()` to `enablePCIInterrupt()` and added `disablePCIInterrupt()`.\n- Changed return value for `irsnd_send_data()` to be false on error conditions.\n- Fixed `ICACHE_RAM_ATTR` error introduced with 3.4.1.\n\n### Version 3.4.1\n- Changed default pins for ATmega328 platform from 3,4,5 to 2,3,4.\n- Adapted to TinyCore 0.0.7.\n- Renamed macro IRMP_TIMING_TEST_PIN to IR_TIMING_TEST_PIN.\n- Changed pins in PinDefinitionsAndMore.h.\n- Never send a trailing space for Arduino.\n- ATTiny88 support.\n\n### Version 3.4.0\n- Added ATtiny3217 / TinyCore support.\n- Added Melinera protocol and single repeat for NEC from upstream.\n\n### Version 3.3.5\n- Added TinyIRReceiver and updated IRDispatcherDemo examples.\n- Fixed \"enabling OUTPUT for dynamic pin\" bug.\n- Improved Apollo3 and MegaCore support.\n\n### Version 3.3.4\n- Removed convenience function `irmp_tone()`, since it statically allocates the tone interrupt vector 7.\n\n### Version 3.3.3\n- Added ATmega8 support.\n- Added `IRSND_GENERATE_NO_SEND_RF` compile switch.\n- Added function `irsnd_data_print()`.\n- New SendAllProtocols example.\n- New DispatcherDemo example.\n- Added `IRMP_FEEDBACK_LED_PIN` compile switch.\n- Removed `IRMP16` protocol from the all list.\n- Added missing Leonardo support.\n\n### Version 3.3.2\n- Added missing Medion entry in `irmp_protocol_names`.\n- Added function `irmp_print_protocol_name()`.\n- Added Teensyduino support.\n- Fixed macro redefinitions in IRSND.\n\n### Version 3.3.1\n- Fix for function `bool irmp_IsBusy()` if `IRMP_ENABLE_PIN_CHANGE_INTERRUPT` is defined.\n\n### Version 3.3.0\n- Added function `bool irmp_IsBusy()`.\n\n### Version 3.2.3\n- Fixed warning for missing `USE_ONE_TIMER_FOR_IRMP_AND_IRSND` macro.\n\n### Version 3.2.2\n- Removed blocking wait for ATmega32U4 Serial in examples.\n- Restored missing line `reset interrupt flags` found by user yumkam.\n- Fixed bug for sending only on no AVR platforms.\n\n### Version 3.2.1\n- Fixed bug in feedback LED handling for dynamic pins for send and receive.\n- Fixed wrong timer selection for STM32F1xx / ARDUINO_ARCH_STM32.\n\n### Version 3.2.0\n- MBED support for Arduino Nano 33 BLE.\n- Added ARDUINO_ARCH_STM32 definition.\n- Fixed ESP8266 wrong memcpy_p definition introduced in 3.0.0.\n\n### Version 3.1.2\n- Fixed interrupt mode bug introduced by merging upstream code for version 3.1.0.\n- Fixed ESP8266 wrong memcpy_p definition introduced in 3.0.0. - Fix was not complete :-(. Use 3.2.0.\n\n### Version 3.1.1\n- Added `MinimalReceiver` example.\n\n### Version 3.1.0\n- Added RF_MEDION protocol\n- IRAM attribute etc.\n- Fixed bug irmp_init used instead of irsnd_init\n- New function irmp_print_active_protocols().\n- Use timer3 for ESP32.\n- Fix missing check for LED pin == 0.\n- Merged upstream v3.2.2 + IRMP_ENABLE_RELEASE_DETECTION.\n- Dynamic pin for feedback LED added.\n\n### Version 3.0.0\n- Support of RF (433MHz) remotes. 2 protocols **Generic 24 bit format** and **X10 format** added.\n- MegaAVR (ATmega4809) support.\n- Added `IRMP_IRSND_ALLOW_DYNAMIC_PINS` and extended `irmp_init()` and `irsnd_init()`to allow input, output and LED feedback pin selection at runtime.\n- Support more protocols simultaneously on 32 bit CPUs.\n- Use same pin and enable flag for receive and send feedback LED.\n- New function `irmp_print_active_protocols()`.\n\n### Version 2.2.1\n- Improved pin layout.\n- Fixed bug with stm32duino 1.9.\n- Version number.\n- Blink13 -> LEDFeedback.\n\n### Version 2.2.0\n- Supported **Apollo3** platform.\n- Fixed DigisparkPro bug.\n\n### Version 2.1.0\n- Supported **SAMD** platform.\n- IRSND enabled for non AVR platforms.\n\n### Version 2.0.0\n- Added IR send functionality (IRSND).\n- Use `TIMER2_COMPB_vect` to be compatible with tone library.\n- No longer required to call initPCIInterrupt() manually if IRMP_ENABLE_PIN_CHANGE_INTERRUPT is set.\n- Separated code for timer to IRTimer.hpp.\n- Separated code for Pin change interrupt to irmpPinChangeInterrupt.hpp.\n- Fixed wrong pin numbers for BluePill.\n\n### Version 1.2.2\n- Fixed bugs introduced in 1.2.1.\n \n### Version 1.2.1\n- Bug for AVR architecture fixed.\n- ATtiny85 + ATtiny167 support for ATTinyCore and Digistump core.\n- Support for \"Generic STM32F1 series\" from \"STM32 Boards (selected from submenu)\" of Arduino Board manager.\n\n### Version 1.2.0 - This version contains a bug for the AVR architecture\n- Added STM32 M3 (BluePill) support.\n\n### Version 1.1.0\n- Added functions `irmp_disable_timer_interrupt()` and `irmp_enable_timer_interrupt()`.\n- Added function `irmp_result_print(Print *aSerial)`.\n- Improved examples.\n\n### Version 1.0.1\n- Added ESP8266 + ESP32 support.\n\n# CI\nThe library examples are tested with GitHub Actions for the following boards:\n\n- arduino:avr:uno\n- arduino:avr:leonardo\n- arduino:avr:mega\n- arduino:megaavr:nona4809:mode=off\n- arduino:samd:arduino_zero_native\n- arduino:mbed:nano33ble\n- arduino:mbed_rp2040:pico\n- rp2040:rp2040:arduino_nano_connect\n- digistump:avr:digispark-tiny:clock=clock16\n- ATTinyCore:avr:attinyx5micr:LTO=enable,sketchclock=8pll\n- ATTinyCore:avr:attinyx7micr:LTO=enable,sketchclock=16external,pinmapping=new,millis=enabled\n- ATTinyCore:avr:attinyx8micr:LTO=enable,sketchclock=16external,pinmapping=mhtiny,millis=enabled  # ATtiny88 China clone board @16 MHz\n- TinyCore:avr:tiny32\n- esp8266:esp8266:d1_mini:eesz=4M3M,xtal=80\n- esp32:esp32:featheresp32:FlashFreq=80\n- STMicroelectronics:stm32:GenF1:pnum=BLUEPILL_F103C8\n- STMicroelectronics:stm32:GenL0:pnum=THUNDERPACK_L072\n- stm32duino:STM32F1:genericSTM32F103C\n- SparkFun:apollo3:sfe_artemis_nano"
  },
  {
    "path": "examples/AllProtocols/ADCUtils.h",
    "content": "/*\n * ADCUtils.h\n *\n *  Copyright (C) 2016-2022  Armin Joachimsmeyer\n *  Email: armin.joachimsmeyer@gmail.com\n *\n *  This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.\n *\n *  ArduinoUtils is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#ifndef _ADC_UTILS_H\n#define _ADC_UTILS_H\n\n#include <Arduino.h>\n\n#if defined(__AVR__) && defined(ADCSRA) && defined(ADATE) && (!defined(__AVR_ATmega4809__))\n#define ADC_UTILS_ARE_AVAILABLE\n\n// External Reference Current is 150 uA for 5 V and 100 uA for 3.5 V\n#define READING_FOR_AREF 1024 // Datasheet 24.2: The minimum value represents GND and the maximum value represents the voltage on the AREF pin minus 1 LSB\n#define MAX_ADC_VALUE    1023\n\n// PRESCALE4 => 13 * 4 = 52 microseconds per ADC conversion at 1 MHz Clock => 19,2 kHz\n#define ADC_PRESCALE2    1 // 26 microseconds per ADC conversion at 1 MHz\n#define ADC_PRESCALE4    2 // 52 microseconds per ADC conversion at 1 MHz\n// PRESCALE8 => 13 * 8 = 104 microseconds per ADC sample at 1 MHz Clock => 9,6 kHz\n#define ADC_PRESCALE8    3 // 104 microseconds per ADC conversion at 1 MHz\n#define ADC_PRESCALE16   4 // 13/208 microseconds per ADC conversion at 16/1 MHz - degradations in linearity at 16 MHz\n#define ADC_PRESCALE32   5 // 26/416 microseconds per ADC conversion at 16/1 MHz - very good linearity at 16 MHz\n#define ADC_PRESCALE64   6 // 52 microseconds per ADC conversion at 16 MHz\n#define ADC_PRESCALE128  7 // 104 microseconds per ADC conversion at 16 MHz --- Arduino default\n\n// definitions for 0.1 ms conversion time\n#if (F_CPU == 1000000)\n#define ADC_PRESCALE ADC_PRESCALE8\n#elif (F_CPU == 8000000)\n#define ADC_PRESCALE ADC_PRESCALE64\n#elif (F_CPU == 16000000)\n#define ADC_PRESCALE ADC_PRESCALE128\n#endif\n\n/*\n * Reference shift values are complicated for ATtinyX5 since we have the extra register bit REFS2\n * in ATTinyCore, this bit is handled programmatical and therefore the defines are different.\n * To keep my library small, I use the changed defines.\n * After including this file you can not call the ATTinyCore readAnalog functions reliable, if you specify references other than default!\n */\n#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n// defines are for ADCUtils.cpp, they can be used WITHOUT bit reordering\n#undef DEFAULT\n#undef EXTERNAL\n#undef INTERNAL1V1\n#undef INTERNAL\n#undef INTERNAL2V56\n#undef INTERNAL2V56_EXTCAP\n\n#define DEFAULT 0\n#define EXTERNAL 4\n#define INTERNAL1V1 8\n#define INTERNAL INTERNAL1V1\n#define INTERNAL2V56 9\n#define INTERNAL2V56_EXTCAP 13\n\n#define SHIFT_VALUE_FOR_REFERENCE REFS2\n#define MASK_FOR_ADC_REFERENCE (_BV(REFS0) | _BV(REFS1) | _BV(REFS2))\n#define MASK_FOR_ADC_CHANNELS (_BV(MUX0) | _BV(MUX1) | _BV(MUX2) | _BV(MUX3))\n#else // AVR_ATtiny85\n\n#define SHIFT_VALUE_FOR_REFERENCE REFS0\n#define MASK_FOR_ADC_REFERENCE (_BV(REFS0) | _BV(REFS1))\n#define MASK_FOR_ADC_CHANNELS (_BV(MUX0) | _BV(MUX1) | _BV(MUX2) | _BV(MUX3))\n#endif\n\n// Temperature channel definitions - 1 LSB / 1 degree Celsius\n#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#define ADC_TEMPERATURE_CHANNEL_MUX 15\n#define ADC_1_1_VOLT_CHANNEL_MUX    12\n#define ADC_GND_CHANNEL_MUX         13\n#define ADC_CHANNEL_MUX_MASK        0x0F\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#define ADC_ISCR_CHANNEL_MUX         3\n#define ADC_TEMPERATURE_CHANNEL_MUX 11\n#define ADC_1_1_VOLT_CHANNEL_MUX    12\n#define ADC_GND_CHANNEL_MUX         14\n#define ADC_VCC_4TH_CHANNEL_MUX     13\n#define ADC_CHANNEL_MUX_MASK        0x1F\n\n#elif defined(__AVR_ATmega328P__)\n#define ADC_TEMPERATURE_CHANNEL_MUX  8\n#define ADC_1_1_VOLT_CHANNEL_MUX    14\n#define ADC_GND_CHANNEL_MUX         15\n#define ADC_CHANNEL_MUX_MASK        0x0F\n\n#elif defined(__AVR_ATmega644P__)\n#define ADC_TEMPERATURE_CHANNEL_MUX  // not existent\n#define ADC_1_1_VOLT_CHANNEL_MUX    0x1E\n#define ADC_GND_CHANNEL_MUX         0x1F\n#define ADC_CHANNEL_MUX_MASK        0x0F\n\n#elif defined(__AVR_ATmega32U4__)\n#define ADC_TEMPERATURE_CHANNEL_MUX 0x27\n#define ADC_1_1_VOLT_CHANNEL_MUX    0x1E\n#define ADC_GND_CHANNEL_MUX         0x1F\n#define ADC_CHANNEL_MUX_MASK        0x3F\n\n#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)\n#define ADC_1_1_VOLT_CHANNEL_MUX    0x1E\n#define ADC_GND_CHANNEL_MUX         0x1F\n#define ADC_CHANNEL_MUX_MASK        0x1F\n\n#define INTERNAL INTERNAL1V1\n\n#else\n#error \"No temperature channel definitions specified for this AVR CPU\"\n#endif\n\n/*\n * Thresholds for OVER and UNDER voltage and detection of kind of power supply (USB or Li-ion)\n *\n * Default values are suitable for Li-ion batteries.\n * We normally have voltage drop at the connectors, so the battery voltage is assumed slightly higher, than the Arduino VCC.\n * But keep in mind that the ultrasonic distance module HC-SR04 may not work reliable below 3.7 volt.\n */\n#if !defined(LI_ION_VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)\n#define LI_ION_VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT             3400 // Do not stress your battery and we require some power for standby\n#endif\n#if !defined(LI_ION_VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)\n#define LI_ION_VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT   3000 // Many Li-ions are specified down to 3.0 volt\n#endif\n\n#if !defined(VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)\n#define VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT            LI_ION_VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT\n#endif\n#if !defined(VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT)\n#define VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT  LI_ION_VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT\n#endif\n#if !defined(VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT)\n#define VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT             5250 // + 5 % operation voltage\n#endif\n#if !defined(VCC_EMERGENCY_OVERVOLTAGE_THRESHOLD_MILLIVOLT)\n#define VCC_EMERGENCY_OVERVOLTAGE_THRESHOLD_MILLIVOLT   5500 // +10 %. Max recommended operation voltage\n#endif\n#if !defined(VCC_CHECK_PERIOD_MILLIS)\n#define VCC_CHECK_PERIOD_MILLIS                         10000L // 10 seconds period of VCC checks\n#endif\n#if !defined(VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP)\n#define VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP     6 // Shutdown after 6 times (60 seconds) VCC below VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT or 1 time below VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT\n#endif\n\n#if !defined(VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT)\n#define VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT   4300 // Assume USB powered above this voltage\n#endif\n\n#if !defined(VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT)\n#define VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT   4950 // Assume USB powered below this voltage, because of the loss in USB cable. If we have > 4950, we assume to be powered by VIN.\n// In contrast to e.g. powered by VIN, which results in almost perfect 5 volt supply\n#endif\n\nextern long sLastVCCCheckMillis;\nextern uint8_t sVCCTooLowCounter;\n\nuint16_t readADCChannel();\nuint16_t readADCChannel(uint8_t aADCChannelNumber);\nuint16_t readADCChannelWithReference(uint8_t aADCChannelNumber, uint8_t aReference);\nuint16_t readADCChannelWithReferenceUsingInternalReference(uint8_t aADCChannelNumber);\nuint16_t waitAndReadADCChannelWithReference(uint8_t aADCChannelNumber, uint8_t aReference);\nuint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t aADCChannelNumber, uint8_t aReference);\nuint16_t readADCChannelWithOversample(uint8_t aADCChannelNumber, uint8_t aOversampleExponent);\nvoid setADCChannelAndReferenceForNextConversion(uint8_t aADCChannelNumber, uint8_t aReference);\nuint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent);\nuint32_t readADCChannelMultiSamples(uint8_t aPrescale, uint16_t aNumberOfSamples);\nuint16_t readADCChannelMultiSamplesWithReference(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples);\nuint32_t readADCChannelMultiSamplesWithReferenceAndPrescaler(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aPrescale,\n        uint16_t aNumberOfSamples);\nuint16_t readADCChannelWithReferenceMax(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples);\nuint16_t readADCChannelWithReferenceMaxMicros(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire);\nuint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aDelay,\n        uint8_t aAllowedDifference, uint8_t aMaxRetries);\n\nvoid setADCChannelForNextConversionAndWaitUsingInternalReference(uint8_t aADCChannelNumber);\nvoid setADCChannelForNextConversionAndWaitUsingDefaultReference(uint8_t aADCChannelNumber);\nuint8_t checkAndWaitForReferenceAndChannelToSwitch(uint8_t aADCChannelNumber, uint8_t aReference);\n\n/*\n * readVCC*() functions store the result in sVCCVoltageMillivolt or sVCCVoltage\n */\nfloat getVCCVoltageSimple(void);\nvoid readVCCVoltageSimple(void);\nvoid readVCCVoltageMillivoltSimple(void);\nvoid readVCCVoltage(void);\nuint16_t getVCCVoltageMillivolt(void);\nvoid readVCCVoltageMillivolt(void);\nuint16_t getVCCVoltageReadingFor1_1VoltReference(void);\nuint16_t printVCCVoltageMillivolt(Print *aSerial);\nvoid readAndPrintVCCVoltageMillivolt(Print *aSerial);\n\nuint16_t getVoltageMillivolt(uint16_t aVCCVoltageMillivolt, uint8_t aADCChannelForVoltageMeasurement);\nuint16_t getVoltageMillivolt(uint8_t aADCChannelForVoltageMeasurement);\nuint16_t getVoltageMillivoltWith_1_1VoltReference(uint8_t aADCChannelForVoltageMeasurement);\nfloat getCPUTemperatureSimple(void);\nfloat getCPUTemperature(void);\nfloat getTemperature(void) __attribute__ ((deprecated (\"Renamed to getCPUTemperature()\"))); // deprecated\n\nbool isVCCUSBPowered();\nbool isVCCUSBPowered(Print *aSerial);\nbool isVCCUndervoltageMultipleTimes();\nvoid resetCounterForVCCUndervoltageMultipleTimes();\nbool isVCCUndervoltage();\nbool isVCCEmergencyUndervoltage();\nbool isVCCOvervoltage();\nbool isVCCOvervoltageSimple();  // Version using readVCCVoltageMillivoltSimple()\nbool isVCCTooHighSimple();      // Version not using readVCCVoltageMillivoltSimple()\n\n#endif //  defined(__AVR__) ...\n\n/*\n * The next variables and functions are defined as stubs on non-AVR platforms to allow for seamless compiling\n */\nextern float sVCCVoltage;\nextern uint16_t sVCCVoltageMillivolt;\n\nuint16_t readADCChannelWithReferenceOversample(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent);\n\nuint16_t getVCCVoltageMillivoltSimple(void);\nfloat getVCCVoltage(void);\nfloat getCPUTemperature(void);\n\n#endif // _ADC_UTILS_H\n"
  },
  {
    "path": "examples/AllProtocols/ADCUtils.hpp",
    "content": "/*\n * ADCUtils.hpp\n *\n * ADC utility functions. Conversion time is defined as 0.104 milliseconds for 16 MHz Arduinos in ADCUtils.h.\n *\n *  Copyright (C) 2016-2023  Armin Joachimsmeyer\n *  Email: armin.joachimsmeyer@gmail.com\n *\n *  This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.\n *\n *  ArduinoUtils is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n */\n\n#ifndef _ADC_UTILS_HPP\n#define _ADC_UTILS_HPP\n\n#include \"ADCUtils.h\"\n#if defined(ADC_UTILS_ARE_AVAILABLE) // set in ADCUtils.h, if supported architecture was detected\n#define ADC_UTILS_ARE_INCLUDED\n\n// Helper macro for getting a macro definition as string\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n#if !defined(BITS_PER_BYTE)\n#define BITS_PER_BYTE 8\n#endif\n\n/*\n * By replacing this value with the voltage you measured a the AREF pin after a conversion\n * with INTERNAL you can calibrate your ADC readout. For my Nanos I measured e.g. 1060 mV and 1093 mV.\n */\n#if !defined(ADC_INTERNAL_REFERENCE_MILLIVOLT)\n#define ADC_INTERNAL_REFERENCE_MILLIVOLT    1100 // Change to value measured at the AREF pin. If value > real AREF voltage, measured values are > real values\n#endif\n\n// Union to speed up the combination of low and high bytes to a word\n// it is not optimal since the compiler still generates 2 unnecessary moves\n// but using  -- value = (high << 8) | low -- gives 5 unnecessary instructions\nunion WordUnionForADCUtils {\n    struct {\n        uint8_t LowByte;\n        uint8_t HighByte;\n    } UByte;\n    uint16_t UWord;\n    int16_t Word;\n    uint8_t *BytePointer;\n};\n\n/*\n * Enable this to see information on each call.\n * Since there should be no library which uses Serial, it should only be enabled for development purposes.\n */\n#if defined(DEBUG)\n#define LOCAL_DEBUG\n#else\n//#define LOCAL_DEBUG // This enables debug output only for this file\n#endif\n#if defined(INFO)\n#define LOCAL_INFO\n#else\n//#define LOCAL_INFO // This enables debug output only for this file\n#endif\n\n/*\n * Persistent storage for VCC value\n */\nfloat sVCCVoltage;\nuint16_t sVCCVoltageMillivolt;\n\n// for isVCCTooLowMultipleTimes()\nlong sLastVCCCheckMillis;\nuint8_t sVCCTooLowCounter = 0;\n\n/*\n * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h.\n * Use previous settings\n */\nuint16_t readADCChannel() {\n    WordUnionForADCUtils tUValue;\n\n    // ADCSRB = 0; // Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE);\n\n    // wait for single conversion to finish\n    loop_until_bit_is_clear(ADCSRA, ADSC);\n\n    // Get value\n    tUValue.UByte.LowByte = ADCL;\n    tUValue.UByte.HighByte = ADCH;\n    return tUValue.UWord;\n    //    return ADCL | (ADCH <<8); // needs 4 bytes more\n}\n\n/*\n * Use new channel aADCChannelNumber, but do not wait for channel switching\n */\nuint16_t readADCChannel(uint8_t aADCChannelNumber) {\n    WordUnionForADCUtils tUValue;\n    ADMUX = aADCChannelNumber | (DEFAULT << SHIFT_VALUE_FOR_REFERENCE);\n\n    // ADCSRB = 0; // Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE);\n\n    // wait for single conversion to finish\n    loop_until_bit_is_clear(ADCSRA, ADSC);\n\n    // Get value\n    tUValue.UByte.LowByte = ADCL;\n    tUValue.UByte.HighByte = ADCH;\n    return tUValue.UWord;\n    //    return ADCL | (ADCH <<8); // needs 4 bytes more\n}\n/*\n * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h.\n */\nuint16_t readADCChannelWithReference(uint8_t aADCChannelNumber, uint8_t aReference) {\n    WordUnionForADCUtils tUValue;\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n\n    // ADCSRB = 0; // Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE);\n\n    // wait for single conversion to finish\n    loop_until_bit_is_clear(ADCSRA, ADSC);\n\n    // Get value\n    tUValue.UByte.LowByte = ADCL;\n    tUValue.UByte.HighByte = ADCH;\n    return tUValue.UWord;\n}\n\nuint16_t readADCChannelWithReferenceUsingInternalReference(uint8_t aADCChannelNumber) {\n    WordUnionForADCUtils tUValue;\n    ADMUX = aADCChannelNumber | (INTERNAL << SHIFT_VALUE_FOR_REFERENCE);\n\n    // ADCSRB = 0; // Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE);\n\n    // wait for single conversion to finish\n    loop_until_bit_is_clear(ADCSRA, ADSC);\n\n    // Get value\n    tUValue.UByte.LowByte = ADCL;\n    tUValue.UByte.HighByte = ADCH;\n    return tUValue.UWord;\n}\n/*\n * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h.\n * Does NOT restore ADMUX after reading\n */\nuint16_t waitAndReadADCChannelWithReference(uint8_t aADCChannelNumber, uint8_t aReference) {\n    checkAndWaitForReferenceAndChannelToSwitch(aADCChannelNumber, aReference);\n    return readADCChannelWithReference(aADCChannelNumber, aReference);\n}\n\n/*\n * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h.\n * Restores ADMUX after reading\n */\nuint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t aADCChannelNumber, uint8_t aReference) {\n    uint8_t tOldADMUX = checkAndWaitForReferenceAndChannelToSwitch(aADCChannelNumber, aReference);\n    uint16_t tResult = readADCChannelWithReference(aADCChannelNumber, aReference);\n    checkAndWaitForReferenceAndChannelToSwitch(tOldADMUX & MASK_FOR_ADC_CHANNELS, tOldADMUX >> SHIFT_VALUE_FOR_REFERENCE);\n    return tResult;\n}\n\n/*\n * To prepare reference and ADMUX for next measurement\n */\nvoid setADCChannelAndReferenceForNextConversion(uint8_t aADCChannelNumber, uint8_t aReference) {\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n}\n\n/*\n * 100 kOhm requires < 100 us, 1 MOhm requires 120 us S&H switching time\n */\nvoid setADCChannelForNextConversionAndWaitUsingInternalReference(uint8_t aADCChannelNumber) {\n    ADMUX = aADCChannelNumber | (INTERNAL << SHIFT_VALUE_FOR_REFERENCE);\n    delayMicroseconds(120); // experimental value is <= 1100 us for Nano board\n}\n\nvoid setADCChannelForNextConversionAndWaitUsingDefaultReference(uint8_t aADCChannelNumber) {\n    ADMUX = aADCChannelNumber | (DEFAULT << SHIFT_VALUE_FOR_REFERENCE);\n    delayMicroseconds(120); // experimental value is <= 1100 us for Nano board\n}\n\n/*\n * @return original ADMUX register content for optional later restoring values\n * All experimental values are acquired by using the ADCSwitchingTest example from this library\n */\nuint8_t checkAndWaitForReferenceAndChannelToSwitch(uint8_t aADCChannelNumber, uint8_t aReference) {\n    uint8_t tOldADMUX = ADMUX;\n    /*\n     * Must wait >= 7 us if reference has to be switched from 1.1 volt/INTERNAL to VCC/DEFAULT (seen on oscilloscope)\n     * This is done after the 2 ADC clock cycles required for Sample & Hold :-)\n     *\n     * Must wait >= 7600 us for Nano board  >= 6200 for Uno board if reference has to be switched from VCC/DEFAULT to 1.1 volt/INTERNAL\n     * Must wait >= 200 us if channel has to be switched to 1.1 volt internal channel if S&H was at 5 Volt\n     */\n    uint8_t tNewReference = (aReference << SHIFT_VALUE_FOR_REFERENCE);\n    ADMUX = aADCChannelNumber | tNewReference;\n#if defined(INTERNAL2V56)\n    if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && (aReference == INTERNAL || aReference == INTERNAL2V56)) {\n#else\n    if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && aReference == INTERNAL) {\n#endif\n#if defined(LOCAL_DEBUG)\n        Serial.println(F(\"Switch from DEFAULT to INTERNAL\"));\n#endif\n        /*\n         * Switch reference from DEFAULT to INTERNAL\n         */\n        delayMicroseconds(8000); // experimental value is >= 7600 us for Nano board and 6200 for Uno board\n    } else if ((tOldADMUX & ADC_CHANNEL_MUX_MASK) != aADCChannelNumber) {\n        if (aADCChannelNumber == ADC_1_1_VOLT_CHANNEL_MUX) {\n            /*\n             * Internal 1.1 Volt channel requires  <= 200 us for Nano board\n             */\n            delayMicroseconds(350); // 350 was ok and 300 was too less for UltimateBatteryTester - result was 226 instead of 225\n        } else {\n            /*\n             * 100 kOhm requires < 100 us, 1 MOhm requires 120 us S&H switching time\n             */\n            delayMicroseconds(120); // experimental value is <= 1100 us for Nano board\n        }\n    }\n    return tOldADMUX;\n}\n\n/*\n * Oversample and multiple samples only makes sense if you expect a noisy input signal\n * It does NOT increase the precision of the measurement, since the ADC has insignificant noise\n */\nuint16_t readADCChannelWithOversample(uint8_t aADCChannelNumber, uint8_t aOversampleExponent) {\n    return readADCChannelWithReferenceOversample(aADCChannelNumber, DEFAULT, aOversampleExponent);\n}\n\n/*\n * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h.\n */\nuint16_t readADCChannelWithReferenceOversample(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent) {\n    uint16_t tSumValue = 0;\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n\n    ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE);\n\n    uint8_t tCount = _BV(aOversampleExponent);\n    for (uint8_t i = 0; i < tCount; i++) {\n        /*\n         * wait for free running conversion to finish.\n         * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.\n         */\n        loop_until_bit_is_set(ADCSRA, ADIF);\n\n        ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished\n        // Add value\n        tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here\n        // tSumValue += (ADCH << 8) | ADCL; // this does NOT work!\n    }\n    ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)\n    // return rounded value\n    return ((tSumValue + (tCount >> 1)) >> aOversampleExponent);\n}\n\n/*\n * Use ADC_PRESCALE32 which gives 26 us conversion time and good linearity for 16 MHz Arduino\n */\nuint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent) {\n    uint16_t tSumValue = 0;\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n\n    ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE32);\n\n    uint8_t tCount = _BV(aOversampleExponent);\n    for (uint8_t i = 0; i < tCount; i++) {\n        /*\n         * wait for free running conversion to finish.\n         * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.\n         */\n        loop_until_bit_is_set(ADCSRA, ADIF);\n\n        ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished\n        // Add value\n        tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here\n        // tSumValue += (ADCH << 8) | ADCL; // this does NOT work!\n    }\n    ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)\n    return ((tSumValue + (tCount >> 1)) >> aOversampleExponent);\n}\n\n/*\n * Returns sum of all sample values\n * Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino by ADC_PRESCALE (=ADC_PRESCALE128) in ADCUtils.h.\n * @ param aNumberOfSamples If > 64 an overflow may occur.\n */\nuint16_t readADCChannelMultiSamplesWithReference(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples) {\n    uint16_t tSumValue = 0;\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n\n    ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE);\n\n    for (uint8_t i = 0; i < aNumberOfSamples; i++) {\n        /*\n         * wait for free running conversion to finish.\n         * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.\n         */\n        loop_until_bit_is_set(ADCSRA, ADIF);\n\n        ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished\n        // Add value\n        tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here\n        // tSumValue += (ADCH << 8) | ADCL; // this does NOT work!\n    }\n    ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)\n    return tSumValue;\n}\n\n/*\n * Returns sum of all sample values\n * Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino for ADC_PRESCALE128 in ADCUtils.h.\n * @ param aPrescale can be one of ADC_PRESCALE2, ADC_PRESCALE4, 8, 16, 32, 64, 128.\n *                   ADC_PRESCALE32 is recommended for excellent linearity and fast readout of 26 microseconds\n * @ param aNumberOfSamples If > 16k an overflow may occur.\n */\nuint32_t readADCChannelMultiSamplesWithReferenceAndPrescaler(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aPrescale,\n        uint16_t aNumberOfSamples) {\n    uint32_t tSumValue = 0;\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n\n    ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | aPrescale);\n\n    for (uint16_t i = 0; i < aNumberOfSamples; i++) {\n        /*\n         * wait for free running conversion to finish.\n         * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.\n         */\n        loop_until_bit_is_set(ADCSRA, ADIF);\n\n        ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished\n        // Add value\n        tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here\n        // tSumValue += (ADCH << 8) | ADCL; // this does NOT work!\n    }\n    ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)\n    return tSumValue;\n}\n\n/*\n * Returns sum of all sample values\n * Assumes, that channel and reference are still set to the right values\n * @ param aNumberOfSamples If > 16k an overflow may occur.\n */\nuint32_t readADCChannelMultiSamples(uint8_t aPrescale, uint16_t aNumberOfSamples) {\n    uint32_t tSumValue = 0;\n\n    ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | aPrescale);\n\n    for (uint16_t i = 0; i < aNumberOfSamples; i++) {\n        /*\n         * wait for free running conversion to finish.\n         * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.\n         */\n        loop_until_bit_is_set(ADCSRA, ADIF);\n\n        ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished\n        // Add value\n        tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here\n        // tSumValue += (ADCH << 8) | ADCL; // this does NOT work!\n    }\n    ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)\n    return tSumValue;\n}\n/*\n * use ADC_PRESCALE32 which gives 26 us conversion time and good linearity\n * @return the maximum value of aNumberOfSamples samples.\n */\nuint16_t readADCChannelWithReferenceMax(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples) {\n    uint16_t tADCValue = 0;\n    uint16_t tMaximum = 0;\n    ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);\n\n    ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.\n    // ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | ADC_PRESCALE32);\n\n    for (uint16_t i = 0; i < aNumberOfSamples; i++) {\n        /*\n         * wait for free running conversion to finish.\n         * Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.\n         */\n        loop_until_bit_is_set(ADCSRA, ADIF);\n\n        ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished\n        // check value\n        tADCValue = ADCL | (ADCH << 8);\n        if (tADCValue > tMaximum) {\n            tMaximum = tADCValue;\n        }\n    }\n    ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)\n    return tMaximum;\n}\n\n/*\n * use ADC_PRESCALE32 which gives 26 us conversion time and good linearity\n * @return the maximum value during aMicrosecondsToAquire measurement.\n */\nuint16_t readADCChannelWithReferenceMaxMicros(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire) {\n    uint16_t tNumberOfSamples = aMicrosecondsToAquire / 26;\n    return readADCChannelWithReferenceMax(aADCChannelNumber, aReference, tNumberOfSamples);\n}\n\n/*\n * aMaxRetries = 255 -> try forever\n * @return (tMax + tMin) / 2\n */\nuint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aDelay,\n        uint8_t aAllowedDifference, uint8_t aMaxRetries) {\n    int tValues[4]; // last value is in tValues[3]\n    int tMin;\n    int tMax;\n\n    /*\n     * Initialize first 4 values before checking\n     */\n    tValues[0] = readADCChannelWithReference(aADCChannelNumber, aReference);\n    for (int i = 1; i < 4; ++i) {\n        if (aDelay != 0) {\n            delay(aDelay); // Minimum is only 3 delays!\n        }\n        tValues[i] = readADCChannelWithReference(aADCChannelNumber, aReference);\n    }\n\n    do {\n        /*\n         * Get min and max of the last 4 values\n         */\n        tMin = READING_FOR_AREF;\n        tMax = 0;\n        for (uint_fast8_t i = 0; i < 4; ++i) {\n            if (tValues[i] < tMin) {\n                tMin = tValues[i];\n            }\n            if (tValues[i] > tMax) {\n                tMax = tValues[i];\n            }\n        }\n        /*\n         * check for terminating condition\n         */\n        if ((tMax - tMin) <= aAllowedDifference) {\n            break;\n        } else {\n            /*\n             * Get next value\n             */\n//            Serial.print(\"Difference=\");\n//            Serial.println(tMax - tMin);\n            // Move values to front\n            for (int i = 0; i < 3; ++i) {\n                tValues[i] = tValues[i + 1];\n            }\n            // and wait before getting next value\n            if (aDelay != 0) {\n                delay(aDelay);\n            }\n            tValues[3] = readADCChannelWithReference(aADCChannelNumber, aReference);\n        }\n        if (aMaxRetries != 255) {\n            aMaxRetries--;\n        }\n    } while (aMaxRetries > 0);\n\n#if defined(LOCAL_DEBUG)\n    if(aMaxRetries == 0) {\n        Serial.print(F(\"No 4 equal values for difference \"));\n        Serial.print(aAllowedDifference);\n        Serial.print(F(\" found \"));\n        Serial.print(tValues[0]);\n        Serial.print(' ');\n        Serial.print(tValues[1]);\n        Serial.print(' ');\n        Serial.print(tValues[2]);\n        Serial.print(' ');\n        Serial.println(tValues[3]);\n    } else {\n        Serial.print(aMaxRetries);\n        Serial.println(F(\" retries left\"));\n    }\n#endif\n\n    return (tMax + tMin) / 2;\n}\n\n/*\n * !!! Function without handling of switched reference and channel.!!!\n * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program.\n * !!! Resolution is only 20 millivolt !!!\n * Raw reading of 1.1 V is 225 at 5 V.\n * Raw reading of 1.1 V is 221 at 5.1 V.\n * Raw reading of 1.1 V is 214 at 5.25 V (+5 %).\n * Raw reading of 1.1 V is 204 at 5.5 V (+10 %).\n */\nfloat getVCCVoltageSimple(void) {\n    // use AVCC with (optional) external capacitor at AREF pin as reference\n    float tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);\n    return ((READING_FOR_AREF * 1.1 * 4) / tVCC);\n}\n\n/*\n * !!! Function without handling of switched reference and channel.!!!\n * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program.\n * !!! Resolution is only 20 millivolt !!!\n */\nuint16_t getVCCVoltageMillivoltSimple(void) {\n    // use AVCC with external capacitor at AREF pin as reference\n    uint16_t tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);\n    return (((uint32_t)READING_FOR_AREF * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCC);\n}\n\n/*\n * Gets the hypothetical 14 bit reading of VCC using 1.1 volt reference\n * Similar to getVCCVoltageMillivolt() * 1024 / 1100\n */\nuint16_t getVCCVoltageReadingFor1_1VoltReference(void) {\n    uint16_t tVCC = waitAndReadADCChannelWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT);\n    /*\n     * Do not switch back ADMUX to enable checkAndWaitForReferenceAndChannelToSwitch() to work correctly for the next measurement\n     */\n    return (((uint32_t)READING_FOR_AREF * READING_FOR_AREF) / tVCC);\n}\n\n/*\n * !!! Resolution is only 20 millivolt !!!\n */\nfloat getVCCVoltage(void) {\n    return (getVCCVoltageMillivolt() / 1000.0);\n}\n\n/*\n * Read value of 1.1 volt internal channel using VCC (DEFAULT) as reference.\n * Handles reference and channel switching by introducing the appropriate delays.\n * !!! Resolution is only 20 millivolt !!!\n * Raw reading of 1.1 V is 225 at 5 V.\n * Raw reading of 1.1 V is 221 at 5.1 V.\n * Raw reading of 1.1 V is 214 at 5.25 V (+5 %).\n * Raw reading of 1.1 V is 204 at 5.5 V (+10 %).\n */\nuint16_t getVCCVoltageMillivolt(void) {\n    uint16_t tVCC = waitAndReadADCChannelWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT);\n    /*\n     * Do not switch back ADMUX to enable checkAndWaitForReferenceAndChannelToSwitch() to work correctly for the next measurement\n     */\n    return (((uint32_t)READING_FOR_AREF * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCC);\n}\n\n/*\n * Does not set sVCCVoltageMillivolt\n */\nuint16_t printVCCVoltageMillivolt(Print *aSerial) {\n    aSerial->print(F(\"VCC=\"));\n    uint16_t tVCCVoltageMillivolt = getVCCVoltageMillivolt();\n    aSerial->print(tVCCVoltageMillivolt);\n    aSerial->println(\" mV\");\n    return tVCCVoltageMillivolt;\n}\n\nvoid readAndPrintVCCVoltageMillivolt(Print *aSerial) {\n    aSerial->print(F(\"VCC=\"));\n    sVCCVoltageMillivolt = getVCCVoltageMillivolt();\n    aSerial->print(sVCCVoltageMillivolt);\n    aSerial->println(\" mV\");\n}\n/*\n * !!! Function without handling of switched reference and channel.!!!\n * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program.\n * !!! Resolution is only 20 millivolt !!!\n */\nvoid readVCCVoltageSimple(void) {\n    // use AVCC with (optional) external capacitor at AREF pin as reference\n    float tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);\n    sVCCVoltage = (READING_FOR_AREF * (((float) ADC_INTERNAL_REFERENCE_MILLIVOLT) / 1000) * 4) / tVCC;\n}\n\n/*\n * !!! Function without handling of switched reference and channel.!!!\n * Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program.\n * !!! Resolution is only 20 millivolt !!!\n */\nvoid readVCCVoltageMillivoltSimple(void) {\n    // use AVCC with external capacitor at AREF pin as reference\n    uint16_t tVCCVoltageMillivoltRaw = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);\n    sVCCVoltageMillivolt = ((uint32_t)READING_FOR_AREF * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCCVoltageMillivoltRaw;\n}\n\n/*\n * !!! Resolution is only 20 millivolt !!!\n */\nvoid readVCCVoltage(void) {\n    sVCCVoltage = getVCCVoltageMillivolt() / 1000.0;\n}\n\n/*\n * Read value of 1.1 volt internal channel using VCC (DEFAULT) as reference.\n * Handles reference and channel switching by introducing the appropriate delays.\n * !!! Resolution is only 20 millivolt !!!\n * Sets also the sVCCVoltageMillivolt variable.\n */\nvoid readVCCVoltageMillivolt(void) {\n    uint16_t tVCCVoltageMillivoltRaw = waitAndReadADCChannelWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT);\n    /*\n     * Do not switch back ADMUX to enable checkAndWaitForReferenceAndChannelToSwitch() to work correctly for the next measurement\n     */\n    sVCCVoltageMillivolt = ((uint32_t)READING_FOR_AREF * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCCVoltageMillivoltRaw;\n}\n\n/*\n * Get voltage at ADC channel aADCChannelForVoltageMeasurement\n * aVCCVoltageMillivolt is assumed as reference voltage\n */\nuint16_t getVoltageMillivolt(uint16_t aVCCVoltageMillivolt, uint8_t aADCChannelForVoltageMeasurement) {\n    uint16_t tInputVoltageRaw = waitAndReadADCChannelWithReference(aADCChannelForVoltageMeasurement, DEFAULT);\n    return (aVCCVoltageMillivolt * (uint32_t) tInputVoltageRaw) / READING_FOR_AREF;\n}\n\n/*\n * Get voltage at ADC channel aADCChannelForVoltageMeasurement\n * Reference voltage VCC is determined just before\n */\nuint16_t getVoltageMillivolt(uint8_t aADCChannelForVoltageMeasurement) {\n    uint16_t tInputVoltageRaw = waitAndReadADCChannelWithReference(aADCChannelForVoltageMeasurement, DEFAULT);\n    return (getVCCVoltageMillivolt() * (uint32_t) tInputVoltageRaw) / READING_FOR_AREF;\n}\n\nuint16_t getVoltageMillivoltWith_1_1VoltReference(uint8_t aADCChannelForVoltageMeasurement) {\n    uint16_t tInputVoltageRaw = waitAndReadADCChannelWithReference(aADCChannelForVoltageMeasurement, INTERNAL);\n    return (ADC_INTERNAL_REFERENCE_MILLIVOLT * (uint32_t) tInputVoltageRaw) / READING_FOR_AREF;\n}\n\n/*\n * Return true if sVCCVoltageMillivolt is > 4.3 V and < 4.95 V\n * This does not really work for the UNO board, because it has no series Diode in the USB VCC\n * and therefore a very low voltage drop.\n */\nbool isVCCUSBPowered() {\n    readVCCVoltageMillivolt();\n    return (VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT < sVCCVoltageMillivolt\n            && sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT);\n}\n\n/*\n * Return true if sVCCVoltageMillivolt is > 4.3 V and < 4.95 V\n */\nbool isVCCUSBPowered(Print *aSerial) {\n    readVCCVoltageMillivolt();\n    aSerial->print(F(\"USB powered is \"));\n    bool tReturnValue;\n    if (VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT\n            < sVCCVoltageMillivolt&& sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT) {\n        tReturnValue = true;\n        aSerial->print(F(\"true \"));\n    } else {\n        tReturnValue = false;\n        aSerial->print(F(\"false \"));\n    }\n    printVCCVoltageMillivolt(aSerial);\n    return tReturnValue;\n}\n\n/*\n * It checks every 10 seconds for 6 times, and then returns once true if the undervoltage condition ( <3.4V ) still applies.\n * @ return true only once, when VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP (6) times voltage too low -> shutdown\n */\nbool isVCCUndervoltageMultipleTimes() {\n    /*\n     * Check VCC every VCC_CHECK_PERIOD_MILLIS - default is 10 seconds\n     */\n    if (millis() - sLastVCCCheckMillis >= VCC_CHECK_PERIOD_MILLIS) {\n        sLastVCCCheckMillis = millis();\n\n#  if defined(INFO)\n        readAndPrintVCCVoltageMillivolt(&Serial);\n#  else\n        readVCCVoltageMillivolt();\n#  endif\n\n        /*\n         * Do not check again if shutdown signaling (sVCCTooLowCounter >= 6) has happened\n         */\n        if (sVCCTooLowCounter < VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP) { // VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP = 6\n            if (sVCCVoltageMillivolt > VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) {\n                sVCCTooLowCounter = 0; // reset counter\n            } else {\n                /*\n                 * Voltage too low, wait VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP (6) times and then signal shut down.\n                 */\n                if (sVCCVoltageMillivolt < VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) {\n                    // emergency shutdown\n                    sVCCTooLowCounter = VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP;\n#  if defined(LOCAL_INFO)\n                    Serial.println(\n                            F(\n                                    \"Undervoltage < \" STR(VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) \" mV detected -> emergency shutdown\"));\n#  endif\n                } else {\n                    sVCCTooLowCounter++;\n#  if defined(LOCAL_INFO)\n                    Serial.print(sVCCVoltageMillivolt);\n                    Serial.print(F(\" mV < \" STR(VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT) \" mV -> undervoltage detected: \"));\n\n                    Serial.print(VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP - sVCCTooLowCounter);\n                    Serial.println(F(\" attempts left\"));\n#  endif\n                }\n                if (sVCCTooLowCounter == VCC_UNDERVOLTAGE_CHECKS_BEFORE_STOP) {\n                    /*\n                     * 6 times voltage too low -> return signal for shutdown etc.\n                     */\n                    return true;\n                }\n            }\n        }\n    }\n    return false;\n}\n\n/*\n * Return true if VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT (3 V) reached\n */\nbool isVCCUndervoltage() {\n    readVCCVoltageMillivolt();\n    return (sVCCVoltageMillivolt < VCC_UNDERVOLTAGE_THRESHOLD_MILLIVOLT);\n}\n\n/*\n * Return true if VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT (3 V) reached\n */\nbool isVCCEmergencyUndervoltage() {\n    readVCCVoltageMillivolt();\n    return (sVCCVoltageMillivolt < VCC_EMERGENCY_UNDERVOLTAGE_THRESHOLD_MILLIVOLT);\n}\n\nvoid resetCounterForVCCUndervoltageMultipleTimes() {\n    sVCCTooLowCounter = 0;\n}\n\n/*\n * Recommended VCC is 1.8 V to 5.5 V, absolute maximum VCC is 6.0 V.\n * Check for 5.25 V, because such overvoltage is quite unlikely to happen during regular operation.\n * Raw reading of 1.1 V is 225 at 5 V.\n * Raw reading of 1.1 V is 221 at 5.1 V.\n * Raw reading of 1.1 V is 214 at 5.25 V (+5 %).\n * Raw reading of 1.1 V is 204 at 5.5 V (+10 %).\n * Raw reading of 1.1 V is 1126000 / VCC_MILLIVOLT\n * @return true if 5 % overvoltage reached\n */\nbool isVCCOvervoltage() {\n    readVCCVoltageMillivolt();\n    return (sVCCVoltageMillivolt > VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT);\n}\nbool isVCCOvervoltageSimple() {\n    readVCCVoltageMillivoltSimple();\n    return (sVCCVoltageMillivolt > VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT);\n}\n\n// Version not using readVCCVoltageMillivoltSimple()\nbool isVCCTooHighSimple() {\n    ADMUX = ADC_1_1_VOLT_CHANNEL_MUX | (DEFAULT << SHIFT_VALUE_FOR_REFERENCE);\n// ADCSRB = 0; // Only active if ADATE is set to 1.\n// ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode\n    ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE128); //  128 -> 104 microseconds per ADC conversion at 16 MHz --- Arduino default\n// wait for single conversion to finish\n    loop_until_bit_is_clear(ADCSRA, ADSC);\n\n// Get value\n    uint16_t tRawValue = ADCL | (ADCH << 8);\n\n    return tRawValue < 1126000 / VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT;\n}\n\n/*\n * Temperature sensor is enabled by selecting the appropriate channel.\n * Different formula for 328P and 328PB!\n * !!! Function without handling of switched reference and channel.!!!\n * Use it ONLY if you only use INTERNAL reference (e.g. only call getTemperatureSimple()) in your program.\n */\nfloat getCPUTemperatureSimple(void) {\n#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)\n    return 0.0;\n#else\n    // use internal 1.1 volt as reference. 4 times oversample. Assume the signal has noise, but never verified :-(\n    uint16_t tTemperatureRaw = readADCChannelWithReferenceOversample(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL, 2);\n#if defined(LOCAL_DEBUG)\n    Serial.print(F(\"TempRaw=\"));\n    Serial.println(tTemperatureRaw);\n#endif\n\n#if defined(__AVR_ATmega328PB__)\n    tTemperatureRaw -= 245;\n    return (float)tTemperatureRaw;\n#elif defined(__AVR_ATtiny85__)\n    tTemperatureRaw -= 273; // 273 and 1.1666 are values from the datasheet\n    return (float)tTemperatureRaw / 1.1666;\n#else\n    tTemperatureRaw -= 317;\n    return (float) tTemperatureRaw / 1.22;\n#endif\n#endif\n}\n\n/*\n * Handles usage of 1.1 V reference and channel switching by introducing the appropriate delays.\n */\nfloat getTemperature(void) {\n    return getCPUTemperature();\n}\nfloat getCPUTemperature(void) {\n#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)\n    return 0.0;\n#else\n    // use internal 1.1 volt as reference\n    checkAndWaitForReferenceAndChannelToSwitch(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL);\n    return getCPUTemperatureSimple();\n#endif\n}\n\n#else // defined(ADC_UTILS_ARE_AVAILABLE)\n// Dummy definition of functions defined in ADCUtils to compile examples for non AVR platforms without errors\n/*\n * Persistent storage for VCC value\n */\nfloat sVCCVoltage;\nuint16_t sVCCVoltageMillivolt;\n\nuint16_t getVCCVoltageMillivoltSimple(void){\n    return 3300;\n}\n\nuint16_t readADCChannelWithReferenceOversample(uint8_t aChannelNumber __attribute__((unused)),\n        uint8_t aReference __attribute__((unused)), uint8_t aOversampleExponent __attribute__((unused))) {\n    return 0;\n}\nfloat getCPUTemperature() {\n    return 20.0;\n}\nfloat getVCCVoltage() {\n    return 3.3;\n}\n#endif // defined(ADC_UTILS_ARE_AVAILABLE)\n\n#if defined(LOCAL_DEBUG)\n#undef LOCAL_DEBUG\n#endif\n#if defined(LOCAL_INFO)\n#undef LOCAL_INFO\n#endif\n#endif // _ADC_UTILS_HPP\n"
  },
  {
    "path": "examples/AllProtocols/AllProtocols.ino",
    "content": "/*\n *  AllProtocols.cpp\n *\n *  Accepts 40 protocols concurrently\n *  If you specify F_INTERRUPTS to 20000 at line 86 (default is 15000) it supports LEGO + RCMM protocols, but disables PENTAX and GREE protocols.\n *  if you see performance issues, you can disable MERLIN Protocol at line 88.\n *\n *  Uses a callback function which is called every time a complete IR command was received.\n *  Prints data to LCD connected parallel at pin 4-9 or serial at pin A4, A5\n *\n *  Copyright (C) 2019-2022  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n#include \"PinDefinitionsAndMore.h\"\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#define IRMP_PROTOCOL_NAMES              1 // Enable protocol number mapping to protocol strings - needs some program memory ~ 420 bytes here\n#define IRMP_USE_COMPLETE_CALLBACK       1 // Enable callback functionality\n//#define NO_LED_FEEDBACK_CODE   // Activate this if you want to suppress LED feedback or if you do not have a LED. This saves 14 bytes code and 2 clock cycles per interrupt.\n\n#if __SIZEOF_INT__ == 4\n#define F_INTERRUPTS                     20000 // Instead of default 15000 to support LEGO + RCMM protocols\n#else\n//#define F_INTERRUPTS                     20000 // Instead of default 15000 to support LEGO + RCMM protocols, but this in turn disables PENTAX and GREE protocols :-(\n//#define IRMP_32_BIT                       1 // This enables MERLIN protocol, but decreases performance for AVR.\n#endif\n\n#include <irmpSelectAllProtocols.h>  // This enables all possible protocols\n//#define IRMP_SUPPORT_SIEMENS_PROTOCOL 1\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irmp.hpp>\n\nIRMP_DATA irmp_data;\n\n/*\n * Activate the type of LCD you use\n * Default is parallel LCD with 2 rows of 16 characters (1602).\n * Serial LCD has the disadvantage, that the first repeat is not detected,\n * because of the long lasting serial communication.\n */\n//#define USE_NO_LCD\n//#define USE_SERIAL_LCD\n/*\n * Define the size of your LCD\n */\n//#define USE_2004_LCD\n#if defined(USE_2004_LCD)\n// definitions for a 2004 LCD\n#define LCD_COLUMNS 20\n#define LCD_ROWS 4\n#else\n#define USE_1602_LCD\n// definitions for a 1602 LCD\n#define LCD_COLUMNS 16\n#define LCD_ROWS 2\n#endif\n\n#if defined(USE_SERIAL_LCD)\n#include \"LiquidCrystal_I2C.hpp\" // Use an up to date library version, which has the init method\nLiquidCrystal_I2C myLCD(0x27, LCD_COLUMNS, LCD_ROWS);  // set the LCD address to 0x27 for a 16 chars and 2 line display\n\n#elif !defined(USE_NO_LCD)\n#include \"LiquidCrystal.h\"\n#define USE_PARALLEL_LCD\n//LiquidCrystal myLCD(4, 5, 6, 7, 8, 9);\nLiquidCrystal myLCD(7, 8, 3, 4, 5, 6);\n#endif\n\n#if defined(USE_SERIAL_LCD) || defined(USE_PARALLEL_LCD)\n#define USE_LCD\n#  if defined(ADC_UTILS_ARE_AVAILABLE)\n// For cyclically display of VCC\n#include \"ADCUtils.hpp\"\n#define MILLIS_BETWEEN_VOLTAGE_PRINT 5000\nuint32_t volatile sMillisOfLastVoltagePrint;\n#  endif\n\nvoid printIRResultOnLCD();\nsize_t printHex(uint16_t aHexByteValue);\n#endif\n\nvoid handleReceivedIRData();\n\nbool volatile sIRMPDataAvailable = false;\n\nvoid setup()\n{\n    Serial.begin(115200);\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217) \\\n    || defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    irmp_init();\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at LED_BUILTIN\n    irmp_register_complete_callback_function(&handleReceivedIRData);\n\n    Serial.print(F(\"Ready to receive IR signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n#if defined(USE_SERIAL_LCD)\n    Serial.println(F(\"With serial LCD connection, the first repeat is not detected, because of the long lasting serial communication!\"));\n#endif\n\n#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)\n    getVCCVoltageMillivoltSimple(); // to initialize ADC mux and reference\n#endif\n\n#if defined(USE_SERIAL_LCD)\n    myLCD.init();\n    myLCD.clear();\n    myLCD.backlight(); // Switch backlight LED on\n#endif\n#if defined(USE_PARALLEL_LCD)\n    myLCD.begin(LCD_COLUMNS, LCD_ROWS); // This also clears display\n#endif\n\n#if defined(USE_LCD)\n    myLCD.setCursor(0, 0);\n    myLCD.print(F(\"IRMP all  v\" VERSION_IRMP));\n    myLCD.setCursor(0, 1);\n    myLCD.print(F(__DATE__));\n#endif\n}\n\nvoid loop()\n{\n    if (sIRMPDataAvailable)\n    {\n        sIRMPDataAvailable = false;\n\n        /*\n         * Serial output\n         * takes 2 milliseconds at 115200\n         */\n        irmp_result_print(&irmp_data);\n\n#if defined(USE_LCD)\n#  if defined(USE_SERIAL_LCD)\n        // This suppresses the receive of the 1. NEC repeat\n        disableIRTimerInterrupt(); // disable timer interrupt, since it disturbs the LCD serial output\n#  endif\n        printIRResultOnLCD();\n#  if defined(USE_SERIAL_LCD)\n        enableIRTimerInterrupt();\n#  endif\n#endif\n    }\n\n#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)\n    /*\n     * Periodically print VCC\n     */\n    if (millis() - sMillisOfLastVoltagePrint > MILLIS_BETWEEN_VOLTAGE_PRINT)\n    {\n        sMillisOfLastVoltagePrint = millis();\n        uint16_t tVCC = getVCCVoltageMillivoltSimple();\n\n        char tVoltageString[5];\n        dtostrf(tVCC / 1000.0, 4, 2, tVoltageString);\n        myLCD.setCursor(11, 0);\n        myLCD.print(tVoltageString);\n        myLCD.print('V');\n    }\n#endif\n}\n\n/*\n * Here we know, that data is available.\n * Since this function is executed in Interrupt handler context, make it short and do not use delay() etc.\n * In order to enable other interrupts you can call interrupts() (enable interrupt again) after getting data.\n */\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR handleReceivedIRData()\n#else\nvoid handleReceivedIRData()\n#endif\n{\n\n#if defined(USE_LCD) && defined(ADC_UTILS_ARE_AVAILABLE)\n    // reset voltage display timer\n    sMillisOfLastVoltagePrint = millis();\n#endif\n\n    /*\n     * Just print the data to Serial and LCD\n     */\n    irmp_get_data(&irmp_data);\n    sIRMPDataAvailable = true;\n}\n\n#if defined(USE_LCD)\n/*\n * LCD output for 1602 and 2004 LCDs\n * 40 - 55 Milliseconds per initial output for a 1602 LCD\n * for a 2004 LCD the initial clearing adds 55 ms.\n * The expander runs at 100 kHz :-(\n * 8 milliseconds for 8 bit; 10 ms for 16 bit code output\n * 3 milliseconds for repeat output\n *\n */\nvoid printIRResultOnLCD()\n{\n    static uint8_t sLastProtocolIndex;\n    static uint16_t sLastProtocolAddress;\n\n#  if (LCD_ROWS >= 4)\n    static uint8_t sLastCommandPrintPosition = 13;\n    const uint8_t tStartRow = 2;\n\n#  else\n    static uint16_t sLastCommand;\n    static uint8_t sLastCommandPrintPosition;\n\n    const uint8_t tStartRow = 0;\n    bool tDisplayWasCleared = false;\n#  endif\n\n    /*\n     * Print only if protocol or address has changed\n     */\n    if (sLastProtocolIndex != irmp_data.protocol || sLastProtocolAddress != irmp_data.address)\n    {\n        sLastProtocolIndex = irmp_data.protocol;\n        sLastProtocolAddress = irmp_data.address;\n#  if (LCD_ROWS >= 4)\n        // clear data lines\n        myLCD.setCursor(0, tStartRow);\n        myLCD.print(F(\"                    \"));\n        myLCD.setCursor(0, tStartRow + 1);\n        myLCD.print(F(\"                    \"));\n#  else\n        myLCD.clear();\n        tDisplayWasCleared = true;\n#  endif\n\n        /*\n         * Show protocol name\n         */\n        myLCD.setCursor(0, tStartRow);\n#  if defined(__AVR__)\n        const char *tProtocolStringPtr = (char*) pgm_read_word(&irmp_protocol_names[irmp_data.protocol]);\n        myLCD.print((__FlashStringHelper*) (tProtocolStringPtr));\n#  else\n        myLCD.print(irmp_protocol_names[irmp_data.protocol]);\n#  endif\n\n        /*\n         * Show address\n         */\n        myLCD.setCursor(0, tStartRow + 1);\n        myLCD.print(F(\"A=\"));\n        printHex(irmp_data.address);\n\n#  if (LCD_COLUMNS > 16)\n        /*\n         * Print prefix of command here, since it is constant string\n         */\n        myLCD.setCursor(9, tStartRow + 1);\n        myLCD.print(F(\"C=\"));\n#  endif\n    }\n    else\n    {\n        /*\n         * Show or clear repetition flag\n         */\n#  if (LCD_COLUMNS > 16)\n        myLCD.setCursor(18, tStartRow + 1);\n#  else\n        myLCD.setCursor(15, tStartRow + 1);\n#  endif\n        if (irmp_data.flags & IRMP_FLAG_REPETITION)\n        {\n            myLCD.print('R');\n            return; // Since it is a repetition, printed data has not changed\n        }\n        else\n        {\n            myLCD.print(' ');\n        }\n    }\n\n    /*\n     * Command prefix\n     */\n    uint16_t tCommand = irmp_data.command;\n\n#  if (LCD_COLUMNS <= 16)\n    // check if prefix position must change\n    if (tDisplayWasCleared || (sLastCommand > 0x100 && tCommand < 0x100) || (sLastCommand < 0x100 && tCommand > 0x100))\n    {\n        sLastCommand = tCommand;\n        /*\n         * Print prefix for 8/16 bit commands\n         */\n        if (tCommand >= 0x100)\n        {\n            sLastCommandPrintPosition = 9;\n        }\n        else\n        {\n            myLCD.setCursor(9, tStartRow + 1);\n            myLCD.print(F(\"C=\"));\n            sLastCommandPrintPosition = 11;\n        }\n    }\n#  endif\n\n    /*\n     * Command data\n     */\n    myLCD.setCursor(sLastCommandPrintPosition, tStartRow + 1);\n    printHex(tCommand);\n}\n\nsize_t printHex(uint16_t aHexByteValue) {\n    myLCD.print(F(\"0x\"));\n    size_t tPrintSize = 2;\n    if (aHexByteValue < 0x10 || (aHexByteValue > 0x100 && aHexByteValue < 0x1000)) {\n        myLCD.print('0'); // leading 0\n        tPrintSize++;\n    }\n    return myLCD.print(aHexByteValue, HEX) + tPrintSize;\n}\n#endif // defined(USE_LCD)\n"
  },
  {
    "path": "examples/AllProtocols/LiquidCrystal_I2C.h",
    "content": "//YWROBOT\n#ifndef LiquidCrystal_I2C_h\n#define LiquidCrystal_I2C_h\n\n#include <inttypes.h>\n#include \"Print.h\"\n#if !defined(USE_SOFT_I2C_MASTER) && !defined(USE_SOFT_WIRE)\n#include <Wire.h>\n#endif\n\n// commands\n#define LCD_CLEARDISPLAY 0x01\n#define LCD_RETURNHOME 0x02\n#define LCD_ENTRYMODESET 0x04\n#define LCD_DISPLAYCONTROL 0x08\n#define LCD_CURSORSHIFT 0x10\n#define LCD_FUNCTIONSET 0x20\n#define LCD_SETCGRAMADDR 0x40\n#define LCD_SETDDRAMADDR 0x80\n\n// flags for display entry mode\n#define LCD_ENTRYRIGHT 0x00\n#define LCD_ENTRYLEFT 0x02\n#define LCD_ENTRYSHIFTINCREMENT 0x01\n#define LCD_ENTRYSHIFTDECREMENT 0x00\n\n// flags for display on/off control\n#define LCD_DISPLAYON 0x04\n#define LCD_DISPLAYOFF 0x00\n#define LCD_CURSORON 0x02\n#define LCD_CURSOROFF 0x00\n#define LCD_BLINKON 0x01\n#define LCD_BLINKOFF 0x00\n\n// flags for display/cursor shift\n#define LCD_DISPLAYMOVE 0x08\n#define LCD_CURSORMOVE 0x00\n#define LCD_MOVERIGHT 0x04\n#define LCD_MOVELEFT 0x00\n\n// flags for function set\n#define LCD_8BITMODE 0x10\n#define LCD_4BITMODE 0x00\n#define LCD_2LINE 0x08\n#define LCD_1LINE 0x00\n#define LCD_5x10DOTS 0x04\n#define LCD_5x8DOTS 0x00\n\n// flags for backlight control\n#define LCD_BACKLIGHT 0x08\n#define LCD_NOBACKLIGHT 0x00\n\n#define En 0b00000100  // Enable bit\n#define Rw 0b00000010  // Read/Write bit\n#define Rs 0b00000001  // Register select bit\n\nclass LiquidCrystal_I2C : public Print {\npublic:\n  LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows);\n  void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS );\n  void clear();\n  void home();\n  void noDisplay();\n  void display();\n  void noBlink();\n  void blink();\n  void noCursor();\n  void cursor();\n  void scrollDisplayLeft();\n  void scrollDisplayRight();\n  void printLeft();\n  void printRight();\n  void leftToRight();\n  void rightToLeft();\n  void shiftIncrement();\n  void shiftDecrement();\n  void noBacklight();\n  void backlight();\n  void autoscroll();\n  void noAutoscroll();\n  void createChar(uint8_t, uint8_t[]);\n  void createChar(uint8_t location, const char *charmap);\n  // Example: \tconst char bell[8] PROGMEM = {B00100,B01110,B01110,B01110,B11111,B00000,B00100,B00000};\n\n  void setCursor(uint8_t, uint8_t);\n  size_t write(uint8_t);\n  void command(uint8_t);\n  void init();\n  void oled_init();\n\n////compatibility API function aliases\nvoid blink_on();\t\t\t\t\t\t// alias for blink()\nvoid blink_off();       \t\t\t\t\t// alias for noBlink()\nvoid cursor_on();      \t \t\t\t\t\t// alias for cursor()\nvoid cursor_off();      \t\t\t\t\t// alias for noCursor()\nvoid setBacklight(uint8_t new_val);\t\t\t\t// alias for backlight() and nobacklight()\nvoid load_custom_character(uint8_t char_num, uint8_t *rows);\t// alias for createChar()\nvoid printstr(const char[]);\n\n////Unsupported API functions (not implemented in this library)\nuint8_t status();\nvoid setContrast(uint8_t new_val);\nuint8_t keypad();\nvoid setDelay(int,int);\nvoid on();\nvoid off();\nuint8_t init_bargraph(uint8_t graphtype);\nvoid draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end);\nvoid draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end);\n\n\nprivate:\n  void init_priv();\n  void send(uint8_t, uint8_t);\n  void write4bits(uint8_t);\n  void expanderWrite(uint8_t);\n  void pulseEnable(uint8_t);\n  uint8_t _Addr;\n  uint8_t _displayfunction;\n  uint8_t _displaycontrol;\n  uint8_t _displaymode;\n  uint8_t _numlines;\n  bool _oled;\n  uint8_t _cols;\n  uint8_t _rows;\n  uint8_t _backlightval;\n};\n\n#endif\n"
  },
  {
    "path": "examples/AllProtocols/LiquidCrystal_I2C.hpp",
    "content": "// LiquidCrystal_I2C.hpp\n// Based on the work by DFRobot\n/*\n * Extensions made by AJ 2023\n * Removed Arduino 0.x support\n * Added SoftI2CMaste support, which drastically reduces program size.\n * Added OLED stuff\n * Added createChar() with PROGMEM input\n * Added fast timing\n */\n#ifndef _LIQUID_CRYSTAL_I2C_HPP\n#define _LIQUID_CRYSTAL_I2C_HPP\n\n#include \"Arduino.h\"\n\n#if defined(__AVR__) && !defined(USE_SOFT_I2C_MASTER) && __has_include(\"SoftI2CMasterConfig.h\")\n#define USE_SOFT_I2C_MASTER // must be before #include \"LiquidCrystal_I2C.hpp\"\n#endif\n\n#include \"LiquidCrystal_I2C.h\"\n#include <inttypes.h>\n\ninline size_t LiquidCrystal_I2C::write(uint8_t value) {\n    send(value, Rs);\n    return 1;\n}\n\n#if defined(USE_SOFT_I2C_MASTER)\n//#define USE_SOFT_I2C_MASTER_H_AS_PLAIN_INCLUDE\n#include \"SoftI2CMasterConfig.h\"    // Include configuration for sources\n#include \"SoftI2CMaster.h\"          // include sources\n#elif defined(USE_SOFT_WIRE)\n#define USE_SOFTWIRE_H_AS_PLAIN_INCLUDE\n#include \"SoftWire.h\"\n#endif\n\n#if defined(__AVR__)\n/*\n * The datasheet says: a command need > 37us to settle. Enable pulse must be > 450ns.\n * Use no delay for enable pulse after each command,\n * because the overhead of this library seems to be using the 37 us and 450 ns.\n * At least it works perfectly for all my LCD's connected to Uno, Nano etc.\n * and it saves a lot of time in realtime applications using LCD as display,\n * like https://github.com/ArminJo/Arduino-DTSU666H_PowerMeter\n */\n#define USE_FAST_TIMING\n#endif\n\n// When the display powers up, it is configured as follows:\n//\n// 1. Display clear\n// 2. Function set:\n//    DL = 1; 8-bit interface data\n//    N = 0; 1-line display\n//    F = 0; 5x8 dot character font\n// 3. Display on/off control:\n//    D = 0; Display off\n//    C = 0; Cursor off\n//    B = 0; Blinking off\n// 4. Entry mode set:\n//    I/D = 1; Increment by 1\n//    S = 0; No shift\n//\n// Note, however, that resetting the Arduino doesn't reset the LCD, so we\n// can't assume that its in that state when a sketch starts (and the\n// LiquidCrystal constructor is called).\n\nLiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t lcd_cols, uint8_t lcd_rows) {\n    _Addr = lcd_Addr;\n    _cols = lcd_cols;\n    _rows = lcd_rows;\n    _backlightval = LCD_NOBACKLIGHT;\n    _oled = false;\n}\n\nvoid LiquidCrystal_I2C::oled_init() {\n    _oled = true;\n    init_priv();\n}\n\nvoid LiquidCrystal_I2C::init() {\n    init_priv();\n}\n\nvoid LiquidCrystal_I2C::init_priv() {\n#if defined(USE_SOFT_I2C_MASTER)\n    i2c_init();\n#else\n    Wire.begin();\n#endif\n    _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;\n    begin(_cols, _rows);\n}\n\nvoid LiquidCrystal_I2C::begin(uint8_t cols __attribute__((unused)), uint8_t lines, uint8_t dotsize) {\n    if (lines > 1) {\n        _displayfunction |= LCD_2LINE;\n    }\n    _numlines = lines;\n\n    // for some 1 line displays you can select a 10 pixel high font\n    if ((dotsize != 0) && (lines == 1)) {\n        _displayfunction |= LCD_5x10DOTS;\n    }\n\n    // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!\n    // according to datasheet, we need at least 40ms after power rises above 2.7V\n    // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50\n    delay(50);\n\n    // Now we pull both RS and R/W low to begin commands\n    expanderWrite(_backlightval);\t// reset expander and turn backlight off (Bit 8 =1)\n    delay(1000);\n\n    //put the LCD into 4 bit mode\n    // this is according to the hitachi HD44780 datasheet\n    // figure 24, pg 46\n\n    // we start in 8bit mode, try to set 4 bit mode\n    write4bits(0x03 << 4);\n    delayMicroseconds(4500); // wait min 4.1ms\n\n    // second try\n    write4bits(0x03 << 4);\n    delayMicroseconds(4500); // wait min 4.1ms\n\n    // third go!\n    write4bits(0x03 << 4);\n    delayMicroseconds(150);\n\n    // finally, set to 4-bit interface\n    write4bits(0x02 << 4);\n\n    // set # lines, font size, etc.\n    command(LCD_FUNCTIONSET | _displayfunction);\n\n    // turn the display on with no cursor or blinking default\n    _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;\n    display();\n\n    // clear it off\n    clear();\n\n    // Initialize to default text direction (for roman languages)\n    _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;\n\n    // set the entry mode\n    command(LCD_ENTRYMODESET | _displaymode);\n\n    home();\n\n}\n\n/********** high level commands, for the user! */\nvoid LiquidCrystal_I2C::clear() {\n    command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero\n#if defined(USE_FAST_TIMING)\n    delayMicroseconds(1500);  // this command takes a long time! // AJ 20.9.23 1200 is too short for my 2004 LCD's, 1400 is OK\n#else\n    delayMicroseconds(2000);  // this command takes a long time!\n#endif\n    if (_oled)\n        setCursor(0, 0);\n}\n\nvoid LiquidCrystal_I2C::home() {\n    command(LCD_RETURNHOME);  // set cursor position to zero\n    delayMicroseconds(2000);  // this command takes a long time!\n}\n\nvoid LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row) {\n    int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };\n    if (row > _numlines) {\n        row = _numlines - 1;    // we count rows starting w/0\n    }\n    command(LCD_SETDDRAMADDR | (col + row_offsets[row]));\n}\n\n// Turn the display on/off (quickly)\nvoid LiquidCrystal_I2C::noDisplay() {\n    _displaycontrol &= ~LCD_DISPLAYON;\n    command(LCD_DISPLAYCONTROL | _displaycontrol);\n}\nvoid LiquidCrystal_I2C::display() {\n    _displaycontrol |= LCD_DISPLAYON;\n    command(LCD_DISPLAYCONTROL | _displaycontrol);\n}\n\n// Turns the underline cursor on/off\nvoid LiquidCrystal_I2C::noCursor() {\n    _displaycontrol &= ~LCD_CURSORON;\n    command(LCD_DISPLAYCONTROL | _displaycontrol);\n}\nvoid LiquidCrystal_I2C::cursor() {\n    _displaycontrol |= LCD_CURSORON;\n    command(LCD_DISPLAYCONTROL | _displaycontrol);\n}\n\n// Turn on and off the blinking cursor\nvoid LiquidCrystal_I2C::noBlink() {\n    _displaycontrol &= ~LCD_BLINKON;\n    command(LCD_DISPLAYCONTROL | _displaycontrol);\n}\nvoid LiquidCrystal_I2C::blink() {\n    _displaycontrol |= LCD_BLINKON;\n    command(LCD_DISPLAYCONTROL | _displaycontrol);\n}\n\n// These commands scroll the display without changing the RAM\nvoid LiquidCrystal_I2C::scrollDisplayLeft(void) {\n    command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);\n}\nvoid LiquidCrystal_I2C::scrollDisplayRight(void) {\n    command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);\n}\n\n// This is for text that flows Left to Right\nvoid LiquidCrystal_I2C::leftToRight(void) {\n    _displaymode |= LCD_ENTRYLEFT;\n    command(LCD_ENTRYMODESET | _displaymode);\n}\n\n// This is for text that flows Right to Left\nvoid LiquidCrystal_I2C::rightToLeft(void) {\n    _displaymode &= ~LCD_ENTRYLEFT;\n    command(LCD_ENTRYMODESET | _displaymode);\n}\n\n// This will 'right justify' text from the cursor\nvoid LiquidCrystal_I2C::autoscroll(void) {\n    _displaymode |= LCD_ENTRYSHIFTINCREMENT;\n    command(LCD_ENTRYMODESET | _displaymode);\n}\n\n// This will 'left justify' text from the cursor\nvoid LiquidCrystal_I2C::noAutoscroll(void) {\n    _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;\n    command(LCD_ENTRYMODESET | _displaymode);\n}\n\n// Allows us to fill the first 8 CGRAM locations\n// with custom characters\nvoid LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {\n    location &= 0x7; // we only have 8 locations 0-7\n    command(LCD_SETCGRAMADDR | (location << 3));\n    for (int i = 0; i < 8; i++) {\n        write(charmap[i]);\n    }\n}\n\n//createChar with PROGMEM input\nvoid LiquidCrystal_I2C::createChar(uint8_t location, const char *charmap) {\n    location &= 0x7; // we only have 8 locations 0-7\n    command(LCD_SETCGRAMADDR | (location << 3));\n    for (int i = 0; i < 8; i++) {\n        write(pgm_read_byte_near(charmap++));\n    }\n}\n\n// Turn the (optional) backlight off/on\nvoid LiquidCrystal_I2C::noBacklight(void) {\n    _backlightval = LCD_NOBACKLIGHT;\n    expanderWrite(0);\n}\n\nvoid LiquidCrystal_I2C::backlight(void) {\n    _backlightval = LCD_BACKLIGHT;\n    expanderWrite(0);\n}\n\n/*********** mid level commands, for sending data/cmds */\n\ninline void LiquidCrystal_I2C::command(uint8_t value) {\n    send(value, 0);\n}\n\n/************ low level data pushing commands **********/\n\n// write either command or data\nvoid LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {\n    uint8_t highnib = value & 0xf0;\n    uint8_t lownib = (value << 4) & 0xf0;\n    write4bits((highnib) | mode);\n    write4bits((lownib) | mode);\n}\n\nvoid LiquidCrystal_I2C::write4bits(uint8_t value) {\n    expanderWrite(value);\n    pulseEnable(value);\n}\n\nvoid LiquidCrystal_I2C::expanderWrite(uint8_t _data) {\n#if defined(USE_SOFT_I2C_MASTER)\n    i2c_write_byte(_Addr << 1, _data | _backlightval);\n#else\n    Wire.beginTransmission(_Addr);\n    Wire.write((int )(_data) | _backlightval);\n    Wire.endTransmission();\n#endif\n}\n\nvoid LiquidCrystal_I2C::pulseEnable(uint8_t _data) {\n    expanderWrite(_data | En);\t// En high\n#if !defined(USE_FAST_TIMING)\n    delayMicroseconds(1);\t\t// enable pulse must be > 450ns // AJ 20.9.23 not required for my LCD's\n#endif\n    expanderWrite(_data & ~En);\t// En low\n#if !defined(USE_FAST_TIMING)\n    delayMicroseconds(50);      // commands need > 37us to settle // AJ 20.9.23 not required for my LCD's\n#endif\n}\n\n// Alias functions\n\nvoid LiquidCrystal_I2C::cursor_on() {\n    cursor();\n}\n\nvoid LiquidCrystal_I2C::cursor_off() {\n    noCursor();\n}\n\nvoid LiquidCrystal_I2C::blink_on() {\n    blink();\n}\n\nvoid LiquidCrystal_I2C::blink_off() {\n    noBlink();\n}\n\nvoid LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows) {\n    createChar(char_num, rows);\n}\n\nvoid LiquidCrystal_I2C::setBacklight(uint8_t new_val) {\n    if (new_val) {\n        backlight();\t\t// turn backlight on\n    } else {\n        noBacklight();\t\t// turn backlight off\n    }\n}\n\nvoid LiquidCrystal_I2C::printstr(const char c[]) {\n    //This function is not identical to the function used for \"real\" I2C displays\n    //it's here so the user sketch doesn't have to be changed\n    print(c);\n}\n\n// unsupported API functions\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\nvoid LiquidCrystal_I2C::off() {\n}\nvoid LiquidCrystal_I2C::on() {\n}\nvoid LiquidCrystal_I2C::setDelay(int cmdDelay, int charDelay) {\n}\nuint8_t LiquidCrystal_I2C::status() {\n    return 0;\n}\nuint8_t LiquidCrystal_I2C::keypad() {\n    return 0;\n}\nuint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype) {\n    return 0;\n}\nvoid LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end) {\n}\nvoid LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end) {\n}\nvoid LiquidCrystal_I2C::setContrast(uint8_t new_val) {\n}\n#pragma GCC diagnostic pop\n\n#endif // _LIQUID_CRYSTAL_I2C_HPP\n"
  },
  {
    "path": "examples/AllProtocols/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/Callback/Callback.ino",
    "content": "/*\n *  Callback.cpp\n *\n *  Uses a callback function which is called every time a complete IR command was received.\n *  This example additionally filters commands from a remote control named WM010 sending NEC commands\n *\n *  Copyright (C) 2019-2022  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n\n#define IRMP_PROTOCOL_NAMES         1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>\n#define IRMP_USE_COMPLETE_CALLBACK  1 // Enable callback functionality\n\n// Enables protocols manually\n//#define IRMP_SUPPORT_SIRCS_PROTOCOL      1\n#define IRMP_SUPPORT_NEC_PROTOCOL        1\n//#define IRMP_SUPPORT_SAMSUNG_PROTOCOL    1\n//#define IRMP_SUPPORT_KASEIKYO_PROTOCOL   1\n\n//#define IRMP_SUPPORT_JVC_PROTOCOL        1\n//#define IRMP_SUPPORT_NEC16_PROTOCOL      1\n//#define IRMP_SUPPORT_NEC42_PROTOCOL      1\n//#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL 1\n//#define IRMP_SUPPORT_DENON_PROTOCOL      1\n//#define IRMP_SUPPORT_RC5_PROTOCOL        1\n//#define IRMP_SUPPORT_RC6_PROTOCOL        1\n//#define IRMP_SUPPORT_IR61_PROTOCOL       1\n//#define IRMP_SUPPORT_GRUNDIG_PROTOCOL    1\n//#define IRMP_SUPPORT_SIEMENS_PROTOCOL    1\n//#define IRMP_SUPPORT_NOKIA_PROTOCOL      1\n\n/*\n * After setting the modifiers we can include the code.\n */\n#include <irmp.hpp>\n\nIRMP_DATA irmp_data;\n\n#define PROCESS_IR_RESULT_IN_MAIN_LOOP\n#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32)\nvolatile bool sIRDataJustReceived = false;\n#endif\n\nvoid handleReceivedIRData();\nvoid evaluateIRCommand(uint16_t aAddress, uint16_t aCommand, uint8_t aFlags);\n\nvoid setup()\n{\n    pinMode(LED_BUILTIN, OUTPUT);\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    //Enable auto resume and pass it the address of your extra buffer\n    irmp_init();\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at LED_BUILTIN\n    irmp_register_complete_callback_function(&handleReceivedIRData);\n\n    Serial.print(F(\"Ready to receive IR signals  of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n}\n\nvoid loop()\n{\n#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32)\n    if (sIRDataJustReceived)\n    {\n        sIRDataJustReceived = false;\n        evaluateIRCommand(irmp_data.address, irmp_data.command, irmp_data.flags);\n        irmp_result_print(&irmp_data); // this is not allowed in ISR context for any kind of RTOS\n    }\n#endif\n    /*\n     * Put your code here\n     */\n}\n\n/*\n * Callback function\n * Here we know, that data is available.\n * This function is executed in ISR (Interrupt Service Routine) context (interrupts are blocked here).\n * Make it short and fast and keep in mind, that you can not use delay(), prints longer than print buffer size etc.,\n * because they require interrupts enabled to return.\n * In order to enable other interrupts you can call sei() (enable interrupt again) after evaluating/copying data.\n * Good practice, but somewhat more complex, is to copy relevant data and signal receiving to main loop.\n */\n#if defined(ESP8266) || defined(ESP32)\nIRAM_ATTR\n#endif\nvoid handleReceivedIRData()\n{\n    irmp_get_data(&irmp_data);\n#if !defined(ARDUINO_ARCH_MBED)\n    interrupts(); // enable interrupts\n#endif\n\n#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32)\n    /*\n     * Set flag to trigger printing of results in main loop,\n     * since printing should not be done in a callback function\n     * running in ISR (Interrupt Service Routine) context where interrupts are disabled.\n     */\n    sIRDataJustReceived = true;\n#else\n    interrupts(); // enable interrupts\n    evaluateIRCommand(irmp_data.address, irmp_data.command, irmp_data.flags);\n    irmp_result_print(&irmp_data); // This is not recommended, but simpler and works, except for any kind of RTOS like on ESP and MBED.\n#endif\n}\n\nvoid evaluateIRCommand(uint16_t aAddress, uint16_t aCommand, uint8_t aFlags)\n{\n    /*\n     * Filter for commands from the WM010 IR Remote\n     */\n    if (aAddress == 0xF708)\n    {\n        /*\n         * Skip repetitions of command\n         */\n        if (!(aAddress & IRMP_FLAG_REPETITION))\n        {\n            /*\n             * Evaluation of IR command\n             */\n            switch (aAddress)\n            {\n            case 0x48:\n                digitalWrite(LED_BUILTIN, HIGH);\n                break;\n            case 0x0B:\n                digitalWrite(LED_BUILTIN, LOW);\n                break;\n            default:\n                break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/Callback/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/IRDispatcherDemo/DemoIRCommandMapping.h",
    "content": "/*\n * DemoIRCommandMapping.h\n *\n * Contains IR remote button codes, strings, and the mapping of codes to functions to call by the dispatcher\n *\n *  Copyright (C) 2019-2026  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#ifndef _IR_COMMAND_MAPPING_H\n#define _IR_COMMAND_MAPPING_H\n\n#include <Arduino.h>\n\n#include \"IRCommandDispatcher.h\" // IRToCommandMappingStruct, IR_COMMAND_FLAG_BLOCKING etc. are defined here\n\n/*\n * !!! Choose your remote !!!\n */\n//#define USE_KEYES_REMOTE_CLONE With number pad and direction control swapped, will be taken as default\n//#define USE_KEYES_REMOTE\n#if !defined(USE_KEYES_REMOTE) && !defined(USE_KEYES_REMOTE_CLONE)\n#define USE_KEYES_REMOTE_CLONE // the one you can buy at Aliexpress\n#endif\n\n#if (defined(USE_KEYES_REMOTE) && defined(USE_KEYES_REMOTE_CLONE))\n#error \"Please choose only one remote for compile\"\n#endif\n\n#if defined(USE_KEYES_REMOTE_CLONE)\n#define IR_REMOTE_NAME \"KEYES_CLONE\"\n// Codes for the KEYES CLONE remote control with 17 keys with number pad above direction control\n#define IR_ADDRESS 0x00\n\n#define IR_UP    0x18\n#define IR_DOWN  0x52\n#define IR_RIGHT 0x5A\n#define IR_LEFT  0x08\n#define IR_OK    0x1C\n\n#define IR_1    0x45\n#define IR_2    0x46\n#define IR_3    0x47\n#define IR_4    0x44\n#define IR_5    0x40\n#define IR_6    0x43\n#define IR_7    0x07\n#define IR_8    0x15\n#define IR_9    0x09\n#define IR_0    0x19\n\n#define IR_STAR 0x16\n#define IR_HASH 0x0D\n/*\n * SECOND:\n * IR button to command mapping for better reading. IR buttons should only referenced here.\n */\n#define COMMAND_ON              IR_UP\n#define COMMAND_OFF             IR_DOWN\n#define COMMAND_INCREASE_BLINK  IR_RIGHT\n#define COMMAND_DECREASE_BLINK  IR_LEFT\n\n#define COMMAND_START           IR_OK\n#define COMMAND_STOP            IR_HASH\n#define COMMAND_RESET           IR_STAR\n#define COMMAND_BLINK           IR_0\n#define COMMAND_TONE1           IR_1\n\n#define COMMAND_TONE2           IR_2\n#define COMMAND_TONE3           IR_3\n//#define            IR_4\n//#define            IR_5\n//#define            IR_6\n//#define            IR_7\n//#define            IR_8\n//#define            IR_9\n\n#endif\n\n#if defined(USE_KEYES_REMOTE)\n#define IR_REMOTE_NAME \"KEYES\"\n/*\n * FIRST:\n * IR code to button mapping for better reading. IR codes should only referenced here.\n */\n// Codes for the KEYES remote control with 17 keys and direction control above number pad\n#define IR_ADDRESS 0x00\n\n#define IR_UP    0x46\n#define IR_DOWN  0x15\n#define IR_RIGHT 0x43\n#define IR_LEFT  0x44\n#define IR_OK    0x40\n\n#define IR_1    0x16\n#define IR_2    0x19\n#define IR_3    0x0D\n#define IR_4    0x0C\n#define IR_5    0x18\n#define IR_6    0x5E\n#define IR_7    0x08\n#define IR_8    0x1C\n#define IR_9    0x5A\n#define IR_0    0x52\n\n#define IR_STAR 0x42\n#define IR_HASH 0x4A\n\n/*\n * SECOND:\n * IR button to command mapping for better reading. IR buttons should only referenced here.\n */\n#define COMMAND_ON              IR_UP\n#define COMMAND_OFF             IR_DOWN\n#define COMMAND_INCREASE_BLINK  IR_RIGHT\n#define COMMAND_DECREASE_BLINK  IR_LEFT\n\n#define COMMAND_RESET           IR_OK\n#define COMMAND_STOP            IR_HASH\n#define COMMAND_STOP            IR_STAR\n#define COMMAND_BLINK           IR_0\n#define COMMAND_TONE2           IR_1\n\n#define COMMAND_TONE1           IR_2\n#define COMMAND_TONE2           IR_3\n#define COMMAND_TONE2           IR_4\n#define COMMAND_TONE2           IR_5\n#define COMMAND_TONE2           IR_6\n#define COMMAND_TONE2           IR_7\n#define COMMAND_TONE2           IR_8\n#define COMMAND_TONE2           IR_9\n#endif\n\n/*\n * THIRD:\n * Main mapping of commands to C functions\n */\n\n// Strings of commands for Serial output\nstatic const char LEDon[] PROGMEM =\"LED on\";\nstatic const char LEDoff[] PROGMEM =\"LED off\";\n\nstatic const char blink20times[] PROGMEM =\"blink 20 times\";\nstatic const char blinkStart[] PROGMEM =\"blink start\";\n\nstatic const char increaseBlink[] PROGMEM =\"increase blink frequency\";\nstatic const char decreaseBlink[] PROGMEM =\"decrease blink frequency\";\n\nstatic const char tone2200[] PROGMEM =\"tone 2200\";\nstatic const char tone1800[] PROGMEM =\"tone 1800\";\nstatic const char printMenu[] PROGMEM =\"printMenu\";\n\nstatic const char reset[] PROGMEM =\"reset\";\nstatic const char stop[] PROGMEM =\"stop\";\n\n/*\n * Main mapping array of commands to C functions and command strings\n * The macro COMMAND_STRING() removes the strings from memory, if USE_DISPATCHER_COMMAND_STRINGS is not enabled\n */\nconst struct IRToCommandMappingStruct IRMapping[] = { /**/\n{ COMMAND_BLINK, IR_COMMAND_FLAG_BLOCKING | IR_COMMAND_FLAG_BEEP, &doLedBlink20times, COMMAND_STRING(blink20times) }, /**/\n{ COMMAND_STOP, IR_COMMAND_FLAG_BLOCKING, &doStop, COMMAND_STRING(stop) }, /* */\n\n/*\n * Short commands that can always be executed, but must be able to terminate other blocking commands (only doLedBlink20times() in this example)\n */\n{ COMMAND_START, IR_COMMAND_FLAG_BLOCKING, &doLedBlinkStart, COMMAND_STRING(blinkStart) }, /**/\n{ COMMAND_ON, IR_COMMAND_FLAG_BLOCKING, &doLedOn, COMMAND_STRING(LEDon) }, /**/\n{ COMMAND_OFF, IR_COMMAND_FLAG_BLOCKING, &doLedOff, COMMAND_STRING(LEDoff) }, /**/\n\n/*\n * Short commands that can always be executed\n */\n{ COMMAND_TONE1, IR_COMMAND_FLAG_NON_BLOCKING, &doTone1800, COMMAND_STRING(tone1800) }, /* Lasts 200 ms and blocks receiving of repeats. tone() requires interrupts enabled */\n{ COMMAND_TONE3, IR_COMMAND_FLAG_NON_BLOCKING, &doPrintMenu, COMMAND_STRING(printMenu) }, /**/\n{ COMMAND_RESET, IR_COMMAND_FLAG_NON_BLOCKING, &doResetBlinkFrequency, COMMAND_STRING(reset) },\n\n/*\n * Repeatable short commands\n */\n{ COMMAND_TONE2, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doTone2200, COMMAND_STRING(tone2200) }, /* Lasts 50 ms and allows receiving of repeats */\n{ COMMAND_INCREASE_BLINK, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doIncreaseBlinkFrequency, COMMAND_STRING(increaseBlink) }, /**/\n{ COMMAND_DECREASE_BLINK, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doDecreaseBlinkFrequency, COMMAND_STRING(decreaseBlink) } };\n\n#endif // _IR_COMMAND_MAPPING_H\n"
  },
  {
    "path": "examples/IRDispatcherDemo/IRDispatcherDemo.ino",
    "content": "/*\n *  IRDispatcherDemo.cpp\n *\n *  Example how to use IRCommandDispatcher to receive IR commands and map them to different actions / functions by means of a mapping array.\n *\n *  Copyright (C) 2020-2026  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Choose the library to be used for IR receiving\n */\n//#define USE_TINY_IR_RECEIVER // Recommended and default, but only for NEC protocol!!! If disabled and IRMP_INPUT_PIN is defined, the IRMP library is used for decoding\n//#define USE_IRREMOTE_LIBRARY // The IRremote library is used for decoding\n//#define USE_IRMP_LIBRARY     // The IRMP library is used for decoding\n//#define DISPATCHER_IR_COMMAND_HAS_MORE_THAN_8_BIT // Enables mapping and dispatching of IR commands consisting of more than 8 bits. Saves up to 160 bytes program memory and 5 bytes RAM + 1 byte RAM per mapping entry.\n#define NO_LED_FEEDBACK_CODE   // We use LED_BUILTIN for command feedback and therefore cannot use is as IR receiving feedback\n#define INFO // To see some informative output of the IRCommandDispatcher library\n//#define DEBUG // To see some additional debug output of the IRCommandDispatcher library\n\n#include \"PinDefinitionsAndMore.h\" // Define macros for input and output pin etc.\n\n#if defined(INFO) || defined(DEBUG)\n#define USE_DISPATCHER_COMMAND_STRINGS // Enables the printing of command strings. Requires additional 2 bytes RAM for each command mapping. Requires program memory for strings, but saves snprintf() code (1.5k) if INFO or DEBUG is activated, which has no effect if snprintf() is also used in other parts of your program / libraries.\n#endif\n#if defined(TONE_PIN)\n#define DISPATCHER_BUZZER_FEEDBACK_PIN  TONE_PIN // The pin to be used for the optional 50 ms buzzer feedback before executing a command. Only available for TinyIR.\n#endif\n\n#if defined(USE_IRMP_LIBRARY)\n//Enable protocols for IRMP\n#define IRMP_SUPPORT_NEC_PROTOCOL         1 // this enables only one protocol\n//#define IRMP_SUPPORT_KASEIKYO_PROTOCOL    1\n//#define IRMP_ENABLE_PIN_CHANGE_INTERRUPT  // Enable interrupt functionality (not for all protocols) - requires around 376 additional bytes of program memory\n#endif // defined(USE_IRMP_LIBRARY)\n\nbool doBlink = false;\nuint16_t sBlinkDelay = 200;\n\n/*\n * The functions which are called by the IR commands.\n * They must be declared before including DemoIRCommandMapping.h, where the mapping to IR keys is defined.\n */\nvoid doPrintMenu();\nvoid doLedOn();\nvoid doLedOff();\nvoid doIncreaseBlinkFrequency();\nvoid doDecreaseBlinkFrequency();\nvoid doStop();\nvoid doResetBlinkFrequency();\nvoid doLedBlinkStart();\nvoid doLedBlink20times();\nvoid doTone1800();\nvoid doTone2200();\n\n/*\n * Set definitions and include IRCommandDispatcher library after the declaration of all commands required for mapping\n */\n#include \"DemoIRCommandMapping.h\" // must be included before IRCommandDispatcher.hpp to define IRMapping array, IR_ADDRESS etc.\n#include \"IRCommandDispatcher.hpp\" // This can optionally set USE_TINY_IR_RECEIVER\n\nvoid IRremoteTone(uint8_t aTonePin, unsigned int aFrequency, unsigned long aDuration);\n\nvoid setup()\n{\n    pinMode(LED_BUILTIN, OUTPUT);\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n#if defined(ESP8266)\n    Serial.println(); // to separate it from the internal boot output\n#endif\n\n    // Just to know which program is running on my Arduino\n#if defined(USE_TINY_IR_RECEIVER)\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing TinyIRReceiver library version \" VERSION_TINYIR));\n#elif defined(USE_IRREMOTE_LIBRARY)\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing IRremote library version \" VERSION_IRREMOTE));\n#elif defined(USE_IRMP_LIBRARY)\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing IRMP library version \" VERSION_IRMP));\n#endif\n\n#if !defined(ESP8266) && !defined(NRF5) && defined(TONE_PIN)\n    // play feedback tone before IRDispatcher.init(), because it kills the IR timer settings, which are made by init()\n    tone(TONE_PIN, 1000, 50);\n    delay(50);\n#endif\n\n    IRDispatcher.init(); // This calls the init function of the chosen library\n    IRDispatcher.printIRInfo(&Serial);\n\n    doPrintMenu();\n#if defined(DEBUG) && defined(SP)\n    Serial.print(F(\"SP=0x\"));\n    Serial.println(SP, HEX);\n#endif\n}\n\nvoid loop()\n{\n\n    IRDispatcher.checkAndRunSuspendedBlockingCommands();\n\n    if (doBlink)\n    {\n        digitalWrite(LED_BUILTIN, HIGH);\n        DELAY_AND_RETURN_IF_STOP(sBlinkDelay);\n        digitalWrite(LED_BUILTIN, LOW);\n        DELAY_AND_RETURN_IF_STOP(sBlinkDelay);\n    }\n\n    if (millis() - IRDispatcher.IRReceivedData.MillisOfLastCode > 120000)\n    {\n        // Short beep as remainder, if we did not receive any command in the last 2 minutes\n        IRDispatcher.IRReceivedData.MillisOfLastCode = millis();\n        doTone1800();\n#if defined(INFO)\n        Serial.println(F(\"2 minutes timeout\"));\n#endif\n    }\n\n//    delay(10);\n}\n\n/*\n * Menu for simple China Keyes or Keyes clone IR controls with number pad and direction control pad\n */\nvoid doPrintMenu()\n{\n    Serial.println();\n    Serial.println(F(\"Press 1 for tone 1800 Hz\"));\n    Serial.println(F(\"Press 2 for tone 2200 Hz\"));\n    Serial.println(F(\"Press 3 for this Menu\"));\n    Serial.println(F(\"Press 0 for LED blink 20 times\"));\n    Serial.println(F(\"Press UP for LED on\"));\n    Serial.println(F(\"Press DOWN for LED off\"));\n    Serial.println(F(\"Press OK for LED blink start\"));\n    Serial.println(F(\"Press RIGHT for LED increase blink frequency\"));\n    Serial.println(F(\"Press LEFT for LED decrease blink frequency\"));\n    Serial.println(F(\"Press STAR for reset blink frequency\"));\n    Serial.println(F(\"Press HASH for stop\"));\n    Serial.println();\n}\n/*\n * Here the actions that are matched to IR keys\n */\nvoid doLedOn()\n{\n    digitalWrite(LED_BUILTIN, HIGH);\n    doBlink = false;\n}\nvoid doLedOff()\n{\n    digitalWrite(LED_BUILTIN, LOW);\n    doBlink = false;\n}\nvoid doIncreaseBlinkFrequency()\n{\n    doBlink = true;\n    if (sBlinkDelay > 5)\n    {\n        sBlinkDelay -= sBlinkDelay / 4;\n    }\n}\nvoid doDecreaseBlinkFrequency()\n{\n    doBlink = true;\n    sBlinkDelay += sBlinkDelay / 4;\n}\nvoid doStop()\n{\n    doBlink = false;\n    digitalWrite(LED_BUILTIN, LOW);\n}\nvoid doResetBlinkFrequency()\n{\n    sBlinkDelay = 200;\n    digitalWrite(LED_BUILTIN, LOW);\n}\nvoid doLedBlinkStart()\n{\n    doBlink = true;\n}\n/*\n * This is a blocking function which checks for stop\n */\nvoid doLedBlink20times()\n{\n    for (int i = 0; i < 20; ++i)\n    {\n        digitalWrite(LED_BUILTIN, HIGH);\n        DELAY_AND_RETURN_IF_STOP(200);\n        digitalWrite(LED_BUILTIN, LOW);\n        DELAY_AND_RETURN_IF_STOP(200);\n    }\n}\n\n/*\n * Lasts 200 ms and blocks receiving of repeats. tone() requires interrupts enabled\n */\nvoid doTone1800()\n{\n#if defined(TONE_PIN)\n    IRremoteTone(TONE_PIN, 1800, 200);\n#endif\n}\n\n/*\n * Lasts 50 ms and allows receiving of repeats\n */\nvoid doTone2200()\n{\n#if defined(TONE_PIN)\n    IRremoteTone(TONE_PIN, 2200, 50);\n#endif\n}\n\n/*\n * Convenience IR library wrapper function for Arduino tone()\n * It currently disables the receiving of repeats\n * It is not part of the library because it statically allocates the tone interrupt vector 7.\n */\nvoid IRremoteTone(uint8_t aTonePin, unsigned int aFrequency, unsigned long aDuration)\n{\n    // IRMP_ENABLE_PIN_CHANGE_INTERRUPT currently disables the receiving of repeats\n#if defined(ESP8266) || defined(NRF5) || defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT) // tone on esp8266 works only once, then it disables IrReceiver.restartTimer() / timerConfigForReceive().\n    (void)  aTonePin;\n    (void)  aFrequency;\n    (void)  aDuration;\n    return;\n#else\n    /*\n     * Stop receiver, generate a single beep and start receiver again\n     */\n#  if defined(ESP32) || defined(USE_TINY_IR_RECEIVER )// ESP32 uses another timer for tone(), maybe other platforms (not tested yet) too.\n    tone(aTonePin, aFrequency, aDuration);\n#  else\n#    if defined(USE_IRREMOTE_LIBRARY)\n    IrReceiver.stopTimer(); // Stop timer consistently before calling tone() or other functions using the timer resource.\n#    else\n    storeIRTimer();\n#    endif\n    tone(aTonePin, aFrequency, 0);\n    if (aDuration == 0)\n    {\n        aDuration = 100;\n    }\n    delay(aDuration);\n    noTone(aTonePin);\n#    if defined(USE_IRREMOTE_LIBRARY)\n    IrReceiver.restartTimer(); // Restart IR timer after timer resource is no longer blocked.\n#    else\n    restoreIRTimer();\n#    endif\n#  endif\n#endif\n}\n"
  },
  {
    "path": "examples/IRDispatcherDemo/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/Interrupt/Interrupt.ino",
    "content": "/*\n *  Interrupt.cpp\n *\n *  Receives IR protocol data by using pin change interrupts and no polling by timer.\n *  !!! This WILL NOT work for all protocols.!!!\n *  Tested for NEC, Kaseiko, Denon, RC6, Samsung + Samsg32.\n *\n *  To disable one of them or to enable other protocols, specify this before the \"#include <irmp.hpp>\" line.\n *  If you get warnings of redefining symbols, just ignore them or undefine them first (see Interrupt example).\n *  The exact names can be found in the library file irmpSelectAllProtocols.h (see Callback example).\n *\n *  Copyright (C) 2019-2022  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n\n#define IRMP_PROTOCOL_NAMES              1 // Enable protocol number mapping to protocol strings - needs some FLASH. Must before #include <irmp*>\n#define IRMP_USE_COMPLETE_CALLBACK       1 // Enable callback functionality\n#define IRMP_ENABLE_PIN_CHANGE_INTERRUPT   // Enable interrupt functionality\n\n#define IRMP_SUPPORT_NEC_PROTOCOL               1       // NEC + APPLE + ONKYO  >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SAMSUNG_PROTOCOL           1       // Samsung + Samsg32    >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_KASEIKYO_PROTOCOL          1       // Kaseikyo             >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC6_PROTOCOL               1       // RC6 & RC6A           >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_DENON_PROTOCOL             1       // DENON, Sharp         >= 10000                 ~250 bytes\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irmp.hpp>\n\nIRMP_DATA irmp_data;\n#define PROCESS_IR_RESULT_IN_MAIN_LOOP\n#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32)\nvolatile bool sIRDataJustReceived = false;\n#endif\n\nvoid handleReceivedIRData();\nvoid evaluateIRCommand(uint16_t aAddress, uint16_t aCommand, uint8_t aFlags);\n\nvoid setup() {\n    Serial.begin(115200);\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    irmp_init();\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at LED_BUILTIN\n    irmp_register_complete_callback_function(&handleReceivedIRData);\n\n    Serial.print(F(\"Ready to receive IR signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n}\n\nvoid loop() {\n#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32)\n    if (sIRDataJustReceived) {\n        sIRDataJustReceived = false;\n        evaluateIRCommand(irmp_data.address, irmp_data.command, irmp_data.flags);\n        irmp_result_print(&irmp_data); // this is not allowed in ISR context for any kind of RTOS\n    }\n#endif\n    /*\n     * Put your code here\n     */\n}\n\n/*\n * Callback function\n * Here we know, that data is available.\n * This function is executed in ISR (Interrupt Service Routine) context (interrupts are blocked here).\n * Make it short and fast and keep in mind, that you can not use delay(), prints longer than print buffer size etc.,\n * because they require interrupts enabled to return.\n * In order to enable other interrupts you can call sei() (enable interrupt again) after evaluating/copying data.\n * Good practice, but somewhat more complex, is to copy relevant data and signal receiving to main loop.\n */\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR handleReceivedIRData()\n#else\nvoid handleReceivedIRData()\n#endif\n{\n    irmp_get_data(&irmp_data);\n#if defined(PROCESS_IR_RESULT_IN_MAIN_LOOP) || defined(ARDUINO_ARCH_MBED) || defined(ESP32)\n    /*\n     * Set flag to trigger printing of results in main loop,\n     * since printing should not be done in a callback function\n     * running in ISR (Interrupt Service Routine) context where interrupts are disabled.\n     */\n    sIRDataJustReceived = true;\n#else\n    interrupts(); // enable interrupts\n    evaluateIRCommand(irmp_data.address, irmp_data.command, irmp_data.flags);\n    irmp_result_print(&irmp_data); // This is not recommended, but simpler and works, except for any kind of RTOS like on ESP and MBED.\n#endif\n}\n\nvoid evaluateIRCommand(uint16_t aAddress, uint16_t aCommand, uint8_t aFlags)\n{\n    /*\n     * Filter for commands from the WM010 IR Remote\n     */\n    if (aAddress == 0xF708)\n    {\n        /*\n         * Skip repetitions of command\n         */\n        if (!(aAddress & IRMP_FLAG_REPETITION))\n        {\n            /*\n             * Evaluation of IR command\n             */\n            switch (aAddress)\n            {\n            case 0x48:\n                digitalWrite(LED_BUILTIN, HIGH);\n                break;\n            case 0x0B:\n                digitalWrite(LED_BUILTIN, LOW);\n                break;\n            default:\n                break;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/Interrupt/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/OneProtocol/OneProtocol.ino",
    "content": "/*\n *  OneProtocol.cpp\n *\n *  Receives IR protocol data. Only one protocol is activated.\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#include \"PinDefinitionsAndMore.h\" // Sets input pin to 3\n\n//#define NO_LED_FEEDBACK_CODE   // Activate this if you want to suppress LED feedback or if you do not have a LED. This saves 14 bytes code and 2 clock cycles per interrupt.\n\n#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n\n//#define IRMP_SUPPORT_SIRCS_PROTOCOL      1\n#define IRMP_SUPPORT_NEC_PROTOCOL        1  // includes APPLE and ONKYO protocols\n//#define IRMP_SUPPORT_SAMSUNG_PROTOCOL    1\n//#define IRMP_SUPPORT_KASEIKYO_PROTOCOL   1\n\n//#define IRMP_SUPPORT_JVC_PROTOCOL        1\n//#define IRMP_SUPPORT_NEC16_PROTOCOL      1\n//#define IRMP_SUPPORT_NEC42_PROTOCOL      1\n//#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL 1\n//#define IRMP_SUPPORT_DENON_PROTOCOL      1\n//#define IRMP_SUPPORT_RC5_PROTOCOL        1\n//#define IRMP_SUPPORT_RC6_PROTOCOL        1\n//#define IRMP_SUPPORT_IR61_PROTOCOL       1\n//#define IRMP_SUPPORT_GRUNDIG_PROTOCOL    1\n//#define IRMP_SUPPORT_SIEMENS_PROTOCOL    1\n//#define IRMP_SUPPORT_NOKIA_PROTOCOL      1\n\n// use F_INTERRUPTS=20000 for Support of LEGO and RCMM\n//#define F_INTERRUPTS                     20000   // interrupts per second, 50us, min: 10000, max: 20000, typ: 15000\n//#define IRMP_SUPPORT_LEGO_PROTOCOL       1       // LEGO Power RC        >= 20000  ~150 bytes\n//#define IRMP_SUPPORT_RCMM_PROTOCOL       1       // RCMM 12,24, or 32    >= 20000  ~150 bytes\n\n/*\n * Protocols which are not enabled in the irmpSelectAllProtocols.h for the AllProtocol example\n */\n//#define IRMP_SUPPORT_FAN_PROTOCOL        1       // FAN (ventilator)     >= 10000   ~50 bytes     conflicts with NUBERT\n//#define IRMP_SUPPORT_ORTEK_PROTOCOL      1       // ORTEK (Hama)         >= 10000  ~150 bytes     conflicts with FDC and NETBOX\n//#define IRMP_SUPPORT_ROOMBA_PROTOCOL     1       // iRobot Roomba        >= 10000  ~150 bytes     conflicts with RC6\n//#define IRMP_SUPPORT_RUWIDO_PROTOCOL     1       // RUWIDO, T-Home       >= 15000  ~550 bytes     conflicts with DENON\n//#define IRMP_SUPPORT_S100_PROTOCOL       1       // S100                 >= 10000  ~250 bytes     conflicts with RC5\n//#define IRMP_SUPPORT_ACP24_PROTOCOL      1       // ACP24                >= 10000  ~250 bytes     conflicts with DENON\n//#define IRMP_SUPPORT_PANASONIC_PROTOCOL  1       // PANASONIC Beamer     >= 10000  ~250 bytes     conflicts with KASEIKYO\n//#define IRMP_SUPPORT_RCII_PROTOCOL       1       // RCII T+A             >= 15000  ~250 bytes     conflicts with GRUNDIG and NOKIA\n/*\n * More protocol definitions can be found in irmpSelectAllProtocols.h\n */\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irmp.hpp>\n\nIRMP_DATA irmp_data;\n\nvoid setup()\n{\n    pinMode(LED_BUILTIN, OUTPUT);\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    // Wait until Serial Monitor is attached.\n    // Required for boards using USB code for Serial like Leonardo.\n    // Is void for USB Serial implementations using external chips e.g. a CH340.\n    while (!Serial)\n        ;\n    // !!! Program will not proceed if no Serial Monitor is attached !!!\n#endif\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    irmp_init();\n\n    Serial.print(F(\"Ready to receive IR signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at ALTERNATIVE_IR_FEEDBACK_LED_PIN\n}\n\nvoid loop()\n{\n    /*\n     * Check if new data available and get them\n     */\n    if (irmp_get_data(&irmp_data))\n    {\n        /*\n         * Here data is available -> evaluate IR command\n         */\n        switch (irmp_data.command)\n        {\n        case 0x48:\n        case 0x40:\n            Serial.println(F(\"Received right code and do something\"));\n            digitalWrite(LED_BUILTIN, HIGH);\n            break;\n        default:\n            break;\n        }\n\n        irmp_result_print(&irmp_data);\n    }\n}\n"
  },
  {
    "path": "examples/OneProtocol/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/RFProtocols/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/RFProtocols/RFProtocols.ino",
    "content": "/*\n *  RFProtocols.cpp\n *\n *  Receives 2 RF protocol (433 MHz) data.\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#include \"PinDefinitionsAndMore.h\" // Sets input pin to 3\n\n#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n\n#include <irmpSelectAllRFProtocols.h>  // This enables all possible RF protocols - currently 2 protocols\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irmp.hpp>\n\nIRMP_DATA irmp_data;\n\nvoid setup()\n{\n// initialize the digital pin as an output.\n    pinMode(LED_BUILTIN, OUTPUT);\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    // Wait until Serial Monitor is attached.\n    // Required for boards using USB code for Serial like Leonardo.\n    // Is void for USB Serial implementations using external chips e.g. a CH340.\n    while (!Serial)\n        ;\n    // !!! Program will not proceed if no Serial Monitor is attached !!!\n#endif\n\n    // Just to know which program is running on my Arduino\n#if defined(ESP8266)\n    Serial.println();\n#endif\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    irmp_init();\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at LED_BUILTIN - commented out, since we use built in LED in loop below\n\n    Serial.print(F(\"Ready to receive  RF (433 MHz) signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n}\n\nvoid loop()\n{\n    /*\n     * Check if new data available and get them\n     */\n    if (irmp_get_data(&irmp_data))\n    {\n        irmp_result_print(&irmp_data);\n    }\n}\n"
  },
  {
    "path": "examples/ReceiveAndSend/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/ReceiveAndSend/ReceiveAndSend.ino",
    "content": "/*\n *  ReceiveAndSend.cpp\n *\n *  Serves as a IR remote macro expander\n *  Receives Samsung32 protocol and on receiving a specified input frame,\n *  it sends multiple Samsung32 frames with appropriate delays in between.\n *  This serves as a Netflix-key emulation for my old Samsung H5273 TV.\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n// ATMEL ATTINY85\n// Piezo speaker must have a 270 ohm resistor in series for USB programming and running at the Samsung TV.\n// IR LED has a 270 ohm resistor in series.\n//                                                    +-\\/-+\n//                                   !RESET (5) PB5  1|    |8  Vcc\n// USB+ 3.6V Z-Diode, 1.5kOhm to VCC  Piezo (3) PB3  2|    |7  PB2 (2) TX Debug output\n// USB- 3.6V Z-Diode              IR Output (4) PB4  3|    |6  PB1 (1) Feedback LED\n//                                              GND  4|    |5  PB0 (0) IR Input\n//                                                    +----+\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone\n * -----------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0           4           3\n * ATtin167     9           8           5 // Digispark pro number schema\n * ATtin167     3           2           7\n * SAMD21       3           4           5\n * ESP8266      14 // D5    12 // D6    %\n * ESP32        15          4           %\n * BluePill     PA6         PA7         PA3\n * APOLLO3      11          12          5\n */\n\n#include <Arduino.h>\n\n/*\n * First define macros for input and output pin etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n//#define IR_OUTPUT_IS_ACTIVE_LOW\n#define IRSND_IR_FREQUENCY          38000\n\n#define IRMP_PROTOCOL_NAMES         1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n#define IRSND_PROTOCOL_NAMES        1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n\n#define IRMP_SUPPORT_SAMSUNG_PROTOCOL     1\n#define IRSND_SUPPORT_SAMSUNG_PROTOCOL    1\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#define USE_ONE_TIMER_FOR_IRMP_AND_IRSND // otherwise we get an error on AVR platform: redefinition of 'void __vector_8()\n#include <irmp.hpp>\n#include <irsnd.hpp>\n\nIRMP_DATA irmp_data;\nIRMP_DATA irsnd_data;\n\nvoid sendSamsungSmartHubMacro(bool aDoSelect);\nvoid IRSendWithDelay(uint16_t aCommand, uint16_t aDelayMillis);\n\nvoid setup()\n{\n    pinMode(LED_BUILTIN, OUTPUT);\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n#if defined(ESP8266)\n    Serial.println(); // to separate it from the internal boot output\n#endif\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    // tone before IR setup, since it kills the IR timer settings\n    tone(TONE_PIN, 2200);\n    digitalWrite(LED_BUILTIN, HIGH);\n    delay(400);\n    digitalWrite(LED_BUILTIN, LOW);\n    noTone(TONE_PIN);\n\n    irmp_init();\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at LED_BUILTIN for receive and send\n\n    irsnd_init();\n\n    Serial.print(F(\"Ready to receive IR signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n    Serial.println(F(\"Ready to send IR signals at pin \" STR(IRSND_OUTPUT_PIN)));\n\n    irsnd_data.protocol = IRMP_SAMSUNG32_PROTOCOL;\n    irsnd_data.address = 0x0707;\n    irsnd_data.flags = 1; // repeat frame 1 time\n}\n\nvoid loop()\n{\n    /*\n     * Check if new data available and get them\n     */\n    if (irmp_get_data(&irmp_data))\n    {\n        irmp_result_print(&irmp_data);\n\n        /*\n         * Here data is available -> evaluate IR command\n         */\n        switch (irmp_data.command)\n        {\n        case 0xB847: // The play key on the bottom of my Samsung remote\n            Serial.println(F(\"Play key detected, open Netflix\"));\n            sendSamsungSmartHubMacro(true);\n            break;\n\n        case 0xB54A: // The pause key on the bottom of my Samsung remote\n            Serial.println(F(\"Pause key detected, open SmartHub\"));\n            sendSamsungSmartHubMacro(false);\n            break;\n\n        default:\n            break;\n        }\n        // Flush repeats received\n        irmp_get_data(&irmp_data);\n    }\n}\n\nvoid IRSendWithDelay(uint16_t aCommand, uint16_t aDelayMillis)\n{\n    irsnd_data.command = aCommand;      // For my Samsung, the high byte is the inverse of the low byte, this is not checked here.\n    // true = wait for frame and trailing space/gap to end. This stores timer state and restores it after sending.\n    if (!irsnd_send_data(&irsnd_data, true))\n    {\n        Serial.println(F(\"Protocol not found\")); // name of protocol is printed by irsnd_data_print()\n    }\n    irsnd_data_print(&Serial,&irsnd_data);\n    delay(aDelayMillis);\n}\n\nbool sMacroWasCalledBefore = false;\n#define INITIAL_WAIT_TIME_APPS_READY_MILLIS 70000 // Time to let the TV load all software before Netflix can be started without an error\n#define INITIAL_WAIT_TIME_SMARTHUB_READY_MILLIS 20000 // Time to let the TV load all software before SmartHub manu can be displayed\n\n/*\n * This macro calls the last SmartHub application you selected manually\n *\n * @param aDoSelect - if true select the current app (needs longer initial wait time) else show smarthub menu\n *\n */\nvoid sendSamsungSmartHubMacro(bool aDoSelect)\n{\n    uint32_t tWaitTimeAfterBoot;\n    if (aDoSelect)\n    {\n        tWaitTimeAfterBoot = INITIAL_WAIT_TIME_APPS_READY_MILLIS;\n    }\n    else\n    {\n        tWaitTimeAfterBoot = INITIAL_WAIT_TIME_SMARTHUB_READY_MILLIS;\n    }\n\n    if (millis() < tWaitTimeAfterBoot)\n    {\n        // division by 1000 and printing requires much (8%) program memory\n        Serial.print(F(\"It is \"));\n        Serial.print(millis() / 1000);\n        Serial.print(F(\" seconds after boot, Samsung H5273 TV requires \"));\n        Serial.print(tWaitTimeAfterBoot / 1000);\n        Serial.println(F(\" seconds after boot to be ready for the command\"));\n\n        tone(TONE_PIN, 2200);\n        delay(100);\n        noTone(TONE_PIN);\n        delay(100);\n        tone(TONE_PIN, 2200);\n        delay(100);\n        noTone(TONE_PIN);\n\n        while (millis() < tWaitTimeAfterBoot)\n        {\n            delay(10); // blocking wait\n        }\n    }\n\n    // Do beep feedback for special key to be received\n    tone(TONE_PIN, 2200);\n    delay(200);\n    noTone(TONE_PIN);\n    irmp_init(); // restore timer for IR receive after using of tone\n\n    Serial.println(F(\"Wait for \\\"not supported\\\" to disappear\"));\n    delay(2000);\n\n    Serial.println(F(\"Start sending of Samsung IR macro\"));\n\n    IRSendWithDelay(0xE51A, 2000); // Menu and wait for the Menu to pop up\n\n    Serial.println(F(\"Wait for the menu to pop up\"));\n    if (!sMacroWasCalledBefore)\n    {\n        delay(2000); // wait additional time for the Menu load\n    }\n\n    for (uint_fast8_t i = 0; i < 4; ++i)\n    {\n        IRSendWithDelay(0x9E61, 250); // Down arrow. For my Samsung, the high byte of the command is the inverse of the low byte\n    }\n\n    IRSendWithDelay(0x9D62, 400); // Right arrow\n    for (uint_fast8_t i = 0; i < 2; ++i)\n    {\n        IRSendWithDelay(0x9E61, 250); // Down arrow\n    }\n\n    delay(250);\n    IRSendWithDelay(0x9768, 1); // Enter for SmartHub\n\n    if (aDoSelect)\n    {\n        Serial.println(F(\"Wait for SmartHub to show up, before entering current application\"));\n        delay(10000); // Wait not longer than 12 seconds, because smarthub menu then disappears\n        IRSendWithDelay(0x9768, 1); // Enter for last application (e.g. Netflix or Amazon)\n    }\n\n    sMacroWasCalledBefore = true;\n    Serial.println(F(\"Done\"));\n\n}\n"
  },
  {
    "path": "examples/ReceiveAndSendDynamicPins/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/ReceiveAndSendDynamicPins/ReceiveAndSendDynamicPins.ino",
    "content": "/*\n *  ReceiveAndSendDynamicPins.cpp\n *\n *  Example how to use pins specified at runtime.\n *\n *  Serves as a IR remote macro expander\n *  Receives Samsung32 protocol and on receiving a specified input frame, it sends multiple Samsung32 frames.\n *  This serves as a Netflix-key emulation for my old Samsung H5273 TV.\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n// ATMEL ATTINY85\n// Piezo speaker must have a 270 ohm resistor in series for USB programming and running at the Samsung TV.\n// IR LED has a 270 ohm resistor in series.\n//                                                    +-\\/-+\n//                                   !RESET (5) PB5  1|    |8  Vcc\n// USB+ 3.6V Z-Diode, 1.5kOhm to VCC  Piezo (3) PB3  2|    |7  PB2 (2) TX Debug output\n// USB- 3.6V Z-Diode              IR Output (4) PB4  3|    |6  PB1 (1) Feedback LED\n//                                              GND  4|    |5  PB0 (0) IR Input\n//                                                    +----+\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone\n * -----------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0           4           3\n * ATtin167     9           8           5 // Digispark pro number schema\n * ATtin167     3           2           7\n * SAMD21       3           4           5\n * ESP8266      14 // D5    12 // D6    %\n * ESP32        15          4           %\n * BluePill     PA6         PA7         PA3\n * APOLLO3      11          12          5\n */\n\n/*\n * Allow dynamic specification of input and output pins.\n * Requires additional 200 bytes program memory.\n * This must be first, it is used in PinDefinitionsAndMore.h\n */\n#define IRMP_IRSND_ALLOW_DYNAMIC_PINS\n\n#include <Arduino.h>\n\n/*\n * Set library modifiers first to set input and output pin etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n//#define IR_OUTPUT_IS_ACTIVE_LOW\n#define IRSND_IR_FREQUENCY          38000\n\n#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n#define IRSND_PROTOCOL_NAMES        1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n\n#define IRMP_SUPPORT_SAMSUNG_PROTOCOL   1\n#define IRSND_SUPPORT_SAMSUNG_PROTOCOL  1\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#define USE_ONE_TIMER_FOR_IRMP_AND_IRSND // otherwise we get an error on AVR platform: redefinition of 'void __vector_8()\n#include <irmp.hpp>\n#include <irsnd.hpp>\n\nIRMP_DATA irmp_data;\nuint8_t sIRMPInputPin;\nIRMP_DATA irsnd_data;\n\nvoid sendSamsungSmartHubMacro(bool aDoSelect);\nvoid IRSendWithDelay(uint16_t aCommand, uint16_t aDelayMillis);\n\nvoid setup()\n{\n    pinMode(LED_BUILTIN, OUTPUT);\n    Serial.begin(115200);\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n#if defined(ESP8266)\n    Serial.println(); // to separate it from the internal boot output\n#endif\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    tone(TONE_PIN, 2200);\n    digitalWrite(LED_BUILTIN, HIGH);\n    delay(400);\n    digitalWrite(LED_BUILTIN, LOW);\n    noTone(TONE_PIN);\n\n    /*\n     * Request pin number from user by serial monitor\n     */\n    Serial.println(F(\"Please enter pin number to use for receiving IR signals.\"));\n    while (Serial.available() == 0)\n    {\n        ; // Wait for user response\n    }\n    sIRMPInputPin = Serial.parseInt();\n    while (Serial.available())\n    {\n        Serial.read(); // read rest of line and CR/LF from buffer to enable for next input\n    }\n    Serial.print(F(\"Ready to receive IR signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \"));\n    Serial.println(sIRMPInputPin);\n    irmp_init(sIRMPInputPin, LED_BUILTIN); // Enable receive signal feedback at LED_BUILTIN for receive (and send)\n\n    Serial.println(F(\"Please enter pin number to use for sending IR signals.\"));\n    while (Serial.available() == 0)\n    {\n        ; // Wait for user response\n    }\n    uint8_t tIRSNDOutputPin = Serial.parseInt();\n    Serial.print(F(\"Ready to send IR signals at pin \"));\n    Serial.println(tIRSNDOutputPin);\n    irsnd_init(tIRSNDOutputPin); // feedback LED is specified at irmp_init()\n\n    irsnd_data.protocol = IRMP_SAMSUNG32_PROTOCOL;\n    irsnd_data.address = 0x0707;\n    irsnd_data.flags = 1; // repeat frame 1 time\n}\n\nvoid loop()\n{\n    /*\n     * Check if new data available and get them\n     */\n    if (irmp_get_data(&irmp_data))\n    {\n        irmp_result_print(&irmp_data);\n\n        /*\n         * Here data is available -> evaluate IR command\n         */\n        switch (irmp_data.command)\n        {\n        case 0xB847: // The play key on the bottom of my Samsung remote\n            Serial.println(F(\"Play key detected, open Netflix\"));\n            sendSamsungSmartHubMacro(true);\n            break;\n\n        case 0xB54A: // The pause key on the bottom of my Samsung remote\n            Serial.println(F(\"Pause key detected, open SmartHub\"));\n            sendSamsungSmartHubMacro(false);\n            break;\n\n        default:\n            break;\n        }\n        // Flush repeats received\n        irmp_get_data(&irmp_data);\n    }\n}\n\nvoid IRSendWithDelay(uint16_t aCommand, uint16_t aDelayMillis)\n{\n    irsnd_data.command = aCommand;\n    // true = wait for frame and trailing space/gap to end. This stores timer state and restores it after sending.\n    if (!irsnd_send_data(&irsnd_data, true))\n    {\n        Serial.println(F(\"Protocol not found\")); // name of protocol is printed by irsnd_data_print()\n    }\n    irsnd_data_print(&Serial,&irsnd_data);\n    delay(aDelayMillis);\n}\n\nbool sMacroWasCalledBefore = false;\n#define INITIAL_WAIT_TIME_APPS_READY_MILLIS 70000 // Time to let the TV load all software before Netflix can be started without an error\n#define INITIAL_WAIT_TIME_SMARTHUB_READY_MILLIS 20000 // Time to let the TV load all software before SmartHub manu can be displayed\n\n/*\n * This macro calls the last SmartHub application you selected manually\n *\n * @param aDoSelect - if true select the current app (needs longer initial wait time) else show smarthub menu\n *\n */\nvoid sendSamsungSmartHubMacro(bool aDoSelect)\n{\n    uint32_t tWaitTimeAfterBoot;\n    if (aDoSelect)\n    {\n        tWaitTimeAfterBoot = INITIAL_WAIT_TIME_APPS_READY_MILLIS;\n    }\n    else\n    {\n        tWaitTimeAfterBoot = INITIAL_WAIT_TIME_SMARTHUB_READY_MILLIS;\n    }\n\n    if (millis() < tWaitTimeAfterBoot)\n    {\n        // division by 1000 and printing requires much (8%) program memory\n        Serial.print(F(\"It is \"));\n        Serial.print(millis() / 1000);\n        Serial.print(F(\" seconds after boot, Samsung H5273 TV requires \"));\n        Serial.print(tWaitTimeAfterBoot / 1000);\n        Serial.println(F(\" seconds after boot to be ready for the command\"));\n\n        tone(TONE_PIN, 2200);\n        delay(100);\n        noTone(TONE_PIN);\n        delay(100);\n        tone(TONE_PIN, 2200);\n        delay(100);\n        noTone(TONE_PIN);\n\n        while (millis() < tWaitTimeAfterBoot)\n        {\n            delay(10); // blocking wait\n        }\n    }\n\n    // Do beep feedback for special key to be received\n    tone(TONE_PIN, 2200);\n    delay(200);\n    noTone(TONE_PIN);\n    irmp_init(sIRMPInputPin); // restore timer for IR receive after using of tone\n\n    Serial.println(F(\"Wait for \\\"not supported\\\" to disappear\"));\n    delay(2000);\n\n    Serial.println(F(\"Start sending of Samsung IR macro\"));\n\n    IRSendWithDelay(0xE51A, 2000); // Menu and wait for the Menu to pop up\n\n    Serial.println(F(\"Wait for the menu to pop up\"));\n    if (!sMacroWasCalledBefore)\n    {\n        delay(2000); // wait additional time for the Menu load\n    }\n\n    for (uint_fast8_t i = 0; i < 4; ++i)\n    {\n        IRSendWithDelay(0x9E61, 250); // Down arrow\n    }\n\n    IRSendWithDelay(0x9D62, 400); // Right arrow\n    for (uint_fast8_t i = 0; i < 2; ++i)\n    {\n        IRSendWithDelay(0x9E61, 250); // Down arrow\n    }\n\n    delay(250);\n    IRSendWithDelay(0x9768, 1); // Enter for SmartHub\n\n    if (aDoSelect)\n    {\n        Serial.println(F(\"Wait for SmartHub to show up, before entering current application\"));\n        delay(10000); // Wait not longer than 12 seconds, because smarthub menu then disappears\n        IRSendWithDelay(0x9768, 1); // Enter for last application (e.g. Netflix or Amazon)\n    }\n\n    sMacroWasCalledBefore = true;\n    Serial.println(F(\"Done\"));\n\n}\n"
  },
  {
    "path": "examples/ReceiverTimingAnalysis/ReceiverTimingAnalysis.ino",
    "content": "/*\n *  ReceiverTimingAnalysis.cpp\n *\n *  This program enables the pin change interrupt at pin 3 and waits for NEC (or other Pulse-Distance-Coding) IR Signal.\n *  It measures the pulse and pause times of the incoming signal and computes some statistics for it.\n *\n *  Observed values:\n *  Delta of each signal type is around 50 up to 100 and at low signals up to 200. TSOP is better, especially at low IR signal level.\n *  VS1838      Mark Excess -50 to +50 us\n *  TSOP31238   Mark Excess 0 to +50\n *\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n#define IR_RECEIVE_PIN    2\n//#define IR_RECEIVE_PIN    3\n\n// Helper macro for getting a macro definition as string\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n\n#if !(defined(EICRA) && defined(EIFR) && defined(EIMSK))\nvoid measureTimingISR(void);\n#endif\n\nvoid setup() {\n    pinMode(LED_BUILTIN, OUTPUT);\n\n    Serial.begin(115200);\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    // Wait until Serial Monitor is attached.\n    // Required for boards using USB code for Serial like Leonardo.\n    // Is void for USB Serial implementations using external chips e.g. a CH340.\n    while (!Serial)\n        ;\n    // !!! Program will not proceed if no Serial Monitor is attached !!!\n#endif\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__));\n\n#if defined(EICRA) && defined(EIFR) && defined(EIMSK)\n#  if (IR_RECEIVE_PIN == 2)\n    EICRA |= _BV(ISC00);  // interrupt on any logical change\n    EIFR |= _BV(INTF0);     // clear interrupt bit\n    EIMSK |= _BV(INT0);     // enable interrupt on next change\n#  elif (IR_RECEIVE_PIN == 3)\n    EICRA |= _BV(ISC10);    // enable interrupt on pin3 on both edges for ATmega328\n    EIFR |= _BV(INTF1);     // clear interrupt bit\n    EIMSK |= _BV(INT1);     // enable interrupt on next change\n#  endif\n#else\n#  if defined(ARDUINO_ARCH_SAMD) // see https://www.arduino.cc/reference/tr/language/functions/external-interrupts/attachinterrupt/ paragraph: Syntax\n    attachInterrupt(IR_RECEIVE_PIN, measureTimingISR, CHANGE);\n#  else\n    attachInterrupt(digitalPinToInterrupt(IR_RECEIVE_PIN), measureTimingISR, CHANGE); // CHANGE can also be an enum :-(\n#  endif\n#endif\n    Serial.println(F(\"Ready to analyze NEC IR signal at pin \" STR(IR_RECEIVE_PIN)));\n    Serial.println();\n}\n\nuint8_t ISREdgeCounter = 0;\nvolatile uint32_t LastMicros;\nstruct timingStruct {\n    uint16_t minimum;\n    uint8_t indexOfMinimum;\n    uint16_t maximum;\n    uint8_t indexOfMaximum;\n    uint16_t average;\n\n    uint16_t SumForAverage;\n    uint8_t SampleCount;\n//    uint8_t LastPrintedCount;\n};\n\nstruct timingStruct Mark;\nstruct timingStruct ShortSpace;\nstruct timingStruct LongSpace;\n\n/*\n * Compute minimum, maximum and average\n */\nvoid processTmingValue(struct timingStruct *aTimingStruct, uint16_t aValue) {\n    if (aTimingStruct->SampleCount == 0) {\n        // initialize values\n        aTimingStruct->minimum = UINT16_MAX;\n        aTimingStruct->maximum = 0;\n        aTimingStruct->SumForAverage = 0;\n    }\n\n    if (aTimingStruct->minimum > aValue) {\n        aTimingStruct->minimum = aValue;\n        aTimingStruct->indexOfMinimum = aTimingStruct->SampleCount;\n    }\n    if (aTimingStruct->maximum < aValue) {\n        aTimingStruct->maximum = aValue;\n        aTimingStruct->indexOfMaximum = aTimingStruct->SampleCount;\n    }\n\n    aTimingStruct->SampleCount++;\n    aTimingStruct->SumForAverage += aValue;\n    aTimingStruct->average = (aTimingStruct->SumForAverage + (aTimingStruct->SampleCount / 2)) / aTimingStruct->SampleCount;\n\n}\n\nvoid printTimingValues(struct timingStruct *aTimingStruct, const char *aCaption) {\n//    if (aTimingStruct->LastPrintedCount != aTimingStruct->SampleCount)\n//    {\n//        aTimingStruct->LastPrintedCount = aTimingStruct->SampleCount;\n    Serial.print(aCaption);\n    Serial.print(F(\": SampleCount=\"));\n    Serial.print(aTimingStruct->SampleCount);\n    Serial.print(F(\" Minimum=\"));\n    Serial.print(aTimingStruct->minimum);\n    Serial.print(F(\" @\"));\n    Serial.print(aTimingStruct->indexOfMinimum);\n    Serial.print(F(\" Maximum=\"));\n    Serial.print(aTimingStruct->maximum);\n    Serial.print(F(\" @\"));\n    Serial.print(aTimingStruct->indexOfMaximum);\n    Serial.print(F(\" Delta=\"));\n    Serial.print(aTimingStruct->maximum - aTimingStruct->minimum);\n    Serial.print(F(\"   Average=\"));\n    Serial.print(aTimingStruct->average);\n\n    Serial.println();\n//    }\n}\n\nvoid loop() {\n    if (Mark.SampleCount >= 32) {\n        /*\n         * This check enables statistics for longer protocols like Kaseikyo/Panasonics\n         */\n#if !defined(ARDUINO_ARCH_MBED)\n        noInterrupts();\n#endif\n        uint32_t tLastMicros = LastMicros;\n#if !defined(ARDUINO_ARCH_MBED)\n        interrupts();\n#endif\n        uint32_t tMicrosDelta = micros() - tLastMicros;\n\n        if (tMicrosDelta > 10000) {\n            // NEC signal ended just now\n            Serial.println();\n            printTimingValues(&Mark, \"Mark      \");\n            printTimingValues(&ShortSpace, \"ShortSpace\");\n            printTimingValues(&LongSpace, \"LongSpace \");\n\n            /*\n             * Print analysis of mark and short spaces\n             */\n            Serial.println(F(\"Analysis  :\"));\n            Serial.print(F(\" (Average of mark + short space)/2 = \"));\n            int16_t MarkAndShortSpaceAverage = (Mark.average + ShortSpace.average) / 2;\n            Serial.print(MarkAndShortSpaceAverage);\n            Serial.print(F(\" us\\r\\n Delta (to NEC standard 560) = \"));\n            Serial.print(MarkAndShortSpaceAverage - 560);\n            Serial.print(F(\"us\\r\\n MARK_EXCESS_MICROS = (Average of mark - Average of mark and short space) = \"));\n            Serial.print((int16_t) Mark.average - MarkAndShortSpaceAverage);\n            Serial.print(F(\"us\"));\n            Serial.println();\n            Serial.println();\n\n            Mark.SampleCount = 0; // used as flag for not printing the results more than once\n        }\n    }\n}\n\n/*\n * The interrupt handler.\n * Just add to the appropriate timing structure.\n */\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR measureTimingISR()\n#else\n#  if defined(EICRA) && defined(EIFR) && defined(EIMSK)\n#    if (IR_RECEIVE_PIN == 2)\nISR(INT0_vect)\n#    elif (IR_RECEIVE_PIN == 3)\nISR(INT1_vect)\n#    endif\n#  else\nvoid measureTimingISR()\n#  endif\n#endif\n{\n    uint32_t tMicros = micros();\n    uint32_t tMicrosDelta = tMicros - LastMicros;\n    LastMicros = tMicros;\n    /*\n     * read level and give feedback\n     */\n    uint8_t tInputLevel = digitalRead(IR_RECEIVE_PIN);\n    digitalWrite(LED_BUILTIN, !tInputLevel);\n\n    if (tMicrosDelta > 10000) {\n        // gap > 10 ms detected, reset counter to first detected edge and initialize timing structures\n        ISREdgeCounter = 1;\n        LongSpace.SampleCount = 0;\n        ShortSpace.SampleCount = 0;\n        Mark.SampleCount = 0;\n    } else {\n        ISREdgeCounter++;\n    }\n\n    /*\n     * Skip header mark and space and first bit mark and space\n     */\n    if (ISREdgeCounter > 4) {\n        if (tInputLevel != LOW) {\n            // Mark ended\n            processTmingValue(&Mark, tMicrosDelta);\n//            Serial.print('M');\n        } else {\n            // Space ended\n            if (tMicrosDelta > 1000) {\n                // long space - logical 1\n                processTmingValue(&LongSpace, tMicrosDelta);\n                Serial.print('1');\n            } else {\n                // short space - logical 0\n                processTmingValue(&ShortSpace, tMicrosDelta);\n                Serial.print('0');\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "examples/SendAllProtocols/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/SendAllProtocols/SendAllProtocols.ino",
    "content": "/*\n *  SendAllProtocols.cpp\n *\n *  Sends 39 protocols for testing purposes\n *\n *  To disable one of them or to enable other protocols, specify this before the \"#include <irmp.hpp>\" line.\n *  If you get warnings of redefining symbols, just ignore them or undefine them first (see Interrupt example).\n *  The exact names can be found in the library file irmpSelectAllProtocols.h (see Callback example).\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Set library modifiers first to set output pin etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n#define IRSND_IR_FREQUENCY          38000\n\n#if ! (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))\n#define IRSND_PROTOCOL_NAMES        1\n#endif\n//#define IRSND_GENERATE_NO_SEND_RF // for back to back tests\n\n#include <irsndSelectAllProtocols.h>\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irsnd.hpp>\n\nIRMP_DATA irsnd_data;\n\nvoid setup()\n{\n    Serial.begin(115200);\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n#if defined(ESP8266)\n    Serial.println(); // to separate it from the internal boot output\n#endif\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    Serial.print(F(\"Send sample frequency=\"));\n    Serial.print(F_INTERRUPTS);\n    Serial.println(F(\" Hz\"));\n\n    irsnd_init();\n    irmp_irsnd_LEDFeedback(true); // Enable send signal feedback at LED_BUILTIN\n\n    Serial.println(F(\"Send IR signals at pin \" STR(IRSND_OUTPUT_PIN)));\n    delay(1000);\n}\n\nvoid loop()\n{\n    static uint16_t sAddress = 0x201;\n    static uint16_t sCommand = 0x201;\n    static uint8_t sRepeats = 0;\n\n    Serial.print(F(\"Now sending all with \"));\n    Serial.print(sRepeats);\n    Serial.println(F(\" repeats\"));\n\n    for (uint_fast8_t i = 0; i < sizeof(irsnd_used_protocol_index); ++i)\n    {\n        irsnd_data.protocol = pgm_read_byte(&irsnd_used_protocol_index[i]);\n        irsnd_data.address = sAddress;\n        irsnd_data.command = sCommand;\n        irsnd_data.flags = sRepeats;\n\n        // true = wait for frame and trailing space/gap to end. This stores timer state and restores it after sending.\n        if (!irsnd_send_data(&irsnd_data, true))\n        {\n            Serial.println(F(\"Protocol not found\")); // name of protocol is printed by irsnd_data_print()\n        }\n\n        irsnd_data_print(&Serial, &irsnd_data);\n\n        sAddress += 0x101;\n        sCommand += 0x101;\n        delay(1000);\n    }\n    Serial.println();\n    Serial.println();\n\n    sRepeats++;\n\n    // we have 0x27 protocols now start with next number range\n    sAddress = (sAddress & 0xC0) + 0x40;\n    sCommand = sAddress;\n\n    delay(2000);\n}\n"
  },
  {
    "path": "examples/SendAllProtocols/SendAllProtocols.log",
    "content": "START ../src/SendAllProtocols.cpp from Mar 17 2026\nUsing library version 3.7.0\nSend sample frequency=19000 Hz\nSend IR signals at pin 3\nProtocol=SIRCS  Address=0x1 Command=0x1\nProtocol=NEC  Address=0x2 Command=0x2\nProtocol=SAMSUNG  Address=0x3 Command=0x3\nProtocol=MATSUSH  Address=0x4 Command=0x4\nProtocol=KASEIKYO  Address=0x5 Command=0x5\nProtocol=RECS80  Address=0x6 Command=0x6\nProtocol=RC5  Address=0x7 Command=0x7\nProtocol=DENON  Address=0x8 Command=0x8\nProtocol=RC6  Address=0x9 Command=0x9\nProtocol=SAMSG32  Address=0xA Command=0xA\nProtocol=APPLE  Address=0xB Command=0xB\nProtocol=RECS80EX  Address=0xC Command=0xC\nProtocol=NUBERT  Address=0xD Command=0xD\nProtocol=GRUNDIG  Address=0xE Command=0xE\nProtocol=NOKIA  Address=0xF Command=0xF\nProtocol=SIEMENS  Address=0x10 Command=0x10\nProtocol=FDC  Address=0x11 Command=0x11\nProtocol=RCCAR  Address=0x12 Command=0x12\nProtocol=JVC  Address=0x13 Command=0x13\nProtocol=RC6A  Address=0x14 Command=0x14\nProtocol=NIKON  Address=0x15 Command=0x15\nProtocol=RUWIDO  Address=0x16 Command=0x16\nProtocol=NEC16  Address=0x17 Command=0x17\nProtocol=NEC42  Address=0x18 Command=0x18\nProtocol=LEGO  Address=0x19 Command=0x19\nProtocol=THOMSON  Address=0x1A Command=0x1A\nProtocol=BOSE  Address=0x1B Command=0x1B\nProtocol=A1TVBOX  Address=0x1C Command=0x1C\nProtocol=TELEFUNKEN  Address=0x1D Command=0x1D\nProtocol=ROOMBA  Address=0x1E Command=0x1E\nProtocol=SPEAKER  Address=0x1F Command=0x1F\nProtocol=LGAIR  Address=0x20 Command=0x20\nProtocol=SAMSG48  Address=0x21 Command=0x21\nProtocol=PENTAX  Address=0x22 Command=0x22\nProtocol=FAN  Address=0x23 Command=0x23\nProtocol=ACP24  Address=0x24 Command=0x24\nProtocol=TECHNICS  Address=0x25 Command=0x25\nProtocol=PANASONIC  Address=0x26 Command=0x26\nProtocol=MITSU_HEAVY  Address=0x27 Command=0x27\n\n\nNow sending all with number of repeats=1\nProtocol=SIRCS  Address=0x40 Command=0x40 Repeats=1\nProtocol=NEC  Address=0x41 Command=0x41 Repeats=1\nProtocol=SAMSUNG  Address=0x42 Command=0x42 Repeats=1\nProtocol=MATSUSH  Address=0x43 Command=0x43 Repeats=1\n"
  },
  {
    "path": "examples/SimpleReceiver/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/SimpleReceiver/SimpleReceiver.ino",
    "content": "/*\n *  SimpleReceiver.cpp\n *\n *  Receives IR protocol data of 15 main protocols.\n *\n *  *****************************************************************************************************************************\n *  To access the library files from your sketch, you have to first use `Sketch > Show Sketch Folder (Ctrl+K)` in the Arduino IDE.\n *  Then navigate to the parallel `libraries` folder and select the library you want to access.\n *  The library files itself are located in the `src` sub-directory.\n *  If you did not yet store the example as your own sketch, then with Ctrl+K you are instantly in the right library folder.\n *  *****************************************************************************************************************************\n *\n *\n *  The following IR protocols are enabled by default:\n *      Sony SIRCS\n *      NEC + APPLE\n *      Samsung + Samsg32\n *      Kaseikyo\n *\n *      Plus 11 other main protocols by including irmpMain15.h instead of irmp.h\n *      JVC, NEC16, NEC42, Matsushita, DENON, Sharp, RC5, RC6 & RC6A, IR60 (SDA2008) Grundig, Siemens Gigaset, Nokia\n *\n *  To disable one of them or to enable other protocols, specify this before the \"#include <irmp.h>\" line.\n *  If you get warnings of redefining symbols, just ignore them or undefine them first (see Interrupt example).\n *  The exact names can be found in the library file irmpSelectAllProtocols.h (see Callback example).\n *\n *  Copyright (C) 2019  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n\n#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some FLASH. Must before #include <irmp*>\n\n//#include <irmpSelectMain15Protocols.h>  // This enables 15 main protocols\n#define IRMP_SUPPORT_NEC_PROTOCOL        1 // this enables only one protocol\n//#define IRMP_SUPPORT_SIRCS_PROTOCOL      1 // this enables only one protocol\n\n/*\n * We use LED_BUILTIN as feedback for commands 0x40 and 0x48 and cannot use it as feedback LED for receiving\n */\n#if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define IRMP_FEEDBACK_LED_PIN   ALTERNATIVE_IR_FEEDBACK_LED_PIN\n#endif\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irmp.hpp>\n\nIRMP_DATA irmp_data;\n\nvoid setup() {\n    pinMode(LED_BUILTIN, OUTPUT);\n\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    // Wait until Serial Monitor is attached.\n    // Required for boards using USB code for Serial like Leonardo.\n    // Is void for USB Serial implementations using external chips e.g. a CH340.\n    while (!Serial)\n        ;\n    // !!! Program will not proceed if no Serial Monitor is attached !!!\n#endif\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    irmp_init();\n\n    Serial.print(F(\"Ready to receive IR signals of protocols: \"));\n    irmp_print_active_protocols(&Serial);\n    Serial.println(F(\"at pin \" STR(IRMP_INPUT_PIN)));\n\n    /*\n     * We use LED_BUILTIN as feedback for commands 0x40 and 0x48 and cannot use it as feedback LED for receiving\n     */\n#if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n    irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at ALTERNATIVE_IR_FEEDBACK_LED_PIN\n    Serial.println(F(\"IR feedback pin is \" STR(ALTERNATIVE_IR_FEEDBACK_LED_PIN)));\n#endif\n\n}\n\nvoid loop() {\n    /*\n     * Check if new data available and get them\n     */\n    if (irmp_get_data(&irmp_data)) {\n        /*\n         * Skip repetitions of command\n         */\n        if (!(irmp_data.flags & IRMP_FLAG_REPETITION)) {\n            /*\n             * Here data is available and is no repetition -> evaluate IR command\n             */\n            switch (irmp_data.command) {\n            case 0x48: // 72\n            case 0x40: // 64\n                digitalWrite(LED_BUILTIN, LOW);\n                delay(4000);\n                break;\n            default:\n                digitalWrite(LED_BUILTIN, HIGH);\n                break;\n            }\n        }\n        irmp_result_print(&irmp_data);\n    }\n}\n"
  },
  {
    "path": "examples/SimpleSender/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRMP examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4\n * ATtinyX5     0|PB0       4|PB4       3|PB3\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark pro\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * SAMD21       3           4           5\n * ESP8266     14|D5       12|D6        %\n * ESP32       15           4           %\n * ESP32-C3     6           7          10\n * BluePill   PA6         PA7         PA3\n * APOLLO3     11          12           5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define IRMP_MEASURE_TIMING // For debugging purposes.\n//\n#if defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board is active LOW\n#define IRMP_INPUT_PIN      14 // D5\n#define IRSND_OUTPUT_PIN    12 // D6 - D4/2 is internal LED\n#define IR_TIMING_TEST_PIN  13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN            42 // Dummy for examples using it\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IRMP_INPUT_PIN       6\n#define IRSND_OUTPUT_PIN     7\n#define TONE_PIN            10\n\n#elif defined(ESP32)\n#define IRMP_INPUT_PIN      15  // D15\n#define IRSND_OUTPUT_PIN     4  // D4\n#include <Arduino.h>\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n\n#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)\n// BluePill in 2 flavors\n// Timer 3 of IRMP blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on the BluePill is active LOW\n#define IRMP_INPUT_PIN          PA6\n#define IRSND_OUTPUT_PIN        PA7\n#define TONE_PIN                PA3\n#define IR_TIMING_TEST_PIN      PA5\n\n#elif  defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n#define IRMP_INPUT_PIN   0\n#define IRSND_OUTPUT_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN         3\n//#define IR_TIMING_TEST_PIN 3\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#  if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define IRMP_INPUT_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IRMP_INPUT_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IRSND_OUTPUT_PIN 8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7\n#define IR_TIMING_TEST_PIN 10 // PA4\n\n#  else\n#define IRMP_INPUT_PIN   3\n#define IRSND_OUTPUT_PIN 2\n#define TONE_PIN         7\n#  endif\n\n#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// Pin 6 is TX pin 7 is RX\n#define IRMP_INPUT_PIN   3 // INT1\n#define IRSND_OUTPUT_PIN 4\n#define TONE_PIN         9\n#define IR_TIMING_TEST_PIN 8\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define IRMP_INPUT_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IRSND_OUTPUT_PIN PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n\n#elif defined(ARDUINO_ARCH_APOLLO3)\n#define IRMP_INPUT_PIN   11\n#define IRSND_OUTPUT_PIN 12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE, Arduino Nano RP2040 Connect\n#define IRMP_INPUT_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IRSND_OUTPUT_PIN    4   // GPIO16\n#define TONE_PIN            5\n\n#elif defined(ARDUINO_ARCH_RP2040) // Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IRMP_INPUT_PIN      15  // to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IRSND_OUTPUT_PIN    16\n#define TONE_PIN            17\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(TEENSYDUINO)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n#elif defined(__AVR__) // Standard AVR Boards like Uno, Nano\n#define IRMP_INPUT_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN 7\n// You can alternatively specify the input pin with port and bit number if you do not have the Arduino pin number at hand\n//#define IRMP_PORT_LETTER D\n//#define IRMP_BIT_NUMBER 2\n\n#elif defined(ARDUINO_ARCH_SAMD)\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#else\n#warning Board / CPU is not detected using pre-processor symbols -> using default values for IRMP_INPUT_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IRMP_INPUT_PIN      2\n#define IRSND_OUTPUT_PIN    3\n#define TONE_PIN            4\n#if !defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#endif\n#define IR_TIMING_TEST_PIN  7\n#endif // defined(ESP8266)\n\n\n#if defined(__AVR_ATmega4809__) // for standard AVR we manage hardware directly in void enablePCIInterrupt()\n#define IRMP_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/*\n * Helper macro for getting a macro definition as string\n */\n#if !defined(STR_HELPER) && !defined(STR)\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n"
  },
  {
    "path": "examples/SimpleSender/SimpleSender.ino",
    "content": "/*\n *  SimpleSender.cpp\n *\n *  Sends NEC or Samsung protocol frames.\n *  Is able to send IR protocol data of 15 main protocols.\n *\n *      Sony SIRCS\n *      NEC + APPLE\n *      Samsung + Samsg32\n *      Kaseikyo\n *\n *      Plus 11 other main protocols\n *      JVC, NEC16, NEC42, Matsushita, DENON, Sharp, RC5, RC6 & RC6A, IR60 (SDA2008) Grundig, Siemens Gigaset, Nokia\n *\n *  To disable one of them or to enable other protocols, specify this before the \"#include <irmp.hpp>\" line.\n *  If you get warnings of redefining symbols, just ignore them or undefine them first (see Interrupt example).\n *  The exact names can be found in the library file irmpSelectAllProtocols.h (see Callback example).\n *\n *  Copyright (C) 2019-2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#include <Arduino.h>\n\n//#define SEND_SAMSUNG // else send NEC\n\n/*\n * Set library modifiers first to set output pin etc.\n */\n#include \"PinDefinitionsAndMore.h\"\n//#define IR_OUTPUT_IS_ACTIVE_LOW\n#define IRSND_IR_FREQUENCY          38000\n\n#define IRSND_PROTOCOL_NAMES        1 // Enable protocol number mapping to protocol strings - requires some FLASH.\n\n#include <irsndSelectMain15Protocols.h>\n// or disable #include <irsndSelectMain15Protocols.h> and use only one protocol to save programming space\n//#define IRSND_SUPPORT_NEC_PROTOCOL        1\n//#define IRSND_SUPPORT_NEC_PROTOCOL        1\n\n/*\n * After setting the definitions we can include the code and compile it.\n */\n#include <irsnd.hpp>\n\nIRMP_DATA irsnd_data;\n\n#if defined(SEND_SAMSUNG)\nunion WordUnion\n{\n    struct\n    {\n        uint8_t LowByte;\n        uint8_t HighByte;\n    } UByte;\n    struct\n    {\n        int8_t LowByte;\n        int8_t HighByte;\n    } Byte;\n    uint8_t UBytes[2];\n    int8_t Bytes[2];\n    uint16_t UWord;\n    int16_t Word;\n    uint8_t *BytePointer;\n};\n#endif\n\nvoid setup() {\n    Serial.begin(115200);\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!\n#endif\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_IRMP));\n\n    irsnd_init();\n    irmp_irsnd_LEDFeedback(true); // Enable send signal feedback at LED_BUILTIN\n\n    Serial.println(F(\"Send IR signals at pin \" STR(IRSND_OUTPUT_PIN)));\n\n#if defined(SEND_SAMSUNG)\n    /*\n     * Send Samsung32\n     */\n    irsnd_data.protocol = IRMP_SAMSUNG32_PROTOCOL;\n    irsnd_data.address = 0x0707;\n    irsnd_data.command = 0xFB04; // For my Samsung, the high byte is the inverse of the low byte\n    irsnd_data.flags = 0; // repeat frame 0 time\n#else\n    /*\n     * Send NEC\n     */\n    irsnd_data.protocol = IRMP_NEC_PROTOCOL;\n    irsnd_data.address = 0x0707;\n    irsnd_data.command = 0xFB; // The required inverse of the 8 bit command is added by the send routine.\n    irsnd_data.flags = 2; // repeat frame 2 times\n#endif\n\n    // true = wait for frame and trailing space/gap to end. This stores timer state and restores it after sending.\n    if (!irsnd_send_data(&irsnd_data, true)) {\n        Serial.println(F(\"Protocol not found\")); // name of protocol is printed by irsnd_data_print()\n    }\n    irsnd_data_print(&Serial, &irsnd_data);\n\n}\n\nvoid loop() {\n    delay(5000);\n    irsnd_data.command++;\n#if defined(SEND_SAMSUNG)\n    // For my Samsung remote, the high byte is the inverse of the low byte\n    WordUnion tNextCommand; // using WordUnion saves 14 bytes program memory for the next 3 lines\n    tNextCommand.UWord = irsnd_data.command;\n    tNextCommand.UByte.HighByte = ~tNextCommand.UByte.LowByte;\n    irsnd_data.command = tNextCommand.UWord;\n#endif\n    irsnd_send_data(&irsnd_data, true);\n    irsnd_data_print(&Serial, &irsnd_data);\n}\n"
  },
  {
    "path": "examples/TinyReceiver/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRremote examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2021-2026  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  Arduino-IRremote is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4         Arduino\n * ATtinyX5     0|PB0       4|PB4       3|PB3     ATTinyCore\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark original core\n * ATtiny84      |PB2        |PA4        |PA3     ATTinyCore\n * ATtiny88     3|PD3       4|PD4       9|PB1     ATTinyCore\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * ATtiny1604   2           3|PA5       %\n * ATtiny816   14|PA1      16|PA3       1|PA5     MegaTinyCore\n * ATtiny1614   8|PA1      10|PA3       1|PA5     MegaTinyCore\n * MKR*         1           3           4\n * SAMD         2           3           4\n * ESP8266      14|D5       12|D6       %\n * ESP32        15          4          27\n * ESP32-C3     2           3           4\n * ESP32-S3     2           3           4\n * BluePill     PA6         PA7       PA3\n * APOLLO3      11          12          5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define _IR_MEASURE_TIMING // For debugging purposes.\n\n#if defined(__AVR__)\n#if (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) && defined(PIN_PB0) // Digispark board. For use with ATTinyCore.\n#include \"ATtinySerialOut.hpp\" // TX is at pin 2 - Available as Arduino library \"ATtinySerialOut\". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore.\n#define IR_RECEIVE_PIN  PIN_PB0\n#define IR_SEND_PIN     PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN        PIN_PB3\n#define _IR_TIMING_TEST_PIN PIN_PB3\n\n#  elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#    if defined(ARDUINO_AVR_DIGISPARKPRO)\n// For use with Digispark original core\n#define IR_RECEIVE_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IR_RECEIVE_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IR_SEND_PIN      8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7 - on Digispark board labeled as pin 5\n#define _IR_TIMING_TEST_PIN 10 // PA4\n#    elif  !defined(PIN_PA3)\n#error ATtiny87 or ATtiny167 is not supported for the selected core. Please extend PinDefinitionsAndMore.h.\n#    else\n// For use with ATTinyCore\n#define IR_RECEIVE_PIN  PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards\n#define IR_SEND_PIN     PIN_PA2 // On Digispark board labeled as pin 8\n#define TONE_PIN        PIN_PA7 // On Digispark board labeled as pin 5\n#    endif\n\n#  elif defined(__AVR_ATtiny84__) && defined(PIN_PB2) // For use with ATTinyCore\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\". Saves 128 bytes program memory.\n#define IR_RECEIVE_PIN   PIN_PB2 // INT0\n#define IR_SEND_PIN      PIN_PA4\n#define TONE_PIN         PIN_PA3\n#define _IR_TIMING_TEST_PIN PIN_PA5\n\n#  elif defined(__AVR_ATtiny88__) && defined(PIN_PD3) // MH-ET Tiny88 board. For use with ATTinyCore.\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\". Saves 128 bytes program memory.\n// Pin 6 is TX, pin 7 is RX\n#define IR_RECEIVE_PIN   PIN_PD3 // 3 - INT1\n#define IR_SEND_PIN      PIN_PD4 // 4\n#define TONE_PIN         PIN_PB1 // 9\n#define _IR_TIMING_TEST_PIN PIN_PB0 // 8\n\n#  elif (defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)) && defined(PIN_PA1) // For use with megaTinyCore\n// Tiny Core Dev board\n// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ - Out of Stock\n// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ - Out of Stock\n#define IR_RECEIVE_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IR_SEND_PIN      PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n#define APPLICATION_PIN  PIN_PC3 // 13, PIN_PA0 is RESET\n#undef LED_BUILTIN               // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output\n#define LED_BUILTIN      PIN_PA6 // use 2 instead of PIN_PA6 for TinyCore32\n\n#  elif defined(__AVR_ATtiny816__) && defined(PIN_PA1) // For use with megaTinyCore\n#define IR_RECEIVE_PIN  PIN_PA1 // 14\n#define IR_SEND_PIN     PIN_PA3 // 16\n#define TONE_PIN        PIN_PA5 // 1\n#define APPLICATION_PIN PIN_PA4 // 0\n#undef LED_BUILTIN              // No LED available, take the one which is connected to the DAC output\n#define LED_BUILTIN     PIN_PB5 // 4\n\n#  elif defined(__AVR_ATtiny1604__) && defined(PIN_PA1) // For use with megaTinyCore\n#define IR_RECEIVE_PIN   PIN_PA1 // 8\n#define IR_SEND_PIN      PIN_PA7 // 3\n#define TONE_PIN         PIN_PA3 // 1  TCA0-WO3\n#define APPLICATION_PIN  PIN_PB2 // 5\n\n#  elif defined(__AVR_ATtiny1614__) && defined(PIN_PA1) // For use with megaTinyCore\n#define IR_RECEIVE_PIN   PIN_PA1 // 8\n#define IR_SEND_PIN      PIN_PA5 // 10 TCA0-WO5\n#define TONE_PIN         PIN_PA3 // 1  TCA0-WO3\n#define APPLICATION_PIN  PIN_PA4 // 0\n\n#  elif  defined(__AVR_ATtiny1624__) && defined(PIN_PA6) // For use with megaTinyCore\n#define IR_RECEIVE_PIN   PIN_PA1 // 8\n#define IR_SEND_PIN      PIN_PA5 // 3  TCA0-WO5\n#define TONE_PIN         PIN_PA3 // 1  TCA0-WO3\n#define APPLICATION_PIN  PIN_PB1 // 6\n\n#  elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \\\n|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \\\n|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \\\n|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \\\n|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \\\n|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \\\n|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \\\n|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \\\n|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN        13\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#  else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc.\n#define IR_RECEIVE_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#    if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit\n// We have no built in LED at pin 13 -> reuse RX LED\n#undef LED_BUILTIN\n#define LED_BUILTIN         LED_BUILTIN_RX\n#    endif\n#  endif // defined(__AVR_ATtiny25__)...\n\n#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4\n// To be compatible with Uno R3.\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#elif defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW\n#define IR_RECEIVE_PIN          14 // D5\n#define IR_SEND_PIN             12 // D6 - D4/pin 2 is internal LED\n#define _IR_TIMING_TEST_PIN      2 // D4\n#define APPLICATION_PIN         13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN                42 // Dummy for examples using it#\n\n#elif defined(ARDUINO_NOLOGO_ESP32C3_SUPER_MINI)\n// ESP32 - C3 super mini\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D8) is active LOW\n#define IR_RECEIVE_PIN           2\n#define IR_SEND_PIN              3\n#define TONE_PIN                 4\n#define APPLICATION_PIN         10\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n// ESP32 - C3 other\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IR_RECEIVE_PIN           6\n#define IR_SEND_PIN              7\n#define TONE_PIN                 9\n#define APPLICATION_PIN         10\n\n#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARDUINO_ESP32S3_DEV)\n// ESP32 - S3 - !!! NOT tested !!!\n#define IR_RECEIVE_PIN          15 // alternatively 13\n#define IR_SEND_PIN             16 // alternatively 14\n#define TONE_PIN                17\n#define APPLICATION_PIN         18\n\n#elif defined(ESP32)\n#include <Arduino.h>\n\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n\n#define IR_RECEIVE_PIN          15  // D15\n#define IR_SEND_PIN              4  // D4\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n#define APPLICATION_PIN         16  // RX2 pin\n\n#elif (defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)) && defined(PA6) // BluePill\n// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define IR_RECEIVE_PIN          PA6\n#define IR_RECEIVE_PIN_STRING   \"PA6\"\n#define IR_SEND_PIN             PA7\n#define IR_SEND_PIN_STRING      \"PA7\"\n#define TONE_PIN                PA3\n#define _IR_TIMING_TEST_PIN     PA5\n#define APPLICATION_PIN         PA2\n#define APPLICATION_PIN_STRING  \"PA2\"\n#  if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8)\n// BluePill LED is active low\n#define FEEDBACK_LED_IS_ACTIVE_LOW\n#  endif\n\n#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards\n#define IR_RECEIVE_PIN  11\n#define IR_SEND_PIN     12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE and Arduino Nano Connect layout for MBED\n// Must be before ARDUINO_ARCH_RP2040, since it is the layout for the MBED core of Arduino Nano Connect\n#define IR_RECEIVE_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IR_SEND_PIN         4   // GPIO16\n#define TONE_PIN            5\n#define APPLICATION_PIN     6\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 8\n\n#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IR_RECEIVE_PIN      15  // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IR_SEND_PIN         16  // GPIO16\n#define TONE_PIN            17\n#define APPLICATION_PIN     18\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 20\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(PARTICLE) && defined(A4) // !!!UNTESTED!!!\n#define IR_RECEIVE_PIN      A4\n#define IR_SEND_PIN         A5 // Particle supports multiple pins\n\n#define LED_BUILTIN         D7\n\n/*\n * 4 times the same (default) layout for easy adaption in the future\n */\n#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc.\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)\n#  if defined(USE_ARDUINO_MKR_PIN_LAYOUT)\n#define IR_RECEIVE_PIN      1 // Pin 2 on MKR is not interrupt capable, see https://www.arduino.cc/reference/tr/language/functions/external-interrupts/attachinterrupt/\n#  else\n#define IR_RECEIVE_PIN      2\n#  endif\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0)\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n#endif\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#elif defined (NRF51) // BBC micro:bit\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define APPLICATION_PIN     1\n#define _IR_TIMING_TEST_PIN 4\n\n#define tone(...) void()    // no tone() available\n#define noTone(a) void()\n#define TONE_PIN           42 // Dummy for examples using it\n\n#else\n#warning Board and Core / CPU is not detected using pre-processor symbols -> using default values for IR_RECEIVE_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n#endif // defined(ESP8266)\n\n#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED)\n#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation\n#else\n# if defined(SEND_PWM_BY_TIMER)\n#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp\n#  endif\n#endif\n\n#if !defined (FLASHEND)\n#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined\n#endif\n\n#if !defined (RAMEND)\n#define RAMEND 0x0FFF // Dummy value for platforms where RAMEND is not defined\n#endif\n"
  },
  {
    "path": "examples/TinyReceiver/TinyReceiver.ino",
    "content": "/*\n *  TinyReceiver.cpp\n *\n *  Small memory footprint and no timer usage!\n *\n *  Receives IR protocol data of NEC protocol using pin change interrupts.\n *  For each complete IR frame/command received, the decoded data is copied to the TinyIRReceiverData structure\n *  and the handleReceivedTinyIRData() function is called in an interrupt context.\n *  However, interrupts are explicitly enabled here to allow the use of delay() and millis() etc.\n *  !!!!!!!!!!!!!!!!!!!!!!\n *  Functions called in interrupt context should be running as short as possible,\n *  !!!!!!!!!!!!!!!!!!!!!\n *\n * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header.\n *  FAST Protocol characteristics:\n * - Bit timing is like NEC or JVC\n * - The header is shorter, 3156 vs. 12500\n * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command.\n *     This results in a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms.\n * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance.\n *\n *\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *  This file is also part of IRMP https://github.com/IRMP-org/IRMP.\n *\n ************************************************************************************\n * MIT License\n *\n * Copyright (c) 2022-2026 Armin Joachimsmeyer\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished\n * to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\n * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\n * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n ************************************************************************************\n */\n\n#include <Arduino.h>\n\n#include \"PinDefinitionsAndMore.h\" // Set IR_RECEIVE_PIN for different CPU's\n\n//#define DEBUG // to see if attachInterrupt is used\n//#define TRACE // to see the state of the ISR state machine\n\n/*\n * Protocol selection\n */\n//#define USE_EXTENDED_NEC_PROTOCOL // Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value.\n//#define USE_ONKYO_PROTOCOL    // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.\n//#define USE_FAST_PROTOCOL     // Use FAST protocol instead of NEC / ONKYO.\n//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.\n/*\n * Set compile options to modify the generated code.\n */\n//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory.\n//#define USE_CALLBACK_FOR_TINY_RECEIVER  // Call the user provided function \"void handleReceivedTinyIRData()\" each time a frame or repeat is received.\n#include \"TinyIRReceiver.hpp\" // include the code\n\nvoid setup() {\n    Serial.begin(115200);\n\n#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/ \\\n    || defined(SERIALUSB_PID)  || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_attiny3217)\n    // Wait until Serial Monitor is attached.\n    // Required for boards using USB code for Serial like Leonardo.\n    // Is void for USB Serial implementations using external chips e.g. a CH340.\n    while (!Serial)\n        ;\n    // !!! Program will not proceed if no Serial Monitor is attached !!!\n#endif\n\n    // Just to know which program is running on my Arduino\n#if defined(ESP8266) || defined(ESP32)\n    Serial.println();\n#endif\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_TINYIR));\n\n    // Enables the interrupt generation on change of IR input signal\n    if (!initPCIInterruptForTinyReceiver()) {\n        Serial.println(F(\"No interrupt available for pin \" STR(IR_RECEIVE_PIN))); // optimized out by the compiler, if not required :-)\n    }\n#if defined(USE_FAST_PROTOCOL)\n    Serial.println(F(\"Ready to receive Fast IR signals at pin \" STR(IR_RECEIVE_PIN)));\n#else\n    Serial.println(F(\"Ready to receive NEC IR signals at pin \" STR(IR_RECEIVE_PIN)));\n#endif\n}\n\nvoid loop() {\n    if (TinyReceiverDecode()) {\n        /*\n         * The library has already copied the data used for this output,\n         * so there is no need to do this in the callback function.\n         */\n#if !defined(USE_FAST_PROTOCOL)\n        // We have no address at FAST protocol\n        Serial.print(F(\"Address=0x\"));\n        Serial.print(TinyIRReceiverData.Address, HEX);\n        Serial.print(' ');\n#endif\n\n        Serial.print(F(\"Command=0x\"));\n        Serial.print(TinyIRReceiverData.Command, HEX);\n        if (TinyIRReceiverData.Flags == IRDATA_FLAGS_IS_REPEAT) {\n            Serial.print(F(\" Repeat\"));\n        }\n        if (TinyIRReceiverData.Flags == IRDATA_FLAGS_PARITY_FAILED) {\n            Serial.print(F(\" Parity failed\"));\n\n#if !defined(USE_EXTENDED_NEC_PROTOCOL) && !defined(USE_ONKYO_PROTOCOL)\n            Serial.print(F(\", try USE_EXTENDED_NEC_PROTOCOL or USE_ONKYO_PROTOCOL\"));\n#endif\n\n        }\n        Serial.println();\n    }\n    /*\n     * Put your code here\n     */\n\n    /*\n     * No resume() required :-)\n     */\n}\n\n/*\n * Optional code, if you require a callback\n */\n#if defined(USE_CALLBACK_FOR_TINY_RECEIVER)\n/*\n * This is the function, which is called if a complete frame was received\n * This function is executed in an ISR (Interrupt Service Routine) context but with interrupts enabled!\n * However, it is always best to keep this callback function short and fast!\n */\n#  if defined(ESP8266) || defined(ESP32)\nIRAM_ATTR\n#  endif\nvoid handleReceivedTinyIRData() {\n#  if defined(ARDUINO_ARCH_MBED) || defined(ESP32)\n    /*\n     * Printing is not allowed in ISR context for RTOS based cores like ESP, even when interrupts are enabled.\n     * For Mbed we get a kernel panic and \"Error Message: Semaphore: 0x0, Not allowed in ISR context\" for Serial.print()\n     * for ESP32 we get a \"Guru Meditation Error: Core  1 panic'ed\" (we also have an RTOS running!)\n     */\n#  else\n    // As an example, print very short output, since we are in an interrupt context and do not want to miss the next interrupts of the repeats coming soon\n    printTinyReceiverResultMinimal(&Serial);\n#  endif\n    if (TinyIRReceiverData.Command == 0x10) {\n        // do something SHORT here\n    } else if (TinyIRReceiverData.Command == 0x11) {\n        // do something SHORT here too\n    }\n}\n#endif\n\n"
  },
  {
    "path": "examples/TinySender/PinDefinitionsAndMore.h",
    "content": "/*\n *  PinDefinitionsAndMore.h\n *\n *  Contains pin definitions for IRremote examples for various platforms\n *  as well as definitions for feedback LED and tone() and includes\n *\n *  Copyright (C) 2021-2026  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  Arduino-IRremote is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Pin mapping table for different platforms\n *\n * Platform     IR input    IR output   Tone      Core/Pin schema\n * --------------------------------------------------------------\n * DEFAULT/AVR  2           3           4         Arduino\n * ATtinyX5     0|PB0       4|PB4       3|PB3     ATTinyCore\n * ATtiny167    3|PA3       2|PA2       7|PA7     ATTinyCore\n * ATtiny167    9|PA3       8|PA2       5|PA7     Digispark original core\n * ATtiny84      |PB2        |PA4        |PA3     ATTinyCore\n * ATtiny88     3|PD3       4|PD4       9|PB1     ATTinyCore\n * ATtiny3216  14|PA1      15|PA2      16|PA3     MegaTinyCore\n * ATtiny1604   2           3|PA5       %\n * ATtiny816   14|PA1      16|PA3       1|PA5     MegaTinyCore\n * ATtiny1614   8|PA1      10|PA3       1|PA5     MegaTinyCore\n * MKR*         1           3           4\n * SAMD         2           3           4\n * ESP8266      14|D5       12|D6       %\n * ESP32        15          4          27\n * ESP32-C3     2           3           4\n * ESP32-S3     2           3           4\n * BluePill     PA6         PA7       PA3\n * APOLLO3      11          12          5\n * RP2040       3|GPIO15    4|GPIO16    5|GPIO17\n */\n//#define _IR_MEASURE_TIMING // For debugging purposes.\n\n#if defined(__AVR__)\n#if (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) && defined(PIN_PB0) // Digispark board. For use with ATTinyCore.\n#include \"ATtinySerialOut.hpp\" // TX is at pin 2 - Available as Arduino library \"ATtinySerialOut\". Saves 700 bytes program memory and 70 bytes RAM for ATtinyCore.\n#define IR_RECEIVE_PIN  PIN_PB0\n#define IR_SEND_PIN     PIN_PB4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.\n#define TONE_PIN        PIN_PB3\n#define _IR_TIMING_TEST_PIN PIN_PB3\n\n#  elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\"\n// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.\n#    if defined(ARDUINO_AVR_DIGISPARKPRO)\n// For use with Digispark original core\n#define IR_RECEIVE_PIN   9 // PA3 - on Digispark board labeled as pin 9\n//#define IR_RECEIVE_PIN  14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#define IR_SEND_PIN      8 // PA2 - on Digispark board labeled as pin 8\n#define TONE_PIN         5 // PA7 - on Digispark board labeled as pin 5\n#define _IR_TIMING_TEST_PIN 10 // PA4\n#    elif  !defined(PIN_PA3)\n#error ATtiny87 or ATtiny167 is not supported for the selected core. Please extend PinDefinitionsAndMore.h.\n#    else\n// For use with ATTinyCore\n#define IR_RECEIVE_PIN  PIN_PA3 // On Digispark board labeled as pin 9 - INT0 is connected to USB+ on DigisparkPro boards\n#define IR_SEND_PIN     PIN_PA2 // On Digispark board labeled as pin 8\n#define TONE_PIN        PIN_PA7 // On Digispark board labeled as pin 5\n#    endif\n\n#  elif defined(__AVR_ATtiny84__) && defined(PIN_PB2) // For use with ATTinyCore\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\". Saves 128 bytes program memory.\n#define IR_RECEIVE_PIN   PIN_PB2 // INT0\n#define IR_SEND_PIN      PIN_PA4\n#define TONE_PIN         PIN_PA3\n#define _IR_TIMING_TEST_PIN PIN_PA5\n\n#  elif defined(__AVR_ATtiny88__) && defined(PIN_PD3) // MH-ET Tiny88 board. For use with ATTinyCore.\n#include \"ATtinySerialOut.hpp\" // Available as Arduino library \"ATtinySerialOut\". Saves 128 bytes program memory.\n// Pin 6 is TX, pin 7 is RX\n#define IR_RECEIVE_PIN   PIN_PD3 // 3 - INT1\n#define IR_SEND_PIN      PIN_PD4 // 4\n#define TONE_PIN         PIN_PB1 // 9\n#define _IR_TIMING_TEST_PIN PIN_PB0 // 8\n\n#  elif (defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)) && defined(PIN_PA1) // For use with megaTinyCore\n// Tiny Core Dev board\n// https://www.tindie.com/products/xkimi/tiny-core-16-dev-board-attiny1616/ - Out of Stock\n// https://www.tindie.com/products/xkimi/tiny-core-32-dev-board-attiny3217/ - Out of Stock\n#define IR_RECEIVE_PIN   PIN_PA1 // 14 use 18 instead of PIN_PA1 for TinyCore32\n#define IR_SEND_PIN      PIN_PA2 // 15, 19 for TinyCore32\n#define TONE_PIN         PIN_PA3 // 16, 20 for TinyCore32\n#define APPLICATION_PIN  PIN_PC3 // 13, PIN_PA0 is RESET\n#undef LED_BUILTIN               // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output\n#define LED_BUILTIN      PIN_PA6 // use 2 instead of PIN_PA6 for TinyCore32\n\n#  elif defined(__AVR_ATtiny816__) && defined(PIN_PA1) // For use with megaTinyCore\n#define IR_RECEIVE_PIN  PIN_PA1 // 14\n#define IR_SEND_PIN     PIN_PA3 // 16\n#define TONE_PIN        PIN_PA5 // 1\n#define APPLICATION_PIN PIN_PA4 // 0\n#undef LED_BUILTIN              // No LED available, take the one which is connected to the DAC output\n#define LED_BUILTIN     PIN_PB5 // 4\n\n#  elif defined(__AVR_ATtiny1604__) && defined(PIN_PA1) // For use with megaTinyCore\n#define IR_RECEIVE_PIN   PIN_PA1 // 8\n#define IR_SEND_PIN      PIN_PA7 // 3\n#define TONE_PIN         PIN_PA3 // 1  TCA0-WO3\n#define APPLICATION_PIN  PIN_PB2 // 5\n\n#  elif defined(__AVR_ATtiny1614__) && defined(PIN_PA1) // For use with megaTinyCore\n#define IR_RECEIVE_PIN   PIN_PA1 // 8\n#define IR_SEND_PIN      PIN_PA5 // 10 TCA0-WO5\n#define TONE_PIN         PIN_PA3 // 1  TCA0-WO3\n#define APPLICATION_PIN  PIN_PA4 // 0\n\n#  elif  defined(__AVR_ATtiny1624__) && defined(PIN_PA6) // For use with megaTinyCore\n#define IR_RECEIVE_PIN   PIN_PA1 // 8\n#define IR_SEND_PIN      PIN_PA5 // 3  TCA0-WO5\n#define TONE_PIN         PIN_PA3 // 1  TCA0-WO3\n#define APPLICATION_PIN  PIN_PB1 // 6\n\n#  elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \\\n|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \\\n|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \\\n|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \\\n|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \\\n|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \\\n|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \\\n|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \\\n|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN        13\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#  else // Default as for ATmega328 like on Uno, Nano, Leonardo, Teensy 2.0 etc.\n#define IR_RECEIVE_PIN      2 // To be compatible with interrupt example, pin 2 is chosen here.\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#    if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit\n// We have no built in LED at pin 13 -> reuse RX LED\n#undef LED_BUILTIN\n#define LED_BUILTIN         LED_BUILTIN_RX\n#    endif\n#  endif // defined(__AVR_ATtiny25__)...\n\n#elif defined(ARDUINO_ARCH_RENESAS_UNO) // Uno R4\n// To be compatible with Uno R3.\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#elif defined(ESP8266)\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW\n#define IR_RECEIVE_PIN          14 // D5\n#define IR_SEND_PIN             12 // D6 - D4/pin 2 is internal LED\n#define _IR_TIMING_TEST_PIN      2 // D4\n#define APPLICATION_PIN         13 // D7\n\n#define tone(...) void()      // tone() inhibits receive timer\n#define noTone(a) void()\n#define TONE_PIN                42 // Dummy for examples using it#\n\n#elif defined(ARDUINO_NOLOGO_ESP32C3_SUPER_MINI)\n// ESP32 - C3 super mini\n#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D8) is active LOW\n#define IR_RECEIVE_PIN           2\n#define IR_SEND_PIN              3\n#define TONE_PIN                 4\n#define APPLICATION_PIN         10\n\n#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32C3_DEV)\n// ESP32 - C3 other\n#define NO_LED_FEEDBACK_CODE   // The  WS2812 on pin 8 of AI-C3 board crashes if used as receive feedback LED, other I/O pins are working...\n#define IR_RECEIVE_PIN           6\n#define IR_SEND_PIN              7\n#define TONE_PIN                 9\n#define APPLICATION_PIN         10\n\n#elif defined(CONFIG_IDF_TARGET_ESP32S3) || defined(ARDUINO_ESP32S3_DEV)\n// ESP32 - S3 - !!! NOT tested !!!\n#define IR_RECEIVE_PIN          15 // alternatively 13\n#define IR_SEND_PIN             16 // alternatively 14\n#define TONE_PIN                17\n#define APPLICATION_PIN         18\n\n#elif defined(ESP32)\n#include <Arduino.h>\n\n// tone() is included in ESP32 core since 2.0.2\n#  if !defined(ESP_ARDUINO_VERSION)\n#define ESP_ARDUINO_VERSION 0x010101 // Version 1.1.1\n#  endif\n#  if !defined(ESP_ARDUINO_VERSION_VAL)\n#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#  endif\n#if ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n#define TONE_LEDC_CHANNEL        1  // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n}\nvoid tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){\n    ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);\n    ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);\n    delay(aDuration);\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\nvoid noTone(uint8_t aPinNumber){\n    ledcWriteTone(TONE_LEDC_CHANNEL, 0);\n}\n#endif // ESP_ARDUINO_VERSION  <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)\n\n#define IR_RECEIVE_PIN          15  // D15\n#define IR_SEND_PIN              4  // D4\n#define TONE_PIN                27  // D27 25 & 26 are DAC0 and 1\n#define APPLICATION_PIN         16  // RX2 pin\n\n#elif (defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1)) && defined(PA6) // BluePill\n// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone()\n#define IR_RECEIVE_PIN          PA6\n#define IR_RECEIVE_PIN_STRING   \"PA6\"\n#define IR_SEND_PIN             PA7\n#define IR_SEND_PIN_STRING      \"PA7\"\n#define TONE_PIN                PA3\n#define _IR_TIMING_TEST_PIN     PA5\n#define APPLICATION_PIN         PA2\n#define APPLICATION_PIN_STRING  \"PA2\"\n#  if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8)\n// BluePill LED is active low\n#define FEEDBACK_LED_IS_ACTIVE_LOW\n#  endif\n\n#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards\n#define IR_RECEIVE_PIN  11\n#define IR_SEND_PIN     12\n#define TONE_PIN         5\n\n#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE and Arduino Nano Connect layout for MBED\n// Must be before ARDUINO_ARCH_RP2040, since it is the layout for the MBED core of Arduino Nano Connect\n#define IR_RECEIVE_PIN      3   // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico\n#define IR_SEND_PIN         4   // GPIO16\n#define TONE_PIN            5\n#define APPLICATION_PIN     6\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 8\n\n#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico\n#define IR_RECEIVE_PIN      15  // GPIO15 to be compatible with the Arduino Nano RP2040 Connect (pin3)\n#define IR_SEND_PIN         16  // GPIO16\n#define TONE_PIN            17\n#define APPLICATION_PIN     18\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 20\n\n// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN\n// and use the external reset with 1 kOhm to ground to enter UF2 mode\n#undef LED_BUILTIN\n#define LED_BUILTIN          6\n\n#elif defined(PARTICLE) && defined(A4) // !!!UNTESTED!!!\n#define IR_RECEIVE_PIN      A4\n#define IR_SEND_PIN         A5 // Particle supports multiple pins\n\n#define LED_BUILTIN         D7\n\n/*\n * 4 times the same (default) layout for easy adaption in the future\n */\n#elif defined(TEENSYDUINO) // Teensy 2.0 is handled at default for ATmega328 like on Uno, Nano, Leonardo etc.\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)\n#  if defined(USE_ARDUINO_MKR_PIN_LAYOUT)\n#define IR_RECEIVE_PIN      1 // Pin 2 on MKR is not interrupt capable, see https://www.arduino.cc/reference/tr/language/functions/external-interrupts/attachinterrupt/\n#  else\n#define IR_RECEIVE_PIN      2\n#  endif\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n\n#if !defined(ARDUINO_SAMD_ADAFRUIT) && !defined(ARDUINO_SEEED_XIAO_M0)\n// On the Zero and others we switch explicitly to SerialUSB\n#define Serial SerialUSB\n#endif\n\n// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.\n// Attention!!! D2 and D4 are swapped on these boards!!!\n// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 24 // PB11\n// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.\n//#undef LED_BUILTIN\n//#define LED_BUILTIN 25 // PB03\n//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW\n\n#elif defined (NRF51) // BBC micro:bit\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define APPLICATION_PIN     1\n#define _IR_TIMING_TEST_PIN 4\n\n#define tone(...) void()    // no tone() available\n#define noTone(a) void()\n#define TONE_PIN           42 // Dummy for examples using it\n\n#else\n#warning Board and Core / CPU is not detected using pre-processor symbols -> using default values for IR_RECEIVE_PIN etc., which may not fit. Please extend PinDefinitionsAndMore.h.\n// Default valued for unidentified boards\n#define IR_RECEIVE_PIN      2\n#define IR_SEND_PIN         3\n#define TONE_PIN            4\n#define APPLICATION_PIN     5\n#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.\n#define _IR_TIMING_TEST_PIN 7\n#endif // defined(ESP8266)\n\n#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED)\n#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation\n#else\n# if defined(SEND_PWM_BY_TIMER)\n#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warnings in IRremote.hpp and IRTimer.hpp\n#  endif\n#endif\n\n#if !defined (FLASHEND)\n#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined\n#endif\n\n#if !defined (RAMEND)\n#define RAMEND 0x0FFF // Dummy value for platforms where RAMEND is not defined\n#endif\n"
  },
  {
    "path": "examples/TinySender/TinySender.ino",
    "content": "/*\n * TinySender.cpp\n *\n *  Example for sending using TinyIR. By default sends simultaneously using all supported protocols\n *  To use a single protocol, simply delete or comment out all unneeded protocols in the main loop\n *  Program size is significantly reduced when using a single protocol\n *  For example, sending only 8 bit address and command NEC codes saves 780 bytes program memory and 26 bytes RAM compared to SimpleSender,\n *  which does the same, but uses the IRRemote library (and is therefore much more flexible).\n *\n *\n * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header.\n *  FAST Protocol characteristics:\n * - Bit timing is like NEC or JVC\n * - The header is shorter, 3156 vs. 12500\n * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command,\n *     leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms.\n * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance.\n *\n *\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *  This file is also part of IRMP https://github.com/IRMP-org/IRMP.\n *\n ************************************************************************************\n * MIT License\n *\n * Copyright (c) 2022-2024 Armin Joachimsmeyer\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished\n * to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\n * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\n * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n ************************************************************************************\n */\n#include <Arduino.h>\n\n#include \"PinDefinitionsAndMore.h\" // Set IR_SEND_PIN for different CPU's\n\n#include \"TinyIRSender.hpp\"\n\nvoid setup() {\n    pinMode(LED_BUILTIN, OUTPUT);\n\n    Serial.begin(115200);\n\n    // Just to know which program is running on my Arduino\n    Serial.println(F(\"START \" __FILE__ \" from \" __DATE__ \"\\r\\nUsing library version \" VERSION_TINYIR));\n    Serial.print(F(\"Send IR signals at pin \"));\n    Serial.println(IR_SEND_PIN);\n}\n\n/*\n * Set up the data to be sent.\n * The compiler is intelligent and removes the code for 16 bit address handling if we call it with an uint8_t address :-).\n * Using an uint16_t address or data requires additional 28 bytes program memory for NEC and 56 bytes program memory for FAST.\n */\nuint8_t sAddress = 0x02;\n//uint16_t sAddress = 0x02;\nuint8_t sCommand = 0x34;\n//uint16_t sCommand = 0x34;\nuint8_t sRepeats = 0;\n\nvoid loop() {\n    /*\n     * Print current send values\n     */\n    Serial.println();\n    Serial.print(F(\"Send now:\"));\n    Serial.print(F(\" address=0x\"));\n    Serial.print(sAddress, HEX);\n    Serial.print(F(\" command=0x\"));\n    Serial.print(sCommand, HEX);\n    Serial.print(F(\" repeats=\"));\n    Serial.print(sRepeats);\n    Serial.println();\n\n    // Send with FAST\n    // No address and only 16 bits of data, interpreted as 8 bit command and 8 bit inverted command for parity checking\n    Serial.println(F(\"Send FAST with 8 bit command\"));\n    Serial.flush();\n    sendFAST(IR_SEND_PIN, sCommand, sRepeats);\n\n    // Send with NEC\n    // NEC uses 8 bit address and 8 bit command each with 8 bit inverted parity checks\n    // However, sendNEC will accept 16 bit address and commands too (but remove the parity checks)\n    Serial.println(F(\"Send NEC with 8 bit address and command\"));\n    Serial.flush();\n    sendNEC(IR_SEND_PIN, sAddress, sCommand, sRepeats);\n\n    // Send with Extended NEC\n    // Like NEC, but the address is forced 16 bits with no parity check\n    Serial.println(F(\"Send ExtendedNEC with 16 bit address and  8 bit command\"));\n    Serial.flush();\n    sendExtendedNEC(IR_SEND_PIN, sAddress, sCommand, sRepeats);\n\n    // Send with ONKYO\n    // Like NEC, but both the address and command are forced 16 bits with no parity check\n    Serial.println(F(\"Send ONKYO with 16 bit address and command\"));\n    Serial.flush();\n    sendONKYO(IR_SEND_PIN, sAddress, sCommand, sRepeats);\n\n    // Send with NEC2\n    // Instead of sending the NEC special repeat code, sends the full original frame for repeats\n    // Sending NEC2 is done by setting the optional bool NEC2Repeats argument to true (defaults to false)\n    // sendExtendedNEC and sendONKYO also support the NEC2Repeats argument for full frame repeats (not demonstrated here)\n    Serial.println(F(\"Send NEC2 with 8 bit address and command and original frame repeats\"));\n    Serial.flush();\n    sendNEC(IR_SEND_PIN, sAddress, sCommand, sRepeats, true);\n\n    /*\n     * Increment send values\n     * Also increment address just for demonstration, which normally makes no sense\n     */\n    sAddress += 0x0101;\n    sCommand += 0x11;\n    sRepeats++;\n    // clip repeats at 4\n    if (sRepeats > 4) {\n        sRepeats = 4;\n    }\n\n    delay(1000);  // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal\n}\n"
  },
  {
    "path": "keywords.txt",
    "content": "#######################################\n# Syntax Coloring Map For IRMP\n#######################################\n\n#######################################\n# Datatypes (KEYWORD1)\n#######################################\n\nirmp_protocol_names\tKEYWORD1\nIRMP_DATA\tKEYWORD1\n\n#######################################\n# Methods and Functions (KEYWORD2)\n#######################################\n\nirmp_init\tKEYWORD2\nirmp_register_complete_callback_function\tKEYWORD2\nirmp_IsBusy\tKEYWORD2\nirmp_print_active_protocols\tKEYWORD2\nirmp_get_data\tKEYWORD2\nirmp_result_print\tKEYWORD2\nirsnd_init\tKEYWORD2\nirsnd_send_data\tKEYWORD2\nirsnd_data_print\tKEYWORD2\nirsnd_is_busy\tKEYWORD2\nirmp_irsnd_LEDFeedback\tKEYWORD2\ndisableIRTimerInterrupt\tKEYWORD2\nenableIRTimerInterrupt\tKEYWORD2\nstoreIRTimer\tKEYWORD2\nrestoreIRTimer\tKEYWORD2\n\n#######################################\n# Constants (LITERAL1)\n#######################################\n\nIRMP_FLAG_REPETITION\tLITERAL1\nIRMP_FLAG_RELEASE\tLITERAL1\nIRMP_PROTOCOL_NAMES\tLITERAL1\nIRMP_USE_COMPLETE_CALLBACK\tLITERAL1\nF_INTERRUPTS\tLITERAL1\nIRSND_IR_FREQUENCY\tLITERAL1\nIR_OUTPUT_IS_ACTIVE_LOW\tLITERAL1\nIRMP_ENABLE_PIN_CHANGE_INTERRUPT\tLITERAL1\nUSE_ONE_TIMER_FOR_IRMP_AND_IRSND\tLITERAL1\nIRMP_ENABLE_RELEASE_DETECTION\tLITERAL1\nIRMP_HIGH_ACTIVE\tLITERAL1\n"
  },
  {
    "path": "library.json",
    "content": "{\n  \"name\": \"IRMP\",\n  \"version\": \"3.7.0\",\n  \"keywords\": \"infrared, ir, remote\",\n  \"description\": \"Receive and Send infrared signals from your remote.\",\n  \"homepage\": \"https://github.com/IRMP-org/IRMP\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/IRMP-org/IRMP.git\"\n  },\n  \"authors\":  [\n    {\n      \"name\": \"Armin Joachimsmeyer\",\n      \"email\": \"armin.arduino@gmail.com\",\n      \"maintainer\": true\n    },\n    {\n      \"name\": \"Frank Meyer\",\n      \"email\": \"frank@fli4l.de\"\n    }\n  ],\n  \"license\": \"GPL-3.0-or-later\",\n  \"frameworks\": \"arduino\",\n  \"platforms\": [\"atmelavr\", \"atmelmegaavr\", \"atmelsam\", \"espressif8266\", \"espressif32\", \"ststm32\"],\n  \"headers\": [\"irmp.hpp\", \"irsnd.hpp\"],\n  \"examples\": \"examples/*/*.ino\",\n  \"export\": {\"exclude\": [\".github\", \"pictures\"]}\n}"
  },
  {
    "path": "library.properties",
    "content": "name=IRMP\nversion=3.7.0\nauthor=Frank Meyer, Armin Joachimsmeyer\nmaintainer=Armin Joachimsmeyer <armin.arduino@gmail.com>, frank@fli4l.de\nsentence=Receive and send infrared signals.<br/>\nparagraph=Supports 50 different IR and 3 RF protocols. Can receive 40 protocols concurrently. Supports ATtiny, AVR and MegaAVR boards as well as ESP8266, ESP32, STM32, SAMD, RP2040 and Apollo boards.\ncategory=Signal Input/Output\nurl=https://github.com/IRMP-org/IRMP\narchitectures=avr,megaavr,samd,esp8266,esp32,stm32,STM32F1,apollo3,mbed,mbed_nano,rp2040\nincludes=irmp.hpp\n"
  },
  {
    "path": "src/IRCommandDispatcher.h",
    "content": "/*\n * IRCommandDispatcher.h\n *\n * Library to process IR commands by calling functions specified in a mapping array.\n *\n * To run this example you need to install the \"IRremote\" or \"IRMP\" library under \"Tools -> Manage Libraries...\" or \"Ctrl+Shift+I\"\n *\n *  Copyright (C) 2019-2026  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of ServoEasing https://github.com/ArminJo/ServoEasing.\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  IRCommandDispatcher is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n */\n\n#ifndef _IR_COMMAND_DISPATCHER_H\n#define _IR_COMMAND_DISPATCHER_H\n\n#include <stdint.h>\n\n//#define DISPATCHER_IR_COMMAND_HAS_MORE_THAN_8_BIT // Enables mapping and dispatching of IR commands consisting of more than 8 bits. Saves up to 160 bytes program memory and 5 bytes RAM + 1 byte RAM per mapping entry.\n//#define USE_DISPATCHER_COMMAND_STRINGS // Enables the printing of command strings. Requires additional 2 bytes RAM for each command mapping. Requires program memory for strings, but saves snprintf() code (1.5k) if INFO or DEBUG is activated, which has no effect if snprintf() is also used in other parts of your program / libraries.\n#if defined(USE_DISPATCHER_COMMAND_STRINGS)\n#define COMMAND_STRING(anyString)   anyString\n#else\n#define COMMAND_STRING(anyString)\n#endif\n/*\n * For command mapping file\n */\n#define IR_COMMAND_FLAG_BLOCKING        0x00 // default - blocking command, repeat not accepted, only one command at a time. Stops an already running command.\n#define IR_COMMAND_FLAG_REPEATABLE      0x01 // repeat accepted\n#define IR_COMMAND_FLAG_NON_BLOCKING    0x02 // Non blocking (short) command that can be processed any time and may interrupt other IR commands - used for stop, set direction etc.\n#define IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING (IR_COMMAND_FLAG_REPEATABLE | IR_COMMAND_FLAG_NON_BLOCKING)\n#define IR_COMMAND_FLAG_BEEP            0x04 // Do a single short beep before executing command. May not be useful for short or repeating commands.\n#define IR_COMMAND_FLAG_BLOCKING_BEEP   (IR_COMMAND_FLAG_BLOCKING | IR_COMMAND_FLAG_BEEP)\n\n#if !defined(IS_STOP_REQUESTED)\n#define IS_STOP_REQUESTED               IRDispatcher.requestToStopReceived\n#endif\n#if !defined(RETURN_IF_STOP)\n#define RETURN_IF_STOP                  if (IRDispatcher.requestToStopReceived) return\n#endif\n#if !defined(BREAK_IF_STOP)\n#define BREAK_IF_STOP                   if (IRDispatcher.requestToStopReceived) break\n#endif\n#if !defined(DELAY_AND_RETURN_IF_STOP)\n#define DELAY_AND_RETURN_IF_STOP(aDurationMillis)   if (IRDispatcher.delayAndCheckForStop(aDurationMillis)) return\n#endif\n\n/*\n * Define as COMMAND_EMPTY a code which is not sent by the remote - otherwise please redefine it here\n */\n#if defined(DISPATCHER_IR_COMMAND_HAS_MORE_THAN_8_BIT)\n#define COMMAND_EMPTY       __UINT_FAST16_MAX__ // 0xFFFF code no command\ntypedef uint_fast16_t IRCommandType;\n#else\ntypedef uint_fast8_t IRCommandType;\n#define COMMAND_EMPTY       __UINT_FAST8_MAX__ // 0xFF code no command\n#endif\n\n// Basic mapping structure\nstruct IRToCommandMappingStruct {\n    IRCommandType IRCode;\n    uint8_t Flags;\n    void (*CommandToCall)();\n#if defined(USE_DISPATCHER_COMMAND_STRINGS)\n    const char *CommandString;\n#endif\n};\n\nstruct IRDataForCommandDispatcherStruct {\n    uint16_t address;           // to distinguish between multiple senders\n    IRCommandType command;\n    bool isRepeat;\n    volatile uint32_t MillisOfLastCode;  // millis() of last IR command -including repeats!- received - for timeouts etc.\n    volatile bool isAvailable; // flag for a polling interpreting function, that a new command has arrived. Is set true by library and set false by main loop.\n};\n\nclass IRCommandDispatcher {\npublic:\n    void init();\n    void printIRInfo(Print *aSerial);\n\n    bool checkAndRunNonBlockingCommands();\n    bool checkAndRunSuspendedBlockingCommands();\n    void setNextBlockingCommand(IRCommandType aBlockingCommandToRunNext);\n    bool delayAndCheckForStop(uint16_t aDelayMillis);\n\n    // The main dispatcher function\n    void checkAndCallCommand(bool aCallBlockingCommandImmediately);\n\n    void printIRCommandString(Print *aSerial, IRCommandType aCommand);\n    void printIRCommandStringForArrayIndex(Print *aSerial, uint_fast8_t aMappingArrayIndex);\n    void setRequestToStopReceived(bool aRequestToStopReceived = true);\n\n    IRCommandType currentBlockingCommandCalled = COMMAND_EMPTY; // The code for the current called command\n    IRCommandType lastBlockingCommandCalled = COMMAND_EMPTY;  // The code for the last called command. Can be evaluated by main loop\n    IRCommandType BlockingCommandToRunNext = COMMAND_EMPTY; // Storage for command currently suspended to allow the current command to end, before it is called by main loop\n    bool justCalledBlockingCommand = false;  // Flag that a blocking command was received and called - is set before call of command\n    /*\n     * Flag for running blocking commands to terminate. To check, you can use \"if (IRDispatcher.requestToStopReceived) return;\" (available as macro RETURN_IF_STOP).\n     * It is set if a blocking IR command received, which cannot be executed directly. Can be reset by main loop, if command has stopped.\n     * It is reset before executing a blocking command.\n     */\n    volatile bool requestToStopReceived;\n    /*\n     * This flag must be true, if we have a function, which want to interpret the IR codes by itself e.g. the calibrate function of QuadrupedControl\n     */\n    bool doNotUseDispatcher = false;\n\n    struct IRDataForCommandDispatcherStruct IRReceivedData;\n\n};\n\nextern IRCommandDispatcher IRDispatcher;\n\n#endif // _IR_COMMAND_DISPATCHER_H\n"
  },
  {
    "path": "src/IRCommandDispatcher.hpp",
    "content": "/*\n * IRCommandDispatcher.hpp\n *\n * Library to process IR commands by calling functions specified in a mapping array.\n * Commands can be tagged as blocking or non blocking.\n *\n * To run this example you need to install the \"IRremote\" or \"IRMP\" library.\n * Install it under \"Tools -> Manage Libraries...\" or \"Ctrl+Shift+I\"\n *\n * The IR library calls a callback function, which executes a non blocking command directly in ISR (Interrupt Service Routine) context!\n * A blocking command is stored and sets a stop flag for an already running blocking function to terminate.\n * The blocking command can in turn be executed by main loop by calling IRDispatcher.checkAndRunSuspendedBlockingCommands().\n *\n *  Copyright (C) 2019-2026  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of ServoEasing https://github.com/ArminJo/ServoEasing.\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *\n *  IRCommandDispatcher is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n */\n\n/*\n * Program behavior is modified by the following macros\n * USE_TINY_IR_RECEIVER\n * USE_IRMP_LIBRARY\n * DISPATCHER_IR_COMMAND_HAS_MORE_THAN_8_BIT\n */\n\n#ifndef _IR_COMMAND_DISPATCHER_HPP\n#define _IR_COMMAND_DISPATCHER_HPP\n\n#include <Arduino.h>\n\n#include \"IRCommandDispatcher.h\"\n\n//#define NO_LED_FEEDBACK_CODE   // Activate this if you want to suppress LED feedback or if you do not have a LED. This saves 14 bytes code and 2 clock cycles per interrupt.\n\n//#define USE_TINY_IR_RECEIVER // Recommended and default, but only for NEC protocol!!! If disabled and IRMP_INPUT_PIN is defined, the IRMP library is used for decoding\n//#define USE_IRREMOTE_LIBRARY // The IRremote library is used for decoding\n//#define USE_IRMP_LIBRARY     // The IRMP library is used for decoding\n#if !defined(USE_TINY_IR_RECEIVER) && !defined(USE_IRREMOTE_LIBRARY) && !defined(USE_IRMP_LIBRARY)\n#define USE_TINY_IR_RECEIVER // Set TiniIR as default library\n#endif\n\nIRCommandDispatcher IRDispatcher;\n\n#if defined(USE_TINY_IR_RECEIVER)\n/******************************\n * Code for the TinyIR library\n ******************************/\n#if defined(USE_ONKYO_PROTOCOL) && ! defined(DISPATCHER_IR_COMMAND_HAS_MORE_THAN_8_BIT)\n#warning ONKYO protocol has 16 bit commands so activating of DISPATCHER_IR_COMMAND_HAS_MORE_THAN_8_BIT is recommended\n#endif\n#define USE_CALLBACK_FOR_TINY_RECEIVER  // Call the function \"handleReceivedTinyIRData()\" below each time a frame or repeat is received.\n#include \"TinyIRReceiver.hpp\" // included in \"IRremote\" and \"IRMP\" library\n\n// This block must be located after the includes of other *.hpp files\n//#define LOCAL_INFO  // This enables info output only for this file\n//#define LOCAL_DEBUG // This enables debug output only for this file - only for development\n//#define LOCAL_TRACE // This enables trace output only for this file - only for development\n#include \"LocalDebugLevelStart.h\"\n\nvoid IRCommandDispatcher::init() {\n    initPCIInterruptForTinyIRReceiver();\n}\n/*\n * This is the TinyIRReceiver callback function, which is called if a complete command was received.\n * Interrupts are enabled here to allow e.g. delay() in commands.\n * Copy the (volatile) IR data in order not to be overwritten on receiving of next frame.\n * Next, check for right address if IR_ADDRESS is defined.\n * At last call the dispatcher.\n */\n#  if defined(ESP8266) || defined(ESP32)\nIRAM_ATTR\n#  endif\nvoid handleReceivedTinyIRData() {\n    IRDispatcher.IRReceivedData.address = TinyIRReceiverData.Address;\n    IRDispatcher.IRReceivedData.command = TinyIRReceiverData.Command;\n    IRDispatcher.IRReceivedData.isRepeat = TinyIRReceiverData.Flags & IRDATA_FLAGS_IS_REPEAT;\n    IRDispatcher.IRReceivedData.MillisOfLastCode = millis();\n\n#  if defined(LOCAL_INFO)\n    printTinyIRReceiverResultMinimal(&Serial);\n#  endif\n\n#  if defined(IR_ADDRESS)\n    // if available, compare address. TinyIRReceiverData.Address saves 6 bytes\n    if (TinyIRReceiverData.Address != IR_ADDRESS) { // IR_ADDRESS is defined in *IRCommandMapping.h\n        INFO_PRINT(F(\"Wrong address. Expected 0x\"));\n        INFO_PRINTLN(IR_ADDRESS, HEX);\n    } else\n#  endif\n    {\n        IRDispatcher.IRReceivedData.isAvailable = true;\n        // check if dispatcher enabled\n        if (!IRDispatcher.doNotUseDispatcher) {\n            /*\n             * Only short (non blocking) commands are executed directly in ISR (Interrupt Service Routine) context,\n             * others are stored for main loop which calls checkAndRunSuspendedBlockingCommands()\n             */\n            IRDispatcher.checkAndCallCommand(false);\n        }\n    }\n}\n\n#elif defined(USE_IRREMOTE_LIBRARY)\n/*********************************\n * Code for the IRremote library\n *********************************/\n#define DECODE_NEC          // Includes Apple and Onkyo\n#include \"IRremote.hpp\"\n\n// This block must be located after the includes of other *.hpp files\n//#define LOCAL_INFO  // This enables info output only for this file\n//#define LOCAL_DEBUG // This enables debug output only for this file - only for development\n//#define LOCAL_TRACE // This enables trace output only for this file - only for development\n#include \"LocalDebugLevelStart.h\"\n\nvoid ReceiveCompleteCallbackHandler();\n\nvoid IRCommandDispatcher::init() {\n    // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED\n    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);\n    /*\n     * Tell the ISR to call this function, when a complete frame has been received\n     */\n    IrReceiver.registerReceiveCompleteCallback(ReceiveCompleteCallbackHandler);\n}\n\n/*\n * Callback function\n * Here we know, that data is available.\n * This function is executed in an ISR (Interrupt Service Routine) context.\n * This means that interrupts are blocked here, so delay(), millis() and Serial prints of data longer than the print buffer size etc. will block forever.\n * This is because they require their internal interrupt routines to run in order to return.\n * Therefore it is best to make this callback function short and fast!\n * A dirty hack is to enable interrupts again by calling sei() (enable interrupt again), but you should know what you are doing,\n */\n#if defined(ESP32) || defined(ESP8266)\nIRAM_ATTR\n# endif\nvoid ReceiveCompleteCallbackHandler() {\n    /*\n     * Fill IrReceiver.decodedIRData\n     */\n    IrReceiver.decode();\n\n    IRDispatcher.IRReceivedData.address = IrReceiver.decodedIRData.address;\n    IRDispatcher.IRReceivedData.command = IrReceiver.decodedIRData.command;\n    IRDispatcher.IRReceivedData.isRepeat = IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT;\n    IRDispatcher.IRReceivedData.MillisOfLastCode = millis();\n\n    // Interrupts are already enabled for SUPPORT_MULTIPLE_RECEIVER_INSTANCES\n#if !defined(SUPPORT_MULTIPLE_RECEIVER_INSTANCES)  && !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) // no Serial etc. possible in callback for RTOS based cores like ESP, even when interrupts are enabled\n    interrupts(); // To enable tone(), delay() etc. for commands. Be careful with non-blocking and repeatable commands which lasts longer than the IR repeat duration.\n#  endif\n\n#  if defined(LOCAL_INFO)\n    IrReceiver.printIRResultMinimal(&Serial);\n    Serial.println();\n#  endif\n    /*\n     * Enable receiving of the next frame.\n     */\n    IrReceiver.resume();\n\n#  if defined(IR_ADDRESS)\n    // if available, compare address\n    if (IRDispatcher.IRReceivedData.address != IR_ADDRESS) { // IR_ADDRESS is defined in *IRCommandMapping.h\n        INFO_PRINT(F(\"Wrong address. Expected 0x\"));\n        INFO_PRINTLN(IR_ADDRESS, HEX);\n    } else\n#  endif\n    {\n        IRDispatcher.IRReceivedData.isAvailable = true;\n        // check if dispatcher enabled\n        if (!IRDispatcher.doNotUseDispatcher) {\n            /*\n             * Only short (non blocking) commands are executed directly in ISR (Interrupt Service Routine) context,\n             * others are stored for main loop which calls checkAndRunSuspendedBlockingCommands()\n             */\n            IRDispatcher.checkAndCallCommand(false);\n        }\n    }\n}\n\n#elif defined(USE_IRMP_LIBRARY)\n/******************************\n * Code for the IRMP library\n ******************************/\n#define IRMP_USE_COMPLETE_CALLBACK  1 // Enable callback functionality. It is required if IRMP library is used.\n#define IRMP_PROTOCOL_NAMES         1 // Enable protocol number mapping to protocol strings for printIRInfo()\n#include \"irmp.hpp\"\n#include \"LocalDebugLevelStart.h\"\n\nIRMP_DATA irmp_data;\n\nvoid handleReceivedIRData();\n\nvoid IRCommandDispatcher::init()\n{\n    irmp_init();\n    irmp_register_complete_callback_function(&handleReceivedIRData); // fixed function in IRCommandDispatcher.hpp\n}\n\n/*\n * This is the callback function, which is called if a complete command was received.\n * Interrupts are NOT enabled here so we must do it manually to allow e.g. delay() in commands.\n * Copy the (volatile) IR data in order not to be overwritten on receiving of next frame.\n * Next, check for right address if IR_ADDRESS is defined.\n * At last call the dispatcher.\n */\n#if defined(ESP8266) || defined(ESP32)\nIRAM_ATTR\n#endif\nvoid handleReceivedIRData()\n{\n    irmp_get_data(&irmp_data);\n\n    IRDispatcher.IRReceivedData.address = irmp_data.address;\n    IRDispatcher.IRReceivedData.command = irmp_data.command;\n    IRDispatcher.IRReceivedData.isRepeat = irmp_data.flags & IRMP_FLAG_REPETITION;\n    IRDispatcher.IRReceivedData.MillisOfLastCode = millis();\n\n#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) // no Serial etc. possible in callback for RTOS based cores like ESP, even when interrupts are enabled\n    interrupts(); // To enable tone(), delay() etc. for commands. Be careful with non-blocking and repeatable commands which lasts longer than the IR repeat duration.\n#  endif\n\n#  if defined(LOCAL_INFO)\n    irmp_result_print(&Serial, &irmp_data);\n#  endif\n\n#  if defined(IR_ADDRESS)\n    // if available, compare address\n    if (IRDispatcher.IRReceivedData.address != IR_ADDRESS) {\n        INFO_PRINT(F(\"Wrong address. Expected 0x\"));\n        INFO_PRINTLN(IR_ADDRESS, HEX);\n    } else\n#  endif\n    {\n        IRDispatcher.IRReceivedData.isAvailable = true;\n        // check if dispatcher enabled\n        if (!IRDispatcher.doNotUseDispatcher)\n        {\n            /*\n             * Only short (non blocking) commands are executed directly in ISR (Interrupt Service Routine) context,\n             * others are stored for main loop which calls checkAndRunSuspendedBlockingCommands()\n             */\n            IRDispatcher.checkAndCallCommand(false);\n        }\n    }\n}\n#endif // elif defined(USE_IRMP_LIBRARY)\n\n/*******************************************\n * Start of the IR library independent code\n *******************************************/\nvoid IRCommandDispatcher::printIRInfo(Print *aSerial) {\n    aSerial->println();\n    // For available IR commands see IRCommandMapping.h https://github.com/ArminJo/PWMMotorControl/blob/master/examples/SmartCarFollower/IRCommandMapping.h\n#if defined(USE_IRMP_LIBRARY)\n#  if defined(IR_REMOTE_NAME)\n    aSerial->println(F(\"Listening to IR remote of type \" STR(IR_REMOTE_NAME) \" at pin \" STR(IRMP_INPUT_PIN)));\n#  else\n    aSerial->println(F(\"Listening to IR remote at pin \" STR(IRMP_INPUT_PIN)));\n#  endif\n    aSerial->print(F(\"Accepted protocols are: \"));\n    irmp_print_active_protocols(&Serial);\n    aSerial->println();\n#else\n#  if defined(IR_REMOTE_NAME)\n    aSerial->println(F(\"Listening to IR remote of type \" STR(IR_REMOTE_NAME) \" at pin \" STR(IR_RECEIVE_PIN)));\n#  else\n    aSerial->println(F(\"Listening to IR remote at pin \" STR(IR_RECEIVE_PIN)));\n#  endif\n#endif\n}\n\n/*\n * The main dispatcher function called by IR-ISR, main loop and checkAndRunSuspendedBlockingCommands()\n * Non blocking commands are executed immediately, blocking commands are executed if no other command is just running.\n * If another blocking command is currently running, the request to stop is set\n * and the command is stored for main loop to be later execute by checkAndRunSuspendedBlockingCommands().\n * This function sets flags justCalledRegularIRCommand, executingBlockingCommand, requestToStopReceived\n * @param aCallBlockingCommandImmediately Run blocking command directly, if no other command is just running.\n *        Should be false if called by ISR in order not to block ISR. Is true when called from checkAndRunSuspendedBlockingCommands().\n */\nvoid IRCommandDispatcher::checkAndCallCommand(bool aCallBlockingCommandImmediately) {\n    if (IRReceivedData.command == COMMAND_EMPTY) {\n        return;\n    }\n\n    /*\n     * Search for command in Array of IRToCommandMappingStruct\n     */\n    for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) {\n        if (IRReceivedData.command == IRMapping[i].IRCode) {\n            /*\n             * Command found\n             */\n#if defined(LOCAL_INFO)\n#  if defined(__AVR__)\n#    if defined(USE_DISPATCHER_COMMAND_STRINGS)\n            const __FlashStringHelper *tCommandName = reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString);\n#    else\n            char tCommandName[7];\n            snprintf_P(tCommandName, sizeof(tCommandName), PSTR(\"0x%x\"), IRMapping[i].IRCode);\n#    endif\n#  else\n#    if defined(USE_DISPATCHER_COMMAND_STRINGS)\n            const char *tCommandName = IRMapping[i].CommandString;\n#    else\n            char tCommandName[7];\n            snprintf(tCommandName, sizeof(tCommandName), \"0x%x\", IRMapping[i].IRCode);\n#    endif\n#  endif\n#endif\n            /*\n             * Check for repeat and if repeat is allowed for the current command\n             */\n            if (IRReceivedData.isRepeat && !(IRMapping[i].Flags & IR_COMMAND_FLAG_REPEATABLE)) {\n\n                DEBUG_PRINT(F(\"Repeats of command \\\"\"));\n                DEBUG_PRINT(tCommandName);\n                DEBUG_PRINTLN(\"\\\" not accepted\");\n\n                return;\n            }\n\n            /*\n             * Do not accept recursive call of the same command\n             */\n            if (currentBlockingCommandCalled == IRReceivedData.command) {\n\n                DEBUG_PRINT(F(\"Recursive command \\\"\"));\n                DEBUG_PRINT(tCommandName);\n                DEBUG_PRINTLN(\"\\\" not accepted\");\n\n                return;\n            }\n\n            /*\n             * Execute commands\n             */\n            bool tIsNonBlockingCommand = (IRMapping[i].Flags & IR_COMMAND_FLAG_NON_BLOCKING);\n            if (tIsNonBlockingCommand) {\n                // short command here, just call\n                INFO_PRINT(F(\"Run non blocking command: \"));\n                INFO_PRINTLN(tCommandName);\n#if defined(DISPATCHER_BUZZER_FEEDBACK_PIN) && defined(USE_TINY_IR_RECEIVER)\n                    /*\n                     * Do (non blocking) buzzer feedback before command is executed\n                     */\n                    if(IRMapping[i].Flags & IR_COMMAND_FLAG_BEEP) {\n                        tone(DISPATCHER_BUZZER_FEEDBACK_PIN, 2200, 50);\n                    }\n#endif\n                IRMapping[i].CommandToCall();\n            } else {\n                /*\n                 * Blocking command here\n                 */\n                if (aCallBlockingCommandImmediately && currentBlockingCommandCalled == COMMAND_EMPTY) {\n                    /*\n                     * Here no blocking command was running and we are called from main loop\n                     */\n                    requestToStopReceived = false;  // Do not stop the command executed now\n                    justCalledBlockingCommand = true;\n                    currentBlockingCommandCalled = IRReceivedData.command;  // set lock for recursive calls\n                    lastBlockingCommandCalled = IRReceivedData.command;     // set history, can be evaluated by main loop\n\n                    /*\n                     * This call is blocking!!!\n                     */\n                    INFO_PRINT(F(\"Run blocking command: \"));\n                    INFO_PRINTLN(tCommandName);\n\n#if defined(DISPATCHER_BUZZER_FEEDBACK_PIN) && defined(USE_TINY_IR_RECEIVER)\n                    /*\n                     * Do (non blocking) buzzer feedback before command is executed\n                     */\n                    if(IRMapping[i].Flags & IR_COMMAND_FLAG_BEEP) {\n                        tone(DISPATCHER_BUZZER_FEEDBACK_PIN, 2200, 50);\n                    }\n#endif\n\n                    IRMapping[i].CommandToCall();\n                    TRACE_PRINTLN(F(\"End of blocking command\"));\n\n                    currentBlockingCommandCalled = COMMAND_EMPTY;\n                } else {\n                    /*\n                     * Called by ISR or another command still running.\n                     * Do not run command directly, but set request to stop to true and store command\n                     * for main loop to execute by checkAndRunSuspendedBlockingCommands()\n                     */\n                    BlockingCommandToRunNext = IRReceivedData.command;\n                    requestToStopReceived = true; // to stop running command\n                    INFO_PRINT(F(\"Requested stop and stored blocking command \"));\n                    INFO_PRINT(tCommandName);\n                    INFO_PRINTLN(F(\" as next command to run.\"));\n                }\n            }\n            break; // command found\n        } // if (IRReceivedData.command == IRMapping[i].IRCode)\n    } // for loop\n    return;\n}\n\n/*\n * Intended to be called from main loop\n * @return true, if command was called\n */\nbool IRCommandDispatcher::checkAndRunSuspendedBlockingCommands() {\n    /*\n     * Take last rejected command and call associated function\n     */\n    if (BlockingCommandToRunNext != COMMAND_EMPTY) {\n\n        INFO_PRINT(F(\"Run stored command=0x\"));\n        INFO_PRINTLN(BlockingCommandToRunNext, HEX);\n\n        IRReceivedData.command = BlockingCommandToRunNext;\n        BlockingCommandToRunNext = COMMAND_EMPTY;\n        IRReceivedData.isRepeat = false;\n        requestToStopReceived = false; // Signal to main loop to stop the command currently executed\n        checkAndCallCommand(true);\n        return true;\n    }\n    return false;\n}\n\n/*\n * Not used internally\n */\nvoid IRCommandDispatcher::setNextBlockingCommand(IRCommandType aBlockingCommandToRunNext) {\n#if defined(LOCAL_INFO)\n    Serial.print(F(\"Set next command to run to 0x\"));\n    Serial.print(aBlockingCommandToRunNext, HEX);\n#  if defined(USE_DISPATCHER_COMMAND_STRINGS)\n    Serial.print('|');\n    printIRCommandString(&Serial, aBlockingCommandToRunNext);\n#  endif\n    Serial.println();\n#endif\n\n    BlockingCommandToRunNext = aBlockingCommandToRunNext;\n    requestToStopReceived = true;\n}\n\n/*\n * Special delay function for the IRCommandDispatcher. Returns prematurely if requestToStopReceived is set.\n * To be used in blocking functions as delay\n * @return  true - as soon as stop received\n */\nbool IRCommandDispatcher::delayAndCheckForStop(uint16_t aDelayMillis) {\n    uint32_t tStartMillis = millis();\n    do {\n        if (requestToStopReceived) {\n            return true;\n        }\n    } while (millis() - tStartMillis < aDelayMillis);\n    return false;\n}\n\nvoid IRCommandDispatcher::printIRCommandStringForArrayIndex(Print *aSerial, uint_fast8_t aMappingArrayIndex) {\n#if defined(__AVR__)\n#  if defined(USE_DISPATCHER_COMMAND_STRINGS)\n    aSerial->println(reinterpret_cast<const __FlashStringHelper*>(IRMapping[aMappingArrayIndex].CommandString));\n#  else\n    aSerial->print(F(\"0x\"));\n    aSerial->println(IRMapping[aMappingArrayIndex].IRCode, HEX);\n#  endif\n#else\n#  if defined(USE_DISPATCHER_COMMAND_STRINGS)\n    aSerial->println(IRMapping[aMappingArrayIndex].CommandString);\n#  else\n    aSerial->print(\"0x\");\n    aSerial->println(IRMapping[aMappingArrayIndex].IRCode, HEX);\n#  endif\n#endif\n}\n\nvoid IRCommandDispatcher::printIRCommandString(Print *aSerial, IRCommandType aCommand) {\n    for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) {\n        if (aCommand == IRMapping[i].IRCode) {\n            printIRCommandStringForArrayIndex(aSerial, i);\n            return;\n        }\n    }\n    aSerial->println(F(\"unknown\"));\n}\n\nvoid IRCommandDispatcher::setRequestToStopReceived(bool aRequestToStopReceived) {\n    requestToStopReceived = aRequestToStopReceived;\n}\n\n#include \"LocalDebugLevelEnd.h\"\n\n#endif // _IR_COMMAND_DISPATCHER_HPP\n"
  },
  {
    "path": "src/IRFeedbackLED.h",
    "content": "/*\n * IRFeedbackLED.h\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n// NO GUARD here, we have the GUARD below with #ifdef _IRSND_H_ and #ifdef _IRMP_H_.\n\n#if defined(ARDUINO)\n#ifndef _IR_FEEDBACK_LED_H\n#define _IR_FEEDBACK_LED_H\n\n// define it for convenience reasons. It is an empty function, if NO_LED_FEEDBACK_CODE is enabled\nvoid irmp_irsnd_LEDFeedback(bool aEnableBlinkLed);          // set the mode\n\n#if !defined(NO_LED_FEEDBACK_CODE)\n/*\n * Set IRMP_FEEDBACK_LED_PIN to a reasonable value\n * defining it to 0 disables LED feedback function otherwise LED_BUILTIN (if available) is taken as feedback LED.\n */\n#if !defined(IRMP_FEEDBACK_LED_PIN)\n#  if defined(LED_BUILTIN)\n#define IRMP_FEEDBACK_LED_PIN LED_BUILTIN\n#  else\n#warning IRMP_FEEDBACK_LED_PIN and LED_BUILTIN  not defined. Pin 5 is used for feedback output if feedback is enabled. You can change this in IRFeedbackLED.h.\n#define IRMP_FEEDBACK_LED_PIN 5 // choose an arbitrary pin\n#  endif\n#endif\n\nvoid irmp_irsnd_SetFeedbackLED(bool aSwitchLedOn);          // set set pin\nconstexpr auto irmp_blink13 = irmp_irsnd_LEDFeedback;       // alias for irmp_blink13\nconstexpr auto irmp_LEDFeedback = irmp_irsnd_LEDFeedback;   // alias for irmp_LEDFeedback\nconstexpr auto irsnd_LEDFeedback = irmp_irsnd_LEDFeedback;  // alias for irsnd_LEDFeedback\n\n#endif // !defined(NO_LED_FEEDBACK_CODE)\n#endif // _IR_FEEDBACK_LED_H\n#endif // defined(ARDUINO)\n"
  },
  {
    "path": "src/IRFeedbackLED.hpp",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * IRFeedbackLED.hpp - Arduino extensions for IR feedback LED handling\n *\n * Copyright (c) 2020-2021 Armin Joachimsmeyer\n *\n * This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IR_FEEDBACK_LED_HPP\n#define _IR_FEEDBACK_LED_HPP\n\n#if defined(ARDUINO)\n\n#include \"IRFeedbackLED.h\"\n\n#if defined(NO_LED_FEEDBACK_CODE)\n// dummy void function in this case\nvoid irmp_irsnd_LEDFeedback(bool aEnableBlinkLed)\n{\n    (void)aEnableBlinkLed;\n}\n#else // defined(NO_LED_FEEDBACK_CODE)\n\nstatic bool irmp_irsnd_LedFeedbackEnabled;\n\n#if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n// global variable to hold feedback led pin number. Set to 0 to not activating feedback LED by default.\nuint_fast8_t irmp_irsnd_LedFeedbackPin = 0;\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\nbool irmp_irsnd_LedFeedbackPinIsActiveLow = true; // global variable to hold feedback led polarity.\n#  else\nbool irmp_irsnd_LedFeedbackPinIsActiveLow = false; // global variable to hold feedback led polarity.\n#  endif\n#endif\n\n/*\n * Enable/disable echoing the input signal to the built in (or specified) LED.\n */\nvoid irmp_irsnd_LEDFeedback(bool aEnableBlinkLed)\n{\n#if defined(IRMP_FEEDBACK_LED_PIN) || defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n    irmp_irsnd_LedFeedbackEnabled = aEnableBlinkLed;\n    if (aEnableBlinkLed)\n    {\n#  if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n        pinMode(irmp_irsnd_LedFeedbackPin, OUTPUT);\n        if (irmp_irsnd_LedFeedbackPinIsActiveLow)\n        {\n            digitalWrite(irmp_irsnd_LedFeedbackPin, HIGH);\n        }\n        else\n        {\n            digitalWrite(irmp_irsnd_LedFeedbackPin, LOW);\n        }\n\n#  elif defined(IRMP_FEEDBACK_LED_PIN)\n        pinModeFast(IRMP_FEEDBACK_LED_PIN, OUTPUT);\n#    if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n        digitalWriteFast(IRMP_FEEDBACK_LED_PIN, HIGH);\n#    else\n        digitalWriteFast(IRMP_FEEDBACK_LED_PIN, LOW);\n#    endif\n#  endif //  defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n    }\n#  if defined(ALLOW_DISABLE_FEEDBACK_LED_EXPLICIT)\n    else\n    {\n        /*\n         * Disable here\n         * normally this code is never used, since disabling is done by setting irmp_led_feedback to false.\n         */\n#    if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n        if(irmp_irsnd_LedFeedbackPin != 0) {\n            pinMode(irmp_irsnd_LedFeedbackPin, INPUT);\n            digitalWrite(irmp_irsnd_LedFeedbackPin, LOW); // to disable internal pullup\n        }\n#    else\n        pinModeFast(IRMP_FEEDBACK_LED_PIN, INPUT);\n        digitalWriteFast(IRMP_FEEDBACK_LED_PIN, LOW); // to disable internal pullup\n#    endif\n    }\n#  endif\n#endif // defined(IRMP_FEEDBACK_LED_PIN) || defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n}\n\n/*\n * Internally used from IRMP_ISR() with -oS it is taken as inline function\n */\n#if defined(ESP8266) || defined(ESP32)\nIRAM_ATTR\n#endif\nvoid irmp_irsnd_SetFeedbackLED(bool aSwitchLedOn)\n{\n#if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n    if(irmp_irsnd_LedFeedbackPin != 0) {\n        if (irmp_irsnd_LedFeedbackPinIsActiveLow)\n        {\n            digitalWrite(irmp_irsnd_LedFeedbackPin, !aSwitchLedOn);\n        }\n        else\n        {\n            digitalWrite(irmp_irsnd_LedFeedbackPin, aSwitchLedOn);\n        }\n    }\n#elif defined(IRMP_FEEDBACK_LED_PIN)\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    // If the built in LED on the board is active LOW\n    digitalWriteFast(IRMP_FEEDBACK_LED_PIN, !aSwitchLedOn);\n#  else\n    digitalWriteFast(IRMP_FEEDBACK_LED_PIN, aSwitchLedOn);\n#  endif\n#endif\n}\n\n#endif // !defined(NO_LED_FEEDBACK_CODE)\n#endif // defined(ARDUINO)\n#endif // _IR_FEEDBACK_LED_HPP\n"
  },
  {
    "path": "src/IRTimer.h",
    "content": "/*\n * IRTimer.h\n *\n *  Copyright (C) 2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n// NO GUARD here, we have the GUARD below with #ifdef _IRSND_H_ and #ifdef _IRMP_H_.\n\n#if defined(ARDUINO)\n#if ! defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND) && defined(_IRMP_ARDUINO_EXT_H) && defined(_IRSND_ARDUINO_EXT_H)\n#error You seem to use receive and send in one sketch but forget to define USE_ONE_TIMER_FOR_IRMP_AND_IRSND before the includes. Unfortunately this cannot be done automatically.\n#endif\n\n#if defined(_IRMP_H_)\nvoid initIRTimerForReceive(void);\n#endif\n\n#if defined(_IRSND_H_)\nextern void initIRTimerForSend(void);\n#endif // defined(_IRSND_H_)\n\nextern void irmp_timer_ISR(void);\n\nextern void disableIRTimerInterrupt(void);\nextern void enableIRTimerInterrupt(void);\n\nextern void storeIRTimer(void);\nextern void restoreIRTimer(void);\n#endif // defined(ARDUINO)\n"
  },
  {
    "path": "src/IRTimer.hpp",
    "content": "/*\n * IRTimer.hpp\n *\n *  Copyright (C) 2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * We use IR timer (timer 2 for AVR) for receive and send. Both functions can be used alternating but not at the same time.\n * For receive we initialize IR timer to generate interrupts at 10 to 20 kHz for calling irmp_ISR().\n * For send we have 76 kHz to toggle output pin. The irsnd_ISR() call rate is 1/4 of IR signal toggle rate.\n * For send, initIRTimer() is called at each irsnd_send_data().\n * The current state of IR timer is stored by initIRTimer() and restored after sending.\n * This enables us to set up IR timer for receiving and on calling irsnd_send_data() the IR timer is reconfigured for the duration of sending.\n * Therefore no (non interrupt) receiving is possible during sending of data.\n */\n\n// NO GUARD here, we have the GUARD below with #ifdef _IRSND_H_ and #ifdef _IRMP_H_.\n#include \"IRTimer.h\"\n\n#if !defined(TIMER_DECLARED)\n#define TIMER_DECLARED\n#  if defined(ESP32)\nstatic hw_timer_t *sReceiveAndSendInterruptTimer = nullptr;\n\n// BluePill in 2 flavors see https://samuelpinches.com.au/3d-printer/cutting-through-some-confusion-on-stm32-and-arduino/\n#  elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1) // Recommended original Arduino_STM32 by Roger Clark.\n// STM32F1 architecture for \"Generic STM32F103C series\" from \"STM32F1 Boards (Arduino_STM32)\" of Arduino Board manager\n// http://dan.drown.org/stm32duino/package_STM32duino_index.json\n#include <HardwareTimer.h> // 4 timers and 4. timer (4.channel) is used for tone()\n/*\n * Use timer 3 as IRMP timer.\n * Timer 3 blocks PA6, PA7, PB0, PB1, so if you require one of them as tone() or Servo output, you must choose another timer.\n */\nHardwareTimer sReceiveAndSendInterruptTimer(3);\n\n#  elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32) // STM32duino by ST Microsystems.\n// stm32 architecture for \"Generic STM32F1 series\" from \"STM32 Boards (selected from submenu)\" of Arduino Board manager\n// https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json\n#include <HardwareTimer.h>\n/*\n * Use timer 4 as IRMP timer.\n * Timer 4 blocks PB6, PB7, PB8, PB9, so if you require one of them as tone() or Servo output, you must choose another timer.\n */\n#    if defined(TIM4)\nHardwareTimer sReceiveAndSendInterruptTimer(TIM4);\n#    else\nHardwareTimer sReceiveAndSendInterruptTimer(TIM2);\n#    endif\n\n#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3\nmbed::Ticker sReceiveAndSendInterruptTimer;\n\n/*\n * RP2040 based boards for pico core\n * https://github.com/earlephilhower/arduino-pico\n * https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json\n * Can use any pin for PWM, no timer restrictions\n */\n#elif defined(ARDUINO_ARCH_RP2040) // Raspberry Pi Pico, Adafruit Feather RP2040, etc.\n#include \"pico/time.h\"\nrepeating_timer_t sReceiveAndSendInterruptTimer;\nbool IRTimerInterruptHandlerHelper(repeating_timer_t*);\n\n#elif defined(TEENSYDUINO)\n// common for all Teensy\nIntervalTimer sReceiveAndSendInterruptTimer;\n\n#  endif\n#endif // TIMER_DECLARED\n\n#if defined(_IRMP_H_)\n// we compile for irmp\n#undef IR_INTERRUPT_FREQUENCY\n#define IR_INTERRUPT_FREQUENCY      F_INTERRUPTS                // define frequency for receive\n\n#elif defined(_IRSND_H_)\n// we compile for irsnd\n#undef IR_INTERRUPT_FREQUENCY\n#define IR_INTERRUPT_FREQUENCY      IRSND_INTERRUPT_FREQUENCY   // define frequency for send\n\n#endif // defined(_IRMP_H_)\n\n// The eclipse formatter has problems with // comments in undefined code blocks\n// !!! Must be without trailing comment and closed by @formatter:on\n// @formatter:off\n#if defined(_IRMP_H_)\nvoid initIRTimerForReceive(void)\n#elif defined(_IRSND_H_)\nvoid initIRTimerForSend(void)\n#endif\n\n{\n#if defined(__AVR__)\n// Use Timer 2\n#  if defined(__AVR_ATmega16__)\n    TCCR2 = _BV(WGM21) | _BV(CS21);                                 // CTC mode, prescale by 8\n    OCR2 = (((F_CPU / 8) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY) - 1; // 132 for 15 kHz @16 MHz, 52 for 38 kHz @16 MHz\n    TCNT2 = 0;\n    TIMSK = _BV(OCIE2);                                             // enable interrupt\n\n#  elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n// Since the ISR takes 5 to 22 microseconds for ATtiny@16MHz only 16 and 8 MHz makes sense\n#    if defined(ARDUINO_AVR_DIGISPARK)\n    // standard Digispark settings use timer 1 for millis() and micros()\n// Timer 0 has only 1 and 8 as useful prescaler\n    TCCR0A = 0;                                                     // must be set to zero before configuration!\n#      if (F_CPU / IR_INTERRUPT_FREQUENCY) > 256                    // for 8 bit timer\n    OCR0A = OCR0B = (((F_CPU / 8) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY) - 1; // 132 for 15 kHz @16 MHz, 52 for 38 kHz @16 MHz\n    TCCR0B = _BV(CS01);                                             // presc = 8\n#      else\n    OCR0A = OCR0B = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;           // compare value: 209 for 76 kHz, 221 for 72kHz @16MHz\n    TCCR0B = _BV(CS00);                                             // presc = 1 / no prescaling\n#      endif\n    TCCR0A = _BV(WGM01);                                            // CTC with OCRA as top\n    TCNT0 = 0;\n    TIMSK |= _BV(OCIE0B);                                           // enable compare match interrupt\n\n#    else\n// Use timer 1\n#      if (F_CPU / IR_INTERRUPT_FREQUENCY) > 256                    // for 8 bit timer\n    OCR1B = OCR1C = (((F_CPU / 8) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY) - 1; // 132 for 15 kHz @16 MHz, 52 for 38 kHz @16 MHz\n    TCCR1 = _BV(CTC1) | _BV(CS12);                                  // switch CTC Mode on, set prescaler to 8\n#      else\n    OCR1B = OCR1C = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;           // compare value: 209 for 76 kHz, 221 for 72kHz @16MHz\n    TCCR1 = _BV(CTC1) | _BV(CS10);                                  // switch CTC Mode on, set prescaler to 1 / no prescaling\n#      endif\n    TCNT1 = 0;\n    TIMSK |= _BV(OCIE1B);                                           // enable compare match interrupt\n#    endif\n\n#  elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n// Timer 1 is a 16 bit counter so we need no prescaler\n    ICR1 = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;                    // 1065 for 15 kHz @16 MHz. compare value: 1/15000 of CPU frequency\n    TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10);                   // switch CTC Mode on, set prescaler to 1 / no prescaling\n    TCNT1 = 0;\n    TIMSK1 = _BV(OCIE1B);                                           // enable compare match B interrupt, compare match A is used by tone library\n\n#  elif defined(__AVR_ATmega4809__) // Uno WiFi Rev 2, Nano Every\n    // TCB1 is used by Tone()\n    // TCB2 is used by Servo\n    // TCB3 is used by millis()\n    TCB0.CTRLB = TCB_CNTMODE_INT_gc;\n    TCB0.CCMP = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;               // compare value: 209 for 76 kHz, 221 for 72kHz @16MHz\n    TCB0.INTFLAGS = TCB_CAPT_bm;                                    // reset interrupt flags\n    TCB0.INTCTRL = TCB_CAPT_bm;                                     // enable capture compare interrupt\n    TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm;\n\n#  elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // TinyCore boards\n    // use one ramp mode and overflow interrupt\n#    if defined(MILLIS_USE_TIMERA0)\n    TCD0.CTRLA = 0;                                                 // reset enable bit in order to unprotect the other bits\n    TCD0.CTRLB = TCD_WGMODE_ONERAMP_gc;                             // must be set since it is used by PWM\n//    TCD0.CMPBSET = 80;\n    TCD0.CMPBCLR = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;            // 1332 for 15 kHz, 262 for 76000 interrupts per second @ 20MHz\n\n    // Generate 50% duty cycle signal for debugging etc.\n//    TCD0.CMPASET = 0;\n//    TCD0.CMPACLR = (F_CPU / (IR_INTERRUPT_FREQUENCY * 2)) - 1;      // 50% duty cycle for WOA\n//    TCD0.CTRLC = 0;                                                 // reset WOx outputs\n\n//    _PROTECTED_WRITE(TCD0.FAULTCTRL,FUSE_CMPAEN_bm);                // enable WOA signal\n//    PORTA.DIRSET = PIN4_bm;                                         // enable WOA output pin 13/PA4\n//    _PROTECTED_WRITE(TCD0.FAULTCTRL,FUSE_CMPAEN_bm | FUSE_CMPBEN_bm); // enable WOA + WOB signal signal\n//    PORTA.DIRSET = PIN4_bm | PIN5_bm;                               // enable WOA + WOB output pins 13/PA4 + 14/PA5\n\n    TCD0.INTFLAGS = TCD_OVF_bm;                                     // reset interrupt flags\n    TCD0.INTCTRL = TCD_OVF_bm;                                      // overflow interrupt\n    // check enable ready\n//    while ((TCD0.STATUS & TCD_ENRDY_bm) == 0); // Wait for Enable Ready to be high - I guess it is not required\n    // enable timer - this locks the other bits and static registers and activates values in double buffered registers\n    TCD0.CTRLA = TCD_ENABLE_bm | TCD_CLKSEL_SYSCLK_gc| TCD_CNTPRES_DIV1_gc; // System clock, no prescale, no synchronization prescaler\n#    else\n    TCA0.SINGLE.CTRLD = 0;                                      // Single mode - required at least for MegaTinyCore\n    TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;            // Normal mode, top = PER\n    TCA0.SINGLE.PER = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;     // 1332 for 15 kHz, 262 for 76000 interrupts per second @ 20MHz\n\n    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;                   // reset interrupt flags\n    TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;                    // overflow interrupt\n    // check enable ready\n//    while ((TCA0.SINGLE.STATUS & TCD_ENRDY_bm) == 0); // Wait for Enable Ready to be high - I guess it is not required\n    // enable timer - this locks the other bits and static registers and activates values in double buffered registers\n    TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm | TCA_SINGLE_CLKSEL_DIV1_gc; // System clock\n#    endif\n#  elif defined(__AVR_ATmega8__)\n#    if (F_CPU / IR_INTERRUPT_FREQUENCY) <= 256                     // for 8 bit timer\n    TCCR2 = _BV(WGM21) | _BV(CS20);                                 // CTC mode, no prescale\n    OCR2 = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;                    // 209 for 76000 interrupts per second\n#    else\n    TCCR2 = _BV(WGM21) | _BV(CS21);                                 // CTC mode, prescale by 8\n    OCR2 = (((F_CPU / 8) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY) - 1; // 132 for 15 kHz @16 MHz, 52 for 38 kHz @16 MHz\n#    endif\n    TCNT2 = 0;\n    TIFR = _BV(OCF2) | _BV(TOV2);                                   // reset interrupt flags\n    TIMSK = _BV(OCIE2);                                             // enable TIMER2_COMP_vect interrupt to be compatible with tone() library\n\n#  elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__)  || defined(__AVR_ATmega32U2__) // Leonardo etc.\n    TCCR3A = 0;\n    TCCR3B = _BV(CS30) | _BV(WGM32);                                // no prescale, CTC mode Top OCR3A\n    // Set OCR3B = OCR3A since we use TIMER3_COMPB_vect as interrupt, but run timer in CTC mode with OCR3A as TOP\n    OCR3B = OCR3A = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;           // 1065 for 15 kHz, 209 for 76 kHz @ 16MHz\n    TCNT3 = 0;\n    TIMSK3 = _BV(OCIE3B);                                           // enable TIMER3_COMPB_vect interrupt to be compatible with tone() library\n\n#  elif defined(OCF2B)  // __AVR_ATmega328__ here\n    TCCR2A = _BV(WGM21);                                            // CTC mode\n#    if (F_CPU / IR_INTERRUPT_FREQUENCY) <= 256                     // for 8 bit timer\n    TCCR2B = _BV(CS20);                                             // no prescale\n    // Set OCR2B = OCR2A since we use TIMER2_COMPB_vect as interrupt, but run timer in CTC mode with OCR2A as TOP\n    OCR2B = OCR2A = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;           // 209 for 76000 interrupts per second @ 16MHz\n#    else\n    TCCR2B = _BV(CS21);                                             // prescale by 8\n    OCR2B = OCR2A = (((F_CPU / 8) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY) - 1; // 132 for 15 kHz @16 MHz, 52 for 38 kHz @16 MHz\n#    endif\n    TCNT2 = 0;\n    TIFR2 = _BV(OCF2B) | _BV(OCF2A) | _BV(TOV2);                    // reset interrupt flags\n    TIMSK2 = _BV(OCIE2B);                                           // enable TIMER2_COMPB_vect interrupt to be compatible with tone() library\n\n#  elif defined(TCCR1B)  // __AVR_ATtiny88__ here\n    TCCR1A = 0;\n    TCCR1B = _BV(WGM12) | _BV(CS10);                                // CTC mode, no prescaling\n    OCR1A = (F_CPU / IR_INTERRUPT_FREQUENCY) - 1;                   // 209 for 76000 interrupts per second @ 16MHz\n    TCNT1 = 0;\n#    if defined(TIMSK1)\n    TIMSK1 = _BV(OCIE1A);                                           // Timer/Counter1, Output Compare A Match Interrupt Enable\n#    else // ATmega128 ?\n    TIMSK = _BV(OCIE1A);                                            // Timer/Counter1, Output Compare A Match Interrupt Enable\n#    endif\n\n#  else // if defined(__AVR_ATmega16__) etc\n#error \"This AVR CPU is not supported by IRMP\"\n#  endif // if defined(__AVR_ATmega16__)\n\n#elif defined(ESP8266)\n    timer1_isr_init();\n    timer1_attachInterrupt(irmp_timer_ISR);\n    /*\n     * TIM_DIV1 = 0,   //80MHz (80 ticks/us - 104857.588 us max)\n     * TIM_DIV16 = 1,  //5MHz (5 ticks/us - 1677721.4 us max)\n     * TIM_DIV256 = 3 //312.5Khz (1 tick = 3.2us - 26843542.4 us max)\n     */\n    timer1_enable(TIM_DIV16, TIM_EDGE, TIM_LOOP); // must be before timer1_write!\n    timer1_write(((80000000 / 16) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY); // 80000000 holds for 80 and 160 MHz clock!\n\n#elif defined(ESP32)\n    // Tasmota requires timer 3 (last of 4 timers)\n    // Use timer with 1 microsecond resolution, main clock is 80MHZ\n    if(sReceiveAndSendInterruptTimer == nullptr) {\n#  if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)\n        sReceiveAndSendInterruptTimer = timerBegin(1000000); // Only 1 parameter is required. 1000000 corresponds to 1 MHz / 1 uSec. After successful setup the timer will automatically start.\n        timerAttachInterrupt(sReceiveAndSendInterruptTimer, irmp_timer_ISR);\n        timerAlarm(sReceiveAndSendInterruptTimer, ((getApbFrequency() / 80) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY, true, 0); // 0 in the last parameter is repeat forever\n#  else\n        sReceiveAndSendInterruptTimer = timerBegin(3, 80, true);\n        timerAttachInterrupt(sReceiveAndSendInterruptTimer, irmp_timer_ISR, false); // false -> level interrupt, true -> edge interrupt, but this is not supported :-(\n        timerAlarmWrite(sReceiveAndSendInterruptTimer, ((getApbFrequency() / 80) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY, true);\n#endif\n    }\n    enableIRTimerInterrupt();\n\n#  if defined(DEBUG) && defined(ESP32)\n    Serial.print(\"CPU frequency=\");\n    Serial.print(getCpuFrequencyMhz());\n    Serial.println(\"MHz\");\n    Serial.print(\"Timer clock frequency=\");\n    Serial.print(getApbFrequency());\n    Serial.println(\"Hz\");\n#  endif\n\n// BluePill in 2 flavors\n#elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1) // Recommended original Arduino_STM32 by Roger Clark.\n    // http://dan.drown.org/stm32duino/package_STM32duino_index.json\n    sReceiveAndSendInterruptTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);\n    sReceiveAndSendInterruptTimer.setPrescaleFactor(1);\n    sReceiveAndSendInterruptTimer.setOverflow(F_CPU / IR_INTERRUPT_FREQUENCY);\n    //sReceiveAndSendInterruptTimer.setPeriod(1000000 / IR_INTERRUPT_FREQUENCY);\n    sReceiveAndSendInterruptTimer.attachInterrupt(TIMER_CH1, irmp_timer_ISR);\n    sReceiveAndSendInterruptTimer.refresh();                                  // Set the timer's count to 0 and update the prescaler and overflow values.\n\n#elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32) // STM32duino by ST Microsystems.\n    // https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json\n    sReceiveAndSendInterruptTimer.setMode(LL_TIM_CHANNEL_CH1, TIMER_OUTPUT_COMPARE, NC);              // used for generating only interrupts, no pin specified\n    sReceiveAndSendInterruptTimer.setPrescaleFactor(1);\n    sReceiveAndSendInterruptTimer.setOverflow(F_CPU / IR_INTERRUPT_FREQUENCY, TICK_FORMAT);           // clock cycles period\n    //sReceiveAndSendInterruptTimer.setOverflow(1000000 / IR_INTERRUPT_FREQUENCY, MICROSEC_FORMAT);   // microsecond period\n    sReceiveAndSendInterruptTimer.attachInterrupt(irmp_timer_ISR);                                    // this sets update interrupt enable\n    sReceiveAndSendInterruptTimer.resume();                           // Start or resume HardwareTimer: all channels are resumed, interrupts are enabled if necessary\n\n#elif defined(ARDUINO_ARCH_SAMD)\n    REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3); // GCLK1=32kHz,  GCLK0=48MHz\n//    while (GCLK->STATUS.bit.SYNCBUSY) // not required to wait\n//        ;\n\n    TcCount16* TC = (TcCount16*) TC3;\n\n    TC->CTRLA.reg &= ~TC_CTRLA_ENABLE;          // Enable write access to CTRLA register\n    while (TC->STATUS.bit.SYNCBUSY == 1);       // wait for sync\n\n// Set Timer counter Mode to 16 bits, use match mode so that the timer counter resets when the count matches the compare register\n    TC->CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ |TC_CTRLA_PRESCALER_DIV1;\n\n    TC->CC[0].reg = (uint16_t) ((F_CPU / IR_INTERRUPT_FREQUENCY) - 1);   // ((48MHz / sampleRate) - 1);\n\n// Enable the compare interrupt\n    TC->INTENSET.reg = 0;\n    TC->INTENSET.bit.MC0 = 1;\n\n    NVIC_EnableIRQ (TC3_IRQn);\n\n    TC->CTRLA.reg |= TC_CTRLA_ENABLE;\n//    while (TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY); // Not required to wait at end of function\n\n//#elif defined(ARDUINO_ARCH_APOLLO3)\n//// Use Timer 3 segment B\n//    am_hal_ctimer_clear(3, AM_HAL_CTIMER_TIMERB);   // reset timer\n//// only AM_HAL_CTIMER_FN_REPEAT resets counter after match (CTC mode)\n//    am_hal_ctimer_config_single(3, AM_HAL_CTIMER_TIMERB, (AM_HAL_CTIMER_INT_ENABLE | AM_HAL_CTIMER_HFRC_12MHZ | AM_HAL_CTIMER_FN_REPEAT));\n//    am_hal_ctimer_compare_set(3, AM_HAL_CTIMER_TIMERB, 0, 12000000 / IR_INTERRUPT_FREQUENCY);\n//    am_hal_ctimer_start(3, AM_HAL_CTIMER_TIMERB);\n//\n//    am_hal_ctimer_int_register(AM_HAL_CTIMER_INT_TIMERB3, irmp_timer_ISR);\n//    am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERB3);\n//    NVIC_EnableIRQ(CTIMER_IRQn);\n\n#elif defined(ARDUINO_ARCH_MBED)\n    sReceiveAndSendInterruptTimer.attach(irmp_timer_ISR, std::chrono::microseconds(1000000 / IR_INTERRUPT_FREQUENCY));\n\n#elif defined(ARDUINO_ARCH_RP2040) // Raspberry Pi Pico, Adafruit Feather RP2040, etc.\n    add_repeating_timer_us(-1000000 / IR_INTERRUPT_FREQUENCY, IRTimerInterruptHandlerHelper, nullptr, &sReceiveAndSendInterruptTimer); // 13.15 us\n\n#elif defined(TEENSYDUINO)\n    sReceiveAndSendInterruptTimer.begin(irmp_timer_ISR, 1000000 / IR_INTERRUPT_FREQUENCY);\n#endif // defined(__AVR__)\n}\n\n// @formatter:on\n#if !defined(TIMER_FUNCTIONS_DEFINED)\n#define TIMER_FUNCTIONS_DEFINED\n/** Temporarily storage for timer register*/\n#if defined(__AVR__)\nuint8_t sTimerTCCRA;\nuint8_t sTimerTCCRB;\n#  if defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) \\\n    || defined(__AVR_ATtiny3217__) || defined(__AVR_ATmega4809__)\nuint16_t sTimerOCR; // we have a 12/16 bit timer\n#  else\nuint8_t sTimerOCR;\n#  endif\nuint8_t sTimerOCRB;\nuint8_t sTimerTIMSK;\n\n#elif defined(ESP8266)\nuint32_t sTimerLoadValue;\n\n#elif defined(ESP32)\nuint64_t sTimerAlarmValue;\n\n#elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32) || defined(__STM32F1__)\nuint32_t sTimerOverflowValue;\n\n#elif defined(ARDUINO_ARCH_SAMD) // || defined(ARDUINO_ARCH_APOLLO3)\nuint16_t sTimerCompareCapureValue;\n\n#endif // defined(__AVR__)\n\n/*\n * If we do not use receive, we have no timer defined at the first call of this function.\n * But for AVR saving the timer settings is possible anyway, since it only consists of saving registers.\n * This helps cooperation with other libraries using the same timer.\n */\nvoid storeIRTimer(void) {\n#if defined(__AVR_ATmega16__)\n    sTimerTCCRA = TCCR2;\n    sTimerOCR = OCR2;\n    sTimerTIMSK = TIMSK;\n\n#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#  if defined(ARDUINO_AVR_DIGISPARK)\n    sTimerTCCRA = TCCR0A;\n    sTimerTCCRB = TCCR0B;\n    sTimerOCRB = OCR0B;\n    sTimerOCR = OCR0A;\n    sTimerTIMSK = TIMSK;\n#  else\n    sTimerTCCRA = TCCR1;\n    sTimerOCRB = OCR1B;\n    sTimerOCR = OCR1C;\n    sTimerTIMSK = TIMSK;\n#  endif\n\n#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n    sTimerTCCRB = TCCR1B;\n    sTimerOCR = ICR1;\n    sTimerOCRB = OCR1B;\n    sTimerTIMSK = TIMSK1;\n\n#elif defined(__AVR_ATmega4809__) // Uno WiFi Rev 2, Nano Every\n    // store current timer state\n    sTimerTCCRA = TCB0.CTRLA;\n    sTimerTCCRB = TCB0.CTRLB;\n    sTimerOCR = TCB0.CCMP;\n    sTimerTIMSK = TCB0.INTCTRL;\n\n#elif defined(__AVR_ATmega8__)\n    sTimerTCCRA = TCCR2;\n    sTimerOCR = OCR2;\n    sTimerTIMSK = TIMSK;\n\n#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__)  || defined(__AVR_ATmega32U2__) // Leonardo etc.\n    // store current timer state\n    sTimerTCCRA = TCCR3A;\n    sTimerTCCRB = TCCR3B;\n    sTimerOCR = OCR3A;\n    sTimerOCRB = OCR3B;\n    sTimerTIMSK = TIMSK3;\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n    // store settings used for PWM\n#  if defined(MILLIS_USE_TIMERA0)\n    sTimerTCCRA = TCD0.CTRLA;\n    sTimerTCCRB = TCD0.CTRLB;\n    sTimerOCR = TCD0.CMPBCLR;\n    sTimerOCRB = TCD0.CTRLC;\n    sTimerTIMSK = TCD0.INTCTRL;\n#  else\n    sTimerTCCRA = TCA0.SINGLE.CTRLA;\n    sTimerTCCRB = TCA0.SINGLE.CTRLB;\n    sTimerOCR = TCA0.SINGLE.PER;\n    sTimerOCRB = TCA0.SINGLE.CTRLC;\n    sTimerTIMSK = TCA0.SINGLE.INTCTRL;\n#  endif\n\n#elif defined(OCF2B)  // __AVR_ATmega328__ here\n    // store current timer state\n    sTimerTCCRA = TCCR2A;\n    sTimerTCCRB = TCCR2B;\n    sTimerOCR = OCR2A;\n    sTimerOCRB = OCR2B;\n    sTimerTIMSK = TIMSK2;\n\n#elif defined(TCCR1B)  // __AVR_ATtiny88__ here\n    // store current timer state\n    sTimerTCCRA = TCCR1A;\n    sTimerTCCRB = TCCR1B;\n    sTimerOCR = OCR1A;\n    sTimerOCRB = OCR1B;\n#    if defined(TIMSK1)\n    sTimerTIMSK = TIMSK1;\n#    else\n    sTimerTIMSK = TIMSK;\n#    endif\n\n#elif defined(__AVR__)\n// #error \"This AVR CPU is not supported by IRMP\"\n\n#elif defined(ESP8266)\n    sTimerLoadValue= T1L;\n#endif // defined(__AVR_ATmega16__)\n\n#if defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n    // If we do not use receive, we have no timer defined at the first call of this function\n#  if defined(ESP32)\n#    if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 0)\n            sTimerAlarmValue = timerAlarmRead(sReceiveAndSendInterruptTimer);\n#    endif\n\n#  elif defined(STM32F1xx)\n    sTimerOverflowValue = sReceiveAndSendInterruptTimer.getOverflow(TICK_FORMAT);\n\n#  elif defined(ARDUINO_ARCH_STM32) // Untested! use settings from BluePill / STM32F1xx\n    sTimerOverflowValue = sReceiveAndSendInterruptTimer.getOverflow(TICK_FORMAT);\n\n#  elif defined(__STM32F1__)\n    sTimerOverflowValue = sReceiveAndSendInterruptTimer.getOverflow();\n\n#  elif defined(ARDUINO_ARCH_SAMD)\n    sTimerCompareCapureValue = TC3->COUNT16.CC[0].reg;\n\n//#    elif defined(ARDUINO_ARCH_APOLLO3)\n//    sTimerCompareCapureValue = *((uint32_t *)CTIMERADDRn(CTIMER, 3, CMPRB0)) & 0xFFFF;\n#  endif\n#endif // defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n}\n\n/*\n * Restore settings of the timer e.g. for IRSND\n */\nvoid restoreIRTimer(void) {\n#if defined(__AVR_ATmega16__)\n    TCCR2 = sTimerTCCRA;\n    OCR2 = sTimerOCR;\n    TIMSK = sTimerTIMSK;\n\n#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#  if defined(ARDUINO_AVR_DIGISPARK)\n    TCCR0A = sTimerTCCRA;\n    TCCR0B = sTimerTCCRB;\n    OCR0B = sTimerOCRB;\n    OCR0A = sTimerOCR;\n    TIMSK = sTimerTIMSK;\n#  else\n    TCCR1 = sTimerTCCRA;\n    OCR1B = sTimerOCRB;\n    OCR1C = sTimerOCR;\n    TIMSK = sTimerTIMSK;\n#  endif\n\n#elif  defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n    TCCR1B = sTimerTCCRB;\n    ICR1 = sTimerOCR;\n    OCR1B = sTimerOCRB;\n    TIMSK1 = sTimerTIMSK;\n\n#elif defined(__AVR_ATmega4809__) // Uno WiFi Rev 2, Nano Every\n    TCB0.CTRLA = sTimerTCCRA;\n    TCB0.CTRLB = sTimerTCCRB;\n    TCB0.CCMP = sTimerOCR;\n    TCB0.INTCTRL = sTimerTIMSK;\n\n#elif defined(__AVR_ATmega8__)\n    TCCR2 = sTimerTCCRA;\n    OCR2 = sTimerOCR;\n    TIMSK = sTimerTIMSK;\n\n#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__)  || defined(__AVR_ATmega32U2__) // Leonardo etc.\n    // restore current timer state\n    TCCR3A = sTimerTCCRA;\n    TCCR3B = sTimerTCCRB;\n    OCR3A = sTimerOCR;\n    OCR3B = sTimerOCRB;\n    TIMSK3 = sTimerTIMSK;\n\n#elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n    // restore settings used for PWM\n#    if defined(MILLIS_USE_TIMERA0)\n    TCD0.CTRLA = 0; // unlock timer\n    TCD0.CTRLB = sTimerTCCRB;\n    TCD0.CMPBCLR = sTimerOCR;\n    TCD0.CTRLC = sTimerOCRB;\n    TCD0.INTCTRL = sTimerTIMSK;\n    TCD0.CTRLA = sTimerTCCRA;\n#    else\n    TCA0.SINGLE.CTRLA = 0; // unlock timer\n    TCA0.SINGLE.CTRLB = sTimerTCCRB;\n    TCA0.SINGLE.PER = sTimerOCR;\n    TCA0.SINGLE.CTRLC = sTimerOCRB;\n    TCA0.SINGLE.INTCTRL = sTimerTIMSK;\n    TCA0.SINGLE.CTRLA = sTimerTCCRA;\n#    endif\n\n#elif defined(OCF2B)  // __AVR_ATmega328__ here\n    TCCR2A = sTimerTCCRA;\n    TCCR2B = sTimerTCCRB;\n    OCR2A = sTimerOCR;\n    OCR2B = sTimerOCRB;\n    TIMSK2 = sTimerTIMSK;\n\n#elif defined(TCCR1B)  // __AVR_ATtiny88__ here\n    // store current timer state\n     TCCR1A = sTimerTCCRA;\n     TCCR1B = sTimerTCCRB;\n     OCR1A = sTimerOCR;\n     OCR1B = sTimerOCRB;\n#    if defined(TIMSK1)\n     TIMSK1 = sTimerTIMSK;\n#    else\n     TIMSK = sTimerTIMSK;\n#    endif\n#elif defined(__AVR__)\n// #error \"This AVR CPU is not supported by IRMP\"\n\n#elif defined(ESP8266)\n    timer1_write(sTimerLoadValue);\n#endif // defined(__AVR_ATmega16__)\n\n#if defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n#  if defined(ESP32)\n#    if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)\n    // we have no timerAlarmRead, so we just initialize timer again.\n    timerAlarm(sReceiveAndSendInterruptTimer, ((getApbFrequency() / 80) + (IR_INTERRUPT_FREQUENCY / 2)) / IR_INTERRUPT_FREQUENCY, true, 0); // 0 in the last parameter is repeat forever\n#    else\n    timerAlarmWrite(sReceiveAndSendInterruptTimer, sTimerAlarmValue, true);\n#    endif\n\n#  elif defined(STM32F1xx)\n    sReceiveAndSendInterruptTimer.setOverflow(sTimerOverflowValue, TICK_FORMAT);\n\n#  elif defined(ARDUINO_ARCH_STM32) // Untested! use settings from BluePill / STM32F1xx\n    sReceiveAndSendInterruptTimer.setOverflow(sTimerOverflowValue, TICK_FORMAT);\n\n#  elif defined(__STM32F1__)\n    sReceiveAndSendInterruptTimer.setOverflow(sTimerOverflowValue);\n\n#  elif defined(ARDUINO_ARCH_SAMD)\n    TC3->COUNT16.CC[0].reg = sTimerCompareCapureValue;\n\n//#  elif defined(ARDUINO_ARCH_APOLLO3)\n//    am_hal_ctimer_compare_set(3, AM_HAL_CTIMER_TIMERB, 0, sTimerCompareCapureValue);\n\n#  elif defined(ARDUINO_ARCH_MBED)\n    sReceiveAndSendInterruptTimer.attach(irmp_timer_ISR, std::chrono::microseconds(1000000 / IR_INTERRUPT_FREQUENCY));\n\n#elif defined(ARDUINO_ARCH_RP2040)\n    add_repeating_timer_us(-1000000 / IR_INTERRUPT_FREQUENCY, IRTimerInterruptHandlerHelper, nullptr, &sReceiveAndSendInterruptTimer);\n\n#  elif defined(TEENSYDUINO)\n    sReceiveAndSendInterruptTimer.update(1000000 / IR_INTERRUPT_FREQUENCY);\n#  endif\n#endif // defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n}\n\n/*\n * NOT used if IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined\n * Initialize timer to generate interrupts at a rate F_INTERRUPTS (15000) per second to poll the input pin.\n */\nvoid disableIRTimerInterrupt(void) {\n#if defined(__AVR__)\n// Use Timer 2\n#  if defined(__AVR_ATmega16__)\n    TIMSK = 0;                  // disable interrupt\n\n#  elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#    if defined(ARDUINO_AVR_DIGISPARK)\n    TIMSK &= ~_BV(OCIE0B);      // disable interrupt\n#    else\n    TIMSK &= ~_BV(OCIE1B);      // disable interrupt\n#    endif\n\n#  elif  defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n    TIMSK1 &= ~_BV(OCIE1A);     // disable interrupt\n\n#elif defined(__AVR_ATmega4809__) // Uno WiFi Rev 2, Nano Every\n    TCB0.INTCTRL &= ~TCB_CAPT_bm;\n\n#elif defined(__AVR_ATmega8__)\n    TIMSK &= ~_BV(OCIE2);       // disable interrupt\n\n#  elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__)  || defined(__AVR_ATmega32U2__) // Leonardo etc.\n    TIMSK3 = 0;                 // disable interrupt\n\n#  elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#    if defined(MILLIS_USE_TIMERA0)\n    TCD0.INTCTRL = 0;           // overflow interrupt\n#    else\n    TCA0.SINGLE.INTCTRL = 0;           // overflow interrupt\n#    endif\n\n#  elif defined(OCF2B)  // __AVR_ATmega328__ here\n    TIMSK2 = 0; // disable interrupt\n\n#  elif defined(TCCR1B)  // __AVR_ATtiny88__ here\n#    if defined(TIMSK1)\n    TIMSK1 = 0;\n#    else\n    TIMSK = 0;\n#    endif\n\n#  else\n// #error \"This AVR CPU is not supported by IRMP\"\n\n#  endif // defined(__AVR_ATmega16__)\n\n#elif defined(ESP8266)\n    timer1_detachInterrupt(); // disables interrupt too\n\n#elif defined(ESP32)\n    if (sReceiveAndSendInterruptTimer != nullptr) {\n#    if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)\n        timerStop(sReceiveAndSendInterruptTimer);\n#    else\n            timerAlarmDisable(sReceiveAndSendInterruptTimer);\n#    endif\n    }\n\n#elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32)     // STM32duino by ST Microsystems.\n    sReceiveAndSendInterruptTimer.setMode(LL_TIM_CHANNEL_CH1, TIMER_DISABLED);\n    sReceiveAndSendInterruptTimer.detachInterrupt();\n\n#elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1) // Recommended original Arduino_STM32 by Roger Clark.\n    sReceiveAndSendInterruptTimer.setMode(TIMER_CH1, TIMER_DISABLED);\n    sReceiveAndSendInterruptTimer.detachInterrupt(TIMER_CH1);\n\n#elif defined(ARDUINO_ARCH_SAMD)\n    TC3->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;\n//    while (TC3->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY) ; // Not required to wait at end of function\n\n//#elif defined(ARDUINO_ARCH_APOLLO3)\n//    am_hal_ctimer_int_disable(AM_HAL_CTIMER_INT_TIMERB3);\n\n#elif defined(ARDUINO_ARCH_MBED)\n    sReceiveAndSendInterruptTimer.detach();\n\n#elif defined(ARDUINO_ARCH_RP2040)\n    cancel_repeating_timer(&sReceiveAndSendInterruptTimer);\n\n#elif defined(TEENSYDUINO)\n    sReceiveAndSendInterruptTimer.end();\n#endif // defined(__AVR__)\n}\n\n// used by AllProtocols example\nvoid enableIRTimerInterrupt(void) {\n#if defined(__AVR__)\n// Use Timer 2\n#  if defined(__AVR_ATmega16__)\n    TIMSK = _BV(OCIE2);             // enable interrupt\n\n#  elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#    if defined(ARDUINO_AVR_DIGISPARK)\n    TIMSK |= _BV(OCIE0B);           // enable compare match interrupt\n#    else\n    TIMSK |= _BV(OCIE1B);           // enable compare match interrupt\n#    endif\n\n#  elif  defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n    TIMSK1 |= _BV(OCIE1A);          // enable compare match interrupt\n\n#elif defined(__AVR_ATmega4809__)   // Uno WiFi Rev 2, Nano Every\n    TCB0.INTCTRL = TCB_CAPT_bm;\n\n#elif defined(__AVR_ATmega8__)\n    TIMSK = _BV(OCIE2);             // enable interrupt\n\n#  elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__)  || defined(__AVR_ATmega32U2__) // Leonardo etc.\n    TIMSK3 = _BV(OCIE3B);           // enable interrupt\n\n#  elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#    if defined(MILLIS_USE_TIMERA0)\n    TCD0.INTCTRL = TCD_OVF_bm;      // overflow interrupt\n#    else\n    TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;      // overflow interrupt\n#    endif\n\n#  elif defined(OCF2B)  // __AVR_ATmega328__ here\n    TIMSK2 = _BV(OCIE2B); // enable interrupt\n\n#  elif defined(TCCR1B)  // __AVR_ATtiny88__ here\n#    if defined(TIMSK1)\n    TIMSK1 = _BV(OCIE1A);\n#    else\n    TIMSK = _BV(OCIE1A);\n#    endif\n\n#  else\n// #error \"This AVR CPU is not supported by IRMP\"\n\n#  endif // defined(__AVR_ATmega16__)\n\n#elif defined(ESP8266)\n    timer1_attachInterrupt(irmp_timer_ISR); // enables interrupt too\n\n#elif defined(ESP32)\n    if (sReceiveAndSendInterruptTimer != nullptr) {\n#  if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)  // timerAlarm() enables it automatically\n        timerStart(sReceiveAndSendInterruptTimer);\n#  else\n        timerAlarmEnable(sReceiveAndSendInterruptTimer);\n#  endif\n    }\n\n#elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32F1) // Recommended original Arduino_STM32 by Roger Clark.\n    // http://dan.drown.org/stm32duino/package_STM32duino_index.json\n    sReceiveAndSendInterruptTimer.setMode(TIMER_CH1, TIMER_OUTPUT_COMPARE);\n    sReceiveAndSendInterruptTimer.attachInterrupt(TIMER_CH1, irmp_timer_ISR);\n    sReceiveAndSendInterruptTimer.refresh(); // Set the timer's count to 0 and update the prescaler and overflow values.\n\n#elif defined(STM32F1xx) || defined(ARDUINO_ARCH_STM32) // STM32duino by ST Microsystems.\n    // https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json\n    sReceiveAndSendInterruptTimer.setMode(LL_TIM_CHANNEL_CH1, TIMER_OUTPUT_COMPARE, NC); // used for generating only interrupts, no pin specified\n    sReceiveAndSendInterruptTimer.attachInterrupt(irmp_timer_ISR);\n    sReceiveAndSendInterruptTimer.refresh();// Set the timer's count to 0 and update the prescaler and overflow values.\n\n#elif defined(ARDUINO_ARCH_SAMD)\n    TC3->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;\n    while (TC3->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY)\n    ; //wait until TC5 is done syncing\n\n//#elif defined(ARDUINO_ARCH_APOLLO3)\n//    am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERB3);\n\n#elif defined(ARDUINO_ARCH_MBED)\n    sReceiveAndSendInterruptTimer.attach(irmp_timer_ISR, std::chrono::microseconds(1000000 / IR_INTERRUPT_FREQUENCY));\n\n#elif defined(ARDUINO_ARCH_RP2040)\n    add_repeating_timer_us(-1000000 / IR_INTERRUPT_FREQUENCY, IRTimerInterruptHandlerHelper, nullptr, &sReceiveAndSendInterruptTimer);\n\n#elif defined(TEENSYDUINO)\n    sReceiveAndSendInterruptTimer.begin(irmp_timer_ISR, 1000000 / IR_INTERRUPT_FREQUENCY);\n#else\n#warning Board / CPU is not covered by definitions using pre-processor symbols -> no timer available. Please extend IRTimer.hpp.\n#endif // defined(__AVR__)\n}\n\n#endif // TIMER_FUNCTIONS_DEFINED\n\n/*\n * If both irmp and irsnd are used, compile it only once in the second step, when all variables are declared.\n */\n#if (! defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND) || ( defined(_IRMP_ARDUINO_EXT_H) && defined(_IRSND_ARDUINO_EXT_H) )) && ! defined(ISR_DEFINED)\n#  if !defined(ISR_DEFINED)\n#define ISR_DEFINED\n#  endif\n/*\n * ISR is active while signal is sent AND during the trailing pause of IR frame\n * Called every 13.5us\n * Bit bang requires 5.9 us. 5 us for 16 push and 16 pop etc. and 0.9 us for function body\n * Together with call of irsnd_ISR() 10.5 us (frame) or 9.4 (trailing pause) - measured by scope\n * We use TIMER2_COMPB_vect to be compatible with tone() library\n */\n#if defined(__AVR__)\n\n#  if F_CPU < 8000000L\n#error F_CPU must not be less than 8MHz for IRMP and IRSND\n#  endif\n\n#  if defined(__AVR_ATmega16__)\nISR(TIMER2_COMP_vect)\n#  elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#    if defined(ARDUINO_AVR_DIGISPARK)\nISR(TIMER0_COMPB_vect)\n#    else\nISR(TIMER1_COMPB_vect)\n#    endif\n\n#  elif defined(__AVR_ATmega4809__) // Uno WiFi Rev 2, Nano Every\nISR(TCB0_INT_vect)\n\n#  elif defined(__AVR_ATmega8__)\nISR(TIMER2_COMP_vect)\n\n#  elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__)  || defined(__AVR_ATmega32U2__) // Leonardo etc.\nISR(TIMER3_COMPB_vect)\n\n#  elif defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#    if defined(MILLIS_USE_TIMERA0)\nISR(TCD0_OVF_vect)\n#    else\nISR(TCA0_OVF_vect)\n#    endif\n\n#  elif defined(OCF2B)  // __AVR_ATmega328__ here\nISR(TIMER2_COMPB_vect)\n\n#  elif defined(TCCR1B)  // __AVR_ATtiny88__ here\nISR(TIMER1_COMPB_vect)\n\n#  else\n// #error \"This AVR CPU is not supported by IRMP\"\n\n#  endif // defined(__AVR_ATmega16__)\n\n#elif defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR irmp_timer_ISR(void)\n\n#elif defined(ARDUINO_ARCH_SAMD)\nvoid TC3_Handler(void)\n\n#elif defined(STM32F1xx) && STM32_CORE_VERSION_MAJOR == 1 &&  STM32_CORE_VERSION_MINOR <= 8 // for \"Generic STM32F1 series\" from \"STM32 Boards (selected from submenu)\" of Arduino Board manager\nvoid irmp_timer_ISR(HardwareTimer *aDummy __attribute__((unused))) // old 1.8 version - changed in stm32duino 1.9 - 5/2020\n\n#elif defined(ARDUINO_ARCH_RP2040)\nvoid irmp_timer_ISR(void);\nbool IRTimerInterruptHandlerHelper(repeating_timer_t*) { // we are called with a different signature\n    irmp_timer_ISR();\n    return true;\n}\nvoid irmp_timer_ISR(void)\n\n#else // STM32F1xx (v1.9), __STM32F1__, ARDUINO_ARCH_APOLLO3, MBED, TEENSYDUINO\nvoid irmp_timer_ISR(void)\n\n#endif // defined(__AVR__)\n\n// Start of ISR\n{\n#if defined(ARDUINO_ARCH_SAMD)\n    TC3->COUNT16.INTFLAG.bit.MC0 = 1; // Clear interrupt\n#endif\n\n#if defined(__AVR_ATmega4809__)     // Uno WiFi Rev 2, Nano Every\n    // Not tested, but with the experience, I made with the ATtiny3217, I guess it is required\n    TCB0.INTFLAGS = TCB_CAPT_bm;    // reset interrupt flags\n#endif\n#if defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n    // must reset interrupt flag here\n#  if defined(MILLIS_USE_TIMERA0)\n    TCD0.INTFLAGS = TCD_OVF_bm;\n#  else\n    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;\n#  endif\n#endif\n\n#if (defined(_IRSND_H_) || defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND))\n    static uint8_t sDivider;        // IR signal toggle rate is 2 (4) times IRSND call rate\n#endif\n\n#if defined(IRMP_MEASURE_TIMING) && defined(IR_TIMING_TEST_PIN)\n    digitalWriteFast(IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles\n#endif\n\n#if defined(_IRSND_H_) || defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n    /*\n     * Send part of ISR\n     */\n    if(irsnd_busy) {\n        if (irsnd_is_on)\n        {\n#  if defined(IRSND_GENERATE_NO_SEND_RF)\n            // output is active low\n            if (__builtin_constant_p(IRSND_OUTPUT_PIN) ) { digitalWriteFast(IRSND_OUTPUT_PIN, IR_OUTPUT_ACTIVE_LEVEL);} else { digitalWrite(IRSND_OUTPUT_PIN, IR_OUTPUT_ACTIVE_LEVEL);}\n#  else\n            if(sDivider & 0x01) // true / inactive if sDivider is 3 or 1, so we start with active and end with inactive\n            {\n                if (__builtin_constant_p(IRSND_OUTPUT_PIN) ) { digitalWriteFast(IRSND_OUTPUT_PIN, IR_OUTPUT_INACTIVE_LEVEL);} else { digitalWrite(IRSND_OUTPUT_PIN, IR_OUTPUT_INACTIVE_LEVEL);}\n            } else {\n                if (__builtin_constant_p(IRSND_OUTPUT_PIN) ) { digitalWriteFast(IRSND_OUTPUT_PIN, IR_OUTPUT_ACTIVE_LEVEL);} else { digitalWrite(IRSND_OUTPUT_PIN, IR_OUTPUT_ACTIVE_LEVEL);}\n            }\n\n\n#  endif // defined(IRSND_GENERATE_NO_SEND_RF)\n        } else {\n            // irsnd off here\n            if (__builtin_constant_p(IRSND_OUTPUT_PIN) ) { digitalWriteFast(IRSND_OUTPUT_PIN, IR_OUTPUT_INACTIVE_LEVEL);} else { digitalWrite(IRSND_OUTPUT_PIN, IR_OUTPUT_INACTIVE_LEVEL);}\n        }\n\n        /*\n         * Call irsnd_ISR() every second (fourth) call if current LED state is inactive\n         */\n        if (--sDivider == 0)\n        {\n            // This in turn calls irsnd_on() or irsnd_off(). Empty call requires additional 0.7 us.\n            if (!irsnd_ISR())\n            {\n                // End of frame\n                restoreIRTimer();\n#  if ! defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n// only send mode required -> disable interrupt\n                disableIRTimerInterrupt();\n#  endif\n                sDivider = 1; // to call irsnd_ISR() directly at next interrupt\n            } else {\n                sDivider = 4;\n            }\n        }\n    } // if(irsnd_busy)\n#endif // defined(_IRSND_H_) || defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n#if defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n    else\n    { // for receive and send in one ISR\n#endif\n\n#if defined(_IRMP_H_) || defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n    /*\n     * Receive part of ISR\n     */\n    irmp_ISR();\n#endif\n\n#if defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND)\n} // for receive and send in one ISR\n#endif\n\n#if defined(IRMP_MEASURE_TIMING) && defined(IR_TIMING_TEST_PIN)\n    digitalWriteFast(IR_TIMING_TEST_PIN, LOW); // 2 clock cycles\n#endif\n}\n#endif // (! defined(USE_ONE_TIMER_FOR_IRMP_AND_IRSND) || ( defined(_IRMP_ARDUINO_EXT_H) && defined(_IRSND_ARDUINO_EXT_H) )) && ! defined(ISR_DEFINED)\n"
  },
  {
    "path": "src/LocalDebugLevelEnd.h",
    "content": "/*\n * LocalDebugLevelEnd.h\n * Undefine local macros at the end of an included (.hpp) file\n *\n *  Copyright (C) 2024  Armin Joachimsmeyer\n *  Email: armin.joachimsmeyer@gmail.com\n *\n *  This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.\n *\n *  Arduino-Utils is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public INFOse for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/*\n * Undefine local macros at the end of an included (.hpp) file\n */\n#if defined(LOCAL_TRACE)\n#undef LOCAL_TRACE\n#endif\n#undef TRACE_PRINT\n#undef TRACE_PRINTLN\n#undef TRACE_FLUSH\n#if defined(LOCAL_DEBUG)\n#undef LOCAL_DEBUG\n#endif\n#undef DEBUG_PRINT\n#undef DEBUG_PRINTLN\n#undef DEBUG_FLUSH\n#if defined(LOCAL_INFO)\n#undef LOCAL_INFO\n#endif\n#undef INFO_PRINT\n#undef INFO_PRINTLN\n#undef INFO_FLUSH\n"
  },
  {
    "path": "src/LocalDebugLevelStart.h",
    "content": "/*\n * LocalDebugLevelStart.h\n * Include to propagate global debug levels to file local ones and to define appropriate print macros.\n * !!! If used in included (.hpp) files, #include \"LocalDebugLevelEnd.h\" must be used at end of file to undefine local macros.\n * If, for example, #define LOCAL_TRACE is placed before this include, it will not be propagated. This enables TRACE-level output to be selected only.\n *\n * LOCAL_TRACE   // Information you need to understand details of a function or if you hunt a bug.\n * LOCAL_DEBUG   // Information need to understand the operating of your program. E.g. function calls and values of control variables.\n * LOCAL_INFO    // Information you want to see in regular operation to see what the program is doing. E.g. \"Now playing Muppets melody\".\n * LOCAL_WARN    // Information that the program may encounter problems, like small Heap/Stack area.\n * LOCAL_ERROR   // Informations to explain why the program will not run. E.g. not enough Ram for all created objects.\n *\n *  Copyright (C) 2024-2026  Armin Joachimsmeyer\n *  Email: armin.joachimsmeyer@gmail.com\n *\n *  This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.\n *\n *  Arduino-Utils is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public INFOse for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n/////////////// put this before the include /////////////////////////\n// This block must be located after the includes of other *.hpp files\n//#define LOCAL_INFO  // This enables info output only for this file\n//#define LOCAL_DEBUG // This enables debug output only for this file - only for development\n//#define LOCAL_TRACE // This enables trace output only for this file - only for development\n\n/*\n * Propagate debug level to local ones but at first not to each other, i.e. enabling TRACE does not enable DEBUG and INFO\n */\n#if defined(TRACE) // Information you need to understand details of a function or if you hunt a bug.\n#define LOCAL_TRACE\n#  if !defined(DO_NOT_PROPAGATE_DEBUG_LEVELS) // Propagate levels by default i.e. enabling TRACE does enable DEBUG and INFO\n#define LOCAL_DEBUG\n#define LOCAL_INFO\n#  endif\n#endif\n\n#if defined(DEBUG) // Information need to understand the operating of your program. E.g. function calls and values of control variables.\n#define LOCAL_DEBUG\n#  if !defined(DO_NOT_PROPAGATE_DEBUG_LEVELS)\n#define LOCAL_INFO\n#  endif\n#endif\n\n#if defined(INFO) // Information you want to see in regular operation to see what the program is doing. E.g. \"START ../src/LightToTone.cpp Version 1.2 from Dec 31 2019\" or \"Now playing Muppets melody\".\n#define LOCAL_INFO\n#endif\n\n/*\n * Define appropriate print macros\n */\n#if defined(LOCAL_TRACE)\n#define TRACE_PRINT(...)      Serial.print(__VA_ARGS__)\n#define TRACE_PRINTLN(...)    Serial.println(__VA_ARGS__)\n#define TRACE_FLUSH()         Serial.flush()\n#else\n#define TRACE_PRINT(...)      void()\n#define TRACE_PRINTLN(...)    void()\n#define TRACE_FLUSH()         void()\n#endif\n\n#if defined(LOCAL_DEBUG)\n#define DEBUG_PRINT(...)      Serial.print(__VA_ARGS__)\n#define DEBUG_PRINTLN(...)    Serial.println(__VA_ARGS__)\n#define DEBUG_FLUSH()         Serial.flush()\n#else\n#define DEBUG_PRINT(...)      void()\n#define DEBUG_PRINTLN(...)    void()\n#define DEBUG_FLUSH()         void()\n\n#endif\n\n#if defined(LOCAL_INFO)\n#define INFO_PRINT(...)      Serial.print(__VA_ARGS__)\n#define INFO_PRINTLN(...)    Serial.println(__VA_ARGS__)\n#define INFO_FLUSH()         Serial.flush()\n#else\n#define INFO_PRINT(...)      void()\n#define INFO_PRINTLN(...)    void()\n#define INFO_FLUSH()         void()\n#endif\n\n"
  },
  {
    "path": "src/LongUnion.h",
    "content": "/*\n * LongUnion.h\n *\n *  Copyright (C) 2020-2022  Armin Joachimsmeyer\n *  Email: armin.joachimsmeyer@gmail.com\n *\n *  This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.\n *\n *  Arduino-Utils is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#if !defined(_WORD_UNION_H) || !defined(_LONG_UNION_H) || !defined(_LONG_LONG_UNION_H)\n\n#include <stdint.h>\n\n#ifndef _WORD_UNION_H\n#define _WORD_UNION_H\n/**\n * Union to specify parts / manifestations of a 16 bit Word without casts and shifts.\n * It also supports the compiler generating small code.\n * Usage: WordUnion tWord;\n *        tWord.UByte.HighByte = 0x12;\n */\nunion WordUnion {\n    struct {\n        uint8_t LowByte;\n        uint8_t HighByte;\n    } UByte;\n    struct {\n        int8_t LowByte;\n        int8_t HighByte;\n    } Byte;\n    uint8_t UBytes[2]; // UBytes[0] is LowByte\n    int8_t Bytes[2];\n    uint16_t UWord;\n    int16_t Word;\n    uint8_t *BytePointer;\n};\n#endif // _WORD_UNION_H\n\n#ifndef _LONG_UNION_H\n#define _LONG_UNION_H\n/**\n * Union to specify parts / manifestations of a 32 bit Long without casts and shifts.\n * It also supports the compiler generating small code.\n */\nunion LongUnion {\n    struct {\n        uint8_t LowByte;\n        uint8_t MidLowByte;\n        uint8_t MidHighByte;\n        uint8_t HighByte;\n    } UByte;\n    struct {\n        int8_t LowByte;\n        int8_t MidLowByte;\n        int8_t MidHighByte;\n        int8_t HighByte;\n    } Byte;\n    /* Does not work for STM32\n    struct {\n        uint8_t LowByte;\n        uint16_t MidWord;\n        uint8_t HighByte;\n    } UByteWord;\n    */\n    struct {\n        uint16_t LowWord;\n        uint16_t HighWord;\n    } UWord;\n    struct {\n        int16_t LowWord;\n        int16_t HighWord;\n    } Word;\n    struct {\n        WordUnion LowWord;\n        WordUnion HighWord;\n    } TwoWordUnions;\n    uint8_t UBytes[4]; // seems to have the same code size as using struct UByte\n    int8_t Bytes[4]; // Bytes[0] is LowByte\n    uint16_t UWords[2];\n    int16_t Words[2];\n    uint32_t ULong;\n    int32_t Long;\n    float Float;\n};\n#endif // _LONG_UNION_H\n\n#ifndef _LONG_LONG_UNION_H\n#define _LONG_LONG_UNION_H\n/**\n * Union to specify parts / manifestations of a 64 bit LongLong without casts and shifts.\n * It also supports the compiler generating small code.\n */\nunion LongLongUnion {\n    struct {\n        uint16_t LowWord;\n        uint16_t MidLowWord;\n        uint16_t MidHighWord;\n        uint16_t HighWord;\n    } UWord;\n    struct {\n        int16_t LowWord;\n        int16_t MidLowWord;\n        int16_t MidHighWord;\n        int16_t HighWord;\n    } Word;\n    struct {\n        WordUnion LowWord;\n        WordUnion MidLowWord;\n        WordUnion MidHighWord;\n        WordUnion HighWord;\n    } FourWordUnions;\n    struct {\n        uint32_t LowLong;\n        uint32_t HighLong;\n    } ULong;\n    struct {\n        int32_t LowLong;\n        int32_t HighLong;\n    } Long;\n    struct {\n        LongUnion LowLong;\n        LongUnion HighLong;\n    } TwoLongUnions;\n    uint8_t UBytes[8]; // seems to have the same code size as using struct UByte\n    int8_t Bytes[8];\n    uint16_t UWords[4];\n    int16_t Words[4];\n    uint64_t ULongLong;\n    int64_t LongLong;\n#if __DBL_MANT_DIG__== 24\n    float Floats[2]; // 32 bit double, as for AVR\n#else\n    // 64 bit double\n    double Double;\n#endif\n};\n#endif // _LONG_LONG_UNION_H\n\n#endif //  !defined(_WORD_UNION_H) || !defined(_LONG_UNION_H) || !defined(_LONG_LONG_UNION_H)\n"
  },
  {
    "path": "src/TinyIR.h",
    "content": "/*\n *  TinyIR.h\n *\n *\n *  Copyright (C) 2021-2025  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *  This file is also part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  TinyIRReceiver is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#ifndef _TINY_IR_H\n#define _TINY_IR_H\n\n#include <Arduino.h>\n\n#include \"LongUnion.h\"\n\n/** \\addtogroup TinyIRReceiver Minimal receiver for NEC and FAST protocol\n * @{\n */\n\n#define VERSION_TINYIR \"2.3.0\"\n#define VERSION_TINYIR_MAJOR 2\n#define VERSION_TINYIR_MINOR 3\n#define VERSION_TINYIR_PATCH 0\n// The change log is at the bottom of the file\n\n/**\n * Timing for NEC protocol\n *\n * see: https://www.sbprojects.net/knowledge/ir/nec.php\n * LSB first, 1 start bit + 16 bit address + 8 bit data + 8 bit inverted data + 1 stop bit.\n */\n#if !defined(NEC_ADDRESS_BITS)\n#define NEC_ADDRESS_BITS        16 // 16 bit address or 8 bit address and 8 bit inverted address\n#define NEC_COMMAND_BITS        16 // Command and inverted command\n#define NEC_BITS                (NEC_ADDRESS_BITS + NEC_COMMAND_BITS)\n\n#define NEC_UNIT                560\n\n#define NEC_HEADER_MARK         (16 * NEC_UNIT) // 8860\n#define NEC_HEADER_SPACE        (8 * NEC_UNIT)  // 4480\n\n#define NEC_BIT_MARK            NEC_UNIT\n#define NEC_ONE_SPACE           (3 * NEC_UNIT)  // 1680\n#define NEC_ZERO_SPACE          NEC_UNIT\n\n#define NEC_REPEAT_HEADER_SPACE (4 * NEC_UNIT)  // 2240\n\n#define NEC_REPEAT_PERIOD       110000 // Commands are repeated every 110 ms (measured from start to start) for as long as the key on the remote control is held down.\n#define NEC_MINIMAL_DURATION     49900 // NEC_HEADER_MARK + NEC_HEADER_SPACE + 32 * 2 * NEC_UNIT + NEC_UNIT // 2.5 because we assume more zeros than ones\n#define NEC_MAXIMUM_REPEAT_DISTANCE (NEC_REPEAT_PERIOD - NEC_MINIMAL_DURATION + 10000) // 70 ms\n#endif\n\n/**\n * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header.\n * FAST protocol characteristics:\n * - Bit timing is like NEC or JVC\n * - The header is shorter, 3156 vs. 12500\n * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command,\n *     leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms.\n * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance.\n */\n/*\n Protocol=FAST Address=0x0 Command=0x76 Raw-Data=0x8976 16 bits LSB first\n +2100,-1050\n + 550,- 500 + 550,-1550 + 550,-1550 + 550,- 500\n + 550,-1550 + 550,-1550 + 550,-1550 + 550,- 500\n + 550,-1550 + 550,- 500 + 550,- 500 + 550,-1550\n + 550,- 500 + 550,- 500 + 550,- 500 + 550,-1550\n + 550\n Sum: 28900\n */\n#define FAST_KHZ                  38\n#define FAST_ADDRESS_BITS          0 // No address\n#define FAST_COMMAND_BITS         16 // Command and inverted command (parity)\n#define FAST_BITS                 (FAST_ADDRESS_BITS + FAST_COMMAND_BITS)\n\n#define FAST_UNIT                 526 // 20 periods of 38 kHz (526.315789)\n\n#define FAST_BIT_MARK             FAST_UNIT\n#define FAST_ONE_SPACE            (3 * FAST_UNIT)     // 1578 -> bit period = 2104\n#define FAST_ZERO_SPACE           FAST_UNIT           //  526 -> bit period = 1052\n\n#define FAST_HEADER_MARK          (4 * FAST_UNIT)     // 2104\n#define FAST_HEADER_SPACE         (2 * FAST_UNIT)     // 1052\n\n#define FAST_REPEAT_PERIOD        50000 // Commands are repeated every 50 ms (measured from start to start) for as long as the key on the remote control is held down.\n#define FAST_REPEAT_DISTANCE      (FAST_REPEAT_PERIOD - (55 * FAST_UNIT)) // 19 ms\n#define FAST_MAXIMUM_REPEAT_DISTANCE (FAST_REPEAT_DISTANCE + 10000) // 29 ms\n\n/*\n * Definitions to switch between FAST and NEC/ONKYO timing with the same code.\n */\n#if defined(USE_FAST_PROTOCOL)\n#define ENABLE_NEC2_REPEATS    // Disables detection of special short frame NEC repeats. Saves 40 bytes program memory.\n\n#define TINY_RECEIVER_ADDRESS_BITS          FAST_ADDRESS_BITS\n#define TINY_RECEIVER_COMMAND_BITS          FAST_COMMAND_BITS\n#if !defined(TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY)\n#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY  true     // 8 bit and 8 bit parity\n//#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY  false    //  16 bit command without parity - not tested\n#endif\n\n#define TINY_RECEIVER_BITS                  FAST_BITS\n#define TINY_RECEIVER_UNIT                  FAST_UNIT\n\n#define TINY_RECEIVER_HEADER_MARK           FAST_HEADER_MARK\n#define TINY_RECEIVER_HEADER_SPACE          FAST_HEADER_SPACE\n#define TINY_RECEIVER_MARK_TIMEOUT          (2 * FAST_HEADER_MARK)\n\n#define TINY_RECEIVER_BIT_MARK              FAST_BIT_MARK\n#define TINY_RECEIVER_ONE_SPACE             FAST_ONE_SPACE\n#define TINY_RECEIVER_ZERO_SPACE            FAST_ZERO_SPACE\n#define TINY_RECEIVER_ONE_THRESHOLD         (2 * FAST_UNIT)  // 1052\n\n#define TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE  FAST_MAXIMUM_REPEAT_DISTANCE // for repeat detection\n\n#else\n\n#define TINY_RECEIVER_ADDRESS_BITS          NEC_ADDRESS_BITS // the address bits + parity\n#  if defined(USE_ONKYO_PROTOCOL)\n#define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY  false     // 16 bit address without parity\n#  elif defined(USE_EXTENDED_NEC_PROTOCOL)\n#define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY  false     // 16 bit address without parity\n#  else\n#define TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY  true     // 8 bit and 8 bit parity\n#  endif\n\n#define TINY_RECEIVER_COMMAND_BITS          NEC_COMMAND_BITS // the command bits + parity\n#  if defined(USE_ONKYO_PROTOCOL)\n#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY  false    // 16 bit command without parity\n#  else\n#define TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY  true     // 8 bit and 8 bit parity\n#  endif\n\n#define TINY_RECEIVER_BITS                  NEC_BITS\n#define TINY_RECEIVER_UNIT                  NEC_UNIT\n\n#define TINY_RECEIVER_HEADER_MARK           NEC_HEADER_MARK\n#define TINY_RECEIVER_MARK_TIMEOUT          (2 * NEC_HEADER_MARK)\n#define TINY_RECEIVER_HEADER_SPACE          NEC_HEADER_SPACE\n\n#define TINY_RECEIVER_BIT_MARK              NEC_BIT_MARK\n#define TINY_RECEIVER_ONE_SPACE             NEC_ONE_SPACE\n#define TINY_RECEIVER_ZERO_SPACE            NEC_ZERO_SPACE\n#define TINY_RECEIVER_ONE_THRESHOLD         (2 * NEC_UNIT)  // 1120\n\n#define TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE  NEC_MAXIMUM_REPEAT_DISTANCE\n#endif\n\n#if defined(USE_CALLBACK_FOR_TINY_RECEIVER)\n/*\n * This function is called, if a complete command was received and must be implemented in the file (user code)\n * which includes this library if USE_CALLBACK_FOR_TINY_RECEIVER is activated.\n */\nextern void handleReceivedTinyIRData();\n#endif\n\n#if !defined(MICROS_IN_ONE_SECOND)\n#define MICROS_IN_ONE_SECOND 1000000L\n#endif\n\n#if !defined(MICROS_IN_ONE_MILLI)\n#define MICROS_IN_ONE_MILLI 1000L\n#endif\n\n/*\n * Macros for comparing timing values\n */\n#define lowerValue25Percent(aDuration)   (aDuration - (aDuration / 4))\n#define upperValue25Percent(aDuration)   (aDuration + (aDuration / 4))\n#define lowerValue50Percent(aDuration)   (aDuration / 2) // (aDuration - (aDuration / 2))\n#define upperValue50Percent(aDuration)   (aDuration + (aDuration / 2))\n\n/*\n * The states for the state machine\n */\n#define IR_RECEIVER_STATE_WAITING_FOR_START_MARK        0\n#define IR_RECEIVER_STATE_WAITING_FOR_START_SPACE       1\n#define IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK   2\n#define IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE        3\n#define IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK         4\n#define IR_RECEIVER_STATE_WAITING_FOR_STOP_MARK         5\n/**\n * Control and data variables of the state machine for TinyIRReceiver\n */\nstruct TinyIRReceiverStruct {\n    /*\n     * State machine\n     */\n    uint32_t LastChangeMicros;      ///< Microseconds of last Pin Change Interrupt.\n    uint8_t IRReceiverState;        ///< The state of the state machine.\n    uint8_t IRRawDataBitCounter;    ///< How many bits are currently contained in raw data.\n    /*\n     * Data\n     */\n#if (TINY_RECEIVER_BITS > 16)\n    uint32_t IRRawDataMask;         ///< The corresponding bit mask for IRRawDataBitCounter.\n    LongUnion IRRawData;            ///< The current raw data. LongUnion helps with decoding of address and command.\n#else\n    uint16_t IRRawDataMask;         ///< The corresponding bit mask for IRRawDataBitCounter.\n    WordUnion IRRawData;            ///< The current raw data. WordUnion helps with decoding of command.\n#endif\n    uint8_t Flags;  ///< One of IRDATA_FLAGS_EMPTY, IRDATA_FLAGS_IS_REPEAT, and IRDATA_FLAGS_PARITY_FAILED\n};\n\n/*\n * Definitions for member TinyIRReceiverCallbackDataStruct.Flags\n * This is a copy of flags from IRremoteInt.h\n */\n#define IRDATA_FLAGS_EMPTY              0x00\n#define IRDATA_FLAGS_IS_REPEAT          0x01\n#define IRDATA_FLAGS_IS_AUTO_REPEAT     0x02 // not used for TinyIR\n#define IRDATA_FLAGS_PARITY_FAILED      0x04 ///< the current (autorepeat) frame violated parity check\n\n/**\n * Is filled before calling the user callback to transfer received data to main loop for further processing.\n */\nstruct TinyIRReceiverCallbackDataStruct {\n#if (TINY_RECEIVER_ADDRESS_BITS > 0)\n#  if (TINY_RECEIVER_ADDRESS_BITS == 16) && !TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY\n    uint16_t Address;\n#  else\n    uint8_t Address;\n#  endif\n#endif\n\n#  if (TINY_RECEIVER_COMMAND_BITS == 16) && !TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY\n    uint16_t Command;\n#else\n    uint8_t Command;\n#endif\n    uint8_t Flags; // Bit coded flags. Can contain one of the bits: IRDATA_FLAGS_IS_REPEAT and IRDATA_FLAGS_PARITY_FAILED\n    bool justWritten; ///< Is set true if new data is available. Used by the main loop / TinyIRReceiverDecode(), to avoid multiple evaluations of the same IR frame.\n};\nextern volatile TinyIRReceiverCallbackDataStruct TinyIRReceiverData;\n\nbool isIRReceiverAttachedForTinyReceiver();\nbool initPCIInterruptForTinyReceiver();\nbool enablePCIInterruptForTinyReceiver();\nvoid disablePCIInterruptForTinyReceiver();\nbool isTinyReceiverIdle();\nbool TinyReceiverDecode();\nvoid printTinyReceiverResultMinimal(Print *aSerial);\n\nbool isIRReceiverAttachedForTinyIRReceiver();\nbool initPCIInterruptForTinyIRReceiver();\nbool enablePCIInterruptForTinyIRReceiver();\nvoid disablePCIInterruptForTinyIRReceiver();\nbool isTinyIRReceiverIdle();\nbool TinyIRReceiverDecode();\nvoid printTinyIRReceiverResultMinimal(Print *aSerial);\n\n\nvoid sendFAST(uint8_t aSendPin, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0);\nvoid sendFast8BitAndParity(uint8_t aSendPin, uint8_t aCommand, uint_fast8_t aNumberOfRepeats = 0);\nvoid sendONKYO(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0, bool aSendNEC2Repeats = false); // Send NEC with 16 bit command, even if aCommand < 0x100\nvoid sendNECMinimal(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0)\n        __attribute__ ((deprecated (\"Renamed to sendNEC().\")));\nvoid sendNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0, bool aSendNEC2Repeats = false);\nvoid sendExtendedNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats = 0, bool aSendNEC2Repeats = false);\n\n#if defined(NO_LED_FEEDBACK_CODE)\n#  if !defined(NO_LED_RECEIVE_FEEDBACK_CODE)\n#define NO_LED_RECEIVE_FEEDBACK_CODE\n#  endif\n#  if !defined(NO_LED_SEND_FEEDBACK_CODE)\n#define NO_LED_SEND_FEEDBACK_CODE\n#  endif\n#endif\n\n#if !defined(IR_FEEDBACK_LED_PIN) && defined(LED_BUILTIN)\n#define IR_FEEDBACK_LED_PIN     LED_BUILTIN\n#endif\n\n/*\n *  Version 2.3.0 - 3/2026\n *  - Renamed TinyReceiver*() functions to TinyIRReceiver*().\n *\n *  Version 2.2.0 - 7/2024\n *  - New TinyReceiverDecode() function to be used as drop in for IrReceiver.decode().\n *\n *  Version 2.1.0 - 2/2024\n *  - New sendExtendedNEC() function and new parameter aSendNEC2Repeats.\n *\n *  Version 2.0.0 - 10/2023\n *  - New TinyIRReceiverData which is filled with address, command and flags.\n *  - Removed parameters address, command and flags from callback handleReceivedTinyIRData() and printTinyReceiverResultMinimal().\n *  - Callback function now only enabled if USE_CALLBACK_FOR_TINY_RECEIVER is activated.\n *\n *  Version 1.2.0 - 01/2023\n * - Added ONKYO protocol, NEC with 16 bit address and command, instead of 8 bit + 8 bit parity address and command.\n * - Renamed functions and macros.\n *\n * Version 1.1.0 - 01/2023\n * - FAST protocol added.\n */\n/** @}*/\n\n#endif // _TINY_IR_H\n"
  },
  {
    "path": "src/TinyIRReceiver.hpp",
    "content": "/*\n *  TinyIRReceiver.hpp\n *\n *  Receives IR data of NEC protocol using pin change interrupts.\n *  NEC is the protocol of most cheap remote controls for Arduino.\n *\n *  Parity check is done for address and data.\n *  On a completely received IR command, the user function handleReceivedIRData(uint8_t aAddress, uint8_t aCommand, uint8_t aFlags)\n *  is called in interrupt context but with interrupts being enabled to enable use of delay() etc.\n *  !!!!!!!!!!!!!!!!!!!!!!\n *  Functions called in interrupt context should be running as short as possible,\n *  so if you require longer action, save the data (address + command) and handle them in the main loop.\n *  !!!!!!!!!!!!!!!!!!!!!\n *  aFlags can contain one of IRDATA_FLAGS_EMPTY, IRDATA_FLAGS_IS_REPEAT and IRDATA_FLAGS_PARITY_FAILED bits\n *\n * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header.\n *  FAST Protocol characteristics:\n * - Bit timing is like NEC or JVC\n * - The header is shorter, 3156 vs. 12500\n * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command,\n *     leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms.\n * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance.\n *\n *\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *  This file is also part of IRMP https://github.com/IRMP-org/IRMP.\n *\n ************************************************************************************\n * MIT License\n *\n * Copyright (c) 2022-2026 Armin Joachimsmeyer\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished\n * to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\n * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\n * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n ************************************************************************************\n */\n\n/*\n * This library can be configured at compile time by the following options / macros:\n * For more details see: https://github.com/Arduino-IRremote/Arduino-IRremote#compile-options--macros-for-this-library (scroll down)\n *\n * - IR_RECEIVE_PIN         The pin number for TinyIRReceiver IR input.\n * - IR_FEEDBACK_LED_PIN    The pin number for TinyIRReceiver feedback LED.\n * - NO_LED_FEEDBACK_CODE   Disables the feedback LED function for send and receive. Saves 14 bytes program memory.\n * - NO_LED_RECEIVE_FEEDBACK_CODE Disables the LED feedback code for receive.\n * - NO_LED_SEND_FEEDBACK_CODE    Disables the LED feedback code for send.\n * - DISABLE_PARITY_CHECKS        Disable parity checks. Saves 48 bytes of program memory.\n * - USE_EXTENDED_NEC_PROTOCOL    Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value.\n * - USE_ONKYO_PROTOCOL     Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.\n * - USE_FAST_PROTOCOL      Use FAST protocol (no address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command) instead of NEC.\n * - ENABLE_NEC2_REPEATS    Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.\n * - USE_CALLBACK_FOR_TINY_RECEIVER   Call the user provided function \"void handleReceivedTinyIRData()\" each time a frame or repeat is received.\n */\n\n#ifndef _TINY_IR_RECEIVER_HPP\n#define _TINY_IR_RECEIVER_HPP\n\n#include <Arduino.h>\n\n/*\n * Protocol selection\n */\n//#define USE_EXTENDED_NEC_PROTOCOL // Like NEC, but take the 16 bit address as one 16 bit value and not as 8 bit normal and 8 bit inverted value.\n//#define USE_ONKYO_PROTOCOL    // Like NEC, but take the 16 bit address and command each as one 16 bit value and not as 8 bit normal and 8 bit inverted value.\n//#define USE_FAST_PROTOCOL     // Use FAST protocol instead of NEC / ONKYO.\n//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.\n//#define DISABLE_PARITY_CHECKS // Disable parity checks. Saves 48 bytes of program memory.\n//#define IR_RECEIVE_PIN          2\n//#define IR_FEEDBACK_LED_PIN     12 // Use this, to disable use of LED_BUILTIN definition for IR_FEEDBACK_LED_PIN\n#include \"TinyIR.h\"\n\n#include \"digitalWriteFast.h\"\n/** \\addtogroup TinyIRReceiver Minimal receiver for NEC and FAST protocol\n * @{\n */\n\n// This block must be located after the includes of other *.hpp files\n//#define LOCAL_DEBUG // This enables debug output only for this file - only for development\n//#define LOCAL_TRACE // This enables trace output only for this file - only for development\n#include \"LocalDebugLevelStart.h\"\n#if defined(LOCAL_DEBUG)\n#define LOCAL_DEBUG_ATTACH_INTERRUPT\n#else\n//#define LOCAL_DEBUG_ATTACH_INTERRUPT  // To see if attachInterrupt() or static interrupt (by register tweaking) is used and no other debug output\n#endif\n\n//#define _IR_MEASURE_TIMING        // Activate this if you want to enable internal hardware timing measurement.\n//#define _IR_TIMING_TEST_PIN 7\nTinyIRReceiverStruct TinyIRReceiverControl;\nvolatile TinyIRReceiverCallbackDataStruct TinyIRReceiverData; // The persistent copy of all IR data after receiving a complete frame. To be used by main program.\n\n/*\n * Set input pin and output pin definitions etc.\n */\n#if defined(IR_INPUT_PIN)\n#warning \"IR_INPUT_PIN is deprecated, use IR_RECEIVE_PIN\"\n#define IR_RECEIVE_PIN  IR_INPUT_PIN\n#endif\n\n#if !defined(IR_RECEIVE_PIN)\n#  if defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#warning \"IR_RECEIVE_PIN is not defined, so it is set to 10\"\n#define IR_RECEIVE_PIN    10\n#  elif defined(__AVR_ATtiny816__)\n#warning \"IR_RECEIVE_PIN is not defined, so it is set to 14\"\n#define IR_RECEIVE_PIN    14\n#  else\n#warning \"IR_RECEIVE_PIN is not defined, so it is set to 2\"\n#define IR_RECEIVE_PIN    2\n#  endif\n#endif\n\n#if !defined(NO_LED_RECEIVE_FEEDBACK_CODE)\n#define LED_RECEIVE_FEEDBACK_CODE // Resolve the double negative\n#endif\n\n#if !( \\\n   (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) /* ATtinyX5 */ \\\n|| defined(__AVR_ATtiny88__) /* MH-ET LIVE Tiny88 */ \\\n|| defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) \\\n|| defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) \\\n|| defined(__AVR_ATmega8__) || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \\\n|| defined(__AVR_ATmega168__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) \\\n  /* ATmegas with ports 0,1,2 above and ATtiny167 only 2 pins below */ \\\n|| ( (defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)) && ( (defined(ARDUINO_AVR_DIGISPARKPRO) && ((IR_RECEIVE_PIN == 3) || (IR_RECEIVE_PIN == 9))) /*ATtinyX7(digisparkpro) and pin 3 or 9 */\\\n        || (! defined(ARDUINO_AVR_DIGISPARKPRO) && ((IR_RECEIVE_PIN == 3) || (IR_RECEIVE_PIN == 14)))) ) /*ATtinyX7(ATTinyCore) and pin 3 or 14 */ \\\n)\n/*\n * Cannot use any static ISR vector here. In other cases we have code provided for generating interrupt on pin change.\n * Requires additional 112 bytes program memory + 4 bytes RAM\n */\n#define TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT\n#endif\n\n/**\n * Declaration of the callback function provided by the user application.\n * It is called every time a complete IR command or repeat was received.\n */\nextern void handleReceivedTinyIRData();\n\nuint32_t sMicrosOfGap; // The length of the gap before the start bit, used for trace\n/**\n * The ISR (Interrupt Service Routine) of TinyIRRreceiver.\n * It handles the NEC protocol decoding and calls the user callback function on complete.\n * 5 us + 3 us for push + pop for a 16MHz ATmega\n */\n#if defined(ESP8266) || defined(ESP32)\nIRAM_ATTR\n#endif\nvoid IRPinChangeInterruptHandler(void) {\n#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)\n    digitalWriteFast(_IR_TIMING_TEST_PIN, HIGH); // 2 clock cycles\n#endif\n    /*\n     * Save IR input level\n     * Negative logic, true / HIGH means inactive / IR space, LOW / false means IR mark.\n     */\n    uint_fast8_t tIRLevel = digitalReadFast(IR_RECEIVE_PIN);\n\n#if defined(LED_RECEIVE_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, tIRLevel);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, !tIRLevel);\n#  endif\n#endif\n\n    /*\n     * 1. compute microseconds after last change\n     */\n    // Repeats can be sent after a pause, which is longer than 64000 microseconds, so we need a 32 bit value for check of repeats\n    uint32_t tCurrentMicros = micros();\n    uint32_t tMicrosOfMarkOrSpace32 = tCurrentMicros - TinyIRReceiverControl.LastChangeMicros; // statement is required to force 32 bit arithmetic\n    uint16_t tMicrosOfMarkOrSpace = tMicrosOfMarkOrSpace32;\n\n    TinyIRReceiverControl.LastChangeMicros = tCurrentMicros;\n\n    uint8_t tState = TinyIRReceiverControl.IRReceiverState;\n\n    TRACE_PRINT(tState);\n    TRACE_PRINT(F(\" D=\"));\n    TRACE_PRINT(tMicrosOfMarkOrSpace);\n//    TRACE_PRINT(F(\" I=\"));\n//    TRACE_PRINT(tIRLevel);\n    TRACE_PRINT('|');\n\n    if (tIRLevel == LOW) {\n        /*\n         * We are at the start of a mark here and tMicrosOfMarkOrSpace is the time of the previous space\n         */\n        if (tMicrosOfMarkOrSpace > TINY_RECEIVER_MARK_TIMEOUT) {\n            // timeout -> must reset state machine\n            tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n        }\n        if (tState == IR_RECEIVER_STATE_WAITING_FOR_START_MARK) {\n            // We are at the beginning of the header mark, check timing at the next transition\n            tState = IR_RECEIVER_STATE_WAITING_FOR_START_SPACE;\n            TinyIRReceiverControl.Flags = IRDATA_FLAGS_EMPTY; // If we do it here, it saves 4 bytes\n#if defined(TRACE) // Do not use LOCAL_TRACE here since sMicrosOfGap is read in a cpp file at TRACE\n            sMicrosOfGap = tMicrosOfMarkOrSpace32;\n#endif\n#if defined(ENABLE_NEC2_REPEATS)\n            // Check for repeat, where full frame is sent again after TINY_RECEIVER_REPEAT_PERIOD ms\n            // Not required for NEC, where repeats are detected by a special header space duration\n            // Must use 32 bit arithmetic here!\n            if (tMicrosOfMarkOrSpace32 < TINY_RECEIVER_MAXIMUM_REPEAT_DISTANCE) {\n                TinyIRReceiverControl.Flags = IRDATA_FLAGS_IS_REPEAT;\n            }\n#endif\n        }\n\n        else if (tState == IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK) {\n            if (tMicrosOfMarkOrSpace >= lowerValue25Percent(TINY_RECEIVER_HEADER_SPACE)\n                    && tMicrosOfMarkOrSpace <= upperValue25Percent(TINY_RECEIVER_HEADER_SPACE)) {\n                /*\n                 * We had a valid data header space before -> initialize data\n                 */\n                TinyIRReceiverControl.IRRawDataBitCounter = 0;\n#if (TINY_RECEIVER_BITS > 16)\n                TinyIRReceiverControl.IRRawData.ULong = 0;\n#else\n                TinyIRReceiverControl.IRRawData.UWord = 0;\n#endif\n                TinyIRReceiverControl.IRRawDataMask = 1;\n                tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE;\n\n#if !defined(ENABLE_NEC2_REPEATS)\n                // Alternatively check for NEC repeat header space length\n            } else if (tMicrosOfMarkOrSpace >= lowerValue25Percent(NEC_REPEAT_HEADER_SPACE)\n                    && tMicrosOfMarkOrSpace <= upperValue25Percent(NEC_REPEAT_HEADER_SPACE)\n                    && TinyIRReceiverControl.IRRawDataBitCounter >= TINY_RECEIVER_BITS) {\n                /*\n                 * We have a repeat header here and no broken receive before -> set repeat flag\n                 */\n                TinyIRReceiverControl.Flags = IRDATA_FLAGS_IS_REPEAT;\n                tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE;\n#endif\n            } else {\n                // This parts are optimized by the compiler into jumps to one code :-)\n                // Wrong length -> reset state\n                tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n            }\n        }\n\n        else if (tState == IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK) {\n            /*\n             * Start of data mark here, check data space length\n             * Maybe the minimum length check could be removed here.\n             */\n            if (tMicrosOfMarkOrSpace >= lowerValue50Percent(TINY_RECEIVER_ZERO_SPACE)\n                    && tMicrosOfMarkOrSpace <= upperValue50Percent(TINY_RECEIVER_ONE_SPACE)) {\n                // We have a valid bit here\n                tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE;\n                if (tMicrosOfMarkOrSpace >= TINY_RECEIVER_ONE_THRESHOLD) {\n                    // we received a 1\n#if (TINY_RECEIVER_BITS > 16)\n                    TinyIRReceiverControl.IRRawData.ULong |= TinyIRReceiverControl.IRRawDataMask;\n#else\n                    TinyIRReceiverControl.IRRawData.UWord |= TinyIRReceiverControl.IRRawDataMask;\n#endif\n                } else {\n                    // we received a 0 - empty code for documentation\n                }\n                // prepare for next bit\n                TinyIRReceiverControl.IRRawDataMask = TinyIRReceiverControl.IRRawDataMask << 1;\n                TinyIRReceiverControl.IRRawDataBitCounter++;\n            } else {\n                // Wrong length -> reset state\n                tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n            }\n        } else {\n            // error wrong state for the received level, e.g. if we missed one change interrupt -> reset state\n            tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n        }\n    }\n\n    else {\n        /*\n         * We are at the start of a space here and tMicrosOfMarkOrSpace is the time of the previous mark\n         *\n         */\n        if (tState == IR_RECEIVER_STATE_WAITING_FOR_START_SPACE) {\n            /*\n             * Check length of header mark here\n             */\n            if (tMicrosOfMarkOrSpace >= lowerValue25Percent(TINY_RECEIVER_HEADER_MARK)\n                    && tMicrosOfMarkOrSpace <= upperValue25Percent(TINY_RECEIVER_HEADER_MARK)) {\n                tState = IR_RECEIVER_STATE_WAITING_FOR_FIRST_DATA_MARK;\n            } else {\n                // Wrong length of header mark -> reset state\n                tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n            }\n        }\n\n        else if (tState == IR_RECEIVER_STATE_WAITING_FOR_DATA_SPACE) {\n            // Check data mark length\n            if (tMicrosOfMarkOrSpace >= lowerValue50Percent(TINY_RECEIVER_BIT_MARK)\n                    && tMicrosOfMarkOrSpace <= upperValue50Percent(TINY_RECEIVER_BIT_MARK)) {\n                /*\n                 * We have a valid mark here, check for transmission complete, i.e. the mark of the stop bit\n                 */\n                if (TinyIRReceiverControl.IRRawDataBitCounter >= TINY_RECEIVER_BITS\n#if !defined(ENABLE_NEC2_REPEATS)\n                        || (TinyIRReceiverControl.Flags & IRDATA_FLAGS_IS_REPEAT) // Do not check for full length received, if we have a short repeat frame\n#endif\n                        ) {\n                    /*\n                     * Code complete -> optionally check parity\n                     */\n                    // Reset state for new start\n                    tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n\n#if !defined(DISABLE_PARITY_CHECKS) && (TINY_RECEIVER_ADDRESS_BITS == 16) && TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY\n                    /*\n                     * Check address parity\n                     * Address is sent first and contained in the lower word\n                     */\n                    if (TinyIRReceiverControl.IRRawData.UBytes[0] != (uint8_t) (~TinyIRReceiverControl.IRRawData.UBytes[1])) {\n#if defined(ENABLE_NEC2_REPEATS)\n                    TinyIRReceiverControl.Flags |= IRDATA_FLAGS_PARITY_FAILED; // here we can have the repeat flag already set\n#else\n                        TinyIRReceiverControl.Flags = IRDATA_FLAGS_PARITY_FAILED; // here we do not check anything, if we have a repeat\n#endif\n                    }\n#endif\n#if !defined(DISABLE_PARITY_CHECKS) && (TINY_RECEIVER_COMMAND_BITS == 16) && TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY\n                    /*\n                     * Check command parity\n                     */\n#if (TINY_RECEIVER_ADDRESS_BITS > 0)\n                    if (TinyIRReceiverControl.IRRawData.UBytes[2] != (uint8_t) (~TinyIRReceiverControl.IRRawData.UBytes[3])) {\n#if defined(ENABLE_NEC2_REPEATS)\n                    TinyIRReceiverControl.Flags |= IRDATA_FLAGS_PARITY_FAILED;\n#else\n                        TinyIRReceiverControl.Flags = IRDATA_FLAGS_PARITY_FAILED;\n#endif\n                        DEBUG_PRINT(F(\"Parity check for command failed. Command=\"));\n                        DEBUG_PRINT(TinyIRReceiverControl.IRRawData.UBytes[2], HEX);\n                        DEBUG_PRINT(F(\" parity=\"));\n                        DEBUG_PRINTLN(TinyIRReceiverControl.IRRawData.UBytes[3], HEX);\n#else\n                    // No address, so command and parity are in the lowest bytes\n                    if (TinyIRReceiverControl.IRRawData.UBytes[0] != (uint8_t) (~TinyIRReceiverControl.IRRawData.UBytes[1])) {\n                        TinyIRReceiverControl.Flags |= IRDATA_FLAGS_PARITY_FAILED;\n                        DEBUG_PRINT(F(\"Parity check for command failed. Command=\"));\n                        DEBUG_PRINT(TinyIRReceiverControl.IRRawData.UBytes[0], HEX);\n                        DEBUG_PRINT(F(\" parity=\"));\n                        DEBUG_PRINTLN(TinyIRReceiverControl.IRRawData.UBytes[1], HEX);\n#endif\n                    }\n#endif\n                    /*\n                     * Call user provided callback here\n                     * The parameter size is dependent of the code variant used in order to save program memory.\n                     * We have 6 cases: 0, 8 bit or 16 bit address, each with 8 or 16 bit command\n                     */\n#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) // no Serial etc. possible in callback for RTOS based cores like ESP, even when interrupts are enabled\n                    interrupts(); // enable interrupts, so delay() etc. works in callback\n#endif\n                    TinyIRReceiverData.justWritten = true;\n                    TinyIRReceiverData.Flags = TinyIRReceiverControl.Flags;\n#if (TINY_RECEIVER_ADDRESS_BITS > 0)\n#  if TINY_RECEIVER_ADDRESS_HAS_8_BIT_PARITY\n                    // Here we have 8 bit address\n                    TinyIRReceiverData.Address = TinyIRReceiverControl.IRRawData.UBytes[0];\n#  else\n                    // Here we have 16 bit address\n                    TinyIRReceiverData.Address = TinyIRReceiverControl.IRRawData.UWord.LowWord;\n#  endif\n#  if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY\n                    // Here we have 8 bit command\n                    TinyIRReceiverData.Command = TinyIRReceiverControl.IRRawData.UBytes[2];\n#  else\n                    // Here we have 16 bit command\n                    TinyIRReceiverData.Command = TinyIRReceiverControl.IRRawData.UWord.HighWord;\n#  endif\n\n#else\n                    // Here we have NO address\n#  if TINY_RECEIVER_COMMAND_HAS_8_BIT_PARITY\n                    // Here we have 8 bit command\n                    TinyIRReceiverData.Command = TinyIRReceiverControl.IRRawData.UBytes[0];\n#  else\n                    // Here we have 16 bit command\n                    TinyIRReceiverData.Command = TinyIRReceiverControl.IRRawData.UWord;\n#  endif\n#endif\n#if defined(USE_CALLBACK_FOR_TINY_RECEIVER)\n                    handleReceivedTinyIRData();\n#endif\n\n                } else {\n                    // not finished yet\n                    tState = IR_RECEIVER_STATE_WAITING_FOR_DATA_MARK;\n                }\n            } else {\n                // Wrong length -> reset state\n                tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n            }\n        } else {\n            // error wrong state for the received level, e.g. if we missed one change interrupt -> reset state\n            tState = IR_RECEIVER_STATE_WAITING_FOR_START_MARK;\n        }\n    }\n\n    TinyIRReceiverControl.IRReceiverState = tState;\n#ifdef _IR_MEASURE_TIMING\n    digitalWriteFast(_IR_TIMING_TEST_PIN, LOW); // 2 clock cycles\n#endif\n}\n\nbool isTinyIRReceiverIdle() {\n    return (TinyIRReceiverControl.IRReceiverState == IR_RECEIVER_STATE_WAITING_FOR_START_MARK);\n}\nbool isTinyReceiverIdle() {\n    return isTinyIRReceiverIdle();\n}\n\n/*\n * Function to be used as drop in for IrReceiver.decode()\n */\nbool TinyIRReceiverDecode() {\n    bool tJustWritten = TinyIRReceiverData.justWritten;\n    if (tJustWritten) {\n        TinyIRReceiverData.justWritten = false;\n    }\n    return tJustWritten;\n}\nbool TinyReceiverDecode() {\n    return TinyIRReceiverDecode();\n}\n\n/*\n * Checks if IR_RECEIVE_PIN is connected and high\n * @return true, if IR Receiver is attached\n */\nbool isIRReceiverAttachedForTinyIRReceiver() {\n    pinModeFast(IR_RECEIVE_PIN, OUTPUT);\n    digitalWriteFast(IR_RECEIVE_PIN, LOW); // discharge pin capacity\n    pinModeFast(IR_RECEIVE_PIN, INPUT);\n    return digitalRead(IR_RECEIVE_PIN); // use slow digitalRead here, since the pin capacity is not fully charged again if we use digitalReadFast.\n}\nbool isIRReceiverAttachedForTinyReceiver() {\n    return isIRReceiverAttachedForTinyIRReceiver();\n}\n\n/**\n * Sets IR_RECEIVE_PIN mode to INPUT, and if IR_FEEDBACK_LED_PIN is defined, sets feedback LED output mode.\n * Then call enablePCIInterruptForTinyIRReceiver()\n */\nbool initPCIInterruptForTinyIRReceiver() {\n    pinModeFast(IR_RECEIVE_PIN, INPUT);\n\n#if defined(LED_RECEIVE_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  endif\n#endif\n    return enablePCIInterruptForTinyReceiver();\n}\nbool initPCIInterruptForTinyReceiver() {\n    return initPCIInterruptForTinyIRReceiver();\n}\n\nvoid printTinyIRReceiverResultMinimal(Print *aSerial) {\n// Print only very short output, since we are in an interrupt context and do not want to miss the next interrupts of the repeats coming soon\n#if defined(USE_FAST_PROTOCOL)\n    aSerial->print(F(\"C=0x\"));\n#else\n    aSerial->print(F(\"A=0x\"));\n    aSerial->print(TinyIRReceiverData.Address, HEX);\n    aSerial->print(F(\" C=0x\"));\n#endif\n    aSerial->print(TinyIRReceiverData.Command, HEX);\n    if (TinyIRReceiverData.Flags == IRDATA_FLAGS_IS_REPEAT) {\n        aSerial->print(F(\" R\"));\n    }\n#if !defined(DISABLE_PARITY_CHECKS)\n    if (TinyIRReceiverData.Flags == IRDATA_FLAGS_PARITY_FAILED) {\n        aSerial->print(F(\" P\"));\n    }\n#endif\n    aSerial->println();\n}\nvoid printTinyReceiverResultMinimal(Print *aSerial) {\n    printTinyIRReceiverResultMinimal(aSerial);\n}\n\n#if !defined(STR_HELPER) && !defined(STR)\n// Helper macro for getting a macro definition as string\n#define STR_HELPER(x) #x\n#define STR(x) STR_HELPER(x)\n#endif\n\n/**************************************************\n * Pin to interrupt mapping for different platforms\n **************************************************/\n#if defined(__AVR_ATtiny816__) || defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define USE_ATTACH_INTERRUPT_DIRECT\n\n#elif !defined(__AVR__) || defined(TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT)\n// Default for all NON AVR platforms\n#define USE_ATTACH_INTERRUPT\n\n#else\n#  if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n#define USE_PCIE\n\n#  elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#    if defined(ARDUINO_AVR_DIGISPARKPRO)\n#      if (IR_RECEIVE_PIN == 3)\n#define USE_INT0\n#      elif (IR_RECEIVE_PIN == 9)\n#define USE_INT1\n#      else\n#        error \"IR_RECEIVE_PIN must be 9 or 3.\"\n#      endif // if (IR_RECEIVE_PIN == 9)\n#    else // defined(ARDUINO_AVR_DIGISPARKPRO)\n#      if (IR_RECEIVE_PIN == 14)\n#define USE_INT0\n#      elif (IR_RECEIVE_PIN == 3)\n#define USE_INT1\n#      else\n#        error \"IR_RECEIVE_PIN must be 14 or 3.\"\n#      endif // if (IR_RECEIVE_PIN == 14)\n#    endif\n\n#  elif (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))\n#    if (IR_RECEIVE_PIN == 21)\n#define USE_INT0\n#    elif (IR_RECEIVE_PIN == 20)\n#define USE_INT1\n#    else\n#warning \"No pin mapping for IR_RECEIVE_PIN to interrupt found -> attachInterrupt() is used now.\"\n#define USE_ATTACH_INTERRUPT\n#    endif\n\n#  else // defined(__AVR_ATtiny25__)\n/*\n * ATmegas + ATtiny88 here\n */\n#    if (IR_RECEIVE_PIN == 2)\n#define USE_INT0\n#    elif (IR_RECEIVE_PIN == 3)\n#define USE_INT1\n\n#    elif IR_RECEIVE_PIN == 4 || IR_RECEIVE_PIN == 5 || IR_RECEIVE_PIN == 6 || IR_RECEIVE_PIN == 7\n    //ATmega328 (Uno, Nano ) etc. Enable pin change interrupt 20 to 23 for port PD4 to PD7 (Arduino pin 4 to 7)\n#define USE_PCINT2\n#    elif IR_RECEIVE_PIN == 8 || IR_RECEIVE_PIN == 9 || IR_RECEIVE_PIN == 10 || IR_RECEIVE_PIN == 11 || IR_RECEIVE_PIN == 12 || IR_RECEIVE_PIN == 13\n    //ATmega328 (Uno, Nano ) etc. Enable pin change interrupt 0 to 5 for port PB0 to PB5 (Arduino pin 8 to 13)\n#define USE_PCINT0\n#    elif IR_RECEIVE_PIN == A0 || IR_RECEIVE_PIN == A1 || IR_RECEIVE_PIN == A2 || IR_RECEIVE_PIN == A3 || IR_RECEIVE_PIN == A4 || IR_RECEIVE_PIN == A5\n    //ATmega328 (Uno, Nano ) etc. Enable pin change interrupt 8 to 13 for port PC0 to PC5 (Arduino pin A0 to A5)\n#define USE_PCINT1\n\n#    else\n#warning \"No pin mapping for IR_RECEIVE_PIN to interrupt found -> attachInterrupt() is used now.\"\n#define USE_ATTACH_INTERRUPT\n#    endif // if (IR_RECEIVE_PIN == 2)\n#  endif // defined(__AVR_ATtiny25__)\n#endif // ! defined(__AVR__) || defined(TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT)\n\n/**\n * Initializes hardware interrupt generation according to IR_RECEIVE_PIN or use attachInterrupt() function.\n * @return true if interrupt was successfully enabled\n */\nbool enablePCIInterruptForTinyIRReceiver() {\n#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)\n    pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);\n#endif\n\n#if defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT)\n#  if defined(USE_ATTACH_INTERRUPT)\n#    if defined(NOT_AN_INTERRUPT) // check if IDE has defined the check of digitalPinToInterrupt\n    if(digitalPinToInterrupt(IR_RECEIVE_PIN) == NOT_AN_INTERRUPT){\n        return false;\n    }\n#    endif\n    // costs 112 bytes program memory + 4 bytes RAM\n#    if defined(ARDUINO_ARCH_SAMD) // see https://www.arduino.cc/reference/tr/language/functions/external-interrupts/attachinterrupt/ paragraph: Syntax\n    attachInterrupt(IR_RECEIVE_PIN, IRPinChangeInterruptHandler, CHANGE); // no extra pin mapping here :-(\n#    else\n    attachInterrupt(digitalPinToInterrupt(IR_RECEIVE_PIN), IRPinChangeInterruptHandler, CHANGE); // CHANGE can be an enum :-(\n#    endif\n#  else\n    // USE_ATTACH_INTERRUPT_DIRECT here, only defined for ATtinies *16, see above\n    // 2.2 us more than version configured with macros and not compatible\n    attachInterrupt(IR_RECEIVE_PIN, IRPinChangeInterruptHandler, CHANGE); // no extra pin mapping here\n#  endif\n\n#  if defined(LOCAL_DEBUG_ATTACH_INTERRUPT)\n    Serial.println(F(\"Use attachInterrupt for pin=\" STR(IR_RECEIVE_PIN)));\n#  endif\n#else\n#  if defined(LOCAL_DEBUG_ATTACH_INTERRUPT)\n    Serial.println(F(\"Use hardware/static interrupt for pin=\" STR(IR_RECEIVE_PIN)));\n#  endif\n\n#  if defined(USE_INT0)\n    // interrupt on any logical change\n    EICRA |= _BV(ISC00);\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT0;\n\n#  elif defined(USE_INT1)\n    EICRA |= _BV(ISC10);\n// clear interrupt bit\n    EIFR |= 1 << INTF1;\n// enable interrupt on next change\n    EIMSK |= 1 << INT1;\n\n#  elif defined(USE_PCIE) // For ATtiny85 etc.\n    // use PinChangeInterrupt no INT0 for pin PB2\n    PCMSK = _BV(IR_RECEIVE_PIN);\n    // clear interrupt bit\n    GIFR |= 1 << PCIF;\n    // enable interrupt on next change\n    GIMSK |= 1 << PCIE;\n\n#  elif defined(USE_PCINT0)\n    PCICR |= _BV(PCIE0);\n    PCMSK0 = digitalPinToBitMask(IR_RECEIVE_PIN);\n#  elif defined(USE_PCINT1)\n    PCICR |= _BV(PCIE1);\n    PCMSK1 = digitalPinToBitMask(IR_RECEIVE_PIN);\n#  elif defined(USE_PCINT2)\n    PCICR |= _BV(PCIE2);\n    PCMSK2 = digitalPinToBitMask(IR_RECEIVE_PIN);\n#  else\n    return false;\n#  endif\n#endif // defined(USE_ATTACH_INTERRUPT)\n    return true;\n}\nbool enablePCIInterruptForTinyReceiver() {\n    return enablePCIInterruptForTinyIRReceiver();\n}\n\nvoid disablePCIInterruptForTinyIRReceiver() {\n#if defined(_IR_MEASURE_TIMING) && defined(_IR_TIMING_TEST_PIN)\n    pinModeFast(_IR_TIMING_TEST_PIN, OUTPUT);\n#endif\n\n#if defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT)\n#  if defined(USE_ATTACH_INTERRUPT)\n    detachInterrupt(digitalPinToInterrupt(IR_RECEIVE_PIN));\n#  else\n    detachInterrupt(IR_RECEIVE_PIN);\n#  endif\n\n#else\n#  if defined(USE_INT0)\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT0);\n\n#  elif defined(USE_INT1)\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT1);\n\n#  elif defined(USE_PCIE) // For ATtiny85 etc.\n    // clear interrupt bit\n    GIFR |= 1 << PCIF;\n    // disable interrupt on next change\n    GIMSK &= ~(1 << PCIE);\n\n#  elif defined(USE_PCINT0)\n    PCICR &= ~(_BV(PCIE0));\n#  elif defined(USE_PCINT1)\n    PCICR &= ~(_BV(PCIE1));\n#  elif defined(USE_PCINT2)\n    PCICR &= ~(_BV(PCIE2));\n\n#  endif\n#endif // defined(USE_ATTACH_INTERRUPT)\n}\nvoid disablePCIInterruptForTinyReceiver() {\n    disablePCIInterruptForTinyIRReceiver();\n}\n\n/*\n * Specify the right INT0, INT1 or PCINT0 interrupt vector according to different pins and cores.\n * The default value of TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT is set in TinyIRReceiver.h\n */\n#if !(defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT))\n#  if defined(USE_INT0)\nISR(INT0_vect)\n\n#  elif defined(USE_INT1)\nISR(INT1_vect)\n\n#  elif defined(USE_PCIE) // For ATtiny85 etc.\n// on ATtinyX5 we do not have a INT1_vect but we can use the PCINT0_vect\nISR(PCINT0_vect)\n\n#  elif defined(USE_PCINT0)\nISR(PCINT0_vect)\n#  elif defined(USE_PCINT1)\nISR(PCINT1_vect)\n#  elif defined(USE_PCINT2)\nISR(PCINT2_vect)\n#  else\nvoid dummyFunctionToAvoidCompilerErrors()\n#  endif\n{\n    IRPinChangeInterruptHandler();\n}\n#endif // !(defined(USE_ATTACH_INTERRUPT) || defined(USE_ATTACH_INTERRUPT_DIRECT))\n\n/** @}*/\n\n#if defined(LOCAL_DEBUG_ATTACH_INTERRUPT)\n#undef LOCAL_DEBUG_ATTACH_INTERRUPT\n#endif\n#include \"LocalDebugLevelEnd.h\"\n\n#endif // _TINY_IR_RECEIVER_HPP\n"
  },
  {
    "path": "src/TinyIRSender.hpp",
    "content": "/*\n *  TinyIRSender.hpp\n *\n *  Sends IR protocol data of NEC and FAST protocol using bit banging.\n *  NEC is the protocol of most cheap remote controls for Arduino.\n *\n * The FAST protocol is a proprietary modified JVC protocol without address, with parity and with a shorter header.\n *  FAST Protocol characteristics:\n * - Bit timing is like NEC or JVC\n * - The header is shorter, 3156 vs. 12500\n * - No address and 16 bit data, interpreted as 8 bit command and 8 bit inverted command,\n *     leading to a fixed protocol length of (6 + (16 * 3) + 1) * 526 = 55 * 526 = 28930 microseconds or 29 ms.\n * - Repeats are sent as complete frames but in a 50 ms period / with a 21 ms distance.\n *\n *\n *  This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.\n *  This file is also part of IRMP https://github.com/IRMP-org/IRMP.\n *\n ************************************************************************************\n * MIT License\n *\n * Copyright (c) 2022-2026 Armin Joachimsmeyer\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is furnished\n * to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\n * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE\n * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n ************************************************************************************\n */\n\n#ifndef _TINY_IR_SENDER_HPP\n#define _TINY_IR_SENDER_HPP\n\n#include <Arduino.h>\n\n//#define ENABLE_NEC2_REPEATS // Instead of sending / receiving the NEC special repeat code, send / receive the original frame for repeat.\n\n//#define NO_LED_SEND_FEEDBACK_CODE     // Disables the LED feedback code for receive.\n//#define IR_FEEDBACK_LED_PIN     12    // Use this, to disable use of LED_BUILTIN definition for IR_FEEDBACK_LED_PIN\n#include \"TinyIR.h\" // Defines protocol timings\n\n#include \"digitalWriteFast.h\"\n/** \\addtogroup TinySender Minimal sender for NEC and FAST protocol\n * @{\n */\n\n#if !defined(IR_SEND_PIN)\n#warning \"IR_SEND_PIN is not defined, so it is set to 3\"\n#define IR_SEND_PIN    3\n#endif\n#if !defined(NO_LED_SEND_FEEDBACK_CODE)\n#define LED_SEND_FEEDBACK_CODE // Resolve the double negative\n#endif\n\n/*\n * Generate 38 kHz IR signal by bit banging and using delayMicroseconds() and micros()\n */\nvoid sendMark(uint8_t aSendPin, unsigned int aMarkMicros) {\n    unsigned long tMicros = micros();\n    unsigned long tNextPeriodEnding = tMicros;\n#if defined(F_CPU)\n    unsigned long tEndMicros = tMicros + (112 / (F_CPU / MICROS_IN_ONE_SECOND)) + aMarkMicros; // To compensate for call duration - 112 is an empirical value\n#else\n    unsigned long tEndMicros = tMicros + aMarkMicros;\n#endif\n    do {\n        /*\n         * Generate pulse\n         */\n        noInterrupts(); // do not let interrupts extend the short on period\n        digitalWriteFast(aSendPin, HIGH);\n        delayMicroseconds(8); // 8 us for a 30 % duty cycle for 38 kHz\n        digitalWriteFast(aSendPin, LOW);\n        interrupts(); // Enable interrupts - to keep micros correct- for the longer off period 3.4 us until receive ISR is active (for 7 us + pop's)\n\n        /*\n         * PWM pause timing and end check\n         * Minimal pause duration is 4.3 us\n         */\n        tNextPeriodEnding += 26; // 26.3 us period for 38 kHz; 26 us -> 38.48 kHz\n        do {\n            tMicros = micros(); // we have only 4 us resolution for AVR @16MHz\n            /*\n             * Exit the forever loop if aMarkMicros has reached\n             */\n            if (tMicros >= tEndMicros) {\n                return;\n            }\n        } while (tMicros < tNextPeriodEnding);\n    } while (true);\n}\n\n/*\n * Send NEC with 16 bit address and command, even if aCommand < 0x100 (I.E. ONKYO)\n * @param aAddress  - The 16 bit address to send.\n * @param aCommand  - The 16 bit command to send.\n * @param aNumberOfRepeats  - Number of repeats send at a period of 110 ms.\n * @param aSendNEC2Repeats - Instead of sending the NEC special repeat code, send the original frame for repeat.\n */\nvoid sendONKYO(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats, bool aSendNEC2Repeats) {\n    pinModeFast(aSendPin, OUTPUT);\n\n#if !defined(NO_LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  endif\n#endif\n\n    uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;\n    while (tNumberOfCommands > 0) {\n        unsigned long tStartOfFrameMillis = millis();\n\n        sendMark(aSendPin, NEC_HEADER_MARK);\n        if ((!aSendNEC2Repeats) && (tNumberOfCommands < aNumberOfRepeats + 1)) {\n            // send the NEC special repeat\n            delayMicroseconds (NEC_REPEAT_HEADER_SPACE); // - 2250\n        } else {\n            // send header\n            delayMicroseconds (NEC_HEADER_SPACE);\n            LongUnion tData;\n            tData.UWord.LowWord = aAddress;\n            tData.UWord.HighWord = aCommand;\n            // Send data\n            for (uint_fast8_t i = 0; i < NEC_BITS; ++i) {\n                sendMark(aSendPin, NEC_BIT_MARK); // constant mark length\n                if (tData.ULong & 1) {\n                    delayMicroseconds (NEC_ONE_SPACE);\n                } else {\n                    delayMicroseconds (NEC_ZERO_SPACE);\n                }\n                tData.ULong >>= 1; // shift command for next bit\n            }\n        }        // send stop bit\n        sendMark(aSendPin, NEC_BIT_MARK);\n\n        tNumberOfCommands--;\n        // skip last delay!\n        if (tNumberOfCommands > 0) {\n            /*\n             * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.\n             */\n            auto tFrameDurationMillis = millis() - tStartOfFrameMillis;\n            if (NEC_REPEAT_PERIOD / 1000 > tFrameDurationMillis) {\n                delay(NEC_REPEAT_PERIOD / 1000 - tFrameDurationMillis);\n            }\n        }\n    }\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  endif\n#endif\n}\n\n/*\n * Send NEC with 8 or 16 bit address or command depending on the values of aAddress and aCommand.\n * @param aAddress  - If aAddress < 0x100 send 8 bit address and 8 bit inverted address, else send 16 bit address.\n * @param aCommand  - If aCommand < 0x100 send 8 bit command and 8 bit inverted command, else send 16 bit command.\n * @param aNumberOfRepeats  - Number of repeats send at a period of 110 ms.\n * @param aSendNEC2Repeats - Instead of sending the NEC special repeat code, send the original frame for repeat.\n */\nvoid sendNECMinimal(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats) {\n    sendNEC(aSendPin, aAddress, aCommand, aNumberOfRepeats); // sendNECMinimal() is deprecated\n}\nvoid sendNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats, bool aSendNEC2Repeats) {\n    pinModeFast(aSendPin, OUTPUT);\n\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  endif\n#endif\n\n    uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;\n    while (tNumberOfCommands > 0) {\n        unsigned long tStartOfFrameMillis = millis();\n\n        sendMark(aSendPin, NEC_HEADER_MARK);\n        if ((!aSendNEC2Repeats) && (tNumberOfCommands < aNumberOfRepeats + 1)) {\n            // send the NEC special repeat\n            delayMicroseconds (NEC_REPEAT_HEADER_SPACE); // - 2250\n        } else {\n            // send header\n            delayMicroseconds (NEC_HEADER_SPACE);\n            LongUnion tData;\n            /*\n             * The compiler is intelligent and removes the code for \"(aAddress > 0xFF)\" if we are called with an uint8_t address :-).\n             * Using an uint16_t address requires additional 28 bytes program memory.\n             */\n            if (aAddress > 0xFF) {\n                tData.UWord.LowWord = aAddress;\n            } else {\n                tData.UByte.LowByte = aAddress; // LSB first\n                tData.UByte.MidLowByte = ~aAddress;\n            }\n            if (aCommand > 0xFF) {\n                tData.UWord.HighWord = aCommand;\n            } else {\n                tData.UByte.MidHighByte = aCommand;\n                tData.UByte.HighByte = ~aCommand; // LSB first\n            }\n            // Send data\n            for (uint_fast8_t i = 0; i < NEC_BITS; ++i) {\n                sendMark(aSendPin, NEC_BIT_MARK); // constant mark length\n\n                if (tData.ULong & 1) {\n                    delayMicroseconds (NEC_ONE_SPACE);\n                } else {\n                    delayMicroseconds (NEC_ZERO_SPACE);\n                }\n                tData.ULong >>= 1; // shift command for next bit\n            }\n        }        // send stop bit\n        sendMark(aSendPin, NEC_BIT_MARK);\n\n        tNumberOfCommands--;\n        // skip last delay!\n        if (tNumberOfCommands > 0) {\n            /*\n             * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.\n             */\n            auto tFrameDurationMillis = millis() - tStartOfFrameMillis;\n            if (NEC_REPEAT_PERIOD / 1000 > tFrameDurationMillis) {\n                delay(NEC_REPEAT_PERIOD / 1000 - tFrameDurationMillis);\n            }\n        }\n    }\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  endif\n#endif\n}\n\n/*\n * Send Extended NEC with a forced 16 bit address and 8 or 16 bit command depending on the value of aCommand.\n * @param aAddress  - Send 16 bit address.\n * @param aCommand  - If aCommand < 0x100 send 8 bit command and 8 bit inverted command, else send 16 bit command.\n * @param aNumberOfRepeats  - Number of repeats send at a period of 110 ms.\n * @param aSendNEC2Repeats - Instead of sending the NEC special repeat code, send the original frame for repeat.\n */\nvoid sendExtendedNEC(uint8_t aSendPin, uint16_t aAddress, uint16_t aCommand, uint_fast8_t aNumberOfRepeats, bool aSendNEC2Repeats) {\n    pinModeFast(aSendPin, OUTPUT);\n\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  endif\n#endif\n\n    uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;\n    while (tNumberOfCommands > 0) {\n        unsigned long tStartOfFrameMillis = millis();\n\n        sendMark(aSendPin, NEC_HEADER_MARK);\n        if ((!aSendNEC2Repeats) && (tNumberOfCommands < aNumberOfRepeats + 1)) {\n            // send the NEC special repeat\n            delayMicroseconds (NEC_REPEAT_HEADER_SPACE); // - 2250\n        } else {\n            // send header\n            delayMicroseconds (NEC_HEADER_SPACE);\n            LongUnion tData;\n            tData.UWord.LowWord = aAddress;\n            if (aCommand > 0xFF) {\n                tData.UWord.HighWord = aCommand;\n            } else {\n                tData.UByte.MidHighByte = aCommand;\n                tData.UByte.HighByte = ~aCommand; // LSB first\n            }\n            // Send data\n            for (uint_fast8_t i = 0; i < NEC_BITS; ++i) {\n                sendMark(aSendPin, NEC_BIT_MARK); // constant mark length\n\n                if (tData.ULong & 1) {\n                    delayMicroseconds (NEC_ONE_SPACE);\n                } else {\n                    delayMicroseconds (NEC_ZERO_SPACE);\n                }\n                tData.ULong >>= 1; // shift command for next bit\n            }\n        }        // send stop bit\n        sendMark(aSendPin, NEC_BIT_MARK);\n\n        tNumberOfCommands--;\n        // skip last delay!\n        if (tNumberOfCommands > 0) {\n            /*\n             * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.\n             */\n            auto tFrameDurationMillis = millis() - tStartOfFrameMillis;\n            if (NEC_REPEAT_PERIOD / 1000 > tFrameDurationMillis) {\n                delay(NEC_REPEAT_PERIOD / 1000 - tFrameDurationMillis);\n            }\n        }\n    }\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  endif\n#endif\n}\n\n/*\n * LSB first, send header, command, inverted command and stop bit\n */\nvoid sendFast8BitAndParity(uint8_t aSendPin, uint8_t aCommand, uint_fast8_t aNumberOfRepeats) {\n    sendFAST(aSendPin, aCommand, aNumberOfRepeats);\n}\n\n/*\n * LSB first, send header, 16 bit command or 8 bit command, inverted command and stop bit\n */\nvoid sendFAST(uint8_t aSendPin, uint16_t aCommand, uint_fast8_t aNumberOfRepeats) {\n    pinModeFast(aSendPin, OUTPUT);\n\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  endif\n#endif\n\n    uint_fast8_t tNumberOfCommands = aNumberOfRepeats + 1;\n    while (tNumberOfCommands > 0) {\n        unsigned long tStartOfFrameMillis = millis();\n\n        // send header\n        sendMark(aSendPin, FAST_HEADER_MARK);\n        delayMicroseconds(FAST_HEADER_SPACE);\n        uint16_t tData;\n        /*\n         * The compiler is intelligent and removes the code for \"(aCommand > 0xFF)\" if we are called with an uint8_t command :-).\n         * Using an uint16_t command requires additional 56 bytes program memory.\n         */\n        if (aCommand > 0xFF) {\n            tData = aCommand;\n        } else {\n            tData = aCommand | (((uint8_t) (~aCommand)) << 8); // LSB first\n        }\n        // Send data\n        for (uint_fast8_t i = 0; i < FAST_BITS; ++i) {\n            sendMark(aSendPin, FAST_BIT_MARK); // constant mark length\n\n            if (tData & 1) {\n                delayMicroseconds(FAST_ONE_SPACE);\n            } else {\n                delayMicroseconds(FAST_ZERO_SPACE);\n            }\n            tData >>= 1; // shift command for next bit\n        }\n        // send stop bit\n        sendMark(aSendPin, FAST_BIT_MARK);\n\n        tNumberOfCommands--;\n        // skip last delay!\n        if (tNumberOfCommands > 0) {\n            /*\n             * Check and fallback for wrong RepeatPeriodMillis parameter. I.e the repeat period must be greater than each frame duration.\n             */\n            auto tFrameDurationMillis = millis() - tStartOfFrameMillis;\n            if (FAST_REPEAT_PERIOD / 1000 > tFrameDurationMillis) {\n                delay(FAST_REPEAT_PERIOD / 1000 - tFrameDurationMillis);\n            }\n        }\n    }\n#if defined(LED_SEND_FEEDBACK_CODE) && defined(IR_FEEDBACK_LED_PIN)\n    pinModeFast(IR_FEEDBACK_LED_PIN, OUTPUT);\n#  if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, HIGH);\n#  else\n    digitalWriteFast(IR_FEEDBACK_LED_PIN, LOW);\n#  endif\n#endif\n}\n\n/** @}*/\n\n#endif // _TINY_IR_SENDER_HPP\n"
  },
  {
    "path": "src/digitalWriteFast.h",
    "content": "/*\n * digitalWriteFast.h\n *\n * Optimized digital functions for AVR microcontrollers\n * by Watterott electronic (www.watterott.com)\n * based on https://code.google.com/p/digitalwritefast\n *\n * The value of DigitalReadFast() is the content of the input register e.g. 0x04 for pin2 and NOT always 0 or 1.\n *\n * License: BSD 3-Clause License (https://opensource.org/licenses/BSD-3-Clause)\n */\n\n#ifndef __digitalWriteFast_h_\n#define __digitalWriteFast_h_ 1\n\n//#define THROW_ERROR_IF_NOT_FAST // If activated, an error is thrown if pin is not a compile time constant\nvoid NonConstantsUsedForPinModeFast( void )  __attribute__ (( error(\"Parameter for pinModeFast() function is not constant\") ));\nvoid NonConstantsUsedForDigitalWriteFast( void )  __attribute__ (( error(\"Parameter for digitalWriteFast() function is not constant\") ));\nvoid NonConstantsUsedForDigitalToggleFast( void )  __attribute__ (( error(\"Parameter for digitalToggleFast() function is not constant\") ));\nint NonConstantsUsedForDigitalReadFast( void )  __attribute__ (( error(\"Parameter for digitalReadFast() function is not constant\") ));\n\n#if !defined(MEGATINYCORE) // megaTinyCore has it own digitalWriteFast function set, except digitalToggleFast().\n\n//#define SANGUINO_PINOUT // define for Sanguino pinout\n\n// general macros/defines\n#if !defined(BIT_READ)\n# define BIT_READ(value, bit)            ((value) &   (1UL << (bit)))\n#endif\n#if !defined(BIT_SET)\n# define BIT_SET(value, bit)             ((value) |=  (1UL << (bit)))\n#endif\n#if !defined(BIT_CLEAR)\n# define BIT_CLEAR(value, bit)           ((value) &= ~(1UL << (bit)))\n#endif\n#if !defined(BIT_WRITE)\n# define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit))\n#endif\n\n#include <Arduino.h> // declarations for the fallback to digitalWrite(), digitalRead() etc.\n\n// --- Arduino Mega and ATmega128x/256x based boards ---\n#if (defined(ARDUINO_AVR_MEGA) || \\\n       defined(ARDUINO_AVR_MEGA1280) || \\\n       defined(ARDUINO_AVR_MEGA2560) || \\\n       defined(__AVR_ATmega1280__) || \\\n       defined(__AVR_ATmega1281__) || \\\n       defined(__AVR_ATmega2560__) || \\\n       defined(__AVR_ATmega2561__))\n\n#define __digitalPinToPortReg(P) \\\n(((P) >= 22 && (P) <= 29) ? &PORTA : \\\n((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \\\n(((P) >= 30 && (P) <= 37) ? &PORTC : \\\n((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \\\n((((P) <= 3) || (P) == 5) ? &PORTE : \\\n(((P) >= 54 && (P) <= 61) ? &PORTF : \\\n((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \\\n((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \\\n(((P) == 14 || (P) == 15) ? &PORTJ : \\\n(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))\n\n#define __digitalPinToDDRReg(P) \\\n(((P) >= 22 && (P) <= 29) ? &DDRA : \\\n((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \\\n(((P) >= 30 && (P) <= 37) ? &DDRC : \\\n((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \\\n((((P) <= 3) || (P) == 5) ? &DDRE : \\\n(((P) >= 54 && (P) <= 61) ? &DDRF : \\\n((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \\\n((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \\\n(((P) == 14 || (P) == 15) ? &DDRJ : \\\n(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))\n\n#define __digitalPinToPINReg(P) \\\n(((P) >= 22 && (P) <= 29) ? &PINA : \\\n((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \\\n(((P) >= 30 && (P) <= 37) ? &PINC : \\\n((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \\\n((((P) <= 3) || (P) == 5) ? &PINE : \\\n(((P) >= 54 && (P) <= 61) ? &PINF : \\\n((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \\\n((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \\\n(((P) == 14 || (P) == 15) ? &PINJ : \\\n(((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))\n\n#define __digitalPinToBit(P) \\\n(((P) >=  7 && (P) <=  9) ? (P) - 3 : \\\n(((P) >= 10 && (P) <= 13) ? (P) - 6 : \\\n(((P) >= 22 && (P) <= 29) ? (P) - 22 : \\\n(((P) >= 30 && (P) <= 37) ? 37 - (P) : \\\n(((P) >= 39 && (P) <= 41) ? 41 - (P) : \\\n(((P) >= 42 && (P) <= 49) ? 49 - (P) : \\\n(((P) >= 50 && (P) <= 53) ? 53 - (P) : \\\n(((P) >= 54 && (P) <= 61) ? (P) - 54 : \\\n(((P) >= 62 && (P) <= 69) ? (P) - 62 : \\\n(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \\\n(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \\\n(((P) == 19) ? 2 : \\\n(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \\\n(((P) == 2) ? 4 : \\\n(((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))\n\n\n// --- Arduino MightyCore standard pinout ---\n#elif (defined(__AVR_ATmega1284P__) || \\\n       defined(__AVR_ATmega1284__)  || \\\n       defined(__AVR_ATmega644P__)  || \\\n       defined(__AVR_ATmega644A__)  || \\\n       defined(__AVR_ATmega644__)   || \\\n       defined(__AVR_ATmega324PB__) || \\\n       defined(__AVR_ATmega324PA__) || \\\n       defined(__AVR_ATmega324P__)  || \\\n       defined(__AVR_ATmega324A__)  || \\\n       defined(__AVR_ATmega164P__)  || \\\n       defined(__AVR_ATmega164A__)  || \\\n       defined(__AVR_ATmega32__)    || \\\n       defined(__AVR_ATmega16__)    || \\\n       defined(__AVR_ATmega8535__))  && \\\n      !defined(BOBUINO_PINOUT)\n\n#if defined(__AVR_ATmega324PB__)\n#define __digitalPinToPortReg(P) \\\n(((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : (((P) >= 24 && (P) <= 31) ? &PORTA : &PORTE))))\n#define __digitalPinToDDRReg(P) \\\n(((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : (((P) >= 24 && (P) <= 31) ? &DDRA : &DDRE))))\n#define __digitalPinToPINReg(P) \\\n(((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : (((P) >= 24 && (P) <= 31) ? &PINA : &PINE))))\n# if defined(SANGUINO_PINOUT)\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (7 - ((P) - 24)) : (P) - 32))))\n# else //MightyCore Pinout\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (((P) >= 16 && (P) <= 23) ? (P) - 24 : (P) - 32))))\n# endif\n#elif defined(PORTA)\n#define __digitalPinToPortReg(P) \\\n(((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA)))\n#define __digitalPinToDDRReg(P) \\\n(((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : &DDRA)))\n#define __digitalPinToPINReg(P) \\\n(((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : &PINA)))\n# if defined(SANGUINO_PINOUT)\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24)))))\n# else //MightyCore Pinout\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))\n# endif\n#else\n#define __digitalPinToPortReg(P) \\\n(((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : &PORTC))\n#define __digitalPinToDDRReg(P) \\\n(((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : &DDRC))\n#define __digitalPinToPINReg(P) \\\n(((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : &PINC))\n# if defined(SANGUINO_PINOUT)\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (7 - ((P) - 24)))))\n# else //MightyCore Pinout\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P) - 8 : (((P) >= 16 && (P) <= 23) ? (P) - 16 : (P) - 24)))\n# endif\n#endif\n\n\n// --- Arduino Leonardo and ATmega16U4/32U4 based boards ---\n#elif (defined(ARDUINO_AVR_LEONARDO) || \\\n       defined(__AVR_ATmega16U4__) || \\\n       defined(__AVR_ATmega32U4__))\n#  if defined(TEENSYDUINO)\n\n#define __digitalPinToPortReg(P) \\\n((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PORTB : (((P) == 9 || (P) == 10) ? &PORTC : (((P) >= 16 && (P) <= 21)) ? &PORTF : &PORTD))\n#define __digitalPinToDDRReg(P) \\\n((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &DDRB : (((P) == 9 || (P) == 10) ? &DDRC : (((P) >= 16 && (P) <= 21)) ? &DDRF : &DDRD))\n#define __digitalPinToPINReg(P) \\\n((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PINB : (((P) == 9 || (P) == 10) ? &PINC : (((P) >= 16 && (P) <= 21)) ? &PINF : &PIND))\n#define __digitalPinToBit(P) \\\n(((P) <= 3) ? (P) : \\\n(((P) == 4 || (P) == 12) ? 7 : \\\n(((P) <= 8) ? (P) - 5 : \\\n(((P) <= 10) ? (P) - 3 : \\\n(((P) == 11) ? 6 : \\\n(((P) <= 15) ? (P) - 9 : \\\n(((P) <= 19) ? 23 - (P) : \\\n(((P) <= 21) ? 21 - (P) : (P) - 18))))))))\n#  else\n\n#define __digitalPinToPortReg(P) \\\n((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF : (((P) == 7) ? &PORTE : &PORTB)))\n#define __digitalPinToDDRReg(P) \\\n((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF : (((P) == 7) ? &DDRE : &DDRB)))\n#define __digitalPinToPINReg(P) \\\n((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF : (((P) == 7) ? &PINE : &PINB)))\n#define __digitalPinToBit(P) \\\n(((P) >= 8 && (P) <= 11) ? (P) - 4 : \\\n(((P) >= 18 && (P) <= 21) ? 25 - (P) : \\\n(((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : \\\n(((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : \\\n(((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6 )))))))))))))))))))\n#  endif\n\n// --- Arduino Uno and ATmega168/328 based boards ---\n#elif (defined(ARDUINO_AVR_UNO) || \\\n       defined(ARDUINO_AVR_DUEMILANOVE) || \\\n       defined(__AVR_ATmega8__) || \\\n       defined(__AVR_ATmega48__) || \\\n       defined(__AVR_ATmega48P__) || \\\n       defined(__AVR_ATmega48PB__) || \\\n       defined(__AVR_ATmega88P__) || \\\n       defined(__AVR_ATmega88PB__) || \\\n       defined(__AVR_ATmega168__) || \\\n       defined(__AVR_ATmega168PA__) || \\\n       defined(__AVR_ATmega168PB__) || \\\n       defined(__AVR_ATmega328__) || \\\n       defined(__AVR_ATmega328P__) || \\\n       defined(__AVR_ATmega328PB__))\n\n#if defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328PB__)\n#define __digitalPinToPortReg(P) \\\n(((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE)))\n#define __digitalPinToDDRReg(P) \\\n(((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE)))\n#define __digitalPinToPINReg(P) \\\n(((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE)))\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (((P) >= 14 && (P) <= 19) ? (P) - 14 : (((P) >= 20 && (P) <= 21) ? (P) - 18 : (P) - 22))))\n#else\n#define __digitalPinToPortReg(P) \\\n(((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))\n#define __digitalPinToDDRReg(P) \\\n(((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))\n#define __digitalPinToPINReg(P) \\\n(((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))\n#define __digitalPinToBit(P) \\\n(((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))\n#endif\n\n// --- Arduino Uno WiFi Rev 2, Nano Every ---\n#elif defined(__AVR_ATmega4809__)\n\n#define __digitalPinToPortReg(P) \\\n(((P) == 2 || (P) == 7 ) ? &VPORTA.OUT : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.OUT : ((P) == 4) ? &VPORTC.OUT : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.OUT : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.OUT : &VPORTF.OUT)\n#define __digitalPinToDDRReg(P) \\\n(((P) == 2 || (P) == 7 ) ? &VPORTA.DIR : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.DIR : ((P) == 4) ? &VPORTC.DIR : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.DIR : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.DIR : &VPORTF.DIR)\n#define __digitalPinToPINReg(P) \\\n(((P) == 2 || (P) == 7 ) ? &VPORTA.IN : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.IN : ((P) == 4) ? &VPORTC.IN : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.IN : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.IN : &VPORTF.IN)\n#define __digitalPinToBit(P) \\\n(((P) == 2 || (P) == 9 || (P) == 11 || (P) == 17) ? 0 : ((P) == 7 || (P) == 10 || (P) == 12 || (P) == 16) ? 1 : ((P) == 5 || (P) == 13 || (P) == 15 || (P) == 18) ? 2 : ((P) == 9 || (P) == 14 || (P) == 19) ? 3 : ((P) == 6 || (P) == 20) ? 4 : ((P) == 3 || (P) == 21) ? 5 :  6 )\n\n\n// TinyCore\n// https://raw.githubusercontent.com/xukangmin/TinyCore/master/avr/package/package_tinycore_index.json\n// https://docs.tinycore.dev/en/latest/\n#elif  defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n#define __digitalPinToPortReg(P) ((P) <= 5 ? &VPORTB.OUT : ((P) <= 9 ? &VPORTC.OUT : ((P) <= 16 ? &VPORTA.OUT : ((P) <= 18 ? &VPORTB.OUT : &VPORTC.OUT))))\n#define __digitalPinToDDRReg(P) ((P) <= 5 ? &VPORTB.DIR : ((P) <= 9 ? &VPORTC.DIR : ((P) <= 16 ? &VPORTA.DIR : ((P) <= 18 ? &VPORTB.DIR : &VPORTC.DIR))))\n#define __digitalPinToPINReg(P) ((P) <= 5 ? &VPORTB.IN : ((P) <= 9 ? &VPORTC.IN : ((P) <= 16 ? &VPORTA.IN : ((P) <= 18 ? &VPORTB.IN : &VPORTC.IN))))\n#define __digitalPinToBit(P) ( (P) <= 3 ? (3 - P) : ((P) <= 5 ? (P) : ((P) <= 9 ? (P - 6) : ((P) <= 16 ? ((P) - 9) : ((P) <= 18 ? ((P) - 11) : ((P) - 15))))) )\n\n#elif defined(__AVR_ATtiny1614__)\n#define __digitalPinToPortReg(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 7 ? &VPORTB.OUT : &VPORTA.OUT))\n#define __digitalPinToDDRReg(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 7 ? &VPORTB.DIR : &VPORTA.DIR))\n#define __digitalPinToPINReg(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 7 ? &VPORTB.IN : &VPORTA.IN))\n#define __digitalPinToBit(P) ( (P) <= 3 ? (P + 4) : ((P) <= 7 ? (7 - P) : ((P) <= 10 ? (P - 7) : (P) - 11)) )\n\n#elif  defined(__AVR_ATtiny816__)\n// https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1029\n#define __digitalPinToPortReg(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 9 ? &VPORTB.OUT : ((P) <= 13 ? &VPORTC.OUT : ((P) <= 17 ? &VPORTA.OUT : &VPORTC.OUT))))\n#define __digitalPinToDDRReg(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 9 ? &VPORTB.DIR : ((P) <= 13 ? &VPORTC.DIR : ((P) <= 17 ? &VPORTA.DIR : &VPORTC.DIR))))\n#define __digitalPinToPINReg(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 9 ? &VPORTB.IN : ((P) <= 13 ? &VPORTC.IN : ((P) <= 17 ? &VPORTA.IN : &VPORTC.IN))))\n#define __digitalPinToBit(P) ( (P) <= 3 ? (P + 4) : ((P) <= 9 ? (9 - P) : ((P) <= 13 ? (P - 10) : ((P) <= 16 ? (P - 13) : ((P) - 17)))) )\n\n// --- ATtinyX5 ---\n#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n// we have only PORTB\n#define __digitalPinToPortReg(P) (&PORTB)\n#define __digitalPinToDDRReg(P)  (&DDRB)\n#define __digitalPinToPINReg(P)  (&PINB)\n#define __digitalPinToBit(P)     (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14))\n\n\n// --- ATtiny88 ---\n#elif defined(__AVR_ATtiny88__)\n# if defined(ARDUINO_AVR_DIGISPARKPRO)\n#define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 14 ? &PORTB : ((P) <= 18 ? &PORTA : &PORTC)))\n#define __digitalPinToDDRReg(P)  ((P) <= 7 ? &DDRD : ((P) <= 14 ? &DDRB : ((P) <= 18 ? &DDRA : &DDRC)))\n#define __digitalPinToPINReg(P)  ((P) <= 7 ? &PIND : ((P) <= 14 ? &PINB : ((P) <= 18 ? &PINA : &PINC)))\n#define __digitalPinToBit(P) ( (P) <= 7 ? (P) : ((P) <= 13 ? ((P) - 8) : ((P) == 14 ? 7 : ((P) <= 16 ? ((P) - 14) : ((P) <= 18 ? ((P) - 17) : ((P) == 25 ? 7 : ((P) - 19)))))) )\n# else\n#define __digitalPinToPortReg(P) ((P) <= 7 ? &PORTD : ((P) <= 15 ? &PORTB : ((P) <= 22 ? &PORTC : ((P) <= 26 ? &PORTA : &PORTC))))\n#define __digitalPinToDDRReg(P) ((P) <= 7 ? &DDRD : ((P) <= 15 ? &DDRB : ((P) <= 22 ? &DDRC : ((P) <= 26 ? &DDRA : &DDRC))))\n#define __digitalPinToPINReg(P) ((P) <= 7 ? &PIND : ((P) <= 15 ? &PINB : ((P) <= 22 ? &PINC : ((P) <= 26 ? &PINA : &PINC))))\n#define __digitalPinToBit(P) ((P) <= 15 ? ((P) & 0x7) : ((P) == 16 ? (7) : ((P) <= 22 ? ((P) - 17) : ((P) == 27 ? (6) : ((P) - 23)))))\n# endif\n\n\n// --- ATtinyX4 + ATtinyX7 ---\n#elif  defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) \\\n    || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n# if defined(ARDUINO_AVR_DIGISPARKPRO) || PIN_PA7 == 5\n// Strange enumeration of pins on Digispark board and core library\n#define __digitalPinToPortReg(P) (((P) <= 4) ? &PORTB : &PORTA)\n#define __digitalPinToDDRReg(P)  (((P) <= 4) ? &DDRB : &DDRA)\n#define __digitalPinToPINReg(P)  (((P) <= 4) ? &PINB : &PINA)\n#define __digitalPinToBit(P)     (((P) <= 2) ? (P) : (((P) == 3) ? 6 : (((P) == 4) ? 3 : (((P) == 5) ? 7 : (P) - 6 ))))\n# else\n// ATtinyX4: PORTA for 0 to 7, PORTB for 8 to 11\n// ATtinyX7: PORTA for 0 to 7, PORTB for 8 to 15\n#define __digitalPinToPortReg(P) (((P) <= 7) ? &PORTA : &PORTB)\n#define __digitalPinToDDRReg(P)  (((P) <= 7) ? &DDRA : &DDRB)\n#define __digitalPinToPINReg(P)  (((P) <= 7) ? &PINA : &PINB)\n#  if  defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__)\n// https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/avr/variants/tinyx41_cw/pins_arduino.h#L334\n// Clockwise layout\n#define __digitalPinToBit(P)     (((P) <= 7) ? (P) : ((P) == 11 ? (3) : 10 - (P)))\n#  else\n#define __digitalPinToBit(P)     (((P) <= 7) ? (P) : (P) - 8 )\n#  endif\n# endif\n#endif\n\n#if !defined(digitalWriteFast)\n#  if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg)\n#    if defined(THROW_ERROR_IF_NOT_FAST)\n#define digitalWriteFast(P, V) \\\ndo { \\\n  if (__builtin_constant_p(P)) { \\\n    BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \\\n  } else { \\\n    NonConstantsUsedForDigitalWriteFast(); \\\n  } \\\n} while (0)\n#    else\n#define digitalWriteFast(P, V) \\\ndo { \\\n  if (__builtin_constant_p(P)) { \\\n    BIT_WRITE(*__digitalPinToPortReg(P), __digitalPinToBit(P), (V)); \\\n  } else { \\\n    digitalWrite((P), (V)); \\\n  } \\\n} while (0)\n#    endif // defined(THROW_ERROR_IF_NOT_FAST)\n#  else\n#define digitalWriteFast digitalWrite\n#  endif\n#endif\n\n#if !defined(pinModeFast)\n#  if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPortReg)\n#    if defined(THROW_ERROR_IF_NOT_FAST)\n#define pinModeFast(P, V) \\\ndo { \\\n  if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \\\n    if (V == INPUT_PULLUP) {\\\n      BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \\\n      BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \\\n    } else { \\\n      BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \\\n    } \\\n  } else { \\\n    NonConstantsUsedForPinModeFast(); \\\n  } \\\n} while (0)\n#    else\n#define pinModeFast(P, V) \\\ndo { \\\n  if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \\\n    if (V == INPUT_PULLUP) {\\\n      BIT_CLEAR(*__digitalPinToDDRReg(P), __digitalPinToBit(P)); \\\n      BIT_SET(*__digitalPinToPortReg(P), __digitalPinToBit(P)); \\\n    } else { \\\n      BIT_WRITE(*__digitalPinToDDRReg(P), __digitalPinToBit(P), (V)); \\\n    } \\\n  } else { \\\n    pinMode((P), (V)); \\\n  } \\\n} while (0)\n#    endif // defined(THROW_ERROR_IF_NOT_FAST)\n#  else\n#define pinModeFast pinMode\n#  endif\n#endif // !defined(pinModeFast)\n\n#if !defined(digitalReadFast)\n#  if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPINReg)\n#    if defined(THROW_ERROR_IF_NOT_FAST)\n#define digitalReadFast(P) ( (int) __digitalReadFast((P)) )\n// since we have return values, it is easier to implement it by ?:\n#define __digitalReadFast(P ) ( (__builtin_constant_p(P) ) ? (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : NonConstantsUsedForDigitalReadFast() )\n#    else\n#define digitalReadFast(P) ( (int) __digitalReadFast((P)) )\n// since we have return values, it is easier to implement it by ?:\n#define __digitalReadFast(P ) ( (__builtin_constant_p(P) ) ? (( BIT_READ(*__digitalPinToPINReg(P), __digitalPinToBit(P))) ? HIGH:LOW ) : digitalRead((P)) )\n#    endif // defined(THROW_ERROR_IF_NOT_FAST)\n#  else\n#define digitalReadFast digitalRead\n#  endif\n#endif // !defined(digitalReadFast)\n\n#if !defined(digitalToggleFast)\n#  if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && defined(__digitalPinToPINReg)\n#    if defined(THROW_ERROR_IF_NOT_FAST)\n#define digitalToggleFast(P) \\\ndo { \\\n  if (__builtin_constant_p(P)) { \\\n    BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \\\n  } else { \\\n    NonConstantsUsedForDigitalToggleFast(); \\\n  } \\\n} while (0)\n#    else\n#define digitalToggleFast(P) \\\ndo { \\\n  if (__builtin_constant_p(P)) { \\\n    BIT_SET(*__digitalPinToPINReg(P), __digitalPinToBit(P)); \\\n  } else { \\\n    digitalWrite(P, ! digitalRead(P)); \\\n  } \\\n} while (0)\n#    endif // defined(THROW_ERROR_IF_NOT_FAST)\n#  else\n#define digitalToggleFast(P) digitalWrite(P, ! digitalRead(P))\n#  endif\n#endif // !defined(digitalToggleFast)\n\n#endif // !defined(MEGATINYCORE)\n#endif //__digitalWriteFast_h_\n"
  },
  {
    "path": "src/irmp.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmp.h\n *\n * Copyright (c) 2009-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMP_H_\n#define _IRMP_H_\n\n#if !defined(IRMP_USE_AS_LIB)\n#  define IRMPCONFIG_STAGE1_H\n#  include \"irmpconfig.h\"\n#  undef IRMPCONFIG_STAGE1_H\n#endif\n\n#include \"irmpsystem.h\"\n\n#if !defined(IRMP_USE_AS_LIB)\n#  define IRMPCONFIG_STAGE2_H\n#  include \"irmpconfig.h\"\n#  undef IRMPCONFIG_STAGE2_H\n#endif\n\n#if defined(ARDUINO)\n#  include \"irmpArduinoExt.h\"\n\n#elif defined (__AVR_XMEGA__)\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRMP_PORT_PRE                         CONCAT(PORT, IRMP_PORT_LETTER)\n#  define IRMP_DDR_PRE                          CONCAT(PORT, IRMP_PORT_LETTER)\n#  define IRMP_PIN_PRE                          CONCAT(PORT, IRMP_PORT_LETTER)\n#  define IRMP_PORT                             IRMP_PORT_PRE.OUT\n#  define IRMP_DDR                              IRMP_DDR_PRE.DIR\n#  define IRMP_PIN                              IRMP_PIN_PRE.IN\n#  define IRMP_BIT                              IRMP_BIT_NUMBER\n#  define input(x)                              ((x) & (1 << IRMP_BIT))\n\n#elif defined (ATMEL_AVR)\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRMP_PORT                             CONCAT(PORT, IRMP_PORT_LETTER)\n#  define IRMP_DDR                              CONCAT(DDR, IRMP_PORT_LETTER)\n#  define IRMP_PIN                              CONCAT(PIN, IRMP_PORT_LETTER)\n#  define IRMP_BIT                              IRMP_BIT_NUMBER\n#  define input(x)                              ((x) & (1 << IRMP_BIT))\n\n#elif defined (PIC_C18) || defined (PIC_CCS) || defined(PIC_XC32)\n#  define input(x)                              (x)\n\n#elif defined (ARM_STM32)\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRMP_PORT                             CONCAT(GPIO, IRMP_PORT_LETTER)\n#  if defined (ARM_STM32L1XX)\n#    define IRMP_PORT_RCC                       CONCAT(RCC_AHBPeriph_GPIO, IRMP_PORT_LETTER)\n#  elif defined (ARM_STM32F10X)\n#    define IRMP_PORT_RCC                       CONCAT(RCC_APB2Periph_GPIO, IRMP_PORT_LETTER)\n#  elif defined (ARM_STM32F30X)\n#    define IRMP_PORT_RCC                       CONCAT(RCC_AHBPeriph_GPIO, IRMP_PORT_LETTER)\n#  elif defined (ARM_STM32F4XX)\n#    define IRMP_PORT_RCC                       CONCAT(RCC_AHB1Periph_GPIO, IRMP_PORT_LETTER)\n#  endif\n#  define IRMP_BIT                              CONCAT(GPIO_Pin_, IRMP_BIT_NUMBER)\n#  define IRMP_PIN                              IRMP_PORT   // for use with input(x) below\n#  define input(x)                              (GPIO_ReadInputDataBit(x, IRMP_BIT))\n#  if !defined(USE_STDPERIPH_DRIVER)\n#    warning The STM32 port of IRMP uses the ST standard peripheral drivers which are not enabled in your build configuration.\n#  endif\n\n#elif defined (ARM_STM32_OPENCM3)\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRMP_PORT                             CONCAT(GPIO, IRMP_PORT_LETTER)\n#  define IRMP_PORT_RCC                         CONCAT(RCC_GPIO, IRMP_PORT_LETTER)\n#  define IRMP_BIT                              CONCAT(GPIO, IRMP_BIT_NUMBER)\n#  define IRMP_PIN                              IRMP_PORT   // for use with input(x) below\n#  define input(x)                              (gpio_get(x, IRMP_BIT))\n\n#elif defined (ARM_STM32_HAL)\n#  define IRMP_BIT                              IRMP_BIT_NUMBER\n#  define IRMP_PIN                              IRMP_BIT_NUMBER   // for use with input(x) below\n#  define input(x)                              HAL_GPIO_ReadPin(IRMP_PORT_LETTER, x)\n\n#elif defined (STELLARIS_ARM_CORTEX_M4)\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRMP_PORT_PERIPH                      CONCAT(SYSCTL_PERIPH_GPIO, IRMP_PORT_LETTER)\n#  define IRMP_PORT_BASE                        CONCAT(GPIO_PORT, CONCAT(IRMP_PORT_LETTER, _BASE))\n#  define IRMP_PORT_PIN                         CONCAT(GPIO_PIN_, IRMP_BIT_NUMBER)\n#  define IRMP_PIN                              IRMP_PORT_PIN\n#  define input(x)                              ((uint8_t)(ROM_GPIOPinRead(IRMP_PORT_BASE, IRMP_PORT_PIN)))\n#  define sei()                                 IntMasterEnable()\n\n#elif defined(__SDCC_stm8)\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRMP_GPIO_STRUCT                      CONCAT(GPIO, IRMP_PORT_LETTER)\n#  define IRMP_BIT                              IRMP_BIT_NUMBER\n#  define IRMP_PIN                              IRMP_GPIO_STRUCT->IDR\n#  define input(x)                              ((x) & (1 << IRMP_BIT))\n\n#elif defined (PICO_RP2040)\n#  define IRMP_BIT                              IRMP_BIT_NUMBER\n#  define IRMP_PIN                              IRMP_BIT_NUMBER // for use with input(x) below\n#  define input(x)                              (gpio_get(x))\n\n#elif defined (TEENSY_ARM_CORTEX_M4)\n#  define input(x)                              ((uint8_t)(digitalReadFast(x)))\n\n#elif defined (__MBED__)\n#  define IRMP_BIT                              gpioIRin\n#  define input(x)                              (gpio_read (&x))\n\n#elif defined(__xtensa__)\n#  define IRMP_BIT                              IRMP_BIT_NUMBER\n#  define input(x)                              GPIO_INPUT_GET(IRMP_BIT_NUMBER)\n\n#elif defined(_CHIBIOS_HAL_)\n#  define input(x)                              palReadLine(x)\n\n#endif\n\n#if IRMP_USE_IDLE_CALL == 1\nvoid irmp_idle(void);                   // the user has to provide an implementation of the irmp_idle() function and link it\n#endif\n\n#if IRMP_USE_COMPLETE_CALLBACK == 1\nvoid irmp_register_complete_callback_function(void (*aCompleteCallbackFunction)(void));\n#endif\n\n#if IRMP_SUPPORT_TECHNICS_PROTOCOL == 1\n#  undef IRMP_SUPPORT_MATSUSHITA_PROTOCOL\n#  define IRMP_SUPPORT_MATSUSHITA_PROTOCOL      1\n#endif\n\n#if IRMP_32_BIT == 0 && IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n#  undef IRMP_SUPPORT_MERLIN_PROTOCOL\n#  warning MERLIN protocol disabled, IRMP_32_BIT=1 needed\n#endif\n\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1 && IRMP_SUPPORT_RUWIDO_PROTOCOL == 1\n#  warning DENON protocol conflicts wih RUWIDO, please enable only one of both protocols\n#  warning RUWIDO protocol disabled\n#  undef IRMP_SUPPORT_RUWIDO_PROTOCOL\n#  define IRMP_SUPPORT_RUWIDO_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 && IRMP_SUPPORT_PANASONIC_PROTOCOL == 1\n#  warning KASEIKYO protocol conflicts wih PANASONIC, please enable only one of both protocols\n#  warning PANASONIC protocol disabled\n#  undef IRMP_SUPPORT_PANASONIC_PROTOCOL\n#  define IRMP_SUPPORT_PANASONIC_PROTOCOL       0\n#endif\n\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1 && IRMP_SUPPORT_ACP24_PROTOCOL == 1\n#  warning DENON protocol conflicts wih ACP24, please enable only one of both protocols\n#  warning ACP24 protocol disabled\n#  undef IRMP_SUPPORT_ACP24_PROTOCOL\n#  define IRMP_SUPPORT_ACP24_PROTOCOL           0\n#endif\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1 && IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n#  warning RC6 protocol conflicts wih ROOMBA, please enable only one of both protocols\n#  warning ROOMBA protocol disabled\n#  undef IRMP_SUPPORT_ROOMBA_PROTOCOL\n#  define IRMP_SUPPORT_ROOMBA_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1 && IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n#  warning PANASONIC protocol conflicts wih MITSU_HEAVY, please enable only one of both protocols\n#  warning MITSU_HEAVY protocol disabled\n#  undef IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\n#  define IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL      0\n#endif\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 && IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n#  warning KASEIKYO protocol conflicts wih MITSU_HEAVY, please enable only one of both protocols\n#  warning MITSU_HEAVY protocol disabled\n#  undef IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\n#  define IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL      0\n#endif\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n#  warning RC5 protocol conflicts wih ORTEK, please enable only one of both protocols\n#  warning ORTEK protocol disabled\n#  undef IRMP_SUPPORT_ORTEK_PROTOCOL\n#  define IRMP_SUPPORT_ORTEK_PROTOCOL           0\n#endif\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_S100_PROTOCOL == 1\n#  warning RC5 protocol conflicts wih S100, please enable only one of both protocols\n#  warning S100 protocol disabled\n#  undef IRMP_SUPPORT_S100_PROTOCOL\n#  define IRMP_SUPPORT_S100_PROTOCOL            0\n#endif\n\n#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1 && IRMP_SUPPORT_FAN_PROTOCOL == 1\n#  warning NUBERT protocol conflicts wih FAN, please enable only one of both protocols\n#  warning FAN protocol disabled\n#  undef IRMP_SUPPORT_FAN_PROTOCOL\n#  define IRMP_SUPPORT_FAN_PROTOCOL             0\n#endif\n\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1 && IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n#  warning FDC protocol conflicts wih ORTEK, please enable only one of both protocols\n#  warning ORTEK protocol disabled\n#  undef IRMP_SUPPORT_ORTEK_PROTOCOL\n#  define IRMP_SUPPORT_ORTEK_PROTOCOL           0\n#endif\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1 && IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n#  warning ORTEK protocol conflicts wih NETBOX, please enable only one of both protocols\n#  warning NETBOX protocol disabled\n#  undef IRMP_SUPPORT_NETBOX_PROTOCOL\n#  define IRMP_SUPPORT_NETBOX_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1 && IRMP_SUPPORT_RCII_PROTOCOL == 1\n#  warning GRUNDIG protocol conflicts wih RCII, please enable only one of both protocols\n#  warning RCII protocol disabled\n#  undef IRMP_SUPPORT_RCII_PROTOCOL\n#  define IRMP_SUPPORT_RCII_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_NOKIA_PROTOCOL == 1 && IRMP_SUPPORT_RCII_PROTOCOL == 1\n#  warning NOKIA protocol conflicts wih RCII, please enable only one of both protocols\n#  warning RCII protocol disabled\n#  undef IRMP_SUPPORT_RCII_PROTOCOL\n#  define IRMP_SUPPORT_RCII_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, SIEMENS protocol disabled (should be at least 15000)\n#  undef IRMP_SUPPORT_SIEMENS_PROTOCOL\n#  define IRMP_SUPPORT_SIEMENS_PROTOCOL         0\n#endif\n\n#if IRMP_SUPPORT_RUWIDO_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, RUWIDO protocol disabled (should be at least 15000)\n#  undef IRMP_SUPPORT_RUWIDO_PROTOCOL\n#  define IRMP_SUPPORT_RUWIDO_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_RECS80_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, RECS80 protocol disabled (should be at least 15000)\n#  undef IRMP_SUPPORT_RECS80_PROTOCOL\n#  define IRMP_SUPPORT_RECS80_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, RECS80EXT protocol disabled (should be at least 15000)\n#  undef IRMP_SUPPORT_RECS80EXT_PROTOCOL\n#  define IRMP_SUPPORT_RECS80EXT_PROTOCOL       0\n#endif\n\n#if IRMP_SUPPORT_LEGO_PROTOCOL == 1 && F_INTERRUPTS < 19000\n#  warning F_INTERRUPTS too low, LEGO protocol disabled (should be at least 19000)\n#  undef IRMP_SUPPORT_LEGO_PROTOCOL\n#  define IRMP_SUPPORT_LEGO_PROTOCOL            0\n#endif\n\n#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1 && IRMP_SUPPORT_SAMSUNG_PROTOCOL == 0\n#  warning SAMSUNG48 protocol needs also SAMSUNG protocol, SAMSUNG protocol enabled\n#  undef IRMP_SUPPORT_SAMSUNG_PROTOCOL\n#  define IRMP_SUPPORT_SAMSUNG_PROTOCOL         1\n#endif\n\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1 && IRMP_SUPPORT_NEC_PROTOCOL == 0\n#  warning JVC protocol needs also NEC protocol, NEC protocol enabled\n#  undef IRMP_SUPPORT_NEC_PROTOCOL\n#  define IRMP_SUPPORT_NEC_PROTOCOL             1\n#endif\n\n#if IRMP_SUPPORT_NEC16_PROTOCOL == 1 && IRMP_SUPPORT_NEC_PROTOCOL == 0\n#  warning NEC16 protocol needs also NEC protocol, NEC protocol enabled\n#  undef IRMP_SUPPORT_NEC_PROTOCOL\n#  define IRMP_SUPPORT_NEC_PROTOCOL             1\n#endif\n\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1 && IRMP_SUPPORT_NEC_PROTOCOL == 0\n#  warning NEC42 protocol needs also NEC protocol, NEC protocol enabled\n#  undef IRMP_SUPPORT_NEC_PROTOCOL\n#  define IRMP_SUPPORT_NEC_PROTOCOL             1\n#endif\n\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1 && IRMP_SUPPORT_NEC_PROTOCOL == 0\n#  warning LGAIR protocol needs also NEC protocol, NEC protocol enabled\n#  undef IRMP_SUPPORT_NEC_PROTOCOL\n#  define IRMP_SUPPORT_NEC_PROTOCOL             1\n#endif\n\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1 && IRMP_SUPPORT_NEC_PROTOCOL == 0\n#  warning MELINERA protocol needs also NEC protocol, NEC protocol enabled\n#  undef IRMP_SUPPORT_NEC_PROTOCOL\n#  define IRMP_SUPPORT_NEC_PROTOCOL             1\n#endif\n\n#if IRMP_SUPPORT_RCMM_PROTOCOL == 1 && F_INTERRUPTS < 19000\n#  warning F_INTERRUPTS too low, RCMM protocol disabled (should be at least 19000)\n#  undef IRMP_SUPPORT_RCMM_PROTOCOL\n#  define IRMP_SUPPORT_RCMM_PROTOCOL            0\n#endif\n\n#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1 && F_INTERRUPTS > 17000 && __SIZEOF_INT__ < 4\n#  warning F_INTERRUPTS too high, PENTAX protocol disabled (should be max 17000)\n#  undef IRMP_SUPPORT_PENTAX_PROTOCOL\n#  define IRMP_SUPPORT_PENTAX_PROTOCOL          0\n#endif\n\n#if IRMP_SUPPORT_GREE_PROTOCOL == 1 && F_INTERRUPTS > 17000 && __SIZEOF_INT__ < 4\n#  warning F_INTERRUPTS too high, GREE protocol disabled (should be max 17000)\n#  undef IRMP_SUPPORT_GREE_PROTOCOL\n#  define IRMP_SUPPORT_GREE_PROTOCOL            0\n#endif\n\n#if F_INTERRUPTS > 20000\n# warning F_INTERRUPTS too high (should be not greater than 20000)\n#endif\n\n#include \"irmpprotocols.h\"\n\n#define IRMP_FLAG_NEW                   0x00\n#define IRMP_FLAG_REPETITION            0x01\n#define IRMP_FLAG_RELEASE               0x02                                    // see IRMP_ENABLE_RELEASE_DETECTION in irmpconfig.h\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nextern void                             irmp_init (void);\n#ifdef __cplusplus\nextern bool                             irmp_get_data (IRMP_DATA *);\nextern bool                             irmp_ISR (void);\n#else\nextern uint_fast8_t                     irmp_get_data (IRMP_DATA *);\nextern uint_fast8_t                     irmp_ISR (void);\n#endif\n#if IRMP_AUTODETECT_REPEATRATE\nextern volatile uint_fast8_t            delta, min_delta, keep_same_key, timeout, upper_border;\nextern volatile uint_fast16_t           tmp_delta;\nextern volatile uint32_t                pass_on_delta_detection;\n#endif\n\n#if IRMP_PROTOCOL_NAMES == 1\nextern const char * const               irmp_protocol_names[IRMP_N_PROTOCOLS + 1] PROGMEM;\n#endif\n\n#if IRMP_USE_CALLBACK == 1\nextern void                             irmp_set_callback_ptr (void (*cb)(uint_fast8_t));\n#endif // IRMP_USE_CALLBACK == 1\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _IRMP_H_ */\n"
  },
  {
    "path": "src/irmp.hpp",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmp.hpp - infrared multi-protocol decoder, supports several remote control protocols\n *\n * Copyright (c) 2009-2019 Frank Meyer - frank(at)fli4l.de\n * 2020 Arduino porting by Armin Joachimsmeyer\n *\n * Supported AVR mikrocontrollers:\n *\n * ATtiny87,  ATtiny167\n * ATtiny45,  ATtiny85\n * ATtiny44,  ATtiny84\n * ATmega8,   ATmega16,  ATmega32\n * ATmega162\n * ATmega164, ATmega324, ATmega644,  ATmega644P, ATmega1284, ATmega1284P\n * ATmega88,  ATmega88P, ATmega168,  ATmega168P, ATmega328P\n *\n * This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#include \"irmp.h\"\n\n#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRMP_SUPPORT_NOKIA_PROTOCOL == 1 || IRMP_SUPPORT_IR60_PROTOCOL == 1\n#  define IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL  1\n#else\n#  define IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL  0\n#endif\n\n#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1 || IRMP_SUPPORT_RUWIDO_PROTOCOL == 1\n#  define IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL   1\n#else\n#  define IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL   0\n#endif\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 ||                   \\\n    IRMP_SUPPORT_RCII_PROTOCOL == 1 ||                  \\\n    IRMP_SUPPORT_S100_PROTOCOL == 1 ||                  \\\n    IRMP_SUPPORT_RC6_PROTOCOL == 1 ||                   \\\n    IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1 ||    \\\n    IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1 ||     \\\n    IRMP_SUPPORT_IR60_PROTOCOL == 1 ||                  \\\n    IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1 ||               \\\n    IRMP_SUPPORT_MERLIN_PROTOCOL == 1 ||                \\\n    IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n#  define IRMP_SUPPORT_MANCHESTER                   1\n#else\n#  define IRMP_SUPPORT_MANCHESTER                   0\n#endif\n\n#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n#  define IRMP_SUPPORT_SERIAL                       1\n#else\n#  define IRMP_SUPPORT_SERIAL                       0\n#endif\n\n#define IRMP_KEY_REPETITION_LEN                 (uint_fast16_t)(F_INTERRUPTS * 150.0e-3 + 0.5)           // autodetect key repetition within 150 msec\n\n#define MIN_TOLERANCE_00                        1.0                           // -0%\n#define MAX_TOLERANCE_00                        1.0                           // +0%\n\n#define MIN_TOLERANCE_02                        0.98                          // -2%\n#define MAX_TOLERANCE_02                        1.02                          // +2%\n\n#define MIN_TOLERANCE_03                        0.97                          // -3%\n#define MAX_TOLERANCE_03                        1.03                          // +3%\n\n#define MIN_TOLERANCE_05                        0.95                          // -5%\n#define MAX_TOLERANCE_05                        1.05                          // +5%\n\n#define MIN_TOLERANCE_10                        0.9                           // -10%\n#define MAX_TOLERANCE_10                        1.1                           // +10%\n\n#define MIN_TOLERANCE_15                        0.85                          // -15%\n#define MAX_TOLERANCE_15                        1.15                          // +15%\n\n#define MIN_TOLERANCE_20                        0.8                           // -20%\n#define MAX_TOLERANCE_20                        1.2                           // +20%\n\n#define MIN_TOLERANCE_25                        0.75                          // -25%\n#define MAX_TOLERANCE_25                        1.25                          // +25%\n\n#define MIN_TOLERANCE_30                        0.7                           // -30%\n#define MAX_TOLERANCE_30                        1.3                           // +30%\n\n#define MIN_TOLERANCE_40                        0.6                           // -40%\n#define MAX_TOLERANCE_40                        1.4                           // +40%\n\n#define MIN_TOLERANCE_50                        0.5                           // -50%\n#define MAX_TOLERANCE_50                        1.5                           // +50%\n\n#define MIN_TOLERANCE_60                        0.4                           // -60%\n#define MAX_TOLERANCE_60                        1.6                           // +60%\n\n#define MIN_TOLERANCE_70                        0.3                           // -70%\n#define MAX_TOLERANCE_70                        1.7                           // +70%\n\n#define SIRCS_START_BIT_PULSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SIRCS_START_BIT_PULSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SIRCS_START_BIT_PAUSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#if IRMP_SUPPORT_NETBOX_PROTOCOL                // only 5% to avoid conflict with NETBOX:\n#  define SIRCS_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5))\n#else                                           // only 5% + 1 to avoid conflict with RC6:\n#  define SIRCS_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#endif\n#define SIRCS_1_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SIRCS_1_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SIRCS_0_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SIRCS_0_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SIRCS_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SIRCS_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define NEC_START_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define NEC_START_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define NEC_START_BIT_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define NEC_START_BIT_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define NEC_REPEAT_START_BIT_PAUSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define NEC_REPEAT_START_BIT_PAUSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define NEC_PULSE_LEN_MIN                       ((uint_fast8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define NEC_PULSE_LEN_MAX                       ((uint_fast8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define NEC_1_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define NEC_1_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define NEC_0_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define NEC_0_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n// autodetect nec repetition frame within 50 msec:\n// NEC seems to send the first repetition frame after 40ms, further repetition frames after 100 ms\n#if 0\n#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX          (uint_fast16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\n#else\n#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX          (uint_fast16_t)(F_INTERRUPTS * 100.0e-3 * MAX_TOLERANCE_20 + 0.5)\n#endif\n\n#define MELINERA_0_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_0_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define MELINERA_0_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_0_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define MELINERA_0_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define MELINERA_0_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define MELINERA_1_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_1_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define MELINERA_1_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_1_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define MELINERA_1_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define MELINERA_1_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MELINERA_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#define SAMSUNG_START_BIT_PULSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SAMSUNG_START_BIT_PULSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SAMSUNG_START_BIT_PAUSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SAMSUNG_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SAMSUNG_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define SAMSUNG_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define SAMSUNG_1_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define SAMSUNG_1_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define SAMSUNG_0_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define SAMSUNG_0_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#define SAMSUNGAH_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SAMSUNGAH_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SAMSUNGAH_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define SAMSUNGAH_START_BIT_PAUSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SAMSUNGAH_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define SAMSUNGAH_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define SAMSUNGAH_1_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define SAMSUNGAH_1_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define SAMSUNGAH_0_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define SAMSUNGAH_0_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * SAMSUNGAH_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#define MATSUSHITA_START_BIT_PULSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define MATSUSHITA_START_BIT_PULSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define MATSUSHITA_START_BIT_PAUSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define MATSUSHITA_START_BIT_PAUSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define MATSUSHITA_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define MATSUSHITA_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define MATSUSHITA_1_PAUSE_LEN_MIN              ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define MATSUSHITA_1_PAUSE_LEN_MAX              ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define MATSUSHITA_0_PAUSE_LEN_MIN              ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define MATSUSHITA_0_PAUSE_LEN_MAX              ((uint_fast8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n\n#define KASEIKYO_START_BIT_PULSE_LEN_MIN        ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define KASEIKYO_START_BIT_PULSE_LEN_MAX        ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define KASEIKYO_START_BIT_PAUSE_LEN_MIN        ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define KASEIKYO_START_BIT_PAUSE_LEN_MAX        ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define KASEIKYO_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define KASEIKYO_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define KASEIKYO_1_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define KASEIKYO_1_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define KASEIKYO_0_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define KASEIKYO_0_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define MITSU_HEAVY_START_BIT_PULSE_LEN_MIN     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define MITSU_HEAVY_START_BIT_PULSE_LEN_MAX     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX     ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define MITSU_HEAVY_PULSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define MITSU_HEAVY_PULSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define MITSU_HEAVY_1_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define MITSU_HEAVY_1_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define MITSU_HEAVY_0_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define MITSU_HEAVY_0_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define PANASONIC_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define PANASONIC_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define PANASONIC_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define PANASONIC_START_BIT_PAUSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define PANASONIC_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define PANASONIC_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define PANASONIC_1_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define PANASONIC_1_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define PANASONIC_0_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define PANASONIC_0_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * PANASONIC_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define VINCENT_START_BIT_PULSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define VINCENT_START_BIT_PULSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define VINCENT_START_BIT_PAUSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define VINCENT_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * VINCENT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define VINCENT_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * VINCENT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define VINCENT_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * VINCENT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define VINCENT_1_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define VINCENT_1_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define VINCENT_0_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define VINCENT_0_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * VINCENT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define RECS80_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define RECS80_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define RECS80_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RECS80_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RECS80_PULSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define RECS80_PULSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define RECS80_1_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RECS80_1_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RECS80_0_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RECS80_0_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#if (0) // IRMP_SUPPORT_BOSE_PROTOCOL == 1 // BOSE conflicts with RC5, so keep tolerance for RC5 minimal here:\n// start pause is well separated, so overlap in start pulse does not disturb, but reducing tolerance leads to worse RC5 recognition\n#define RC5_START_BIT_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RC5_START_BIT_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#else\n#define RC5_START_BIT_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC5_START_BIT_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#endif\n\n#define RC5_BIT_LEN_MIN                         ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC5_BIT_LEN_MAX                         ((uint_fast8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define RCII_START_BIT_PULSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCII_START_BIT_PULSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCII_START_BIT_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCII_START_BIT_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCII_START_BIT2_PULSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT2_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCII_START_BIT2_PULSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * RCII_START_BIT2_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n\n#define RCII_BIT_LEN_MIN                        ((uint_fast8_t)(F_INTERRUPTS * RCII_BIT_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define RCII_BIT_LEN                            ((uint_fast8_t)(F_INTERRUPTS * RCII_BIT_TIME))\n#define RCII_BIT_LEN_MAX                        ((uint_fast8_t)(F_INTERRUPTS * RCII_BIT_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#if IRMP_SUPPORT_BOSE_PROTOCOL == 1 // BOSE conflicts with S100, so keep tolerance for S100 minimal here:\n#define S100_START_BIT_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define S100_START_BIT_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#else\n#define S100_START_BIT_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define S100_START_BIT_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#endif\n\n#define S100_BIT_LEN_MIN                         ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define S100_BIT_LEN_MAX                         ((uint_fast8_t)(F_INTERRUPTS * S100_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define DENON_PULSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define DENON_PULSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define DENON_1_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define DENON_1_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n// RUWIDO (see t-home-mediareceiver-15kHz.txt) conflicts here with DENON\n#define DENON_0_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define DENON_0_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define DENON_AUTO_REPETITION_PAUSE_LEN         ((uint_fast16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define THOMSON_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * THOMSON_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define THOMSON_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * THOMSON_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define THOMSON_1_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * THOMSON_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define THOMSON_1_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * THOMSON_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define THOMSON_0_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * THOMSON_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define THOMSON_0_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * THOMSON_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define RC6_START_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC6_START_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RC6_START_BIT_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC6_START_BIT_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RC6_TOGGLE_BIT_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC6_TOGGLE_BIT_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RC6_BIT_PULSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC6_BIT_PULSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_60 + 0.5) + 1)       // pulses: 300 - 800\n#define RC6_BIT_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RC6_BIT_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1)       // pauses: 300 - 600\n\n#define RECS80EXT_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define RECS80EXT_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define RECS80EXT_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RECS80EXT_START_BIT_PAUSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RECS80EXT_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define RECS80EXT_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define RECS80EXT_1_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RECS80EXT_1_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RECS80EXT_0_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RECS80EXT_0_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define NUBERT_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NUBERT_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NUBERT_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NUBERT_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NUBERT_1_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NUBERT_1_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NUBERT_1_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NUBERT_1_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NUBERT_0_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NUBERT_0_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NUBERT_0_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NUBERT_0_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define FAN_START_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FAN_START_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define FAN_START_BIT_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FAN_START_BIT_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define FAN_1_PULSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FAN_1_PULSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define FAN_1_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FAN_1_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define FAN_0_PULSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FAN_0_PULSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define FAN_0_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FAN_0_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define SPEAKER_START_BIT_PULSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define SPEAKER_START_BIT_PULSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define SPEAKER_START_BIT_PAUSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define SPEAKER_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define SPEAKER_1_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define SPEAKER_1_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define SPEAKER_1_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define SPEAKER_1_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define SPEAKER_0_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define SPEAKER_0_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define SPEAKER_0_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define SPEAKER_0_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * SPEAKER_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX   ((PAUSE_LEN)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) // value must be below IRMP_TIMEOUT\n#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX   ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_PULSE_LEN_MIN              ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_PULSE_LEN_MAX              ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_1_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_1_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_0_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_0_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_R_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_R_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MIN  ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MAX  ((uint_fast8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define IR60_TIMEOUT_LEN                        ((uint_fast8_t)(F_INTERRUPTS * IR60_TIMEOUT_TIME * 0.5))\n#define GRUNDIG_NOKIA_IR60_START_BIT_LEN_MIN    ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX    ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define GRUNDIG_NOKIA_IR60_BIT_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define GRUNDIG_NOKIA_IR60_BIT_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN    ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) + 1)\n#define GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX    ((uint_fast8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MIN_TOLERANCE_00 + 0.5) - 0)\n#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_00 + 0.5) - 1)\n#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME * MIN_TOLERANCE_00 + 0.5) - 1)\n#define SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME * MIN_TOLERANCE_00 + 0.5) - 1)\n#define SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define FDC_START_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)   // 5%: avoid conflict with NETBOX\n#define FDC_START_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5))\n#define FDC_START_BIT_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define FDC_START_BIT_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5))\n#define FDC_PULSE_LEN_MIN                       ((uint_fast8_t)(F_INTERRUPTS * FDC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define FDC_PULSE_LEN_MAX                       ((uint_fast8_t)(F_INTERRUPTS * FDC_PULSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)\n#define FDC_1_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define FDC_1_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#if 0\n#define FDC_0_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)   // could be negative: 255\n#else\n#define FDC_0_PAUSE_LEN_MIN                     (1)                                                                         // simply use 1\n#endif\n#define FDC_0_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define RCCAR_START_BIT_PULSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RCCAR_START_BIT_PULSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RCCAR_START_BIT_PAUSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RCCAR_START_BIT_PAUSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RCCAR_PULSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define RCCAR_PULSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define RCCAR_1_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define RCCAR_1_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME * MAX_TOLERANCE_25 + 0.5) + 1)\n#define RCCAR_0_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MIN_TOLERANCE_25 + 0.5) - 1)\n#define RCCAR_0_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#define JVC_START_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define JVC_START_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define JVC_REPEAT_START_BIT_PAUSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MIN_TOLERANCE_40 + 0.5) - 1)  // HACK!\n#define JVC_REPEAT_START_BIT_PAUSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MAX_TOLERANCE_70 + 0.5) - 1)  // HACK!\n#define JVC_PULSE_LEN_MIN                       ((uint_fast8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define JVC_PULSE_LEN_MAX                       ((uint_fast8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define JVC_1_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define JVC_1_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define JVC_0_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define JVC_0_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n// autodetect JVC repetition frame within 50 msec:\n#define JVC_FRAME_REPEAT_PAUSE_LEN_MAX          (uint_fast16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\n\n#define NIKON_START_BIT_PULSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NIKON_START_BIT_PULSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NIKON_START_BIT_PAUSE_LEN_MIN           ((uint_fast16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NIKON_START_BIT_PAUSE_LEN_MAX           ((uint_fast16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NIKON_REPEAT_START_BIT_PAUSE_LEN_MIN    ((uint_fast8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NIKON_REPEAT_START_BIT_PAUSE_LEN_MAX    ((uint_fast8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NIKON_PULSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * NIKON_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NIKON_PULSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * NIKON_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NIKON_1_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NIKON_1_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NIKON_0_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define NIKON_0_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define NIKON_FRAME_REPEAT_PAUSE_LEN_MAX        (uint_fast16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\n\n#define KATHREIN_START_BIT_PULSE_LEN_MIN        ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_START_BIT_PULSE_LEN_MAX        ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define KATHREIN_START_BIT_PAUSE_LEN_MIN        ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_START_BIT_PAUSE_LEN_MAX        ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define KATHREIN_1_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_1_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define KATHREIN_1_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_1_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define KATHREIN_0_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_0_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define KATHREIN_0_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_0_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define KATHREIN_SYNC_BIT_PAUSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_SYNC_BIT_PAUSE_LEN_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define KATHREIN_SYNC_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * KATHREIN_SYNC_BIT_PAUSE_LEN_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define NETBOX_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define NETBOX_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define NETBOX_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define NETBOX_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * NETBOX_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define NETBOX_PULSE_LEN                        ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PULSE_TIME))\n#define NETBOX_PAUSE_LEN                        ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PAUSE_TIME))\n#define NETBOX_PULSE_REST_LEN                   ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PULSE_TIME / 4))\n#define NETBOX_PAUSE_REST_LEN                   ((uint_fast8_t)(F_INTERRUPTS * NETBOX_PAUSE_TIME / 4))\n\n#define LEGO_START_BIT_PULSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define LEGO_START_BIT_PULSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define LEGO_START_BIT_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define LEGO_START_BIT_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define LEGO_PULSE_LEN_MIN                      ((uint_fast8_t)(F_INTERRUPTS * LEGO_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define LEGO_PULSE_LEN_MAX                      ((uint_fast8_t)(F_INTERRUPTS * LEGO_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define LEGO_1_PAUSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME * MIN_TOLERANCE_25 + 0.5) - 1)\n#define LEGO_1_PAUSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)\n#define LEGO_0_PAUSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)\n#define LEGO_0_PAUSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define IRMP16_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define IRMP16_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define IRMP16_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define IRMP16_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * IRMP16_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define IRMP16_PULSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * IRMP16_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define IRMP16_PULSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * IRMP16_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define IRMP16_1_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * IRMP16_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define IRMP16_1_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * IRMP16_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define IRMP16_0_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * IRMP16_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define IRMP16_0_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * IRMP16_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define GREE_START_BIT_PULSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define GREE_START_BIT_PULSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define GREE_START_BIT_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define GREE_START_BIT_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * GREE_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define GREE_PULSE_LEN_MIN                      ((uint_fast8_t)(F_INTERRUPTS * GREE_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define GREE_PULSE_LEN_MAX                      ((uint_fast8_t)(F_INTERRUPTS * GREE_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define GREE_1_PAUSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * GREE_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define GREE_1_PAUSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * GREE_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define GREE_0_PAUSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * GREE_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define GREE_0_PAUSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * GREE_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define BOSE_START_BIT_PULSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define BOSE_START_BIT_PULSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define BOSE_START_BIT_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define BOSE_START_BIT_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * BOSE_START_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define BOSE_PULSE_LEN_MIN                       ((uint_fast8_t)(F_INTERRUPTS * BOSE_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define BOSE_PULSE_LEN_MAX                       ((uint_fast8_t)(F_INTERRUPTS * BOSE_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define BOSE_1_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * BOSE_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define BOSE_1_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * BOSE_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define BOSE_0_PAUSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * BOSE_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define BOSE_0_PAUSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * BOSE_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define BOSE_FRAME_REPEAT_PAUSE_LEN_MAX          (uint_fast16_t)(F_INTERRUPTS * 100.0e-3 * MAX_TOLERANCE_20 + 0.5)\n\n#define A1TVBOX_START_BIT_PULSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define A1TVBOX_START_BIT_PULSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define A1TVBOX_START_BIT_PAUSE_LEN_MIN         ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define A1TVBOX_START_BIT_PAUSE_LEN_MAX         ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PAUSE_TIME * MAX_TOLERANCE_00 + 0.5) + 1)\n#define A1TVBOX_BIT_PULSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define A1TVBOX_BIT_PULSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define A1TVBOX_BIT_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PAUSE_TIME * MIN_TOLERANCE_00 + 0.5) - 0)\n#define A1TVBOX_BIT_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * A1TVBOX_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define MERLIN_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define MERLIN_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define MERLIN_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define MERLIN_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * MERLIN_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define MERLIN_BIT_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define MERLIN_BIT_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define MERLIN_BIT_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define MERLIN_BIT_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * MERLIN_BIT_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#define ORTEK_START_BIT_PULSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define ORTEK_START_BIT_PULSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define ORTEK_START_BIT_PAUSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define ORTEK_START_BIT_PAUSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * ORTEK_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define ORTEK_BIT_PULSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define ORTEK_BIT_PULSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define ORTEK_BIT_PAUSE_LEN_MIN                 ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define ORTEK_BIT_PAUSE_LEN_MAX                 ((uint_fast8_t)(F_INTERRUPTS * ORTEK_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define TELEFUNKEN_START_BIT_PULSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define TELEFUNKEN_START_BIT_PULSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define TELEFUNKEN_START_BIT_PAUSE_LEN_MIN      ((uint_fast8_t)(F_INTERRUPTS * (TELEFUNKEN_START_BIT_PAUSE_TIME) * MIN_TOLERANCE_10 + 0.5) - 1)\n#define TELEFUNKEN_START_BIT_PAUSE_LEN_MAX      ((uint_fast8_t)(F_INTERRUPTS * (TELEFUNKEN_START_BIT_PAUSE_TIME) * MAX_TOLERANCE_10 + 0.5) - 1)\n#define TELEFUNKEN_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define TELEFUNKEN_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define TELEFUNKEN_1_PAUSE_LEN_MIN              ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define TELEFUNKEN_1_PAUSE_LEN_MAX              ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define TELEFUNKEN_0_PAUSE_LEN_MIN              ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define TELEFUNKEN_0_PAUSE_LEN_MAX              ((uint_fast8_t)(F_INTERRUPTS * TELEFUNKEN_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n// autodetect TELEFUNKEN repetition frame within 50 msec:\n// #define TELEFUNKEN_FRAME_REPEAT_PAUSE_LEN_MAX   (uint_fast16_t)(F_INTERRUPTS * TELEFUNKEN_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\n\n#define ROOMBA_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define ROOMBA_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define ROOMBA_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define ROOMBA_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define ROOMBA_1_PAUSE_LEN_EXACT                ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME + 0.5))\n#define ROOMBA_1_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define ROOMBA_1_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define ROOMBA_1_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define ROOMBA_1_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define ROOMBA_0_PAUSE_LEN                      ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME))\n#define ROOMBA_0_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define ROOMBA_0_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define ROOMBA_0_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define ROOMBA_0_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define RCMM32_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCMM32_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * RCMM32_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCMM32_BIT_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * RCMM32_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_BIT_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * RCMM32_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCMM32_BIT_00_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_00_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_BIT_00_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_00_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCMM32_BIT_01_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_01_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_BIT_01_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_01_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCMM32_BIT_10_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_10_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_BIT_10_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_10_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RCMM32_BIT_11_PAUSE_LEN_MIN             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_11_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RCMM32_BIT_11_PAUSE_LEN_MAX             ((uint_fast8_t)(F_INTERRUPTS * RCMM32_11_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n\n#define PENTAX_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define PENTAX_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define PENTAX_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define PENTAX_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * PENTAX_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define PENTAX_1_PAUSE_LEN_EXACT                ((uint_fast8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME + 0.5))\n#define PENTAX_PULSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define PENTAX_PULSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define PENTAX_1_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define PENTAX_1_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define PENTAX_0_PAUSE_LEN                      ((uint_fast8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME))\n#define PENTAX_PULSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define PENTAX_PULSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define PENTAX_0_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define PENTAX_0_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n\n#define ACP24_START_BIT_PULSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PULSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1)\n#define ACP24_START_BIT_PULSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PULSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1)\n#define ACP24_START_BIT_PAUSE_LEN_MIN           ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PAUSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1)\n#define ACP24_START_BIT_PAUSE_LEN_MAX           ((uint_fast8_t)(F_INTERRUPTS * ACP24_START_BIT_PAUSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1)\n#define ACP24_PULSE_LEN_MIN                     ((uint_fast8_t)(F_INTERRUPTS * ACP24_PULSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1)\n#define ACP24_PULSE_LEN_MAX                     ((uint_fast8_t)(F_INTERRUPTS * ACP24_PULSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1)\n#define ACP24_1_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * ACP24_1_PAUSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1)\n#define ACP24_1_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * ACP24_1_PAUSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1)\n#define ACP24_0_PAUSE_LEN_MIN                   ((uint_fast8_t)(F_INTERRUPTS * ACP24_0_PAUSE_TIME * MIN_TOLERANCE_15 + 0.5) - 1)\n#define ACP24_0_PAUSE_LEN_MAX                   ((uint_fast8_t)(F_INTERRUPTS * ACP24_0_PAUSE_TIME * MAX_TOLERANCE_15 + 0.5) + 1)\n\n#define METZ_START_BIT_PULSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define METZ_START_BIT_PULSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define METZ_START_BIT_PAUSE_LEN_MIN            ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define METZ_START_BIT_PAUSE_LEN_MAX            ((uint_fast8_t)(F_INTERRUPTS * METZ_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define METZ_PULSE_LEN_MIN                      ((uint_fast8_t)(F_INTERRUPTS * METZ_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define METZ_PULSE_LEN_MAX                      ((uint_fast8_t)(F_INTERRUPTS * METZ_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define METZ_1_PAUSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * METZ_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define METZ_1_PAUSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * METZ_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define METZ_0_PAUSE_LEN_MIN                    ((uint_fast8_t)(F_INTERRUPTS * METZ_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)\n#define METZ_0_PAUSE_LEN_MAX                    ((uint_fast8_t)(F_INTERRUPTS * METZ_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)\n#define METZ_FRAME_REPEAT_PAUSE_LEN_MAX         (uint_fast16_t)(F_INTERRUPTS * METZ_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)\n\n#define RF_GEN24_1_PAUSE_LEN_EXACT              ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_1_PAUSE_TIME + 0.5))\n#define RF_GEN24_1_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_1_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define RF_GEN24_1_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_1_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define RF_GEN24_1_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define RF_GEN24_1_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define RF_GEN24_0_PAUSE_LEN                    ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_0_PAUSE_TIME))\n#define RF_GEN24_0_PULSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_0_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define RF_GEN24_0_PULSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_0_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n#define RF_GEN24_0_PAUSE_LEN_MIN                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)\n#define RF_GEN24_0_PAUSE_LEN_MAX                ((uint_fast8_t)(F_INTERRUPTS * RF_GEN24_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)\n\n#define RF_X10_START_BIT_PULSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * RF_X10_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RF_X10_START_BIT_PULSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * RF_X10_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RF_X10_START_BIT_PAUSE_LEN_MIN          ((uint_fast8_t)(F_INTERRUPTS * RF_X10_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RF_X10_START_BIT_PAUSE_LEN_MAX          ((uint_fast8_t)(F_INTERRUPTS * RF_X10_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RF_X10_1_PAUSE_LEN_EXACT                ((uint_fast8_t)(F_INTERRUPTS * RF_X10_1_PAUSE_TIME + 0.5))\n#define RF_X10_1_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_X10_1_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RF_X10_1_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_X10_1_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RF_X10_0_PAUSE_LEN                      ((uint_fast8_t)(F_INTERRUPTS * RF_X10_0_PAUSE_TIME))\n#define RF_X10_0_PULSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_X10_0_PULSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RF_X10_0_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_X10_0_PAUSE_LEN_MAX                  ((uint_fast8_t)(F_INTERRUPTS * RF_X10_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define RF_MEDION_START_BIT_PULSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_START_BIT_PULSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RF_MEDION_START_BIT_PULSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_START_BIT_PULSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RF_MEDION_START_BIT_PAUSE_LEN_MIN       ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)\n#define RF_MEDION_START_BIT_PAUSE_LEN_MAX       ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)\n#define RF_MEDION_1_PAUSE_LEN_EXACT             ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_1_PAUSE_TIME + 0.5))\n#define RF_MEDION_1_PULSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_MEDION_1_PULSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RF_MEDION_1_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_MEDION_1_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RF_MEDION_0_PAUSE_LEN                   ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_0_PAUSE_TIME))\n#define RF_MEDION_0_PULSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_MEDION_0_PULSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n#define RF_MEDION_0_PAUSE_LEN_MIN               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)\n#define RF_MEDION_0_PAUSE_LEN_MAX               ((uint_fast8_t)(F_INTERRUPTS * RF_MEDION_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)\n\n#define AUTO_FRAME_REPETITION_LEN               (uint_fast16_t)(F_INTERRUPTS * AUTO_FRAME_REPETITION_TIME + 0.5)        // use uint_fast16_t!\n\n#define STOP_BIT_PAUSE_TIME_MIN                 3000.0e-6                                                               // minimum stop bit pause time: 3.0 msec\n#define STOP_BIT_PAUSE_LEN_MIN                  ((uint_fast8_t)(F_INTERRUPTS * STOP_BIT_PAUSE_TIME_MIN + 0.5) + 1)      // minimum stop bit pause len\n\n// XC8 Compiler does not support variadic macros\n#if defined(ANALYZE)\n#  define ANALYZE_PUTCHAR(a)                    { if (! silent)             { putchar (a);          } }\n#  define ANALYZE_ONLY_NORMAL_PUTCHAR(a)        { if (! silent && !verbose) { putchar (a);          } }\n// #  define ANALYZE_PRINTF(...)                { if (verbose)              { printf (__VA_ARGS__); } }\n#  define ANALYZE_PRINTF1(a)                    { if (verbose)              { printf (a); } }\n#  define ANALYZE_PRINTF2(a,b)                  { if (verbose)              { printf (a,b); } }\n#  define ANALYZE_PRINTF3(a,b,c)                { if (verbose)              { printf (a,b,c); } }\n#  define ANALYZE_PRINTF4(a,b,c,d)              { if (verbose)              { printf (a,b,c,d); } }\n#  define ANALYZE_PRINTF5(a,b,c,d,e)            { if (verbose)              { printf (a,b,c,d,e); } }\n#  define ANALYZE_PRINTF6(a,b,c,d,e,f)          { if (verbose)              { printf (a,b,c,d,e,f); } }\n#  define ANALYZE_PRINTF7(a,b,c,d,e,f,g)        { if (verbose)              { printf (a,b,c,d,e,f,g); } }\n#  define ANALYZE_PRINTF8(a,b,c,d,e,f,g,h)      { if (verbose)              { printf (a,b,c,d,e,f,g,h); } }\n#  define ANALYZE_PRINTF9(a,b,c,d,e,f,g,h,i)    { if (verbose)              { printf (a,b,c,d,e,f,g,h,i); } }\n//#  define ANALYZE_ONLY_NORMAL_PRINTF(...)     { if (! silent && !verbose) { printf (__VA_ARGS__); } }\n#  define ANALYZE_ONLY_NORMAL_PRINTF1(a)        { if (! silent && !verbose) { printf (a); } }\n#  define ANALYZE_NEWLINE()                     { if (verbose)              { putchar ('\\n');       } }\nstatic int                                      silent;\nstatic int                                      time_counter;\nstatic int                                      verbose;\n\n#else\n#  define ANALYZE_PUTCHAR(a)\n#  define ANALYZE_ONLY_NORMAL_PUTCHAR(a)\n// #  define ANALYZE_PRINTF(...)\n#  define ANALYZE_PRINTF1(a)\n#  define ANALYZE_PRINTF2(a,b)\n#  define ANALYZE_PRINTF3(a,b,c)\n#  define ANALYZE_PRINTF4(a,b,c,d)\n#  define ANALYZE_PRINTF5(a,b,c,d,e)\n#  define ANALYZE_PRINTF6(a,b,c,d,e,f)\n#  define ANALYZE_PRINTF7(a,b,c,d,e,f,g)\n#  define ANALYZE_PRINTF8(a,b,c,d,e,f,g,h)\n#  define ANALYZE_PRINTF9(a,b,c,d,e,f,g,h,i)\n//#  define ANALYZE_ONLY_NORMAL_PRINTF(...)\n#  define ANALYZE_ONLY_NORMAL_PRINTF1(a)\n#  define ANALYZE_NEWLINE()\n#endif\n\n#if IRMP_USE_CALLBACK == 1\nstatic void                                     (*irmp_callback_ptr) (uint_fast8_t);\n#endif // IRMP_USE_CALLBACK == 1\n\n#if IRMP_USE_COMPLETE_CALLBACK == 1\nstatic void (*irmp_complete_callback_function)(void);\nvoid irmp_register_complete_callback_function(void (*aCompleteCallbackFunction)(void)) {\n    irmp_complete_callback_function = aCompleteCallbackFunction;\n}\n#endif // IRMP_USE_COMPLETE_CALLBACK == 1\n\n#define PARITY_CHECK_OK                         1\n#define PARITY_CHECK_FAILED                     0\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Protocol names\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined(UNIX_OR_WINDOWS) || IRMP_PROTOCOL_NAMES == 1\n#include \"irmpprotocols.hpp\"  // include protocol strings and array of strings\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Logging\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if IRMP_LOGGING == 1                                                   // logging via UART\n\n#if defined(ARM_STM32F4XX)\n#  define  STM32_GPIO_CLOCK   RCC_AHB1Periph_GPIOA                      // UART2 on PA2\n#  define  STM32_UART_CLOCK   RCC_APB1Periph_USART2\n#  define  STM32_GPIO_PORT    GPIOA\n#  define  STM32_GPIO_PIN     GPIO_Pin_2\n#  define  STM32_GPIO_SOURCE  GPIO_PinSource2\n#  define  STM32_UART_AF      GPIO_AF_USART2\n#  define  STM32_UART_COM     USART2\n#  define  STM32_UART_BAUD    115200                                    // 115200 Baud\n#  include \"stm32f4xx_usart.h\"\n#elif defined(ARM_STM32F10X) || defined(ARM_STM32F30X)\n#  define  STM32_UART_COM     USART3                                    // UART3 on PB10\n#elif defined(ARDUINO)                                                  // Arduino Serial implementation\n#  include \"HardwareSerial.h\"\n#elif defined(_CHIBIOS_HAL_)                                            // ChibiOS HAL\n#  if IRMP_EXT_LOGGING == 1\n#    error IRMP_EXT_LOGGING not implemented for ChibiOS HAL, use regular logging instead\n#  endif\n#else\n#  if IRMP_EXT_LOGGING == 1                                             // use external logging\n#    include \"irmpextlog.h\"\n#  else                                                                 // normal UART log (IRMP_EXT_LOGGING == 0)\n#    define BAUD                                    9600L\n#  if !defined(UNIX_OR_WINDOWS)\n#    include <util/setbaud.h>\n#  endif\n\n#if defined(UBRR)0H\n\n#define UART0_UBRRH                             UBRR0H\n#define UART0_UBRRL                             UBRR0L\n#define UART0_UCSRA                             UCSR0A\n#define UART0_UCSRB                             UCSR0B\n#define UART0_UCSRC                             UCSR0C\n#define UART0_UDRE_BIT_VALUE                    (1<<UDRE0)\n#define UART0_UCSZ1_BIT_VALUE                   (1<<UCSZ01)\n#define UART0_UCSZ0_BIT_VALUE                   (1<<UCSZ00)\n#if defined(URSEL)0\n#define UART0_URSEL_BIT_VALUE                   (1<<URSEL0)\n#else\n#define UART0_URSEL_BIT_VALUE                   (0)\n#endif\n#define UART0_TXEN_BIT_VALUE                    (1<<TXEN0)\n#define UART0_UDR                               UDR0\n#define UART0_U2X                               U2X0\n\n#else\n\n#define UART0_UBRRH                             UBRRH\n#define UART0_UBRRL                             UBRRL\n#define UART0_UCSRA                             UCSRA\n#define UART0_UCSRB                             UCSRB\n#define UART0_UCSRC                             UCSRC\n#define UART0_UDRE_BIT_VALUE                    (1<<UDRE)\n#define UART0_UCSZ1_BIT_VALUE                   (1<<UCSZ1)\n#define UART0_UCSZ0_BIT_VALUE                   (1<<UCSZ0)\n#if defined(URSEL)\n#define UART0_URSEL_BIT_VALUE                   (1<<URSEL)\n#else\n#define UART0_URSEL_BIT_VALUE                   (0)\n#endif\n#define UART0_TXEN_BIT_VALUE                    (1<<TXEN)\n#define UART0_UDR                               UDR\n#define UART0_U2X                               U2X\n\n#endif //UBRR0H\n#endif //IRMP_EXT_LOGGING\n#endif //ARM_STM32F4XX\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Initialize  UART\n *  @details  Initializes UART\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\nvoid\nirmp_uart_init (void)\n{\n#if !defined(UNIX_OR_WINDOWS)\n#if defined(ARM_STM32F4XX)\n    GPIO_InitTypeDef GPIO_InitStructure;\n    USART_InitTypeDef USART_InitStructure;\n\n    // Clock enable vom TX Pin\n    RCC_AHB1PeriphClockCmd(STM32_GPIO_CLOCK, ENABLE);\n\n    // Clock enable der UART\n    RCC_APB1PeriphClockCmd(STM32_UART_CLOCK, ENABLE);\n\n    // UART Alternative-Funktion mit dem IO-Pin verbinden\n    GPIO_PinAFConfig(STM32_GPIO_PORT,STM32_GPIO_SOURCE,STM32_UART_AF);\n\n    // UART als Alternative-Funktion mit PushPull\n    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\n    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;\n    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\n    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;\n\n    // TX-Pin\n    GPIO_InitStructure.GPIO_Pin = STM32_GPIO_PIN;\n    GPIO_Init(STM32_GPIO_PORT, &GPIO_InitStructure);\n\n    // Oversampling\n    USART_OverSampling8Cmd(STM32_UART_COM, ENABLE);\n\n    // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS\n    USART_InitStructure.USART_BaudRate = STM32_UART_BAUD;\n    USART_InitStructure.USART_WordLength = USART_WordLength_8b;\n    USART_InitStructure.USART_StopBits = USART_StopBits_1;\n    USART_InitStructure.USART_Parity = USART_Parity_No;\n    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;\n    USART_InitStructure.USART_Mode = USART_Mode_Tx;\n    USART_Init(STM32_UART_COM, &USART_InitStructure);\n\n    // UART enable\n    USART_Cmd(STM32_UART_COM, ENABLE);\n\n#elif defined(ARM_STM32F10X)\n    GPIO_InitTypeDef GPIO_InitStructure;\n    USART_InitTypeDef USART_InitStructure;\n\n    // Clock enable vom TX Pin\n    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // UART3 an PB10\n\n    // Clock enable der UART\n    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);\n\n    // UART als Alternative-Funktion mit PushPull\n    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;\n    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;\n\n    // TX-Pin\n    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;\n    GPIO_Init(GPIOB, &GPIO_InitStructure);\n\n    // Oversampling\n    USART_OverSampling8Cmd(STM32_UART_COM, ENABLE);\n\n    // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS\n    USART_InitStructure.USART_BaudRate = 115200;\n    USART_InitStructure.USART_WordLength = USART_WordLength_8b;\n    USART_InitStructure.USART_StopBits = USART_StopBits_1;\n    USART_InitStructure.USART_Parity = USART_Parity_No;\n    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;\n    USART_InitStructure.USART_Mode = USART_Mode_Tx;\n    USART_Init(STM32_UART_COM, &USART_InitStructure);\n\n    // UART enable\n    USART_Cmd(STM32_UART_COM, ENABLE);\n\n#elif defined(ARM_STM32F30X)\n    GPIO_InitTypeDef GPIO_InitStructure;\n    USART_InitTypeDef USART_InitStructure;\n\n    // Clock enable vom TX Pin\n    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // UART3 an PB10\n\n    // Clock enable der UART\n    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);\n\n    // UART Alternative-Funktion mit dem IO-Pin verbinden\n    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_7);\n\n    // UART als Alternative-Funktion mit PushPull\n    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\n    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;\n\n    // TX-Pin\n    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;\n    GPIO_Init(GPIOB, &GPIO_InitStructure);\n\n    // Oversampling\n    USART_OverSampling8Cmd(STM32_UART_COM, ENABLE);\n\n    // init baud rate, 8 data bits, 1 stop bit, no parity, no RTS+CTS\n    USART_InitStructure.USART_BaudRate = 115200;\n    USART_InitStructure.USART_WordLength = USART_WordLength_8b;\n    USART_InitStructure.USART_StopBits = USART_StopBits_1;\n    USART_InitStructure.USART_Parity = USART_Parity_No;\n    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;\n    USART_InitStructure.USART_Mode = USART_Mode_Tx;\n    USART_Init(STM32_UART_COM, &USART_InitStructure);\n\n    // UART enable\n    USART_Cmd(STM32_UART_COM, ENABLE);\n\n#elif defined(ARDUINO)\n    // we use the Arduino Serial Implementation\n    // you have to call Serial.begin(SER_BAUD); in Arduino setup() function\n\n#elif defined (__AVR_XMEGA__)\n\n    PMIC.CTRL |= PMIC_HILVLEN_bm;\n\n    USARTC1.BAUDCTRLB = 0;\n    USARTC1.BAUDCTRLA = F_CPU / 153600 - 1;\n    USARTC1.CTRLA = USART_RXCINTLVL_HI_gc;                                                          // high INT level (receive)\n    USARTC1.CTRLB = USART_TXEN_bm | USART_RXEN_bm;                                                  // activated RX and TX\n    USARTC1.CTRLC = USART_CHSIZE_8BIT_gc;                                                           // 8 Bit\n    PORTC.DIR |= (1<<7);                                                                            // TXD is output\n    PORTC.DIR &= ~(1<<6);\n\n#elif defined (_CHIBIOS_HAL_)\n    // we use the SD interface for logging, no need to init that here\n\n#else\n\n#if (IRMP_EXT_LOGGING == 0)                                                                         // use UART\n    UART0_UBRRH = UBRRH_VALUE;                                                                      // set baud rate\n    UART0_UBRRL = UBRRL_VALUE;\n\n#if USE_2X\n    UART0_UCSRA |= (1<<UART0_U2X);\n#else\n    UART0_UCSRA &= ~(1<<UART0_U2X);\n#endif\n\n    UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE;\n    UART0_UCSRB |= UART0_TXEN_BIT_VALUE;                                                            // enable UART TX\n#else                                                                                               // other log method\n    initextlog();\n#endif //IRMP_EXT_LOGGING\n#endif //ARM_STM32F4XX\n#endif // UNIX_OR_WINDOWS\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Send character\n *  @details  Sends character\n *  @param    ch character to be transmitted\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\nvoid\nirmp_uart_putc (unsigned char ch)\n{\n#if !defined(UNIX_OR_WINDOWS)\n#if defined(ARM_STM32F4XX) || defined(ARM_STM32F10X) || defined(ARM_STM32F30X)\n    // warten bis altes Byte gesendet wurde\n    while (USART_GetFlagStatus(STM32_UART_COM, USART_FLAG_TXE) == RESET)\n    {\n        ;\n    }\n\n    USART_SendData(STM32_UART_COM, ch);\n\n    if (ch == '\\n')\n    {\n        while (USART_GetFlagStatus(STM32_UART_COM, USART_FLAG_TXE) == RESET);\n        USART_SendData(STM32_UART_COM, '\\r');\n    }\n\n#elif defined(ARDUINO)\n    // we use the Arduino Serial Implementation\n    Serial.write(ch);\n\n#elif defined(_CHIBIOS_HAL_)\n    // use the SD interface from HAL, log to IRMP_LOGGING_SD which is defined in irmpconfig.h\n    sdWriteI(&IRMP_LOGGING_SD,&ch,1);      // we are called from interrupt context, so use the ...I version of the function\n\n#else\n#if (IRMP_EXT_LOGGING == 0)\n\n#  if defined (__AVR_XMEGA__)\n    while (!(USARTC1.STATUS & USART_DREIF_bm))\n    {\n        ;\n    }\n\n    USARTC1.DATA = ch;\n\n#  else // AVR_MEGA\n    while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))\n    {\n        ;\n    }\n\n    UART0_UDR = ch;\n\n#  endif // __AVR_XMEGA__\n\n#else\n\n    sendextlog(ch);                                                         // use external log\n\n#endif // IRMP_EXT_LOGGING\n#endif // ARM_STM32F4XX\n#else\n    fputc (ch, stderr);\n#endif // UNIX_OR_WINDOWS\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Log IR signal\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#define STARTCYCLES                       2                                 // min count of zeros before start of logging\n#define ENDBITS                        1000                                 // number of sequenced highbits to detect end\n#define DATALEN                         700                                 // log buffer size\n\nstatic void\nirmp_log (uint_fast8_t val)\n{\n    static uint8_t          buf[DATALEN];                                   // logging buffer\n    static uint_fast16_t    buf_idx;                                        // index\n    static uint_fast8_t     startcycles;                                    // current number of start-zeros\n    static uint_fast16_t    cnt;                                            // counts sequenced highbits - to detect end\n    static uint_fast8_t     last_val = 1;\n\n    if (! val && (startcycles < STARTCYCLES) && !buf_idx)                   // prevent that single random zeros init logging\n    {\n        startcycles++;\n    }\n    else\n    {\n        startcycles = 0;\n\n        if (! val || buf_idx != 0)                                          // start or continue logging on \"0\", \"1\" cannot init logging\n        {\n            if (last_val == val)\n            {\n                cnt++;\n\n                if (val && cnt > ENDBITS)                                   // if high received then look at log-stop condition\n                {                                                           // if stop condition is true, output on uart\n                    uint_fast8_t     i8;\n                    uint_fast16_t    i;\n                    uint_fast16_t    j;\n                    uint_fast8_t     v = '1';\n                    uint_fast16_t    d;\n\n                    for (i8 = 0; i8 < STARTCYCLES; i8++)\n                    {\n                        irmp_uart_putc ('0');                               // the ignored starting zeros\n                    }\n\n                    for (i = 0; i < buf_idx; i++)\n                    {\n                        d = buf[i];\n\n                        if (d == 0xff)\n                        {\n                            i++;\n                            d = buf[i];\n                            i++;\n                            d |= ((uint_fast16_t) buf[i] << 8);\n                        }\n\n                        for (j = 0; j < d; j++)\n                        {\n                            irmp_uart_putc (v);\n                        }\n\n                        v = (v == '1') ? '0' : '1';\n                    }\n\n                    for (i8 = 0; i8 < 20; i8++)\n                    {\n                        irmp_uart_putc ('1');\n                    }\n\n                    irmp_uart_putc ('\\n');\n                    buf_idx = 0;\n                    last_val = 1;\n                    cnt = 0;\n                }\n            }\n            else if (buf_idx < DATALEN - 3)\n            {\n                if (cnt >= 0xff)\n                {\n                    buf[buf_idx++]  = 0xff;\n                    buf[buf_idx++]  = (cnt & 0xff);\n                    buf[buf_idx]    = (cnt >> 8);\n                }\n                else\n                {\n                    buf[buf_idx] = cnt;\n                }\n\n                buf_idx++;\n                cnt = 1;\n                last_val = val;\n            }\n        }\n    }\n}\n\n#else\n#define irmp_log(val)\n#endif //IRMP_LOGGING\n\ntypedef struct\n{\n    uint_fast8_t    protocol;                                                // ir protocol\n    uint_fast8_t    pulse_1_len_min;                                         // minimum length of pulse with bit value 1\n    uint_fast8_t    pulse_1_len_max;                                         // maximum length of pulse with bit value 1\n    uint_fast8_t    pause_1_len_min;                                         // minimum length of pause with bit value 1\n    uint_fast8_t    pause_1_len_max;                                         // maximum length of pause with bit value 1\n    uint_fast8_t    pulse_0_len_min;                                         // minimum length of pulse with bit value 0\n    uint_fast8_t    pulse_0_len_max;                                         // maximum length of pulse with bit value 0\n    uint_fast8_t    pause_0_len_min;                                         // minimum length of pause with bit value 0\n    uint_fast8_t    pause_0_len_max;                                         // maximum length of pause with bit value 0\n    uint_fast8_t    address_offset;                                          // address offset\n    uint_fast8_t    address_end;                                             // end of address\n    uint_fast8_t    command_offset;                                          // command offset\n    uint_fast8_t    command_end;                                             // end of command\n    uint_fast8_t    complete_len;                                            // complete length of frame\n    uint_fast8_t    stop_bit;                                                // flag: frame has stop bit\n    uint_fast8_t    lsb_first;                                               // flag: LSB first\n    uint_fast8_t    flags;                                                   // some flags\n} IRMP_PARAMETER;\n\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER sircs_param =\n{\n    IRMP_SIRCS_PROTOCOL,                                                // protocol:        ir protocol\n    SIRCS_1_PULSE_LEN_MIN,                                              // pulse_1_len_min: minimum length of pulse with bit value 1\n    SIRCS_1_PULSE_LEN_MAX,                                              // pulse_1_len_max: maximum length of pulse with bit value 1\n    SIRCS_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    SIRCS_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    SIRCS_0_PULSE_LEN_MIN,                                              // pulse_0_len_min: minimum length of pulse with bit value 0\n    SIRCS_0_PULSE_LEN_MAX,                                              // pulse_0_len_max: maximum length of pulse with bit value 0\n    SIRCS_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    SIRCS_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    SIRCS_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    SIRCS_ADDRESS_OFFSET + SIRCS_ADDRESS_LEN,                           // address_end:     end of address\n    SIRCS_COMMAND_OFFSET,                                               // command_offset:  command offset\n    SIRCS_COMMAND_OFFSET + SIRCS_COMMAND_LEN,                           // command_end:     end of command\n    SIRCS_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    SIRCS_STOP_BIT,                                                     // stop_bit:        flag: frame has stop bit\n    SIRCS_LSB,                                                          // lsb_first:       flag: LSB first\n    SIRCS_FLAGS                                                         // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER nec_param =\n{\n    IRMP_NEC_PROTOCOL,                                                  // protocol:        ir protocol\n    NEC_PULSE_LEN_MIN,                                                  // pulse_1_len_min: minimum length of pulse with bit value 1\n    NEC_PULSE_LEN_MAX,                                                  // pulse_1_len_max: maximum length of pulse with bit value 1\n    NEC_1_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    NEC_1_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    NEC_PULSE_LEN_MIN,                                                  // pulse_0_len_min: minimum length of pulse with bit value 0\n    NEC_PULSE_LEN_MAX,                                                  // pulse_0_len_max: maximum length of pulse with bit value 0\n    NEC_0_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    NEC_0_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    NEC_ADDRESS_OFFSET,                                                 // address_offset:  address offset\n    NEC_ADDRESS_OFFSET + NEC_ADDRESS_LEN,                               // address_end:     end of address\n    NEC_COMMAND_OFFSET,                                                 // command_offset:  command offset\n    NEC_COMMAND_OFFSET + NEC_COMMAND_LEN,                               // command_end:     end of command\n    NEC_COMPLETE_DATA_LEN,                                              // complete_len:    complete length of frame\n    NEC_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    NEC_LSB,                                                            // lsb_first:       flag: LSB first\n    NEC_FLAGS                                                           // flags:           some flags\n};\n\nstatic const PROGMEM IRMP_PARAMETER nec_rep_param =\n{\n    IRMP_NEC_PROTOCOL,                                                  // protocol:        ir protocol\n    NEC_PULSE_LEN_MIN,                                                  // pulse_1_len_min: minimum length of pulse with bit value 1\n    NEC_PULSE_LEN_MAX,                                                  // pulse_1_len_max: maximum length of pulse with bit value 1\n    NEC_1_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    NEC_1_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    NEC_PULSE_LEN_MIN,                                                  // pulse_0_len_min: minimum length of pulse with bit value 0\n    NEC_PULSE_LEN_MAX,                                                  // pulse_0_len_max: maximum length of pulse with bit value 0\n    NEC_0_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    NEC_0_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    0,                                                                  // address_offset:  address offset\n    0,                                                                  // address_end:     end of address\n    0,                                                                  // command_offset:  command offset\n    0,                                                                  // command_end:     end of command\n    0,                                                                  // complete_len:    complete length of frame\n    NEC_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    NEC_LSB,                                                            // lsb_first:       flag: LSB first\n    NEC_FLAGS                                                           // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER nec42_param =\n{\n    IRMP_NEC42_PROTOCOL,                                                // protocol:        ir protocol\n    NEC_PULSE_LEN_MIN,                                                  // pulse_1_len_min: minimum length of pulse with bit value 1\n    NEC_PULSE_LEN_MAX,                                                  // pulse_1_len_max: maximum length of pulse with bit value 1\n    NEC_1_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    NEC_1_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    NEC_PULSE_LEN_MIN,                                                  // pulse_0_len_min: minimum length of pulse with bit value 0\n    NEC_PULSE_LEN_MAX,                                                  // pulse_0_len_max: maximum length of pulse with bit value 0\n    NEC_0_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    NEC_0_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    NEC42_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    NEC42_ADDRESS_OFFSET + NEC42_ADDRESS_LEN,                           // address_end:     end of address\n    NEC42_COMMAND_OFFSET,                                               // command_offset:  command offset\n    NEC42_COMMAND_OFFSET + NEC42_COMMAND_LEN,                           // command_end:     end of command\n    NEC42_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    NEC_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    NEC_LSB,                                                            // lsb_first:       flag: LSB first\n    NEC_FLAGS                                                           // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n#if 0 // not needed, switching from NEC\n\nstatic const PROGMEM IRMP_PARAMETER lgair_param =\n{\n    IRMP_LGAIR_PROTOCOL,                                                // protocol:        ir protocol\n    NEC_PULSE_LEN_MIN,                                                  // pulse_1_len_min: minimum length of pulse with bit value 1\n    NEC_PULSE_LEN_MAX,                                                  // pulse_1_len_max: maximum length of pulse with bit value 1\n    NEC_1_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    NEC_1_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    NEC_PULSE_LEN_MIN,                                                  // pulse_0_len_min: minimum length of pulse with bit value 0\n    NEC_PULSE_LEN_MAX,                                                  // pulse_0_len_max: maximum length of pulse with bit value 0\n    NEC_0_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    NEC_0_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    LGAIR_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    LGAIR_ADDRESS_OFFSET + LGAIR_ADDRESS_LEN,                           // address_end:     end of address\n    LGAIR_COMMAND_OFFSET,                                               // command_offset:  command offset\n    LGAIR_COMMAND_OFFSET + LGAIR_COMMAND_LEN,                           // command_end:     end of command\n    LGAIR_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    NEC_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    NEC_LSB,                                                            // lsb_first:       flag: LSB first\n    NEC_FLAGS                                                           // flags:           some flags\n};\n\n#endif // 0 not needed, switching from NEC\n#endif\n\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER samsung_param =\n{\n    IRMP_SAMSUNG_PROTOCOL,                                              // protocol:        ir protocol\n    SAMSUNG_PULSE_LEN_MIN,                                              // pulse_1_len_min: minimum length of pulse with bit value 1\n    SAMSUNG_PULSE_LEN_MAX,                                              // pulse_1_len_max: maximum length of pulse with bit value 1\n    SAMSUNG_1_PAUSE_LEN_MIN,                                            // pause_1_len_min: minimum length of pause with bit value 1\n    SAMSUNG_1_PAUSE_LEN_MAX,                                            // pause_1_len_max: maximum length of pause with bit value 1\n    SAMSUNG_PULSE_LEN_MIN,                                              // pulse_0_len_min: minimum length of pulse with bit value 0\n    SAMSUNG_PULSE_LEN_MAX,                                              // pulse_0_len_max: maximum length of pulse with bit value 0\n    SAMSUNG_0_PAUSE_LEN_MIN,                                            // pause_0_len_min: minimum length of pause with bit value 0\n    SAMSUNG_0_PAUSE_LEN_MAX,                                            // pause_0_len_max: maximum length of pause with bit value 0\n    SAMSUNG_ADDRESS_OFFSET,                                             // address_offset:  address offset\n    SAMSUNG_ADDRESS_OFFSET + SAMSUNG_ADDRESS_LEN,                       // address_end:     end of address\n    SAMSUNG_COMMAND_OFFSET,                                             // command_offset:  command offset\n    SAMSUNG_COMMAND_OFFSET + SAMSUNG_COMMAND_LEN,                       // command_end:     end of command\n    SAMSUNG_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame\n    SAMSUNG_STOP_BIT,                                                   // stop_bit:        flag: frame has stop bit\n    SAMSUNG_LSB,                                                        // lsb_first:       flag: LSB first\n    SAMSUNG_FLAGS                                                       // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER samsungah_param =\n{\n    IRMP_SAMSUNGAH_PROTOCOL,                                            // protocol:        ir protocol\n    SAMSUNGAH_PULSE_LEN_MIN,                                            // pulse_1_len_min: minimum length of pulse with bit value 1\n    SAMSUNGAH_PULSE_LEN_MAX,                                            // pulse_1_len_max: maximum length of pulse with bit value 1\n    SAMSUNGAH_1_PAUSE_LEN_MIN,                                          // pause_1_len_min: minimum length of pause with bit value 1\n    SAMSUNGAH_1_PAUSE_LEN_MAX,                                          // pause_1_len_max: maximum length of pause with bit value 1\n    SAMSUNGAH_PULSE_LEN_MIN,                                            // pulse_0_len_min: minimum length of pulse with bit value 0\n    SAMSUNGAH_PULSE_LEN_MAX,                                            // pulse_0_len_max: maximum length of pulse with bit value 0\n    SAMSUNGAH_0_PAUSE_LEN_MIN,                                          // pause_0_len_min: minimum length of pause with bit value 0\n    SAMSUNGAH_0_PAUSE_LEN_MAX,                                          // pause_0_len_max: maximum length of pause with bit value 0\n    SAMSUNGAH_ADDRESS_OFFSET,                                           // address_offset:  address offset\n    SAMSUNGAH_ADDRESS_OFFSET + SAMSUNGAH_ADDRESS_LEN,                   // address_end:     end of address\n    SAMSUNGAH_COMMAND_OFFSET,                                           // command_offset:  command offset\n    SAMSUNGAH_COMMAND_OFFSET + SAMSUNGAH_COMMAND_LEN,                   // command_end:     end of command\n    SAMSUNGAH_COMPLETE_DATA_LEN,                                        // complete_len:    complete length of frame\n    SAMSUNGAH_STOP_BIT,                                                 // stop_bit:        flag: frame has stop bit\n    SAMSUNGAH_LSB,                                                      // lsb_first:       flag: LSB first\n    SAMSUNGAH_FLAGS                                                     // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER telefunken_param =\n{\n    IRMP_TELEFUNKEN_PROTOCOL,                                           // protocol:        ir protocol\n    TELEFUNKEN_PULSE_LEN_MIN,                                           // pulse_1_len_min: minimum length of pulse with bit value 1\n    TELEFUNKEN_PULSE_LEN_MAX,                                           // pulse_1_len_max: maximum length of pulse with bit value 1\n    TELEFUNKEN_1_PAUSE_LEN_MIN,                                         // pause_1_len_min: minimum length of pause with bit value 1\n    TELEFUNKEN_1_PAUSE_LEN_MAX,                                         // pause_1_len_max: maximum length of pause with bit value 1\n    TELEFUNKEN_PULSE_LEN_MIN,                                           // pulse_0_len_min: minimum length of pulse with bit value 0\n    TELEFUNKEN_PULSE_LEN_MAX,                                           // pulse_0_len_max: maximum length of pulse with bit value 0\n    TELEFUNKEN_0_PAUSE_LEN_MIN,                                         // pause_0_len_min: minimum length of pause with bit value 0\n    TELEFUNKEN_0_PAUSE_LEN_MAX,                                         // pause_0_len_max: maximum length of pause with bit value 0\n    TELEFUNKEN_ADDRESS_OFFSET,                                          // address_offset:  address offset\n    TELEFUNKEN_ADDRESS_OFFSET + TELEFUNKEN_ADDRESS_LEN,                 // address_end:     end of address\n    TELEFUNKEN_COMMAND_OFFSET,                                          // command_offset:  command offset\n    TELEFUNKEN_COMMAND_OFFSET + TELEFUNKEN_COMMAND_LEN,                 // command_end:     end of command\n    TELEFUNKEN_COMPLETE_DATA_LEN,                                       // complete_len:    complete length of frame\n    TELEFUNKEN_STOP_BIT,                                                // stop_bit:        flag: frame has stop bit\n    TELEFUNKEN_LSB,                                                     // lsb_first:       flag: LSB first\n    TELEFUNKEN_FLAGS                                                    // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER matsushita_param =\n{\n    IRMP_MATSUSHITA_PROTOCOL,                                           // protocol:        ir protocol\n    MATSUSHITA_PULSE_LEN_MIN,                                           // pulse_1_len_min: minimum length of pulse with bit value 1\n    MATSUSHITA_PULSE_LEN_MAX,                                           // pulse_1_len_max: maximum length of pulse with bit value 1\n    MATSUSHITA_1_PAUSE_LEN_MIN,                                         // pause_1_len_min: minimum length of pause with bit value 1\n    MATSUSHITA_1_PAUSE_LEN_MAX,                                         // pause_1_len_max: maximum length of pause with bit value 1\n    MATSUSHITA_PULSE_LEN_MIN,                                           // pulse_0_len_min: minimum length of pulse with bit value 0\n    MATSUSHITA_PULSE_LEN_MAX,                                           // pulse_0_len_max: maximum length of pulse with bit value 0\n    MATSUSHITA_0_PAUSE_LEN_MIN,                                         // pause_0_len_min: minimum length of pause with bit value 0\n    MATSUSHITA_0_PAUSE_LEN_MAX,                                         // pause_0_len_max: maximum length of pause with bit value 0\n    MATSUSHITA_ADDRESS_OFFSET,                                          // address_offset:  address offset\n    MATSUSHITA_ADDRESS_OFFSET + MATSUSHITA_ADDRESS_LEN,                 // address_end:     end of address\n    MATSUSHITA_COMMAND_OFFSET,                                          // command_offset:  command offset\n    MATSUSHITA_COMMAND_OFFSET + MATSUSHITA_COMMAND_LEN,                 // command_end:     end of command\n    MATSUSHITA_COMPLETE_DATA_LEN,                                       // complete_len:    complete length of frame\n    MATSUSHITA_STOP_BIT,                                                // stop_bit:        flag: frame has stop bit\n    MATSUSHITA_LSB,                                                     // lsb_first:       flag: LSB first\n    MATSUSHITA_FLAGS                                                    // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER kaseikyo_param =\n{\n    IRMP_KASEIKYO_PROTOCOL,                                             // protocol:        ir protocol\n    KASEIKYO_PULSE_LEN_MIN,                                             // pulse_1_len_min: minimum length of pulse with bit value 1\n    KASEIKYO_PULSE_LEN_MAX,                                             // pulse_1_len_max: maximum length of pulse with bit value 1\n    KASEIKYO_1_PAUSE_LEN_MIN,                                           // pause_1_len_min: minimum length of pause with bit value 1\n    KASEIKYO_1_PAUSE_LEN_MAX,                                           // pause_1_len_max: maximum length of pause with bit value 1\n    KASEIKYO_PULSE_LEN_MIN,                                             // pulse_0_len_min: minimum length of pulse with bit value 0\n    KASEIKYO_PULSE_LEN_MAX,                                             // pulse_0_len_max: maximum length of pulse with bit value 0\n    KASEIKYO_0_PAUSE_LEN_MIN,                                           // pause_0_len_min: minimum length of pause with bit value 0\n    KASEIKYO_0_PAUSE_LEN_MAX,                                           // pause_0_len_max: maximum length of pause with bit value 0\n    KASEIKYO_ADDRESS_OFFSET,                                            // address_offset:  address offset\n    KASEIKYO_ADDRESS_OFFSET + KASEIKYO_ADDRESS_LEN,                     // address_end:     end of address\n    KASEIKYO_COMMAND_OFFSET,                                            // command_offset:  command offset\n    KASEIKYO_COMMAND_OFFSET + KASEIKYO_COMMAND_LEN,                     // command_end:     end of command\n    KASEIKYO_COMPLETE_DATA_LEN,                                         // complete_len:    complete length of frame\n    KASEIKYO_STOP_BIT,                                                  // stop_bit:        flag: frame has stop bit\n    KASEIKYO_LSB,                                                       // lsb_first:       flag: LSB first\n    KASEIKYO_FLAGS                                                      // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER panasonic_param =\n{\n    IRMP_PANASONIC_PROTOCOL,                                            // protocol:        ir protocol\n    PANASONIC_PULSE_LEN_MIN,                                            // pulse_1_len_min: minimum length of pulse with bit value 1\n    PANASONIC_PULSE_LEN_MAX,                                            // pulse_1_len_max: maximum length of pulse with bit value 1\n    PANASONIC_1_PAUSE_LEN_MIN,                                          // pause_1_len_min: minimum length of pause with bit value 1\n    PANASONIC_1_PAUSE_LEN_MAX,                                          // pause_1_len_max: maximum length of pause with bit value 1\n    PANASONIC_PULSE_LEN_MIN,                                            // pulse_0_len_min: minimum length of pulse with bit value 0\n    PANASONIC_PULSE_LEN_MAX,                                            // pulse_0_len_max: maximum length of pulse with bit value 0\n    PANASONIC_0_PAUSE_LEN_MIN,                                          // pause_0_len_min: minimum length of pause with bit value 0\n    PANASONIC_0_PAUSE_LEN_MAX,                                          // pause_0_len_max: maximum length of pause with bit value 0\n    PANASONIC_ADDRESS_OFFSET,                                           // address_offset:  address offset\n    PANASONIC_ADDRESS_OFFSET + PANASONIC_ADDRESS_LEN,                   // address_end:     end of address\n    PANASONIC_COMMAND_OFFSET,                                           // command_offset:  command offset\n    PANASONIC_COMMAND_OFFSET + PANASONIC_COMMAND_LEN,                   // command_end:     end of command\n    PANASONIC_COMPLETE_DATA_LEN,                                        // complete_len:    complete length of frame\n    PANASONIC_STOP_BIT,                                                 // stop_bit:        flag: frame has stop bit\n    PANASONIC_LSB,                                                      // lsb_first:       flag: LSB first\n    PANASONIC_FLAGS                                                     // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER mitsu_heavy_param =\n{\n    IRMP_MITSU_HEAVY_PROTOCOL,                                          // protocol:        ir protocol\n    MITSU_HEAVY_PULSE_LEN_MIN,                                          // pulse_1_len_min: minimum length of pulse with bit value 1\n    MITSU_HEAVY_PULSE_LEN_MAX,                                          // pulse_1_len_max: maximum length of pulse with bit value 1\n    MITSU_HEAVY_1_PAUSE_LEN_MIN,                                        // pause_1_len_min: minimum length of pause with bit value 1\n    MITSU_HEAVY_1_PAUSE_LEN_MAX,                                        // pause_1_len_max: maximum length of pause with bit value 1\n    MITSU_HEAVY_PULSE_LEN_MIN,                                          // pulse_0_len_min: minimum length of pulse with bit value 0\n    MITSU_HEAVY_PULSE_LEN_MAX,                                          // pulse_0_len_max: maximum length of pulse with bit value 0\n    MITSU_HEAVY_0_PAUSE_LEN_MIN,                                        // pause_0_len_min: minimum length of pause with bit value 0\n    MITSU_HEAVY_0_PAUSE_LEN_MAX,                                        // pause_0_len_max: maximum length of pause with bit value 0\n    MITSU_HEAVY_ADDRESS_OFFSET,                                         // address_offset:  address offset\n    MITSU_HEAVY_ADDRESS_OFFSET + MITSU_HEAVY_ADDRESS_LEN,               // address_end:     end of address\n    MITSU_HEAVY_COMMAND_OFFSET,                                         // command_offset:  command offset\n    MITSU_HEAVY_COMMAND_OFFSET + MITSU_HEAVY_COMMAND_LEN,               // command_end:     end of command\n    MITSU_HEAVY_COMPLETE_DATA_LEN,                                      // complete_len:    complete length of frame\n    MITSU_HEAVY_STOP_BIT,                                               // stop_bit:        flag: frame has stop bit\n    MITSU_HEAVY_LSB,                                                    // lsb_first:       flag: LSB first\n    MITSU_HEAVY_FLAGS                                                   // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER vincent_param =\n{\n    IRMP_VINCENT_PROTOCOL,                                              // protocol:        ir protocol\n    VINCENT_PULSE_LEN_MIN,                                              // pulse_1_len_min: minimum length of pulse with bit value 1\n    VINCENT_PULSE_LEN_MAX,                                              // pulse_1_len_max: maximum length of pulse with bit value 1\n    VINCENT_1_PAUSE_LEN_MIN,                                            // pause_1_len_min: minimum length of pause with bit value 1\n    VINCENT_1_PAUSE_LEN_MAX,                                            // pause_1_len_max: maximum length of pause with bit value 1\n    VINCENT_PULSE_LEN_MIN,                                              // pulse_0_len_min: minimum length of pulse with bit value 0\n    VINCENT_PULSE_LEN_MAX,                                              // pulse_0_len_max: maximum length of pulse with bit value 0\n    VINCENT_0_PAUSE_LEN_MIN,                                            // pause_0_len_min: minimum length of pause with bit value 0\n    VINCENT_0_PAUSE_LEN_MAX,                                            // pause_0_len_max: maximum length of pause with bit value 0\n    VINCENT_ADDRESS_OFFSET,                                             // address_offset:  address offset\n    VINCENT_ADDRESS_OFFSET + VINCENT_ADDRESS_LEN,                       // address_end:     end of address\n    VINCENT_COMMAND_OFFSET,                                             // command_offset:  command offset\n    VINCENT_COMMAND_OFFSET + VINCENT_COMMAND_LEN,                       // command_end:     end of command\n    VINCENT_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame\n    VINCENT_STOP_BIT,                                                   // stop_bit:        flag: frame has stop bit\n    VINCENT_LSB,                                                        // lsb_first:       flag: LSB first\n    VINCENT_FLAGS                                                       // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RECS80_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER recs80_param =\n{\n    IRMP_RECS80_PROTOCOL,                                               // protocol:        ir protocol\n    RECS80_PULSE_LEN_MIN,                                               // pulse_1_len_min: minimum length of pulse with bit value 1\n    RECS80_PULSE_LEN_MAX,                                               // pulse_1_len_max: maximum length of pulse with bit value 1\n    RECS80_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    RECS80_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    RECS80_PULSE_LEN_MIN,                                               // pulse_0_len_min: minimum length of pulse with bit value 0\n    RECS80_PULSE_LEN_MAX,                                               // pulse_0_len_max: maximum length of pulse with bit value 0\n    RECS80_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    RECS80_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    RECS80_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    RECS80_ADDRESS_OFFSET + RECS80_ADDRESS_LEN,                         // address_end:     end of address\n    RECS80_COMMAND_OFFSET,                                              // command_offset:  command offset\n    RECS80_COMMAND_OFFSET + RECS80_COMMAND_LEN,                         // command_end:     end of command\n    RECS80_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    RECS80_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    RECS80_LSB,                                                         // lsb_first:       flag: LSB first\n    RECS80_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rc5_param =\n{\n    IRMP_RC5_PROTOCOL,                                                  // protocol:        ir protocol\n    RC5_BIT_LEN_MIN,                                                    // pulse_1_len_min: here: minimum length of short pulse\n    RC5_BIT_LEN_MAX,                                                    // pulse_1_len_max: here: maximum length of short pulse\n    RC5_BIT_LEN_MIN,                                                    // pause_1_len_min: here: minimum length of short pause\n    RC5_BIT_LEN_MAX,                                                    // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    RC5_ADDRESS_OFFSET,                                                 // address_offset:  address offset\n    RC5_ADDRESS_OFFSET + RC5_ADDRESS_LEN,                               // address_end:     end of address\n    RC5_COMMAND_OFFSET,                                                 // command_offset:  command offset\n    RC5_COMMAND_OFFSET + RC5_COMMAND_LEN,                               // command_end:     end of command\n    RC5_COMPLETE_DATA_LEN,                                              // complete_len:    complete length of frame\n    RC5_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    RC5_LSB,                                                            // lsb_first:       flag: LSB first\n    RC5_FLAGS                                                           // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RCII_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rcii_param =\n{\n    IRMP_RCII_PROTOCOL,                                                 // protocol:        ir protocol\n    RCII_BIT_LEN_MIN,                                                   // pulse_1_len_min: here: minimum length of short pulse\n    RCII_BIT_LEN_MAX,                                                   // pulse_1_len_max: here: maximum length of short pulse\n    RCII_BIT_LEN_MIN,                                                   // pause_1_len_min: here: minimum length of short pause\n    RCII_BIT_LEN_MAX,                                                   // pause_1_len_max: here: maximum length of short pause\n    RCII_BIT_LEN_MIN,                                                                  // pulse_0_len_min: here: not used\n    RCII_BIT_LEN_MAX,                                                                  // pulse_0_len_max: here: not used\n    RCII_BIT_LEN_MIN,                                                                  // pause_0_len_min: here: not used\n    RCII_BIT_LEN_MAX,                                                                  // pause_0_len_max: here: not used\n    RCII_ADDRESS_OFFSET,                                                // address_offset:  address offset\n    RCII_ADDRESS_OFFSET + RCII_ADDRESS_LEN,                             // address_end:     end of address\n    RCII_COMMAND_OFFSET,                                                // command_offset:  command offset\n    RCII_COMMAND_OFFSET + RCII_COMMAND_LEN,                             // command_end:     end of command\n    RCII_COMPLETE_DATA_LEN,                                             // complete_len:    complete length of frame\n    RCII_STOP_BIT,                                                      // stop_bit:        flag: frame has stop bit\n    RCII_LSB,                                                           // lsb_first:       flag: LSB first\n    RCII_FLAGS                                                          // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_S100_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER s100_param =\n{\n    IRMP_S100_PROTOCOL,                                                 // protocol:        ir protocol\n    S100_BIT_LEN_MIN,                                                   // pulse_1_len_min: here: minimum length of short pulse\n    S100_BIT_LEN_MAX,                                                   // pulse_1_len_max: here: maximum length of short pulse\n    S100_BIT_LEN_MIN,                                                   // pause_1_len_min: here: minimum length of short pause\n    S100_BIT_LEN_MAX,                                                   // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    S100_ADDRESS_OFFSET,                                                // address_offset:  address offset\n    S100_ADDRESS_OFFSET + S100_ADDRESS_LEN,                             // address_end:     end of address\n    S100_COMMAND_OFFSET,                                                // command_offset:  command offset\n    S100_COMMAND_OFFSET + S100_COMMAND_LEN,                             // command_end:     end of command\n    S100_COMPLETE_DATA_LEN,                                             // complete_len:    complete length of frame\n    S100_STOP_BIT,                                                      // stop_bit:        flag: frame has stop bit\n    S100_LSB,                                                           // lsb_first:       flag: LSB first\n    S100_FLAGS                                                          // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER denon_param =\n{\n    IRMP_DENON_PROTOCOL,                                                // protocol:        ir protocol\n    DENON_PULSE_LEN_MIN,                                                // pulse_1_len_min: minimum length of pulse with bit value 1\n    DENON_PULSE_LEN_MAX,                                                // pulse_1_len_max: maximum length of pulse with bit value 1\n    DENON_1_PAUSE_LEN_MIN,                                              // pause_1_len_min: minimum length of pause with bit value 1\n    DENON_1_PAUSE_LEN_MAX,                                              // pause_1_len_max: maximum length of pause with bit value 1\n    DENON_PULSE_LEN_MIN,                                                // pulse_0_len_min: minimum length of pulse with bit value 0\n    DENON_PULSE_LEN_MAX,                                                // pulse_0_len_max: maximum length of pulse with bit value 0\n    DENON_0_PAUSE_LEN_MIN,                                              // pause_0_len_min: minimum length of pause with bit value 0\n    DENON_0_PAUSE_LEN_MAX,                                              // pause_0_len_max: maximum length of pause with bit value 0\n    DENON_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    DENON_ADDRESS_OFFSET + DENON_ADDRESS_LEN,                           // address_end:     end of address\n    DENON_COMMAND_OFFSET,                                               // command_offset:  command offset\n    DENON_COMMAND_OFFSET + DENON_COMMAND_LEN,                           // command_end:     end of command\n    DENON_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    DENON_STOP_BIT,                                                     // stop_bit:        flag: frame has stop bit\n    DENON_LSB,                                                          // lsb_first:       flag: LSB first\n    DENON_FLAGS                                                         // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rc6_param =\n{\n    IRMP_RC6_PROTOCOL,                                                  // protocol:        ir protocol\n\n    RC6_BIT_PULSE_LEN_MIN,                                              // pulse_1_len_min: here: minimum length of short pulse\n    RC6_BIT_PULSE_LEN_MAX,                                              // pulse_1_len_max: here: maximum length of short pulse\n    RC6_BIT_PAUSE_LEN_MIN,                                              // pause_1_len_min: here: minimum length of short pause\n    RC6_BIT_PAUSE_LEN_MAX,                                              // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    RC6_ADDRESS_OFFSET,                                                 // address_offset:  address offset\n    RC6_ADDRESS_OFFSET + RC6_ADDRESS_LEN,                               // address_end:     end of address\n    RC6_COMMAND_OFFSET,                                                 // command_offset:  command offset\n    RC6_COMMAND_OFFSET + RC6_COMMAND_LEN,                               // command_end:     end of command\n    RC6_COMPLETE_DATA_LEN_SHORT,                                        // complete_len:    complete length of frame\n    RC6_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    RC6_LSB,                                                            // lsb_first:       flag: LSB first\n    RC6_FLAGS                                                           // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER recs80ext_param =\n{\n    IRMP_RECS80EXT_PROTOCOL,                                            // protocol:        ir protocol\n    RECS80EXT_PULSE_LEN_MIN,                                            // pulse_1_len_min: minimum length of pulse with bit value 1\n    RECS80EXT_PULSE_LEN_MAX,                                            // pulse_1_len_max: maximum length of pulse with bit value 1\n    RECS80EXT_1_PAUSE_LEN_MIN,                                          // pause_1_len_min: minimum length of pause with bit value 1\n    RECS80EXT_1_PAUSE_LEN_MAX,                                          // pause_1_len_max: maximum length of pause with bit value 1\n    RECS80EXT_PULSE_LEN_MIN,                                            // pulse_0_len_min: minimum length of pulse with bit value 0\n    RECS80EXT_PULSE_LEN_MAX,                                            // pulse_0_len_max: maximum length of pulse with bit value 0\n    RECS80EXT_0_PAUSE_LEN_MIN,                                          // pause_0_len_min: minimum length of pause with bit value 0\n    RECS80EXT_0_PAUSE_LEN_MAX,                                          // pause_0_len_max: maximum length of pause with bit value 0\n    RECS80EXT_ADDRESS_OFFSET,                                           // address_offset:  address offset\n    RECS80EXT_ADDRESS_OFFSET + RECS80EXT_ADDRESS_LEN,                   // address_end:     end of address\n    RECS80EXT_COMMAND_OFFSET,                                           // command_offset:  command offset\n    RECS80EXT_COMMAND_OFFSET + RECS80EXT_COMMAND_LEN,                   // command_end:     end of command\n    RECS80EXT_COMPLETE_DATA_LEN,                                        // complete_len:    complete length of frame\n    RECS80EXT_STOP_BIT,                                                 // stop_bit:        flag: frame has stop bit\n    RECS80EXT_LSB,                                                      // lsb_first:       flag: LSB first\n    RECS80EXT_FLAGS                                                     // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER nubert_param =\n{\n    IRMP_NUBERT_PROTOCOL,                                               // protocol:        ir protocol\n    NUBERT_1_PULSE_LEN_MIN,                                             // pulse_1_len_min: minimum length of pulse with bit value 1\n    NUBERT_1_PULSE_LEN_MAX,                                             // pulse_1_len_max: maximum length of pulse with bit value 1\n    NUBERT_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    NUBERT_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    NUBERT_0_PULSE_LEN_MIN,                                             // pulse_0_len_min: minimum length of pulse with bit value 0\n    NUBERT_0_PULSE_LEN_MAX,                                             // pulse_0_len_max: maximum length of pulse with bit value 0\n    NUBERT_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    NUBERT_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    NUBERT_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    NUBERT_ADDRESS_OFFSET + NUBERT_ADDRESS_LEN,                         // address_end:     end of address\n    NUBERT_COMMAND_OFFSET,                                              // command_offset:  command offset\n    NUBERT_COMMAND_OFFSET + NUBERT_COMMAND_LEN,                         // command_end:     end of command\n    NUBERT_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    NUBERT_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    NUBERT_LSB,                                                         // lsb_first:       flag: LSB first\n    NUBERT_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_FAN_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER fan_param =\n{\n    IRMP_FAN_PROTOCOL,                                                  // protocol:        ir protocol\n    FAN_1_PULSE_LEN_MIN,                                                // pulse_1_len_min: minimum length of pulse with bit value 1\n    FAN_1_PULSE_LEN_MAX,                                                // pulse_1_len_max: maximum length of pulse with bit value 1\n    FAN_1_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    FAN_1_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    FAN_0_PULSE_LEN_MIN,                                                // pulse_0_len_min: minimum length of pulse with bit value 0\n    FAN_0_PULSE_LEN_MAX,                                                // pulse_0_len_max: maximum length of pulse with bit value 0\n    FAN_0_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    FAN_0_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    FAN_ADDRESS_OFFSET,                                                 // address_offset:  address offset\n    FAN_ADDRESS_OFFSET + FAN_ADDRESS_LEN,                               // address_end:     end of address\n    FAN_COMMAND_OFFSET,                                                 // command_offset:  command offset\n    FAN_COMMAND_OFFSET + FAN_COMMAND_LEN,                               // command_end:     end of command\n    FAN_COMPLETE_DATA_LEN,                                              // complete_len:    complete length of frame\n    FAN_STOP_BIT,                                                       // stop_bit:        flag: frame has NO stop bit\n    FAN_LSB,                                                            // lsb_first:       flag: LSB first\n    FAN_FLAGS                                                           // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER speaker_param =\n{\n    IRMP_SPEAKER_PROTOCOL,                                              // protocol:        ir protocol\n    SPEAKER_1_PULSE_LEN_MIN,                                            // pulse_1_len_min: minimum length of pulse with bit value 1\n    SPEAKER_1_PULSE_LEN_MAX,                                            // pulse_1_len_max: maximum length of pulse with bit value 1\n    SPEAKER_1_PAUSE_LEN_MIN,                                            // pause_1_len_min: minimum length of pause with bit value 1\n    SPEAKER_1_PAUSE_LEN_MAX,                                            // pause_1_len_max: maximum length of pause with bit value 1\n    SPEAKER_0_PULSE_LEN_MIN,                                            // pulse_0_len_min: minimum length of pulse with bit value 0\n    SPEAKER_0_PULSE_LEN_MAX,                                            // pulse_0_len_max: maximum length of pulse with bit value 0\n    SPEAKER_0_PAUSE_LEN_MIN,                                            // pause_0_len_min: minimum length of pause with bit value 0\n    SPEAKER_0_PAUSE_LEN_MAX,                                            // pause_0_len_max: maximum length of pause with bit value 0\n    SPEAKER_ADDRESS_OFFSET,                                             // address_offset:  address offset\n    SPEAKER_ADDRESS_OFFSET + SPEAKER_ADDRESS_LEN,                       // address_end:     end of address\n    SPEAKER_COMMAND_OFFSET,                                             // command_offset:  command offset\n    SPEAKER_COMMAND_OFFSET + SPEAKER_COMMAND_LEN,                       // command_end:     end of command\n    SPEAKER_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame\n    SPEAKER_STOP_BIT,                                                   // stop_bit:        flag: frame has stop bit\n    SPEAKER_LSB,                                                        // lsb_first:       flag: LSB first\n    SPEAKER_FLAGS                                                       // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER bang_olufsen_param =\n{\n    IRMP_BANG_OLUFSEN_PROTOCOL,                                         // protocol:        ir protocol\n    BANG_OLUFSEN_PULSE_LEN_MIN,                                         // pulse_1_len_min: minimum length of pulse with bit value 1\n    BANG_OLUFSEN_PULSE_LEN_MAX,                                         // pulse_1_len_max: maximum length of pulse with bit value 1\n    BANG_OLUFSEN_1_PAUSE_LEN_MIN,                                       // pause_1_len_min: minimum length of pause with bit value 1\n    BANG_OLUFSEN_1_PAUSE_LEN_MAX,                                       // pause_1_len_max: maximum length of pause with bit value 1\n    BANG_OLUFSEN_PULSE_LEN_MIN,                                         // pulse_0_len_min: minimum length of pulse with bit value 0\n    BANG_OLUFSEN_PULSE_LEN_MAX,                                         // pulse_0_len_max: maximum length of pulse with bit value 0\n    BANG_OLUFSEN_0_PAUSE_LEN_MIN,                                       // pause_0_len_min: minimum length of pause with bit value 0\n    BANG_OLUFSEN_0_PAUSE_LEN_MAX,                                       // pause_0_len_max: maximum length of pause with bit value 0\n    BANG_OLUFSEN_ADDRESS_OFFSET,                                        // address_offset:  address offset\n    BANG_OLUFSEN_ADDRESS_OFFSET + BANG_OLUFSEN_ADDRESS_LEN,             // address_end:     end of address\n    BANG_OLUFSEN_COMMAND_OFFSET,                                        // command_offset:  command offset\n    BANG_OLUFSEN_COMMAND_OFFSET + BANG_OLUFSEN_COMMAND_LEN,             // command_end:     end of command\n    BANG_OLUFSEN_COMPLETE_DATA_LEN,                                     // complete_len:    complete length of frame\n    BANG_OLUFSEN_STOP_BIT,                                              // stop_bit:        flag: frame has stop bit\n    BANG_OLUFSEN_LSB,                                                   // lsb_first:       flag: LSB first\n    BANG_OLUFSEN_FLAGS                                                  // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1\n\nstatic uint_fast8_t first_bit;\n\nstatic const PROGMEM IRMP_PARAMETER grundig_param =\n{\n    IRMP_GRUNDIG_PROTOCOL,                                              // protocol:        ir protocol\n\n    GRUNDIG_NOKIA_IR60_BIT_LEN_MIN,                                     // pulse_1_len_min: here: minimum length of short pulse\n    GRUNDIG_NOKIA_IR60_BIT_LEN_MAX,                                     // pulse_1_len_max: here: maximum length of short pulse\n    GRUNDIG_NOKIA_IR60_BIT_LEN_MIN,                                     // pause_1_len_min: here: minimum length of short pause\n    GRUNDIG_NOKIA_IR60_BIT_LEN_MAX,                                     // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    GRUNDIG_ADDRESS_OFFSET,                                             // address_offset:  address offset\n    GRUNDIG_ADDRESS_OFFSET + GRUNDIG_ADDRESS_LEN,                       // address_end:     end of address\n    GRUNDIG_COMMAND_OFFSET,                                             // command_offset:  command offset\n    GRUNDIG_COMMAND_OFFSET + GRUNDIG_COMMAND_LEN + 1,                   // command_end:     end of command (USE 1 bit MORE to STORE NOKIA DATA!)\n    NOKIA_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame, here: NOKIA instead of GRUNDIG!\n    GRUNDIG_NOKIA_IR60_STOP_BIT,                                        // stop_bit:        flag: frame has stop bit\n    GRUNDIG_NOKIA_IR60_LSB,                                             // lsb_first:       flag: LSB first\n    GRUNDIG_NOKIA_IR60_FLAGS                                            // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER ruwido_param =\n{\n    IRMP_RUWIDO_PROTOCOL,                                               // protocol:        ir protocol\n    SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MIN,                                // pulse_1_len_min: here: minimum length of short pulse\n    SIEMENS_OR_RUWIDO_BIT_PULSE_LEN_MAX,                                // pulse_1_len_max: here: maximum length of short pulse\n    SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MIN,                                // pause_1_len_min: here: minimum length of short pause\n    SIEMENS_OR_RUWIDO_BIT_PAUSE_LEN_MAX,                                // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    RUWIDO_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    RUWIDO_ADDRESS_OFFSET + RUWIDO_ADDRESS_LEN,                         // address_end:     end of address\n    RUWIDO_COMMAND_OFFSET,                                              // command_offset:  command offset\n    RUWIDO_COMMAND_OFFSET + RUWIDO_COMMAND_LEN,                         // command_end:     end of command\n    SIEMENS_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame, here: SIEMENS instead of RUWIDO!\n    SIEMENS_OR_RUWIDO_STOP_BIT,                                         // stop_bit:        flag: frame has stop bit\n    SIEMENS_OR_RUWIDO_LSB,                                              // lsb_first:       flag: LSB first\n    SIEMENS_OR_RUWIDO_FLAGS                                             // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER fdc_param =\n{\n    IRMP_FDC_PROTOCOL,                                                  // protocol:        ir protocol\n    FDC_PULSE_LEN_MIN,                                                  // pulse_1_len_min: minimum length of pulse with bit value 1\n    FDC_PULSE_LEN_MAX,                                                  // pulse_1_len_max: maximum length of pulse with bit value 1\n    FDC_1_PAUSE_LEN_MIN,                                                // pause_1_len_min: minimum length of pause with bit value 1\n    FDC_1_PAUSE_LEN_MAX,                                                // pause_1_len_max: maximum length of pause with bit value 1\n    FDC_PULSE_LEN_MIN,                                                  // pulse_0_len_min: minimum length of pulse with bit value 0\n    FDC_PULSE_LEN_MAX,                                                  // pulse_0_len_max: maximum length of pulse with bit value 0\n    FDC_0_PAUSE_LEN_MIN,                                                // pause_0_len_min: minimum length of pause with bit value 0\n    FDC_0_PAUSE_LEN_MAX,                                                // pause_0_len_max: maximum length of pause with bit value 0\n    FDC_ADDRESS_OFFSET,                                                 // address_offset:  address offset\n    FDC_ADDRESS_OFFSET + FDC_ADDRESS_LEN,                               // address_end:     end of address\n    FDC_COMMAND_OFFSET,                                                 // command_offset:  command offset\n    FDC_COMMAND_OFFSET + FDC_COMMAND_LEN,                               // command_end:     end of command\n    FDC_COMPLETE_DATA_LEN,                                              // complete_len:    complete length of frame\n    FDC_STOP_BIT,                                                       // stop_bit:        flag: frame has stop bit\n    FDC_LSB,                                                            // lsb_first:       flag: LSB first\n    FDC_FLAGS                                                           // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rccar_param =\n{\n    IRMP_RCCAR_PROTOCOL,                                                // protocol:        ir protocol\n    RCCAR_PULSE_LEN_MIN,                                                // pulse_1_len_min: minimum length of pulse with bit value 1\n    RCCAR_PULSE_LEN_MAX,                                                // pulse_1_len_max: maximum length of pulse with bit value 1\n    RCCAR_1_PAUSE_LEN_MIN,                                              // pause_1_len_min: minimum length of pause with bit value 1\n    RCCAR_1_PAUSE_LEN_MAX,                                              // pause_1_len_max: maximum length of pause with bit value 1\n    RCCAR_PULSE_LEN_MIN,                                                // pulse_0_len_min: minimum length of pulse with bit value 0\n    RCCAR_PULSE_LEN_MAX,                                                // pulse_0_len_max: maximum length of pulse with bit value 0\n    RCCAR_0_PAUSE_LEN_MIN,                                              // pause_0_len_min: minimum length of pause with bit value 0\n    RCCAR_0_PAUSE_LEN_MAX,                                              // pause_0_len_max: maximum length of pause with bit value 0\n    RCCAR_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    RCCAR_ADDRESS_OFFSET + RCCAR_ADDRESS_LEN,                           // address_end:     end of address\n    RCCAR_COMMAND_OFFSET,                                               // command_offset:  command offset\n    RCCAR_COMMAND_OFFSET + RCCAR_COMMAND_LEN,                           // command_end:     end of command\n    RCCAR_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    RCCAR_STOP_BIT,                                                     // stop_bit:        flag: frame has stop bit\n    RCCAR_LSB,                                                          // lsb_first:       flag: LSB first\n    RCCAR_FLAGS                                                         // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_NIKON_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER nikon_param =\n{\n    IRMP_NIKON_PROTOCOL,                                                // protocol:        ir protocol\n    NIKON_PULSE_LEN_MIN,                                                // pulse_1_len_min: minimum length of pulse with bit value 1\n    NIKON_PULSE_LEN_MAX,                                                // pulse_1_len_max: maximum length of pulse with bit value 1\n    NIKON_1_PAUSE_LEN_MIN,                                              // pause_1_len_min: minimum length of pause with bit value 1\n    NIKON_1_PAUSE_LEN_MAX,                                              // pause_1_len_max: maximum length of pause with bit value 1\n    NIKON_PULSE_LEN_MIN,                                                // pulse_0_len_min: minimum length of pulse with bit value 0\n    NIKON_PULSE_LEN_MAX,                                                // pulse_0_len_max: maximum length of pulse with bit value 0\n    NIKON_0_PAUSE_LEN_MIN,                                              // pause_0_len_min: minimum length of pause with bit value 0\n    NIKON_0_PAUSE_LEN_MAX,                                              // pause_0_len_max: maximum length of pause with bit value 0\n    NIKON_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    NIKON_ADDRESS_OFFSET + NIKON_ADDRESS_LEN,                           // address_end:     end of address\n    NIKON_COMMAND_OFFSET,                                               // command_offset:  command offset\n    NIKON_COMMAND_OFFSET + NIKON_COMMAND_LEN,                           // command_end:     end of command\n    NIKON_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    NIKON_STOP_BIT,                                                     // stop_bit:        flag: frame has stop bit\n    NIKON_LSB,                                                          // lsb_first:       flag: LSB first\n    NIKON_FLAGS                                                         // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER kathrein_param =\n{\n    IRMP_KATHREIN_PROTOCOL,                                             // protocol:        ir protocol\n    KATHREIN_1_PULSE_LEN_MIN,                                           // pulse_1_len_min: minimum length of pulse with bit value 1\n    KATHREIN_1_PULSE_LEN_MAX,                                           // pulse_1_len_max: maximum length of pulse with bit value 1\n    KATHREIN_1_PAUSE_LEN_MIN,                                           // pause_1_len_min: minimum length of pause with bit value 1\n    KATHREIN_1_PAUSE_LEN_MAX,                                           // pause_1_len_max: maximum length of pause with bit value 1\n    KATHREIN_0_PULSE_LEN_MIN,                                           // pulse_0_len_min: minimum length of pulse with bit value 0\n    KATHREIN_0_PULSE_LEN_MAX,                                           // pulse_0_len_max: maximum length of pulse with bit value 0\n    KATHREIN_0_PAUSE_LEN_MIN,                                           // pause_0_len_min: minimum length of pause with bit value 0\n    KATHREIN_0_PAUSE_LEN_MAX,                                           // pause_0_len_max: maximum length of pause with bit value 0\n    KATHREIN_ADDRESS_OFFSET,                                            // address_offset:  address offset\n    KATHREIN_ADDRESS_OFFSET + KATHREIN_ADDRESS_LEN,                     // address_end:     end of address\n    KATHREIN_COMMAND_OFFSET,                                            // command_offset:  command offset\n    KATHREIN_COMMAND_OFFSET + KATHREIN_COMMAND_LEN,                     // command_end:     end of command\n    KATHREIN_COMPLETE_DATA_LEN,                                         // complete_len:    complete length of frame\n    KATHREIN_STOP_BIT,                                                  // stop_bit:        flag: frame has stop bit\n    KATHREIN_LSB,                                                       // lsb_first:       flag: LSB first\n    KATHREIN_FLAGS                                                      // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER netbox_param =\n{\n    IRMP_NETBOX_PROTOCOL,                                               // protocol:        ir protocol\n    NETBOX_PULSE_LEN,                                                   // pulse_1_len_min: minimum length of pulse with bit value 1, here: exact value\n    NETBOX_PULSE_REST_LEN,                                              // pulse_1_len_max: maximum length of pulse with bit value 1, here: rest value\n    NETBOX_PAUSE_LEN,                                                   // pause_1_len_min: minimum length of pause with bit value 1, here: exact value\n    NETBOX_PAUSE_REST_LEN,                                              // pause_1_len_max: maximum length of pause with bit value 1, here: rest value\n    NETBOX_PULSE_LEN,                                                   // pulse_0_len_min: minimum length of pulse with bit value 0, here: exact value\n    NETBOX_PULSE_REST_LEN,                                              // pulse_0_len_max: maximum length of pulse with bit value 0, here: rest value\n    NETBOX_PAUSE_LEN,                                                   // pause_0_len_min: minimum length of pause with bit value 0, here: exact value\n    NETBOX_PAUSE_REST_LEN,                                              // pause_0_len_max: maximum length of pause with bit value 0, here: rest value\n    NETBOX_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    NETBOX_ADDRESS_OFFSET + NETBOX_ADDRESS_LEN,                         // address_end:     end of address\n    NETBOX_COMMAND_OFFSET,                                              // command_offset:  command offset\n    NETBOX_COMMAND_OFFSET + NETBOX_COMMAND_LEN,                         // command_end:     end of command\n    NETBOX_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    NETBOX_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    NETBOX_LSB,                                                         // lsb_first:       flag: LSB first\n    NETBOX_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER lego_param =\n{\n    IRMP_LEGO_PROTOCOL,                                                 // protocol:        ir protocol\n    LEGO_PULSE_LEN_MIN,                                                 // pulse_1_len_min: minimum length of pulse with bit value 1\n    LEGO_PULSE_LEN_MAX,                                                 // pulse_1_len_max: maximum length of pulse with bit value 1\n    LEGO_1_PAUSE_LEN_MIN,                                               // pause_1_len_min: minimum length of pause with bit value 1\n    LEGO_1_PAUSE_LEN_MAX,                                               // pause_1_len_max: maximum length of pause with bit value 1\n    LEGO_PULSE_LEN_MIN,                                                 // pulse_0_len_min: minimum length of pulse with bit value 0\n    LEGO_PULSE_LEN_MAX,                                                 // pulse_0_len_max: maximum length of pulse with bit value 0\n    LEGO_0_PAUSE_LEN_MIN,                                               // pause_0_len_min: minimum length of pause with bit value 0\n    LEGO_0_PAUSE_LEN_MAX,                                               // pause_0_len_max: maximum length of pause with bit value 0\n    LEGO_ADDRESS_OFFSET,                                                // address_offset:  address offset\n    LEGO_ADDRESS_OFFSET + LEGO_ADDRESS_LEN,                             // address_end:     end of address\n    LEGO_COMMAND_OFFSET,                                                // command_offset:  command offset\n    LEGO_COMMAND_OFFSET + LEGO_COMMAND_LEN,                             // command_end:     end of command\n    LEGO_COMPLETE_DATA_LEN,                                             // complete_len:    complete length of frame\n    LEGO_STOP_BIT,                                                      // stop_bit:        flag: frame has stop bit\n    LEGO_LSB,                                                           // lsb_first:       flag: LSB first\n    LEGO_FLAGS                                                          // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_IRMP16_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER irmp16_param =\n{\n    IRMP_IRMP16_PROTOCOL,                                               // protocol:        ir protocol\n    IRMP16_PULSE_LEN_MIN,                                               // pulse_1_len_min: minimum length of pulse with bit value 1\n    IRMP16_PULSE_LEN_MAX,                                               // pulse_1_len_max: maximum length of pulse with bit value 1\n    IRMP16_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    IRMP16_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    IRMP16_PULSE_LEN_MIN,                                               // pulse_0_len_min: minimum length of pulse with bit value 0\n    IRMP16_PULSE_LEN_MAX,                                               // pulse_0_len_max: maximum length of pulse with bit value 0\n    IRMP16_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    IRMP16_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    IRMP16_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    IRMP16_ADDRESS_OFFSET + IRMP16_ADDRESS_LEN,                         // address_end:     end of address\n    IRMP16_COMMAND_OFFSET,                                              // command_offset:  command offset\n    IRMP16_COMMAND_OFFSET + IRMP16_COMMAND_LEN,                         // command_end:     end of command\n    IRMP16_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    IRMP16_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    IRMP16_LSB,                                                         // lsb_first:       flag: LSB first\n    IRMP16_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_GREE_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER gree_param =\n{\n    IRMP_GREE_PROTOCOL,                                               // protocol:        ir protocol\n    GREE_PULSE_LEN_MIN,                                               // pulse_1_len_min: minimum length of pulse with bit value 1\n    GREE_PULSE_LEN_MAX,                                               // pulse_1_len_max: maximum length of pulse with bit value 1\n    GREE_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    GREE_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    GREE_PULSE_LEN_MIN,                                               // pulse_0_len_min: minimum length of pulse with bit value 0\n    GREE_PULSE_LEN_MAX,                                               // pulse_0_len_max: maximum length of pulse with bit value 0\n    GREE_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    GREE_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    GREE_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    GREE_ADDRESS_OFFSET + GREE_ADDRESS_LEN,                         // address_end:     end of address\n    GREE_COMMAND_OFFSET,                                              // command_offset:  command offset\n    GREE_COMMAND_OFFSET + GREE_COMMAND_LEN,                         // command_end:     end of command\n    GREE_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    GREE_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    GREE_LSB,                                                         // lsb_first:       flag: LSB first\n    GREE_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER thomson_param =\n{\n    IRMP_THOMSON_PROTOCOL,                                              // protocol:        ir protocol\n    THOMSON_PULSE_LEN_MIN,                                              // pulse_1_len_min: minimum length of pulse with bit value 1\n    THOMSON_PULSE_LEN_MAX,                                              // pulse_1_len_max: maximum length of pulse with bit value 1\n    THOMSON_1_PAUSE_LEN_MIN,                                            // pause_1_len_min: minimum length of pause with bit value 1\n    THOMSON_1_PAUSE_LEN_MAX,                                            // pause_1_len_max: maximum length of pause with bit value 1\n    THOMSON_PULSE_LEN_MIN,                                              // pulse_0_len_min: minimum length of pulse with bit value 0\n    THOMSON_PULSE_LEN_MAX,                                              // pulse_0_len_max: maximum length of pulse with bit value 0\n    THOMSON_0_PAUSE_LEN_MIN,                                            // pause_0_len_min: minimum length of pause with bit value 0\n    THOMSON_0_PAUSE_LEN_MAX,                                            // pause_0_len_max: maximum length of pause with bit value 0\n    THOMSON_ADDRESS_OFFSET,                                             // address_offset:  address offset\n    THOMSON_ADDRESS_OFFSET + THOMSON_ADDRESS_LEN,                       // address_end:     end of address\n    THOMSON_COMMAND_OFFSET,                                             // command_offset:  command offset\n    THOMSON_COMMAND_OFFSET + THOMSON_COMMAND_LEN,                       // command_end:     end of command\n    THOMSON_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame\n    THOMSON_STOP_BIT,                                                   // stop_bit:        flag: frame has stop bit\n    THOMSON_LSB,                                                        // lsb_first:       flag: LSB first\n    THOMSON_FLAGS                                                       // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_BOSE_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER bose_param =\n{\n    IRMP_BOSE_PROTOCOL,                                                 // protocol:        ir protocol\n    BOSE_PULSE_LEN_MIN,                                                 // pulse_1_len_min: minimum length of pulse with bit value 1\n    BOSE_PULSE_LEN_MAX,                                                 // pulse_1_len_max: maximum length of pulse with bit value 1\n    BOSE_1_PAUSE_LEN_MIN,                                               // pause_1_len_min: minimum length of pause with bit value 1\n    BOSE_1_PAUSE_LEN_MAX,                                               // pause_1_len_max: maximum length of pause with bit value 1\n    BOSE_PULSE_LEN_MIN,                                                 // pulse_0_len_min: minimum length of pulse with bit value 0\n    BOSE_PULSE_LEN_MAX,                                                 // pulse_0_len_max: maximum length of pulse with bit value 0\n    BOSE_0_PAUSE_LEN_MIN,                                               // pause_0_len_min: minimum length of pause with bit value 0\n    BOSE_0_PAUSE_LEN_MAX,                                               // pause_0_len_max: maximum length of pause with bit value 0\n    BOSE_ADDRESS_OFFSET,                                                // address_offset:  address offset\n    BOSE_ADDRESS_OFFSET + BOSE_ADDRESS_LEN,                             // address_end:     end of address\n    BOSE_COMMAND_OFFSET,                                                // command_offset:  command offset\n    BOSE_COMMAND_OFFSET + BOSE_COMMAND_LEN,                             // command_end:     end of command\n    BOSE_COMPLETE_DATA_LEN,                                             // complete_len:    complete length of frame\n    BOSE_STOP_BIT,                                                      // stop_bit:        flag: frame has stop bit\n    BOSE_LSB,                                                           // lsb_first:       flag: LSB first\n    BOSE_FLAGS                                                          // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER a1tvbox_param =\n{\n    IRMP_A1TVBOX_PROTOCOL,                                              // protocol:        ir protocol\n\n    A1TVBOX_BIT_PULSE_LEN_MIN,                                          // pulse_1_len_min: here: minimum length of short pulse\n    A1TVBOX_BIT_PULSE_LEN_MAX,                                          // pulse_1_len_max: here: maximum length of short pulse\n    A1TVBOX_BIT_PAUSE_LEN_MIN,                                          // pause_1_len_min: here: minimum length of short pause\n    A1TVBOX_BIT_PAUSE_LEN_MAX,                                          // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    A1TVBOX_ADDRESS_OFFSET,                                             // address_offset:  address offset\n    A1TVBOX_ADDRESS_OFFSET + A1TVBOX_ADDRESS_LEN,                       // address_end:     end of address\n    A1TVBOX_COMMAND_OFFSET,                                             // command_offset:  command offset\n    A1TVBOX_COMMAND_OFFSET + A1TVBOX_COMMAND_LEN,                       // command_end:     end of command\n    A1TVBOX_COMPLETE_DATA_LEN,                                          // complete_len:    complete length of frame\n    A1TVBOX_STOP_BIT,                                                   // stop_bit:        flag: frame has stop bit\n    A1TVBOX_LSB,                                                        // lsb_first:       flag: LSB first\n    A1TVBOX_FLAGS                                                       // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER merlin_param =\n{\n    IRMP_MERLIN_PROTOCOL,                                               // protocol:        ir protocol\n\n    MERLIN_BIT_PULSE_LEN_MIN,                                           // pulse_1_len_min: here: minimum length of short pulse\n    MERLIN_BIT_PULSE_LEN_MAX,                                           // pulse_1_len_max: here: maximum length of short pulse\n    MERLIN_BIT_PAUSE_LEN_MIN,                                           // pause_1_len_min: here: minimum length of short pause\n    MERLIN_BIT_PAUSE_LEN_MAX,                                           // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    MERLIN_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    MERLIN_ADDRESS_OFFSET + MERLIN_ADDRESS_LEN,                         // address_end:     end of address\n    MERLIN_COMMAND_OFFSET,                                              // command_offset:  command offset\n    MERLIN_COMMAND_OFFSET + MERLIN_COMMAND_LEN,                         // command_end:     end of command\n    MERLIN_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    MERLIN_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    MERLIN_LSB,                                                         // lsb_first:       flag: LSB first\n    MERLIN_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER ortek_param =\n{\n    IRMP_ORTEK_PROTOCOL,                                                // protocol:        ir protocol\n\n    ORTEK_BIT_PULSE_LEN_MIN,                                            // pulse_1_len_min: here: minimum length of short pulse\n    ORTEK_BIT_PULSE_LEN_MAX,                                            // pulse_1_len_max: here: maximum length of short pulse\n    ORTEK_BIT_PAUSE_LEN_MIN,                                            // pause_1_len_min: here: minimum length of short pause\n    ORTEK_BIT_PAUSE_LEN_MAX,                                            // pause_1_len_max: here: maximum length of short pause\n    0,                                                                  // pulse_0_len_min: here: not used\n    0,                                                                  // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    ORTEK_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    ORTEK_ADDRESS_OFFSET + ORTEK_ADDRESS_LEN,                           // address_end:     end of address\n    ORTEK_COMMAND_OFFSET,                                               // command_offset:  command offset\n    ORTEK_COMMAND_OFFSET + ORTEK_COMMAND_LEN,                           // command_end:     end of command\n    ORTEK_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    ORTEK_STOP_BIT,                                                     // stop_bit:        flag: frame has stop bit\n    ORTEK_LSB,                                                          // lsb_first:       flag: LSB first\n    ORTEK_FLAGS                                                         // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER roomba_param =\n{\n    IRMP_ROOMBA_PROTOCOL,                                               // protocol:        ir protocol\n    ROOMBA_1_PULSE_LEN_MIN,                                             // pulse_1_len_min: minimum length of pulse with bit value 1\n    ROOMBA_1_PULSE_LEN_MAX,                                             // pulse_1_len_max: maximum length of pulse with bit value 1\n    ROOMBA_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    ROOMBA_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    ROOMBA_0_PULSE_LEN_MIN,                                             // pulse_0_len_min: minimum length of pulse with bit value 0\n    ROOMBA_0_PULSE_LEN_MAX,                                             // pulse_0_len_max: maximum length of pulse with bit value 0\n    ROOMBA_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    ROOMBA_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    ROOMBA_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    ROOMBA_ADDRESS_OFFSET + ROOMBA_ADDRESS_LEN,                         // address_end:     end of address\n    ROOMBA_COMMAND_OFFSET,                                              // command_offset:  command offset\n    ROOMBA_COMMAND_OFFSET + ROOMBA_COMMAND_LEN,                         // command_end:     end of command\n    ROOMBA_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    ROOMBA_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    ROOMBA_LSB,                                                         // lsb_first:       flag: LSB first\n    ROOMBA_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RCMM_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rcmm_param =\n{\n    IRMP_RCMM32_PROTOCOL,                                               // protocol:        ir protocol\n\n    RCMM32_BIT_PULSE_LEN_MIN,                                           // pulse_1_len_min: here: minimum length of short pulse\n    RCMM32_BIT_PULSE_LEN_MAX,                                           // pulse_1_len_max: here: maximum length of short pulse\n    0,                                                                  // pause_1_len_min: here: minimum length of short pause\n    0,                                                                  // pause_1_len_max: here: maximum length of short pause\n    RCMM32_BIT_PULSE_LEN_MIN,                                           // pulse_0_len_min: here: not used\n    RCMM32_BIT_PULSE_LEN_MAX,                                           // pulse_0_len_max: here: not used\n    0,                                                                  // pause_0_len_min: here: not used\n    0,                                                                  // pause_0_len_max: here: not used\n    RCMM32_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    RCMM32_ADDRESS_OFFSET + RCMM32_ADDRESS_LEN,                         // address_end:     end of address\n    RCMM32_COMMAND_OFFSET,                                              // command_offset:  command offset\n    RCMM32_COMMAND_OFFSET + RCMM32_COMMAND_LEN,                         // command_end:     end of command\n    RCMM32_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    RCMM32_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    RCMM32_LSB,                                                         // lsb_first:       flag: LSB first\n    RCMM32_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER pentax_param =\n{\n    IRMP_PENTAX_PROTOCOL,                                               // protocol:        ir protocol\n    PENTAX_PULSE_LEN_MIN,                                               // pulse_1_len_min: minimum length of pulse with bit value 1\n    PENTAX_PULSE_LEN_MAX,                                               // pulse_1_len_max: maximum length of pulse with bit value 1\n    PENTAX_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    PENTAX_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    PENTAX_PULSE_LEN_MIN,                                               // pulse_0_len_min: minimum length of pulse with bit value 0\n    PENTAX_PULSE_LEN_MAX,                                               // pulse_0_len_max: maximum length of pulse with bit value 0\n    PENTAX_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    PENTAX_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    PENTAX_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    PENTAX_ADDRESS_OFFSET + PENTAX_ADDRESS_LEN,                         // address_end:     end of address\n    PENTAX_COMMAND_OFFSET,                                              // command_offset:  command offset\n    PENTAX_COMMAND_OFFSET + PENTAX_COMMAND_LEN,                         // command_end:     end of command\n    PENTAX_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    PENTAX_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    PENTAX_LSB,                                                         // lsb_first:       flag: LSB first\n    PENTAX_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_ACP24_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER acp24_param =\n{\n    IRMP_ACP24_PROTOCOL,                                                // protocol:        ir protocol\n    ACP24_PULSE_LEN_MIN,                                                // pulse_1_len_min: minimum length of pulse with bit value 1\n    ACP24_PULSE_LEN_MAX,                                                // pulse_1_len_max: maximum length of pulse with bit value 1\n    ACP24_1_PAUSE_LEN_MIN,                                              // pause_1_len_min: minimum length of pause with bit value 1\n    ACP24_1_PAUSE_LEN_MAX,                                              // pause_1_len_max: maximum length of pause with bit value 1\n    ACP24_PULSE_LEN_MIN,                                                // pulse_0_len_min: minimum length of pulse with bit value 0\n    ACP24_PULSE_LEN_MAX,                                                // pulse_0_len_max: maximum length of pulse with bit value 0\n    ACP24_0_PAUSE_LEN_MIN,                                              // pause_0_len_min: minimum length of pause with bit value 0\n    ACP24_0_PAUSE_LEN_MAX,                                              // pause_0_len_max: maximum length of pause with bit value 0\n    ACP24_ADDRESS_OFFSET,                                               // address_offset:  address offset\n    ACP24_ADDRESS_OFFSET + ACP24_ADDRESS_LEN,                           // address_end:     end of address\n    ACP24_COMMAND_OFFSET,                                               // command_offset:  command offset\n    ACP24_COMMAND_OFFSET + ACP24_COMMAND_LEN,                           // command_end:     end of command\n    ACP24_COMPLETE_DATA_LEN,                                            // complete_len:    complete length of frame\n    ACP24_STOP_BIT,                                                     // stop_bit:        flag: frame has stop bit\n    ACP24_LSB,                                                          // lsb_first:       flag: LSB first\n    ACP24_FLAGS                                                         // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_METZ_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER metz_param =\n{\n    IRMP_METZ_PROTOCOL,                                                 // protocol:        ir protocol\n    METZ_PULSE_LEN_MIN,                                                 // pulse_1_len_min: minimum length of pulse with bit value 1\n    METZ_PULSE_LEN_MAX,                                                 // pulse_1_len_max: maximum length of pulse with bit value 1\n    METZ_1_PAUSE_LEN_MIN,                                               // pause_1_len_min: minimum length of pause with bit value 1\n    METZ_1_PAUSE_LEN_MAX,                                               // pause_1_len_max: maximum length of pause with bit value 1\n    METZ_PULSE_LEN_MIN,                                                 // pulse_0_len_min: minimum length of pulse with bit value 0\n    METZ_PULSE_LEN_MAX,                                                 // pulse_0_len_max: maximum length of pulse with bit value 0\n    METZ_0_PAUSE_LEN_MIN,                                               // pause_0_len_min: minimum length of pause with bit value 0\n    METZ_0_PAUSE_LEN_MAX,                                               // pause_0_len_max: maximum length of pause with bit value 0\n    METZ_ADDRESS_OFFSET,                                                // address_offset:  address offset\n    METZ_ADDRESS_OFFSET + METZ_ADDRESS_LEN,                             // address_end:     end of address\n    METZ_COMMAND_OFFSET,                                                // command_offset:  command offset\n    METZ_COMMAND_OFFSET + METZ_COMMAND_LEN,                             // command_end:     end of command\n    METZ_COMPLETE_DATA_LEN,                                             // complete_len:    complete length of frame\n    METZ_STOP_BIT,                                                      // stop_bit:        flag: frame has stop bit\n    METZ_LSB,                                                           // lsb_first:       flag: LSB first\n    METZ_FLAGS                                                          // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rf_gen24_param =\n{\n    RF_GEN24_PROTOCOL,                                                  // protocol:        ir protocol\n\n    RF_GEN24_1_PULSE_LEN_MIN,                                           // pulse_1_len_min: minimum length of pulse with bit value 1\n    RF_GEN24_1_PULSE_LEN_MAX,                                           // pulse_1_len_max: maximum length of pulse with bit value 1\n    RF_GEN24_1_PAUSE_LEN_MIN,                                           // pause_1_len_min: minimum length of pause with bit value 1\n    RF_GEN24_1_PAUSE_LEN_MAX,                                           // pause_1_len_max: maximum length of pause with bit value 1\n    RF_GEN24_0_PULSE_LEN_MIN,                                           // pulse_0_len_min: minimum length of pulse with bit value 0\n    RF_GEN24_0_PULSE_LEN_MAX,                                           // pulse_0_len_max: maximum length of pulse with bit value 0\n    RF_GEN24_0_PAUSE_LEN_MIN,                                           // pause_0_len_min: minimum length of pause with bit value 0\n    RF_GEN24_0_PAUSE_LEN_MAX,                                           // pause_0_len_max: maximum length of pause with bit value 0\n    RF_GEN24_ADDRESS_OFFSET,                                            // address_offset:  address offset\n    RF_GEN24_ADDRESS_OFFSET + RF_GEN24_ADDRESS_LEN,                     // address_end:     end of address\n    RF_GEN24_COMMAND_OFFSET,                                            // command_offset:  command offset\n    RF_GEN24_COMMAND_OFFSET + RF_GEN24_COMMAND_LEN,                     // command_end:     end of command\n    RF_GEN24_COMPLETE_DATA_LEN,                                         // complete_len:    complete length of frame\n    RF_GEN24_STOP_BIT,                                                  // stop_bit:        flag: frame has stop bit\n    RF_GEN24_LSB,                                                       // lsb_first:       flag: LSB first\n    RF_GEN24_FLAGS                                                      // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RF_X10_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rf_x10_param =\n{\n    RF_X10_PROTOCOL,                                                    // protocol:        ir protocol\n\n    RF_X10_1_PULSE_LEN_MIN,                                             // pulse_1_len_min: minimum length of pulse with bit value 1\n    RF_X10_1_PULSE_LEN_MAX,                                             // pulse_1_len_max: maximum length of pulse with bit value 1\n    RF_X10_1_PAUSE_LEN_MIN,                                             // pause_1_len_min: minimum length of pause with bit value 1\n    RF_X10_1_PAUSE_LEN_MAX,                                             // pause_1_len_max: maximum length of pause with bit value 1\n    RF_X10_0_PULSE_LEN_MIN,                                             // pulse_0_len_min: minimum length of pulse with bit value 0\n    RF_X10_0_PULSE_LEN_MAX,                                             // pulse_0_len_max: maximum length of pulse with bit value 0\n    RF_X10_0_PAUSE_LEN_MIN,                                             // pause_0_len_min: minimum length of pause with bit value 0\n    RF_X10_0_PAUSE_LEN_MAX,                                             // pause_0_len_max: maximum length of pause with bit value 0\n    RF_X10_ADDRESS_OFFSET,                                              // address_offset:  address offset\n    RF_X10_ADDRESS_OFFSET + RF_X10_ADDRESS_LEN,                         // address_end:     end of address\n    RF_X10_COMMAND_OFFSET,                                              // command_offset:  command offset\n    RF_X10_COMMAND_OFFSET + RF_X10_COMMAND_LEN,                         // command_end:     end of command\n    RF_X10_COMPLETE_DATA_LEN,                                           // complete_len:    complete length of frame\n    RF_X10_STOP_BIT,                                                    // stop_bit:        flag: frame has stop bit\n    RF_X10_LSB,                                                         // lsb_first:       flag: LSB first\n    RF_X10_FLAGS                                                        // flags:           some flags\n};\n\n#endif\n\n#if IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n\nstatic const PROGMEM IRMP_PARAMETER rf_medion_param =\n{\n    RF_MEDION_PROTOCOL,                                                 // protocol:        ir protocol\n\n    RF_MEDION_1_PULSE_LEN_MIN,                                          // pulse_1_len_min: minimum length of pulse with bit value 1\n    RF_MEDION_1_PULSE_LEN_MAX,                                          // pulse_1_len_max: maximum length of pulse with bit value 1\n    RF_MEDION_1_PAUSE_LEN_MIN,                                          // pause_1_len_min: minimum length of pause with bit value 1\n    RF_MEDION_1_PAUSE_LEN_MAX,                                          // pause_1_len_max: maximum length of pause with bit value 1\n    RF_MEDION_0_PULSE_LEN_MIN,                                          // pulse_0_len_min: minimum length of pulse with bit value 0\n    RF_MEDION_0_PULSE_LEN_MAX,                                          // pulse_0_len_max: maximum length of pulse with bit value 0\n    RF_MEDION_0_PAUSE_LEN_MIN,                                          // pause_0_len_min: minimum length of pause with bit value 0\n    RF_MEDION_0_PAUSE_LEN_MAX,                                          // pause_0_len_max: maximum length of pause with bit value 0\n    RF_MEDION_ADDRESS_OFFSET,                                           // address_offset:  address offset\n    RF_MEDION_ADDRESS_OFFSET + RF_MEDION_ADDRESS_LEN,                   // address_end:     end of address\n    RF_MEDION_COMMAND_OFFSET,                                           // command_offset:  command offset\n    RF_MEDION_COMMAND_OFFSET + RF_MEDION_COMMAND_LEN,                   // command_end:     end of command\n    RF_MEDION_COMPLETE_DATA_LEN,                                        // complete_len:    complete length of frame\n    RF_MEDION_STOP_BIT,                                                 // stop_bit:        flag: frame has stop bit\n    RF_MEDION_LSB,                                                      // lsb_first:       flag: LSB first\n    RF_MEDION_FLAGS                                                     // flags:           some flags\n};\n\n#endif\n\nstatic uint_fast8_t                             irmp_bit;               // current bit position\nstatic IRMP_PARAMETER                           irmp_param;\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\nstatic IRMP_PARAMETER                           irmp_param2;\n#endif\n\nstatic volatile uint_fast8_t                    irmp_ir_detected = FALSE;\nstatic volatile uint_fast8_t                    irmp_protocol;\nstatic volatile uint_fast16_t                   irmp_address;\n#if IRMP_32_BIT == 1\nstatic uint_fast32_t                            irmp_command;\n#else\nstatic uint_fast16_t                            irmp_command; // removed volatile, because it is only used in irmp_get_data and therefore volatile makes no sense\n#endif\nstatic volatile uint_fast16_t                   irmp_id;                // only used for SAMSUNG protocol\nstatic uint_fast8_t                             irmp_flags; // removed volatile, because it is only used in irmp_get_data and therefore volatile makes no sense\n// static volatile uint_fast8_t                 irmp_busy_flag;\n#if IRMP_AUTODETECT_REPEATRATE\nvolatile uint_fast16_t                          delta_detection = 0;    // interval between two detections in ticks\nvolatile uint32_t                               pass_on_delta_detection = 0xFFFF;    // interval between two detections in ticks\nvolatile uint_fast16_t                          tmp_delta = 0xFFFF;\nvolatile uint_fast8_t                           delta = 0;              // interval between two detections in ms\nvolatile uint_fast8_t                           min_delta = 170;  // detected repeat rate, preset to greatest known repeat rate\nstatic volatile uint_fast8_t                    previous_irmp_protocol = 0;\nvolatile uint_fast8_t                           same_key = 0;\nvolatile uint_fast8_t                           keep_same_key = 0;\nvolatile uint_fast8_t                           timeout = 1;\nvolatile uint_fast8_t                           upper_border = 176;     // repeatrate plus jitter (threshold for timeout)\n#endif\n\n#if defined(__MBED__)\n// DigitalIn inputPin(IRMP_PIN, PullUp);                                // this requires mbed.h and source to be compiled as cpp\ngpio_t                                          gpioIRin;               // use low level c function instead\n#endif\n\n\n#if defined(ANALYZE)\n#define input(x)                                (x)\nstatic uint_fast8_t                             IRMP_PIN;\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Initialize IRMP decoder\n *  @details  Configures IRMP input pin\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(ANALYZE)\n#if ! defined(ARDUINO)\nvoid\nirmp_init (void)\n{\n#if defined(PIC_CCS) || defined(PIC_C18)                                // PIC: do nothing\n#elif defined(PIC_XC32)\n#  if defined(IRMP_ANSELBIT)\n    IRMP_ANSELBIT = 0;\n#  endif\n#elif defined (ARM_STM32_HAL)                                           // STM32 with Hal Library: do nothing\n#elif defined (ARM_STM32)                                               // STM32\n    GPIO_InitTypeDef     GPIO_InitStructure;\n\n    /* GPIOx clock enable */\n#  if defined (ARM_STM32L1XX)\n    RCC_AHBPeriphClockCmd(IRMP_PORT_RCC, ENABLE);\n#  elif defined (ARM_STM32F10X)\n    RCC_APB2PeriphClockCmd(IRMP_PORT_RCC, ENABLE);\n#  elif defined (ARM_STM32F30X)\n    RCC_AHBPeriphClockCmd(IRMP_PORT_RCC, ENABLE);\n#  elif defined (ARM_STM32F4XX)\n    RCC_AHB1PeriphClockCmd(IRMP_PORT_RCC, ENABLE);\n#  endif\n\n    /* GPIO Configuration */\n    GPIO_InitStructure.GPIO_Pin = IRMP_BIT;\n#  if defined (ARM_STM32L1XX) || defined (ARM_STM32F4XX)\n    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;\n    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\n    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\n    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\n#  elif defined (ARM_STM32F10X)\n    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\n    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;\n#  elif defined (ARM_STM32F30X)\n    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;\n    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\n    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\n#  endif\n    GPIO_Init(IRMP_PORT, &GPIO_InitStructure);\n\n#elif defined (ARM_STM32_OPENCM3)                                       // ARM_STM32_OPENCM3\n\n    /* GPIOx clock enable */\n#  if defined (STM32L1) || defined (STM32F1) || defined (STM32F3) || defined (STM32F4)\n    rcc_periph_clock_enable(IRMP_PORT_RCC);\n#  endif\n\n    /* GPIO Configuration */\n#  if defined (STM32L1) || defined (STM32F4) || defined (STM32F3)\n    gpio_mode_setup(IRMP_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, IRMP_BIT);\n    gpio_set_output_options(IRMP_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, IRMP_BIT);\n#  elif defined (STM32F1)\n    gpio_set_mode(IRMP_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, IRMP_BIT);\n#  endif\n\n#elif defined(STELLARIS_ARM_CORTEX_M4)\n    // Enable the GPIO port\n    ROM_SysCtlPeripheralEnable(IRMP_PORT_PERIPH);\n\n    // Set as an input\n    ROM_GPIODirModeSet(IRMP_PORT_BASE, IRMP_PORT_PIN, GPIO_DIR_MODE_IN);\n    ROM_GPIOPadConfigSet(IRMP_PORT_BASE, IRMP_PORT_PIN, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);\n\n#elif defined(__SDCC_stm8)                                              // STM8\n    IRMP_GPIO_STRUCT->DDR &= ~(1<<IRMP_BIT);                            // pin is input\n    IRMP_GPIO_STRUCT->CR1 |= (1<<IRMP_BIT);                             // activate pullup\n\n#elif defined (TEENSY_ARM_CORTEX_M4)                                    // TEENSY\n    pinMode(IRMP_PIN, INPUT);\n\n#elif defined(__xtensa__)                                               // ESP8266\n    pinMode(IRMP_BIT_NUMBER, INPUT);\n                                                                        // select pin function\n#  if (IRMP_BIT_NUMBER == 12)\n    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);\n//  doesn't work for me:\n//  # elif (IRMP_BIT_NUMBER == 13)\n//  PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U , FUNC_GPIO13);\n#  else\n#   warning Please add PIN_FUNC_SELECT when necessary.\n#  endif\n    GPIO_DIS_OUTPUT(IRMP_BIT_NUMBER);\n\n#elif defined(__MBED__)\n    gpio_init_in_ex(&gpioIRin, IRMP_PIN, IRMP_PINMODE);                 // initialize input for IR diode\n\n#elif defined(_CHIBIOS_HAL_)\n    // ChibiOS HAL automatically initializes all pins according to the board config file, no need to repeat here\n\n#elif defined(PICO_RP2040)\n    /* GPIO Configuration */\n    gpio_init(IRMP_BIT);\n    gpio_pull_up(IRMP_BIT);\n\n#else                                                                   // AVR\n    IRMP_PORT &= ~(1<<IRMP_BIT);                                        // deactivate pullup\n    IRMP_DDR &= ~(1<<IRMP_BIT);                                         // set pin to input\n#endif\n\n#if IRMP_LOGGING == 1\n    irmp_uart_init ();\n#endif\n}\n#endif // ! defined(ARDUINO)\n#endif // if !defined(ANALYZE)\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Get IRMP data\n *  @details  gets decoded IRMP data\n *  @param    pointer in order to store IRMP data\n *  @return    TRUE: successful, FALSE: failed\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#  ifdef __cplusplus\nbool\n#else\nuint_fast8_t\n#endif\nirmp_get_data (IRMP_DATA * irmp_data_p)\n{\n    uint_fast8_t   tReturnCode = FALSE;\n\n    if (irmp_ir_detected)\n    {\n        switch (irmp_protocol)\n        {\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n            case IRMP_SAMSUNG_PROTOCOL:\n                if ((irmp_command >> 8) == (~irmp_command & 0x00FF))\n                {\n                    irmp_command &= 0xff;\n//                    irmp_command |= irmp_id << 8; // for samsung32 irmp_id looks to be the same as irmp_command\n                    tReturnCode = TRUE;\n                }\n                break;\n\n#  if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\n            case IRMP_SAMSUNG48_PROTOCOL:\n                irmp_command = (irmp_command & 0x00FF) | ((irmp_id & 0x00FF) << 8);\n                tReturnCode = TRUE;\n                break;\n#  endif\n#endif\n\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n            case IRMP_SIRCS_PROTOCOL:\n                // Concatenate high byte of command and low byte of address\n                irmp_address <<= 7;\n                irmp_address = irmp_address | irmp_command >> 8;\n                // Command is 7 bytes, so add the 8.th bit of command to address\n                irmp_address <<= 1;\n                if ((irmp_command & 0x80))\n                {\n                    irmp_address++;\n                }\n                irmp_command &= 0x7F;\n                tReturnCode = TRUE;\n                break;\n#endif\n\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n            case IRMP_NEC_PROTOCOL:\n                if ((irmp_command >> 8) == (~irmp_command & 0x00FF))\n                {\n                    if ((irmp_address >> 8) == (~irmp_address & 0x00FF))\n                    {\n                        irmp_address &= 0xff;\n                    }\n                    irmp_command &= 0xff;\n                }\n                else if (irmp_address == 0x87EE)\n                {\n                    ANALYZE_PRINTF1 (\"APPLE protocol detected\\n\");\n                    irmp_protocol = IRMP_APPLE_PROTOCOL;\n                    irmp_address = (irmp_command & 0xFF00) >> 8; // address was received in command!\n                    irmp_command &= 0x00FF;\n                }\n                else\n                {\n                    ANALYZE_PRINTF1 (\"ONKYO protocol detected\\n\");\n                    irmp_protocol = IRMP_ONKYO_PROTOCOL;\n                }\n                tReturnCode = TRUE;\n                break;\n#endif\n\n#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\n            case IRMP_VINCENT_PROTOCOL:\n                if ((irmp_command >> 8) == (irmp_command & 0x00FF))\n                {\n                    irmp_command &= 0xff;\n                    tReturnCode = TRUE;\n                }\n                break;\n#endif\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n            case IRMP_KASEIKYO_PROTOCOL:\n                /*\n                 * Todo AJ 14.7.22 The bit before the command (not existent bit 16 of command) is skipped and I have a Panasonic remote where it is 1 for 2 buttons\n                 * and the 4 LSB command bits are always zero for this remote\n                 */\n                if( irmp_address == 0x2002) // PANASONIC_VENDOR_ID_CODE\n                {\n                    ANALYZE_PRINTF1 (\"Kaseikyo_Panasonic protocol detected\\n\");\n                    irmp_protocol = IRMP_PANASONIC_PROTOCOL;\n                    irmp_command = irmp_command >> 4; // remove the 4 zero bits\n                    irmp_address = (irmp_command & 0xF00) >> 8; // LSB address (genre1) was received in command!\n                    irmp_address |= irmp_flags & 0xF0; // MSB of address(genre2 bits) are located in MSB of the flag byte\n                    irmp_command &= 0x00FF;\n                }\n                tReturnCode = TRUE;\n                break;\n#endif\n\n#if IRMP_SUPPORT_BOSE_PROTOCOL == 1\n            case IRMP_BOSE_PROTOCOL:\n                if ((irmp_command >> 8) == (~irmp_command & 0x00FF))\n                {\n                    irmp_command &= 0xff;\n                    tReturnCode = TRUE;\n                }\n                break;\n#endif\n\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n            case IRMP_MERLIN_PROTOCOL:\n                if (irmp_bit == 10)\n                {\n                    tReturnCode = TRUE;\n                }\n                else if (irmp_bit >= 19 && ((irmp_bit - 3) % 8 == 0))\n                {\n                    if (((irmp_command >> 1) & 1) != (irmp_command & 1))\n                    {\n                        irmp_command >>= 1;\n                        irmp_command |= ((irmp_address & 1) << (irmp_bit - 12));\n                        irmp_address >>= 1;\n                        tReturnCode = TRUE;\n                    }\n                }\n                break;\n#endif\n\n#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\n            case IRMP_SIEMENS_PROTOCOL:\n            case IRMP_RUWIDO_PROTOCOL:\n                if (((irmp_command >> 1) & 0x0001) == (~irmp_command & 0x0001))\n                {\n                    irmp_command >>= 1;\n                    tReturnCode = TRUE;\n                }\n                break;\n#endif\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n            case IRMP_KATHREIN_PROTOCOL:\n                if (irmp_command != 0x0000)\n                {\n                    tReturnCode = TRUE;\n                }\n                break;\n#endif\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1\n            case IRMP_RC5_PROTOCOL:\n                irmp_address &= ~0x20;                              // clear toggle bit\n                tReturnCode = TRUE;\n                break;\n#endif\n#if IRMP_SUPPORT_S100_PROTOCOL == 1\n            case IRMP_S100_PROTOCOL:\n                irmp_address &= ~0x20;                              // clear toggle bit\n                tReturnCode = TRUE;\n                break;\n#endif\n#if IRMP_SUPPORT_IR60_PROTOCOL == 1\n            case IRMP_IR60_PROTOCOL:\n                if (irmp_command != 0x007d)                         // 0x007d (== 62<<1 + 1) is start instruction frame\n                {\n                    tReturnCode = TRUE;\n                }\n                else\n                {\n                    ANALYZE_PRINTF1(\"Info IR60: got start instruction frame\\n\");\n                }\n                break;\n#endif\n#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n            case IRMP_RCCAR_PROTOCOL:\n                // frame in irmp_data:\n                // Bit 12 11 10 9  8  7  6  5  4  3  2  1  0\n                //     V  D7 D6 D5 D4 D3 D2 D1 D0 A1 A0 C1 C0   //         10 9  8  7  6  5  4  3  2  1  0\n                irmp_address = (irmp_command & 0x000C) >> 2;    // addr:   0  0  0  0  0  0  0  0  0  A1 A0\n                irmp_command = ((irmp_command & 0x1000) >> 2) | // V-Bit:  V  0  0  0  0  0  0  0  0  0  0\n                               ((irmp_command & 0x0003) << 8) | // C-Bits: 0  C1 C0 0  0  0  0  0  0  0  0\n                               ((irmp_command & 0x0FF0) >> 4);  // D-Bits:          D7 D6 D5 D4 D3 D2 D1 D0\n                tReturnCode = TRUE;                                     // Summe:  V  C1 C0 D7 D6 D5 D4 D3 D2 D1 D0\n                break;\n#endif\n\n#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1                           // squeeze code to 8 bit, upper bit indicates release-key\n            case IRMP_NETBOX_PROTOCOL:\n                if (irmp_command & 0x1000)                      // last bit set?\n                {\n                    if ((irmp_command & 0x1f) == 0x15)          // key pressed: 101 01 (LSB)\n                    {\n                        irmp_command >>= 5;\n                        irmp_command &= 0x7F;\n                        tReturnCode = TRUE;\n                    }\n                    else if ((irmp_command & 0x1f) == 0x10)     // key released: 000 01 (LSB)\n                    {\n                        irmp_command >>= 5;\n                        irmp_command |= 0x80;\n                        tReturnCode = TRUE;\n                    }\n                    else\n                    {\n                        ANALYZE_PRINTF1(\"error NETBOX: bit6/7 must be 0/1\\n\");\n                    }\n                }\n                else\n                {\n                    ANALYZE_PRINTF1(\"error NETBOX: last bit not set\\n\");\n                }\n                break;\n#endif\n#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\n            case IRMP_LEGO_PROTOCOL:\n            {\n                uint_fast8_t crc = 0x0F ^ ((irmp_command & 0xF000) >> 12) ^ ((irmp_command & 0x0F00) >> 8) ^ ((irmp_command & 0x00F0) >> 4);\n\n                if ((irmp_command & 0x000F) == crc)\n                {\n                    irmp_command >>= 4;\n                    tReturnCode = TRUE;\n                }\n                else\n                {\n                    ANALYZE_PRINTF1 (\"CRC error in LEGO protocol\\n\");\n                    // rtc = TRUE;                              // don't accept codes with CRC errors\n                }\n                break;\n            }\n#endif\n\n#if IRMP_SUPPORT_METZ_PROTOCOL == 1\n            case IRMP_METZ_PROTOCOL:\n                irmp_address &= ~0x40;                              // clear toggle bit\n                if (((~irmp_address) & 0x07) == (irmp_address >> 3) && ((~irmp_command) & 0x3f) == (irmp_command >> 6))\n                {\n                    irmp_address >>= 3;\n                    irmp_command >>= 6;\n                    tReturnCode = TRUE;\n                }\n                break;\n#endif\n\n\n#if IRMP_SUPPORT_RF_X10_PROTOCOL == 1 || IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n            case RF_X10_PROTOCOL:\n            case RF_MEDION_PROTOCOL:\n            {\n                uint8_t channel;\n                uint8_t checksum;\n\n                channel = irmp_command & 0x0F;                      // lower nibble: RF channel 0-15\n                irmp_command >>= 4;                                 // shift out channel\n\n                checksum = irmp_address;                            // get checksum\n\n                if (((irmp_command + (0x0055 + (channel << 4))) & 0x7F) == checksum)\n                {                                                   // checksum correct?\n                    irmp_address = channel + 1;                     // set address to channel + 1\n                    tReturnCode = TRUE;\n                }\n                break;\n            }\n#endif\n\n            default:\n            {\n                tReturnCode = TRUE;\n                break;\n            }\n        }\n\n        if (tReturnCode)\n        {\n            irmp_data_p->protocol = irmp_protocol;\n            irmp_data_p->address  = irmp_address;\n            irmp_data_p->command  = irmp_command;\n\n#if IRMP_AUTODETECT_REPEATRATE\n            tmp_delta = (pass_on_delta_detection * (1000000 / F_INTERRUPTS)) / 1000; // ms, this division is not precise\n            if (tmp_delta > 0xFF ) // reduce to uint8_t\n                delta = 0xFF;\n            else\n                delta = tmp_delta;\n            if (irmp_protocol != previous_irmp_protocol) { // reset\n                min_delta = 170;\n                upper_border = min_delta * (100 + JITTER_COMPENSATION) / 100 + 1;\n                timeout = 1;\n                keep_same_key = 0;\n                previous_irmp_protocol = irmp_protocol;\n            } else {\n                if (!(irmp_protocol == IRMP_NEC_PROTOCOL && delta < 75)) { // if NEC, ignore first short interval\n                    if (delta < min_delta && same_key)\n                        min_delta = delta;\n                }\n                upper_border = min_delta * (100 + JITTER_COMPENSATION) / 100 + 1;\n                timeout = (delta >= upper_border);\n                if (irmp_protocol == IRMP_RC5_PROTOCOL || irmp_protocol == IRMP_RC6_PROTOCOL || irmp_protocol == IRMP_RC6A_PROTOCOL || irmp_protocol == IRMP_RECS80_PROTOCOL \\\n                    || irmp_protocol == IRMP_RECS80EXT_PROTOCOL || irmp_protocol == IRMP_RCMM24_PROTOCOL || irmp_protocol == IRMP_RCMM32_PROTOCOL \\\n                    || irmp_protocol == IRMP_THOMSON_PROTOCOL || irmp_protocol == IRMP_S100_PROTOCOL || irmp_protocol == IRMP_METZ_PROTOCOL) {\n                    if (same_key) // same_key is false, if toggle; not using timeout helps detecting repeats after misdetection and timeout isn't needed for discerning repetition\n                        irmp_flags |= IRMP_FLAG_REPETITION;\n                } else {\n                    if (same_key && !timeout)\n                        irmp_flags |= IRMP_FLAG_REPETITION;\n                }\n                keep_same_key = same_key;\n                same_key = 0;\n            }\n#endif\n\n            irmp_data_p->flags    = irmp_flags;\n        }\n        else\n        {\n            irmp_protocol = IRMP_UNKNOWN_PROTOCOL;\n        }\n\n        irmp_command  = 0;                                      // don't reset irmp_protocol here, needed for detection of NEC & JVC repetition frames!\n        irmp_address  = 0;\n        irmp_flags    = 0;\n\n        irmp_ir_detected = FALSE;\n    }\n\n    return tReturnCode;\n}\n\n#if IRMP_USE_CALLBACK == 1\nvoid\nirmp_set_callback_ptr (void (*cb)(uint_fast8_t))\n{\n    irmp_callback_ptr = cb;\n}\n#endif // IRMP_USE_CALLBACK == 1\n\n// these statics must not be volatile, because they are only used by irmp_store_bit(), which is called by irmp_ISR()\nstatic uint_fast16_t irmp_tmp_address;                                      // ir address\n#if IRMP_32_BIT == 1\nstatic uint_fast32_t irmp_tmp_command;                                      // ir command\n#else\nstatic uint_fast16_t irmp_tmp_command;                                      // ir command\n#endif\n\n#if (IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)) || IRMP_SUPPORT_NEC42_PROTOCOL == 1\nstatic uint_fast16_t irmp_tmp_address2;                                     // ir address\nstatic uint_fast16_t irmp_tmp_command2;                                     // ir command\n#endif\n\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\nstatic uint_fast16_t irmp_lgair_address;                                    // ir address\nstatic uint_fast16_t irmp_lgair_command;                                    // ir command\n#endif\n\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\nstatic uint_fast16_t irmp_melinera_command;                                 // ir command\n#endif\n\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\nstatic uint_fast16_t irmp_tmp_id;                                           // ir id (only SAMSUNG)\n#endif\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\nstatic uint8_t      xor_check[6];                                           // check kaseikyo \"parity\" bits\nstatic uint_fast8_t genre2;                                                 // save genre2 bits here, later copied to MSB in flags\n#endif\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\nstatic uint_fast8_t  parity;                                                // number of '1' of the first 14 bits, check if even.\n#endif\n\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\nstatic uint_fast8_t  check;                                                 // number of '1' of the first 14 bits, check if even.\nstatic uint_fast8_t  mitsu_parity;                                          // number of '1' of the first 14 bits, check if even.\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  store bit\n *  @details  store bit in temp address or temp command\n *  @param    value to store: 0 or 1\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n// verhindert, dass irmp_store_bit() inline compiliert wird:\n// static void irmp_store_bit (uint_fast8_t) __attribute__ ((noinline));\n\nstatic void\nirmp_store_bit (uint_fast8_t value)\n{\n#if IRMP_SUPPORT_ACP24_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_ACP24_PROTOCOL)                                                 // squeeze 64 bits into 16 bits:\n    {\n        if (value)\n        {\n            // ACP24-Frame:\n            //           1         2         3         4         5         6\n            // 0123456789012345678901234567890123456789012345678901234567890123456789\n            // N VVMMM    ? ???    t vmA x                 y                     TTTT\n            //\n            // irmp_data_p->command:\n            //\n            //         5432109876543210\n            //         NAVVvMMMmtxyTTTT\n\n            switch (irmp_bit)\n            {\n                case  0: irmp_tmp_command |= (1<<15); break;                                        // N\n                case  2: irmp_tmp_command |= (1<<13); break;                                        // V\n                case  3: irmp_tmp_command |= (1<<12); break;                                        // V\n                case  4: irmp_tmp_command |= (1<<10); break;                                        // M\n                case  5: irmp_tmp_command |= (1<< 9); break;                                        // M\n                case  6: irmp_tmp_command |= (1<< 8); break;                                        // M\n                case 20: irmp_tmp_command |= (1<< 6); break;                                        // t\n                case 22: irmp_tmp_command |= (1<<11); break;                                        // v\n                case 23: irmp_tmp_command |= (1<< 7); break;                                        // m\n                case 24: irmp_tmp_command |= (1<<14); break;                                        // A\n                case 26: irmp_tmp_command |= (1<< 5); break;                                        // x\n                case 44: irmp_tmp_command |= (1<< 4); break;                                        // y\n                case 66: irmp_tmp_command |= (1<< 3); break;                                        // T\n                case 67: irmp_tmp_command |= (1<< 2); break;                                        // T\n                case 68: irmp_tmp_command |= (1<< 1); break;                                        // T\n                case 69: irmp_tmp_command |= (1<< 0); break;                                        // T\n            }\n        }\n    }\n    else\n#endif // IRMP_SUPPORT_ACP24_PROTOCOL\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_ORTEK_PROTOCOL)\n    {\n        if (irmp_bit < 14)\n        {\n            if (value)\n            {\n                parity++;\n            }\n        }\n        else if (irmp_bit == 14)\n        {\n            if (value)                                                                                      // value == 1: even parity\n            {\n                if (parity & 0x01)\n                {\n                    parity = PARITY_CHECK_FAILED;\n                }\n                else\n                {\n                    parity = PARITY_CHECK_OK;\n                }\n            }\n            else\n            {\n                if (parity & 0x01)                                                                          // value == 0: odd parity\n                {\n                    parity = PARITY_CHECK_OK;\n                }\n                else\n                {\n                    parity = PARITY_CHECK_FAILED;\n                }\n            }\n        }\n    }\n    else\n#endif\n    {\n        ;\n    }\n\n#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1\n    if (irmp_bit == 0 && irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL)\n    {\n        first_bit = value;\n    }\n    else\n#endif\n\n    if (irmp_bit >= irmp_param.address_offset && irmp_bit < irmp_param.address_end)\n    {\n        if (irmp_param.lsb_first)\n        {\n            irmp_tmp_address |= (((uint_fast16_t) (value)) << (irmp_bit - irmp_param.address_offset));      // CV wants cast\n        }\n        else\n        {\n            irmp_tmp_address <<= 1;\n            irmp_tmp_address |= value;\n        }\n    }\n    else if (irmp_bit >= irmp_param.command_offset && irmp_bit < irmp_param.command_end)\n    {\n        if (irmp_param.lsb_first)\n        {\n#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\n            if (irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL && irmp_bit >= 32)\n            {\n                irmp_tmp_id |= (((uint_fast16_t) (value)) << (irmp_bit - 32));                              // CV wants cast\n            }\n            else\n#endif\n            {\n                irmp_tmp_command |= (((uint_fast16_t) (value)) << (irmp_bit - irmp_param.command_offset));  // CV wants cast\n            }\n        }\n        else\n        {\n            irmp_tmp_command <<= 1;\n            irmp_tmp_command |= value;\n        }\n    }\n\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_NEC_PROTOCOL || irmp_param.protocol == IRMP_NEC42_PROTOCOL)\n    {\n        if (irmp_bit < 8)\n        {\n            irmp_lgair_address <<= 1;                                                                       // LGAIR uses MSB\n            irmp_lgair_address |= value;\n        }\n        else if (irmp_bit < 24)\n        {\n            irmp_lgair_command <<= 1;                                                                       // LGAIR uses MSB\n            irmp_lgair_command |= value;\n        }\n    }\n    // NO else!\n#endif\n\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_NEC_PROTOCOL || irmp_param.protocol == IRMP_NEC42_PROTOCOL || irmp_param.protocol == IRMP_MELINERA_PROTOCOL)\n    {\n        irmp_melinera_command <<= 1;                                                                        // MELINERA uses MSB\n        irmp_melinera_command |= value;\n    }\n#endif\n\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && irmp_bit >= 13 && irmp_bit < 26)\n    {\n        irmp_tmp_address2 |= (((uint_fast16_t) (value)) << (irmp_bit - 13));                                // CV wants cast\n    }\n    else\n#endif\n\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit >= SAMSUNG_ID_OFFSET && irmp_bit < SAMSUNG_ID_OFFSET + SAMSUNG_ID_LEN)\n    {\n        irmp_tmp_id |= (((uint_fast16_t) (value)) << (irmp_bit - SAMSUNG_ID_OFFSET));                       // store with LSB first\n    }\n    else\n#endif\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL)\n    {\n        if (irmp_bit >= 20 && irmp_bit < 24)\n        {\n            irmp_tmp_command |= (((uint_fast16_t) (value)) << (irmp_bit - 8));  // store 4 system bits (genre 1) in upper nibble with LSB first\n        }\n        else if (irmp_bit >= 24 && irmp_bit < 28)\n        {\n            genre2 |= (((uint_fast8_t) (value)) << (irmp_bit - 20));            // store 4 system bits (genre 2) in upper nibble with LSB first\n        }\n\n        if (irmp_bit < KASEIKYO_COMPLETE_DATA_LEN)\n        {\n            if (value)\n            {\n                xor_check[irmp_bit / 8] |= 1 << (irmp_bit % 8);\n            }\n            else\n            {\n                xor_check[irmp_bit / 8] &= ~(1 << (irmp_bit % 8));\n            }\n        }\n    }\n    else\n#endif\n\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n    if (irmp_param.protocol == IRMP_MITSU_HEAVY_PROTOCOL)                           // squeeze 64 bits into 16 bits:\n    {\n        if (irmp_bit == 72 )\n        {                                                                           // irmp_tmp_address, irmp_tmp_command received: check parity & compress\n            mitsu_parity = PARITY_CHECK_OK;\n\n            check = irmp_tmp_address >> 8;                                          // inverted upper byte == lower byte?\n            check = ~ check;\n\n            if (check == (irmp_tmp_address & 0xFF))\n            {                                                                       // ok:\n                irmp_tmp_address <<= 8;                                             // throw away upper byte\n            }\n            else\n            {\n                mitsu_parity = PARITY_CHECK_FAILED;\n            }\n\n            check = irmp_tmp_command >> 8;                                          // inverted upper byte == lower byte?\n            check = ~ check;\n            if (check == (irmp_tmp_command & 0xFF))\n            {                                                                       // ok:  pack together\n                irmp_tmp_address |= irmp_tmp_command & 0xFF;                        // byte 1, byte2 in irmp_tmp_address, irmp_tmp_command can be used for byte 3\n            }\n            else\n            {\n                mitsu_parity = PARITY_CHECK_FAILED;\n            }\n            irmp_tmp_command = 0;\n        }\n\n        if (irmp_bit >= 72 )\n        {                                                                           // receive 3. word in irmp_tmp_command\n            irmp_tmp_command <<= 1;\n            irmp_tmp_command |= value;\n        }\n    }\n    else\n#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\n    {\n        ;\n    }\n\n    irmp_bit++;\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  store bit\n *  @details  store bit in temp address or temp command\n *  @param    value to store: 0 or 1\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\nstatic void\nirmp_store_bit2 (uint_fast8_t value)\n{\n    uint_fast8_t irmp_bit2;\n\n    if (irmp_param.protocol)\n    {\n        irmp_bit2 = irmp_bit - 2;\n    }\n    else\n    {\n        irmp_bit2 = irmp_bit - 1;\n    }\n\n    if (irmp_bit2 >= irmp_param2.address_offset && irmp_bit2 < irmp_param2.address_end)\n    {\n        irmp_tmp_address2 |= (((uint_fast16_t) (value)) << (irmp_bit2 - irmp_param2.address_offset));   // CV wants cast\n    }\n    else if (irmp_bit2 >= irmp_param2.command_offset && irmp_bit2 < irmp_param2.command_end)\n    {\n        irmp_tmp_command2 |= (((uint_fast16_t) (value)) << (irmp_bit2 - irmp_param2.command_offset));   // CV wants cast\n    }\n}\n#endif // IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\n\n#if defined(ANALYZE)\nstatic uint32_t s_curSample = 0;\nstatic uint32_t s_startBitSample = 0;\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  ISR routine\n *  @details  ISR routine, called 10000 to 20000 times per second\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n    static uint_fast8_t     irmp_start_bit_detected;                                // flag: start bit detected\n    static uint_fast8_t     wait_for_space;                                         // flag: wait for data bit space\n    static uint_fast8_t     wait_for_start_space;                                   // flag: wait for start bit space\n#if __SIZEOF_INT__ == 4\n    static uint_fast16_t irmp_pulse_time;                                            // count bit time for pulse\n#else\n    static uint_fast8_t irmp_pulse_time;                                            // count bit time for pulse\n#endif\n    static PAUSE_LEN        irmp_pause_time;                                        // count bit time for pause\n    static uint_fast16_t    key_repetition_len;                                     // SIRCS repeats frame 2-5 times with 45 ms pause\n    static uint_fast8_t     repetition_frame_number;\n\n#if defined(ARDUINO)\n#include \"irmpArduinoExt.hpp\" // Must be included after declaration of irmp_start_bit_detected etc.\n#endif\n\n/*\n * 4 us idle, 45 us at start of each pulse @16 MHz ATmega 328p\n */\n#if defined(ESP8266) || defined(ESP32)\nbool IRAM_ATTR irmp_ISR(void)\n#else\n#  ifdef __cplusplus\nbool irmp_ISR(void)\n#  else\nuint_fast8_t irmp_ISR(void)\n#  endif\n#endif\n\n{\n    static uint_fast16_t    last_irmp_address = 0xFFFF;                             // save last irmp address to recognize key repetition\n#if IRMP_ENABLE_RELEASE_DETECTION == 1\n    static uint_fast8_t     key_released = TRUE;\n#endif\n#if IRMP_32_BIT == 1\n    static uint_fast32_t    last_irmp_command = 0xFFFFFFFF;                         // save last irmp command to recognize key repetition\n#else\n    static uint_fast16_t    last_irmp_command = 0xFFFF;                             // save last irmp command to recognize key repetition\n#endif\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n    static uint_fast16_t    last_irmp_denon_command;                                // save last irmp command to recognize DENON frame repetition\n    static uint_fast16_t    denon_repetition_len = 0xFFFF;                          // denon repetition len of 2nd auto generated frame\n#endif\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_S100_PROTOCOL == 1\n    static uint_fast8_t     rc5_cmd_bit6;                                           // bit 6 of RC5 command is the inverted 2nd start bit\n#endif\n#if IRMP_SUPPORT_MANCHESTER == 1\n    static PAUSE_LEN        last_pause;                                             // last pause value\n#endif\n#if IRMP_SUPPORT_MANCHESTER == 1 || IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n    static uint_fast8_t     last_value;                                             // last bit value\n#endif\n#if IRMP_SUPPORT_RCII_PROTOCOL == 1\n    static uint_fast8_t     waiting_for_2nd_pulse = 0;\n#endif\n#if IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n    uint_fast8_t            bit_0 = 0;\n#endif\n    uint_fast8_t            irmp_input;                                             // input value\n\n#if defined(ANALYZE)\n    time_counter++;\n#endif // ANALYZE\n\n#if IRMP_HIGH_ACTIVE == 1\n    irmp_input = ! input(IRMP_PIN);\n#else\n    irmp_input = input(IRMP_PIN);\n#endif\n\n#if IRMP_USE_CALLBACK == 1\n    if (irmp_callback_ptr)\n    {\n        static uint_fast8_t last_inverted_input;\n\n        if (last_inverted_input != !irmp_input)\n        {\n            (*irmp_callback_ptr) (! irmp_input);\n            last_inverted_input = !irmp_input;\n        }\n    }\n#endif // IRMP_USE_CALLBACK == 1\n\n#if defined(ARDUINO)\n#  if !defined(NO_LED_FEEDBACK_CODE)\n    irmp_DoLEDFeedback(irmp_input);\n#  endif\n#endif\n\n    irmp_log(irmp_input);                                                       // log ir signal, if IRMP_LOGGING defined\n\n#if IRMP_AUTODETECT_REPEATRATE\n    if (delta_detection < 0xFFFF)\n        delta_detection++;\n#if IRMP_ENABLE_RELEASE_DETECTION == 1\n    if (! key_released && delta_detection * (1000000 / F_INTERRUPTS) / 1000 >= upper_border)\n        {\n            irmp_address        = last_irmp_address;\n            irmp_command        = last_irmp_command;\n            irmp_flags          = IRMP_FLAG_RELEASE;\n            irmp_ir_detected    = TRUE;\n            key_released        = TRUE;\n        }\n#endif\n#endif\n\n    if (! irmp_ir_detected)                                                     // ir code already detected?\n    {                                                                           // no...\n        if (! irmp_start_bit_detected)                                          // start bit detected?\n        {                                                                       // no...\n            if (! irmp_input)                                                   // receiving burst?\n            {                                                                   // yes...\n//              irmp_busy_flag = TRUE;\n#if defined(ANALYZE)\n                if (! irmp_pulse_time)\n                {\n                    s_startBitSample = s_curSample;\n                    ANALYZE_PRINTF2(\"%8.3fms [starting pulse]\\n\", (double) (time_counter * 1000) / F_INTERRUPTS);\n                }\n#endif // ANALYZE\n                irmp_pulse_time++;                                              // increment counter\n            }\n            else\n            {                                                                   // no...\n                if (irmp_pulse_time)                                            // it's dark....\n                {                                                               // set flags for counting the time of darkness...\n                    irmp_start_bit_detected = 1;\n                    wait_for_start_space    = 1;\n                    wait_for_space          = 0;\n                    irmp_tmp_command        = 0;\n                    irmp_tmp_address        = 0;\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n                    genre2                  = 0;\n#endif\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n                    irmp_tmp_id = 0;\n#endif\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1) || IRMP_SUPPORT_NEC42_PROTOCOL == 1\n                    irmp_tmp_command2       = 0;\n                    irmp_tmp_address2       = 0;\n#endif\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n                    irmp_lgair_command      = 0;\n                    irmp_lgair_address      = 0;\n#endif\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\n                    irmp_melinera_command   = 0;\n#endif\n                    irmp_bit                = 0xff;\n                    irmp_pause_time         = 1;                                // 1st pause: set to 1, not to 0!\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_S100_PROTOCOL == 1\n                    rc5_cmd_bit6            = 0;                                // fm 2010-03-07: bugfix: reset it after incomplete RC5 frame!\n#endif\n                }\n                else\n                {\n                    if (key_repetition_len < 0xFFFF)                            // avoid overflow of counter\n                    {\n                        key_repetition_len++;\n\n#if IRMP_ENABLE_RELEASE_DETECTION == 1\n#if !IRMP_AUTODETECT_REPEATRATE\n                        if (! key_released && key_repetition_len > IRMP_KEY_RELEASE_LEN)\n                        {\n                            irmp_address        = last_irmp_address;\n                            irmp_command        = last_irmp_command;\n                            irmp_flags          = IRMP_FLAG_RELEASE;\n                            irmp_ir_detected    = TRUE;\n                            key_released        = TRUE;\n                        }\n#endif\n#endif\n\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n                        if (denon_repetition_len < 0xFFFF)                      // avoid overflow of counter\n                        {\n                            denon_repetition_len++;\n\n                            if (denon_repetition_len >= DENON_AUTO_REPETITION_PAUSE_LEN && last_irmp_denon_command != 0)\n                            {\n                                ANALYZE_PRINTF2 (\"%8.3fms warning: did not receive inverted command repetition\\n\",\n                                                (double) (time_counter * 1000) / F_INTERRUPTS);\n                                last_irmp_denon_command = 0;\n                                denon_repetition_len = 0xFFFF;\n                            }\n                        }\n#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1\n                    }\n                }\n            }\n        }\n        else\n        {\n            if (wait_for_start_space)                                           // we have received start bit...\n            {                                                                   // ...and are counting the time of darkness\n                if (irmp_input)                                                 // still dark?\n                {                                                               // yes\n                    irmp_pause_time++;                                          // increment counter\n\n#if IRMP_SUPPORT_NIKON_PROTOCOL == 1\n                    if (((irmp_pulse_time < NIKON_START_BIT_PULSE_LEN_MIN || irmp_pulse_time > NIKON_START_BIT_PULSE_LEN_MAX) && irmp_pause_time > IRMP_TIMEOUT_LEN) ||\n                         irmp_pause_time > IRMP_TIMEOUT_NIKON_LEN)\n#else\n                    if (irmp_pause_time > IRMP_TIMEOUT_LEN)                     // timeout?\n#endif\n                    {                                                           // yes...\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                        if (irmp_protocol == IRMP_JVC_PROTOCOL)                 // don't show eror if JVC protocol, irmp_pulse_time has been set below!\n                        {\n                            ;\n                        }\n                        else\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n                        {\n                            ANALYZE_PRINTF4 (\"%8.3fms error 1: pause after start bit pulse %d too long: %d\\n\", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_pulse_time, irmp_pause_time);\n                            ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                        }\n\n                        irmp_start_bit_detected = 0;                            // reset flags, let's wait for another start bit\n                        irmp_pulse_time         = 0;\n                        irmp_pause_time         = 0;\n                    }\n                }\n                else\n                {                                                               // receiving first data pulse!\n                    IRMP_PARAMETER * irmp_param_p;\n                    irmp_param_p = (IRMP_PARAMETER *) 0;\n                    irmp_bit = 0;\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\n                    irmp_param2.protocol = 0;\n#endif\n\n                    ANALYZE_PRINTF4 (\"%8.3fms [start-bit: pulse = %2d, pause = %2d]\\n\", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_pulse_time, irmp_pause_time);\n\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n                    if (irmp_pulse_time >= SIRCS_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIRCS_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= SIRCS_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIRCS_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's SIRCS\n                        ANALYZE_PRINTF5 (\"protocol = SIRCS, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        SIRCS_START_BIT_PULSE_LEN_MIN, SIRCS_START_BIT_PULSE_LEN_MAX,\n                                        SIRCS_START_BIT_PAUSE_LEN_MIN, SIRCS_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &sircs_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                    if (irmp_protocol == IRMP_JVC_PROTOCOL &&                                                       // last protocol was JVC, awaiting repeat frame\n                        irmp_pulse_time >= JVC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= JVC_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= JVC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= JVC_REPEAT_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = NEC or JVC (type 1) repeat frame, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        JVC_START_BIT_PULSE_LEN_MIN, JVC_START_BIT_PULSE_LEN_MAX,\n                                        JVC_REPEAT_START_BIT_PAUSE_LEN_MIN, JVC_REPEAT_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &nec_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n                    if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX)\n                    {\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n                        ANALYZE_PRINTF5 (\"protocol = NEC42, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,\n                                        NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &nec42_param;\n#else\n                        ANALYZE_PRINTF5 (\"protocol = NEC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,\n                                        NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &nec_param;\n#endif\n                    }\n                    else if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN        && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&\n                             irmp_pause_time >= NEC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's NEC\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                        if (irmp_protocol == IRMP_JVC_PROTOCOL)                 // last protocol was JVC, awaiting repeat frame\n                        {                                                       // some jvc remote controls use nec repetition frame for jvc repetition frame\n                            ANALYZE_PRINTF5 (\"protocol = JVC repeat frame type 2, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,\n                                            NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX);\n                            irmp_param_p = (IRMP_PARAMETER *) &nec_param;\n                        }\n                        else\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n                        {\n                            ANALYZE_PRINTF5 (\"protocol = NEC (repetition frame), start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,\n                                            NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX);\n\n                            irmp_param_p = (IRMP_PARAMETER *) &nec_rep_param;\n                        }\n                    }\n                    else\n\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                    if (irmp_protocol == IRMP_JVC_PROTOCOL &&                   // last protocol was JVC, awaiting repeat frame\n                        irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= NEC_0_PAUSE_LEN_MIN         && irmp_pause_time <= NEC_0_PAUSE_LEN_MAX)\n                    {                                                           // it's JVC repetition type 3\n                        ANALYZE_PRINTF5 (\"protocol = JVC repeat frame type 3, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,\n                                        NEC_0_PAUSE_LEN_MIN, NEC_0_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &nec_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n\n#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1\n\n#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n                    if (irmp_pulse_time >= TELEFUNKEN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= TELEFUNKEN_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= TELEFUNKEN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= TELEFUNKEN_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = TELEFUNKEN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        TELEFUNKEN_START_BIT_PULSE_LEN_MIN, TELEFUNKEN_START_BIT_PULSE_LEN_MAX,\n                                        TELEFUNKEN_START_BIT_PAUSE_LEN_MIN, TELEFUNKEN_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &telefunken_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n\n#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n                    if (irmp_pulse_time >= ROOMBA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= ROOMBA_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= ROOMBA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= ROOMBA_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = ROOMBA, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        ROOMBA_START_BIT_PULSE_LEN_MIN, ROOMBA_START_BIT_PULSE_LEN_MAX,\n                                        ROOMBA_START_BIT_PAUSE_LEN_MIN, ROOMBA_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &roomba_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n\n#if IRMP_SUPPORT_ACP24_PROTOCOL == 1\n                    if (irmp_pulse_time >= ACP24_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= ACP24_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= ACP24_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= ACP24_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = ACP24, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        ACP24_START_BIT_PULSE_LEN_MIN, ACP24_START_BIT_PULSE_LEN_MAX,\n                                        ACP24_START_BIT_PAUSE_LEN_MIN, ACP24_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &acp24_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n\n#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1\n                    if (irmp_pulse_time >= PENTAX_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= PENTAX_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= PENTAX_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= PENTAX_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = PENTAX, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        PENTAX_START_BIT_PULSE_LEN_MIN, PENTAX_START_BIT_PULSE_LEN_MAX,\n                                        PENTAX_START_BIT_PAUSE_LEN_MIN, PENTAX_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &pentax_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_PENTAX_PROTOCOL == 1\n\n#if IRMP_SUPPORT_NIKON_PROTOCOL == 1\n                    if (irmp_pulse_time >= NIKON_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NIKON_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= NIKON_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NIKON_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = NIKON, start bit timings: pulse: %3d - %3d, pause: %3u - %3u\\n\",\n                                        NIKON_START_BIT_PULSE_LEN_MIN, NIKON_START_BIT_PULSE_LEN_MAX,\n                                        (unsigned int) NIKON_START_BIT_PAUSE_LEN_MIN, (unsigned int) NIKON_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &nikon_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_NIKON_PROTOCOL == 1\n\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n                    if (irmp_pulse_time >= SAMSUNG_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's SAMSUNG\n                        ANALYZE_PRINTF5 (\"protocol = SAMSUNG, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        SAMSUNG_START_BIT_PULSE_LEN_MIN, SAMSUNG_START_BIT_PULSE_LEN_MAX,\n                                        SAMSUNG_START_BIT_PAUSE_LEN_MIN, SAMSUNG_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &samsung_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n\n#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n                    if (irmp_pulse_time >= SAMSUNGAH_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNGAH_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= SAMSUNGAH_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNGAH_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's SAMSUNGAH\n                        ANALYZE_PRINTF5 (\"protocol = SAMSUNGAH, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        SAMSUNGAH_START_BIT_PULSE_LEN_MIN, SAMSUNGAH_START_BIT_PULSE_LEN_MAX,\n                                        SAMSUNGAH_START_BIT_PAUSE_LEN_MIN, SAMSUNGAH_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &samsungah_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n\n#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1\n                    if (irmp_pulse_time >= MATSUSHITA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MATSUSHITA_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= MATSUSHITA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MATSUSHITA_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's MATSUSHITA\n                        ANALYZE_PRINTF5 (\"protocol = MATSUSHITA, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        MATSUSHITA_START_BIT_PULSE_LEN_MIN, MATSUSHITA_START_BIT_PULSE_LEN_MAX,\n                                        MATSUSHITA_START_BIT_PAUSE_LEN_MIN, MATSUSHITA_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &matsushita_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n                    if (irmp_pulse_time >= KASEIKYO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= KASEIKYO_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= KASEIKYO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KASEIKYO_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's KASEIKYO\n                        ANALYZE_PRINTF5 (\"protocol = KASEIKYO, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        KASEIKYO_START_BIT_PULSE_LEN_MIN, KASEIKYO_START_BIT_PULSE_LEN_MAX,\n                                        KASEIKYO_START_BIT_PAUSE_LEN_MIN, KASEIKYO_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &kaseikyo_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n\n#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1\n                    if (irmp_pulse_time >= PANASONIC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= PANASONIC_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= PANASONIC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= PANASONIC_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's PANASONIC\n                        ANALYZE_PRINTF5 (\"protocol = PANASONIC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        PANASONIC_START_BIT_PULSE_LEN_MIN, PANASONIC_START_BIT_PULSE_LEN_MAX,\n                                        PANASONIC_START_BIT_PAUSE_LEN_MIN, PANASONIC_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &panasonic_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_PANASONIC_PROTOCOL == 1\n\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n                    if (irmp_pulse_time >= MITSU_HEAVY_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MITSU_HEAVY_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's MITSU_HEAVY\n                        ANALYZE_PRINTF5 (\"protocol = MITSU_HEAVY, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        MITSU_HEAVY_START_BIT_PULSE_LEN_MIN, MITSU_HEAVY_START_BIT_PULSE_LEN_MAX,\n                                        MITSU_HEAVY_START_BIT_PAUSE_LEN_MIN, MITSU_HEAVY_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &mitsu_heavy_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n\n#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\n                    if (irmp_pulse_time >= VINCENT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= VINCENT_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= VINCENT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= VINCENT_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's VINCENT\n                        ANALYZE_PRINTF5 (\"protocol = VINCENT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        VINCENT_START_BIT_PULSE_LEN_MIN, VINCENT_START_BIT_PULSE_LEN_MAX,\n                                        VINCENT_START_BIT_PAUSE_LEN_MIN, VINCENT_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &vincent_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_VINCENT_PROTOCOL == 1\n\n#if IRMP_SUPPORT_METZ_PROTOCOL == 1\n                    if (irmp_pulse_time >= METZ_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= METZ_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= METZ_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= METZ_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = METZ, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        METZ_START_BIT_PULSE_LEN_MIN, METZ_START_BIT_PULSE_LEN_MAX,\n                                        METZ_START_BIT_PAUSE_LEN_MIN, METZ_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &metz_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_METZ_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1                                         // RF_GEN24 has no start bit\n                    if (irmp_pulse_time >= RF_GEN24_0_PULSE_LEN_MIN && irmp_pulse_time <= RF_GEN24_0_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RF_GEN24_0_PAUSE_LEN_MIN && irmp_pause_time <= RF_GEN24_0_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF1 (\"protocol = RF_GEN24\\n\");\n                        irmp_param_p = (IRMP_PARAMETER *) &rf_gen24_param;\n                        bit_0 = 0;\n                    }\n                    else\n                    if (irmp_pulse_time >= RF_GEN24_1_PULSE_LEN_MIN && irmp_pulse_time <= RF_GEN24_1_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RF_GEN24_1_PAUSE_LEN_MIN && irmp_pause_time <= RF_GEN24_1_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF1 (\"protocol = RF_GEN24\\n\");\n                        irmp_param_p = (IRMP_PARAMETER *) &rf_gen24_param;\n                        bit_0 = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RF_X10_PROTOCOL == 1\n                    if (irmp_pulse_time >= RF_X10_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RF_X10_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RF_X10_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RF_X10_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = RF_X10, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RF_X10_START_BIT_PULSE_LEN_MIN, RF_X10_START_BIT_PULSE_LEN_MAX,\n                                        RF_X10_START_BIT_PAUSE_LEN_MIN, RF_X10_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &rf_x10_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RF_X10_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n                    if (irmp_pulse_time >= RF_MEDION_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RF_MEDION_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RF_MEDION_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RF_MEDION_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = RF_MEDION, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RF_MEDION_START_BIT_PULSE_LEN_MIN, RF_MEDION_START_BIT_PULSE_LEN_MAX,\n                                        RF_MEDION_START_BIT_PAUSE_LEN_MIN, RF_MEDION_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &rf_medion_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RECS80_PROTOCOL == 1\n                    if (irmp_pulse_time >= RECS80_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RECS80_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's RECS80\n                        ANALYZE_PRINTF5 (\"protocol = RECS80, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RECS80_START_BIT_PULSE_LEN_MIN, RECS80_START_BIT_PULSE_LEN_MAX,\n                                        RECS80_START_BIT_PAUSE_LEN_MIN, RECS80_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &recs80_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1\n\n#if IRMP_SUPPORT_S100_PROTOCOL == 1\n                    if (((irmp_pulse_time >= S100_START_BIT_LEN_MIN     && irmp_pulse_time <= S100_START_BIT_LEN_MAX) ||\n                         (irmp_pulse_time >= 2 * S100_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * S100_START_BIT_LEN_MAX)) &&\n                        ((irmp_pause_time >= S100_START_BIT_LEN_MIN     && irmp_pause_time <= S100_START_BIT_LEN_MAX) ||\n                         (irmp_pause_time >= 2 * S100_START_BIT_LEN_MIN && irmp_pause_time <= 2 * S100_START_BIT_LEN_MAX)))\n                    {                                                           // it's S100\n                        ANALYZE_PRINTF9 (\"protocol = S100, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        S100_START_BIT_LEN_MIN, S100_START_BIT_LEN_MAX,\n                                        2 * S100_START_BIT_LEN_MIN, 2 * S100_START_BIT_LEN_MAX,\n                                        S100_START_BIT_LEN_MIN, S100_START_BIT_LEN_MAX,\n                                        2 * S100_START_BIT_LEN_MIN, 2 * S100_START_BIT_LEN_MAX);\n\n                        irmp_param_p = (IRMP_PARAMETER *) &s100_param;\n                        last_pause = irmp_pause_time;\n\n                        if ((irmp_pulse_time > S100_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * S100_START_BIT_LEN_MAX) ||\n                            (irmp_pause_time > S100_START_BIT_LEN_MAX && irmp_pause_time <= 2 * S100_START_BIT_LEN_MAX))\n                        {\n                          last_value  = 0;\n                          rc5_cmd_bit6 = 1<<6;\n                        }\n                        else\n                        {\n                          last_value  = 1;\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_S100_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1\n                    if (((irmp_pulse_time >= RC5_START_BIT_LEN_MIN     && irmp_pulse_time <= RC5_START_BIT_LEN_MAX) ||\n                         (irmp_pulse_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX)) &&\n                        ((irmp_pause_time >= RC5_START_BIT_LEN_MIN     && irmp_pause_time <= RC5_START_BIT_LEN_MAX) ||\n                         (irmp_pause_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)))\n                    {                                                           // it's RC5\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1\n                        if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX &&\n                            irmp_pause_time >= FDC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FDC_START_BIT_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PRINTF1 (\"protocol = RC5 or FDC\\n\");\n                            ANALYZE_PRINTF5 (\"FDC start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX,\n                                            FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX);\n                            ANALYZE_PRINTF5 (\"RC5 start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,\n                                            RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX);\n                            memcpy_P (&irmp_param2, &fdc_param, sizeof (IRMP_PARAMETER));\n                        }\n                        else\n#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n                        if (irmp_pulse_time >= RCCAR_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_START_BIT_PULSE_LEN_MAX &&\n                            irmp_pause_time >= RCCAR_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_START_BIT_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PRINTF1 (\"protocol = RC5 or RCCAR\\n\");\n                            ANALYZE_PRINTF5 (\"RCCAR start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX,\n                                            RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX);\n                            ANALYZE_PRINTF5 (\"RC5 start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,\n                                            RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX);\n                            memcpy_P (&irmp_param2, &rccar_param, sizeof (IRMP_PARAMETER));\n                        }\n                        else\n#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n                        {\n                            ANALYZE_PRINTF9 (\"protocol = RC5, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                            RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,\n                                            2 * RC5_START_BIT_LEN_MIN, 2 * RC5_START_BIT_LEN_MAX,\n                                            RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,\n                                            2 * RC5_START_BIT_LEN_MIN, 2 * RC5_START_BIT_LEN_MAX);\n                        }\n\n                        irmp_param_p = (IRMP_PARAMETER *) &rc5_param;\n                        last_pause = irmp_pause_time;\n\n                        if ((irmp_pulse_time > RC5_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX) ||\n                            (irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX))\n                        {\n                            last_value  = 0;\n                            rc5_cmd_bit6 = 1<<6;\n                        }\n                        else\n                        {\n                            last_value  = 1;\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_RC5_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RCII_PROTOCOL == 1\n                    if ((irmp_pulse_time >= RCII_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCII_START_BIT_PULSE_LEN_MAX) &&\n                        (irmp_pause_time >= RCII_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCII_START_BIT_PAUSE_LEN_MAX))\n                    {                                                           // it's RCII\n                        ANALYZE_PRINTF5 (\"protocol = RCII, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RCII_START_BIT_PULSE_LEN_MIN, RCII_START_BIT_PULSE_LEN_MAX,\n                                        RCII_START_BIT_PAUSE_LEN_MIN, RCII_START_BIT_PAUSE_LEN_MAX)\n                        irmp_param_p = (IRMP_PARAMETER *) &rcii_param;\n                        last_pause = irmp_pause_time;\n                        waiting_for_2nd_pulse = 1;\n                        last_value  = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RCII_PROTOCOL == 1\n\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n                    if ( (irmp_pulse_time >= DENON_PULSE_LEN_MIN && irmp_pulse_time <= DENON_PULSE_LEN_MAX) &&\n                        ((irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX) ||\n                         (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)))\n                    {                                                           // it's DENON\n                        ANALYZE_PRINTF7 (\"protocol = DENON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or %3d - %3d\\n\",\n                                        DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX,\n                                        DENON_1_PAUSE_LEN_MIN, DENON_1_PAUSE_LEN_MAX,\n                                        DENON_0_PAUSE_LEN_MIN, DENON_0_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &denon_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1\n\n#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n                    if ( (irmp_pulse_time >= THOMSON_PULSE_LEN_MIN && irmp_pulse_time <= THOMSON_PULSE_LEN_MAX) &&\n                        ((irmp_pause_time >= THOMSON_1_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_1_PAUSE_LEN_MAX) ||\n                         (irmp_pause_time >= THOMSON_0_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_0_PAUSE_LEN_MAX)))\n                    {                                                           // it's THOMSON\n                        ANALYZE_PRINTF7 (\"protocol = THOMSON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or %3d - %3d\\n\",\n                                        THOMSON_PULSE_LEN_MIN, THOMSON_PULSE_LEN_MAX,\n                                        THOMSON_1_PAUSE_LEN_MIN, THOMSON_1_PAUSE_LEN_MAX,\n                                        THOMSON_0_PAUSE_LEN_MIN, THOMSON_0_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &thomson_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n\n#if IRMP_SUPPORT_BOSE_PROTOCOL == 1\n                    if (irmp_pulse_time >= BOSE_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= BOSE_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= BOSE_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= BOSE_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = BOSE, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        BOSE_START_BIT_PULSE_LEN_MIN, BOSE_START_BIT_PULSE_LEN_MAX,\n                                        BOSE_START_BIT_PAUSE_LEN_MIN, BOSE_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &bose_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_BOSE_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n                    if (irmp_pulse_time >= RC6_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RC6_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RC6_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RC6_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's RC6\n                        ANALYZE_PRINTF5 (\"protocol = RC6, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RC6_START_BIT_PULSE_LEN_MIN, RC6_START_BIT_PULSE_LEN_MAX,\n                                        RC6_START_BIT_PAUSE_LEN_MIN, RC6_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &rc6_param;\n                        last_pause = 0;\n                        last_value = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1\n                    if (irmp_pulse_time >= RECS80EXT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80EXT_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RECS80EXT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80EXT_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's RECS80EXT\n                        ANALYZE_PRINTF5 (\"protocol = RECS80EXT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RECS80EXT_START_BIT_PULSE_LEN_MIN, RECS80EXT_START_BIT_PULSE_LEN_MAX,\n                                        RECS80EXT_START_BIT_PAUSE_LEN_MIN, RECS80EXT_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &recs80ext_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1\n\n#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1\n                    if (irmp_pulse_time >= NUBERT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NUBERT_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= NUBERT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NUBERT_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's NUBERT\n                        ANALYZE_PRINTF5 (\"protocol = NUBERT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        NUBERT_START_BIT_PULSE_LEN_MIN, NUBERT_START_BIT_PULSE_LEN_MAX,\n                                        NUBERT_START_BIT_PAUSE_LEN_MIN, NUBERT_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &nubert_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_NUBERT_PROTOCOL == 1\n\n#if IRMP_SUPPORT_FAN_PROTOCOL == 1\n                    if (irmp_pulse_time >= FAN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FAN_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= FAN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FAN_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's FAN\n                        ANALYZE_PRINTF5 (\"protocol = FAN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        FAN_START_BIT_PULSE_LEN_MIN, FAN_START_BIT_PULSE_LEN_MAX,\n                                        FAN_START_BIT_PAUSE_LEN_MIN, FAN_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &fan_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_FAN_PROTOCOL == 1\n\n#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1\n                    if (irmp_pulse_time >= SPEAKER_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SPEAKER_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= SPEAKER_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SPEAKER_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's SPEAKER\n                        ANALYZE_PRINTF5 (\"protocol = SPEAKER, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        SPEAKER_START_BIT_PULSE_LEN_MIN, SPEAKER_START_BIT_PULSE_LEN_MAX,\n                                        SPEAKER_START_BIT_PAUSE_LEN_MIN, SPEAKER_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &speaker_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_SPEAKER_PROTOCOL == 1\n\n#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n                    if (irmp_pulse_time >= BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN && irmp_pulse_time <= BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX &&\n                        irmp_pause_time >= BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX)\n                    {                                                           // it's BANG_OLUFSEN\n                        ANALYZE_PRINTF1 (\"protocol = BANG_OLUFSEN\\n\");\n                        ANALYZE_PRINTF5 (\"start bit 1 timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX,\n                                        BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX);\n                        ANALYZE_PRINTF5 (\"start bit 2 timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX,\n                                        BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX);\n                        ANALYZE_PRINTF5 (\"start bit 3 timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX,\n                                        BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX);\n                        ANALYZE_PRINTF5 (\"start bit 4 timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX,\n                                        BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &bang_olufsen_param;\n                        last_value = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n\n#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1\n                    if (irmp_pulse_time >= GRUNDIG_NOKIA_IR60_START_BIT_LEN_MIN && irmp_pulse_time <= GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX &&\n                        irmp_pause_time >= GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN && irmp_pause_time <= GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX)\n                    {                                                           // it's GRUNDIG\n                        ANALYZE_PRINTF5 (\"protocol = GRUNDIG, pre bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        GRUNDIG_NOKIA_IR60_START_BIT_LEN_MIN, GRUNDIG_NOKIA_IR60_START_BIT_LEN_MAX,\n                                        GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MIN, GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &grundig_param;\n                        last_pause = irmp_pause_time;\n                        last_value  = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1\n\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1 // check MERLIN before RUWIDO!\n                    if (irmp_pulse_time >= MERLIN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MERLIN_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= MERLIN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MERLIN_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's MERLIN\n                        ANALYZE_PRINTF5 (\"protocol = MERLIN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        MERLIN_START_BIT_PULSE_LEN_MIN, MERLIN_START_BIT_PULSE_LEN_MAX,\n                                        MERLIN_START_BIT_PAUSE_LEN_MIN, MERLIN_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &merlin_param;\n                        last_pause = irmp_pause_time;\n                        last_value = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n\n#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\n                    if (((irmp_pulse_time >= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX) ||\n                         (irmp_pulse_time >= 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX)) &&\n                        ((irmp_pause_time >= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX) ||\n                         (irmp_pause_time >= 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX)))\n                    {                                                           // it's RUWIDO or SIEMENS\n                        ANALYZE_PRINTF9 (\"protocol = RUWIDO, start bit timings: pulse: %3d - %3d or %3d - %3d, pause: %3d - %3d or %3d - %3d\\n\",\n                                        SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN,   SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX,\n                                        2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_START_BIT_PULSE_LEN_MAX,\n                                        SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN,   SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX,\n                                        2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MIN, 2 * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &ruwido_param;\n                        last_pause = irmp_pause_time;\n                        last_value  = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\n\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1\n                    if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= FDC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FDC_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = FDC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX,\n                                        FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &fdc_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n                    if (irmp_pulse_time >= RCCAR_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RCCAR_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = RCCAR, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX,\n                                        RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &rccar_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n                    if (irmp_pulse_time >= KATHREIN_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= KATHREIN_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= KATHREIN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KATHREIN_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's KATHREIN\n                        ANALYZE_PRINTF5 (\"protocol = KATHREIN, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        KATHREIN_START_BIT_PULSE_LEN_MIN, KATHREIN_START_BIT_PULSE_LEN_MAX,\n                                        KATHREIN_START_BIT_PAUSE_LEN_MIN, KATHREIN_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &kathrein_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n\n#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n                    if (irmp_pulse_time >= NETBOX_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NETBOX_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= NETBOX_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NETBOX_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's NETBOX\n                        ANALYZE_PRINTF5 (\"protocol = NETBOX, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        NETBOX_START_BIT_PULSE_LEN_MIN, NETBOX_START_BIT_PULSE_LEN_MAX,\n                                        NETBOX_START_BIT_PAUSE_LEN_MIN, NETBOX_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &netbox_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n\n#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\n                    if (irmp_pulse_time >= LEGO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= LEGO_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= LEGO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= LEGO_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = LEGO, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        LEGO_START_BIT_PULSE_LEN_MIN, LEGO_START_BIT_PULSE_LEN_MAX,\n                                        LEGO_START_BIT_PAUSE_LEN_MIN, LEGO_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &lego_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_LEGO_PROTOCOL == 1\n\n#if IRMP_SUPPORT_IRMP16_PROTOCOL == 1\n                    if (irmp_pulse_time >= IRMP16_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= IRMP16_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= IRMP16_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= IRMP16_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = IRMP16, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        IRMP16_START_BIT_PULSE_LEN_MIN, IRMP16_START_BIT_PULSE_LEN_MAX,\n                                        IRMP16_START_BIT_PAUSE_LEN_MIN, IRMP16_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &irmp16_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_IRMP16_PROTOCOL == 1\n\n#if IRMP_SUPPORT_GREE_PROTOCOL == 1\n                    if (irmp_pulse_time >= GREE_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= GREE_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= GREE_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= GREE_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF5 (\"protocol = GREE, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        GREE_START_BIT_PULSE_LEN_MIN, GREE_START_BIT_PULSE_LEN_MAX,\n                                        GREE_START_BIT_PAUSE_LEN_MIN, GREE_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &gree_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_GREE_PROTOCOL == 1\n\n#if IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1\n                    if (irmp_pulse_time >= A1TVBOX_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= A1TVBOX_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= A1TVBOX_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= A1TVBOX_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's A1TVBOX\n                        ANALYZE_PRINTF5 (\"protocol = A1TVBOX, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        A1TVBOX_START_BIT_PULSE_LEN_MIN, A1TVBOX_START_BIT_PULSE_LEN_MAX,\n                                        A1TVBOX_START_BIT_PAUSE_LEN_MIN, A1TVBOX_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &a1tvbox_param;\n                        last_pause = 0;\n                        last_value = 1;\n                    }\n                    else\n#endif // IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n                    if (irmp_pulse_time >= ORTEK_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= ORTEK_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= ORTEK_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= ORTEK_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's ORTEK (Hama)\n                        ANALYZE_PRINTF5 (\"protocol = ORTEK, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        ORTEK_START_BIT_PULSE_LEN_MIN, ORTEK_START_BIT_PULSE_LEN_MAX,\n                                        ORTEK_START_BIT_PAUSE_LEN_MIN, ORTEK_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &ortek_param;\n                        last_pause  = 0;\n                        last_value  = 1;\n                        parity      = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RCMM_PROTOCOL == 1\n                    if (irmp_pulse_time >= RCMM32_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCMM32_START_BIT_PULSE_LEN_MAX &&\n                        irmp_pause_time >= RCMM32_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_START_BIT_PAUSE_LEN_MAX)\n                    {                                                           // it's RCMM\n                        ANALYZE_PRINTF5 (\"protocol = RCMM, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\\n\",\n                                        RCMM32_START_BIT_PULSE_LEN_MIN, RCMM32_START_BIT_PULSE_LEN_MAX,\n                                        RCMM32_START_BIT_PAUSE_LEN_MIN, RCMM32_START_BIT_PAUSE_LEN_MAX);\n                        irmp_param_p = (IRMP_PARAMETER *) &rcmm_param;\n                    }\n                    else\n#endif // IRMP_SUPPORT_RCMM_PROTOCOL == 1\n                    {\n                        ANALYZE_PRINTF1 (\"protocol = UNKNOWN\\n\");\n                        irmp_start_bit_detected = 0;                            // wait for another start bit...\n                        irmp_param.protocol = 0;                                // reset protocol\n                    }\n\n                    if (irmp_start_bit_detected)\n                    {\n                        memcpy_P (&irmp_param, irmp_param_p, sizeof (IRMP_PARAMETER));\n\n                        if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))\n                        {\n                            ANALYZE_PRINTF3 (\"pulse_1: %3d - %3d\\n\", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max);\n                            ANALYZE_PRINTF3 (\"pause_1: %3d - %3d\\n\", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max);\n                        }\n                        else\n                        {\n                            ANALYZE_PRINTF5 (\"pulse: %3d - %3d or %3d - %3d\\n\", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max,\n                                            2 * irmp_param.pulse_1_len_min, 2 * irmp_param.pulse_1_len_max);\n                            ANALYZE_PRINTF5 (\"pause: %3d - %3d or %3d - %3d\\n\", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max,\n                                            2 * irmp_param.pause_1_len_min, 2 * irmp_param.pause_1_len_max);\n                        }\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\n                        if (irmp_param2.protocol)\n                        {\n                            ANALYZE_PRINTF3 (\"pulse_0: %3d - %3d\\n\", irmp_param2.pulse_0_len_min, irmp_param2.pulse_0_len_max);\n                            ANALYZE_PRINTF3 (\"pause_0: %3d - %3d\\n\", irmp_param2.pause_0_len_min, irmp_param2.pause_0_len_max);\n                            ANALYZE_PRINTF3 (\"pulse_1: %3d - %3d\\n\", irmp_param2.pulse_1_len_min, irmp_param2.pulse_1_len_max);\n                            ANALYZE_PRINTF3 (\"pause_1: %3d - %3d\\n\", irmp_param2.pause_1_len_min, irmp_param2.pause_1_len_max);\n                        }\n#endif\n\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_RC6_PROTOCOL)\n                        {\n                            ANALYZE_PRINTF3 (\"pulse_toggle: %3d - %3d\\n\", RC6_TOGGLE_BIT_LEN_MIN, RC6_TOGGLE_BIT_LEN_MAX);\n                        }\n#endif\n\n                        if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))\n                        {\n                            ANALYZE_PRINTF3 (\"pulse_0: %3d - %3d\\n\", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);\n                            ANALYZE_PRINTF3 (\"pause_0: %3d - %3d\\n\", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max);\n                        }\n                        else\n                        {\n                            ANALYZE_PRINTF5 (\"pulse: %3d - %3d or %3d - %3d\\n\", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max,\n                                            2 * irmp_param.pulse_0_len_min, 2 * irmp_param.pulse_0_len_max);\n                            ANALYZE_PRINTF5 (\"pause: %3d - %3d or %3d - %3d\\n\", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max,\n                                            2 * irmp_param.pause_0_len_min, 2 * irmp_param.pause_0_len_max);\n                        }\n\n#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_BANG_OLUFSEN_PROTOCOL)\n                        {\n                            ANALYZE_PRINTF3 (\"pulse_r: %3d - %3d\\n\", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);\n                            ANALYZE_PRINTF3 (\"pause_r: %3d - %3d\\n\", BANG_OLUFSEN_R_PAUSE_LEN_MIN, BANG_OLUFSEN_R_PAUSE_LEN_MAX);\n                        }\n#endif\n\n                        ANALYZE_PRINTF2 (\"command_offset: %2d\\n\", irmp_param.command_offset);\n                        ANALYZE_PRINTF2 (\"command_len:    %3d\\n\", irmp_param.command_end - irmp_param.command_offset);\n                        ANALYZE_PRINTF2 (\"complete_len:   %3d\\n\", irmp_param.complete_len);\n                        ANALYZE_PRINTF2 (\"stop_bit:       %3d\\n\", irmp_param.stop_bit);\n                    }\n\n#if IRMP_SUPPORT_MANCHESTER == 1\n                    if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) &&\n                         irmp_param.protocol != IRMP_RUWIDO_PROTOCOL && // Manchester, but not RUWIDO\n                         irmp_param.protocol != IRMP_RC6_PROTOCOL /*** &&    // Manchester, but not RC6\n                         irmp_param.protocol != IRMP_RCII_PROTOCOL ****/)     // Manchester, but not RCII\n                    {\n                        if (irmp_pause_time > irmp_param.pulse_1_len_max && irmp_pause_time <= 2 * irmp_param.pulse_1_len_max)\n                        {\n                            ANALYZE_PRINTF5 (\"%8.3fms [bit %2d: pulse = %3d, pause = %3d] \", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time);\n                            ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1');\n                            ANALYZE_NEWLINE ();\n                            irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 0 : 1);\n                        }\n                        else if (! last_value)  // && irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max)\n                        {\n                            ANALYZE_PRINTF5 (\"%8.3fms [bit %2d: pulse = %3d, pause = %3d] \", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time);\n                            ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '1' : '0');\n                            ANALYZE_NEWLINE ();\n                            irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0);\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_MANCHESTER == 1\n\n#if IRMP_SUPPORT_SERIAL == 1\n                    if (irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL)\n                    {\n                        ; // do nothing\n                    }\n                    else\n#endif // IRMP_SUPPORT_SERIAL == 1\n\n\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_DENON_PROTOCOL)\n                    {\n                        ANALYZE_PRINTF5 (\"%8.3fms [bit %2d: pulse = %3d, pause = %3d] \", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time);\n\n                        if (irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX)\n                        {                                                       // pause timings correct for \"1\"?\n                            ANALYZE_PUTCHAR ('1');                              // yes, store 1\n                            ANALYZE_NEWLINE ();\n                            irmp_store_bit (1);\n                        }\n                        else // if (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)\n                        {                                                       // pause timings correct for \"0\"?\n                            ANALYZE_PUTCHAR ('0');                              // yes, store 0\n                            ANALYZE_NEWLINE ();\n                            irmp_store_bit (0);\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1\n#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_THOMSON_PROTOCOL)\n                    {\n                        ANALYZE_PRINTF5 (\"%8.3fms [bit %2d: pulse = %3d, pause = %3d] \", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time);\n\n                        if (irmp_pause_time >= THOMSON_1_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_1_PAUSE_LEN_MAX)\n                        {                                                       // pause timings correct for \"1\"?\n                          ANALYZE_PUTCHAR ('1');                                // yes, store 1\n                          ANALYZE_NEWLINE ();\n                          irmp_store_bit (1);\n                        }\n                        else // if (irmp_pause_time >= THOMSON_0_PAUSE_LEN_MIN && irmp_pause_time <= THOMSON_0_PAUSE_LEN_MAX)\n                        {                                                       // pause timings correct for \"0\"?\n                          ANALYZE_PUTCHAR ('0');                                // yes, store 0\n                          ANALYZE_NEWLINE ();\n                          irmp_store_bit (0);\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n#if IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n                    if (irmp_param.protocol == RF_GEN24_PROTOCOL)\n                    {\n                        ANALYZE_PRINTF5 (\"%8.3fms [bit %2d: pulse = %3d, pause = %3d] \", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time);\n                        ANALYZE_PUTCHAR (bit_0 + '0');\n                        ANALYZE_NEWLINE ();\n                        irmp_store_bit (bit_0);                                 // start bit is data bit\n                    }\n                    else\n#endif // IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n                    {\n                        ;                                                       // else do nothing\n                    }\n\n                    irmp_pulse_time = 1;                                        // set counter to 1, not 0\n                    irmp_pause_time = 0;\n                    wait_for_start_space = 0;\n                }\n            }\n            else if (wait_for_space)                                            // the data section....\n            {                                                                   // counting the time of darkness....\n                uint_fast8_t got_light = FALSE;\n\n                if (irmp_input)                                                 // still dark?\n                {                                                               // yes...\n                    irmp_pause_time++;                                          // increment counter\n\n                    if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 1 && irmp_pause_time > ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) ? 0 : STOP_BIT_PAUSE_LEN_MIN))\n                    {\n                        if (\n#if IRMP_SUPPORT_MANCHESTER == 1\n                            (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) ||\n#endif\n#if IRMP_SUPPORT_SERIAL == 1\n                            (irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL) ||\n#endif\n                            (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max))\n                        {\n                            if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))\n                            {\n                                ANALYZE_PRINTF1 (\"stop bit detected\\n\");\n\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\n                                if (irmp_param.protocol == IRMP_MELINERA_PROTOCOL)\n                                {\n                                    irmp_tmp_command = irmp_melinera_command;  // set command\n                                    irmp_tmp_address = 0;                      // no address\n                                }\n#endif\n                            }\n\n                            irmp_param.stop_bit = 0;\n                        }\n                        else\n                        {\n                            ANALYZE_PRINTF5 (\"error: stop bit timing wrong, irmp_bit = %d, irmp_pulse_time = %d, pulse_0_len_min = %d, pulse_0_len_max = %d\\n\",\n                                            irmp_bit, irmp_pulse_time, irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);\n                            irmp_start_bit_detected = 0;                        // wait for another start bit...\n                            irmp_pulse_time         = 0;\n                            irmp_pause_time         = 0;\n                        }\n                    }\n                    else\n\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL &&                           // Sony has a variable number of bits:\n                        irmp_pause_time > SIRCS_PAUSE_LEN_MAX &&                                // minimum is 12\n                        irmp_bit >= 12 - 1)                                                     // pause too long?\n                    {                                                                           // yes, break and close this frame\n                        irmp_param.complete_len = irmp_bit + 1;                                 // set new complete length\n                        got_light = TRUE;                                                       // this is a lie, but helps (generates stop bit)\n                        irmp_tmp_address |= (irmp_bit - SIRCS_MINIMUM_DATA_LEN + 1) << 8;       // new: store number of additional bits in upper byte of address!\n                        irmp_param.command_end = irmp_param.command_offset + irmp_bit + 1;      // correct command length\n                        irmp_pause_time = SIRCS_PAUSE_LEN_MAX - 1;                              // correct pause length\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_MERLIN_PROTOCOL &&                          // Merlin has a variable number of bits:\n                        irmp_pause_time > MERLIN_START_BIT_PAUSE_LEN_MAX &&                     // minimum is 8\n                        irmp_bit >= 8 - 1)                                                      // pause too long?\n                    {                                                                           // yes, break and close this frame\n                        irmp_param.complete_len = irmp_bit;                                     // set new complete length\n                        got_light = TRUE;                                                       // this is a lie, but helps (generates stop bit)\n                        irmp_pause_time = MERLIN_BIT_PAUSE_LEN_MAX - 1;                         // correct pause length\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_FAN_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_FAN_PROTOCOL &&                             // FAN has no stop bit.\n                        irmp_bit >= FAN_COMPLETE_DATA_LEN - 1)                                  // last bit in frame\n                    {                                                                           // yes, break and close this frame\n                        if (irmp_pulse_time <= FAN_0_PULSE_LEN_MAX && irmp_pause_time >= FAN_0_PAUSE_LEN_MIN)\n                        {\n                            ANALYZE_PRINTF1 (\"Generating virtual stop bit\\n\");\n                            got_light = TRUE;                                                   // this is a lie, but helps (generates stop bit)\n                        }\n                        else if (irmp_pulse_time >= FAN_1_PULSE_LEN_MIN && irmp_pause_time >= FAN_1_PAUSE_LEN_MIN)\n                        {\n                            ANALYZE_PRINTF1 (\"Generating virtual stop bit\\n\");\n                            got_light = TRUE;                                                   // this is a lie, but helps (generates stop bit)\n                        }\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_SERIAL == 1\n                    // NETBOX generates no stop bit, here is the timeout condition:\n                    if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL) && irmp_param.protocol == IRMP_NETBOX_PROTOCOL &&\n                        irmp_pause_time >= NETBOX_PULSE_LEN * (NETBOX_COMPLETE_DATA_LEN - irmp_bit))\n                    {\n                        got_light = TRUE;                                                       // this is a lie, but helps (generates stop bit)\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_GRUNDIG_NOKIA_IR60_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL && !irmp_param.stop_bit)\n                    {\n                        if (irmp_pause_time > IR60_TIMEOUT_LEN && (irmp_bit == 5 || irmp_bit == 6))\n                        {\n                            ANALYZE_PRINTF1 (\"Switching to IR60 protocol\\n\");\n                            got_light = TRUE;                                       // this is a lie, but generates a stop bit ;-)\n                            irmp_param.stop_bit = TRUE;                             // set flag\n\n                            irmp_param.protocol         = IRMP_IR60_PROTOCOL;       // change protocol\n                            irmp_param.complete_len     = IR60_COMPLETE_DATA_LEN;   // correct complete len\n                            irmp_param.address_offset   = IR60_ADDRESS_OFFSET;\n                            irmp_param.address_end      = IR60_ADDRESS_OFFSET + IR60_ADDRESS_LEN;\n                            irmp_param.command_offset   = IR60_COMMAND_OFFSET;\n                            irmp_param.command_end      = IR60_COMMAND_OFFSET + IR60_COMMAND_LEN;\n\n                            irmp_tmp_command <<= 1;\n                            irmp_tmp_command |= first_bit;\n                        }\n                        else if (irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN - 2)\n                        {                                                           // special manchester decoder\n                            irmp_param.complete_len = GRUNDIG_COMPLETE_DATA_LEN;    // correct complete len\n                            got_light = TRUE;                                       // this is a lie, but generates a stop bit ;-)\n                            irmp_param.stop_bit = TRUE;                             // set flag\n                        }\n                        else if (irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN)\n                        {\n                            ANALYZE_PRINTF2 (\"Switching to NOKIA protocol, irmp_bit = %d\\n\", irmp_bit);\n                            irmp_param.protocol         = IRMP_NOKIA_PROTOCOL;      // change protocol\n                            irmp_param.address_offset   = NOKIA_ADDRESS_OFFSET;\n                            irmp_param.address_end      = NOKIA_ADDRESS_OFFSET + NOKIA_ADDRESS_LEN;\n                            irmp_param.command_offset   = NOKIA_COMMAND_OFFSET;\n                            irmp_param.command_end      = NOKIA_COMMAND_OFFSET + NOKIA_COMMAND_LEN;\n\n                            if (irmp_tmp_command & 0x300)\n                            {\n                                irmp_tmp_address = (irmp_tmp_command >> 8);\n                                irmp_tmp_command &= 0xFF;\n                            }\n                        }\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_SIEMENS_OR_RUWIDO_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_RUWIDO_PROTOCOL && !irmp_param.stop_bit)\n                    {\n                        if (irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= RUWIDO_COMPLETE_DATA_LEN - 2)\n                        {                                                           // special manchester decoder\n                            irmp_param.complete_len = RUWIDO_COMPLETE_DATA_LEN;     // correct complete len\n                            got_light = TRUE;                                       // this is a lie, but generates a stop bit ;-)\n                            irmp_param.stop_bit = TRUE;                             // set flag\n                        }\n                        else if (irmp_bit >= RUWIDO_COMPLETE_DATA_LEN)\n                        {\n                            ANALYZE_PRINTF1 (\"Switching to SIEMENS protocol\\n\");\n                            irmp_param.protocol         = IRMP_SIEMENS_PROTOCOL;    // change protocol\n                            irmp_param.address_offset   = SIEMENS_ADDRESS_OFFSET;\n                            irmp_param.address_end      = SIEMENS_ADDRESS_OFFSET + SIEMENS_ADDRESS_LEN;\n                            irmp_param.command_offset   = SIEMENS_COMMAND_OFFSET;\n                            irmp_param.command_end      = SIEMENS_COMMAND_OFFSET + SIEMENS_COMMAND_LEN;\n\n                            //                   76543210\n                            // RUWIDO:  AAAAAAAAACCCCCCCp\n                            // SIEMENS: AAAAAAAAAAACCCCCCCCCCp\n                            irmp_tmp_address <<= 2;\n                            irmp_tmp_address |= (irmp_tmp_command >> 6);\n                            irmp_tmp_command &= 0x003F;\n                            irmp_tmp_command |= last_value;\n                        }\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_ROOMBA_PROTOCOL &&                          // Roomba has no stop bit\n                        irmp_bit >= ROOMBA_COMPLETE_DATA_LEN - 1)                               // it's the last data bit...\n                    {                                                                           // break and close this frame\n                        if (irmp_pulse_time >= ROOMBA_1_PULSE_LEN_MIN && irmp_pulse_time <= ROOMBA_1_PULSE_LEN_MAX)\n                        {\n                            irmp_pause_time = ROOMBA_1_PAUSE_LEN_EXACT;\n                        }\n                        else if (irmp_pulse_time >= ROOMBA_0_PULSE_LEN_MIN && irmp_pulse_time <= ROOMBA_0_PULSE_LEN_MAX)\n                        {\n                            irmp_pause_time = ROOMBA_0_PAUSE_LEN;\n                        }\n\n                        got_light = TRUE;                                                       // this is a lie, but helps (generates stop bit)\n                    }\n                    else\n#endif\n#if IRMP_SUPPORT_MANCHESTER == 1\n                    if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) &&\n                        (irmp_param.protocol != IRMP_RC6_PROTOCOL || irmp_param.complete_len != RC6_COMPLETE_DATA_LEN_LONG) && // not RC6A\n                        irmp_pause_time >= 2 * irmp_param.pause_1_len_max && irmp_bit >= irmp_param.complete_len - 2 && !irmp_param.stop_bit)\n                    {                                                       // special manchester decoder\n                        got_light = TRUE;                                   // this is a lie, but generates a stop bit ;-)\n                        irmp_param.stop_bit = TRUE;                         // set flag\n                    }\n                    else if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) &&\n                        irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG && // RC6A\n                            irmp_pause_time >= 2 * irmp_param.pause_1_len_max) // this pause indicates the end\n                    {                                                       // special manchester decoder\n                        got_light = TRUE;                                   // this is a lie, but generates a stop bit ;-)\n                        irmp_param.stop_bit = TRUE;                         // set flag\n                        irmp_param.complete_len = irmp_bit + 1;             // at least 1 more bit will be added at last position\n                    }\n                    else\n#endif // IRMP_SUPPORT_MANCHESTER == 1\n                    if (irmp_pause_time > IRMP_TIMEOUT_LEN)                 // timeout?\n                    {                                                       // yes...\n                        if (irmp_bit == irmp_param.complete_len - 1 && irmp_param.stop_bit == 0)\n                        {\n                            irmp_bit++;\n                        }\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n                        else if ((irmp_param.protocol == IRMP_NEC_PROTOCOL || irmp_param.protocol == IRMP_NEC42_PROTOCOL) && irmp_bit == 0)\n                        {                                                               // it was a non-standard repetition frame\n                            ANALYZE_PRINTF1 (\"Detected non-standard repetition frame, switching to NEC repetition\\n\");\n                            if (key_repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)\n                            {\n                                irmp_param.stop_bit     = TRUE;                         // set flag\n                                irmp_param.protocol     = IRMP_NEC_PROTOCOL;            // switch protocol\n                                irmp_param.complete_len = irmp_bit;                     // patch length: 16 or 17\n                                irmp_tmp_address = last_irmp_address;                   // address is last address\n                                irmp_tmp_command = last_irmp_command;                   // command is last command\n                                irmp_flags |= IRMP_FLAG_REPETITION;\n                                key_repetition_len = 0;\n                            }\n                            else\n                            {\n                                ANALYZE_PRINTF3 (\"ignoring NEC repetition frame: timeout occured, key_repetition_len = %u > %u\\n\",\n                                                (unsigned int) key_repetition_len, (unsigned int) NEC_FRAME_REPEAT_PAUSE_LEN_MAX);\n                                irmp_ir_detected = FALSE;\n                            }\n                        }\n#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17))      // it was a JVC stop bit\n                        {\n                            ANALYZE_PRINTF2 (\"Switching to JVC protocol, irmp_bit = %d\\n\", irmp_bit);\n                            irmp_param.stop_bit     = TRUE;                                     // set flag\n                            irmp_param.protocol     = IRMP_JVC_PROTOCOL;                        // switch protocol\n                            irmp_param.complete_len = irmp_bit;                                 // patch length: 16 or 17\n                            irmp_tmp_command        = (irmp_tmp_address >> 4);                  // set command: upper 12 bits are command bits\n                            irmp_tmp_address        = irmp_tmp_address & 0x000F;                // lower 4 bits are address bits\n                            irmp_start_bit_detected = 1;                                        // tricky: don't wait for another start bit...\n                        }\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 28 || irmp_bit == 29))      // it was a LGAIR stop bit\n                        {\n                            ANALYZE_PRINTF2 (\"Switching to LGAIR protocol, irmp_bit = %d\\n\", irmp_bit);\n                            irmp_param.stop_bit     = TRUE;                                     // set flag\n                            irmp_param.protocol     = IRMP_LGAIR_PROTOCOL;                      // switch protocol\n                            irmp_param.complete_len = irmp_bit;                                 // patch length: 16 or 17\n                            irmp_tmp_command        = irmp_lgair_command;                       // set command: upper 8 bits are command bits\n                            irmp_tmp_address        = irmp_lgair_address;                       // lower 4 bits are address bits\n                            irmp_start_bit_detected = 1;                                        // tricky: don't wait for another start bit...\n                        }\n#endif // IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && irmp_bit == 32)      // it was a NEC stop bit\n                        {\n                            ANALYZE_PRINTF1 (\"Switching to NEC protocol\\n\");\n                            irmp_param.stop_bit     = TRUE;                                     // set flag\n                            irmp_param.protocol     = IRMP_NEC_PROTOCOL;                        // switch protocol\n                            irmp_param.complete_len = irmp_bit;                                 // patch length: 16 or 17\n\n                            //        0123456789ABC0123456789ABC0123456701234567\n                            // NEC42: AAAAAAAAAAAAAaaaaaaaaaaaaaCCCCCCCCcccccccc\n                            // NEC:   AAAAAAAAaaaaaaaaCCCCCCCCcccccccc\n                            irmp_tmp_address        |= (irmp_tmp_address2 & 0x0007) << 13;      // fm 2012-02-13: 12 -> 13\n                            irmp_tmp_command        = (irmp_tmp_address2 >> 3) | (irmp_tmp_command << 10);\n                        }\n#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && irmp_bit == 28)      // it was a NEC stop bit\n                        {\n                            ANALYZE_PRINTF1 (\"Switching to LGAIR protocol\\n\");\n                            irmp_param.stop_bit     = TRUE;                                     // set flag\n                            irmp_param.protocol     = IRMP_LGAIR_PROTOCOL;                      // switch protocol\n                            irmp_param.complete_len = irmp_bit;                                 // patch length: 16 or 17\n                            irmp_tmp_address        = irmp_lgair_address;\n                            irmp_tmp_command        = irmp_lgair_command;\n                        }\n#endif // IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_NEC42_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17))  // it was a JVC stop bit\n                        {\n                            ANALYZE_PRINTF2 (\"Switching to JVC protocol, irmp_bit = %d\\n\", irmp_bit);\n                            irmp_param.stop_bit     = TRUE;                                     // set flag\n                            irmp_param.protocol     = IRMP_JVC_PROTOCOL;                        // switch protocol\n                            irmp_param.complete_len = irmp_bit;                                 // patch length: 16 or 17\n\n                            //        0123456789ABC0123456789ABC0123456701234567\n                            // NEC42: AAAAAAAAAAAAAaaaaaaaaaaaaaCCCCCCCCcccccccc\n                            // JVC:   AAAACCCCCCCCCCCC\n                            irmp_tmp_command        = (irmp_tmp_address >> 4) | (irmp_tmp_address2 << 9);   // set command: upper 12 bits are command bits\n                            irmp_tmp_address        = irmp_tmp_address & 0x000F;                            // lower 4 bits are address bits\n                        }\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n#endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1\n\n#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL && irmp_bit == 32)          // it was a SAMSUNG32 stop bit\n                        {\n                            ANALYZE_PRINTF1 (\"Switching to SAMSUNG32 protocol\\n\");\n                            irmp_param.protocol         = IRMP_SAMSUNG32_PROTOCOL;\n                            irmp_param.command_offset   = SAMSUNG32_COMMAND_OFFSET;\n                            irmp_param.command_end      = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN;\n                            irmp_param.complete_len     = SAMSUNG32_COMPLETE_DATA_LEN;\n                        }\n#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n\n#if IRMP_SUPPORT_RCMM_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_RCMM32_PROTOCOL && (irmp_bit == 12 || irmp_bit == 24))  // it was a RCMM stop bit\n                        {\n                            if (irmp_bit == 12)\n                            {\n                                irmp_tmp_command = (irmp_tmp_address & 0xFF);                   // set command: lower 8 bits are command bits\n                                irmp_tmp_address >>= 8;                                         // upper 4 bits are address bits\n\n                                ANALYZE_PRINTF2 (\"Switching to RCMM12 protocol, irmp_bit = %d\\n\", irmp_bit);\n                                irmp_param.protocol     = IRMP_RCMM12_PROTOCOL;                 // switch protocol\n                            }\n                            else // if ((irmp_bit == 24)\n                            {\n                                ANALYZE_PRINTF2 (\"Switching to RCMM24 protocol, irmp_bit = %d\\n\", irmp_bit);\n                                irmp_param.protocol     = IRMP_RCMM24_PROTOCOL;                 // switch protocol\n                            }\n                            irmp_param.stop_bit     = TRUE;                                     // set flag\n                            irmp_param.complete_len = irmp_bit;                                 // patch length\n                        }\n#endif // IRMP_SUPPORT_RCMM_PROTOCOL == 1\n\n#if IRMP_SUPPORT_TECHNICS_PROTOCOL == 1\n                        else if (irmp_param.protocol == IRMP_MATSUSHITA_PROTOCOL && irmp_bit == 22)  // it was a TECHNICS stop bit\n                        {\n                            ANALYZE_PRINTF2 (\"Switching to TECHNICS protocol, irmp_bit = %d\\n\", irmp_bit);\n                            // Situation:\n                            // The first 12 bits have been stored in irmp_tmp_command (LSB first)\n                            // The following 10 bits have been stored in irmp_tmp_address (LSB first)\n                            // The code of TECHNICS is:\n                            //   cccccccccccCCCCCCCCCCC (11 times c and 11 times C)\n                            //   ccccccccccccaaaaaaaaaa\n                            // where C is inverted value of c\n\n                            irmp_tmp_address <<= 1;\n                            if (irmp_tmp_command & (1<<11))\n                            {\n                                irmp_tmp_address |= 1;\n                                irmp_tmp_command &= ~(1<<11);\n                            }\n\n                            if (irmp_tmp_command == ((~irmp_tmp_address) & 0x07FF))\n                            {\n                                irmp_tmp_address = 0;\n\n                                irmp_param.protocol     = IRMP_TECHNICS_PROTOCOL;                   // switch protocol\n                                irmp_param.complete_len = irmp_bit;                                 // patch length\n                            }\n                            else\n                            {\n                                ANALYZE_PRINTF1 (\"error 8: TECHNICS frame error\\n\");\n                                ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                                irmp_start_bit_detected = 0;                    // wait for another start bit...\n                                irmp_pulse_time         = 0;\n                                irmp_pause_time         = 0;\n                            }\n                        }\n#endif // IRMP_SUPPORT_TECHNICS_PROTOCOL == 1\n                        else\n                        {\n                            ANALYZE_PRINTF3 (\"error 2: pause %d after data bit %d too long\\n\", irmp_pause_time, irmp_bit);\n                            ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                            irmp_start_bit_detected = 0;                    // wait for another start bit...\n                            irmp_pulse_time         = 0;\n                            irmp_pause_time         = 0;\n                        }\n                    }\n                }\n                else\n                {                                                               // got light now!\n                    got_light = TRUE;\n                }\n\n                if (got_light)\n                {\n                    ANALYZE_PRINTF5 (\"%8.3fms [bit %2d: pulse = %3d, pause = %3d] \", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit, irmp_pulse_time, irmp_pause_time);\n\n#if IRMP_SUPPORT_MANCHESTER == 1\n                    if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))                                     // Manchester\n                    {\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n                        if (irmp_param.complete_len == irmp_bit && irmp_param.protocol == IRMP_MERLIN_PROTOCOL)\n                        {\n                            if (last_value == 0)\n                            {\n                                if (irmp_pulse_time >= 2 * irmp_param.pulse_1_len_min && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max &&\n                                    last_pause >= irmp_param.pause_1_len_min && last_pause <= irmp_param.pulse_1_len_max)\n                                {\n                                    irmp_param.complete_len += 2;\n                                    irmp_store_bit(0);\n                                    irmp_store_bit(1);\n                                    ANALYZE_PUTCHAR ('0');\n                                    ANALYZE_PUTCHAR ('1');\n                                    ANALYZE_NEWLINE ();\n                                }\n                            }\n                            else\n                            {\n                                if (last_pause >= 2 * irmp_param.pause_1_len_min && last_pause <= 2 * irmp_param.pulse_1_len_max)\n                                {\n                                    if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max)\n                                    {\n                                        irmp_param.complete_len++;\n                                        irmp_store_bit(0);\n                                        ANALYZE_PUTCHAR ('0');\n                                        ANALYZE_NEWLINE ();\n                                    }\n                                    else if (irmp_pulse_time >= 2 * irmp_param.pulse_1_len_min && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max)\n                                    {\n                                        irmp_param.complete_len += 2;\n                                        irmp_store_bit(0);\n                                        irmp_store_bit(1);\n                                        ANALYZE_PUTCHAR ('0');\n                                        ANALYZE_PUTCHAR ('1');\n                                        ANALYZE_NEWLINE ();\n                                    }\n                                }\n                            }\n                        }\n                        else\n#endif\n#if 1\n                        if (irmp_pulse_time > irmp_param.pulse_1_len_max /* && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max */)\n#else // better, but some IR-RCs use asymmetric timings :-/\n                        if (irmp_pulse_time > irmp_param.pulse_1_len_max && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max &&\n                            irmp_pause_time <= 2 * irmp_param.pause_1_len_max)\n#endif\n                        {\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n                            if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == irmp_bit + 1) // RC6A\n                            {\n                                    irmp_param.complete_len++; // this is the last position and 2 bits (instead of only 1) will be added\n                            }\n\n                            if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 4 && irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MIN)         // RC6 toggle bit\n                            {\n                                ANALYZE_PUTCHAR ('T');\n\n                                if (irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG)                      // RC6 mode 6A\n                                {\n                                    irmp_store_bit (1);\n                                    last_value = 1;\n                                }\n                                else                                                                            // RC6 mode 0\n                                {\n                                    irmp_store_bit (0);\n                                    last_value = 0;\n                                }\n                                ANALYZE_NEWLINE ();\n                            }\n                            else\n#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1\n                            {\n                                ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1');\n                                irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 0  :  1 );\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n                                if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 4 && irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MIN)      // RC6 toggle bit\n                                {\n                                    ANALYZE_PUTCHAR ('T');\n                                    irmp_store_bit (1);\n\n                                    if (irmp_pause_time > 2 * irmp_param.pause_1_len_max)\n                                    {\n                                        last_value = 0;\n                                    }\n                                    else\n                                    {\n                                        last_value = 1;\n                                    }\n                                    ANALYZE_NEWLINE ();\n                                }\n                                else\n#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1\n                                {\n                                    ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '1' : '0');\n                                    irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 :   0 );\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCII_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\n                                    if (! irmp_param2.protocol)\n#endif\n                                    {\n                                        ANALYZE_NEWLINE ();\n                                    }\n                                    last_value = (irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0;\n                                }\n                            }\n                        }\n                        else if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max\n                                 /* && irmp_pause_time <= 2 * irmp_param.pause_1_len_max */)\n                        {\n                            uint_fast8_t manchester_value;\n\n                            if (last_pause > irmp_param.pause_1_len_max && last_pause <= 2 * irmp_param.pause_1_len_max)\n                            {\n                                manchester_value = last_value ? 0 : 1;\n                                last_value  = manchester_value;\n                            }\n                            else\n                            {\n                                manchester_value = last_value;\n                            }\n\n                            ANALYZE_PUTCHAR (manchester_value + '0');\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)\n                            if (! irmp_param2.protocol)\n#endif\n                            {\n                                ANALYZE_NEWLINE ();\n                            }\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n                            if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 1 && manchester_value == 1)     // RC6 mode != 0 ???\n                            {\n                                ANALYZE_PRINTF1 (\"Switching to RC6A protocol\\n\");\n                                irmp_param.complete_len = RC6_COMPLETE_DATA_LEN_LONG;\n                                irmp_param.address_offset = 5;\n                                irmp_param.address_end = irmp_param.address_offset + 15;\n                                irmp_param.command_offset = irmp_param.address_end + 1;                                 // skip 1 system bit, changes like a toggle bit\n                                irmp_param.command_end = irmp_param.command_offset + 16 - 1;\n                                irmp_tmp_address = 0;\n                            }\n#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1\n\n                            irmp_store_bit (manchester_value);\n                        }\n                        else\n                        {\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_FDC_PROTOCOL == 1\n                            if (irmp_param2.protocol == IRMP_FDC_PROTOCOL &&\n                                irmp_pulse_time >= FDC_PULSE_LEN_MIN && irmp_pulse_time <= FDC_PULSE_LEN_MAX &&\n                                ((irmp_pause_time >= FDC_1_PAUSE_LEN_MIN && irmp_pause_time <= FDC_1_PAUSE_LEN_MAX) ||\n                                 (irmp_pause_time >= FDC_0_PAUSE_LEN_MIN && irmp_pause_time <= FDC_0_PAUSE_LEN_MAX)))\n                            {\n                                ANALYZE_PUTCHAR ('?');\n                                irmp_param.protocol = 0;                // switch to FDC, see below\n                            }\n                            else\n#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n                            if (irmp_param2.protocol == IRMP_RCCAR_PROTOCOL &&\n                                irmp_pulse_time >= RCCAR_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_PULSE_LEN_MAX &&\n                                ((irmp_pause_time >= RCCAR_1_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_1_PAUSE_LEN_MAX) ||\n                                 (irmp_pause_time >= RCCAR_0_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_0_PAUSE_LEN_MAX)))\n                            {\n                                ANALYZE_PUTCHAR ('?');\n                                irmp_param.protocol = 0;                // switch to RCCAR, see below\n                            }\n                            else\n#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n                            {\n                                ANALYZE_PUTCHAR ('?');\n                                ANALYZE_NEWLINE ();\n                                ANALYZE_PRINTF4 (\"error 3 manchester: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                                ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                                irmp_start_bit_detected = 0;                            // reset flags and wait for next start bit\n                                irmp_pause_time         = 0;\n                            }\n                        }\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_FDC_PROTOCOL == 1\n                        if (irmp_param2.protocol == IRMP_FDC_PROTOCOL && irmp_pulse_time >= FDC_PULSE_LEN_MIN && irmp_pulse_time <= FDC_PULSE_LEN_MAX)\n                        {\n                            if (irmp_pause_time >= FDC_1_PAUSE_LEN_MIN && irmp_pause_time <= FDC_1_PAUSE_LEN_MAX)\n                            {\n                                ANALYZE_PRINTF1 (\"   1 (FDC)\\n\");\n                                irmp_store_bit2 (1);\n                            }\n                            else if (irmp_pause_time >= FDC_0_PAUSE_LEN_MIN && irmp_pause_time <= FDC_0_PAUSE_LEN_MAX)\n                            {\n                                ANALYZE_PRINTF1 (\"   0 (FDC)\\n\");\n                                irmp_store_bit2 (0);\n                            }\n\n                            if (! irmp_param.protocol)\n                            {\n                                ANALYZE_PRINTF1 (\"Switching to FDC protocol\\n\");\n                                memcpy (&irmp_param, &irmp_param2, sizeof (IRMP_PARAMETER));\n                                irmp_param2.protocol = 0;\n                                irmp_tmp_address = irmp_tmp_address2;\n                                irmp_tmp_command = irmp_tmp_command2;\n                            }\n                        }\n#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n                        if (irmp_param2.protocol == IRMP_RCCAR_PROTOCOL && irmp_pulse_time >= RCCAR_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_PULSE_LEN_MAX)\n                        {\n                            if (irmp_pause_time >= RCCAR_1_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_1_PAUSE_LEN_MAX)\n                            {\n                                ANALYZE_PRINTF1 (\"   1 (RCCAR)\\n\");\n                                irmp_store_bit2 (1);\n                            }\n                            else if (irmp_pause_time >= RCCAR_0_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_0_PAUSE_LEN_MAX)\n                            {\n                                ANALYZE_PRINTF1 (\"   0 (RCCAR)\\n\");\n                                irmp_store_bit2 (0);\n                            }\n\n                            if (! irmp_param.protocol)\n                            {\n                                ANALYZE_PRINTF1 (\"Switching to RCCAR protocol\\n\");\n                                memcpy (&irmp_param, &irmp_param2, sizeof (IRMP_PARAMETER));\n                                irmp_param2.protocol = 0;\n                                irmp_tmp_address = irmp_tmp_address2;\n                                irmp_tmp_command = irmp_tmp_command2;\n                            }\n                        }\n#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n\n                        last_pause      = irmp_pause_time;\n                        wait_for_space  = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_MANCHESTER == 1\n\n#if IRMP_SUPPORT_SERIAL == 1\n                    if (irmp_param.flags & IRMP_PARAM_FLAG_IS_SERIAL)\n                    {\n                        while (irmp_bit < irmp_param.complete_len && irmp_pulse_time > irmp_param.pulse_1_len_max)\n                        {\n                            ANALYZE_PUTCHAR ('1');\n                            irmp_store_bit (1);\n\n                            if (irmp_pulse_time >= irmp_param.pulse_1_len_min)\n                            {\n                                irmp_pulse_time -= irmp_param.pulse_1_len_min;\n                            }\n                            else\n                            {\n                                irmp_pulse_time = 0;\n                            }\n                        }\n\n                        while (irmp_bit < irmp_param.complete_len && irmp_pause_time > irmp_param.pause_1_len_max)\n                        {\n                            ANALYZE_PUTCHAR ('0');\n                            irmp_store_bit (0);\n\n                            if (irmp_pause_time >= irmp_param.pause_1_len_min)\n                            {\n                                irmp_pause_time -= irmp_param.pause_1_len_min;\n                            }\n                            else\n                            {\n                                irmp_pause_time = 0;\n                            }\n                        }\n                        ANALYZE_NEWLINE ();\n                        wait_for_space = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_SERIAL == 1\n\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit == 16)       // Samsung: 16th bit\n                    {\n                        if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX &&\n                            irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PRINTF1 (\"SYNC\\n\");\n                            wait_for_space = 0;\n                            irmp_bit++;\n                        }\n                        else  if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX)\n                        {\n#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\n                            ANALYZE_PRINTF1 (\"Switching to SAMSUNG48 protocol \");\n                            irmp_param.protocol         = IRMP_SAMSUNG48_PROTOCOL;\n                            irmp_param.command_offset   = SAMSUNG48_COMMAND_OFFSET;\n                            irmp_param.command_end      = SAMSUNG48_COMMAND_OFFSET + SAMSUNG48_COMMAND_LEN;\n                            irmp_param.complete_len     = SAMSUNG48_COMPLETE_DATA_LEN;\n#else\n                            ANALYZE_PRINTF1 (\"Switching to SAMSUNG32 protocol \");\n                            irmp_param.protocol         = IRMP_SAMSUNG32_PROTOCOL;\n                            irmp_param.command_offset   = SAMSUNG32_COMMAND_OFFSET;\n                            irmp_param.command_end      = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN;\n                            irmp_param.complete_len     = SAMSUNG32_COMPLETE_DATA_LEN;\n#endif\n                            if (irmp_pause_time >= SAMSUNG_1_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_1_PAUSE_LEN_MAX)\n                            {\n                                ANALYZE_PUTCHAR ('1');\n                                ANALYZE_NEWLINE ();\n                                irmp_store_bit (1);\n                                wait_for_space = 0;\n                            }\n                            else\n                            {\n                                ANALYZE_PUTCHAR ('0');\n                                ANALYZE_NEWLINE ();\n                                irmp_store_bit (0);\n                                wait_for_space = 0;\n                            }\n                        }\n                        else\n                        {                                                           // timing incorrect!\n                            ANALYZE_PRINTF4 (\"error 3 Samsung: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                            ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                            irmp_start_bit_detected = 0;                            // reset flags and wait for next start bit\n                            irmp_pause_time         = 0;\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL\n\n#if IRMP_SUPPORT_NEC16_PROTOCOL\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_NEC42_PROTOCOL &&\n#else // IRMP_SUPPORT_NEC_PROTOCOL instead\n                    if (irmp_param.protocol == IRMP_NEC_PROTOCOL &&\n#endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1\n                        irmp_bit == 8 && irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX)\n                    {\n                        ANALYZE_PRINTF1 (\"Switching to NEC16 protocol\\n\");\n                        irmp_param.protocol         = IRMP_NEC16_PROTOCOL;\n                        irmp_param.address_offset   = NEC16_ADDRESS_OFFSET;\n                        irmp_param.address_end      = NEC16_ADDRESS_OFFSET + NEC16_ADDRESS_LEN;\n                        irmp_param.command_offset   = NEC16_COMMAND_OFFSET;\n                        irmp_param.command_end      = NEC16_COMMAND_OFFSET + NEC16_COMMAND_LEN;\n                        irmp_param.complete_len     = NEC16_COMPLETE_DATA_LEN;\n                        wait_for_space = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_NEC16_PROTOCOL\n\n#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_BANG_OLUFSEN_PROTOCOL)\n                    {\n                        if (irmp_pulse_time >= BANG_OLUFSEN_PULSE_LEN_MIN && irmp_pulse_time <= BANG_OLUFSEN_PULSE_LEN_MAX)\n                        {\n                            if (irmp_bit == 1)                                      // Bang & Olufsen: 3rd bit\n                            {\n                                if (irmp_pause_time >= BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX)\n                                {\n                                    ANALYZE_PRINTF1 (\"3rd start bit\\n\");\n                                    wait_for_space = 0;\n                                    irmp_bit++;\n                                }\n                                else\n                                {                                                   // timing incorrect!\n                                    ANALYZE_PRINTF4 (\"error 3a B&O: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                                    ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                                    irmp_start_bit_detected = 0;                    // reset flags and wait for next start bit\n                                    irmp_pause_time         = 0;\n                                }\n                            }\n                            else if (irmp_bit == 19)                                // Bang & Olufsen: trailer bit\n                            {\n                                if (irmp_pause_time >= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MAX)\n                                {\n                                    ANALYZE_PRINTF1 (\"trailer bit\\n\");\n                                    wait_for_space = 0;\n                                    irmp_bit++;\n                                }\n                                else\n                                {                                                   // timing incorrect!\n                                    ANALYZE_PRINTF4 (\"error 3b B&O: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                                    ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                                    irmp_start_bit_detected = 0;                    // reset flags and wait for next start bit\n                                    irmp_pause_time         = 0;\n                                }\n                            }\n                            else\n                            {\n                                if (irmp_pause_time >= BANG_OLUFSEN_1_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_1_PAUSE_LEN_MAX)\n                                {                                                   // pulse & pause timings correct for \"1\"?\n                                    ANALYZE_PUTCHAR ('1');\n                                    ANALYZE_NEWLINE ();\n                                    irmp_store_bit (1);\n                                    last_value = 1;\n                                    wait_for_space = 0;\n                                }\n                                else if (irmp_pause_time >= BANG_OLUFSEN_0_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_0_PAUSE_LEN_MAX)\n                                {                                                   // pulse & pause timings correct for \"0\"?\n                                    ANALYZE_PUTCHAR ('0');\n                                    ANALYZE_NEWLINE ();\n                                    irmp_store_bit (0);\n                                    last_value = 0;\n                                    wait_for_space = 0;\n                                }\n                                else if (irmp_pause_time >= BANG_OLUFSEN_R_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_R_PAUSE_LEN_MAX)\n                                {\n                                    ANALYZE_PUTCHAR (last_value + '0');\n                                    ANALYZE_NEWLINE ();\n                                    irmp_store_bit (last_value);\n                                    wait_for_space = 0;\n                                }\n                                else\n                                {                                                   // timing incorrect!\n                                    ANALYZE_PRINTF4 (\"error 3c B&O: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                                    ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                                    irmp_start_bit_detected = 0;                    // reset flags and wait for next start bit\n                                    irmp_pause_time         = 0;\n                                }\n                            }\n                        }\n                        else\n                        {                                                           // timing incorrect!\n                            ANALYZE_PRINTF4 (\"error 3d B&O: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                            ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                            irmp_start_bit_detected = 0;                            // reset flags and wait for next start bit\n                            irmp_pause_time         = 0;\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL\n\n#if IRMP_SUPPORT_RCMM_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_RCMM32_PROTOCOL)\n                    {\n                        if (irmp_pause_time >= RCMM32_BIT_00_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_00_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PUTCHAR ('0');\n                            ANALYZE_PUTCHAR ('0');\n                            irmp_store_bit (0);\n                            irmp_store_bit (0);\n                        }\n                        else if (irmp_pause_time >= RCMM32_BIT_01_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_01_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PUTCHAR ('0');\n                            ANALYZE_PUTCHAR ('1');\n                            irmp_store_bit (0);\n                            irmp_store_bit (1);\n                        }\n                        else if (irmp_pause_time >= RCMM32_BIT_10_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_10_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PUTCHAR ('1');\n                            ANALYZE_PUTCHAR ('0');\n                            irmp_store_bit (1);\n                            irmp_store_bit (0);\n                        }\n                        else if (irmp_pause_time >= RCMM32_BIT_11_PAUSE_LEN_MIN && irmp_pause_time <= RCMM32_BIT_11_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PUTCHAR ('1');\n                            ANALYZE_PUTCHAR ('1');\n                            irmp_store_bit (1);\n                            irmp_store_bit (1);\n                        }\n\n                        ANALYZE_PRINTF1 (\"\\n\");\n                        wait_for_space = 0;\n                    }\n                    else\n#endif\n\n                    if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max &&\n                        irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max)\n                    {                                                               // pulse & pause timings correct for \"1\"?\n                        ANALYZE_PUTCHAR ('1');\n                        ANALYZE_NEWLINE ();\n                        irmp_store_bit (1);\n                        wait_for_space = 0;\n                    }\n                    else if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max &&\n                             irmp_pause_time >= irmp_param.pause_0_len_min && irmp_pause_time <= irmp_param.pause_0_len_max)\n                    {                                                               // pulse & pause timings correct for \"0\"?\n                        ANALYZE_PUTCHAR ('0');\n                        ANALYZE_NEWLINE ();\n                        irmp_store_bit (0);\n                        wait_for_space = 0;\n                    }\n                    else\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL\n\n                    if (irmp_param.protocol == IRMP_KATHREIN_PROTOCOL &&\n                        irmp_pulse_time >= KATHREIN_1_PULSE_LEN_MIN && irmp_pulse_time <= KATHREIN_1_PULSE_LEN_MAX &&\n                        (((irmp_bit == 8 || irmp_bit == 6) &&\n                                irmp_pause_time >= KATHREIN_SYNC_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KATHREIN_SYNC_BIT_PAUSE_LEN_MAX) ||\n                         (irmp_bit == 12 &&\n                                irmp_pause_time >= KATHREIN_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KATHREIN_START_BIT_PAUSE_LEN_MAX)))\n\n                    {\n                        if (irmp_bit == 8)\n                        {\n                            irmp_bit++;\n                            ANALYZE_PUTCHAR ('S');\n                            ANALYZE_NEWLINE ();\n                            irmp_tmp_command <<= 1;\n                        }\n                        else\n                        {\n                            ANALYZE_PUTCHAR ('S');\n                            ANALYZE_NEWLINE ();\n                            irmp_store_bit (1);\n                        }\n                        wait_for_space = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_KATHREIN_PROTOCOL\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_NEC42_PROTOCOL &&\n#else // IRMP_SUPPORT_NEC_PROTOCOL instead\n                    if (irmp_param.protocol == IRMP_NEC_PROTOCOL &&\n#endif // IRMP_SUPPORT_NEC42_PROTOCOL == 1\n                       (\n                        (irmp_pulse_time >= MELINERA_0_PULSE_LEN_MIN && irmp_pulse_time <= MELINERA_0_PULSE_LEN_MAX &&\n                         irmp_pause_time >= MELINERA_0_PAUSE_LEN_MIN && irmp_pause_time <= MELINERA_0_PAUSE_LEN_MAX) ||\n                        (irmp_pulse_time >= MELINERA_1_PULSE_LEN_MIN && irmp_pulse_time <= MELINERA_1_PULSE_LEN_MAX &&\n                         irmp_pause_time >= MELINERA_1_PAUSE_LEN_MIN && irmp_pause_time <= MELINERA_1_PAUSE_LEN_MAX)\n                       ))\n                    {\n                        ANALYZE_PRINTF1 (\"Switching to MELINERA protocol \");\n                        irmp_param.protocol         = IRMP_MELINERA_PROTOCOL;\n                        irmp_param.pulse_0_len_min  = MELINERA_0_PULSE_LEN_MIN;\n                        irmp_param.pulse_0_len_max  = MELINERA_0_PULSE_LEN_MAX;\n                        irmp_param.pause_0_len_min  = MELINERA_0_PAUSE_LEN_MIN;\n                        irmp_param.pulse_0_len_max  = MELINERA_0_PAUSE_LEN_MAX;\n                        irmp_param.pulse_1_len_min  = MELINERA_1_PULSE_LEN_MIN;\n                        irmp_param.pulse_1_len_max  = MELINERA_1_PULSE_LEN_MAX;\n                        irmp_param.pause_1_len_min  = MELINERA_1_PAUSE_LEN_MIN;\n                        irmp_param.pulse_1_len_max  = MELINERA_1_PAUSE_LEN_MAX;\n                        irmp_param.address_offset   = MELINERA_ADDRESS_OFFSET;\n                        irmp_param.address_end      = MELINERA_ADDRESS_OFFSET + MELINERA_ADDRESS_LEN;\n                        irmp_param.command_offset   = MELINERA_COMMAND_OFFSET;\n                        irmp_param.command_end      = MELINERA_COMMAND_OFFSET + MELINERA_COMMAND_LEN;\n                        irmp_param.complete_len     = MELINERA_COMPLETE_DATA_LEN;\n\n                        if (irmp_pause_time >= MELINERA_0_PAUSE_LEN_MIN && irmp_pause_time <= MELINERA_0_PAUSE_LEN_MAX)\n                        {\n                            ANALYZE_PUTCHAR ('0');\n                            irmp_store_bit (0);\n                        }\n                        else\n                        {\n                            ANALYZE_PUTCHAR ('1');\n                            irmp_store_bit (1);\n                        }\n\n                        ANALYZE_NEWLINE ();\n                        wait_for_space = 0;\n                    }\n                    else\n#endif // IRMP_SUPPORT_MELINERA_PROTOCOL\n                    {                                                               // timing incorrect!\n                        ANALYZE_PRINTF4 (\"error 3: timing not correct: data bit %d,  pulse: %d, pause: %d\\n\", irmp_bit, irmp_pulse_time, irmp_pause_time);\n                        ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                        irmp_start_bit_detected = 0;                                // reset flags and wait for next start bit\n                        irmp_pause_time         = 0;\n                    }\n\n                    irmp_pulse_time = 1;                                            // set counter to 1, not 0\n                }\n            }\n            else\n            {                                                                       // counting the pulse length ...\n                if (! irmp_input)                                                   // still light?\n                {                                                                   // yes...\n                    irmp_pulse_time++;                                              // increment counter\n                }\n                else\n                {                                                                   // now it's dark!\n                    wait_for_space  = 1;                                            // let's count the time (see above)\n                    irmp_pause_time = 1;                                            // set pause counter to 1, not 0\n\n#if IRMP_SUPPORT_RCII_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_RCII_PROTOCOL && waiting_for_2nd_pulse)\n                    {\n                        // fm: output is \"1000 466\" or \"1533 466\"\n                        // printf (\"fm: %d %d\\n\", irmp_pulse_time * 1000000 / F_INTERRUPTS, RCII_BIT_LEN * 1000000 / F_INTERRUPTS);\n                        irmp_pulse_time -= RCII_BIT_LEN;\n                        last_value = 0;\n\n                        ANALYZE_PRINTF2 (\"RCII: got 2nd pulse, irmp_pulse_time = %d\\n\", irmp_pulse_time);\n                        waiting_for_2nd_pulse = 0;\n                    }\n#endif\n                }\n            }\n\n            if (irmp_start_bit_detected && irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 0)    // enough bits received?\n            {\n                if (last_irmp_command == irmp_tmp_command && key_repetition_len < AUTO_FRAME_REPETITION_LEN)\n                {\n                    repetition_frame_number++;\n                }\n                else\n                {\n                    repetition_frame_number = 0;\n                }\n\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n                // if SIRCS protocol and the code will be repeated within 50 ms, we will ignore 2nd and 3rd repetition frame\n                if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && (repetition_frame_number == 1 || repetition_frame_number == 2))\n                {\n                    ANALYZE_PRINTF4 (\"code skipped: SIRCS auto repetition frame #%d, counter = %u, auto repetition len = %u\\n\",\n                                    repetition_frame_number + 1, (unsigned int) key_repetition_len, (unsigned int) AUTO_FRAME_REPETITION_LEN);\n                    key_repetition_len = 0;\n                }\n                else\n#endif\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n                // if ORTEK protocol and the code will be repeated within 50 ms, we will ignore 2nd repetition frame\n                if (irmp_param.protocol == IRMP_ORTEK_PROTOCOL && repetition_frame_number == 1)\n                {\n                    ANALYZE_PRINTF4 (\"code skipped: ORTEK auto repetition frame #%d, counter = %d, auto repetition len = %d\\n\",\n                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\n                    key_repetition_len = 0;\n                }\n                else\n#endif\n\n#if 0 && IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1    // fm 2015-12-02: don't ignore every 2nd frame\n                // if KASEIKYO protocol and the code will be repeated within 50 ms, we will ignore 2nd repetition frame\n                if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && repetition_frame_number == 1)\n                {\n                    ANALYZE_PRINTF4 (\"code skipped: KASEIKYO auto repetition frame #%d, counter = %d, auto repetition len = %d\\n\",\n                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\n                    key_repetition_len = 0;\n                }\n                else\n#endif\n\n#if 0 && IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1     // fm 2015-12-02: don't ignore every 2nd frame\n                // if SAMSUNG32 or SAMSUNG48 protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame\n                if ((irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL || irmp_param.protocol == IRMP_SAMSUNG48_PROTOCOL) && (repetition_frame_number & 0x01))\n                {\n                    ANALYZE_PRINTF4 (\"code skipped: SAMSUNG32/SAMSUNG48 auto repetition frame #%d, counter = %d, auto repetition len = %d\\n\",\n                                    repetition_frame_number + 1, key_repetition_len, AUTO_FRAME_REPETITION_LEN);\n                    key_repetition_len = 0;\n                }\n                else\n#endif\n\n#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1\n                // if NUBERT protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame\n                if (irmp_param.protocol == IRMP_NUBERT_PROTOCOL && (repetition_frame_number & 0x01))\n                {\n                    ANALYZE_PRINTF4 (\"code skipped: NUBERT auto repetition frame #%d, counter = %u, auto repetition len = %u\\n\",\n                                    repetition_frame_number + 1, (unsigned int) key_repetition_len, (unsigned int) AUTO_FRAME_REPETITION_LEN);\n                    key_repetition_len = 0;\n                }\n                else\n#endif\n\n#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1\n                // if SPEAKER protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame\n                if (irmp_param.protocol == IRMP_SPEAKER_PROTOCOL && (repetition_frame_number & 0x01))\n                {\n                    ANALYZE_PRINTF4 (\"code skipped: SPEAKER auto repetition frame #%d, counter = %u, auto repetition len = %u\\n\",\n                                    repetition_frame_number + 1, (unsigned int) key_repetition_len, (unsigned int) AUTO_FRAME_REPETITION_LEN);\n                    key_repetition_len = 0;\n                }\n                else\n#endif\n\n                {\n                    ANALYZE_PRINTF3 (\"%8.3fms code detected, length = %d\\n\", (double) (time_counter * 1000) / F_INTERRUPTS, irmp_bit);\n                    irmp_ir_detected = TRUE;\n\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_KATHREIN_PROTOCOL && irmp_tmp_command == 0x0000)\n                    {\n                        if (irmp_tmp_command == 0x0000)                             // KATHREIN sends key release with command = 0x0000, ignore it\n                        {\n                            ANALYZE_PRINTF1 (\"got KATHREIN release command, ignore it\\n\");\n                            irmp_ir_detected = FALSE;\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_KATHREIN_PROTOCOL\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_DENON_PROTOCOL)\n                    {                                                               // check for repetition frame\n                        if ((~irmp_tmp_command & 0x3FF) == last_irmp_denon_command) // command bits must be inverted\n                        {\n                            irmp_tmp_command = last_irmp_denon_command;             // use command received before!\n                            last_irmp_denon_command = 0;\n\n                            irmp_protocol = irmp_param.protocol;                    // store protocol\n                            irmp_address = irmp_tmp_address;                        // store address\n                            irmp_command = irmp_tmp_command;                        // store command\n                        }\n                        else\n                        {\n                            if ((irmp_tmp_command & 0x01) == 0x00)\n                            {\n                                ANALYZE_PRINTF2 (\"%8.3fms info Denon: waiting for inverted command repetition\\n\", (double) (time_counter * 1000) / F_INTERRUPTS);\n                                last_irmp_denon_command = irmp_tmp_command;\n                                denon_repetition_len = 0;\n                                irmp_ir_detected = FALSE;\n                            }\n                            else\n                            {\n                                ANALYZE_PRINTF2 (\"%8.3fms warning Denon: got unexpected inverted command, ignoring it\\n\", (double) (time_counter * 1000) / F_INTERRUPTS);\n                                last_irmp_denon_command = 0;\n                                irmp_ir_detected = FALSE;\n                            }\n                        }\n                    }\n                    else\n#endif // IRMP_SUPPORT_DENON_PROTOCOL\n\n#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL && irmp_tmp_command == 0x01ff)\n                    {                                                               // Grundig start frame?\n                        ANALYZE_PRINTF1 (\"Detected GRUNDIG start frame, ignoring it\\n\");\n                        irmp_ir_detected = FALSE;\n                    }\n                    else\n#endif // IRMP_SUPPORT_GRUNDIG_PROTOCOL\n\n#if IRMP_SUPPORT_NOKIA_PROTOCOL == 1\n                    if (irmp_param.protocol == IRMP_NOKIA_PROTOCOL && irmp_tmp_address == 0x00ff && irmp_tmp_command == 0x00fe)\n                    {                                                               // Nokia start frame?\n                        ANALYZE_PRINTF1 (\"Detected NOKIA start frame, ignoring it\\n\");\n                        irmp_ir_detected = FALSE;\n                    }\n                    else\n#endif // IRMP_SUPPORT_NOKIA_PROTOCOL\n                    {\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0)  // repetition frame\n                        {\n                            if (key_repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)\n                            {\n                                ANALYZE_PRINTF2 (\"Detected NEC repetition frame, key_repetition_len = %u\\n\", (unsigned int) key_repetition_len);\n                                ANALYZE_ONLY_NORMAL_PRINTF1(\"REPETETION FRAME                \");\n                                irmp_tmp_address = last_irmp_address;                   // address is last address\n                                irmp_tmp_command = last_irmp_command;                   // command is last command\n                                irmp_flags |= IRMP_FLAG_REPETITION;\n                                key_repetition_len = 0;\n                            }\n                            else\n                            {\n                                ANALYZE_PRINTF3 (\"Detected NEC repetition frame, ignoring it: timeout occured, key_repetition_len = %u > %u\\n\",\n                                                (unsigned int) key_repetition_len, (unsigned int) NEC_FRAME_REPEAT_PAUSE_LEN_MAX);\n                                irmp_ir_detected = FALSE;\n                            }\n                        }\n#endif // IRMP_SUPPORT_NEC_PROTOCOL\n\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL)\n                        {\n                            uint_fast8_t xor_value;\n\n                            xor_value = (xor_check[0] & 0x0F) ^ ((xor_check[0] & 0xF0) >> 4) ^ (xor_check[1] & 0x0F) ^ ((xor_check[1] & 0xF0) >> 4);\n\n                            if (xor_value != (xor_check[2] & 0x0F))\n                            {\n                                ANALYZE_PRINTF3 (\"error 4: wrong XOR check for customer id: 0x%1x 0x%1x\\n\", xor_value, xor_check[2] & 0x0F);\n                                irmp_ir_detected = FALSE;\n                            }\n\n                            xor_value = xor_check[2] ^ xor_check[3] ^ xor_check[4];\n\n                            if (xor_value != xor_check[5])\n                            {\n                                ANALYZE_PRINTF3 (\"error 5: wrong XOR check for data bits: 0x%02x 0x%02x\\n\", xor_value, xor_check[5]);\n                                irmp_ir_detected = FALSE;\n                            }\n\n                            irmp_flags |= genre2;       // write the genre2 bits into MSB of the flag byte\n                        }\n#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_ORTEK_PROTOCOL)\n                        {\n                            if (parity == PARITY_CHECK_FAILED)\n                            {\n                                ANALYZE_PRINTF1 (\"error 6: parity check failed\\n\");\n                                irmp_ir_detected = FALSE;\n                            }\n\n                            if ((irmp_tmp_address & 0x03) == 0x02)\n                            {\n                                ANALYZE_PRINTF1 (\"code skipped: ORTEK end of transmission frame (key release)\\n\");\n                                irmp_ir_detected = FALSE;\n                            }\n                            irmp_tmp_address >>= 2;\n                        }\n#endif // IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_MITSU_HEAVY_PROTOCOL)\n                        {\n                            check = irmp_tmp_command >> 8;                    // inverted upper byte == lower byte?\n                            check = ~ check;\n                            if (check == (irmp_tmp_command & 0xFF)) {         //ok:\n                              irmp_tmp_command &= 0xFF;\n                            }\n                            else  mitsu_parity = PARITY_CHECK_FAILED;\n                            if (mitsu_parity == PARITY_CHECK_FAILED)\n                            {\n                                ANALYZE_PRINTF1 (\"error 7: parity check failed\\n\");\n                                irmp_ir_detected = FALSE;\n                            }\n                        }\n#endif // IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL\n\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG)     // RC6 mode = 6?\n                        {\n                            irmp_protocol = IRMP_RC6A_PROTOCOL;\n                        }\n                        else if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_20)       // RC6 mode = 6?\n                        {\n                            irmp_protocol = IRMP_RC6A20_PROTOCOL;\n                        }\n                        else if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_28)       // RC6 mode = 6?\n                        {\n                            irmp_protocol = IRMP_RC6A28_PROTOCOL;\n                        }\n                        else\n#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1\n                        {\n                            irmp_protocol = irmp_param.protocol;\n                        }\n\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_FDC_PROTOCOL)\n                        {\n                            if (irmp_tmp_command & 0x000F)                          // released key?\n                            {\n                                irmp_tmp_command = (irmp_tmp_command >> 4) | 0x80;  // yes, set bit 7\n                            }\n                            else\n                            {\n                                irmp_tmp_command >>= 4;                             // no, it's a pressed key\n                            }\n                            irmp_tmp_command |= (irmp_tmp_address << 2) & 0x0F00;   // 000000CCCCAAAAAA -> 0000CCCC00000000\n                            irmp_tmp_address &= 0x003F;\n                        }\n#endif\n\n                        irmp_address = irmp_tmp_address;                            // store address\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_NEC_PROTOCOL)\n                        {\n                            last_irmp_address = irmp_tmp_address;                   // store as last address, too\n                        }\n#endif\n\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_RC5_PROTOCOL)\n                        {\n                            irmp_tmp_command |= rc5_cmd_bit6;                       // store bit 6\n                        }\n#endif\n#if IRMP_SUPPORT_S100_PROTOCOL == 1\n                        if (irmp_param.protocol == IRMP_S100_PROTOCOL)\n                        {\n                            irmp_tmp_command |= rc5_cmd_bit6;                       // store bit 6\n                        }\n#endif\n                        irmp_command = irmp_tmp_command;                            // store command\n\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n                        irmp_id = irmp_tmp_id;\n#endif\n                    }\n                }\n\n                if (irmp_ir_detected)\n                {\n                    if (last_irmp_command == irmp_tmp_command &&\n                        last_irmp_address == irmp_tmp_address &&\n#if IRMP_AUTODETECT_REPEATRATE\n                        irmp_protocol == previous_irmp_protocol)\n                    {\n                        same_key = 1;\n                    }\n                    pass_on_delta_detection = delta_detection;\n                    delta_detection = 0;\n#else\n                        key_repetition_len < IRMP_KEY_REPETITION_LEN) // time after data frame, not total since start\n                    {\n                        irmp_flags |= IRMP_FLAG_REPETITION;\n                    }\n#endif\n                    last_irmp_address   = irmp_tmp_address;                          // store as last address, too\n                    last_irmp_command   = irmp_tmp_command;                          // store as last command, too\n\n#if IRMP_ENABLE_RELEASE_DETECTION == 1\n                    key_released        = FALSE;\n#endif\n                    key_repetition_len  = 0;\n                }\n                else\n                {\n                    ANALYZE_ONLY_NORMAL_PUTCHAR ('\\n');\n                }\n\n                irmp_start_bit_detected = 0;                                        // and wait for next start bit\n                irmp_tmp_command        = 0;\n                irmp_pulse_time         = 0;\n                irmp_pause_time         = 0;\n\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n                if (irmp_protocol == IRMP_JVC_PROTOCOL)                             // the stop bit of JVC frame is also start bit of next frame\n                {                                                                   // set pulse time here!\n                    irmp_pulse_time = ((uint_fast8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME));\n                }\n#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1\n            }\n        }\n    }\n\n#if defined(STELLARIS_ARM_CORTEX_M4)\n    // Clear the timer interrupt\n    TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);\n#endif\n\n#if (defined(_CHIBIOS_RT_) || defined(_CHIBIOS_NIL_)) && IRMP_USE_EVENT == 1\n    if (IRMP_EVENT_THREAD_PTR != nullptr && irmp_ir_detected)\n        chEvtSignalI(IRMP_EVENT_THREAD_PTR,IRMP_EVENT_BIT);\n#endif\n\n#if IRMP_USE_COMPLETE_CALLBACK == 1\n    if (irmp_complete_callback_function != nullptr && irmp_ir_detected) {\n        irmp_complete_callback_function();\n    }\n#endif\n\n#if IRMP_USE_IDLE_CALL == 1\n    // check if there is no ongoing transmission or repetition\n    if (!irmp_start_bit_detected && !irmp_pulse_time\n        && key_repetition_len > IRMP_KEY_REPETITION_LEN)\n    {\n        // no ongoing transmission\n        // enough time passed since last decoded signal that a repetition won't affect our output\n\n        irmp_idle();\n    }\n#endif // IRMP_USE_IDLE_CALL\n\n    return (irmp_ir_detected);\n}\n\n#if defined(ANALYZE)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * main functions - for Unix/Linux + Windows only!\n *\n * AVR: see main.c!\n *\n * Compile it under linux with:\n * cc irmp.c -o irmp\n *\n * usage: ./irmp [-v|-s|-a|-l] < file\n *\n * options:\n *   -v verbose\n *   -s silent\n *   -a analyze\n *   -l list pulse/pauses\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\nvoid\nprint_spectrum (const char *text, int *buf, int is_pulse)\n{\n    int     i;\n    int     j;\n    int     min;\n    int     max;\n    int     max_value = 0;\n    int     value;\n    int     sum = 0;\n    int     counter = 0;\n    double  average = 0;\n    double  tolerance;\n\n    puts (\"-----------------------------------------------------------------------------\");\n    printf (\"%s:\\n\", text);\n\n    for (i = 0; i < 256; i++)\n    {\n        if (buf[i] > max_value)\n        {\n            max_value = buf[i];\n        }\n    }\n\n    for (i = 1; i < 200; i++)\n    {\n        if (buf[i] > 0)\n        {\n            printf (\"%3d \", i);\n            value = (buf[i] * 60) / max_value;\n\n            for (j = 0; j < value; j++)\n            {\n                putchar ('o');\n            }\n            printf (\" %d\\n\", buf[i]);\n\n            sum += i * buf[i];\n            counter += buf[i];\n        }\n        else\n        {\n            max = i - 1;\n\n            if (counter > 0)\n            {\n                average = (float) sum / (float) counter;\n\n                if (is_pulse)\n                {\n                    printf (\"pulse \");\n                }\n                else\n                {\n                    printf (\"pause \");\n                }\n\n                printf (\"avg: %4.1f=%6.1f us, \", average, (1000000. * average) / (float) F_INTERRUPTS);\n                printf (\"min: %2d=%6.1f us, \", min, (1000000. * min) / (float) F_INTERRUPTS);\n                printf (\"max: %2d=%6.1f us, \", max, (1000000. * max) / (float) F_INTERRUPTS);\n\n                tolerance = (max - average);\n\n                if (average - min > tolerance)\n                {\n                    tolerance = average - min;\n                }\n\n                tolerance = tolerance * 100 / average;\n                printf (\"tol: %4.1f%%\\n\", tolerance);\n            }\n\n            counter = 0;\n            sum = 0;\n            min = i + 1;\n        }\n    }\n}\n\n#define STATE_LEFT_SHIFT    0x01\n#define STATE_RIGHT_SHIFT   0x02\n#define STATE_LEFT_CTRL     0x04\n#define STATE_LEFT_ALT      0x08\n#define STATE_RIGHT_ALT     0x10\n\n#define KEY_ESCAPE          0x1B            // keycode = 0x006e\n#define KEY_MENUE           0x80            // keycode = 0x0070\n#define KEY_BACK            0x81            // keycode = 0x0071\n#define KEY_FORWARD         0x82            // keycode = 0x0072\n#define KEY_ADDRESS         0x83            // keycode = 0x0073\n#define KEY_WINDOW          0x84            // keycode = 0x0074\n#define KEY_1ST_PAGE        0x85            // keycode = 0x0075\n#define KEY_STOP            0x86            // keycode = 0x0076\n#define KEY_MAIL            0x87            // keycode = 0x0077\n#define KEY_FAVORITES       0x88            // keycode = 0x0078\n#define KEY_NEW_PAGE        0x89            // keycode = 0x0079\n#define KEY_SETUP           0x8A            // keycode = 0x007a\n#define KEY_FONT            0x8B            // keycode = 0x007b\n#define KEY_PRINT           0x8C            // keycode = 0x007c\n#define KEY_ON_OFF          0x8E            // keycode = 0x007c\n\n#define KEY_INSERT          0x90            // keycode = 0x004b\n#define KEY_DELETE          0x91            // keycode = 0x004c\n#define KEY_LEFT            0x92            // keycode = 0x004f\n#define KEY_HOME            0x93            // keycode = 0x0050\n#define KEY_END             0x94            // keycode = 0x0051\n#define KEY_UP              0x95            // keycode = 0x0053\n#define KEY_DOWN            0x96            // keycode = 0x0054\n#define KEY_PAGE_UP         0x97            // keycode = 0x0055\n#define KEY_PAGE_DOWN       0x98            // keycode = 0x0056\n#define KEY_RIGHT           0x99            // keycode = 0x0059\n#define KEY_MOUSE_1         0x9E            // keycode = 0x0400\n#define KEY_MOUSE_2         0x9F            // keycode = 0x0800\n\nstatic uint_fast8_t\nget_fdc_key (uint_fast16_t cmd)\n{\n    static const uint8_t key_table[128] =\n    {\n     // 0     1      2    3    4     5    6    7    8     9     A     B     C     D     E     F\n        0x00, '^',  '1', '2', '3',  '4', '5', '6', '7',  '8',  '9',  '0',  0xDF, 0xB4,  0x00, '\\b',\n        '\\t', 'q',  'w', 'e', 'r',  't', 'z', 'u', 'i',  'o',  'p',  0xFC, '+',  0x00,  0x00, 'a',\n        's',  'd',  'f', 'g', 'h',  'j', 'k', 'l', 0xF6, 0xE4, '#',  '\\r', 0x00, '<',   'y',  'x',\n        'c',  'v',  'b', 'n', 'm',  ',', '.', '-', 0x00, 0x00, 0x00, 0x00, 0x00,  ' ',  0x00, 0x00,\n\n        0x00, 0xB0, '!', '\"', 0xA7, '$', '%', '&', '/',  '(',  ')',  '=',  '?',  0x60,  0x00, '\\b',\n        '\\t', 'Q',  'W', 'E', 'R',  'T', 'Z', 'U', 'I',  'O',  'P',  0xDC, '*',  0x00,  0x00, 'A',\n        'S',  'D',  'F', 'G', 'H',  'J', 'K', 'L', 0xD6, 0xC4, '\\'', '\\r', 0x00, '>',   'Y',  'X',\n        'C',  'V',  'B', 'N', 'M',  ';', ':', '_', 0x00, 0x00, 0x00, 0x00, 0x00, ' ',   0x00, 0x00\n    };\n    static uint_fast8_t state;\n\n    uint_fast8_t key = 0;\n\n    switch (cmd)\n    {\n        case 0x002C: state |=  STATE_LEFT_SHIFT;    break;              // pressed left shift\n        case 0x00AC: state &= ~STATE_LEFT_SHIFT;    break;              // released left shift\n        case 0x0039: state |=  STATE_RIGHT_SHIFT;   break;              // pressed right shift\n        case 0x00B9: state &= ~STATE_RIGHT_SHIFT;   break;              // released right shift\n        case 0x003A: state |=  STATE_LEFT_CTRL;     break;              // pressed left ctrl\n        case 0x00BA: state &= ~STATE_LEFT_CTRL;     break;              // released left ctrl\n        case 0x003C: state |=  STATE_LEFT_ALT;      break;              // pressed left alt\n        case 0x00BC: state &= ~STATE_LEFT_ALT;      break;              // released left alt\n        case 0x003E: state |=  STATE_RIGHT_ALT;     break;              // pressed left alt\n        case 0x00BE: state &= ~STATE_RIGHT_ALT;     break;              // released left alt\n\n        case 0x006e: key = KEY_ESCAPE;              break;\n        case 0x004b: key = KEY_INSERT;              break;\n        case 0x004c: key = KEY_DELETE;              break;\n        case 0x004f: key = KEY_LEFT;                break;\n        case 0x0050: key = KEY_HOME;                break;\n        case 0x0051: key = KEY_END;                 break;\n        case 0x0053: key = KEY_UP;                  break;\n        case 0x0054: key = KEY_DOWN;                break;\n        case 0x0055: key = KEY_PAGE_UP;             break;\n        case 0x0056: key = KEY_PAGE_DOWN;           break;\n        case 0x0059: key = KEY_RIGHT;               break;\n        case 0x0400: key = KEY_MOUSE_1;             break;\n        case 0x0800: key = KEY_MOUSE_2;             break;\n\n        default:\n        {\n            if (!(cmd & 0x80))                      // pressed key\n            {\n                if (cmd >= 0x70 && cmd <= 0x7F)     // function keys\n                {\n                    key = cmd + 0x10;               // 7x -> 8x\n                }\n                else if (cmd < 64)                  // key listed in key_table\n                {\n                    if (state & (STATE_LEFT_ALT | STATE_RIGHT_ALT))\n                    {\n                        switch (cmd)\n                        {\n                            case 0x0003: key = 0xB2;    break; // upper 2\n                            case 0x0008: key = '{';     break;\n                            case 0x0009: key = '[';     break;\n                            case 0x000A: key = ']';     break;\n                            case 0x000B: key = '}';     break;\n                            case 0x000C: key = '\\\\';    break;\n                            case 0x001C: key = '~';     break;\n                            case 0x002D: key = '|';     break;\n                            case 0x0034: key = 0xB5;    break; // Mu\n                        }\n                    }\n                    else if (state & (STATE_LEFT_CTRL))\n                    {\n                        if (key_table[cmd] >= 'a' && key_table[cmd] <= 'z')\n                        {\n                            key = key_table[cmd] - 'a' + 1;\n                        }\n                        else\n                        {\n                            key = key_table[cmd];\n                        }\n                    }\n                    else\n                    {\n                        int idx = cmd + ((state & (STATE_LEFT_SHIFT | STATE_RIGHT_SHIFT)) ? 64 : 0);\n\n                        if (key_table[idx])\n                        {\n                            key = key_table[idx];\n                        }\n                    }\n                }\n            }\n            break;\n        }\n    }\n\n    return (key);\n}\n\nstatic int         analyze = FALSE;\nstatic int         list = FALSE;\nstatic IRMP_DATA   irmp_data;\nstatic int         expected_protocol;\nstatic int         expected_address;\nstatic int         expected_command;\nstatic int         do_check_expected_values;\n\nstatic void\nnext_tick (void)\n{\n    if (! analyze && ! list)\n    {\n        (void) irmp_ISR ();\n\n        if (irmp_get_data (&irmp_data))\n        {\n            uint_fast8_t key;\n\n            ANALYZE_ONLY_NORMAL_PUTCHAR (' ');\n\n            if (verbose)\n            {\n                printf (\"%8.3fms \", (double) (time_counter * 1000) / F_INTERRUPTS);\n            }\n\n            if (irmp_data.protocol == IRMP_ACP24_PROTOCOL)\n            {\n                uint16_t    temp = (irmp_data.command & 0x000F) + 15;\n\n                printf (\"p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, temp=%d\",\n                        irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, temp);\n            }\n            else if (irmp_data.protocol == IRMP_FDC_PROTOCOL && (key = get_fdc_key (irmp_data.command)) != 0)\n            {\n                if ((key >= 0x20 && key < 0x7F) || key >= 0xA0)\n                {\n                    printf (\"p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x, key='%c'\",\n                            irmp_data.protocol,  irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key, key);\n                }\n                else if (key == '\\r' || key == '\\t' || key == KEY_ESCAPE || (key >= 0x80 && key <= 0x9F))                 // function keys\n                {\n                    const char * p = (const char *) nullptr;\n\n                    switch (key)\n                    {\n                        case '\\t'                : p = \"TAB\";           break;\n                        case '\\r'                : p = \"CR\";            break;\n                        case KEY_ESCAPE          : p = \"ESCAPE\";        break;\n                        case KEY_MENUE           : p = \"MENUE\";         break;\n                        case KEY_BACK            : p = \"BACK\";          break;\n                        case KEY_FORWARD         : p = \"FORWARD\";       break;\n                        case KEY_ADDRESS         : p = \"ADDRESS\";       break;\n                        case KEY_WINDOW          : p = \"WINDOW\";        break;\n                        case KEY_1ST_PAGE        : p = \"1ST_PAGE\";      break;\n                        case KEY_STOP            : p = \"STOP\";          break;\n                        case KEY_MAIL            : p = \"MAIL\";          break;\n                        case KEY_FAVORITES       : p = \"FAVORITES\";     break;\n                        case KEY_NEW_PAGE        : p = \"NEW_PAGE\";      break;\n                        case KEY_SETUP           : p = \"SETUP\";         break;\n                        case KEY_FONT            : p = \"FONT\";          break;\n                        case KEY_PRINT           : p = \"PRINT\";         break;\n                        case KEY_ON_OFF          : p = \"ON_OFF\";        break;\n\n                        case KEY_INSERT          : p = \"INSERT\";        break;\n                        case KEY_DELETE          : p = \"DELETE\";        break;\n                        case KEY_LEFT            : p = \"LEFT\";          break;\n                        case KEY_HOME            : p = \"HOME\";          break;\n                        case KEY_END             : p = \"END\";           break;\n                        case KEY_UP              : p = \"UP\";            break;\n                        case KEY_DOWN            : p = \"DOWN\";          break;\n                        case KEY_PAGE_UP         : p = \"PAGE_UP\";       break;\n                        case KEY_PAGE_DOWN       : p = \"PAGE_DOWN\";     break;\n                        case KEY_RIGHT           : p = \"RIGHT\";         break;\n                        case KEY_MOUSE_1         : p = \"KEY_MOUSE_1\";   break;\n                        case KEY_MOUSE_2         : p = \"KEY_MOUSE_2\";   break;\n                        default                  : p = \"<UNKNWON>\";     break;\n                    }\n\n                    printf (\"p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x, key=%s\",\n                            irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key, p);\n                }\n                else\n                {\n                    printf (\"p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x, asc=0x%02x\",\n                            irmp_data.protocol,  irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags, key);\n                }\n            }\n            else\n            {\n                printf (\"p=%2d (%s), a=0x%04x, c=0x%04x, f=0x%02x\",\n                        irmp_data.protocol, irmp_protocol_names[irmp_data.protocol], irmp_data.address, irmp_data.command, irmp_data.flags);\n            }\n\n            if (do_check_expected_values)\n            {\n                if (irmp_data.protocol != expected_protocol ||\n                    irmp_data.address  != expected_address  ||\n                    irmp_data.command  != expected_command)\n                {\n                    printf (\"\\nerror 7: expected values differ: p=%2d (%s), a=0x%04x, c=0x%04x\\n\",\n                            expected_protocol, irmp_protocol_names[expected_protocol], expected_address, expected_command);\n                }\n                else\n                {\n                    printf (\" checked!\\n\");\n                }\n                do_check_expected_values = FALSE;                           // only check 1st frame in a line!\n            }\n            else\n            {\n                putchar ('\\n');\n            }\n        }\n    }\n}\n\nint\nmain (int argc, char ** argv)\n{\n    int         i;\n    int         ch;\n    int         last_ch = 0;\n    int         pulse = 0;\n    int         pause = 0;\n\n    int         start_pulses[256];\n    int         start_pauses[256];\n    int         pulses[256];\n    int         pauses[256];\n\n    int         first_pulse = TRUE;\n    int         first_pause = TRUE;\n\n    if (argc == 2)\n    {\n        if (! strcmp (argv[1], \"-v\"))\n        {\n            verbose = TRUE;\n        }\n        else if (! strcmp (argv[1], \"-l\"))\n        {\n            list = TRUE;\n        }\n        else if (! strcmp (argv[1], \"-a\"))\n        {\n            analyze = TRUE;\n        }\n        else if (! strcmp (argv[1], \"-s\"))\n        {\n            silent = TRUE;\n        }\n    }\n\n    for (i = 0; i < 256; i++)\n    {\n        start_pulses[i] = 0;\n        start_pauses[i] = 0;\n        pulses[i] = 0;\n        pauses[i] = 0;\n    }\n\n    if (IRMP_HIGH_ACTIVE)\n    {\n        IRMP_PIN = 0x00;\n    }\n    else\n    {\n        IRMP_PIN = 0xFF;\n    }\n\n    while ((ch = getchar ()) != EOF)\n    {\n        if (ch == '_' || ch == '0')\n        {\n            if (last_ch != ch)\n            {\n                if (pause > 0)\n                {\n                    if (list)\n                    {\n                        printf (\"pause: %d\\n\", pause);\n                    }\n\n                    if (analyze)\n                    {\n                        if (first_pause)\n                        {\n                            if (pause < 256)\n                            {\n                                start_pauses[pause]++;\n                            }\n                            first_pause = FALSE;\n                        }\n                        else\n                        {\n                            if (pause < 256)\n                            {\n                                pauses[pause]++;\n                            }\n                        }\n                    }\n                }\n                pause = 0;\n            }\n            pulse++;\n\n            if (IRMP_HIGH_ACTIVE)\n            {\n                IRMP_PIN = 0xff;\n            }\n            else\n            {\n                IRMP_PIN = 0x00;\n            }\n        }\n        else if (ch == 0xaf || ch == '-' || ch == '1')\n        {\n            if (last_ch != ch)\n            {\n                if (list)\n                {\n                    printf (\"pulse: %d \", pulse);\n                }\n\n                if (analyze)\n                {\n                    if (first_pulse)\n                    {\n                        if (pulse < 256)\n                        {\n                            start_pulses[pulse]++;\n                        }\n                        first_pulse = FALSE;\n                    }\n                    else\n                    {\n                        if (pulse < 256)\n                        {\n                            pulses[pulse]++;\n                        }\n                    }\n                }\n                pulse = 0;\n            }\n\n            pause++;\n\n            if (IRMP_HIGH_ACTIVE)\n            {\n                IRMP_PIN = 0x00;\n            }\n            else\n            {\n                IRMP_PIN = 0xff;\n            }\n        }\n        else if (ch == '\\n')\n        {\n            if (IRMP_HIGH_ACTIVE)\n            {\n                IRMP_PIN = 0x00;\n            }\n            else\n            {\n                IRMP_PIN = 0xff;\n            }\n\n            time_counter = 0;\n\n            if (list && pause > 0)\n            {\n                printf (\"pause: %d\\n\", pause);\n            }\n            pause = 0;\n\n            if (! analyze)\n            {\n                for (i = 0; i < (int) ((10000.0 * F_INTERRUPTS) / 10000); i++)               // newline: long pause of 10000 msec\n                {\n                    next_tick ();\n                }\n            }\n            first_pulse = TRUE;\n            first_pause = TRUE;\n        }\n        else if (ch == '#')\n        {\n            time_counter = 0;\n\n            if (analyze)\n            {\n                while ((ch = getchar()) != '\\n' && ch != EOF)\n                {\n                    ;\n                }\n            }\n            else\n            {\n                char            buf[1024];\n                char *          p;\n                int             idx = -1;\n\n                puts (\"----------------------------------------------------------------------\");\n                putchar (ch);\n\n\n                while ((ch = getchar()) != '\\n' && ch != EOF)\n                {\n                    if (ch != '\\r')                                                         // ignore CR in DOS/Windows files\n                    {\n                        if (ch == '[' && idx == -1)\n                        {\n                            idx = 0;\n                        }\n                        else if (idx >= 0)\n                        {\n                            if (ch == ']')\n                            {\n                                do_check_expected_values = FALSE;\n                                buf[idx] = '\\0';\n                                idx = -1;\n\n                                expected_protocol = atoi (buf);\n\n                                if (expected_protocol > 0)\n                                {\n                                    p = buf;\n                                    while (*p)\n                                    {\n                                        if (*p == 'x')\n                                        {\n                                            p++;\n\n                                            if (sscanf (p, \"%x\", &expected_address) == 1)\n                                            {\n                                                do_check_expected_values = TRUE;\n                                            }\n                                            break;\n                                        }\n                                        p++;\n                                    }\n\n                                    if (do_check_expected_values)\n                                    {\n                                        do_check_expected_values = FALSE;\n\n                                        while (*p)\n                                        {\n                                            if (*p == 'x')\n                                            {\n                                                p++;\n\n                                                if (sscanf (p, \"%x\", &expected_command) == 1)\n                                                {\n                                                    do_check_expected_values = TRUE;\n                                                }\n                                                break;\n                                            }\n                                            p++;\n                                        }\n\n                                        if (do_check_expected_values)\n                                        {\n                                            // printf (\"!%2d %04x %04x!\\n\", expected_protocol, expected_address, expected_command);\n                                        }\n                                    }\n                                }\n                            }\n                            else if (idx < 1024 - 2)\n                            {\n                                buf[idx++] = ch;\n                            }\n                        }\n                        putchar (ch);\n                    }\n                }\n                putchar ('\\n');\n            }\n\n        }\n\n        last_ch = ch;\n\n        next_tick ();\n    }\n\n    if (analyze)\n    {\n        print_spectrum (\"START PULSES\", start_pulses, TRUE);\n        print_spectrum (\"START PAUSES\", start_pauses, FALSE);\n        print_spectrum (\"PULSES\", pulses, TRUE);\n        print_spectrum (\"PAUSES\", pauses, FALSE);\n        puts (\"-----------------------------------------------------------------------------\");\n    }\n    return 0;\n}\n\n#endif // ANALYZE\n"
  },
  {
    "path": "src/irmpArduinoExt.h",
    "content": "/*\n * irmpArduinoExt.h  Arduino extensions to the original irmp.h\n *\n *  Copyright (C) 2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#if defined(ARDUINO)\n#ifndef _IRMP_ARDUINO_EXT_H\n#define _IRMP_ARDUINO_EXT_H\n\n#include <Arduino.h>  // for Print\n\n#include \"irmpVersion.h\"\n#include \"IRFeedbackLED.h\" // for redefinition of\n\n#include \"digitalWriteFast.h\" // we use pinModeFast() and digitalReadFast() and digitalWriteFast() in turn\n\n/*\n * For debugging purposes. The timing test pin for some platforms is specified in the PinDefinitionsAndMore.h files included in each example.\n */\n//#define IRMP_MEASURE_TIMING\n//#define IR_TIMING_TEST_PIN <yourPinNumber>\n//\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Enable dynamic pin configuration in contrast to the static one which is known at compile time and saves program memory and CPU cycles.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n//#define IRMP_IRSND_ALLOW_DYNAMIC_PINS\n//\n//\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Enable PinChangeInterrupt add on for irmp_ISR(). Tested for NEC, Kaseiko, Denon, RC6 protocols and Arduino Uno and Arduino ATmega.\n * Receives IR protocol data  by using pin change interrupts and no polling by timer.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n//#define IRMP_ENABLE_PIN_CHANGE_INTERRUPT\n#if defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)\n#  if ! (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) /* ATtinyX5 */ \\\n&& ! ( (defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)) && ( (defined(ARDUINO_AVR_DIGISPARKPRO) && ((IRMP_INPUT_PIN == 3) || (IRMP_INPUT_PIN == 9))) /*ATtinyX7(digisparkpro) and pin 3 or 9 */\\\n        || (! defined(ARDUINO_AVR_DIGISPARKPRO) && ((IRMP_INPUT_PIN == 3) || (IRMP_INPUT_PIN == 14)))) ) /*ATtinyX7(ATTinyCore) and pin 3 or 14 */ \\\n&& ! ( ( defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) \\\n        || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) \\\n        || defined(__AVR_ATmega8__) || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \\\n        || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__)) \\\n&& ((IRMP_INPUT_PIN == 2) || (IRMP_INPUT_PIN == 3)) ) /* ATmegas and pin 2 or 3 */\n#  define IRMP_USE_ARDUINO_ATTACH_INTERRUPT // cannot use any static ISR vector here\n#  endif\n\n#  undef F_INTERRUPTS\n#  define F_INTERRUPTS                          15625   // 15625 interrupts per second gives 64 us period\n#endif\n\n#if defined(__AVR__)\n#define uint_fast8_t uint8_t\n#define uint_fast16_t uint16_t\n\n#elif defined(ESP8266)\n#include \"ets_sys.h\"\n#include \"osapi.h\"\n#include \"gpio.h\"\n#include \"os_type.h\"\n#include \"c_types.h\"\n\n#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3\n#include \"mbed.h\"\n\n#elif defined(ESP32)\n#elif defined(STM32F1xx) // for \"Generic STM32F1 series\" from \"STM32 Boards (selected from submenu)\" of Arduino Board manager\n#elif defined(ARDUINO_ARCH_STM32) // Untested! use settings from BluePill / STM32F1xx\n#elif defined(__STM32F1__) // for \"Generic STM32F103C series\" from \"STM32F1 Boards (STM32duino.com)\" of Arduino Board manager\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for Arduino IDE if no IRMP_INPUT_PIN specified\n * Should be first, since it covers multiple platforms\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\nextern uint_fast8_t irmp_InputPin; // global variable to hold input pin number. Is referenced by defining IRMP_INPUT_PIN as irmp_InputPin.\n\n#undef IRMP_INPUT_PIN\n#define IRMP_INPUT_PIN              irmp_InputPin\n#else // defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n#  if !defined(IRMP_INPUT_PIN)                                       // Arduino IDE uses IRMP_INPUT_PIN instead of PORT and BIT\n#define IRMP_INPUT_PIN              2\n#  endif\n#endif\n\n#if defined(IRMP_INPUT_PIN)\n#  if defined(__AVR__)\n#    define input(x)                (__builtin_constant_p(IRMP_INPUT_PIN) ) ? digitalReadFast(IRMP_INPUT_PIN) : digitalRead(IRMP_INPUT_PIN)\n#  else\n#    define input(x)                digitalRead(IRMP_INPUT_PIN)\n#  endif\n#endif\n\n#if !defined(IR_TIMING_TEST_PIN)              // Only for test purposes\n#define IR_TIMING_TEST_PIN        5\n#endif\n\nvoid irmp_init(uint_fast8_t aIrmpInputPin);\nvoid irmp_init(uint_fast8_t aIrmpInputPin, uint_fast8_t aIrmpFeedbackLedPin);\nvoid irmp_init(uint_fast8_t aIrmpInputPin, uint_fast8_t aIrmpFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow);\n\nbool irmp_IsBusy();\n\nextern uint32_t irmp_last_change_micros;\n\nvoid irmp_result_print(Print *aSerial, IRMP_DATA *aIRMPDataPtr);\nvoid irmp_result_print(IRMP_DATA *aIRMPDataPtr);\n\nvoid irmp_PCI_ISR(void);\nvoid enablePCIInterrupt(void);\nvoid disablePCIInterrupt(void);\n\nvoid irmp_print_active_protocols(Print *aSerial);\nvoid irmp_print_protocol_name(Print *aSerial, uint8_t aProtocolNumber);\n\nextern const uint8_t irmp_used_protocol_index[] PROGMEM;\nextern const char *const irmp_used_protocol_names[] PROGMEM;\n\n#endif // _IRMP_ARDUINO_EXT_H\n#endif // ARDUINO\n"
  },
  {
    "path": "src/irmpArduinoExt.hpp",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpArduinoExt.hpp - Arduino extensions to the original irmp.c\n *\n * Copyright (c) 2019-2020 Armin Joachimsmeyer\n *\n * This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n//  // Must be included after declaration of irmp_start_bit_detected etc.\n#if defined(ARDUINO)\n#undef _IRSND_H_                // We are in IRMP now! Remove old symbol maybe set from former including irsnd.hpp.\n#include \"IRTimer.hpp\"          // include code for timer\n#include \"IRFeedbackLED.hpp\"    // include code for Feedback LED\n#include \"irmpprotocols.hpp\"    // include protocol strings and array of strings\n\n#if defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)\n#include \"irmpPinChangeInterrupt.hpp\"\n#endif // defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)\n\n#if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\nuint_fast8_t irmp_InputPin; // global variable to hold input pin number. Is referenced by defining IRMP_INPUT_PIN as irmp_InputPin.\n\n/*\n * Initialize, and activate feedback LED function\n */\nvoid irmp_init(uint_fast8_t aIrmpInputPin, uint_fast8_t aFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow)\n{\n    irmp_InputPin = aIrmpInputPin;\n\n#if !defined(NO_LED_FEEDBACK_CODE)\n    irmp_irsnd_LedFeedbackPin = aFeedbackLedPin;\n    irmp_irsnd_LedFeedbackPinIsActiveLow = aIrmpLedFeedbackPinIsActiveLow;\n\n    /*\n     * enable feedback LED if (aFeedbackLedPin != 0)\n     */\n    irmp_irsnd_LEDFeedback(aFeedbackLedPin);\n#else\n    (void) aFeedbackLedPin; // to avoid compiler warnings\n    (void) aIrmpLedFeedbackPinIsActiveLow; // to avoid compiler warnings\n#endif\n\n#  if defined IRMP_ENABLE_PIN_CHANGE_INTERRUPT\n    enablePCIInterrupt();\n#  else\n    initIRTimerForReceive();\n#  endif\n#  if defined(IRMP_MEASURE_TIMING)\n    pinModeFast(IR_TIMING_TEST_PIN, OUTPUT);\n#  endif\n}\n\n/*\n * Initialize, and activate feedback LED function\n * @param irmp_irsnd_LedFeedbackPin if 0 feedback led is not activated\n */\nvoid irmp_init(uint_fast8_t aIrmpInputPin, uint_fast8_t aFeedbackLedPin)\n{\n#if defined(NO_LED_FEEDBACK_CODE)\n    irmp_init(aIrmpInputPin, aFeedbackLedPin, false);\n#else\n    irmp_init(aIrmpInputPin, aFeedbackLedPin, irmp_irsnd_LedFeedbackPinIsActiveLow);\n#endif\n}\n\n/*\n * Initialize, but do not activate feedback LED by default, using irmp_irsnd_LedFeedbackPin as led pin.\n */\nvoid irmp_init(uint_fast8_t aIrmpInputPin)\n{\n#if defined(NO_LED_FEEDBACK_CODE)\n    irmp_init(aIrmpInputPin, 0, false);\n#else\n    irmp_init(aIrmpInputPin, irmp_irsnd_LedFeedbackPin, irmp_irsnd_LedFeedbackPinIsActiveLow);\n#endif\n\n#  if defined(IRMP_FEEDBACK_LED_PIN)\n    // set pin if we have one at hand\n    irmp_irsnd_LedFeedbackPin = IRMP_FEEDBACK_LED_PIN;\n#  endif\n}\n#endif // if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n\nvoid irmp_init(void)\n{\n#  if defined(IRMP_INPUT_PIN)\n    pinModeFast(IRMP_INPUT_PIN, INPUT);                                 // set pin to input\n#  else\n    IRMP_PORT &= ~_BV(IRMP_BIT);                                        // deactivate pullup\n    IRMP_DDR &= ~_BV(IRMP_BIT);// set pin to input\n#  endif\n#  if defined IRMP_ENABLE_PIN_CHANGE_INTERRUPT\n    enablePCIInterrupt();\n#  else\n    initIRTimerForReceive();\n#  endif\n#  if defined(IRMP_MEASURE_TIMING)\n    pinModeFast(IR_TIMING_TEST_PIN, OUTPUT);\n#  endif\n}\n\n/*\n * Called from the receiver ISR IRMP_ISR() with the raw input value. Receiver signal input is active low!\n * With -oS it is taken as inline function\n */\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR irmp_DoLEDFeedback(bool aSwitchLedOff)\n#else\nvoid irmp_DoLEDFeedback(bool aSwitchLedOff)\n#endif\n{\n#if !defined(NO_LED_FEEDBACK_CODE)\n    if (irmp_irsnd_LedFeedbackEnabled)\n    {\n        irmp_irsnd_SetFeedbackLED(!aSwitchLedOff);\n    }\n#else\n    (void) aSwitchLedOff; // to avoid compiler warnings\n#endif\n}\n\n/*\n * returns true, if there is an ongoing transmission or repetition\n */\nbool irmp_IsBusy()\n{\n#if defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)\n    uint32_t tTicks = micros() - irmp_last_change_micros;\n    tTicks = (tTicks << 2) >> 8;\n    return (irmp_start_bit_detected || irmp_pulse_time || tTicks <= IRMP_KEY_REPETITION_LEN);\n#else\n    return (irmp_start_bit_detected || irmp_pulse_time || key_repetition_len <= IRMP_KEY_REPETITION_LEN);\n#endif\n}\n\n/*\n * irmp_used_protocol_index holds the protocol numbers (from irmpprotocols.h)\n * for the included protocol name entries of the irmp_used_protocol_names array below\n * E.g. irmp_used_protocol_index=2,7 and irmp_used_protocol_names=\"NEC\",\"RC5\".\n *\n * Both arrays together are generally smaller than the complete irmp_protocol_names array\n * allowing them to be used on ATtinies even if program code for access is bigger.\n * Flash size is more than 100 bytes less (for 15 protocols) using these arrays.\n */\nconst uint8_t irmp_used_protocol_index[] PROGMEM =\n{\n    IRMP_UNKNOWN_PROTOCOL,\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n    IRMP_SIRCS_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n    IRMP_NEC_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n    IRMP_SAMSUNG_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1\n    IRMP_MATSUSHITA_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n    IRMP_KASEIKYO_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RECS80_PROTOCOL == 1\n    IRMP_RECS80_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1\n    IRMP_RC5_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n    IRMP_DENON_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n    IRMP_RC6_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n    IRMP_SAMSUNG32_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n    IRMP_APPLE_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1\n    IRMP_RECS80EXT_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1\n    IRMP_NUBERT_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n    IRMP_BANG_OLUFSEN_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1\n    IRMP_GRUNDIG_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NOKIA_PROTOCOL == 1\n    IRMP_NOKIA_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_SIEMENS_PROTOCOL  == 1\n    IRMP_SIEMENS_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1\n    IRMP_FDC_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n    IRMP_RCCAR_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n    IRMP_JVC_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n    IRMP_RC6A_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NIKON_PROTOCOL == 1\n    IRMP_NIKON_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RUWIDO_PROTOCOL == 1\n    IRMP_RUWIDO_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_IR60_PROTOCOL == 1\n    IRMP_IR60_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n    IRMP_KATHREIN_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n    IRMP_NETBOX_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NEC16_PROTOCOL == 1\n    IRMP_NEC16_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n    IRMP_NEC42_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\n    IRMP_LEGO_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n    IRMP_THOMSON_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_BOSE_PROTOCOL == 1\n    IRMP_BOSE_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1\n    IRMP_A1TVBOX_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n    IRMP_ORTEK_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n    IRMP_TELEFUNKEN_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n    IRMP_ROOMBA_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RCMM_PROTOCOL  == 1\n    IRMP_RCMM32_PROTOCOL,\n    IRMP_RCMM24_PROTOCOL,\n    IRMP_RCMM12_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1\n    IRMP_SPEAKER_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n    IRMP_LGAIR_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\n    IRMP_SAMSUNG48_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n    IRMP_MERLIN_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1\n    IRMP_PENTAX_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_FAN_PROTOCOL == 1\n    IRMP_FAN_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_S100_PROTOCOL == 1\n    IRMP_S100_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_ACP24_PROTOCOL  == 1\n    IRMP_ACP24_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_TECHNICS_PROTOCOL == 1\n    IRMP_TECHNICS_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1 || IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 // Panasonic vendor ID for kaseikyo\n    IRMP_PANASONIC_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n    IRMP_MITSU_HEAVY_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\n    IRMP_VINCENT_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n    IRMP_SAMSUNGAH_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_IRMP16_PROTOCOL == 1\n    IRMP_IRMP16_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_GREE_PROTOCOL == 1\n    IRMP_GREE_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RCII_PROTOCOL == 1\n    IRMP_RCII_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_METZ_PROTOCOL == 1\n    IRMP_METZ_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n    IRMP_ONKYO_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n    RF_GEN24_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RF_X10_PROTOCOL == 1\n    RF_X10_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n    RF_MEDION_PROTOCOL\n#endif\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\n    IRMP_MELINERA_PROTOCOL\n#endif\n#if IRMP_SUPPORT_RC6A20_PROTOCOL == 1\n    IRMP_RC6A20_PROTOCOL\n#endif\n#if IRMP_SUPPORT_RC6A28_PROTOCOL == 1\n    IRMP_RC6A28_PROTOCOL\n#endif\n};\n\nconst char * const irmp_used_protocol_names[] PROGMEM =\n{\n    proto_unknown,\n#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1\n    proto_sircs,\n#endif\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n    proto_nec,\n#endif\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n    proto_samsung,\n#endif\n#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1\n    proto_matsushita,\n#endif\n#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1\n    proto_kaseikyo,\n#endif\n#if IRMP_SUPPORT_RECS80_PROTOCOL == 1\n    proto_recs80,\n#endif\n#if IRMP_SUPPORT_RC5_PROTOCOL == 1\n    proto_rc5,\n#endif\n#if IRMP_SUPPORT_DENON_PROTOCOL == 1\n    proto_denon,\n#endif\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n    proto_rc6,\n#endif\n#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1\n    proto_samsung32,\n#endif\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n    proto_apple,\n#endif\n#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1\n    proto_recs80ext,\n#endif\n#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1\n    proto_nubert,\n#endif\n#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n    proto_bang_olufsen,\n#endif\n#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1\n    proto_grundig,\n#endif\n#if IRMP_SUPPORT_NOKIA_PROTOCOL == 1\n    proto_nokia,\n#endif\n#if IRMP_SUPPORT_SIEMENS_PROTOCOL  == 1\n    proto_siemens,\n#endif\n#if IRMP_SUPPORT_FDC_PROTOCOL == 1\n    proto_fdc,\n#endif\n#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1\n    proto_rccar,\n#endif\n#if IRMP_SUPPORT_JVC_PROTOCOL == 1\n    proto_jvc,\n#endif\n#if IRMP_SUPPORT_RC6_PROTOCOL == 1\n    proto_rc6a,\n#endif\n#if IRMP_SUPPORT_NIKON_PROTOCOL == 1\n    proto_nikon,\n#endif\n#if IRMP_SUPPORT_RUWIDO_PROTOCOL == 1\n    proto_ruwido,\n#endif\n#if IRMP_SUPPORT_IR60_PROTOCOL == 1\n    proto_ir60,\n#endif\n#if IRMP_SUPPORT_KATHREIN_PROTOCOL == 1\n    proto_kathrein,\n#endif\n#if IRMP_SUPPORT_NETBOX_PROTOCOL == 1\n    proto_netbox,\n#endif\n#if IRMP_SUPPORT_NEC16_PROTOCOL == 1\n    proto_nec16,\n#endif\n#if IRMP_SUPPORT_NEC42_PROTOCOL == 1\n    proto_nec42,\n#endif\n#if IRMP_SUPPORT_LEGO_PROTOCOL == 1\n    proto_lego,\n#endif\n#if IRMP_SUPPORT_THOMSON_PROTOCOL == 1\n    proto_thomson,\n#endif\n#if IRMP_SUPPORT_BOSE_PROTOCOL == 1\n    proto_bose,\n#endif\n#if IRMP_SUPPORT_A1TVBOX_PROTOCOL == 1\n    proto_a1tvbox,\n#endif\n#if IRMP_SUPPORT_ORTEK_PROTOCOL == 1\n    proto_ortek,\n#endif\n#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n    proto_telefunken,\n#endif\n#if IRMP_SUPPORT_ROOMBA_PROTOCOL == 1\n    proto_roomba,\n#endif\n#if IRMP_SUPPORT_RCMM_PROTOCOL  == 1\n    proto_rcmm32,\n    proto_rcmm24,\n    proto_rcmm12,\n#endif\n#if IRMP_SUPPORT_SPEAKER_PROTOCOL == 1\n    proto_speaker,\n#endif\n#if IRMP_SUPPORT_LGAIR_PROTOCOL == 1\n    proto_lgair,\n#endif\n#if IRMP_SUPPORT_SAMSUNG48_PROTOCOL == 1\n    proto_samsung48,\n#endif\n#if IRMP_SUPPORT_MERLIN_PROTOCOL == 1\n    proto_merlin,\n#endif\n#if IRMP_SUPPORT_PENTAX_PROTOCOL == 1\n    proto_pentax,\n#endif\n#if IRMP_SUPPORT_FAN_PROTOCOL == 1\n    proto_fan,\n#endif\n#if IRMP_SUPPORT_S100_PROTOCOL == 1\n    proto_s100,\n#endif\n#if IRMP_SUPPORT_ACP24_PROTOCOL  == 1\n    proto_acp24,\n#endif\n#if IRMP_SUPPORT_TECHNICS_PROTOCOL == 1\n    proto_technics,\n#endif\n#if IRMP_SUPPORT_PANASONIC_PROTOCOL == 1 || IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1 // Panasonic vendor ID for kaseikyo\n    proto_panasonic,\n#endif\n#if IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n    proto_mitsu_heavy,\n#endif\n#if IRMP_SUPPORT_VINCENT_PROTOCOL == 1\n    proto_vincent,\n#endif\n#if IRMP_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n    proto_samsungah,\n#endif\n#if IRMP_SUPPORT_IRMP16_PROTOCOL == 1\n    proto_irmp16,\n#endif\n#if IRMP_SUPPORT_GREE_PROTOCOL == 1\n    proto_gree,\n#endif\n#if IRMP_SUPPORT_RCII_PROTOCOL == 1\n    proto_rcii,\n#endif\n#if IRMP_SUPPORT_METZ_PROTOCOL == 1\n    proto_metz,\n#endif\n#if IRMP_SUPPORT_NEC_PROTOCOL == 1\n    proto_onkyo,\n#endif\n#if IRMP_SUPPORT_RF_GEN24_PROTOCOL == 1\n    proto_rf_gen24,\n#endif\n#if IRMP_SUPPORT_RF_X10_PROTOCOL == 1\n    proto_rf_x10,\n#endif\n#if IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n    proto_rf_medion\n#endif\n#if IRMP_SUPPORT_MELINERA_PROTOCOL == 1\n    proto_melinera\n#endif\n#if IRMP_SUPPORT_RC6A20_PROTOCOL == 1\n    proto_rc6a20\n#endif\n#if IRMP_SUPPORT_RC6A28_PROTOCOL == 1\n    proto_rc6a28\n#endif\n};\n\n/*\n * No newline after printing\n */\nvoid irmp_print_active_protocols(Print *aSerial)\n{\n// skip protocol 0 = UNKNOWN\n    for (uint_fast8_t i = 1; i < sizeof(irmp_used_protocol_index); ++i)\n    {\n#if IRMP_PROTOCOL_NAMES == 1\n        /*\n         * Read names of protocol from array and print\n         */\n#  if defined(__AVR__)\n        const char* tProtocolStringPtr = (char*) pgm_read_word(&irmp_used_protocol_names[i]);\n        aSerial->print((__FlashStringHelper *) (tProtocolStringPtr));\n#  else\n        aSerial->print(irmp_used_protocol_names[i]);\n#  endif\n#else\n        /*\n         * Print just numbers of the protocols not the names\n         */\n#  if defined(__AVR__)\n        uint8_t tProtocolNumber = (uint8_t) pgm_read_byte(&irmp_used_protocol_index[i]);\n        aSerial->print(tProtocolNumber);\n#  else\n        aSerial->print(irmp_used_protocol_index[i]);\n#  endif\n#endif\n        aSerial->print(\", \");\n    }\n}\n\nvoid irmp_print_protocol_name(Print *aSerial, uint8_t aProtocolNumber)\n{\n#if IRMP_PROTOCOL_NAMES == 1\n#  if defined(__AVR__)\n    for (uint_fast8_t i = 0; i < sizeof(irmp_used_protocol_index); ++i)\n    {\n        if(pgm_read_byte(&irmp_used_protocol_index[i]) == aProtocolNumber)\n        {\n            const char* tProtocolStringPtr = (char*) pgm_read_word(&irmp_used_protocol_names[i]);\n            aSerial->print((__FlashStringHelper *) (tProtocolStringPtr));\n            return;\n        }\n    }\n#  else\n    // no need to save space\n    aSerial->print(irmp_protocol_names[aProtocolNumber]);\n#  endif\n#endif\n    // append protocol number\n    aSerial->print(F(\" | 0x\"));\n    aSerial->print(aProtocolNumber, HEX);\n}\n\n/*\n * Print protocol name or number, address, code and repetition flag\n * needs appr. 2 milliseconds for output\n */\nvoid irmp_result_print(Print *aSerial, IRMP_DATA *aIRMPDataPtr)\n{\n    /*\n     * Print protocol name or number\n     */\n    aSerial->print(F(\"P=\"));\n    irmp_print_protocol_name(aSerial, aIRMPDataPtr->protocol);\n\n    /*\n     * Print address, code and repetition flag\n     */\n    aSerial->print(F(\" A=0x\"));\n    aSerial->print(aIRMPDataPtr->address, HEX);\n    aSerial->print(F(\" C=0x\"));\n    aSerial->print(aIRMPDataPtr->command, HEX);\n    if (aIRMPDataPtr->flags & IRMP_FLAG_REPETITION)\n    {\n        aSerial->print(F(\" R\"));\n    }\n    aSerial->println();\n}\n\n/*\n * Do not just call irmp_result_print( &Serial, aIRMPDataPtr) above, since this is not always possible for ATtinies.\n */\nvoid irmp_result_print(IRMP_DATA *aIRMPDataPtr)\n{\n    /*\n     * Print protocol name or number\n     */\n    Serial.print(F(\"P=\"));\n// Wee need to check if &Serial is of type Print in order not to get errors on e.g. ATtinies\n// This is not the exact right condition, but on ATtinies you will mostly disable protocol names\n#if IRMP_PROTOCOL_NAMES == 1\n    irmp_print_protocol_name(&Serial, aIRMPDataPtr->protocol);\n#else\n    Serial.print(F(\"0x\"));\n    Serial.print(aIRMPDataPtr->protocol, HEX);\n#endif\n\n    /*\n     * Print address, code and repetition flag\n     */\n    Serial.print(F(\" A=0x\"));\n    Serial.print(aIRMPDataPtr->address, HEX);\n    Serial.print(F(\" C=0x\"));\n    Serial.print(aIRMPDataPtr->command, HEX);\n    if (aIRMPDataPtr->flags & IRMP_FLAG_REPETITION)\n    {\n        Serial.print(F(\" R\"));\n    }\n    Serial.println();\n}\n\n#endif // defined(ARDUINO)\n"
  },
  {
    "path": "src/irmpPinChangeInterrupt.hpp",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpPinChangeInterrupt.hpp\n *\n * Functions and ISR for the pin change interrupt functionality for IRMP - For Arduino platform\n * Must be included after irmp_ISR to have all the internal variables of irmp_ISR declared\n *\n *  Copyright (C) 2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#ifndef _IRMP_PIN_CHANGE_INTERRUPT_HPP\n#define _IRMP_PIN_CHANGE_INTERRUPT_HPP\n\n//#define PCI_DEBUG\n\n#  if defined(__AVR__)\nvoid irmp_debug_print(const __FlashStringHelper *aMessage, bool aDoShortOutput = true);\n#  else\nvoid irmp_debug_print(const char *aMessage, bool aDoShortOutput);\n#  endif\n\nuint32_t irmp_last_change_micros; // microseconds of last Pin Change Interrupt. Used for irmp_IsBusy().\n/*\n * Wrapper for irmp_ISR() in order to run it with Pin Change Interrupts.\n * Needs additional 8-9us per call and 13us for signal going inactive and 19us for going active.\n * Tested for NEC, Kaseiko, Denon, RC6, Samsung and others.\n * Requires micros() for timing.\n */\n//#define PCI_DEBUG\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR irmp_PCI_ISR(void)\n#else\nvoid irmp_PCI_ISR(void)\n#endif\n{\n\n    // save IR input level - negative logic, true means inactive / IR pause\n    uint_fast8_t irmp_input = input(IRMP_PIN);\n\n    /*\n     * 1. compute ticks after last change\n     */\n    uint32_t tMicros = micros();\n    uint32_t tTicks = tMicros - irmp_last_change_micros; // values up to 10000\n    irmp_last_change_micros = tMicros;\n#if (F_INTERRUPTS == 15625)\n    // F_INTERRUPTS value of 31250 does not work (maybe 8 bit overflow?)\n    tTicks = (tTicks << 2) >> 8;// saves 1.3 us\n#else\n#error F_INTERRUPTS must be 15625 (to avoid a time consuming division)\n#endif\n\n    if (tTicks != 0) {\n        tTicks -= 1; // adjust for irmp_pulse_time / irmp_pause_time incremented in irmp_ISR()\n    }\n\n    /*\n     * 2. check for input level and tweak timings\n     */\n    if (irmp_input) // true means inactive / IR pause\n    {\n        // start of pause -> just set pulse width\n        irmp_pulse_time += tTicks;\n    } else {\n        if (irmp_start_bit_detected) {\n            irmp_pause_time += tTicks;\n        } else { // start pulse here -> set pause or time between repetitions\n            if (tTicks > UINT16_MAX) {\n                // avoid overflow for 16 bit key_repetition_len\n                tTicks = UINT16_MAX;\n            }\n            key_repetition_len = tTicks;\n        }\n    }\n\n    /*\n     * 3. call the protocol detection routine\n     */\n    irmp_ISR();\n\n    if (!irmp_ir_detected && irmp_input) {\n        /*\n         * No valid protocol detected and IR input is inactive now -> simulate end for protocols.\n         * IRMP may be waiting for stop bit, but detects it only at the next call, so do one additional call.\n         * !!! ATTENTION !!! This will NOT work if we try to receive simultaneously two protocols which are only different in length like NEC16 and NEC42\n         */\n#if defined(PCI_DEBUG)\n        Serial.write('x');\n        if (irmp_bit > 0 && irmp_bit == irmp_param.complete_len)\n        {\n            Serial.println(irmp_start_bit_detected); // print start bit if complete_len is reached\n        }\n#endif\n        if (irmp_start_bit_detected && irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == TRUE) {\n            // Try to detect a nec repeat irmp_bit is 0\n#if defined(PCI_DEBUG)\n            irmp_debug_print(F(\"R\"));\n#endif\n            PAUSE_LEN irmp_pause_time_store = irmp_pause_time;\n            irmp_pause_time = STOP_BIT_PAUSE_LEN_MIN + 1; // set pause time to minimal pause required to detect a stop bit\n            irmp_ISR(); // Call to detect a NEC repeat\n#if defined(PCI_DEBUG)\n            irmp_debug_print(F(\"E\")); // print info after call\n            Serial.println();\n#endif\n            if (irmp_ir_detected) {\n                // no protocol detected -> restore irmp_pause_time. Not sure if this is really required.\n                irmp_pause_time = irmp_pause_time_store;\n            }\n        }\n\n        // For condition see also line 4203 and 5098 in irmp.hpp\n        if (irmp_start_bit_detected && irmp_bit > 0 && irmp_bit == irmp_param.complete_len) {\n            // Complete length of bit now received -> try to detect end of protocol\n#if defined(PCI_DEBUG)\n            irmp_debug_print(F(\"S\")); // print info before call\n#endif\n            PAUSE_LEN irmp_pause_time_store = irmp_pause_time;\n            irmp_pause_time = STOP_BIT_PAUSE_LEN_MIN + 1; // set pause time to minimal pause required to detect a stop bit\n            irmp_ISR(); // Call to detect end of protocol, irmp_param.stop_bit (printed as Sb) should be set to 0 if stop bit was successfully detected.\n#if defined(PCI_DEBUG)\n            irmp_debug_print(F(\"E\")); // print info after call\n            Serial.println();\n#endif\n            if (irmp_ir_detected) {\n                // no protocol detected -> restore irmp_pause_time. Not sure if this is really required.\n                irmp_pause_time = irmp_pause_time_store;\n            }\n        }\n\n#if (IRMP_SUPPORT_MANCHESTER == 1)\n    /*\n     * Simulate end for Manchester/biphase protocols - 130 bytes\n     */\n    if (((irmp_bit == irmp_param.complete_len - 1 && tTicks < irmp_param.pause_1_len_max)\n                    || (irmp_bit == irmp_param.complete_len - 2 && tTicks > irmp_param.pause_1_len_max))\n            && (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) && irmp_start_bit_detected)\n    {\n#  if defined(PCI_DEBUG)\n    Serial.println('M'); // Try to detect a Manchester end of protocol\n#  endif\n    irmp_pause_time = 2 * irmp_param.pause_1_len_max;\n        irmp_ISR();        // Write last one (with value 0) or 2 (with last value 1) data bits and set wait for dummy stop bit\n        irmp_ISR();// process dummy stop bit\n        irmp_ISR();// reset stop bit and call callback\n    }\n#endif\n    }\n}\n\nvoid enablePCIInterrupt() {\n#if defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n    attachInterrupt(IRMP_INPUT_PIN, irmp_PCI_ISR, CHANGE); // 14.2 us before LED Feedback compared to 12 if configured with macros and less compatible\n\n#elif ! defined(__AVR__) || defined(IRMP_USE_ARDUINO_ATTACH_INTERRUPT)\n#  if defined(ARDUINO_ARCH_SAMD) // see https://www.arduino.cc/reference/tr/language/functions/external-interrupts/attachinterrupt/ paragraph: Syntax\n    attachInterrupt(IRMP_INPUT_PIN, irmp_PCI_ISR, CHANGE);\n#  else\n    attachInterrupt(digitalPinToInterrupt(IRMP_INPUT_PIN), irmp_PCI_ISR, CHANGE); // CHANGE can be an enum :-(\n#  endif\n\n#else\n#  if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n    // use PinChangeInterrupt\n    PCMSK |= _BV(IRMP_INPUT_PIN);\n    // clear interrupt bit\n    GIFR |= 1 << PCIF;\n    // enable interrupt on next change\n    GIMSK |= 1 << PCIE;\n\n#  elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#    if defined(ARDUINO_AVR_DIGISPARKPRO)\n#      if (IRMP_INPUT_PIN == 3)\n    // interrupt on any logical change\n    EICRA |= _BV(ISC00);\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT0;\n#      elif (IRMP_INPUT_PIN == 9)\n    EICRA |= _BV(ISC10);\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT1;\n#      else\n#        error \"For interrupt mode (IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined) IRMP_INPUT_PIN must be 9 or 3.\"\n#      endif // if (IRMP_INPUT_PIN == 9)\n\n#    else // defined(ARDUINO_AVR_DIGISPARKPRO)\n#      if (IRMP_INPUT_PIN == 14)\n    // interrupt on any logical change\n    EICRA |= _BV(ISC00);\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT0;\n#      elif (IRMP_INPUT_PIN == 3)\n    EICRA |= _BV(ISC10);\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT1;\n#      else\n#        error \"For interrupt mode (IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined) IRMP_INPUT_PIN must be 14 or 3.\"\n#      endif // if (IRMP_INPUT_PIN == 14)\n#    endif\n\n#  else // defined(__AVR_ATtiny25__)\n    /*\n     * ATmegas here\n     */\n#    if (IRMP_INPUT_PIN == 2)\n    // interrupt on any logical change\n    EICRA |= _BV(ISC00);\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT0;\n#    elif (IRMP_INPUT_PIN == 3)\n    EICRA |= _BV(ISC10);\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // enable interrupt on next change\n    EIMSK |= 1 << INT1;\n#    else\n#      error \"For interrupt mode (IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined) IRMP_INPUT_PIN must be 2 or 3.\"\n#    endif // if (IRMP_INPUT_PIN == 2)\n#  endif // defined(__AVR_ATtiny25__)\n#endif // ! defined(__AVR__) || defined(IRMP_USE_ARDUINO_ATTACH_INTERRUPT)\n}\n\nvoid disablePCIInterrupt() {\n#if defined(__AVR_ATtiny1616__)  || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)\n    detachInterrupt(IRMP_INPUT_PIN);\n\n#elif ! defined(__AVR__) || defined(IRMP_USE_ARDUINO_ATTACH_INTERRUPT)\n    detachInterrupt(digitalPinToInterrupt(IRMP_INPUT_PIN));\n\n#else\n#  if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)\n    // clear interrupt bit\n    GIFR |= 1 << PCIF;\n    // disable interrupt on next change\n    GIMSK &= ~(1 << PCIE);\n\n#  elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)\n#    if defined(ARDUINO_AVR_DIGISPARKPRO)\n#      if (IRMP_INPUT_PIN == 3)\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // disable interrupt on next change\n    EIMSK &= ~( 1 << INT0);\n#      elif (IRMP_INPUT_PIN == 9)\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT1);\n#      else\n#        error \"For interrupt mode (IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined) IRMP_INPUT_PIN must be 9 or 3.\"\n#      endif // if (IRMP_INPUT_PIN == 9)\n\n#    else // defined(ARDUINO_AVR_DIGISPARKPRO)\n#      if (IRMP_INPUT_PIN == 14)\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT0);\n#      elif (IRMP_INPUT_PIN == 3)\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT1);\n#      else\n#        error \"For interrupt mode (IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined) IRMP_INPUT_PIN must be 14 or 3.\"\n#      endif // if (IRMP_INPUT_PIN == 14)\n#    endif\n\n#  else // defined(__AVR_ATtiny25__)\n    /*\n     * ATmegas here\n     */\n#    if (IRMP_INPUT_PIN == 2)\n    // clear interrupt bit\n    EIFR |= 1 << INTF0;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT0);\n#    elif (IRMP_INPUT_PIN == 3)\n    // clear interrupt bit\n    EIFR |= 1 << INTF1;\n    // disable interrupt on next change\n    EIMSK &= ~(1 << INT1);\n#    else\n#      error \"For interrupt mode (IRMP_ENABLE_PIN_CHANGE_INTERRUPT is defined) IRMP_INPUT_PIN must be 2 or 3.\"\n#    endif // if (IRMP_INPUT_PIN == 2)\n#  endif // defined(__AVR_ATtiny25__)\n#endif // ! defined(__AVR__) || defined(IRMP_USE_ARDUINO_ATTACH_INTERRUPT)\n}\n\n/*\n * Specify the right INT0, INT1 or PCINT0 interrupt vector according to different pins and cores\n */\n#if defined(__AVR__) && !defined(IRMP_USE_ARDUINO_ATTACH_INTERRUPT)\n#  if (IRMP_INPUT_PIN == 2)\nISR(INT0_vect) // Pin 2 global assignment\n\n#  elif (IRMP_INPUT_PIN == 3)\n#    if  defined(ARDUINO_AVR_DIGISPARKPRO)\nISR(INT0_vect) //  Pin 3 / PB6 / INT0 is connected to USB+ on DigisparkPro boards\n#    else\nISR(INT1_vect) // Pin 3 global assignment\n#    endif\n\n#  elif (IRMP_INPUT_PIN == 9) // Digispark pro\nISR(INT1_vect)\n\n#  elif (IRMP_INPUT_PIN == 14) // For AVR_ATtiny167 INT0 is on pin 14 / PB6\nISR(INT0_vect)\n#  elif (! defined(ISC10)) || ((defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)) && INT1_PIN != 3)\n// on ATtinyX5 we do not have a INT1_vect but we can use the PCINT0_vect\nISR(PCINT0_vect)\n#  endif // (IRMP_INPUT_PIN == 2)\n{\n    irmp_PCI_ISR();\n}\n#endif // defined(__AVR__) && !defined(IRMP_USE_ARDUINO_ATTACH_INTERRUPT)\n\n#if defined(__AVR__)\nvoid irmp_debug_print(const __FlashStringHelper *aMessage, bool aDoShortOutput)\n#else\nvoid irmp_debug_print(const char *aMessage, bool aDoShortOutput)\n#endif\n{\n    Serial.print(aMessage);\n    Serial.print(' ');\n    Serial.print(irmp_ir_detected); // valid IR command detected\n    Serial.print(F(\" St\"));\n    Serial.print(irmp_start_bit_detected);\n\n    Serial.print(F(\" Ws\"));\n    Serial.print(wait_for_space); // true if in data/address section and no signal. Now increment pause time.\n    Serial.print(F(\" Wss\"));\n    Serial.print(wait_for_start_space); // true if we have received start bit\n\n    Serial.print(F(\" L\"));\n    Serial.print(irmp_param.complete_len); // maximum bit position\n    Serial.print(F(\" B\"));\n    Serial.print((int8_t) irmp_bit); // current bit position - FF(-1) is start value\n    Serial.print(F(\" Pu\"));\n    Serial.print(irmp_pulse_time); // bit time for pulse\n    Serial.print(F(\" Pa\"));\n    Serial.print(irmp_pause_time);\n\n    Serial.print(F(\" Sb\"));\n    Serial.print(irmp_param.stop_bit); // boolean. 1 = stop bit required\n\n    if (!aDoShortOutput)\n    {\n        Serial.print(F(\" F\"));\n        Serial.print(irmp_flags); // currently only repetition flag\n        Serial.print(F(\" K\"));\n        Serial.print(key_repetition_len); // the pause after a command to distinguish repetitions from new commands\n        Serial.print(F(\" R\"));\n        Serial.print(repetition_frame_number); // Number of repetitions\n    }\n\n    Serial.println();\n}\n\n#endif // _IRMP_PIN_CHANGE_INTERRUPT_HPP\n"
  },
  {
    "path": "src/irmpSelectAllProtocols.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpSelectAllProtocols.h\n * 42 + 1 protocols enabled\n * 8 Protocols disabled since they conflicts with the enabled ones\n * Depending on the value of F_INTERRUPTS 2 other protocols (LEGO and RCMM or PENTAX and GREE) are disabled too - see F_INTERRUPTS below\n *\n *\n * Copyright (c) 2009-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMP_SELECT_PROTOCOLS_H\n#define _IRMP_SELECT_PROTOCOLS_H\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 if you want to disable one or more decoders.\n * This saves program memory.\n *\n * 1 enable  decoder\n * 0 disable decoder\n *\n * The standard decoders are enabled per default.\n * Less common protocols are disabled here, you need to enable them manually.\n *\n * If you want to use FDC or RCCAR simultaneous with RC5 protocol, additional program memory is required.\n * If you don't need RC5 when using FDC/RCCAR, you should disable RC5.\n * You cannot enable both DENON and RUWIDO, only enable one of them.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Protocols Part 1: IR decoders\n * If you use a RF receiver, deactivate all IR protocols!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n// 4 typical protocols, disable here!           Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_SIRCS_PROTOCOL             1       // Sony SIRCS           >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_NEC_PROTOCOL               1       // NEC + APPLE + ONKYO  >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SAMSUNG_PROTOCOL           1       // Samsung + Samsg32    >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_KASEIKYO_PROTOCOL          1       // Kaseikyo             >= 10000                 ~250 bytes\n\n// 11 more protocols, enable here!              Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_JVC_PROTOCOL               1       // JVC                  >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_NEC16_PROTOCOL             1       // NEC16                >= 10000                 ~100 bytes\n#define IRMP_SUPPORT_NEC42_PROTOCOL             1       // NEC42                >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL        1       // Matsushita           >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_DENON_PROTOCOL             1       // DENON, Sharp         >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC5_PROTOCOL               1       // RC5                  >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC6_PROTOCOL               1       // RC6 & RC6A           >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_IR60_PROTOCOL              1       // IR60 (SDA2008)       >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_GRUNDIG_PROTOCOL           1       // Grundig              >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SIEMENS_PROTOCOL           1       // Siemens Gigaset      >= 15000                 ~550 bytes\n#define IRMP_SUPPORT_NOKIA_PROTOCOL             1       // Nokia                >= 10000                 ~300 bytes\n\n// 27 + 8 exotic protocols, enable here!        Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_BOSE_PROTOCOL              1       // BOSE                 >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_KATHREIN_PROTOCOL          1       // Kathrein             >= 10000                 ~200 bytes\n#define IRMP_SUPPORT_NUBERT_PROTOCOL            1       // NUBERT               >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_FAN_PROTOCOL               0       // FAN (ventilator)     >= 10000                  ~50 bytes     conflicts with NUBERT\n#define IRMP_SUPPORT_SPEAKER_PROTOCOL           1       // SPEAKER (~NUBERT)    >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL      1       // Bang & Olufsen       >= 10000                 ~200 bytes\n#define IRMP_SUPPORT_RECS80_PROTOCOL            1       // RECS80 (SAA3004)     >= 15000                  ~50 bytes\n#define IRMP_SUPPORT_RECS80EXT_PROTOCOL         1       // RECS80EXT (SAA3008)  >= 15000                  ~50 bytes\n#define IRMP_SUPPORT_THOMSON_PROTOCOL           1       // Thomson              >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_NIKON_PROTOCOL             1       // NIKON camera         >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_NETBOX_PROTOCOL            1       // Netbox keyboard      >= 10000                 ~400 bytes (PROTOTYPE!)\n#define IRMP_SUPPORT_ORTEK_PROTOCOL             0       // ORTEK (Hama)         >= 10000                 ~150 bytes     conflicts with FDC and NETBOX\n#define IRMP_SUPPORT_TELEFUNKEN_PROTOCOL        1       // Telefunken 1560      >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_FDC_PROTOCOL               1       // FDC3402 keyboard     >= 10000 (better 15000)  ~150 bytes (~400 in combination with RC5)\n#define IRMP_SUPPORT_RCCAR_PROTOCOL             1       // RC Car               >= 10000 (better 15000)  ~150 bytes (~500 in combination with RC5)\n#define IRMP_SUPPORT_ROOMBA_PROTOCOL            0       // iRobot Roomba        >= 10000                 ~150 bytes     conflicts with RC6\n#define IRMP_SUPPORT_RUWIDO_PROTOCOL            0       // RUWIDO, T-Home       >= 15000                 ~550 bytes     conflicts with DENON\n#define IRMP_SUPPORT_A1TVBOX_PROTOCOL           1       // A1 TV BOX            >= 15000 (better 20000)  ~300 bytes\n#define IRMP_SUPPORT_LEGO_PROTOCOL              1       // LEGO Power RC        >= 20000                 ~150 bytes\n#define IRMP_SUPPORT_RCMM_PROTOCOL              1       // RCMM 12,24, or 32    >= 20000                 ~150 bytes\n#define IRMP_SUPPORT_LGAIR_PROTOCOL             1       // LG Air Condition     >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SAMSUNG48_PROTOCOL         1       // Samsung48            >= 10000                 ~100 bytes (SAMSUNG must be enabled!)\n#define IRMP_SUPPORT_MERLIN_PROTOCOL            1       // Merlin               >= 15000 (better 20000)  ~300 bytes (requires IRMP_32_BIT=1)\n#define IRMP_SUPPORT_PENTAX_PROTOCOL            1       // Pentax               >= 10000 <=17000         ~150 bytes (<= 17000 due to 8 bit timing overflow issue)\n#define IRMP_SUPPORT_S100_PROTOCOL              0       // S100                 >= 10000                 ~250 bytes     conflicts with RC5\n#define IRMP_SUPPORT_ACP24_PROTOCOL             0       // ACP24                >= 10000                 ~250 bytes     conflicts with DENON\n#define IRMP_SUPPORT_TECHNICS_PROTOCOL          1       // TECHNICS             >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_PANASONIC_PROTOCOL         0       // PANASONIC Beamer     >= 10000                 ~250 bytes     Panasonic is Kaseikyo with vendor code 0x2002 and you cannot distinguish it by start bit timing.\n#define IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL       0       // Mitsubishi Aircond   >= 10000                 ~250 bytes     Mitsubishi is Kaseikyo with vendor code 0xCB23 and you cannot distinguish it by start bit timing.\n#define IRMP_SUPPORT_VINCENT_PROTOCOL           1       // VINCENT              >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_SAMSUNGAH_PROTOCOL         1       // SAMSUNG AH           >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_IRMP16_PROTOCOL            0       // IRMP specific        >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_GREE_PROTOCOL              1       // GREE CLIMATE         >= 10000 <=17000         ~250 bytes\n#define IRMP_SUPPORT_RCII_PROTOCOL              0       // RCII T+A             >= 15000                 ~250 bytes     conflicts with GRUNDIG and NOKIA\n#define IRMP_SUPPORT_METZ_PROTOCOL              1\n#define IRMP_SUPPORT_MELINERA_PROTOCOL          1       // MELINERA (Lidl)      >= 10000\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Protocols Part 2: RF decoders\n * If you use an IR sensor, deactivate all RF protocols!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP_SUPPORT_RF_GEN24_PROTOCOL          0       // RF GEN24 (generic)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_X10_PROTOCOL            0       // RF PC X10 (Medion)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_MEDION_PROTOCOL         0       // RF PC Medion         >= 15000                 ~250 bytes\n\n\n#endif // _IRMP_SELECT_ALL_PROTOCOLS_H\n"
  },
  {
    "path": "src/irmpSelectAllRFProtocols.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpSelectAllRFProtocols.h\n * 2 protocols enabled\n *\n * Copyright (c) 2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMP_SELECT_ALL_RF_PROTOCOLS_H\n#define _IRMP_SELECT_ALL_RF_PROTOCOLS_H\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 if you want to disable one or more decoders.\n * This saves program memory.\n *\n * 1 enable  decoder\n * 0 disable decoder\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Protocols Part 2: RF decoders\n * If you use an IR sensor, deactivate all RF protocols!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP_SUPPORT_RF_GEN24_PROTOCOL          1       // RF GEN24 (generic)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_X10_PROTOCOL            1       // RF PC X10 (Medion)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_MEDION_PROTOCOL         1       // RF PC Medion         >= 15000                 ~250 bytes\n\n// Usually IR sensors are low active, RF receivers are high active.\n#define IRMP_HIGH_ACTIVE                        1       // set to 1 if you use a RF receiver!\n\n#endif // _IRMP_SELECT_ALL_RF_PROTOCOLS_H\n"
  },
  {
    "path": "src/irmpSelectMain15Protocols.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpSelectMain15Protocols.h\n *\n *\n * Copyright (c) 2009-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMP_SELECT_PROTOCOLS_H\n#define _IRMP_SELECT_PROTOCOLS_H\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 (or deactivate it) if you want to disable one or more decoders.\n * This saves program memory.\n *\n * 1 enable  decoder\n * 0 disable decoder\n *\n * The standard decoders are enabled per default.\n * Less common protocols are disabled here, you need to enable them manually.\n *\n * If you want to use FDC or RCCAR simultaneous with RC5 protocol, additional program memory is required.\n * If you don't need RC5 when using FDC/RCCAR, you should disable RC5.\n * You cannot enable both DENON and RUWIDO, only enable one of them.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_SIRCS_PROTOCOL             1       // Sony SIRCS           >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_NEC_PROTOCOL               1       // NEC + APPLE + ONKYO  >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SAMSUNG_PROTOCOL           1       // Samsung + Samsg32    >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_KASEIKYO_PROTOCOL          1       // Kaseikyo             >= 10000                 ~250 bytes\n\n// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_JVC_PROTOCOL               1       // JVC                  >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_NEC16_PROTOCOL             1       // NEC16                >= 10000                 ~100 bytes\n#define IRMP_SUPPORT_NEC42_PROTOCOL             1       // NEC42                >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL        1       // Matsushita           >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_DENON_PROTOCOL             1       // DENON, Sharp         >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC5_PROTOCOL               1       // RC5                  >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC6_PROTOCOL               1       // RC6 & RC6A           >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_IR60_PROTOCOL              1       // IR60 (SDA2008)       >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_GRUNDIG_PROTOCOL           1       // Grundig              >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SIEMENS_PROTOCOL           1       // Siemens Gigaset      >= 15000                 ~550 bytes\n#define IRMP_SUPPORT_NOKIA_PROTOCOL             1       // Nokia                >= 10000                 ~300 bytes\n\n#endif // _IRMP_SELECT_PROTOCOLS_H\n"
  },
  {
    "path": "src/irmpVersion.h",
    "content": "/*\n * irmpVersion.h\n *\n * Is used for IRMP and IRSND, and therefore a separate file\n *\n *  Created on: 28.05.2020\n *      Author: Armin\n */\n\n#ifndef _IRMPVERSION_H\n#define _IRMPVERSION_H\n\n#define VERSION_IRMP \"3.7.0\"\n#define VERSION_IRMP_MAJOR 3\n#define VERSION_IRMP_MINOR 7\n#define VERSION_IRMP_PATCH 0\n\n/*\n * Macro to convert 3 version parts into an integer\n * To be used in preprocessor comparisons, such as #if VERSION_IRMP_HEX >= VERSION_HEX_VALUE(3, 7, 0)\n */\n#define VERSION_HEX_VALUE(major, minor, patch) ((major << 16) | (minor << 8) | (patch))\n#define VERSION_IRMP_HEX  VERSION_HEX_VALUE(VERSION_IRMP_MAJOR, VERSION_IRMP_MINOR, VERSION_IRMP_PATCH)\n#endif /* _IRMPVERSION_H */\n"
  },
  {
    "path": "src/irmpconfig.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpconfig.h\n *\n * DO NOT INCLUDE THIS FILE, WILL BE INCLUDED BY IRMP.H!\n *\n * Copyright (c) 2009-2020 Frank Meyer - frank(at)fli4l.de\n * Extensions for PIC 12F1820 W.Strobl 2014-07-20\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMP_H_\n#  error please include only irmp.h, not irmpconfig.h\n#endif\n\n#if defined(IRMPCONFIG_STAGE1_H)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change IRMP_32_BIT here\n *\n * Normally, IRMP_32_BIT ist 0. Then we use irmp.command as a 16 bit value.\n * If you set IRMP_32_BIT to 1, we will use irmp.command as a 32 bit value.\n * A 32 bit command costs more CPU resources on 8 bit processors (e.g. AVR),\n * but there are IR protocols which need more than 16 bits for a reasonable\n * command value.\n *\n * If you want to use one of the following protocols, set IRMP_32_BIT to 1,\n * otherwise set it to 0:\n *    - MERLIN\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#if !defined(IRMP_32_BIT)\n#  if __SIZEOF_INT__ == 4\n#  define IRMP_32_BIT     1                                                                               // use 32 bit command value, 0 or 1\n#  else\n#  define IRMP_32_BIT     0                                                                               // use 32 bit command value, 0 or 1\n#  endif\n#endif\n\n#endif // IRMPCONFIG_STAGE1_H\n\n#if defined(IRMPCONFIG_STAGE2_H)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change F_INTERRUPTS if you change the number of interrupts per second,\n * Normally, F_INTERRUPTS should be in the range from 10000 to 15000, typical is 15000\n * A value above 15000 costs additional program memory, absolute maximum value is 20000.\n * A value of 20000 is needed for Support of LEGO and RCMM, but it prevents using PENTAX or GREE\n *  since for 20000 they have 8 bit overflow issues because of the long start bits.\n * On PIC with XC8/C18 Compiler, use 15151 as the correct value.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(F_INTERRUPTS)\n#  define F_INTERRUPTS                          15000                           // interrupts per second, 66,66us, min: 10000, max: 20000, typ: 15000\n#endif\n\n#if ! defined(ARDUINO)\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 if you want to disable one or more decoders.\n * This saves program memory.\n *\n * 1 enable  decoder\n * 0 disable decoder\n *\n * The standard decoders are enabled per default.\n * Less common protocols are disabled here, you need to enable them manually.\n *\n * If you want to use FDC or RCCAR simultaneous with RC5 protocol, additional program memory is required.\n * If you don't need RC5 when using FDC/RCCAR, you should disable RC5.\n * You cannot enable both DENON and RUWIDO, only enable one of them.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Protocols Part 1: IR decoders\n * If you use a RF receiver, deactivate all IR protocols!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_SIRCS_PROTOCOL             1       // Sony SIRCS           >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_NEC_PROTOCOL               1       // NEC + APPLE + ONKYO  >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SAMSUNG_PROTOCOL           1       // Samsung + Samsg32    >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_KASEIKYO_PROTOCOL          1       // Kaseikyo             >= 10000                 ~250 bytes\n\n// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_JVC_PROTOCOL               0       // JVC                  >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_NEC16_PROTOCOL             0       // NEC16                >= 10000                 ~100 bytes\n#define IRMP_SUPPORT_NEC42_PROTOCOL             0       // NEC42                >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL        0       // Matsushita           >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_DENON_PROTOCOL             0       // DENON, Sharp         >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC5_PROTOCOL               0       // RC5                  >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RC6_PROTOCOL               0       // RC6 & RC6A           >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_IR60_PROTOCOL              0       // IR60 (SDA2008)       >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_GRUNDIG_PROTOCOL           0       // Grundig              >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SIEMENS_PROTOCOL           0       // Siemens Gigaset      >= 15000                 ~550 bytes\n#define IRMP_SUPPORT_NOKIA_PROTOCOL             0       // Nokia                >= 10000                 ~300 bytes\n\n// exotic protocols, enable here!               Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRMP_SUPPORT_BOSE_PROTOCOL              0       // BOSE                 >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_KATHREIN_PROTOCOL          0       // Kathrein             >= 10000                 ~200 bytes\n#define IRMP_SUPPORT_NUBERT_PROTOCOL            0       // NUBERT               >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_FAN_PROTOCOL               0       // FAN (ventilator)     >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_SPEAKER_PROTOCOL           0       // SPEAKER (~NUBERT)    >= 10000                  ~50 bytes\n#define IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL      0       // Bang & Olufsen       >= 10000                 ~200 bytes\n#define IRMP_SUPPORT_RECS80_PROTOCOL            0       // RECS80 (SAA3004)     >= 15000                  ~50 bytes\n#define IRMP_SUPPORT_RECS80EXT_PROTOCOL         0       // RECS80EXT (SAA3008)  >= 15000                  ~50 bytes\n#define IRMP_SUPPORT_THOMSON_PROTOCOL           0       // Thomson              >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_NIKON_PROTOCOL             0       // NIKON camera         >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_NETBOX_PROTOCOL            0       // Netbox keyboard      >= 10000                 ~400 bytes (PROTOTYPE!)\n#define IRMP_SUPPORT_ORTEK_PROTOCOL             0       // ORTEK (Hama)         >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_TELEFUNKEN_PROTOCOL        0       // Telefunken 1560      >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_FDC_PROTOCOL               0       // FDC3402 keyboard     >= 10000 (better 15000)  ~150 bytes (~400 in combination with RC5)\n#define IRMP_SUPPORT_RCCAR_PROTOCOL             0       // RC Car               >= 10000 (better 15000)  ~150 bytes (~500 in combination with RC5)\n#define IRMP_SUPPORT_ROOMBA_PROTOCOL            0       // iRobot Roomba        >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_RUWIDO_PROTOCOL            0       // RUWIDO, T-Home       >= 15000                 ~550 bytes\n#define IRMP_SUPPORT_A1TVBOX_PROTOCOL           0       // A1 TV BOX            >= 15000 (better 20000)  ~300 bytes\n#define IRMP_SUPPORT_LEGO_PROTOCOL              0       // LEGO Power RC        >= 20000                 ~150 bytes\n#define IRMP_SUPPORT_RCMM_PROTOCOL              0       // RCMM 12,24, or 32    >= 20000                 ~150 bytes\n#define IRMP_SUPPORT_LGAIR_PROTOCOL             0       // LG Air Condition     >= 10000                 ~300 bytes\n#define IRMP_SUPPORT_SAMSUNG48_PROTOCOL         0       // Samsung48            >= 10000                 ~100 bytes (SAMSUNG must be enabled!)\n#define IRMP_SUPPORT_MERLIN_PROTOCOL            0       // Merlin               >= 15000 (better 20000)  ~300 bytes (requires IRMP_32_BIT=1)\n#define IRMP_SUPPORT_PENTAX_PROTOCOL            0       // Pentax               >= 10000                 ~150 bytes\n#define IRMP_SUPPORT_S100_PROTOCOL              0       // S100                 >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_ACP24_PROTOCOL             0       // ACP24                >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_TECHNICS_PROTOCOL          0       // TECHNICS             >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_PANASONIC_PROTOCOL         0       // PANASONIC Beamer     >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_MITSU_HEAVY_PROTOCOL       0       // Mitsubishi Aircond   >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_VINCENT_PROTOCOL           0       // VINCENT              >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_SAMSUNGAH_PROTOCOL         0       // SAMSUNG AH           >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_IRMP16_PROTOCOL            0       // IRMP specific        >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_GREE_PROTOCOL              0       // GREE CLIMATE         >= 10000                 ~250 bytes\n#define IRMP_SUPPORT_RCII_PROTOCOL              0       // RCII T+A             >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_METZ_PROTOCOL              0       // METZ                 >= 15000                 ~250 bytes\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Protocols Part 2: RF decoders\n * If you use an IR sensor, deactivate all RF protocols!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP_SUPPORT_RF_GEN24_PROTOCOL          0       // RF GEN24 (generic)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_X10_PROTOCOL            0       // RF PC X10 (Medion)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_MEDION_PROTOCOL         0       // RF PC Medion         >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_MELINERA_PROTOCOL          0       // MELINERA (Lidl)      >= 10000\n#endif // ! defined(ARDUINO)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for ATMEL ATmega/ATTiny/XMega\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined (ATMEL_AVR) || defined (__AVR_XMEGA__)                      // use PB6 as IR input on AVR\n#  define IRMP_PORT_LETTER                      B\n#  define IRMP_BIT_NUMBER                       6\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for PIC C18 or XC8 compiler\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (PIC_C18)                                                 // use RB4 as IR input on PIC (C18 or XC8 compiler)\n#  if defined(__12F1840)\n#    define IRMP_PIN                            RA5                     // on 12F1840 with XC8 compiler\n#  else\n#    define IRMP_PIN                            PORTBbits.RB4           // PIC C18\n#  endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for PIC XC32 or ChipKIT compiler\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (PIC_XC32)                                                // use RB13 as IR input on PIC (XC32 or ChipKIT compiler)\n#  define IRMP_PIN                              PORTBbits.RB13\n#  define IRMP_ANSELBIT                         ANSELBbits.ANSB13       // leave this undefined if the pin has no analog function\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for PIC CCS compiler\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (PIC_CCS)\n#  define IRMP_PIN                              PIN_B4                  // use PB4 as IR input on PIC (CCS compiler)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for ARM STM32\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (ARM_STM32)                                               // use C13 as IR input on STM32\n#  define IRMP_PORT_LETTER                      C\n#  define IRMP_BIT_NUMBER                       13\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Hardware pin for ARM STM32 (HAL) - don't change here, define IRMP_RECEIVE_GPIO_Port & IRMP_RECEIVE_PIN in STM32Cube (Main.h)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (ARM_STM32_HAL)                                           // STM32: IRMP_RECEIVE_GPIO_Port & IRMP_RECEIVE_PIN must be defined in STM32Cube\n#  define IRMP_PORT_LETTER                      IRMP_Receive_GPIO_Port\n#  define IRMP_BIT_NUMBER                       IRMP_Receive_Pin\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for Stellaris ARM Cortex M4\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (STELLARIS_ARM_CORTEX_M4)                                 // use B4 as IR input on Stellaris LM4F\n#  define IRMP_PORT_LETTER                      B\n#  define IRMP_BIT_NUMBER                       4\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for STM8\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (SDCC_STM8)                                               // use PA1 as IR input on STM8\n#  define IRMP_PORT_LETTER                      A                       // change here\n#  define IRMP_BIT_NUMBER                       1                       // change here\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for ESP8266\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (__xtensa__)\n#  define IRMP_BIT_NUMBER                       12                      // use GPIO12 (Pin 7 UEXT) on ESP8266-EVB evaluation board\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for Teensy 3.x with teensyduino gcc compiler\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (TEENSY_ARM_CORTEX_M4)\n#  define IRMP_PIN                              1                       // use Digital pin 1 as IR input on Teensy\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for MBED\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined(__MBED__)\n#  define IRMP_PIN                              P0_22                   // use P1_27 on LPC1347\n#  define IRMP_PINMODE                          PullUp                  // hardware dependent\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change hardware pin here for ChibiOS HAL\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined(_CHIBIOS_HAL_)\n#  define IRMP_PIN                              LINE_IR_IN              // use pin names as defined in the board config file, prefixed with \"LINE_\"\n#  define IRMP_LOGGING_SD                       SD1                     // the ChibiOS HAL Serial Driver instance to log to\n                                                                        // (when IRMP_LOGGING is enabled below).\n                                                                        // Make sure SERIAL_BUFFERS_SIZE is large enough when enabling logging\n#elif defined(ARDUINO)\n// specified here to avoid else case\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Handling of unknown target system: DON'T CHANGE\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif !defined (UNIX_OR_WINDOWS)\n#  error target system not defined.\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change if sensor is high active\n *\n * Usually IR sensors are low active, RF receivers are high active. Change here if you use a RF receiver!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_HIGH_ACTIVE)\n#  define IRMP_HIGH_ACTIVE                      0                       // set to 1 if you use a RF receiver!\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Enable detection of key releases\n *\n * If user releases a key on the remote control, last protocol/address/command will be returned with flag IRMP_FLAG_RELEASE set\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_ENABLE_RELEASE_DETECTION)\n#  define IRMP_ENABLE_RELEASE_DETECTION         0                       // enable detection of key releases\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Set IRMP_LOGGING to 1 if want to log data to UART with 9600Bd\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_LOGGING)\n#  define IRMP_LOGGING                          0                       // 1: log IR signal (scan), 0: do not. default is 0\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Use external logging routines\n * If you enable external logging, you have also to enable IRMP_LOGGING above\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_EXT_LOGGING)\n#  define IRMP_EXT_LOGGING                      0                       // 1: use external logging, 0: do not. default is 0\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Set IRMP_PROTOCOL_NAMES to 1 if want to access protocol names (for logging etc), costs ~300 bytes RAM!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_PROTOCOL_NAMES)\n#  define IRMP_PROTOCOL_NAMES                   0                       // 1: access protocol names, 0: do not. default is 0\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Use Callbacks to indicate input signal\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_USE_CALLBACK)\n#  define IRMP_USE_CALLBACK                     0                       // 1: use callbacks. 0: do not. default is 0\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Call the user-provided irmp_idle() function when IRMP is idle.\n * Can be used to disable the timer irq and enter a sleep mode to save power\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_USE_IDLE_CALL)\n#  define IRMP_USE_IDLE_CALL                    0                       // 1: use idle calls. 0: do not. default is 0\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Use Callback if complete data was received\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRMP_USE_COMPLETE_CALLBACK)\n#  define IRMP_USE_COMPLETE_CALLBACK           0                        // 1: use callback. 0: do not. default is 0\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Autodetect repeat rate\n * For precise detection of key repetition (and key release)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#ifndef IRMP_AUTODETECT_REPEATRATE\n#  define IRMP_AUTODETECT_REPEATRATE            0                       // 1: autodetect repeat rate. 0: do not. default is 0\n#  define JITTER_COMPENSATION                   3                       // percent, increase for remote controls with big jitter\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Use ChibiOS Events to signal that valid IR data was received\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined(_CHIBIOS_RT_) || defined(_CHIBIOS_NIL_)\n\n#  if !defined(IRMP_USE_EVENT)\n#    define IRMP_USE_EVENT                      0                       // 1: use event. 0: do not. default is 0\n#  endif\n\n#  if IRMP_USE_EVENT == 1 && !defined(IRMP_EVENT_BIT)\n#    define IRMP_EVENT_BIT                      1                       // event flag or bit to send\n#  endif\n#  if IRMP_USE_EVENT == 1 && !defined(IRMP_EVENT_THREAD_PTR)\n#    define IRMP_EVENT_THREAD_PTR               ir_receive_thread_p     // pointer to the thread to send the event to\nextern thread_t *IRMP_EVENT_THREAD_PTR;                                 // the pointer must be defined and initialized elsewhere\n#  endif\n\n#endif // _CHIBIOS_RT_ || _CHIBIOS_NIL_\n\n#endif // _IRMPCONFIG_STAGE2_H_\n"
  },
  {
    "path": "src/irmpprotocols.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpprotocols.h - irmp protocols\n *\n * DO NOT INCLUDE THIS FILE, WILL BE INCLUDED BY IRMP.H or IRSND.H!\n *\n * Copyright (c) 2013-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMP_PROTOCOLS_H_\n#define _IRMP_PROTOCOLS_H_\n\n#if !defined(_IRMP_H_) && !defined(_IRSND_H_)\n#  error please include only irmp.h or irsnd.h, not irmpprotocols.h\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * IR protocols:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP_UNKNOWN_PROTOCOL                    0              // unknown protocol\n#define IRMP_SIRCS_PROTOCOL                      1              // Sony\n#define IRMP_NEC_PROTOCOL                        2              // NEC with 32 bits, 16 address + 8 (+ 8 generated) command bits, Pioneer, JVC, Toshiba, NoName etc.\n#define IRMP_SAMSUNG_PROTOCOL                    3              // Samsung\n#define IRMP_MATSUSHITA_PROTOCOL                 4              // Matsushita\n#define IRMP_KASEIKYO_PROTOCOL                   5              // Kaseikyo (Panasonic etc)\n#define IRMP_RECS80_PROTOCOL                     6              // Philips, Thomson, Nordmende, Telefunken, Saba\n#define IRMP_RC5_PROTOCOL                        7              // Philips etc\n#define IRMP_DENON_PROTOCOL                      8              // Denon, Sharp\n#define IRMP_RC6_PROTOCOL                        9              // Philips etc\n#define IRMP_SAMSUNG32_PROTOCOL                 10              // Samsung32: no sync pulse at bit 16, length 32 instead of 37\n#define IRMP_APPLE_PROTOCOL                     11              // Apple, very similar to NEC\n#define IRMP_RECS80EXT_PROTOCOL                 12              // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba\n#define IRMP_NUBERT_PROTOCOL                    13              // Nubert\n#define IRMP_BANG_OLUFSEN_PROTOCOL              14              // Bang & Olufsen\n#define IRMP_GRUNDIG_PROTOCOL                   15              // Grundig\n#define IRMP_NOKIA_PROTOCOL                     16              // Nokia\n#define IRMP_SIEMENS_PROTOCOL                   17              // Siemens, e.g. Gigaset\n#define IRMP_FDC_PROTOCOL                       18              // FDC keyboard\n#define IRMP_RCCAR_PROTOCOL                     19              // RC Car\n#define IRMP_JVC_PROTOCOL                       20              // JVC (NEC with 16 bits)\n#define IRMP_RC6A_PROTOCOL                      21              // RC6A, e.g. Kathrein, XBOX\n#define IRMP_NIKON_PROTOCOL                     22              // Nikon\n#define IRMP_RUWIDO_PROTOCOL                    23              // Ruwido, e.g. T-Home Mediareceiver\n#define IRMP_IR60_PROTOCOL                      24              // IR60 (SDA2008)\n#define IRMP_KATHREIN_PROTOCOL                  25              // Kathrein\n#define IRMP_NETBOX_PROTOCOL                    26              // Netbox keyboard (bitserial)\n#define IRMP_NEC16_PROTOCOL                     27              // NEC with 16 bits (incl. sync)\n#define IRMP_NEC42_PROTOCOL                     28              // NEC with 42 bits\n#define IRMP_LEGO_PROTOCOL                      29              // LEGO Power Functions RC\n#define IRMP_THOMSON_PROTOCOL                   30              // Thomson\n#define IRMP_BOSE_PROTOCOL                      31              // BOSE\n#define IRMP_A1TVBOX_PROTOCOL                   32              // A1 TV Box\n#define IRMP_ORTEK_PROTOCOL                     33              // ORTEK - Hama\n#define IRMP_TELEFUNKEN_PROTOCOL                34              // Telefunken (1560)\n#define IRMP_ROOMBA_PROTOCOL                    35              // iRobot Roomba vacuum cleaner\n#define IRMP_RCMM32_PROTOCOL                    36              // Fujitsu-Siemens (Activy remote control)\n#define IRMP_RCMM24_PROTOCOL                    37              // Fujitsu-Siemens (Activy keyboard)\n#define IRMP_RCMM12_PROTOCOL                    38              // Fujitsu-Siemens (Activy keyboard)\n#define IRMP_SPEAKER_PROTOCOL                   39              // Another loudspeaker protocol, similar to Nubert\n#define IRMP_LGAIR_PROTOCOL                     40              // LG air conditioner\n#define IRMP_SAMSUNG48_PROTOCOL                 41              // air conditioner with SAMSUNG protocol (48 bits)\n#define IRMP_MERLIN_PROTOCOL                    42              // Merlin (Pollin 620 185)\n#define IRMP_PENTAX_PROTOCOL                    43              // Pentax camera\n#define IRMP_FAN_PROTOCOL                       44              // FAN (ventilator), very similar to NUBERT, but last bit is data bit instead of stop bit\n#define IRMP_S100_PROTOCOL                      45              // very similar to RC5, but 14 instead of 13 data bits\n#define IRMP_ACP24_PROTOCOL                     46              // Stiebel Eltron ACP24 air conditioner\n#define IRMP_TECHNICS_PROTOCOL                  47              // Technics, similar to Matsushita, but 22 instead of 24 bits\n#define IRMP_PANASONIC_PROTOCOL                 48              // Panasonic (Beamer), start bits similar to KASEIKYO\n#define IRMP_MITSU_HEAVY_PROTOCOL               49              // Mitsubishi-Heavy Aircondition, similar timing as Panasonic beamer\n#define IRMP_VINCENT_PROTOCOL                   50              // Vincent\n#define IRMP_SAMSUNGAH_PROTOCOL                 51              // SAMSUNG AH\n#define IRMP_IRMP16_PROTOCOL                    52              // IRMP specific protocol for data transfer, e.g. between two microcontrollers via IR\n#define IRMP_GREE_PROTOCOL                      53              // Gree climate\n#define IRMP_RCII_PROTOCOL                      54              // RC II Infra Red Remote Control Protocol for FM8\n#define IRMP_METZ_PROTOCOL                      55              // METZ\n#define IRMP_ONKYO_PROTOCOL                     56              // Like NEC but with 16 address + 16 command bits\n\n#define RF_GEN24_PROTOCOL                       57              // RF Generic, 24 Bits (Pollin 550666, EAN 4049702006022 and many other similar RF remote controls))\n#define RF_X10_PROTOCOL                         58              // RF PC X10 Remote Control (Medion, Pollin 721815)\n#define RF_MEDION_PROTOCOL                      59              // RF PC Medion Remote Control (Medion)\n#define IRMP_MELINERA_PROTOCOL                  60\n#define IRMP_RC6A20_PROTOCOL                    61              // RC6A20, e.g. Sky+\n#define IRMP_RC6A28_PROTOCOL                    62              // RC6A28, e.g. Sky Q (Sky+ Pro)\n\n#define IRMP_N_PROTOCOLS                        62              // number of supported protocols\n\n#if defined(UNIX_OR_WINDOWS) || IRMP_PROTOCOL_NAMES == 1 || IRSND_PROTOCOL_NAMES == 1\nextern const char proto_unknown[]       PROGMEM;\nextern const char proto_sircs[]         PROGMEM;\nextern const char proto_nec[]           PROGMEM;\nextern const char proto_samsung[]       PROGMEM;\nextern const char proto_matsushita[]    PROGMEM;\nextern const char proto_kaseikyo[]      PROGMEM;\nextern const char proto_recs80[]        PROGMEM;\nextern const char proto_rc5[]           PROGMEM;\nextern const char proto_denon[]         PROGMEM;\nextern const char proto_rc6[]           PROGMEM;\nextern const char proto_samsung32[]     PROGMEM;\nextern const char proto_apple[]         PROGMEM;\nextern const char proto_recs80ext[]     PROGMEM;\nextern const char proto_nubert[]        PROGMEM;\nextern const char proto_bang_olufsen[]  PROGMEM;\nextern const char proto_grundig[]       PROGMEM;\nextern const char proto_nokia[]         PROGMEM;\nextern const char proto_siemens[]       PROGMEM;\nextern const char proto_fdc[]           PROGMEM;\nextern const char proto_rccar[]         PROGMEM;\nextern const char proto_jvc[]           PROGMEM;\nextern const char proto_rc6a[]          PROGMEM;\nextern const char proto_nikon[]         PROGMEM;\nextern const char proto_ruwido[]        PROGMEM;\nextern const char proto_ir60[]          PROGMEM;\nextern const char proto_kathrein[]      PROGMEM;\nextern const char proto_netbox[]        PROGMEM;\nextern const char proto_nec16[]         PROGMEM;\nextern const char proto_nec42[]         PROGMEM;\nextern const char proto_lego[]          PROGMEM;\nextern const char proto_thomson[]       PROGMEM;\nextern const char proto_bose[]          PROGMEM;\nextern const char proto_a1tvbox[]       PROGMEM;\nextern const char proto_ortek[]         PROGMEM;\nextern const char proto_telefunken[]    PROGMEM;\nextern const char proto_roomba[]        PROGMEM;\nextern const char proto_rcmm32[]        PROGMEM;\nextern const char proto_rcmm24[]        PROGMEM;\nextern const char proto_rcmm12[]        PROGMEM;\nextern const char proto_speaker[]       PROGMEM;\nextern const char proto_lgair[]         PROGMEM;\nextern const char proto_samsung48[]     PROGMEM;\nextern const char proto_merlin[]        PROGMEM;\nextern const char proto_pentax[]        PROGMEM;\nextern const char proto_fan[]           PROGMEM;\nextern const char proto_s100[]          PROGMEM;\nextern const char proto_acp24[]         PROGMEM;\nextern const char proto_technics[]      PROGMEM;\nextern const char proto_panasonic[]     PROGMEM;\nextern const char proto_mitsu_heavy[]   PROGMEM;\nextern const char proto_vincent[]       PROGMEM;\nextern const char proto_samsungah[]     PROGMEM;\nextern const char proto_irmp16[]        PROGMEM;\nextern const char proto_gree[]          PROGMEM;\nextern const char proto_rcii[]          PROGMEM;\nextern const char proto_metz[]          PROGMEM;\nextern const char proto_onkyo[]         PROGMEM;\n\nextern const char proto_rf_gen24[]      PROGMEM;\nextern const char proto_rf_x10[]        PROGMEM;\nextern const char proto_rf_medion[]     PROGMEM;\nextern const char proto_melinera[]      PROGMEM;\nextern const char proto_rc6a20[]        PROGMEM;\nextern const char proto_rc6a28[]        PROGMEM;\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * timing constants:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n// fm 22.09.2011: may not be more than 16000L, otherwise some JVC codes will not be accepted\n#define IRMP_TIMEOUT_TIME                       15500.0e-6                  // timeout after 15.5 ms darkness\n#define IRMP_TIMEOUT_TIME_MS                    15500L                      // timeout after 15.5 ms darkness\n\n#if IRMP_SUPPORT_NIKON_PROTOCOL == 1\n#  define IRMP_TIMEOUT_NIKON_TIME               29500.0e-6                  // 2nd timeout after 29.5 ms darkness (only for NIKON!)\n#  define IRMP_TIMEOUT_NIKON_TIME_MS            29500L                      // 2nd timeout after 29.5 ms darkness\ntypedef uint16_t    PAUSE_LEN;\n#  define IRMP_TIMEOUT_NIKON_LEN                (PAUSE_LEN)(F_INTERRUPTS * IRMP_TIMEOUT_NIKON_TIME + 0.5)\n#else\n#  if (F_INTERRUPTS * IRMP_TIMEOUT_TIME_MS) / 1000000 >= 254\ntypedef uint16_t    PAUSE_LEN;\n#  else\ntypedef uint8_t     PAUSE_LEN;\n#  endif\n#endif\n\n#define IRMP_TIMEOUT_LEN                        (PAUSE_LEN)(F_INTERRUPTS * IRMP_TIMEOUT_TIME + 0.5)\n\n#define IRMP_KEY_RELEASE_TIME                   25.0e-3                  // key release timeout detection after 25.0 ms darkness\n#define IRMP_KEY_RELEASE_LEN                    (uint16_t)(F_INTERRUPTS * IRMP_KEY_RELEASE_TIME + 0.5)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * flags of struct IRMP_PARAMETER:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP_PARAM_FLAG_IS_MANCHESTER           0x01\n#define IRMP_PARAM_FLAG_1ST_PULSE_IS_1          0x02\n#define IRMP_PARAM_FLAG_IS_SERIAL               0x04\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * SIRCS:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define SIRCS_START_BIT_PULSE_TIME              2400.0e-6                       // 2400 usec pulse\n#define SIRCS_START_BIT_PAUSE_TIME               600.0e-6                       //  600 usec pause\n#define SIRCS_1_PULSE_TIME                      1200.0e-6                       // 1200 usec pulse\n#define SIRCS_0_PULSE_TIME                       600.0e-6                       //  600 usec pulse\n#define SIRCS_PAUSE_TIME                         600.0e-6                       //  600 usec pause\n#define SIRCS_FRAMES                            3                               // SIRCS sends each frame 3 times\n#define SIRCS_AUTO_REPETITION_PAUSE_TIME          25.0e-3                       // auto repetition after 25ms\n#define SIRCS_FRAME_REPEAT_PAUSE_TIME             25.0e-3                       // frame repeat after 25ms\n#define SIRCS_ADDRESS_OFFSET                    15                              // skip 15 bits\n#define SIRCS_ADDRESS_LEN                       5                               // read up to 5 address bits\n#define SIRCS_COMMAND_OFFSET                    0                               // skip 0 bits\n#define SIRCS_COMMAND_LEN                       15                              // read 12-15 command bits\n#define SIRCS_MINIMUM_DATA_LEN                  12                              // minimum data length\n#define SIRCS_COMPLETE_DATA_LEN                 20                              // complete length - may be up to 20\n#define SIRCS_STOP_BIT                          0                               // has no stop bit\n#define SIRCS_LSB                               1                               // LSB...MSB\n#define SIRCS_FLAGS                             0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * NEC & NEC42 & NEC16 & LGAIR & MELINERA:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define NEC_START_BIT_PULSE_TIME                9000.0e-6                       // 9000 usec pulse\n#define NEC_START_BIT_PAUSE_TIME                4500.0e-6                       // 4500 usec pause\n#define NEC_REPEAT_START_BIT_PAUSE_TIME         2250.0e-6                       // 2250 usec pause\n#define NEC_PULSE_TIME                           560.0e-6                       //  560 usec pulse\n#define NEC_1_PAUSE_TIME                        1690.0e-6                       // 1690 usec pause\n#define NEC_0_PAUSE_TIME                         560.0e-6                       //  560 usec pause\n#define NEC_FRAME_REPEAT_PAUSE_TIME               40.0e-3                       // frame repeat after 40ms\n#define NEC_ADDRESS_OFFSET                       0                              // skip 0 bits\n#define NEC_ADDRESS_LEN                         16                              // read 16 address bits\n#define NEC_COMMAND_OFFSET                      16                              // skip 16 bits (8 address + 8 /address)\n#define NEC_COMMAND_LEN                         16                              // read 16 bits (8 command + 8 /command)\n#define NEC_COMPLETE_DATA_LEN                   32                              // complete length\n#define NEC_STOP_BIT                            1                               // has stop bit\n#define NEC_LSB                                 1                               // LSB...MSB\n#define NEC_FLAGS                               0                               // flags\n\n#define NEC42_ADDRESS_OFFSET                    0                               // skip 0 bits\n#define NEC42_ADDRESS_LEN                      13                               // read 13 address bits\n#define NEC42_COMMAND_OFFSET                   26                               // skip 26 bits (2 x 13 address bits)\n#define NEC42_COMMAND_LEN                       8                               // read 8 command bits\n#define NEC42_COMPLETE_DATA_LEN                42                               // complete length (2 x 13 + 2 x 8)\n\n#define LGAIR_ADDRESS_OFFSET                    0                               // skip 0 bits\n#define LGAIR_ADDRESS_LEN                       8                               // read 8 address bits\n#define LGAIR_COMMAND_OFFSET                    8                               // skip 8 bits (8 address)\n#define LGAIR_COMMAND_LEN                      16                               // read 16 bits (16 command)\n#define LGAIR_COMPLETE_DATA_LEN                28                               // complete length (8 address + 16 command + 4 checksum)\n\n#define NEC16_ADDRESS_OFFSET                    0                               // skip 0 bits\n#define NEC16_ADDRESS_LEN                       8                               // read 8 address bits\n#define NEC16_COMMAND_OFFSET                    8                               // skip 8 bits (8 address)\n#define NEC16_COMMAND_LEN                       8                               // read 8 bits (8 command)\n#define NEC16_COMPLETE_DATA_LEN                 16                              // complete length\n\n#define MELINERA_START_BIT_PULSE_TIME           8800.0e-6                       // 8800 usec pulse\n#define MELINERA_START_BIT_PAUSE_TIME           4100.0e-6                       // 4100 usec pause\n#define MELINERA_0_PULSE_TIME                    440.0e-6                       //  430 usec pause\n#define MELINERA_0_PAUSE_TIME                    590.0e-6                       //  600 usec pause\n#define MELINERA_1_PULSE_TIME                    970.0e-6                       //  910 usec pause\n#define MELINERA_1_PAUSE_TIME                   1140.0e-6                       // 1160 usec pause\n#define MELINERA_FRAME_REPEAT_PAUSE_TIME          40.0e-3                       // frame repeat after 40ms\n#define MELINERA_ADDRESS_OFFSET                 0                               // skip 0 bits\n#define MELINERA_ADDRESS_LEN                    0                               // read 0 address bits\n#define MELINERA_COMMAND_OFFSET                 0                               // skip 0 bits (0 address)\n#define MELINERA_COMMAND_LEN                    8                               // read 8 bits (8 command)\n#define MELINERA_COMPLETE_DATA_LEN              8                               // complete length\n#define MELINERA_STOP_BIT                       1                               // has stop bit\n#define MELINERA_LSB                            0                               // MSB\n#define MELINERA_FLAGS                          0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * SAMSUNG & SAMSUNG32 & SAMSUNG48:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define SAMSUNG_START_BIT_PULSE_TIME            4500.0e-6                       // 4500 usec pulse\n#define SAMSUNG_START_BIT_PAUSE_TIME            4500.0e-6                       // 4500 usec pause\n#define SAMSUNG_PULSE_TIME                       550.0e-6                       //  550 usec pulse\n#define SAMSUNG_1_PAUSE_TIME                    1500.0e-6                       // 1550 usec pause\n#define SAMSUNG_0_PAUSE_TIME                     500.0e-6                       //  500 usec pause\n\n#define SAMSUNG_FRAME_REPEAT_PAUSE_TIME           25.0e-3                       // frame repeat after 25ms\n#define SAMSUNG_ADDRESS_OFFSET                   0                              // skip 0 bits\n#define SAMSUNG_ADDRESS_LEN                     16                              // read 16 address bits\n#define SAMSUNG_ID_OFFSET                       17                              // skip 16 + 1 sync bit\n#define SAMSUNG_ID_LEN                          4                               // read 4 id bits\n#define SAMSUNG_COMMAND_OFFSET                  21                              // skip 16 + 1 sync + 4 data bits\n#define SAMSUNG_COMMAND_LEN                     16                              // read 16 command bits\n#define SAMSUNG_COMPLETE_DATA_LEN               37                              // complete length\n#define SAMSUNG_STOP_BIT                        1                               // has stop bit\n#define SAMSUNG_LSB                             1                               // LSB...MSB?\n#define SAMSUNG_FLAGS                           0                               // flags\n\n#define SAMSUNG32_COMMAND_OFFSET                16                              // skip 16 bits\n#define SAMSUNG32_COMMAND_LEN                   16                              // read 16 command bits\n#define SAMSUNG32_COMPLETE_DATA_LEN             32                              // complete length\n#define SAMSUNG32_FRAMES                        1                               // SAMSUNG32 sends one frame\n#define SAMSUNG32_AUTO_REPETITION_PAUSE_TIME    47.0e-3                         // repetition after 47 ms\n#define SAMSUNG32_FRAME_REPEAT_PAUSE_TIME       47.0e-3                         // frame repeat after 47ms\n\n#define SAMSUNG48_COMMAND_OFFSET                16                              // skip 16 bits\n#define SAMSUNG48_COMMAND_LEN                   32                              // read 32 command bits\n#define SAMSUNG48_COMPLETE_DATA_LEN             48                              // complete length\n#define SAMSUNG48_FRAMES                        2                               // SAMSUNG48 sends each frame 2 times\n#define SAMSUNG48_AUTO_REPETITION_PAUSE_TIME    5.0e-3                          // repetition after 5 ms\n#define SAMSUNG48_FRAME_REPEAT_PAUSE_TIME       47.0e-3                         // frame repeat after 47ms\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * SAMSUNGAH:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define SAMSUNGAH_START_BIT_PULSE_TIME          2500.0e-6                       // 2500 usec pulse\n#define SAMSUNGAH_START_BIT_PAUSE_TIME          1900.0e-6                       // 1900 usec pause\n#define SAMSUNGAH_PULSE_TIME                     450.0e-6                       //  450 usec pulse\n#define SAMSUNGAH_1_PAUSE_TIME                  1100.0e-6                       // 1100 usec pause\n#define SAMSUNGAH_0_PAUSE_TIME                   450.0e-6                       //  450 usec pause\n#define SAMSUNGAH_FRAME_REPEAT_PAUSE_TIME         40.0e-3                       // frame repeat after 40ms\n#define SAMSUNGAH_ADDRESS_OFFSET                 0                              // skip 0 bits\n#define SAMSUNGAH_ADDRESS_LEN                   16                              // read 16 address bits, ignore 17..31\n#define SAMSUNGAH_COMMAND_OFFSET                32                              // skip 32 bits\n#define SAMSUNGAH_COMMAND_LEN                   16                              // read 32 bits\n#define SAMSUNGAH_COMPLETE_DATA_LEN             48                              // complete length\n#define SAMSUNGAH_STOP_BIT                      1                               // has stop bit\n#define SAMSUNGAH_LSB                           1                               // LSB...MSB?\n#define SAMSUNGAH_FLAGS                         0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * MATSUSHITA:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define MATSUSHITA_START_BIT_PULSE_TIME         3488.0e-6                       // 3488 usec pulse\n#define MATSUSHITA_START_BIT_PAUSE_TIME         3488.0e-6                       // 3488 usec pause\n#define MATSUSHITA_PULSE_TIME                    872.0e-6                       //  872 usec pulse\n#define MATSUSHITA_1_PAUSE_TIME                 2616.0e-6                       // 2616 usec pause\n#define MATSUSHITA_0_PAUSE_TIME                  872.0e-6                       //  872 usec pause\n#define MATSUSHITA_FRAME_REPEAT_PAUSE_TIME        40.0e-3                       // frame repeat after 40ms\n#define MATSUSHITA_ADDRESS_OFFSET               12                              // skip 12 bits\n#define MATSUSHITA_ADDRESS_LEN                  12                              // read 12 address bits\n#define MATSUSHITA_COMMAND_OFFSET               0                               // skip 0 bits\n#define MATSUSHITA_COMMAND_LEN                  12                              // read 12 bits (6 custom + 6 command)\n#define MATSUSHITA_COMPLETE_DATA_LEN            24                              // complete length\n#define MATSUSHITA_STOP_BIT                     1                               // has stop bit\n#define MATSUSHITA_LSB                          1                               // LSB...MSB?\n#define MATSUSHITA_FLAGS                        0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * TECHNICS: same timings as MATSUSHITA\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define TECHNICS_ADDRESS_LEN                    0                               // read 0 address bits\n#define TECHNICS_COMMAND_LEN                    11                              // read 11 bits\n#define TECHNICS_COMPLETE_DATA_LEN              22                              // complete length\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * KASEIKYO: 48 bit\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define KASEIKYO_START_BIT_PULSE_TIME           3456.0e-6                       // 3380 usec pulse\n#define KASEIKYO_START_BIT_PAUSE_TIME           1728.0e-6                       // 1690 usec pause\n#define KASEIKYO_PULSE_TIME                      432.0e-6                       //  525 usec pulse\n#define KASEIKYO_1_PAUSE_TIME                   1296.0e-6                       //  525 usec pause\n#define KASEIKYO_0_PAUSE_TIME                    432.0e-6                       // 1690 usec pause\n#define KASEIKYO_AUTO_REPETITION_PAUSE_TIME       74.0e-3                       // repetition after 74 ms\n#define KASEIKYO_FRAME_REPEAT_PAUSE_TIME          74.0e-3                       // frame repeat after 74 ms\n#define KASEIKYO_ADDRESS_OFFSET                  0                              // skip 0 bits\n#define KASEIKYO_ADDRESS_LEN                    16                              // read 16 address / manufacturer bits\n#define KASEIKYO_COMMAND_OFFSET                 28                              // skip 28 bits (16 manufacturer & 4 parity & 8 genre)\n#define KASEIKYO_COMMAND_LEN                    12                              // read 12 command bits (10 real command & 2 id)\n#define KASEIKYO_COMPLETE_DATA_LEN              48                              // complete length\n#define KASEIKYO_STOP_BIT                       1                               // has stop bit\n#define KASEIKYO_LSB                            1                               // LSB...MSB?\n#define KASEIKYO_FRAMES                         1                               // KASEIKYO sends 1 frame\n#define KASEIKYO_FLAGS                          0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * PANASONIC (Beamer), start bit timings similar to KASEIKYO   56 bit\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define PANASONIC_START_BIT_PULSE_TIME           3600.0e-6                      // 3600 usec pulse\n#define PANASONIC_START_BIT_PAUSE_TIME           1600.0e-6                      // 1690 usec pause\n#define PANASONIC_PULSE_TIME                      432.0e-6                      //  565 usec pulse\n#define PANASONIC_1_PAUSE_TIME                   1296.0e-6                      // 1140 usec pause\n#define PANASONIC_0_PAUSE_TIME                    432.0e-6                      //  316 usec pause\n#define PANASONIC_AUTO_REPETITION_PAUSE_TIME       40.0e-3                      // repetition after 40 ms?\n#define PANASONIC_FRAME_REPEAT_PAUSE_TIME          40.0e-3                      // frame repeat after 40 ms\n#define PANASONIC_ADDRESS_OFFSET                 24                             // skip 24 bits: 010000000000010000000001\n#define PANASONIC_ADDRESS_LEN                    16                             // read 16 address bits\n#define PANASONIC_COMMAND_OFFSET                 40                             // skip 40 bits\n#define PANASONIC_COMMAND_LEN                    16                             // read 16 command bits\n#define PANASONIC_COMPLETE_DATA_LEN              56                             // complete length\n#define PANASONIC_STOP_BIT                       1                              // has stop bit\n#define PANASONIC_LSB                            1                              // LSB...MSB?\n#define PANASONIC_FRAMES                         1                              // PANASONIC sends 1 frame\n#define PANASONIC_FLAGS                          0                              // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * MITSUBISHI-Heavy Aircondition, timings similar to PANASONIC beamer  88 bit\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define MITSU_HEAVY_START_BIT_PULSE_TIME          3200.0e-6                     // 3600 usec pulse\n#define MITSU_HEAVY_START_BIT_PAUSE_TIME          1560.0e-6                     // 1690 usec pause\n#define MITSU_HEAVY_PULSE_TIME                     400.0e-6                     //  565 usec pulse\n#define MITSU_HEAVY_1_PAUSE_TIME                  1200.0e-6                     // 1140 usec pause\n#define MITSU_HEAVY_0_PAUSE_TIME                   430.0e-6                     //  316 usec pause\n#define MITSU_HEAVY_FRAME_REPEAT_PAUSE_TIME         40.0e-3                     // frame repeat after 40 ms\n#define MITSU_HEAVY_ADDRESS_OFFSET                 40                           // skip 24 bits: 010000000000010000000001\n#define MITSU_HEAVY_ADDRESS_LEN                    16                           // read 16 address bits\n#define MITSU_HEAVY_COMMAND_OFFSET                 56                           // skip 40 bits\n#define MITSU_HEAVY_COMMAND_LEN                    16                           // read 16 command bits\n#define MITSU_HEAVY_COMPLETE_DATA_LEN              88                           // complete length\n#define MITSU_HEAVY_STOP_BIT                       1                            // has stop bit\n#define MITSU_HEAVY_LSB                            0                            // LSB...MSB?\n#define MITSU_HEAVY_FRAMES                         1                            // PANASONIC sends 1 frame\n#define MITSU_HEAVY_FLAGS                          0                            // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * VINCENT\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define VINCENT_START_BIT_PULSE_TIME            2500.0e-6                       // 2500 usec pulse\n#define VINCENT_START_BIT_PAUSE_TIME            4600.0e-6                       // 4600 usec pause\n#define VINCENT_PULSE_TIME                       550.0e-6                       //  550 usec pulse\n#define VINCENT_1_PAUSE_TIME                    1540.0e-6                       // 1540 usec pause\n#define VINCENT_0_PAUSE_TIME                     550.0e-6                       //  550 usec pause\n#define VINCENT_FRAME_REPEAT_PAUSE_TIME           40.0e-3                       // frame repeat after 40 ms ?\n#define VINCENT_ADDRESS_OFFSET                     0                            // skip 0 bits\n#define VINCENT_ADDRESS_LEN                       16                            // read 16 address bits\n#define VINCENT_COMMAND_OFFSET                    16                            // skip 16 bits\n#define VINCENT_COMMAND_LEN                       16                            // read 16 command bits\n#define VINCENT_COMPLETE_DATA_LEN                 32                            // complete length\n#define VINCENT_STOP_BIT                           1                            // has stop bit\n#define VINCENT_LSB                                0                            // LSB...MSB?\n#define VINCENT_FRAMES                             1                            // VINCENT sends 1 frame\n#define VINCENT_FLAGS                              0                            // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RECS80:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RECS80_START_BIT_PULSE_TIME              158.0e-6                       //  158 usec pulse\n#define RECS80_START_BIT_PAUSE_TIME             7432.0e-6                       // 7432 usec pause\n#define RECS80_PULSE_TIME                        158.0e-6                       //  158 usec pulse\n#define RECS80_1_PAUSE_TIME                     7432.0e-6                       // 7432 usec pause\n#define RECS80_0_PAUSE_TIME                     4902.0e-6                       // 4902 usec pause\n#define RECS80_FRAME_REPEAT_PAUSE_TIME            45.0e-3                       // frame repeat after 45ms\n#define RECS80_ADDRESS_OFFSET                   1                               // skip 1 bit (toggle bit)\n#define RECS80_ADDRESS_LEN                      3                               // read 3 address bits\n#define RECS80_COMMAND_OFFSET                   4                               // skip 4 bits (1 toggle + 3 address)\n#define RECS80_COMMAND_LEN                      6                               // read 6 command bits\n#define RECS80_COMPLETE_DATA_LEN                10                              // complete length\n#define RECS80_STOP_BIT                         1                               // has stop bit\n#define RECS80_LSB                              0                               // MSB...LSB\n#define RECS80_FLAGS                            0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RC5:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RC5_BIT_TIME                             889.0e-6                       // 889 usec pulse/pause\n#define RC5_FRAME_REPEAT_PAUSE_TIME               88.9e-3                       // frame repeat after 88.9ms\n\n#define RC5_ADDRESS_OFFSET                      1                               // skip 1 bit (2nd start)\n#define RC5_ADDRESS_LEN                         6                               // read 1 toggle bit (for key repetition detection) + 5 address bits\n#define RC5_COMMAND_OFFSET                      7                               // skip 5 bits (2nd start + 1 toggle + 5 address)\n#define RC5_COMMAND_LEN                         6                               // read 6 command bits\n#define RC5_COMPLETE_DATA_LEN                   13                              // complete length\n#define RC5_STOP_BIT                            0                               // has no stop bit\n#define RC5_LSB                                 0                               // MSB...LSB\n#define RC5_FLAGS                               IRMP_PARAM_FLAG_IS_MANCHESTER   // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RCII:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RCII_START_BIT_PULSE_TIME                512.0e-6                       //  512 usec pulse\n#define RCII_START_BIT_PAUSE_TIME               2560.0e-6                       // 2560 usec pause\n#define RCII_START_BIT2_PULSE_TIME              1024.0e-6                       // 1024 usec pulse\n\n#define RCII_BIT_TIME                            512.0e-6                       // 512 usec pulse/pause\n#define RCII_FRAME_REPEAT_PAUSE_TIME             117.76e-3                      // frame repeat after 117.76ms\n\n#define RCII_ADDRESS_OFFSET                     0                               // skip 1 bit (2nd start)\n#define RCII_ADDRESS_LEN                        0                               // no address\n#define RCII_COMMAND_OFFSET                     0                               // command offset is 0\n#define RCII_COMMAND_LEN                        10                              // read 1 + 9 command bits\n#define RCII_COMPLETE_DATA_LEN                  10                              // complete length\n#define RCII_STOP_BIT                           0                               // has no stop bit\n#define RCII_LSB                                0                               // MSB...LSB\n#define RCII_FLAGS                              (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1)  // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * S100: very similar to RC5, but 14 insted of 13 bits\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define S100_BIT_TIME                             889.0e-6                       // 889 usec pulse/pause\n#define S100_FRAME_REPEAT_PAUSE_TIME               88.9e-3                       // frame repeat after 88.9ms\n\n#define S100_ADDRESS_OFFSET                      1                               // skip 1 bit (2nd start)\n#define S100_ADDRESS_LEN                         6                               // read 1 toggle bit (for key repetition detection) + 5 address bits\n#define S100_COMMAND_OFFSET                      7                               // skip 5 bits (2nd start + 1 toggle + 5 address)\n#define S100_COMMAND_LEN                         7                               // read 7 command bits\n#define S100_COMPLETE_DATA_LEN                   14                              // complete length\n#define S100_STOP_BIT                            0                               // has no stop bit\n#define S100_LSB                                 0                               // MSB...LSB\n#define S100_FLAGS                               IRMP_PARAM_FLAG_IS_MANCHESTER   // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * DENON:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define DENON_PULSE_TIME                         310.0e-6                       //  310 usec pulse in practice,  275 in theory\n#define DENON_1_PAUSE_TIME                      1780.0e-6                       // 1780 usec pause in practice, 1900 in theory\n#define DENON_0_PAUSE_TIME                       745.0e-6                       //  745 usec pause in practice,  775 in theory\n#define DENON_FRAMES                            2                               // DENON sends each frame 2 times\n#define DENON_AUTO_REPETITION_PAUSE_TIME          45.0e-3                       // inverted repetition after 45ms\n#define DENON_FRAME_REPEAT_PAUSE_TIME             45.0e-3                       // frame repeat after 45ms\n#define DENON_ADDRESS_OFFSET                    0                               // skip 0 bits\n#define DENON_ADDRESS_LEN                       5                               // read 5 address bits\n#define DENON_COMMAND_OFFSET                    5                               // skip 5\n#define DENON_COMMAND_LEN                       10                              // read 10 command bits\n#define DENON_COMPLETE_DATA_LEN                 15                              // complete length\n#define DENON_STOP_BIT                          1                               // has stop bit\n#define DENON_LSB                               0                               // MSB...LSB\n#define DENON_FLAGS                             0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RC6:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RC6_START_BIT_PULSE_TIME                2666.0e-6                       // 2.666 msec pulse\n#define RC6_START_BIT_PAUSE_TIME                 889.0e-6                       // 889 usec pause\n#define RC6_TOGGLE_BIT_TIME                      889.0e-6                       // 889 msec pulse/pause\n#define RC6_BIT_TIME                             444.0e-6                       // 444 usec pulse/pause\n#define RC6_BIT_2_TIME                           889.0e-6                       // 889 usec pulse/pause\n#define RC6_BIT_3_TIME                          1333.0e-6                       // 1333 usec pulse/pause\n#define RC6_FRAME_REPEAT_PAUSE_TIME               45.0e-3                       // frame repeat after 45ms\n#define RC6_ADDRESS_OFFSET                      5                               // skip \"1\" + 3 mode bits + 1 toggle bit\n#define RC6_ADDRESS_LEN                         8                               // read 8 address bits\n#define RC6_COMMAND_OFFSET                      13                              // skip 12 bits (\"1\" + 3 mode + 1 toggle + 8 address)\n#define RC6_COMMAND_LEN                         8                               // read 8 command bits\n#define RC6_COMPLETE_DATA_LEN_SHORT             21                              // complete length\n#define RC6_COMPLETE_DATA_LEN_20                25                              // complete length\n#define RC6_COMPLETE_DATA_LEN_28                33                              // complete length\n#define RC6_COMPLETE_DATA_LEN_LONG              36                              // complete length\n#define RC6_STOP_BIT                            0                               // has no stop bit\n#define RC6_LSB                                 0                               // MSB...LSB\n#define RC6_FLAGS                               (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1)   // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RECS80EXT:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RECS80EXT_START_BIT_PULSE_TIME           158.0e-6                       //  158 usec pulse\n#define RECS80EXT_START_BIT_PAUSE_TIME          3637.0e-6                       // 3637 usec pause\n#define RECS80EXT_PULSE_TIME                     158.0e-6                       //  158 usec pulse\n#define RECS80EXT_1_PAUSE_TIME                  7432.0e-6                       // 7432 usec pause\n#define RECS80EXT_0_PAUSE_TIME                  4902.0e-6                       // 4902 usec pause\n#define RECS80EXT_FRAME_REPEAT_PAUSE_TIME         45.0e-3                       // frame repeat after 45ms\n#define RECS80EXT_ADDRESS_OFFSET                2                               // skip 2 bits (2nd start + 1 toggle)\n#define RECS80EXT_ADDRESS_LEN                   4                               // read 4 address bits\n#define RECS80EXT_COMMAND_OFFSET                6                               // skip 6 bits (2nd start + 1 toggle + 4 address)\n#define RECS80EXT_COMMAND_LEN                   6                               // read 6 command bits\n#define RECS80EXT_COMPLETE_DATA_LEN             12                              // complete length\n#define RECS80EXT_STOP_BIT                      1                               // has stop bit\n#define RECS80EXT_LSB                           0                               // MSB...LSB\n#define RECS80EXT_FLAGS                         0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * NUBERT:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define NUBERT_START_BIT_PULSE_TIME             1340.0e-6                       // 1340 usec pulse\n#define NUBERT_START_BIT_PAUSE_TIME              340.0e-6                       //  340 usec pause\n#define NUBERT_1_PULSE_TIME                     1340.0e-6                       // 1340 usec pulse\n#define NUBERT_1_PAUSE_TIME                      340.0e-6                       //  340 usec pause\n#define NUBERT_0_PULSE_TIME                      500.0e-6                       //  500 usec pulse\n#define NUBERT_0_PAUSE_TIME                     1300.0e-6                       // 1300 usec pause\n#define NUBERT_FRAMES                           2                               // Nubert sends 2 frames\n#define NUBERT_AUTO_REPETITION_PAUSE_TIME         35.0e-3                       // auto repetition after 35ms\n#define NUBERT_FRAME_REPEAT_PAUSE_TIME            35.0e-3                       // frame repeat after 45ms\n#define NUBERT_ADDRESS_OFFSET                   0                               // skip 0 bits\n#define NUBERT_ADDRESS_LEN                      0                               // read 0 address bits\n#define NUBERT_COMMAND_OFFSET                   0                               // skip 0 bits\n#define NUBERT_COMMAND_LEN                      10                              // read 10 bits\n#define NUBERT_COMPLETE_DATA_LEN                10                              // complete length\n#define NUBERT_STOP_BIT                         1                               // has stop bit\n#define NUBERT_LSB                              0                               // MSB?\n#define NUBERT_FLAGS                            0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * FAN: (ventilator)\n *\n * Similar to NUBERT, but\n *   - has data bit instead of stop bit\n *   - has NO frame repetition\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define FAN_START_BIT_PULSE_TIME                1280.0e-6                       // 1280 usec pulse\n#define FAN_START_BIT_PAUSE_TIME                 380.0e-6                       //  380 usec pause\n#define FAN_1_PULSE_TIME                        1280.0e-6                       // 1280 usec pulse\n#define FAN_1_PAUSE_TIME                         380.0e-6                       //  380 usec pause\n#define FAN_0_PULSE_TIME                         380.0e-6                       //  380 usec pulse\n#define FAN_0_PAUSE_TIME                        1280.0e-6                       // 1280 usec pause\n#define FAN_FRAMES                              1                               // FAN sends only 1 frame (NUBERT sends 2)\n#define FAN_AUTO_REPETITION_PAUSE_TIME            6.6e-3                        // auto repetition after 6.6ms\n#define FAN_FRAME_REPEAT_PAUSE_TIME               6.6e-3                        // frame repeat after 6.6ms\n#define FAN_ADDRESS_OFFSET                      0                               // skip 0 bits\n#define FAN_ADDRESS_LEN                         0                               // read 0 address bits\n#define FAN_COMMAND_OFFSET                      0                               // skip 0 bits\n#define FAN_COMMAND_LEN                         11                              // read 10 bits\n#define FAN_COMPLETE_DATA_LEN                   11                              // complete length\n#define FAN_STOP_BIT                            0                               // has NO stop bit (fm: this seems to be wrong)\n#define FAN_LSB                                 0                               // MSB\n#define FAN_FLAGS                               0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * SPEAKER:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define SPEAKER_START_BIT_PULSE_TIME             440.0e-6                       //  440 usec pulse\n#define SPEAKER_START_BIT_PAUSE_TIME            1250.0e-6                       // 1250 usec pause\n#define SPEAKER_1_PULSE_TIME                    1250.0e-6                       // 1250 usec pulse\n#define SPEAKER_1_PAUSE_TIME                     440.0e-6                       //  440 usec pause\n#define SPEAKER_0_PULSE_TIME                     440.0e-6                       //  440 usec pulse\n#define SPEAKER_0_PAUSE_TIME                    1250.0e-6                       // 1250 usec pause\n#define SPEAKER_FRAMES                          2                               // SPEAKER sends 2 frames\n#define SPEAKER_AUTO_REPETITION_PAUSE_TIME        35.0e-3                       // auto repetition after 35ms\n#define SPEAKER_FRAME_REPEAT_PAUSE_TIME           35.0e-3                       // frame repeat after 45ms\n#define SPEAKER_ADDRESS_OFFSET                  0                               // skip 0 bits\n#define SPEAKER_ADDRESS_LEN                     0                               // read 0 address bits\n#define SPEAKER_COMMAND_OFFSET                  0                               // skip 0 bits\n#define SPEAKER_COMMAND_LEN                     10                              // read 10 bits\n#define SPEAKER_COMPLETE_DATA_LEN               10                              // complete length\n#define SPEAKER_STOP_BIT                        1                               // has stop bit\n#define SPEAKER_LSB                             0                               // MSB?\n#define SPEAKER_FLAGS                           0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * BANG_OLUFSEN:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define BANG_OLUFSEN_START_BIT1_PULSE_TIME       200.0e-6                       //   200 usec pulse\n#define BANG_OLUFSEN_START_BIT1_PAUSE_TIME      3125.0e-6                       //  3125 usec pause\n#define BANG_OLUFSEN_START_BIT2_PULSE_TIME       200.0e-6                       //   200 usec pulse\n#define BANG_OLUFSEN_START_BIT2_PAUSE_TIME      3125.0e-6                       //  3125 usec pause\n#define BANG_OLUFSEN_START_BIT3_PULSE_TIME       200.0e-6                       //   200 usec pulse\n#define BANG_OLUFSEN_START_BIT3_PAUSE_TIME     15625.0e-6                       // 15625 usec pause\n#define BANG_OLUFSEN_START_BIT4_PULSE_TIME       200.0e-6                       //   200 usec pulse\n#define BANG_OLUFSEN_START_BIT4_PAUSE_TIME      3125.0e-6                       //  3125 usec pause\n#define BANG_OLUFSEN_PULSE_TIME                  200.0e-6                       //   200 usec pulse\n#define BANG_OLUFSEN_1_PAUSE_TIME               9375.0e-6                       //  9375 usec pause\n#define BANG_OLUFSEN_0_PAUSE_TIME               3125.0e-6                       //  3125 usec pause\n#define BANG_OLUFSEN_R_PAUSE_TIME               6250.0e-6                       //  6250 usec pause (repeat last bit)\n#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME    12500.0e-6                       // 12500 usec pause (trailer bit)\n#define BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME      45.0e-3                       // frame repeat after 45ms\n#define BANG_OLUFSEN_ADDRESS_OFFSET             0                               // no address bits\n#define BANG_OLUFSEN_ADDRESS_LEN                0                               // no address bits\n#define BANG_OLUFSEN_COMMAND_OFFSET             3                               // skip startbits 2, 3, 4\n#define BANG_OLUFSEN_COMMAND_LEN                16                              // read 16 command bits\n#define BANG_OLUFSEN_COMPLETE_DATA_LEN          20                              // complete length: startbits 2, 3, 4 + 16 data bits + trailer bit\n#define BANG_OLUFSEN_STOP_BIT                   1                               // has stop bit\n#define BANG_OLUFSEN_LSB                        0                               // MSB...LSB\n#define BANG_OLUFSEN_FLAGS                      0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * GRUNDIG & NOKIA\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define GRUNDIG_NOKIA_IR60_BIT_TIME             528.0e-6                        // 528 usec pulse/pause\n#define GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME       2639.0e-6                       // 2639 usec pause after pre bit\n#define GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_TIME  117.76e-3                   // info frame repeat after 117.76 ms\n#define GRUNDIG_NOKIA_IR60_STOP_BIT             0                               // has no stop bit\n#define GRUNDIG_NOKIA_IR60_LSB                  1                               // MSB...LSB\n#define GRUNDIG_NOKIA_IR60_FLAGS                (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1)  // flags\n\n#define GRUNDIG_FRAMES                          2                               // GRUNDIG sends each frame 1+1 times\n#define GRUNDIG_AUTO_REPETITION_PAUSE_TIME      20.0e-3                         // repetition after 20ms\n#define GRUNDIG_ADDRESS_OFFSET                  0                               // no address\n#define GRUNDIG_ADDRESS_LEN                     0                               // no address\n#define GRUNDIG_COMMAND_OFFSET                  1                               // skip 1 start bit\n#define GRUNDIG_COMMAND_LEN                     9                               // read 9 command bits\n#define GRUNDIG_COMPLETE_DATA_LEN               10                              // complete length: 1 start bit + 9 data bits\n\n#define NOKIA_FRAMES                            3                               // NOKIA sends each frame 1 + 1 + 1 times\n#define NOKIA_AUTO_REPETITION_PAUSE_TIME        20.0e-3                         // repetition after 20ms\n#define NOKIA_ADDRESS_OFFSET                    9                               // skip 9 bits (1 start bit + 8 data bits)\n#define NOKIA_ADDRESS_LEN                       8                               // 7 address bits\n#define NOKIA_COMMAND_OFFSET                    1                               // skip 1 bit (1 start bit)\n#define NOKIA_COMMAND_LEN                       8                               // read 8 command bits\n#define NOKIA_COMPLETE_DATA_LEN                 17                              // complete length: 1 start bit + 8 address bits + 8 command bits\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * IR60:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IR60_FRAMES                             2                               // IR60 sends each frame 1+1 times\n#define IR60_AUTO_REPETITION_PAUSE_TIME         22.2e-3                         // repetition after 22.2ms\n#define IR60_TIMEOUT_TIME                       5000.0e-6                       // timeout grundig frame, switch to IR60\n#define IR60_ADDRESS_OFFSET                     0                               // skip 1 bits\n#define IR60_ADDRESS_LEN                        0                               // read 0 address bits\n#define IR60_COMMAND_OFFSET                     0                               // skip 1 bit (start bit after pre bit, always 1)\n#define IR60_COMMAND_LEN                        7                               // read 6 command bits\n#define IR60_COMPLETE_DATA_LEN                  7                               // complete length\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * SIEMENS & RUWIDO:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#define SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME    275.0e-6                      //  275 usec pulse\n#define SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME    550.0e-6                      //  550 usec pause\n#define SIEMENS_OR_RUWIDO_BIT_PULSE_TIME          275.0e-6                      //  275 usec short pulse\n#define SIEMENS_OR_RUWIDO_BIT_PULSE_TIME_2        550.0e-6                      //  550 usec long pulse\n#define SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME          275.0e-6                      //  275 usec short pause\n#define SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME_2        550.0e-6                      //  550 usec long pause\n\n#define SIEMENS_OR_RUWIDO_FRAME_REPEAT_PAUSE_TIME 45.0e-3                       // frame repeat after 45ms\n#define SIEMENS_OR_RUWIDO_STOP_BIT                0                             // has no stop bit\n#define SIEMENS_OR_RUWIDO_LSB                     0                             // MSB...LSB\n#define SIEMENS_OR_RUWIDO_FLAGS                   (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1)  // flags\n\n#define RUWIDO_ADDRESS_OFFSET                   0                               // skip 0 bits\n#define RUWIDO_ADDRESS_LEN                      9                               // read 9 address bits\n#define RUWIDO_COMMAND_OFFSET                   9                               // skip 9 bits\n#define RUWIDO_COMMAND_LEN                      8                               // read 7 + 1 command bits, last bit is only check bit\n#define RUWIDO_COMPLETE_DATA_LEN                17                              // complete length\n\n#define SIEMENS_ADDRESS_OFFSET                  0                               // skip 0 bits\n#define SIEMENS_ADDRESS_LEN                     11                              // read 11 bits\n#define SIEMENS_COMMAND_OFFSET                  11                              // skip 11 bits\n#define SIEMENS_COMMAND_LEN                     11                              // read 10 + 1 command bits, last bit is only check bit\n#define SIEMENS_COMPLETE_DATA_LEN               22                              // complete length\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * FDC:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define FDC_START_BIT_PULSE_TIME                 2085.0e-6                      // 2085 usec pulse\n#define FDC_START_BIT_PAUSE_TIME                  966.0e-6                      //  966 usec pause\n#define FDC_PULSE_TIME                            300.0e-6                      //  300 usec pulse\n#define FDC_1_PAUSE_TIME                          715.0e-6                      //  715 usec pause\n#define FDC_0_PAUSE_TIME                          220.0e-6                      //  220 usec pause\n#define FDC_FRAME_REPEAT_PAUSE_TIME                60.0e-3                      // frame repeat after 60ms\n#define FDC_ADDRESS_OFFSET                       0                              // skip 0 bits\n#define FDC_ADDRESS_LEN                         14                              // read 14 address bits, but use only 6, shift 8 into command\n#define FDC_COMMAND_OFFSET                      20                              // skip 20 bits\n#define FDC_COMMAND_LEN                         12                              // read 12 bits\n#define FDC_COMPLETE_DATA_LEN                   40                              // complete length\n#define FDC_STOP_BIT                            1                               // has stop bit\n#define FDC_LSB                                 1                               // LSB...MSB\n#define FDC_FLAGS                               0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RCCAR:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RCCAR_START_BIT_PULSE_TIME               2000.0e-6                      // 2000 usec pulse\n#define RCCAR_START_BIT_PAUSE_TIME               2000.0e-6                      // 2000 usec pause\n#define RCCAR_PULSE_TIME                          600.0e-6                      //  360 usec pulse\n#define RCCAR_1_PAUSE_TIME                        450.0e-6                      //  650 usec pause\n#define RCCAR_0_PAUSE_TIME                        900.0e-6                      //  180 usec pause\n#define RCCAR_FRAME_REPEAT_PAUSE_TIME              40.0e-3                      // frame repeat after 40ms\n#define RCCAR_ADDRESS_OFFSET                     0                              // skip 0 bits\n#define RCCAR_ADDRESS_LEN                        0                              // read 0 address bits\n#define RCCAR_COMMAND_OFFSET                     0                              // skip 0 bits\n#define RCCAR_COMMAND_LEN                       13                              // read 13 bits\n#define RCCAR_COMPLETE_DATA_LEN                 13                              // complete length\n#define RCCAR_STOP_BIT                          1                               // has stop bit\n#define RCCAR_LSB                               1                               // LSB...MSB\n#define RCCAR_FLAGS                             0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * JVC:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define JVC_START_BIT_PULSE_TIME                9000.0e-6                       // 9000 usec pulse\n#define JVC_START_BIT_PAUSE_TIME                4500.0e-6                       // 4500 usec pause\n#define JVC_PULSE_TIME                           560.0e-6                       //  560 usec pulse\n#define JVC_1_PAUSE_TIME                        1690.0e-6                       // 1690 usec pause\n#define JVC_0_PAUSE_TIME                         560.0e-6                       //  560 usec pause\n#define JVC_FRAME_REPEAT_PAUSE_TIME               22.0e-3                       // frame repeat after 22ms\n#define JVC_ADDRESS_OFFSET                       0                              // skip 0 bits\n#define JVC_ADDRESS_LEN                          4                              // read 4 address bits\n#define JVC_COMMAND_OFFSET                       4                              // skip 4 bits\n#define JVC_COMMAND_LEN                         12                              // read 12 bits\n#define JVC_COMPLETE_DATA_LEN                   16                              // complete length\n#define JVC_STOP_BIT                            1                               // has stop bit\n#define JVC_LSB                                 1                               // LSB...MSB\n#define JVC_FLAGS                               0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * NIKON:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define NIKON_START_BIT_PULSE_TIME              2200.0e-6                       //  2200 usec pulse\n#define NIKON_START_BIT_PAUSE_TIME             27100.0e-6                       // 27100 usec pause\n#define NIKON_PULSE_TIME                         500.0e-6                       //   500 usec pulse\n#define NIKON_1_PAUSE_TIME                      3500.0e-6                       //  3500 usec pause\n#define NIKON_0_PAUSE_TIME                      1500.0e-6                       //  1500 usec pause\n#define NIKON_FRAME_REPEAT_PAUSE_TIME             60.0e-3                       // frame repeat after 60ms\n#define NIKON_ADDRESS_OFFSET                    0                               // skip 0 bits\n#define NIKON_ADDRESS_LEN                       0                               // read 0 address bits\n#define NIKON_COMMAND_OFFSET                    0                               // skip 0 bits\n#define NIKON_COMMAND_LEN                       2                               // read 2 bits\n#define NIKON_COMPLETE_DATA_LEN                 2                               // complete length\n#define NIKON_STOP_BIT                          1                               // has stop bit\n#define NIKON_LSB                               0                               // LSB...MSB\n#define NIKON_FLAGS                             0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * KATHREIN:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define KATHREIN_START_BIT_PULSE_TIME            210.0e-6                       // 1340 usec pulse\n#define KATHREIN_START_BIT_PAUSE_TIME           6218.0e-6                       //  340 usec pause\n#define KATHREIN_1_PULSE_TIME                    210.0e-6                       // 1340 usec pulse\n#define KATHREIN_1_PAUSE_TIME                   3000.0e-6                       //  340 usec pause\n#define KATHREIN_0_PULSE_TIME                    210.0e-6                       //  500 usec pulse\n#define KATHREIN_0_PAUSE_TIME                   1400.0e-6                       // 1300 usec pause\n#define KATHREIN_SYNC_BIT_PAUSE_LEN_TIME        4600.0e-6                       // 4600 usec sync (on 6th and/or 8th bit)\n#define KATHREIN_FRAMES                         1                               // Kathrein sends 1 frame\n#define KATHREIN_AUTO_REPETITION_PAUSE_TIME     35.0e-3                         // auto repetition after 35ms\n#define KATHREIN_FRAME_REPEAT_PAUSE_TIME        35.0e-3                         // frame repeat after 35ms\n#define KATHREIN_ADDRESS_OFFSET                 1                               // skip 1 bits\n#define KATHREIN_ADDRESS_LEN                    4                               // read 4 address bits\n#define KATHREIN_COMMAND_OFFSET                 5                               // skip 5 bits\n#define KATHREIN_COMMAND_LEN                    7                               // read 7 bits\n#define KATHREIN_COMPLETE_DATA_LEN              13                              // complete length\n#define KATHREIN_STOP_BIT                       1                               // has stop bit\n#define KATHREIN_LSB                            0                               // MSB\n#define KATHREIN_FLAGS                          0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * NETBOX:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define NETBOX_START_BIT_PULSE_TIME             2400.0e-6                       // 2400 usec pulse\n#define NETBOX_START_BIT_PAUSE_TIME              800.0e-6                       //  800 usec pause\n#define NETBOX_PULSE_TIME                        800.0e-6                       //  800 usec pulse\n#define NETBOX_PAUSE_TIME                        800.0e-6                       //  800 usec pause\n#define NETBOX_FRAMES                           1                               // Netbox sends 1 frame\n#define NETBOX_AUTO_REPETITION_PAUSE_TIME       35.0e-3                         // auto repetition after 35ms\n#define NETBOX_FRAME_REPEAT_PAUSE_TIME          35.0e-3                         // frame repeat after 35ms\n#define NETBOX_ADDRESS_OFFSET                   0                               // skip 0 bits\n#define NETBOX_ADDRESS_LEN                      3                               // read 3 address bits\n#define NETBOX_COMMAND_OFFSET                   3                               // skip 3 bits\n#define NETBOX_COMMAND_LEN                      13                              // read 13 bits\n#define NETBOX_COMPLETE_DATA_LEN                16                              // complete length\n#define NETBOX_STOP_BIT                         0                               // has no stop bit\n#define NETBOX_LSB                              1                               // LSB\n#define NETBOX_FLAGS                            IRMP_PARAM_FLAG_IS_SERIAL       // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * LEGO:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define LEGO_START_BIT_PULSE_TIME                158.0e-6                       //  158 usec pulse ( 6 x 1/38kHz)\n#define LEGO_START_BIT_PAUSE_TIME               1026.0e-6                       // 1026 usec pause (39 x 1/38kHz)\n#define LEGO_PULSE_TIME                          158.0e-6                       //  158 usec pulse ( 6 x 1/38kHz)\n#define LEGO_1_PAUSE_TIME                        553.0e-6                       //  553 usec pause (21 x 1/38kHz)\n#define LEGO_0_PAUSE_TIME                        263.0e-6                       //  263 usec pause (10 x 1/38kHz)\n#define LEGO_FRAME_REPEAT_PAUSE_TIME              40.0e-3                       // frame repeat after 40ms\n#define LEGO_ADDRESS_OFFSET                     0                               // skip 0 bits\n#define LEGO_ADDRESS_LEN                        0                               // read 0 address bits\n#define LEGO_COMMAND_OFFSET                     0                               // skip 0 bits\n#define LEGO_COMMAND_LEN                        16                              // read 16 bits (12 command + 4 CRC)\n#define LEGO_COMPLETE_DATA_LEN                  16                              // complete length\n#define LEGO_STOP_BIT                           1                               // has stop bit\n#define LEGO_LSB                                0                               // MSB...LSB\n#define LEGO_FLAGS                              0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * THOMSON:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define THOMSON_PULSE_TIME                       550.0e-6                       //  550 usec pulse\n#define THOMSON_1_PAUSE_TIME                    4500.0e-6                       // 4500 usec pause\n#define THOMSON_0_PAUSE_TIME                    2000.0e-6                       // 2000 usec pause\n#define THOMSON_FRAMES                          1                               // THOMSON sends 1 frame\n#define THOMSON_AUTO_REPETITION_PAUSE_TIME        35.0e-3                       // repetition after 35ms\n#define THOMSON_FRAME_REPEAT_PAUSE_TIME           35.0e-3                       // frame repeat after 35ms\n#define THOMSON_ADDRESS_OFFSET                  0                               // skip 0 bits\n#define THOMSON_ADDRESS_LEN                     4                               // read 4 address bits\n#define THOMSON_COMMAND_OFFSET                  5                               // skip 4 address bits + 1 toggle bit\n#define THOMSON_COMMAND_LEN                     7                               // read 7 command bits\n#define THOMSON_COMPLETE_DATA_LEN               12                              // complete length\n#define THOMSON_STOP_BIT                        1                               // has stop bit\n#define THOMSON_LSB                             0                               // MSB...LSB\n#define THOMSON_FLAGS                           0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * BOSE:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define BOSE_START_BIT_PULSE_TIME               1060.0e-6                       // 1060 usec pulse\n#define BOSE_START_BIT_PAUSE_TIME               1425.0e-6                       // 1425 usec pause\n#define BOSE_PULSE_TIME                          550.0e-6                       //  550 usec pulse\n#define BOSE_1_PAUSE_TIME                       1425.0e-6                       // 1425 usec pause\n#define BOSE_0_PAUSE_TIME                        437.0e-6                       //  437 usec pause\n#define BOSE_FRAMES                             1\n#define BOSE_AUTO_REPETITION_PAUSE_TIME           40.0e-3                       // repetition after 40ms?\n#define BOSE_FRAME_REPEAT_PAUSE_TIME              40.0e-3                       // frame repeat after 40ms?\n#define BOSE_ADDRESS_OFFSET                      0                              // skip 0 bits\n#define BOSE_ADDRESS_LEN                         0                              // read 16 address bits\n#define BOSE_COMMAND_OFFSET                      0                              // skip 16 bits (8 address + 8 /address)\n#define BOSE_COMMAND_LEN                        16                              // read 16 bits (8 command + 8 /command)\n#define BOSE_COMPLETE_DATA_LEN                  16                              // complete length\n#define BOSE_STOP_BIT                           1                               // has stop bit\n#define BOSE_LSB                                1                               // LSB...MSB\n#define BOSE_FLAGS                              0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * A1TVBOX:\n * In reality A1 TV Box has no start bit with 300/340 usec. There are 2 start bits \"10\" with 250us pulse + 150us pause + 150us pause + 250us pulse\n * This is not very easy to detect, because 1st and 2nd pause of both start bits are closely spaced.\n * So IRMP looks for pseudo start bit with 300/340 usec and ignores the second half of the 2nd bit (250us pulse)\n * This method only works because the first data bit (which is the 3rd bit) following is always \"1\":\n * IRMP treats the first \"long\" pulse (250us of 2nd start bit + 250us of 1st data bit) of this \"1\" as a first _short_ pulse.\n * This is a bug in IRMP's manchester decoder, but a good feature here ;-)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define A1TVBOX_START_BIT_PULSE_TIME            300.0e-6                        // 300 usec pulse\n#define A1TVBOX_START_BIT_PAUSE_TIME            340.0e-6                        // 340 usec pause\n#define A1TVBOX_BIT_PULSE_TIME                  250.0e-6                        // 250 usec pulse\n#define A1TVBOX_BIT_PAUSE_TIME                  150.0e-6                        // 150 usec pulse\n#define A1TVBOX_STOP_BIT                        0                               // has no stop bit\n#define A1TVBOX_LSB                             0                               // MSB...LSB\n#define A1TVBOX_FLAGS                           (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1 )  // flags\n#define A1TVBOX_FRAMES                          1                               // A1TVBOX sends each frame 1 times\n#define A1TVBOX_ADDRESS_OFFSET                  1                               // skip 1 bits\n#define A1TVBOX_ADDRESS_LEN                     8                               // read 8 address bits\n#define A1TVBOX_COMMAND_OFFSET                  9                               // skip 9 bits (start bit + address)\n#define A1TVBOX_COMMAND_LEN                     8                               // read 8 command bits\n#define A1TVBOX_COMPLETE_DATA_LEN               17                              // complete length incl. start bit\n#define A1TVBOX_FRAME_REPEAT_PAUSE_TIME         50.0e-3                         // 50 msec pause between frames, don't know if it is correct\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * MERLIN:\n * See notes for A1TVBOX\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define MERLIN_START_BIT_PULSE_TIME            210.0e-6                         // 210 usec pulse\n#define MERLIN_START_BIT_PAUSE_TIME            420.0e-6                         // 429 usec pause\n#define MERLIN_BIT_PULSE_TIME                  210.0e-6                         // 210 usec pulse\n#define MERLIN_BIT_PAUSE_TIME                  210.0e-6                         // 210 usec pulse\n#define MERLIN_STOP_BIT                        0                                // has no stop bit\n#define MERLIN_LSB                             0                                // MSB...LSB\n#define MERLIN_FLAGS                           (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1 )  // flags\n#define MERLIN_FRAMES                          1                                // MERLIN sends each frame 1 times\n#define MERLIN_ADDRESS_OFFSET                  2                                // skip 1 bits\n#define MERLIN_ADDRESS_LEN                     9                                // read 9 address bits\n#define MERLIN_COMMAND_OFFSET                  11                               // skip 11 bits (start bit + address)\n#define MERLIN_COMMAND_LEN                     16                               // read up to 16 command bits (could be up to 32)\n#define MERLIN_COMPLETE_DATA_LEN               27                               // complete length incl. start bit\n#define MERLIN_FRAME_REPEAT_PAUSE_TIME         50.0e-3                          // 50 msec pause between frames, don't know if it is correct\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * ORTEK (Hama): 6 address bits + 2 frame type bits + 6 command bits + 1 parity bit + 1 unknown bit + \"1\" + \"0\"\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define ORTEK_START_BIT_PULSE_TIME              2000.0e-6                       // 2000 usec pulse\n#define ORTEK_START_BIT_PAUSE_TIME              1000.0e-6                       // 1000 usec pause\n#define ORTEK_BIT_TIME                           500.0e-6                       //  500 usec pulse/pause\n#define ORTEK_FRAME_REPEAT_PAUSE_TIME             45.0e-3                       // frame repeat after 45ms\n#define ORTEK_ADDRESS_OFFSET                    0                               // skip 0 bits\n#define ORTEK_ADDRESS_LEN                       8                               // read 6 address bits + 2 special bits\n#define ORTEK_COMMAND_OFFSET                    8                               // skip 6 address bits + 2 special bits\n#define ORTEK_COMMAND_LEN                       6                               // read 6 command bits\n#define ORTEK_COMPLETE_DATA_LEN                 18                              // complete length\n#define ORTEK_STOP_BIT                          0                               // has no stop bit\n#define ORTEK_LSB                               0                               // MSB...LSB\n#define ORTEK_FLAGS                             (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1)   // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * TELEFUNKEN:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define TELEFUNKEN_START_BIT_PULSE_TIME          600.0e-6                       //  600 usec pulse\n#define TELEFUNKEN_START_BIT_PAUSE_TIME         1500.0e-6                       // 1500 usec pause\n#define TELEFUNKEN_PULSE_TIME                    600.0e-6                       //  600 usec pulse\n#define TELEFUNKEN_1_PAUSE_TIME                 1500.0e-6                       // 1500 usec pause\n#define TELEFUNKEN_0_PAUSE_TIME                  600.0e-6                       //  600 usec pause\n#define TELEFUNKEN_FRAME_REPEAT_PAUSE_TIME        22.0e-3                       // frame repeat after XX ms ?????\n#define TELEFUNKEN_ADDRESS_OFFSET                0                              // skip 0 bits\n#define TELEFUNKEN_ADDRESS_LEN                   0                              // read 0 address bits\n#define TELEFUNKEN_COMMAND_OFFSET                0                              // skip 0 bits\n#define TELEFUNKEN_COMMAND_LEN                  15                              // read 15 bits\n#define TELEFUNKEN_COMPLETE_DATA_LEN            15                              // complete length\n#define TELEFUNKEN_STOP_BIT                     1                               // has stop bit\n#define TELEFUNKEN_LSB                          0                               // LSB...MSB\n#define TELEFUNKEN_FLAGS                        0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * ROOMBA\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define ROOMBA_START_BIT_PULSE_TIME             2790.0e-6                       // 2790 usec pulse\n#define ROOMBA_START_BIT_PAUSE_TIME              930.0e-6                       //  930 usec pause\n#define ROOMBA_0_PULSE_TIME                      930.0e-6                       //  930 usec pulse\n#define ROOMBA_1_PULSE_TIME                     2790.0e-6                       // 2790 usec pulse\n#define ROOMBA_0_PAUSE_TIME                     2790.0e-6                       // 2790 usec pause\n#define ROOMBA_1_PAUSE_TIME                      930.0e-6                       //  930 usec pause\n#define ROOMBA_FRAME_REPEAT_PAUSE_TIME            18.0e-3                       // frame repeat after 18ms\n#define ROOMBA_ADDRESS_OFFSET                    0                              // skip 0 bits\n#define ROOMBA_ADDRESS_LEN                       0                              // read 0 address bits\n#define ROOMBA_COMMAND_OFFSET                    0                              // skip 0 bits\n#define ROOMBA_COMMAND_LEN                       7                              // read 7 bits\n#define ROOMBA_COMPLETE_DATA_LEN                 7                              // complete length\n#define ROOMBA_STOP_BIT                         0                               // has stop bit (fm: sure?)\n#define ROOMBA_LSB                              0                               // MSB...LSB\n#define ROOMBA_FLAGS                            0                               // flags\n#define ROOMBA_FRAMES                           8                               // ROOMBA sends 8 frames (this is a lie, but more comfortable)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RC-MM (32, 24, or 12 bit)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RCMM32_START_BIT_PULSE_TIME              500.0e-6                       // 500 usec pulse\n#define RCMM32_START_BIT_PAUSE_TIME              220.0e-6                       // 220 usec pause\n#define RCMM32_PULSE_TIME                        230.0e-6                       // 230 usec pulse\n#define RCMM32_00_PAUSE_TIME                     220.0e-6                       // 220 usec pause\n#define RCMM32_01_PAUSE_TIME                     370.0e-6                       // 370 usec pause\n#define RCMM32_10_PAUSE_TIME                     540.0e-6                       // 540 usec pause\n#define RCMM32_11_PAUSE_TIME                     720.0e-6                       // 720 usec pause\n\n#define RCMM32_FRAME_REPEAT_PAUSE_TIME            80.0e-3                       // frame repeat after 80 ms\n#define RCMM32_ADDRESS_OFFSET                    0                              // skip 0 bits\n#define RCMM32_ADDRESS_LEN                      16                              //  read 16 address bits\n#define RCMM32_COMMAND_OFFSET                   17                              // skip 17 bits\n#define RCMM32_COMMAND_LEN                      15                              // read 15 bits\n#define RCMM32_COMPLETE_DATA_LEN                32                              // complete length\n#define RCMM32_STOP_BIT                         1                               // has stop bit\n#define RCMM32_LSB                              0                               // LSB...MSB\n#define RCMM32_FLAGS                            0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * PENTAX:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define PENTAX_START_BIT_PULSE_TIME             13000.0e-6                      // 13 msec pulse\n#define PENTAX_START_BIT_PAUSE_TIME              3000.0e-6                      // 3 msec pause\n#define PENTAX_PULSE_TIME                        1000.0e-6                      // 1 msec pulse\n#define PENTAX_1_PAUSE_TIME                      3000.0e-6                      // 3 msec pause\n#define PENTAX_0_PAUSE_TIME                      1000.0e-6                      // 1 msec pause\n#define PENTAX_FRAME_REPEAT_PAUSE_TIME             60.0e-3                      // frame repeat after 60ms\n#define PENTAX_ADDRESS_OFFSET                  0                                // skip 0 bits\n#define PENTAX_ADDRESS_LEN                     0                                // read 0 address bits\n#define PENTAX_COMMAND_OFFSET                  0                                // skip 0 bits\n#define PENTAX_COMMAND_LEN                     6                                // read 6 bits\n#define PENTAX_COMPLETE_DATA_LEN               6                                // complete length\n#define PENTAX_STOP_BIT                        1                                // has stop bit\n#define PENTAX_LSB                             0                                // LSB...MSB\n#define PENTAX_FLAGS                           0                                // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * ACP24: Stiebel Eltron ACP24 air conditioner\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define ACP24_START_BIT_PULSE_TIME               390.0e-6                       //  390 usec pulse\n#define ACP24_START_BIT_PAUSE_TIME               950.0e-6                       //  950 usec pause\n#define ACP24_PULSE_TIME                         390.0e-6                       //  390 usec pulse\n#define ACP24_1_PAUSE_TIME                      1300.0e-6                       // 1300 usec pause\n#define ACP24_0_PAUSE_TIME                       950.0e-6                       //  950 usec pause\n#define ACP24_FRAME_REPEAT_PAUSE_TIME             22.0e-3                       // frame repeat after 22ms?\n#define ACP24_ADDRESS_OFFSET                     0                              // skip 0 bits\n#define ACP24_ADDRESS_LEN                        0                              // read 6 address bits\n#define ACP24_COMMAND_OFFSET                     0                              // skip 6 bits\n#define ACP24_COMMAND_LEN                        0                              // read 0 bits (70 bits will be read and compressed by special routine)\n#define ACP24_COMPLETE_DATA_LEN                 70                              // complete length\n#define ACP24_STOP_BIT                          1                               // has stop bit\n#define ACP24_LSB                               0                               // LSB...MSB\n#define ACP24_FLAGS                             0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * IRMP16:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP16_START_BIT_PULSE_TIME              842.0e-6                       //  842 usec pulse (32 x 1/38kHz)\n#define IRMP16_START_BIT_PAUSE_TIME             1052.0e-6                       // 1052 usec pause (40 x 1/38kHz)\n#define IRMP16_PULSE_TIME                        421.0e-6                       //  421 usec pulse (16 x 1/38kHz)\n#define IRMP16_1_PAUSE_TIME                      842.0e-6                       //  842 usec pause (32 x 1/38kHz)\n#define IRMP16_0_PAUSE_TIME                      421.0e-6                       //  421 usec pause (16 x 1/38kHz)\n#define IRMP16_FRAME_REPEAT_PAUSE_TIME            40.0e-3                       // frame repeat after 40ms\n#define IRMP16_ADDRESS_OFFSET                   0                               // skip 0 bits\n#define IRMP16_ADDRESS_LEN                      0                               // read 0 address bits\n#define IRMP16_COMMAND_OFFSET                   0                               // skip 0 bits\n#define IRMP16_COMMAND_LEN                      16                              // read 16 bits (12 command + 4 CRC)\n#define IRMP16_COMPLETE_DATA_LEN                16                              // complete length\n#define IRMP16_STOP_BIT                         1                               // has stop bit\n#define IRMP16_LSB                              1                               // LSB...MSB\n#define IRMP16_FLAGS                            0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * GREE - climate:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define GREE_START_BIT_PULSE_TIME              12000.0e-6                       // 12000 usec pulse (32 x 1/38kHz)\n#define GREE_START_BIT_PAUSE_TIME               6000.0e-6                       //  6000 usec pause (40 x 1/38kHz)\n#define GREE_PULSE_TIME                          900.0e-6                       //   900 usec pulse (16 x 1/38kHz)\n#define GREE_1_PAUSE_TIME                        700.0e-6                       //   700 usec pause (32 x 1/38kHz)\n#define GREE_0_PAUSE_TIME                       2100.0e-6                       //  2100 usec pause (16 x 1/38kHz)\n#define GREE_FRAME_REPEAT_PAUSE_TIME              40.0e-3                       // frame repeat after 40ms\n#define GREE_ADDRESS_OFFSET                     0                               // skip 0 bits\n#define GREE_ADDRESS_LEN                        16                              // read 16 address bits\n#define GREE_COMMAND_OFFSET                     16                              // skip 16 bits\n#define GREE_COMMAND_LEN                        16                              // read 16 bits\n#define GREE_COMPLETE_DATA_LEN                  32                              // complete length\n#define GREE_STOP_BIT                           1                               // has stop bit\n#define GREE_LSB                                1                               // LSB...MSB\n#define GREE_FLAGS                              0                               // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * METZ:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define METZ_START_BIT_PULSE_TIME                870.0e-6                       //  870 usec pulse\n#define METZ_START_BIT_PAUSE_TIME               2300.0e-6                       // 2300 usec pause\n#define METZ_PULSE_TIME                          435.0e-6                       //  435 usec pulse\n#define METZ_1_PAUSE_TIME                       1680.0e-6                       // 1680 usec pause\n#define METZ_0_PAUSE_TIME                        960.0e-6                       //  960 usec pause\n#define METZ_FRAME_REPEAT_PAUSE_TIME             122.0e-3                       // frame repeat after 122ms\n#define METZ_ADDRESS_OFFSET                      1                              // skip 1 bit (toggle bit)\n#define METZ_ADDRESS_LEN                         6                              // read 6 address bits\n#define METZ_COMMAND_OFFSET                      7                              // skip 7 bits\n#define METZ_COMMAND_LEN                        13                              // read 13 bits\n#define METZ_COMPLETE_DATA_LEN                  20                              // complete length\n#define METZ_STOP_BIT                            0                              // has no stop bit\n#define METZ_LSB                                 0                              // MSB...LSB\n#define METZ_FLAGS                               0                              // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RF GEN24 generic remote control (Pollin 550666, EAN 4049702006022 and many other similar RF remote controls)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RF_GEN24_0_PULSE_TIME                   400.0e-6                        //  400 usec pulse\n#define RF_GEN24_0_PAUSE_TIME                  1066.0e-6                        // 1066 usec pause\n#define RF_GEN24_1_PULSE_TIME                  1066.0e-6                        // 1066 usec pulse\n#define RF_GEN24_1_PAUSE_TIME                   400.0e-6                        //  400 usec pause\n\n#define RF_GEN24_FRAME_REPEAT_PAUSE_TIME         10.0e-3                        // frame repeat after 10 msec\n#define RF_GEN24_ADDRESS_OFFSET                  0                              // skip 0 bits\n#define RF_GEN24_ADDRESS_LEN                    10                              // read 10 address bits\n#define RF_GEN24_COMMAND_OFFSET                 10                              // skip 0 + 10 bits\n#define RF_GEN24_COMMAND_LEN                    14                              // read 14 command bits\n#define RF_GEN24_COMPLETE_DATA_LEN              24                              // complete length\n#define RF_GEN24_STOP_BIT                        1                              // has stop bit\n#define RF_GEN24_LSB                             0                              // MSB...LSB\n#define RF_GEN24_FLAGS                           0                              // flags\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RF X10 remote control (MEDION, Pollin 721815)\n *\n * Frame:\n * 1 toggle bit + 7 checksum bits + 1 toggle bit + 7 command bits + 4 channel bits\n *\n * Rule:\n * checksum = (command + 0x0055 + (channel << 4)) & 0x7F\n *\n * Here we store checksum in address, command incl. 4 channel bits in command\n *\n * In irmp_get_data():\n *  irmp_command = command << 4\n *  irmp_address = channel + 1\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RF_X10_START_BIT_PULSE_TIME             2850.0e-6                        // 2850 usec pulse\n#define RF_X10_START_BIT_PAUSE_TIME             1710.0e-6                        // 1710 usec pulse\n#define RF_X10_0_PULSE_TIME                      570.0e-6                        //  570 usec pulse\n#define RF_X10_0_PAUSE_TIME                      570.0e-6                        //  570 usec pause\n#define RF_X10_1_PULSE_TIME                      570.0e-6                        //  570 usec pulse\n#define RF_X10_1_PAUSE_TIME                     1710.0e-6                        // 1710 usec pause\n\n#define RF_X10_FRAME_REPEAT_PAUSE_TIME          4456.0e-6                        // frame repeat after 4460 usec\n#define RF_X10_ADDRESS_OFFSET                    1                               // skip 1st toggle bit\n#define RF_X10_ADDRESS_LEN                       7                               // store 7 command bits in address\n#define RF_X10_COMMAND_OFFSET                    9                               // skip 1st toggle bit + 7 command bits + 2nd toggle bit\n#define RF_X10_COMMAND_LEN                      11                               // read 7 alternative command bits plus 4 0-bits\n#define RF_X10_COMPLETE_DATA_LEN                20                               // complete length\n#define RF_X10_STOP_BIT                          1                               // has stop bit\n#define RF_X10_LSB                               0                               // MSB...LSB\n#define RF_X10_FLAGS                             0                               // flags\n\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * RF MEDION PC remote control (MEDION)\n *\n * Frame is simular to RF_X10, see above. Only the start bit timing differs.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define RF_MEDION_START_BIT_PULSE_TIME          3960.0e-6                        // 3960 usec pulse\n#define RF_MEDION_START_BIT_PAUSE_TIME           610.0e-6                        //  610 usec pulse\n#define RF_MEDION_0_PULSE_TIME                   570.0e-6                        //  570 usec pulse\n#define RF_MEDION_0_PAUSE_TIME                   570.0e-6                        //  570 usec pause\n#define RF_MEDION_1_PULSE_TIME                   570.0e-6                        //  570 usec pulse\n#define RF_MEDION_1_PAUSE_TIME                  1710.0e-6                        // 1710 usec pause\n\n#define RF_MEDION_FRAME_REPEAT_PAUSE_TIME       5000.0e-6                        // frame repeat after 5000 usec\n#define RF_MEDION_ADDRESS_OFFSET                 1                               // skip 1st toggle bit\n#define RF_MEDION_ADDRESS_LEN                    7                               // store 7 command bits in address\n#define RF_MEDION_COMMAND_OFFSET                 9                               // skip 1st toggle bit + 7 command bits + 2nd toggle bit\n#define RF_MEDION_COMMAND_LEN                   11                               // read 7 alternative command bits plus 4 0-bits\n#define RF_MEDION_COMPLETE_DATA_LEN             20                               // complete length\n#define RF_MEDION_STOP_BIT                       1                               // has stop bit\n#define RF_MEDION_LSB                            0                               // MSB...LSB\n#define RF_MEDION_FLAGS                          0                               // flags\n\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Frame Repetitions:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define AUTO_FRAME_REPETITION_TIME              80.0e-3                         // SIRCS/SAMSUNG32/NUBERT: automatic repetition after 25-50ms\n\n#endif // _IRMP_PROTOCOLS_H_\n"
  },
  {
    "path": "src/irmpprotocols.hpp",
    "content": "/*\n * irmpprotocols.hpp - irmp protocols\n *\n *  Copyright (C) 2020-2021  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#ifndef IRMP_PROTOCOLS_HPP\n#define IRMP_PROTOCOLS_HPP\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * IR protocol strings for IRMP and IRSND:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\nconst char proto_unknown[]       PROGMEM = \"UNKNOWN\";\nconst char proto_sircs[]         PROGMEM = \"SIRCS\";\nconst char proto_nec[]           PROGMEM = \"NEC\";\nconst char proto_samsung[]       PROGMEM = \"SAMSUNG\";\nconst char proto_matsushita[]    PROGMEM = \"MATSUSH\";\nconst char proto_kaseikyo[]      PROGMEM = \"KASEIKYO\";\nconst char proto_recs80[]        PROGMEM = \"RECS80\";\nconst char proto_rc5[]           PROGMEM = \"RC5\";\nconst char proto_denon[]         PROGMEM = \"DENON\";\nconst char proto_rc6[]           PROGMEM = \"RC6\";\nconst char proto_samsung32[]     PROGMEM = \"SAMSG32\";\nconst char proto_apple[]         PROGMEM = \"APPLE\";\nconst char proto_recs80ext[]     PROGMEM = \"RECS80EX\";\nconst char proto_nubert[]        PROGMEM = \"NUBERT\";\nconst char proto_bang_olufsen[]  PROGMEM = \"BANG OLU\";\nconst char proto_grundig[]       PROGMEM = \"GRUNDIG\";\nconst char proto_nokia[]         PROGMEM = \"NOKIA\";\nconst char proto_siemens[]       PROGMEM = \"SIEMENS\";\nconst char proto_fdc[]           PROGMEM = \"FDC\";\nconst char proto_rccar[]         PROGMEM = \"RCCAR\";\nconst char proto_jvc[]           PROGMEM = \"JVC\";\nconst char proto_rc6a[]          PROGMEM = \"RC6A\";\nconst char proto_nikon[]         PROGMEM = \"NIKON\";\nconst char proto_ruwido[]        PROGMEM = \"RUWIDO\";\nconst char proto_ir60[]          PROGMEM = \"IR60\";\nconst char proto_kathrein[]      PROGMEM = \"KATHREIN\";\nconst char proto_netbox[]        PROGMEM = \"NETBOX\";\nconst char proto_nec16[]         PROGMEM = \"NEC16\";\nconst char proto_nec42[]         PROGMEM = \"NEC42\";\nconst char proto_lego[]          PROGMEM = \"LEGO\";\nconst char proto_thomson[]       PROGMEM = \"THOMSON\";\nconst char proto_bose[]          PROGMEM = \"BOSE\";\nconst char proto_a1tvbox[]       PROGMEM = \"A1TVBOX\";\nconst char proto_ortek[]         PROGMEM = \"ORTEK\";\nconst char proto_telefunken[]    PROGMEM = \"TELEFUNKEN\";\nconst char proto_roomba[]        PROGMEM = \"ROOMBA\";\nconst char proto_rcmm32[]        PROGMEM = \"RCMM32\";\nconst char proto_rcmm24[]        PROGMEM = \"RCMM24\";\nconst char proto_rcmm12[]        PROGMEM = \"RCMM12\";\nconst char proto_speaker[]       PROGMEM = \"SPEAKER\";\nconst char proto_lgair[]         PROGMEM = \"LGAIR\";\nconst char proto_samsung48[]     PROGMEM = \"SAMSG48\";\nconst char proto_merlin[]        PROGMEM = \"MERLIN\";\nconst char proto_pentax[]        PROGMEM = \"PENTAX\";\nconst char proto_fan[]           PROGMEM = \"FAN\";\nconst char proto_s100[]          PROGMEM = \"S100\";\nconst char proto_acp24[]         PROGMEM = \"ACP24\";\nconst char proto_technics[]      PROGMEM = \"TECHNICS\";\nconst char proto_panasonic[]     PROGMEM = \"PANASONIC\";\nconst char proto_mitsu_heavy[]   PROGMEM = \"MITSU_HEAVY\";\nconst char proto_vincent[]       PROGMEM = \"VINCENT\";\nconst char proto_samsungah[]     PROGMEM = \"SAMSUNGAH\";\nconst char proto_irmp16[]        PROGMEM = \"IRMP16\";\nconst char proto_gree[]          PROGMEM = \"GREE\";\nconst char proto_rcii[]          PROGMEM = \"RCII\";\nconst char proto_metz[]          PROGMEM = \"METZ\";\nconst char proto_onkyo[]         PROGMEM = \"ONKYO\";\n\nconst char proto_rf_gen24[]      PROGMEM = \"RF_GEN24\";\nconst char proto_rf_x10[]        PROGMEM = \"RF_X10\";\nconst char proto_rf_medion[]     PROGMEM = \"RF_MEDION\";\n\nconst char proto_melinera[]      PROGMEM = \"MELINERA\";\nconst char proto_rc6a20[]        PROGMEM = \"RC6A20\";\nconst char proto_rc6a28[]        PROGMEM = \"RC6A28\";\n\n/*\n * Must be in the same order as the Protocol numbers in irmpprotocols.h starting with IRMP_UNKNOWN_PROTOCOL = 0\n */\nconst char * const\nirmp_protocol_names[IRMP_N_PROTOCOLS + 1] PROGMEM =\n{\n    proto_unknown,\n    proto_sircs,\n    proto_nec,\n    proto_samsung,\n    proto_matsushita,\n    proto_kaseikyo,\n    proto_recs80,\n    proto_rc5,\n    proto_denon,\n    proto_rc6,\n    proto_samsung32,\n    proto_apple,\n    proto_recs80ext,\n    proto_nubert,\n    proto_bang_olufsen,\n    proto_grundig,\n    proto_nokia,\n    proto_siemens,\n    proto_fdc,\n    proto_rccar,\n    proto_jvc,\n    proto_rc6a,\n    proto_nikon,\n    proto_ruwido,\n    proto_ir60,\n    proto_kathrein,\n    proto_netbox,\n    proto_nec16,\n    proto_nec42,\n    proto_lego,\n    proto_thomson,\n    proto_bose,\n    proto_a1tvbox,\n    proto_ortek,\n    proto_telefunken,\n    proto_roomba,\n    proto_rcmm32,\n    proto_rcmm24,\n    proto_rcmm12,\n    proto_speaker,\n    proto_lgair,\n    proto_samsung48,\n    proto_merlin,\n    proto_pentax,\n    proto_fan,\n    proto_s100,\n    proto_acp24,\n    proto_technics,\n    proto_panasonic,\n    proto_mitsu_heavy,\n    proto_vincent,\n    proto_samsungah,\n    proto_irmp16,\n    proto_gree,\n    proto_rcii,\n    proto_metz,\n    proto_onkyo,\n\n    proto_rf_gen24,\n    proto_rf_x10,\n    proto_rf_medion,\n\n    proto_melinera,\n    proto_rc6a20,\n    proto_rc6a28\n};\n\n#endif // IRMP_PROTOCOLS_HPP\n"
  },
  {
    "path": "src/irmpsystem.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irmpsystem.h - system specific includes and defines\n *\n * Copyright (c) 2009-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRMPSYSTEM_H_\n#define _IRMPSYSTEM_H_\n\n#if !defined(_IRMP_H_) && !defined(_IRSND_H_)\n#  error please include only irmp.h or irsnd.h, not irmpsystem.h\n#endif\n\n#if defined(ARDUINO)                                                                // AVR Arduino. Should be first, since it covers multiple platforms\n// to avoid the other includes and defines which are incompatible with ARDUINO\n\n#elif defined(__18CXX)                                                                // Microchip PIC C18 compiler\n#  define PIC_C18\n\n#elif defined(__XC8)                                                                // PIC XC8 compiler\n#  include <xc.h>\n#  define PIC_C18\n\n#elif defined(__XC32)                                                               // XC32 or ChipKit compiler\n#  define PIC_XC32\n\n#elif defined(__PCM__) || defined(__PCB__) || defined(__PCH__)                      // CCS PIC compiler\n#  define PIC_CCS\n\n#elif defined(STM32L1XX_MD) || defined(STM32L1XX_MDP) || defined(STM32L1XX_HD)      // ARM STM32\n#  include <stm32l1xx.h>\n#  define ARM_STM32\n#  define ARM_STM32L1XX\n#  define F_CPU (SysCtlClockGet())\n\n#elif defined(STM32F10X_LD) || defined(STM32F10X_LD_VL) \\\n   || defined(STM32F10X_MD) || defined(STM32F10X_MD_VL) \\\n   || defined(STM32F10X_HD) || defined(STM32F10X_HD_VL) \\\n   || defined(STM32F10X_XL) || defined(STM32F10X_CL)                                // ARM STM32\n#  include <stm32f10x.h>\n#  define ARM_STM32\n#  define ARM_STM32F10X\n#  define F_CPU (SysCtlClockGet())\n\n#elif defined(STM32F30X)                                                            // ARM STM32\n#  include <stm32f30x.h>\n#  define ARM_STM32\n#  define ARM_STM32F30X\n#  define F_CPU (SysCtlClockGet())\n\n#elif defined(STM32F4XX)                                                            // ARM STM32\n#  include <stm32f4xx.h>\n#  define ARM_STM32\n#  define ARM_STM32F4XX\n#  define F_CPU (SysCtlClockGet())\n\n#elif defined(STM32L1) ||  defined(STM32F1) || defined(STM32F3) || defined(STM32F4) // ARM STM32 OPENCM3\n#  include <stdint.h>\n#  include <libopencm3/stm32/gpio.h>\n#  include <libopencm3/stm32/timer.h>\n#  include <libopencm3/cm3/nvic.h>\n#  include <libopencm3/stm32/rcc.h>\n#  include \"../config.h\"\n#  define ARM_STM32_OPENCM3\n#  define F_CPU rcc_ahb_frequency\n\n#elif defined(USE_HAL_DRIVER)                                                       // ARM STM32 with HAL Library\n#  include \"gpio.h\"\n#  if defined(_IRSND_H_)\n#    include\"tim.h\"\n#  endif\n#  define ARM_STM32_HAL\n#  define F_CPU SystemCoreClock\n\n#elif defined(__SDCC_stm8)                                                          // STM8\n#  define SDCC_STM8\n\n#elif defined(TARGET_IS_BLIZZARD_RA2)                                               // TI Stellaris (tested on Stellaris Launchpad with Code Composer Studio)\n#  define STELLARIS_ARM_CORTEX_M4\n#  define F_CPU (SysCtlClockGet())\n\n#elif defined(__xtensa__)                                                           // ESP8266 (Arduino)\n#  include \"Arduino.h\"\n#  include \"ets_sys.h\"\n#  include \"osapi.h\"\n#  include \"gpio.h\"\n#  include \"os_type.h\"\n#  include \"c_types.h\"\n#  define uint_fast8_t uint8_t\n#  define uint_fast16_t uint16_t\n\n#elif defined(TEENSYDUINO) && (defined(__MK20DX256__) || defined(__MK20DX128__))    // Teensy 3.x (tested on Teensy 3.1 in Arduino 1.6.5 / Teensyduino 1.2.5)\n#  include <core_pins.h>\n#  define TEENSY_ARM_CORTEX_M4\n\n#elif defined(unix) || defined(WIN32) || defined(__APPLE__)                         // Unix/Linux or Windows or Apple\n#  define UNIX_OR_WINDOWS\n\n#elif defined(__MBED__)                                                             // mbed platform\n// #include \"mbed.h\"                                                                // if mbed.h is used, source must be compiled as cpp\n#include \"gpio_api.h\"\n\n#elif defined(IRMP_CHIBIOS_HAL)                                                     // ChibiOS HAL\n#  include \"hal.h\"\n\n#elif defined(PICO_RP2040)                                                          // rp2040 with the pico-sdk\n#  include \"hardware/clocks.h\"\n#  include \"hardware/pwm.h\"\n#  include \"pico/stdlib.h\"\n#  define F_CPU (clock_get_hz(clk_sys))\n\n#else\n#  define ATMEL_AVR                                                                 // ATMEL AVR\n#endif\n\n#include <string.h>\n\n#if defined(UNIX_OR_WINDOWS)                                                              // Analyze on Unix/Linux or Windows\n#  include <stdio.h>\n#  include <stdlib.h>\n#  define F_CPU 8000000L\n#  define ANALYZE\n#  include <stdint.h>\n#  ifdef _MSC_VER\n#    define IRMP_PACKED_STRUCT\n#  endif\n#endif\n\n#if defined(ARDUINO)                                                                // AVR Arduino. Should be first, since it covers multiple platforms\n// to avoid the other includes and defines which are incompatible with ARDUINO\n\n#elif defined(ATMEL_AVR)\n#  include <stdint.h>\n#  include <stdio.h>\n#  include <avr/io.h>\n#  include <util/delay.h>\n#  include <avr/pgmspace.h>\n#  include <avr/interrupt.h>\n#  define IRSND_OC2                     0       // OC2\n#  define IRSND_OC2A                    1       // OC2A\n#  define IRSND_OC2B                    2       // OC2B\n#  define IRSND_OC0                     3       // OC0\n#  define IRSND_OC0A                    4       // OC0A\n#  define IRSND_OC0B                    5       // OC0B\n\n#  define IRSND_XMEGA_OC0A              0       // OC0A\n#  define IRSND_XMEGA_OC0B              1       // OC0B\n#  define IRSND_XMEGA_OC0C              2       // OC0C\n#  define IRSND_XMEGA_OC0D              3       // OC0D\n#  define IRSND_XMEGA_OC1A              4       // OC1A\n#  define IRSND_XMEGA_OC1B              5       // OC1B\n\n#elif defined(STELLARIS_ARM_CORTEX_M4)\n\n#  include \"inc/hw_ints.h\"\n#  include \"inc/hw_memmap.h\"\n#  include \"inc/hw_types.h\"\n#  include \"inc/hw_gpio.h\"\n#  include \"driverlib/fpu.h\"\n#  include \"driverlib/sysctl.h\"\n#  include \"driverlib/interrupt.h\"\n#  include \"driverlib/gpio.h\"\n#  include \"driverlib/rom.h\"\n#  include \"driverlib/systick.h\"\n#  include \"driverlib/pin_map.h\"\n#  include \"driverlib/timer.h\"\n#  define PROGMEM\n#  define memcpy_P                      memcpy\n#  define APP_SYSTICKS_PER_SEC          32\n\n#elif defined(ARM_STM32F10X)\n\n#  include \"stm32f10x_gpio.h\"\n#  include \"stm32f10x_rcc.h\"\n#  include \"stm32f10x_tim.h\"\n#  include \"misc.h\"\n#  define PROGMEM\n#  define memcpy_P                      memcpy\n\n#elif defined(SDCC_STM8)\n\n#  include \"stm8s.h\"\n#  define PROGMEM\n#  define memcpy_P                      memcpy\n#  define __attribute__(x)\n#  define uint_fast8_t                  uint8_t\n#  define uint_fast16_t                 uint16_t\n\n#elif defined(TEENSY_ARM_CORTEX_M4)\n#  define PROGMEM\n#  define memcpy_P                      memcpy\n\n#elif defined(__xtensa__)\n#  define PROGMEM\n#  define memcpy_P                      memcpy\n\n#elif defined(__MBED__)\n#  define PROGMEM\n#  define memcpy_P                      memcpy\n\n#else\n#  if ! defined(PROGMEM)\n#    define PROGMEM\n#  endif\n#  if ! defined(memcpy_P)\n#    define memcpy_P                      memcpy\n#  endif\n\n#endif\n\n#if defined(PIC_CCS) || defined(PIC_C18)\ntypedef unsigned char                   uint8_t;\ntypedef unsigned short                  uint16_t;\ntypedef unsigned char                   uint_fast8_t;\ntypedef unsigned short                  uint_fast16_t;\n#endif\n\n#if defined (PIC_C18)                                                               // PIC C18 or XC8 compiler\n#  include <p18cxxx.h>                                                              // main PIC18 h file\n#ifndef __XC8\n#  include <timers.h>                                                               // timer lib\n#  include <pwm.h>                                                                  // pwm lib\n#endif\n#  define IRSND_PIC_CCP1                1                                           // PIC C18 RC2 = PWM1 module\n#  define IRSND_PIC_CCP2                2                                           // PIC C18 RC1 = PWM2 module\n#endif\n\n#if !defined(TRUE)\n#  define TRUE                          1\n#  define FALSE                         0\n#endif\n\n#if defined(PIC_XC32)                                                               // XC32 or ChipKit compiler\n#  include <xc.h>\n#  include <stdint.h>\n#endif\n\n#if defined(PIC_C18)\n#  define IRMP_PACKED_STRUCT\n#else\n#  if !defined(IRMP_PACKED_STRUCT)\n#    define IRMP_PACKED_STRUCT          __attribute__ ((__packed__))\n#  endif\n#endif\n\ntypedef struct IRMP_PACKED_STRUCT IRMP_DATA\n{\n    uint8_t                             protocol;                                   // protocol, e.g. IRMP_NEC_PROTOCOL\n    uint16_t                            address;                                    // address\n    uint16_t                            command;                                    // command\n    uint8_t                             flags;                                      // flags, e.g. repetition\n} IRMP_DATA;\n\n#endif // _IRMPSYSTEM_H_\n"
  },
  {
    "path": "src/irsnd.h",
    "content": " /*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irsnd.h\n *\n * Copyright (c) 2010-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRSND_H_\n#define _IRSND_H_\n\n#include \"irmpsystem.h\"\n#if !defined(IRSND_USE_AS_LIB)\n#  include \"irsndconfig.h\"\n#endif\n\n#if defined(ARDUINO)\n#  include \"irsndArduinoExt.h\"\n\n#elif defined (ARM_STM32)                         // STM32\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRSND_PORT                            CONCAT(GPIO, IRSND_PORT_LETTER)\n#  if defined (ARM_STM32L1XX)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_AHBPeriph_GPIO, IRSND_PORT_LETTER)\n#    define IRSND_GPIO_AF                       CONCAT(GPIO_AF_TIM, IRSND_TIMER_NUMBER)\n#  elif defined (ARM_STM32F10X)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_APB2Periph_GPIO, IRSND_PORT_LETTER)\n#  elif  defined (ARM_STM32F30X)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_AHBPeriph_GPIO, IRSND_PORT_LETTER)\n#  elif defined (ARM_STM32F4XX)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_AHB1Periph_GPIO, IRSND_PORT_LETTER)\n#    define IRSND_GPIO_AF                       CONCAT(GPIO_AF_TIM, IRSND_TIMER_NUMBER)\n#  endif\n#  define IRSND_BIT                             CONCAT(GPIO_Pin_, IRSND_BIT_NUMBER)\n#  define IRSND_TIMER                           CONCAT(TIM, IRSND_TIMER_NUMBER)\n#  define IRSND_TIMER_CHANNEL                   CONCAT(TIM_Channel_, IRSND_TIMER_CHANNEL_NUMBER)\n#  if ((IRSND_TIMER_NUMBER >= 2) && (IRSND_TIMER_NUMBER <= 5)) || ((IRSND_TIMER_NUMBER >= 12) && (IRSND_TIMER_NUMBER <= 14))\n#    define IRSND_TIMER_RCC                     CONCAT(RCC_APB1Periph_TIM, IRSND_TIMER_NUMBER)\n#  elif (IRSND_TIMER_NUMBER == 1) || ((IRSND_TIMER_NUMBER >= 8) && (IRSND_TIMER_NUMBER <= 11))\n#    define IRSND_TIMER_RCC                     CONCAT(RCC_APB2Periph_TIM, IRSND_TIMER_NUMBER)\n#  else\n#    error IRSND_TIMER_NUMBER not valid.\n#  endif\n#  if !defined(USE_STDPERIPH_DRIVER)\n#    warning The STM32 port of IRSND uses the ST standard peripheral drivers which are not enabled in your build configuration.\n#  endif\n\n#elif defined (ARM_STM32_OPENCM3)                 // STM32_OPENCM3\n#  define _CONCAT(a,b)                          a##b\n#  define CONCAT(a,b)                           _CONCAT(a,b)\n#  define IRSND_PORT                            CONCAT(GPIO, IRSND_PORT_LETTER)\n#  if defined (ARM_STM32L1)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_GPIO, IRSND_PORT_LETTER)\n#    define IRSND_GPIO_AF                       CONCAT(GPIO_AF_TIM, IRSND_TIMER_NUMBER)\n#  elif defined (STM32F1)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_GPIO, IRSND_PORT_LETTER)\n#  elif  defined (ARM_STM32F3)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_GPIO, IRSND_PORT_LETTER)\n#  elif defined (ARM_STM32F4)\n#    define IRSND_PORT_RCC                      CONCAT(RCC_GPIO, IRSND_PORT_LETTER)\n#    define IRSND_GPIO_AF                       CONCAT(GPIO_AF_TIM, IRSND_TIMER_NUMBER)\n#  endif\n#  define IRSND_BIT                             CONCAT(GPIO, IRSND_BIT_NUMBER)\n#  define IRSND_TIMER                           CONCAT(TIM, IRSND_TIMER_NUMBER)\n#  define IRSND_TIMER_CHANNEL                   CONCAT(TIM_OC, IRSND_TIMER_CHANNEL_NUMBER)\n#  if ((IRSND_TIMER_NUMBER >= 2) && (IRSND_TIMER_NUMBER <= 5)) || ((IRSND_TIMER_NUMBER >= 12) && (IRSND_TIMER_NUMBER <= 14))\n#    define IRSND_TIMER_RCC                     CONCAT(RCC_TIM, IRSND_TIMER_NUMBER)\n#  elif (IRSND_TIMER_NUMBER == 1) || ((IRSND_TIMER_NUMBER >= 8) && (IRSND_TIMER_NUMBER <= 11))\n#    define IRSND_TIMER_RCC                     CONCAT(RCC_TIM, IRSND_TIMER_NUMBER)\n#  else\n#    error IRSND_TIMER_NUMBER not valid.\n#  endif\n\n#elif defined (ARDUINO_ARCH_RP2040)               // ARDUINO_ARCH_RP2040\n#  define IRSND_BIT                             IRSND_BIT_NUMBER\n\n#elif defined(PIC_C18)\n\n# if defined(__12F1840)\n    // Do not change lines below unless you have a different HW. This example is for 12F1840\n    // setup macro for PWM used PWM module\n\n    //~ #    define PWMon()                         TMR2=0,IRSND_PIN=1\n    //~ #    define PWMoff()                        CCP1CON &=(~0b1100)\n    //~ #    define PWMon()                         TMR2ON=1\n    //~ #    define PWMoff()                        TMR2ON=0\n    #if defined(IRSND_DEBUG)\n        #define PWMon()                             LATA0=1\n        #define PWMoff()                            LATA0=0\n        #define IRSND_PIN                           LATA0\n    #else\n        #    define PWMon()                         TMR2=0,CCP1CON |=0b1100\n        #    define PWMoff()                        CCP1CON &=(~0b1100)\n        #    define IRSND_PIN                       RA2\n    #endif\n\n#else\n    // Do not change lines below until you have a different HW. Example is for 18F2550/18F4550\n    // setup macro for PWM used PWM module\n    #  if IRSND_OCx == IRSND_PIC_CCP2\n    #    define PWMon()                             TMR2=0,CCP2CON |=0b1100\n    #    define PWMoff()                            CCP2CON &=(~0b1100)\n    #    define IRSND_PIN                           TRISCbits.TRISC1        // RC1 = PWM2\n    #    define SetDCPWM(x)                         SetDCPWM2(x)\n    #    define ClosePWM                            ClosePWM2\n    #    define OpenPWM(x)                          OpenPWM2(x)\n    #  endif\n    #  if IRSND_OCx == IRSND_PIC_CCP1\n    #    define PWMon()                             TMR2=0,CCP1CON |=0b1100\n    #    define PWMoff()                            CCP1CON &=(~0b1100)\n    #    define IRSND_PIN                           TRISCbits.TRISC2        // RC2 = PWM1\n    #    define SetDCPWM(x)                         SetDCPWM1(x)\n    #    define ClosePWM                            ClosePWM1\n    #    define OpenPWM(x)                          OpenPWM1(x)\n    # endif\n# endif\n#  endif // PIC_C18\n\n#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, SIEMENS protocol disabled (should be at least 15000)\n#  undef IRSND_SUPPORT_SIEMENS_PROTOCOL\n#  define IRSND_SUPPORT_SIEMENS_PROTOCOL        0\n#endif\n\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, A1TVBOX protocol disabled (should be at least 15000)\n#  undef IRSND_SUPPORT_A1TVBOX_PROTOCOL\n#  define IRSND_SUPPORT_A1TVBOX_PROTOCOL        0\n#endif\n\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, RECS80 protocol disabled (should be at least 15000)\n#  undef IRSND_SUPPORT_RECS80_PROTOCOL\n#  define IRSND_SUPPORT_RECS80_PROTOCOL         0\n#endif\n\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 && F_INTERRUPTS < 15000\n#  warning F_INTERRUPTS too low, RECS80EXT protocol disabled (should be at least 15000)\n#  undef IRSND_SUPPORT_RECS80EXT_PROTOCOL\n#  define IRSND_SUPPORT_RECS80EXT_PROTOCOL      0\n#endif\n\n#if IRSND_SUPPORT_LEGO_PROTOCOL == 1 && F_INTERRUPTS < 19000\n#  warning F_INTERRUPTS too low, LEGO protocol disabled (should be at least 19000)\n#  undef IRSND_SUPPORT_LEGO_PROTOCOL\n#  define IRSND_SUPPORT_LEGO_PROTOCOL           0\n#endif\n\n#include \"irmpprotocols.h\"\n\n#define IRSND_NO_REPETITIONS                     0      // no repetitions\n#define IRSND_MAX_REPETITIONS                   14      // max # of repetitions\n#define IRSND_ENDLESS_REPETITION                15      // endless repetitions\n#define IRSND_REPETITION_MASK                   0x0F    // lower nibble of flags\n#define IRSND_RAW_REPETITION_FRAME              0x10    // send one or more raw repetition frames, yet only used for NEC\n#define IRSND_SUPPRESS_TRAILER                  0x20    // suppress trailer\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\nextern void                                     irsnd_init (void);\n#  ifdef __cplusplus\nextern bool                                     irsnd_is_busy (void);\nextern bool                                     irsnd_send_data (IRMP_DATA *, uint8_t);\nextern bool                                     irsnd_ISR (void);\n#else\nextern uint8_t                                  irsnd_is_busy (void);\nextern uint8_t                                  irsnd_send_data (IRMP_DATA *, uint8_t);\nextern uint8_t                                  irsnd_ISR (void);\n#endif\nextern void                                     irsnd_stop (void);\n\n#if IRSND_USE_CALLBACK == 1\nextern void                                     irsnd_set_callback_ptr (void (*cb)(uint8_t));\n#endif // IRSND_USE_CALLBACK == 1\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _IRSND_H_ */\n"
  },
  {
    "path": "src/irsnd.hpp",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * @file irsnd.c\n *\n * Copyright (c) 2010-2020 Frank Meyer - frank(at)fli4l.de\n *\n * Supported AVR mikrocontrollers:\n *\n * ATtiny87,  ATtiny167\n * ATtiny45,  ATtiny85\n * ATtiny44   ATtiny84\n * ATtiny2313 ATtiny4313\n * ATmega8,   ATmega16,  ATmega32\n * ATmega162\n * ATmega164, ATmega324, ATmega644,  ATmega644P, ATmega1284, ATmega1284P\n * ATmega88,  ATmega88P, ATmega168,  ATmega168P, ATmega328P\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#include \"irsnd.h\"\n\n#if !defined(F_CPU)\n#  error F_CPU unkown\n#endif\n\n#define IRMP_NEC_REPETITION_PROTOCOL                0xFF            // pseudo protocol: NEC repetition frame\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  ATtiny pin definition of OC0A / OC0B\n *  ATmega pin definition of OC2 / OC2A / OC2B / OC0 / OC0A / OC0B\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny84__)        // ATtiny44/84 uses OC0A = PB2 or OC0B = PA7\n#  if IRSND_OCx == IRSND_OC0A                                       // OC0A\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        2\n#  elif IRSND_OCx == IRSND_OC0B                                     // OC0B\n#    define IRSND_PORT_LETTER                       A\n#    define IRSND_BIT_NUMBER                        7\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)      // ATtiny45/85 uses OC0A = PB0 or OC0B = PB1\n#  if IRSND_OCx == IRSND_OC0A                                       // OC0A\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        0\n#  elif IRSND_OCx == IRSND_OC0B                                     // OC0B\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        1\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATtiny2313__) || defined (__AVR_ATtiny4313__)  // ATtiny2313/4313 uses OC0A = PB2 or OC0B = PD5\n#  if IRSND_OCx == IRSND_OC0A                                       // OC0A\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        2\n#  elif IRSND_OCx == IRSND_OC0B                                     // OC0B\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        5\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC0A or IRSND_OC0B in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATtiny87__) || defined (__AVR_ATtiny167__)     // ATtiny87/167 uses OC0A = PA2\n#  if IRSND_OCx == IRSND_OC0A                                       // OC0A\n#    define IRSND_PORT_LETTER                       A\n#    define IRSND_BIT_NUMBER                        2\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC0A in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATmega8__)                                     // ATmega8 uses only OC2 = PB3\n#  if IRSND_OCx == IRSND_OC2                                        // OC2\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        3\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC2 in irsndconfig.h\n#  endif // IRSND_OCx\n#elif defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__)      // ATmega16|32 uses OC0 = PB3 or OC2 = PD7\n#  if IRSND_OCx == IRSND_OC2                                        // OC2\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        7\n#  elif IRSND_OCx == IRSND_OC0                                      // OC0\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        3\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC2 or IRSND_OC0 in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATmega162__)                                   // ATmega162 uses OC2 = PB1 or OC0 = PB0\n#  if IRSND_OCx == IRSND_OC2                                        // OC2\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        1\n#  elif IRSND_OCx == IRSND_OC0                                      // OC0\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        0\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC2 or IRSND_OC0 in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATmega164__)   \\\n   || defined (__AVR_ATmega324__)   \\\n   || defined (__AVR_ATmega644__)   \\\n   || defined (__AVR_ATmega644P__)  \\\n   || defined (__AVR_ATmega1284__)  \\\n   || defined (__AVR_ATmega1284P__)                                 // ATmega164|324|644|644P|1284 uses OC2A = PD7 or OC2B = PD6 or OC0A = PB3 or OC0B = PB4\n#  if IRSND_OCx == IRSND_OC2A                                       // OC2A\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        7\n#  elif IRSND_OCx == IRSND_OC2B                                     // OC2B\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        6\n#  elif IRSND_OCx == IRSND_OC0A                                     // OC0A\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        3\n#  elif IRSND_OCx == IRSND_OC0B                                     // OC0B\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        4\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC2A, IRSND_OC2B, IRSND_OC0A, or IRSND_OC0B in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATmega48__)    \\\n   || defined (__AVR_ATmega88__)    \\\n   || defined (__AVR_ATmega88P__)   \\\n   || defined (__AVR_ATmega168__)   \\\n   || defined (__AVR_ATmega168P__)  \\\n   || defined (__AVR_ATmega328P__)                                  // ATmega48|88|168|168|328 uses OC2A = PB3 or OC2B = PD3 or OC0A = PD6 or OC0B = PD5\n#  if IRSND_OCx == IRSND_OC2A                                       // OC2A\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        3\n#  elif IRSND_OCx == IRSND_OC2B                                     // OC2B\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        3\n#  elif IRSND_OCx == IRSND_OC0A                                     // OC0A\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        6\n#  elif IRSND_OCx == IRSND_OC0B                                     // OC0B\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        5\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_OC2A, IRSND_OC2B, IRSND_OC0A, or IRSND_OC0B in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_ATmega8515__)                                  // ATmega8515 uses OC0 = PB0 or OC1A = PD5 or OC1B = PE2\n#  if IRSND_OCx == IRSND_OC0\n#    define IRSND_PORT_LETTER                       B\n#    define IRSND_BIT_NUMBER                        0\n#  elif IRSND_OCx == IRSND_OC1A\n#    define IRSND_PORT_LETTER                       D\n#    define IRSND_BIT_NUMBER                        5\n#  elif IRSND_OCx == IRSND_OC1B\n#    define IRSND_PORT_LETTER                       E\n#    define IRSND_BIT_NUMBER                        2\n#  endif // IRSND_OCx\n\n#elif defined (__AVR_XMEGA__)                                       // ATxmega\n#  if IRSND_OCx == IRSND_XMEGA_OC0A\n#    define IRSND_BIT_NUMBER                        0\n#  elif IRSND_OCx == IRSND_XMEGA_OC0B\n#    define IRSND_BIT_NUMBER                        1\n#  elif IRSND_OCx == IRSND_XMEGA_OC0C\n#    define IRSND_BIT_NUMBER                        2\n#  elif IRSND_OCx == IRSND_XMEGA_OC0D\n#    define IRSND_BIT_NUMBER                        3\n#  elif IRSND_OCx == IRSND_XMEGA_OC1A\n#    define IRSND_BIT_NUMBER                        4\n#  elif IRSND_OCx == IRSND_XMEGA_OC1B\n#    define IRSND_BIT_NUMBER                        5\n#  else\n#    error Wrong value for IRSND_OCx, choose IRSND_XMEGA_OC0A, IRSND_XMEGA_OC0B, IRSND_XMEGA_OC0C, IRSND_XMEGA_OC0D, IRSND_XMEGA_OC1A, or IRSND_XMEGA_OC1B in irsndconfig.h\n#  endif // IRSND_OCx\n\n#elif defined (PIC_C18)                                                 // Microchip C18 compiler\n    //Nothing here to do here -> See irsndconfig.h\n#elif defined (ARM_STM32)                                               // STM32\n    //Nothing here to do here -> See irsndconfig.h\n#elif defined (ARM_STM32_OPENCM3)                                       // STM32_OPENCM3\n    //Nothing here to do here -> See irsndconfig.h\n#elif defined (ARM_STM32_HAL)                                           // STM32 with Hal Library\n    //Nothing here to do here -> See irsndconfig.h\n#elif defined (ARDUINO_ARCH_RP2040)                                     // ARDUINO_ARCH_RP2040\n    uint slice_num;\n#elif defined (__xtensa__)                                              // ESP8266\n    //Nothing here to do here -> See irsndconfig.h\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Macro digitalPinHasPWM bothers PIC_C18 compiler, but why?\n *\n * #elif defined (TEENSY_ARM_CORTEX_M4)                                // Teensy3\n * #  if !digitalPinHasPWM(IRSND_PIN)\n * #    error need pin with PWM output.\n * #  endif\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n #elif defined(ARDUINO)\n// specified here to avoid else case\n\n#else\n#  if !defined (unix) && !defined (WIN32)\n#    error mikrocontroller not defined, please fill in definitions here.\n#  endif // unix, WIN32\n#endif // __AVR...\n\n#if defined(__AVR_XMEGA__)\n#  define _CONCAT(a,b)                              a##b\n#  define CONCAT(a,b)                               _CONCAT(a,b)\n#  define IRSND_PORT                                IRSND_PORT_PRE.OUT\n#  define IRSND_DDR                                 IRSND_PORT_PRE.DIR\n#  define IRSND_PIN                                 IRSND_PORT_PRE.IN\n#  define IRSND_BIT                                 IRSND_BIT_NUMBER\n#elif defined(ATMEL_AVR)\n#  define _CONCAT(a,b)                              a##b\n#  define CONCAT(a,b)                               _CONCAT(a,b)\n#  define IRSND_PORT                                CONCAT(PORT, IRSND_PORT_LETTER)\n#  define IRSND_DDR                                 CONCAT(DDR, IRSND_PORT_LETTER)\n#  define IRSND_BIT                                 IRSND_BIT_NUMBER\n#endif\n\n#if IRSND_SUPPORT_NIKON_PROTOCOL == 1\ntypedef uint16_t IRSND_PAUSE_LEN;\n#else\ntypedef uint8_t IRSND_PAUSE_LEN;\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  IR timings\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRSND_SIRCS_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_SIRCS_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_SIRCS_1_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)\n#define IRSND_SIRCS_0_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)\n#define IRSND_SIRCS_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)\n#define IRSND_SIRCS_AUTO_REPETITION_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * SIRCS_AUTO_REPETITION_PAUSE_TIME + 0.5)               // use uint16_t!\n#define IRSND_SIRCS_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_REPEAT_PAUSE_TIME + 0.5)                  // use uint16_t!\n\n#define IRSND_NEC_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_NEC_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_NEC_REPEAT_START_BIT_PAUSE_LEN        (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_NEC_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)\n#define IRSND_NEC_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)\n#define IRSND_NEC_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)\n#define IRSND_NEC_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME + 0.5)                    // use uint16_t!\n\n#define IRSND_MELINERA_START_BIT_PULSE_LEN          (uint8_t)(F_INTERRUPTS * MELINERA_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_MELINERA_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * MELINERA_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_MELINERA_REPEAT_START_BIT_PAUSE_LEN   (uint8_t)(F_INTERRUPTS * MELINERA_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_MELINERA_1_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * MELINERA_1_PULSE_TIME + 0.5)\n#define IRSND_MELINERA_0_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * MELINERA_0_PULSE_TIME + 0.5)\n#define IRSND_MELINERA_1_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * MELINERA_1_PAUSE_TIME + 0.5)\n#define IRSND_MELINERA_0_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * MELINERA_0_PAUSE_TIME + 0.5)\n#define IRSND_MELINERA_FRAME_REPEAT_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * MELINERA_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\n\n#define IRSND_SAMSUNG_START_BIT_PULSE_LEN           (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_SAMSUNG_START_BIT_PAUSE_LEN           (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_SAMSUNG_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)\n#define IRSND_SAMSUNG_1_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)\n#define IRSND_SAMSUNG_0_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)\n#define IRSND_SAMSUNG_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * SAMSUNG_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#define IRSND_SAMSUNG32_AUTO_REPETITION_PAUSE_LEN   (uint16_t)(F_INTERRUPTS * SAMSUNG32_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\n#define IRSND_SAMSUNG32_FRAME_REPEAT_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_SAMSUNG48_AUTO_REPETITION_PAUSE_LEN   (uint16_t)(F_INTERRUPTS * SAMSUNG48_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\n#define IRSND_SAMSUNG48_FRAME_REPEAT_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * SAMSUNG48_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_MATSUSHITA_START_BIT_PULSE_LEN        (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_MATSUSHITA_START_BIT_PAUSE_LEN        (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_MATSUSHITA_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)\n#define IRSND_MATSUSHITA_1_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)\n#define IRSND_MATSUSHITA_0_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)\n#define IRSND_MATSUSHITA_FRAME_REPEAT_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * MATSUSHITA_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!\n\n#define IRSND_KASEIKYO_START_BIT_PULSE_LEN          (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_KASEIKYO_START_BIT_PAUSE_LEN          (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_KASEIKYO_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME + 0.5)\n#define IRSND_KASEIKYO_1_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME + 0.5)\n#define IRSND_KASEIKYO_0_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME + 0.5)\n#define IRSND_KASEIKYO_AUTO_REPETITION_PAUSE_LEN    (uint16_t)(F_INTERRUPTS * KASEIKYO_AUTO_REPETITION_PAUSE_TIME + 0.5)            // use uint16_t!\n#define IRSND_KASEIKYO_FRAME_REPEAT_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * KASEIKYO_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\n\n#define IRSND_PANASONIC_START_BIT_PULSE_LEN         (uint8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_PANASONIC_START_BIT_PAUSE_LEN         (uint8_t)(F_INTERRUPTS * PANASONIC_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_PANASONIC_PULSE_LEN                   (uint8_t)(F_INTERRUPTS * PANASONIC_PULSE_TIME + 0.5)\n#define IRSND_PANASONIC_1_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * PANASONIC_1_PAUSE_TIME + 0.5)\n#define IRSND_PANASONIC_0_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * PANASONIC_0_PAUSE_TIME + 0.5)\n#define IRSND_PANASONIC_AUTO_REPETITION_PAUSE_LEN   (uint16_t)(F_INTERRUPTS * PANASONIC_AUTO_REPETITION_PAUSE_TIME + 0.5)           // use uint16_t!\n#define IRSND_PANASONIC_FRAME_REPEAT_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * PANASONIC_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_MITSU_HEAVY_START_BIT_PULSE_LEN       (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_MITSU_HEAVY_START_BIT_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_MITSU_HEAVY_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_PULSE_TIME + 0.5)\n#define IRSND_MITSU_HEAVY_1_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_1_PAUSE_TIME + 0.5)\n#define IRSND_MITSU_HEAVY_0_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * MITSU_HEAVY_0_PAUSE_TIME + 0.5)\n#define IRSND_MITSU_HEAVY_FRAME_REPEAT_PAUSE_LEN    (uint16_t)(F_INTERRUPTS * MITSU_HEAVY_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!\n\n#define IRSND_RECS80_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_RECS80_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_RECS80_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)\n#define IRSND_RECS80_1_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)\n#define IRSND_RECS80_0_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)\n#define IRSND_RECS80_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * RECS80_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\n\n#define IRSND_RC5_START_BIT_LEN                     (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)\n#define IRSND_RC5_BIT_LEN                           (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)\n#define IRSND_RC5_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * RC5_FRAME_REPEAT_PAUSE_TIME + 0.5)                    // use uint16_t!\n\n#define IRSND_RC6_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_RC6_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_RC6_BIT_LEN                           (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)\n#define IRSND_RC6_BIT_2_LEN                         (uint8_t)(F_INTERRUPTS * RC6_BIT_2_TIME + 0.5)\n#define IRSND_RC6_BIT_3_LEN                         (uint8_t)(F_INTERRUPTS * RC6_BIT_3_TIME + 0.5)\n#define IRSND_RC6_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * RC6_FRAME_REPEAT_PAUSE_TIME + 0.5)                    // use uint16_t!\n\n#define IRSND_DENON_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)\n#define IRSND_DENON_1_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)\n#define IRSND_DENON_0_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)\n#define IRSND_DENON_AUTO_REPETITION_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME + 0.5)               // use uint16_t!\n#define IRSND_DENON_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * DENON_FRAME_REPEAT_PAUSE_TIME + 0.5)                  // use uint16_t!\n\n#define IRSND_THOMSON_PULSE_LEN                     (uint8_t)(F_INTERRUPTS * THOMSON_PULSE_TIME + 0.5)\n#define IRSND_THOMSON_1_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * THOMSON_1_PAUSE_TIME + 0.5)\n#define IRSND_THOMSON_0_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * THOMSON_0_PAUSE_TIME + 0.5)\n#define IRSND_THOMSON_AUTO_REPETITION_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * THOMSON_AUTO_REPETITION_PAUSE_TIME + 0.5)             // use uint16_t!\n#define IRSND_THOMSON_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * THOMSON_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#define IRSND_RECS80EXT_START_BIT_PULSE_LEN         (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_RECS80EXT_START_BIT_PAUSE_LEN         (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_RECS80EXT_PULSE_LEN                   (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)\n#define IRSND_RECS80EXT_1_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)\n#define IRSND_RECS80EXT_0_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)\n#define IRSND_RECS80EXT_FRAME_REPEAT_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * RECS80EXT_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_TELEFUNKEN_START_BIT_PULSE_LEN        (uint8_t)(F_INTERRUPTS * TELEFUNKEN_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_TELEFUNKEN_START_BIT_PAUSE_LEN        (uint8_t)(F_INTERRUPTS * TELEFUNKEN_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_TELEFUNKEN_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * TELEFUNKEN_PULSE_TIME + 0.5)\n#define IRSND_TELEFUNKEN_1_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * TELEFUNKEN_1_PAUSE_TIME + 0.5)\n#define IRSND_TELEFUNKEN_0_PAUSE_LEN                (uint8_t)(F_INTERRUPTS * TELEFUNKEN_0_PAUSE_TIME + 0.5)\n#define IRSND_TELEFUNKEN_AUTO_REPETITION_PAUSE_LEN  (uint16_t)(F_INTERRUPTS * TELEFUNKEN_AUTO_REPETITION_PAUSE_TIME + 0.5)          // use uint16_t!\n#define IRSND_TELEFUNKEN_FRAME_REPEAT_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * TELEFUNKEN_FRAME_REPEAT_PAUSE_TIME + 0.5)             // use uint16_t!\n\n#define IRSND_BOSE_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * BOSE_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_BOSE_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * BOSE_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_BOSE_PULSE_LEN                        (uint8_t)(F_INTERRUPTS * BOSE_PULSE_TIME + 0.5)\n#define IRSND_BOSE_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * BOSE_1_PAUSE_TIME + 0.5)\n#define IRSND_BOSE_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * BOSE_0_PAUSE_TIME + 0.5)\n#define IRSND_BOSE_AUTO_REPETITION_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * BOSE_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\n#define IRSND_BOSE_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * BOSE_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\n\n#define IRSND_NUBERT_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_NUBERT_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_NUBERT_1_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)\n#define IRSND_NUBERT_1_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)\n#define IRSND_NUBERT_0_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)\n#define IRSND_NUBERT_0_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)\n#define IRSND_NUBERT_AUTO_REPETITION_PAUSE_LEN      (uint16_t)(F_INTERRUPTS * NUBERT_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\n#define IRSND_NUBERT_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\n\n#define IRSND_FAN_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * FAN_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_FAN_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * FAN_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_FAN_1_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * FAN_1_PULSE_TIME + 0.5)\n#define IRSND_FAN_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * FAN_1_PAUSE_TIME + 0.5)\n#define IRSND_FAN_0_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * FAN_0_PULSE_TIME + 0.5)\n#define IRSND_FAN_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * FAN_0_PAUSE_TIME + 0.5)\n#define IRSND_FAN_AUTO_REPETITION_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * FAN_AUTO_REPETITION_PAUSE_TIME + 0.5)              // use uint16_t!\n#define IRSND_FAN_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * FAN_FRAME_REPEAT_PAUSE_TIME + 0.5)                 // use uint16_t!\n\n#define IRSND_SPEAKER_START_BIT_PULSE_LEN           (uint8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_SPEAKER_START_BIT_PAUSE_LEN           (uint8_t)(F_INTERRUPTS * SPEAKER_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_SPEAKER_1_PULSE_LEN                   (uint8_t)(F_INTERRUPTS * SPEAKER_1_PULSE_TIME + 0.5)\n#define IRSND_SPEAKER_1_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * SPEAKER_1_PAUSE_TIME + 0.5)\n#define IRSND_SPEAKER_0_PULSE_LEN                   (uint8_t)(F_INTERRUPTS * SPEAKER_0_PULSE_TIME + 0.5)\n#define IRSND_SPEAKER_0_PAUSE_LEN                   (uint8_t)(F_INTERRUPTS * SPEAKER_0_PAUSE_TIME + 0.5)\n#define IRSND_SPEAKER_AUTO_REPETITION_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * SPEAKER_AUTO_REPETITION_PAUSE_TIME + 0.5)             // use uint16_t!\n#define IRSND_SPEAKER_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * SPEAKER_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#define IRSND_BANG_OLUFSEN_START_BIT1_PULSE_LEN     (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_START_BIT1_PAUSE_LEN     (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_START_BIT2_PULSE_LEN     (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_START_BIT2_PAUSE_LEN     (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_START_BIT3_PULSE_LEN     (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_START_BIT3_PAUSE_LEN     (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_PULSE_LEN                (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_1_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_0_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_R_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN    (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)\n#define IRSND_BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN   (uint16_t)(F_INTERRUPTS * BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME + 0.5)           // use uint16_t!\n\n#define IRSND_GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN      (uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_PRE_PAUSE_TIME + 0.5)\n#define IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN            (uint8_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_BIT_TIME + 0.5)\n#define IRSND_GRUNDIG_AUTO_REPETITION_PAUSE_LEN     (uint16_t)(F_INTERRUPTS * GRUNDIG_AUTO_REPETITION_PAUSE_TIME + 0.5)             // use uint16_t!\n#define IRSND_NOKIA_AUTO_REPETITION_PAUSE_LEN       (uint16_t)(F_INTERRUPTS * NOKIA_AUTO_REPETITION_PAUSE_TIME + 0.5)               // use uint16_t!\n#define IRSND_GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_TIME + 0.5)   // use uint16_t!\n\n#define IRSND_IR60_AUTO_REPETITION_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * IR60_AUTO_REPETITION_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#define IRSND_SIEMENS_START_BIT_LEN                 (uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_SIEMENS_BIT_LEN                       (uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME + 0.5)\n#define IRSND_SIEMENS_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_FRAME_REPEAT_PAUSE_TIME + 0.5)      // use uint16_t!\n\n#define IRSND_RUWIDO_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_RUWIDO_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_RUWIDO_BIT_PULSE_LEN                  (uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PULSE_TIME + 0.5)\n#define IRSND_RUWIDO_BIT_PAUSE_LEN                  (uint8_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_BIT_PAUSE_TIME + 0.5)\n#define IRSND_RUWIDO_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * SIEMENS_OR_RUWIDO_FRAME_REPEAT_PAUSE_TIME + 0.5)      // use uint16_t!\n\n#define IRSND_FDC_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_FDC_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_FDC_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME + 0.5)\n#define IRSND_FDC_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME + 0.5)\n#define IRSND_FDC_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME + 0.5)\n#define IRSND_FDC_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * FDC_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#define IRSND_RCCAR_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_RCCAR_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_RCCAR_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME + 0.5)\n#define IRSND_RCCAR_1_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME + 0.5)\n#define IRSND_RCCAR_0_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME + 0.5)\n#define IRSND_RCCAR_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * RCCAR_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_JVC_START_BIT_PULSE_LEN               (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_JVC_START_BIT_PAUSE_LEN               (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_JVC_REPEAT_START_BIT_PAUSE_LEN        (uint8_t)(F_INTERRUPTS * JVC_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_JVC_PULSE_LEN                         (uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME + 0.5)\n#define IRSND_JVC_1_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME + 0.5)\n#define IRSND_JVC_0_PAUSE_LEN                       (uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME + 0.5)\n#define IRSND_JVC_FRAME_REPEAT_PAUSE_LEN            (uint16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#define IRSND_NIKON_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_NIKON_START_BIT_PAUSE_LEN             (uint16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_NIKON_REPEAT_START_BIT_PAUSE_LEN      (uint8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_NIKON_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * NIKON_PULSE_TIME + 0.5)\n#define IRSND_NIKON_1_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME + 0.5)\n#define IRSND_NIKON_0_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME + 0.5)\n#define IRSND_NIKON_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_LEGO_START_BIT_PULSE_LEN              (uint8_t)(F_INTERRUPTS * LEGO_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_LEGO_START_BIT_PAUSE_LEN              (uint8_t)(F_INTERRUPTS * LEGO_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_LEGO_REPEAT_START_BIT_PAUSE_LEN       (uint8_t)(F_INTERRUPTS * LEGO_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_LEGO_PULSE_LEN                        (uint8_t)(F_INTERRUPTS * LEGO_PULSE_TIME + 0.5)\n#define IRSND_LEGO_1_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * LEGO_1_PAUSE_TIME + 0.5)\n#define IRSND_LEGO_0_PAUSE_LEN                      (uint8_t)(F_INTERRUPTS * LEGO_0_PAUSE_TIME + 0.5)\n#define IRSND_LEGO_FRAME_REPEAT_PAUSE_LEN           (uint16_t)(F_INTERRUPTS * LEGO_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\n\n#define IRSND_IRMP16_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * IRMP16_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_IRMP16_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * IRMP16_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_IRMP16_REPEAT_START_BIT_PAUSE_LEN     (uint8_t)(F_INTERRUPTS * IRMP16_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_IRMP16_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * IRMP16_PULSE_TIME + 0.5)\n#define IRSND_IRMP16_1_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * IRMP16_1_PAUSE_TIME + 0.5)\n#define IRSND_IRMP16_0_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * IRMP16_0_PAUSE_TIME + 0.5)\n#define IRSND_IRMP16_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * IRMP16_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\n\n#define IRSND_A1TVBOX_START_BIT_PULSE_LEN           (uint8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_A1TVBOX_START_BIT_PAUSE_LEN           (uint8_t)(F_INTERRUPTS * A1TVBOX_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_A1TVBOX_BIT_PULSE_LEN                 (uint8_t)(F_INTERRUPTS * A1TVBOX_BIT_PULSE_TIME + 0.5)\n#define IRSND_A1TVBOX_BIT_PAUSE_LEN                 (uint8_t)(F_INTERRUPTS * A1TVBOX_BIT_PAUSE_TIME + 0.5)\n#define IRSND_A1TVBOX_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * A1TVBOX_FRAME_REPEAT_PAUSE_TIME + 0.5)            // use uint16_t!\n#define IRSND_A1TVBOX_FRAME_REPEAT_PAUSE_LEN        (uint16_t)(F_INTERRUPTS * A1TVBOX_FRAME_REPEAT_PAUSE_TIME + 0.5)            // use uint16_t!\n\n#define IRSND_ROOMBA_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_ROOMBA_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * ROOMBA_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_ROOMBA_1_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * ROOMBA_1_PULSE_TIME + 0.5)\n#define IRSND_ROOMBA_0_PULSE_LEN                    (uint8_t)(F_INTERRUPTS * ROOMBA_0_PULSE_TIME + 0.5)\n#define IRSND_ROOMBA_1_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * ROOMBA_1_PAUSE_TIME + 0.5)\n#define IRSND_ROOMBA_0_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * ROOMBA_0_PAUSE_TIME + 0.5)\n#define IRSND_ROOMBA_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * ROOMBA_FRAME_REPEAT_PAUSE_TIME + 0.5)               // use uint16_t!\n\n#define IRSND_PENTAX_START_BIT_PULSE_LEN            (uint8_t)(F_INTERRUPTS * PENTAX_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_PENTAX_START_BIT_PAUSE_LEN            (uint8_t)(F_INTERRUPTS * PENTAX_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_PENTAX_REPEAT_START_BIT_PAUSE_LEN     (uint8_t)(F_INTERRUPTS * PENTAX_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_PENTAX_PULSE_LEN                      (uint8_t)(F_INTERRUPTS * PENTAX_PULSE_TIME + 0.5)\n#define IRSND_PENTAX_1_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * PENTAX_1_PAUSE_TIME + 0.5)\n#define IRSND_PENTAX_0_PAUSE_LEN                    (uint8_t)(F_INTERRUPTS * PENTAX_0_PAUSE_TIME + 0.5)\n#define IRSND_PENTAX_FRAME_REPEAT_PAUSE_LEN         (uint16_t)(F_INTERRUPTS * PENTAX_FRAME_REPEAT_PAUSE_TIME + 0.5)              // use uint16_t!\n\n#define IRSND_ACP24_START_BIT_PULSE_LEN             (uint8_t)(F_INTERRUPTS * ACP24_START_BIT_PULSE_TIME + 0.5)\n#define IRSND_ACP24_START_BIT_PAUSE_LEN             (uint8_t)(F_INTERRUPTS * ACP24_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_ACP24_REPEAT_START_BIT_PAUSE_LEN      (uint8_t)(F_INTERRUPTS * ACP24_REPEAT_START_BIT_PAUSE_TIME + 0.5)\n#define IRSND_ACP24_PULSE_LEN                       (uint8_t)(F_INTERRUPTS * ACP24_PULSE_TIME + 0.5)\n#define IRSND_ACP24_1_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * ACP24_1_PAUSE_TIME + 0.5)\n#define IRSND_ACP24_0_PAUSE_LEN                     (uint8_t)(F_INTERRUPTS * ACP24_0_PAUSE_TIME + 0.5)\n#define IRSND_ACP24_FRAME_REPEAT_PAUSE_LEN          (uint16_t)(F_INTERRUPTS * ACP24_FRAME_REPEAT_PAUSE_TIME + 0.5)                // use uint16_t!\n\n#if defined(PIC_C18)                                  // PIC C18\n#  define IRSND_FREQ_TYPE                       uint8_t\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 30000  / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 32000  / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 36000  / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 38000  / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 40000  / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 56000  / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) ((F_CPU / 455000 / 2 / Pre_Scaler / PIC_Scaler) - 1)\n#elif defined (ARM_STM32)                       // STM32\n#  define IRSND_FREQ_TYPE                       uint32_t\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\n#elif defined (ARM_STM32_OPENCM3)               // STM32_OPENCM3\n#  define IRSND_FREQ_TYPE                       uint32_t\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\n#elif defined (ARM_STM32_HAL)                   // STM32 with Hal Library\n#  define IRSND_FREQ_TYPE                       uint32_t\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\n#elif defined (ARDUINO_ARCH_RP2040)             // ARDUINO_ARCH_RP2040\n#  define IRSND_FREQ_TYPE                       uint32_t\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\n#elif defined (TEENSY_ARM_CORTEX_M4)            // TEENSY\n#  define IRSND_FREQ_TYPE                       float\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\n#elif defined (__xtensa__)                      // ESP8266\n#  define IRSND_FREQ_TYPE                       float\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) (30000)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) (32000)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) (36000)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) (38000)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) (40000)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) (56000)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) (455000)\n#else                                           // AVR\n#  if F_CPU >= 16000000L\n#    define AVR_PRESCALER                       8\n#  else\n#    define AVR_PRESCALER                       1\n#  endif\n#  define IRSND_FREQ_TYPE                       uint8_t\n#  define IRSND_FREQ_30_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 30000 / AVR_PRESCALER / 2) - 1)\n#  define IRSND_FREQ_32_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 32000 / AVR_PRESCALER / 2) - 1)\n#  define IRSND_FREQ_36_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 36000 / AVR_PRESCALER / 2) - 1)\n#  define IRSND_FREQ_38_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 38000 / AVR_PRESCALER / 2) - 1)\n#  define IRSND_FREQ_40_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 40000 / AVR_PRESCALER / 2) - 1)\n#  define IRSND_FREQ_56_KHZ                     (IRSND_FREQ_TYPE) ((F_CPU / 56000 / AVR_PRESCALER / 2) - 1)\n#  define IRSND_FREQ_455_KHZ                    (IRSND_FREQ_TYPE) ((F_CPU / 455000 / AVR_PRESCALER / 2) - 1)\n#endif\n\n// @formatter:off\n// Used for Arduino by IRTimer.hpp\nvolatile uint8_t                                irsnd_busy = 0;\nvolatile uint8_t                                irsnd_is_on = FALSE;\n\nstatic volatile uint8_t                         irsnd_protocol = 0;\nstatic volatile uint8_t                         irsnd_buffer[11] = { 0 };\nstatic volatile uint8_t                         irsnd_repeat = 0;\nstatic volatile uint8_t                         irsnd_suppress_trailer = 0;\n// @formatter:on\n\n#if defined(ARDUINO)\n#include \"irsndArduinoExt.hpp\" // must be after the declarations of irsnd_busy etc.\n#else\n\n#if IRSND_USE_CALLBACK == 1\nstatic void                                     (*irsnd_callback_ptr) (uint8_t);\n#endif // IRSND_USE_CALLBACK == 1\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Switch PWM on\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\nstatic void\nirsnd_on (void)\n{\n    if (! irsnd_is_on)\n    {\n#if !defined(ANALYZE)\n#  if defined(PIC_C18)                                  // PIC C18\n        PWMon();\n        // IRSND_PIN = 0; // output mode -> enable PWM outout pin (0=PWM on, 1=PWM off)\n\n#  elif defined (ARM_STM32)                             // STM32\n        IRSND_TIMER->EGR = TIM_PSCReloadMode_Immediate; // Generate an update event to reload the Prescaler and the Repetition counter values immediately\n        TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Enable);      // enable OC-output (is being disabled in TIM_SelectOCxM())\n        TIM_Cmd(IRSND_TIMER, ENABLE);                   // enable counter\n\n        #  elif defined (ARM_STM32_OPENCM3)                     // STM32_OPENCM3\n        TIM_EGR(IRSND_TIMER) = TIM_EGR_UG;              // Generate an update event to reload the Prescaler and the Repetition counter values immediately\n        timer_enable_oc_output(IRSND_TIMER, IRSND_TIMER_CHANNEL);      // enable OC-output\n        timer_enable_counter(IRSND_TIMER);              // enable counter\n\n#  elif defined (ARM_STM32_HAL)                         // STM32 with Hal Library\n        IRSND_TIMER->EGR = TIM_EGR_UG;                  // Generate an update event to reload the Prescaler and the Repetition counter values immediately\n        HAL_TIM_PWM_Start(&IRSND_TIMER_HANDLER, IRSND_TIMER_CHANNEL_NUMBER);\n\n#  elif defined (ARDUINO_ARCH_RP2040)                   // ARDUINO_ARCH_RP2040\n        pwm_set_counter(slice_num, 0);                  // reset counter\n        pwm_set_enabled(slice_num, true);               // enable counter\n        gpio_set_outover(IRSND_BIT, GPIO_OVERRIDE_NORMAL);\n\n#  elif defined (TEENSY_ARM_CORTEX_M4)                  // TEENSY\n        analogWrite(IRSND_PIN, 33 * 255 / 100);         // pwm 33%\n\n#  elif defined (__xtensa__)                            // ESP8266 (Arduino)\n        analogWrite(IRSND_PIN, 33 * 1023 / 100);        // pwm 33%\n\n#  elif defined (__AVR_XMEGA__)\n#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                 // use OC0A\n                XMEGA_Timer.CTRLB |= (1<<TC0_CCAEN_bp);                 // Compare A\n#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                               // use OC0B\n                XMEGA_Timer.CTRLB |= (1<<TC0_CCBEN_bp);                 // Compare B\n#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                 // use OC0C\n                XMEGA_Timer.CTRLB |= (1<<TC0_CCCEN_bp);                 // Compare C\n#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                 // use OC0D\n                XMEGA_Timer.CTRLB |= (1<<TC0_CCDEN_bp);                 // Compare D\n#    elif IRSND_OCx == IRSND_XMEGA_OC1A                                 // use OC1A\n                XMEGA_Timer.CTRLB |= (1<<TC1_CCAEN_bp);                 // Compare A\n#    elif IRSND_OCx == IRSND_XMEGA_OC1B                                 // use OC1B\n                XMEGA_Timer.CTRLB |= (1<<TC1_CCBEN_bp);                 // Compare B\n#    else\n#       error wrong value of IRSND_OCx\n#    endif // IRSND_OCx\n\n#  else                                                 // AVR\n#    if   IRSND_OCx == IRSND_OC2                        // use OC2\n        TCCR2 |= (1<<COM20)|(1<<WGM21);                 // toggle OC2 on compare match,  clear Timer 2 at compare match OCR2\n#    elif IRSND_OCx == IRSND_OC2A                       // use OC2A\n        TCCR2A |= (1<<COM2A0)|(1<<WGM21);               // toggle OC2A on compare match, clear Timer 2 at compare match OCR2A\n#    elif IRSND_OCx == IRSND_OC2B                       // use OC2B\n        TCCR2A |= (1<<COM2B0)|(1<<WGM21);               // toggle OC2B on compare match, clear Timer 2 at compare match OCR2A (yes: A, not B!)\n#    elif IRSND_OCx == IRSND_OC0                        // use OC0\n        TCCR0 |= (1<<COM00)|(1<<WGM01);                 // toggle OC0 on compare match,  clear Timer 0 at compare match OCR0\n#    elif IRSND_OCx == IRSND_OC0A                       // use OC0A\n        TCCR0A |= (1<<COM0A0)|(1<<WGM01);               // toggle OC0A on compare match, clear Timer 0 at compare match OCR0A\n#    elif IRSND_OCx == IRSND_OC0B                       // use OC0B\n        TCCR0A |= (1<<COM0B0)|(1<<WGM01);               // toggle OC0B on compare match, clear Timer 0 at compare match OCR0A (yes: A, not B!)\n#    else\n#      error wrong value of IRSND_OCx\n#    endif // IRSND_OCx\n#  endif // C18\n#endif // ANALYZE\n\n#if IRSND_USE_CALLBACK == 1\n        if (irsnd_callback_ptr)\n        {\n            (*irsnd_callback_ptr) (TRUE);\n        }\n#endif // IRSND_USE_CALLBACK == 1\n\n        irsnd_is_on = TRUE;\n    }\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Switch PWM off\n *  @details  Switches PWM off\n *  Only called by irsnd_ISR\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\nstatic void\nirsnd_off (void)\n{\n    if (irsnd_is_on)\n    {\n#if !defined(ANALYZE)\n\n#  if defined(PIC_C18)                                                                  // PIC C18\n        PWMoff();\n        // IRSND_PIN = 1; //input mode -> disbale PWM output pin (0=PWM on, 1=PWM off)\n\n#  elif defined (ARM_STM32)                                                             // STM32\n        TIM_CCxCmd(IRSND_TIMER, IRSND_TIMER_CHANNEL, TIM_CCx_Disable);                   // disable OC-output\n        TIM_Cmd(IRSND_TIMER, DISABLE);                                                  // disable counter\n\n#  elif defined (ARM_STM32_OPENCM3)                                                     // STM32_OPENCM3\n        timer_disable_oc_output(IRSND_TIMER, IRSND_TIMER_CHANNEL);                      // disable OC-output\n        timer_disable_counter(IRSND_TIMER);                                             // disable counter\n\n#  elif defined (ARM_STM32_HAL)                                                         // STM32\n        HAL_TIM_PWM_Stop(&IRSND_TIMER_HANDLER, IRSND_TIMER_CHANNEL_NUMBER);\n\n#  elif defined (ARDUINO_ARCH_RP2040)                                                   // ARDUINO_ARCH_RP2040\n        pwm_set_enabled(slice_num, false);                                              // disable counter\n        gpio_set_outover(IRSND_BIT, GPIO_OVERRIDE_LOW);                                 // set IRSND_BIT to low\n\n#  elif defined (TEENSY_ARM_CORTEX_M4)                                                  // TEENSY\n        analogWrite(IRSND_PIN, 0);                                                      // pwm off, LOW level\n\n#  elif defined (__xtensa__)                                                            // ESP8266\n        analogWrite(IRSND_PIN, 0);                                                      // pwm off, LOW level\n\n#  elif defined (__AVR_XMEGA__)\n#    if (IRSND_OCx == IRSND_XMEGA_OC0A)                                                 // use OC0A\n        XMEGA_Timer.CTRLB &= ~(1<<TC0_CCAEN_bp);                                        // Compare A disconnected\n#    elif (IRSND_OCx == IRSND_XMEGA_OC0B)                                               // use OC0B\n        XMEGA_Timer.CTRLB &= ~(1<<TC0_CCBEN_bp);                                        // Compare B disconnected\n#    elif IRSND_OCx == IRSND_XMEGA_OC0C                                                 // use OC0C\n        XMEGA_Timer.CTRLB &= ~(1<<TC0_CCCEN_bp);                                        // Compare C disconnected\n#    elif IRSND_OCx == IRSND_XMEGA_OC0D                                                 // use OC0D\n        XMEGA_Timer.CTRLB &= ~(1<<TC0_CCDEN_bp);                                        // Compare D disconnected\n#    elif IRSND_OCx == IRSND_XMEGA_OC1A                                                 // use OC1A\n                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCAEN_bp);                                // Compare A disconnected\n#    elif IRSND_OCx == IRSND_XMEGA_OC1B                                                 // use OC1B\n                XMEGA_Timer.CTRLB &= ~(1<<TC1_CCBEN_bp);                                // Compare B disconnected\n#    else\n#       error wrong value of IRSND_OCx\n#    endif // IRSND_OCx\n\n#  else //AVR\n\n#    if   IRSND_OCx == IRSND_OC2                        // use OC2\n        TCCR2 &= ~(1<<COM20);                           // normal port operation, OC2 disconnected.\n#    elif IRSND_OCx == IRSND_OC2A                       // use OC2A\n        TCCR2A &= ~(1<<COM2A0);                         // normal port operation, OC2A disconnected.\n#    elif IRSND_OCx == IRSND_OC2B                       // use OC2B\n        TCCR2A &= ~(1<<COM2B0);                         // normal port operation, OC2B disconnected.\n#    elif IRSND_OCx == IRSND_OC0                        // use OC0\n        TCCR0 &= ~(1<<COM00);                           // normal port operation, OC0 disconnected.\n#    elif IRSND_OCx == IRSND_OC0A                       // use OC0A\n        TCCR0A &= ~(1<<COM0A0);                         // normal port operation, OC0A disconnected.\n#    elif IRSND_OCx == IRSND_OC0B                       // use OC0B\n        TCCR0A &= ~(1<<COM0B0);                         // normal port operation, OC0B disconnected.\n#    else\n#      error wrong value of IRSND_OCx\n#    endif // IRSND_OCx\n        IRSND_PORT  &= ~(1<<IRSND_BIT);                 // set IRSND_BIT to low\n#  endif //C18\n#endif // ANALYZE\n\n#if IRSND_USE_CALLBACK == 1\n        if (irsnd_callback_ptr)\n        {\n           (*irsnd_callback_ptr) (FALSE);\n        }\n#endif // IRSND_USE_CALLBACK == 1\n\n        irsnd_is_on = FALSE;\n    }\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Set PWM frequency\n *  @details  sets pwm frequency\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined(__12F1840)\nextern void pwm_init(uint16_t freq);\n#include <stdio.h>\n#endif\n\nstatic void\nirsnd_set_freq (IRSND_FREQ_TYPE freq)\n{\n#if !defined(ANALYZE)\n#  if defined(PIC_C18)                                                                      // PIC C18 or XC8\n#    if defined(__12F1840)                                                                  // XC8\n        TRISA2=0;\n        PR2=freq;\n        CCP1M0=1;\n        CCP1M1=1;\n        CCP1M2=1;\n        CCP1M3=1;\n        DC1B0=1;\n        DC1B1=0;\n        CCPR1L = 0b01101001;\n        TMR2IF = 0;\n        TMR2ON=1;\n        CCP1CON &=(~0b0011); // p 197 \"active high\"\n#    else                                                                                   // PIC C18\n        OpenPWM(freq);\n        SetDCPWM( (uint16_t) (freq * 2) + 1); // freq*2 = Duty cycles 50%\n#    endif\n        PWMoff();\n#  elif defined (ARM_STM32)                                                                 // STM32\n        static uint32_t      TimeBaseFreq = 0;\n\n        if (TimeBaseFreq == 0)\n        {\n            RCC_ClocksTypeDef        RCC_ClocksStructure;\n            /* Get system clocks and store timer clock in variable */\n            RCC_GetClocksFreq(&RCC_ClocksStructure);\n#    if ((IRSND_TIMER_NUMBER >= 2) && (IRSND_TIMER_NUMBER <= 5)) || ((IRSND_TIMER_NUMBER >= 12) && (IRSND_TIMER_NUMBER <= 14))\n            if (RCC_ClocksStructure.PCLK1_Frequency == RCC_ClocksStructure.HCLK_Frequency)\n            {\n               TimeBaseFreq = RCC_ClocksStructure.PCLK1_Frequency;\n            }\n            else\n            {\n               TimeBaseFreq = RCC_ClocksStructure.PCLK1_Frequency * 2;\n            }\n#    else\n            if (RCC_ClocksStructure.PCLK2_Frequency == RCC_ClocksStructure.HCLK_Frequency)\n            {\n               TimeBaseFreq = RCC_ClocksStructure.PCLK2_Frequency;\n            }\n            else\n            {\n               TimeBaseFreq = RCC_ClocksStructure.PCLK2_Frequency * 2;\n            }\n#    endif\n        }\n\n        freq = TimeBaseFreq/freq;\n\n        /* Set frequency */\n        TIM_SetAutoreload(IRSND_TIMER, freq - 1);\n        /* Set duty cycle */\n        TIM_SetCompare1(IRSND_TIMER, freq / 2);\n\n#  elif defined (ARM_STM32_OPENCM3)                                                         // ARM_STM32_OPENCM3\n        static uint32_t      TimeBaseFreq = 0;\n\n        if (TimeBaseFreq == 0)\n        {\n#    if ((IRSND_TIMER_NUMBER >= 2) && (IRSND_TIMER_NUMBER <= 5)) || ((IRSND_TIMER_NUMBER >= 12) && (IRSND_TIMER_NUMBER <= 14))\n            if (rcc_apb1_frequency == rcc_ahb_frequency)\n            {\n               TimeBaseFreq = rcc_apb1_frequency;\n            }\n            else\n            {\n               TimeBaseFreq = rcc_apb1_frequency * 2;\n            }\n#    else\n            if (rcc_apb2_frequency == rcc_ahb_frequency)\n            {\n               TimeBaseFreq = rcc_apb2_frequency;\n            }\n            else\n            {\n               TimeBaseFreq = rcc_apb2_frequency * 2;\n            }\n#    endif\n        }\n\n        freq = TimeBaseFreq/freq;\n\n        /* Set frequency */\n        timer_set_period(IRSND_TIMER, freq - 1);\n        /* Set duty cycle */\n        timer_set_oc_value(IRSND_TIMER, TIM_OC1, freq / 2);\n\n#  elif defined (ARM_STM32_HAL)                                                            // STM32 with Hal Library\n\n        TIM_MasterConfigTypeDef sMasterConfig;\n        TIM_OC_InitTypeDef sConfigOC;\n\n        uint32_t uwPrescalerValue = (uint32_t) ((IRSND_TIMER_SPEED_APBX) / (freq*10)) - 1; //1kHz\n\n        //IRSND_TIMER_HANDLER.Instance = TIM2;\n        IRSND_TIMER_HANDLER.Init.Prescaler = uwPrescalerValue;\n        IRSND_TIMER_HANDLER.Init.CounterMode = TIM_COUNTERMODE_UP;\n        IRSND_TIMER_HANDLER.Init.Period = 10 -1;\n        IRSND_TIMER_HANDLER.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;\n        IRSND_TIMER_HANDLER.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;\n\n        if (HAL_TIM_PWM_Init(&IRSND_TIMER_HANDLER) != HAL_OK)\n        {\n            _Error_Handler(__FILE__, __LINE__);\n        }\n\n        sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;\n        sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;\n\n        if (HAL_TIMEx_MasterConfigSynchronization(&IRSND_TIMER_HANDLER, &sMasterConfig) != HAL_OK)\n        {\n            _Error_Handler(__FILE__, __LINE__);\n        }\n\n        sConfigOC.OCMode = TIM_OCMODE_PWM1;\n        sConfigOC.Pulse = IRSND_TIMER_HANDLER.Init.Period / 2;\n        sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;\n        sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;\n\n        if (HAL_TIM_PWM_ConfigChannel(&IRSND_TIMER_HANDLER, &sConfigOC, IRSND_TIMER_CHANNEL_NUMBER ) != HAL_OK)\n        {\n            _Error_Handler(__FILE__, __LINE__);\n        }\n\n#  elif defined (ARDUINO_ARCH_RP2040)                                                       // ARDUINO_ARCH_RP2040\n        static uint32_t      TimeBaseFreq = 0;\n\n        if (TimeBaseFreq == 0)\n        {\n               TimeBaseFreq = F_CPU;\n        }\n\n        freq = TimeBaseFreq/freq;\n\n        /* Set frequency */\n        pwm_set_wrap(slice_num, freq - 1);\n        /* Set duty cycle */\n        pwm_set_gpio_level(IRSND_BIT, freq / 2);\n\n#  elif defined (TEENSY_ARM_CORTEX_M4)\n        analogWriteResolution(8);                                                           // 8 bit\n        analogWriteFrequency(IRSND_PIN, freq);\n        analogWrite(IRSND_PIN, 0);                                                          // pwm off, LOW level\n\n#elif defined (__xtensa__)\n        // analogWriteRange(255);\n        analogWriteFreq(freq);\n        analogWrite(IRSND_PIN, 0);                                                          // pwm off, LOW level\n\n#  elif defined (__AVR_XMEGA__)\n        XMEGA_Timer.CCA = freq;\n\n#  else                                                                                     // AVR\n\n#    if IRSND_OCx == IRSND_OC2\n        OCR2 = freq;                                                                        // use register OCR2 for OC2\n#    elif IRSND_OCx == IRSND_OC2A                                                           // use OC2A\n        OCR2A = freq;                                                                       // use register OCR2A for OC2A and OC2B!\n#    elif IRSND_OCx == IRSND_OC2B                                                           // use OC2B\n        OCR2A = freq;                                                                       // use register OCR2A for OC2A and OC2B!\n#    elif IRSND_OCx == IRSND_OC0                                                            // use OC0\n        OCR0 = freq;                                                                        // use register OCR2 for OC2\n#    elif IRSND_OCx == IRSND_OC0A                                                           // use OC0A\n        OCR0A = freq;                                                                       // use register OCR0A for OC0A and OC0B!\n#    elif IRSND_OCx == IRSND_OC0B                                                           // use OC0B\n        OCR0A = freq;                                                                       // use register OCR0A for OC0A and OC0B!\n#    else\n#      error wrong value of IRSND_OCx\n#    endif\n#  endif //PIC_C18\n#endif // ANALYZE\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  Initialize the PWM\n *  @details  Configures 0CR0A, 0CR0B and 0CR2B as PWM channels\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\nvoid\nirsnd_init (void)\n{\n#if !defined(ANALYZE)\n#  if defined(PIC_C18)                                                      // PIC C18 or XC8 compiler\n#    if ! defined(__12F1840)                                                // only C18:\n        OpenTimer;\n#    endif\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                 // default frequency\n        IRSND_PIN = 0;                                                      // set IO to outout\n        PWMoff();\n#  elif defined (ARM_STM32)                                                 // STM32\n        GPIO_InitTypeDef            GPIO_InitStructure;\n        TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;\n        TIM_OCInitTypeDef           TIM_OCInitStructure;\n\n       /* GPIOx clock enable */\n#    if defined (ARM_STM32L1XX)\n        RCC_AHBPeriphClockCmd(IRSND_PORT_RCC, ENABLE);\n#    elif defined (ARM_STM32F10X)\n        RCC_APB2PeriphClockCmd(IRSND_PORT_RCC, ENABLE);\n        // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // only in case of remapping, not necessary for default port-timer mapping\n#    elif defined (ARM_STM32F30X)\n        RCC_AHBPeriphClockCmd(IRSND_PORT_RCC, ENABLE);\n#    elif defined (ARM_STM32F4XX)\n        RCC_AHB1PeriphClockCmd(IRSND_PORT_RCC, ENABLE);\n#    endif\n\n        /* GPIO Configuration */\n        GPIO_InitStructure.GPIO_Pin = IRSND_BIT;\n#    if defined (ARM_STM32L1XX) || defined (ARM_STM32F4XX)\n        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\n        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\n        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\n        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\n        GPIO_Init(IRSND_PORT, &GPIO_InitStructure);\n        GPIO_PinAFConfig(IRSND_PORT, (uint8_t)IRSND_BIT_NUMBER, IRSND_GPIO_AF);\n#    elif defined (ARM_STM32F10X)\n        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\n        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;\n        GPIO_Init(IRSND_PORT, &GPIO_InitStructure);\n        // GPIO_PinRemapConfig(GPIO_*Remap*_TIM[IRSND_TIMER_NUMBER], ENABLE); // only in case of remapping, not necessary for default port-timer mapping\n#    elif defined (ARM_STM32F30X)\n        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\n        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\n        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\n        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\n        GPIO_Init(IRSND_PORT, &GPIO_InitStructure);\n        // GPIO_PinRemapConfig(GPIO_*Remap*_TIM[IRSND_TIMER_NUMBER], ENABLE); // only in case of remapping, not necessary for default port-timer mapping\n\n#    endif\n\n        /* TIMx clock enable */\n#    if ((IRSND_TIMER_NUMBER >= 2) && (IRSND_TIMER_NUMBER <= 5)) || ((IRSND_TIMER_NUMBER >= 12) && (IRSND_TIMER_NUMBER <= 14))\n        RCC_APB1PeriphClockCmd(IRSND_TIMER_RCC, ENABLE);\n#    else\n        RCC_APB2PeriphClockCmd(IRSND_TIMER_RCC, ENABLE);\n#    endif\n\n        /* Time base configuration */\n        TIM_TimeBaseStructure.TIM_Period = -1;     // set dummy value (don't set to 0), will be initialized later\n        TIM_TimeBaseStructure.TIM_Prescaler = 0;\n        TIM_TimeBaseStructure.TIM_ClockDivision = 0;\n        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;\n        TIM_TimeBaseInit(IRSND_TIMER, &TIM_TimeBaseStructure);\n\n        /* PWM1 Mode configuration */\n        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;\n        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;\n        TIM_OCInitStructure.TIM_Pulse = 0;         // will be initialized later\n        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;\n        TIM_OC1Init(IRSND_TIMER, &TIM_OCInitStructure);\n\n        /* Preload configuration */\n        TIM_ARRPreloadConfig(IRSND_TIMER, ENABLE);\n        TIM_OC1PreloadConfig(IRSND_TIMER, TIM_OCPreload_Enable);\n\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // set default frequency\n\n#  elif defined (ARM_STM32_OPENCM3)                                         // ARM_STM32_OPENCM3\n\n       /* GPIOx clock enable */\n#    if defined (STM32L1) || defined (STM32F1) || defined (STM32F3) || defined (STM32F4)\n        rcc_periph_clock_enable(IRSND_PORT_RCC);\n#    endif\n\n        /* GPIO Configuration */\n#    if defined (STM32L) || defined (STM32F4)\n        gpio_mode_setup(IRSND_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, IRSND_BIT);\n        gpio_set_output_options(IRSND_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, IRSND_BIT);\n        gpio_set_af(IRSND_PORT, IRSND_GPIO_AF, (uint8_t)IRSND_BIT_NUMBER);\n#    elif defined (STM32F1)\n        gpio_set_mode(IRSND_PORT, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, IRSND_BIT);\n#    elif defined (STM32F3)\n        gpio_mode_setup(IRSND_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, IRSND_BIT);\n        gpio_set_output_options(IRSND_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, IRSND_BIT);\n        //gpio_set_af(IRSND_PORT, IRSND_GPIO_AF, (uint8_t)IRSND_BIT_NUMBER);\n\n#    endif\n\n        /* TIMx clock enable */\n#    if ((IRSND_TIMER_NUMBER >= 2) && (IRSND_TIMER_NUMBER <= 5)) || ((IRSND_TIMER_NUMBER >= 12) && (IRSND_TIMER_NUMBER <= 14))\n        rcc_periph_clock_enable(IRSND_TIMER_RCC);\n#    else\n        rcc_periph_clock_enable(IRSND_TIMER_RCC);\n#    endif\n\n        /* Time base configuration */\n        timer_set_mode(IRSND_TIMER, 0, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);\n                timer_set_period(IRSND_TIMER, -1);     // set dummy value (don't set to 0), will be initialized later\n                timer_set_prescaler(IRSND_TIMER, 0);\n\n        /* PWM1 Mode configuration */\n        timer_set_oc_mode(IRSND_TIMER, TIM_OC1, TIM_OCM_PWM1);\n        timer_enable_oc_output(IRSND_TIMER, TIM_OC1);\n        timer_set_oc_value(IRSND_TIMER, TIM_OC1, 0);         // will be initialized later\n        timer_set_oc_polarity_high(IRSND_TIMER, TIM_OC1);\n\n        /* Preload configuration */\n        timer_enable_preload(IRSND_TIMER);\n        timer_enable_oc_preload(IRSND_TIMER, TIM_OC1);\n\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // set default frequency\n\n#  elif defined (ARM_STM32_HAL)\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // default frequency\n\n#  elif defined (ARDUINO_ARCH_RP2040)                                               // ARDUINO_ARCH_RP2040\n        /* GPIO Configuration */\n        gpio_set_function(IRSND_BIT, GPIO_FUNC_PWM);\n        slice_num = pwm_gpio_to_slice_num(IRSND_BIT);\n        pwm_set_output_polarity(slice_num, true, true);\n        gpio_set_outover(IRSND_BIT, GPIO_OVERRIDE_LOW);\n\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // set default frequency\n\n#  elif defined (TEENSY_ARM_CORTEX_M4)\n        if (!digitalPinHasPWM(IRSND_PIN))\n        {\n            return;\n        }\n\n#  elif defined (__xtensa__)\n        pinMode(IRSND_PIN, OUTPUT);\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n\n#  elif defined (__AVR_XMEGA__)\n        IRSND_PORT &= ~(1<<IRSND_BIT);                                              // set IRSND_BIT to low\n        IRSND_DDR |= (1<<IRSND_BIT);                                                // set IRSND_BIT to output\n\n        XMEGA_Timer.PER = 0xFFFF; //Topwert\n        XMEGA_Timer.CTRLB |= TC_WGMODE_FRQ_gc; //Modus: Frequenz entspricht CTC\n\n#    if AVR_PRESCALER == 8\n        XMEGA_Timer.CTRLA |= TC_CLKSEL_DIV8_gc;                                     // start Timer  prescaler = 8\n#    else\n        XMEGA_Timer.CTRLA |= TC_CLKSEL_DIV1_gc;                                     // start Timer  prescaler = 1\n#    endif\n\n# else                                                                              // AVR\n        IRSND_PORT &= ~(1<<IRSND_BIT);                                              // set IRSND_BIT to low\n        IRSND_DDR |= (1<<IRSND_BIT);                                                // set IRSND_BIT to output\n\n#    if   IRSND_OCx == IRSND_OC2                                                    // use OC2\n        TCCR2 = (1<<WGM21);                                                         // CTC mode\n#       if AVR_PRESCALER == 8\n          TCCR2 |= (1<<CS21);                                                       // start Timer 2, prescaler = 8\n#       else\n          TCCR2 |= (1<<CS20);                                                       // start Timer 2, prescaler = 1\n#       endif\n#    elif IRSND_OCx == IRSND_OC2A || IRSND_OCx == IRSND_OC2B                        // use OC2A or OC2B\n        TCCR2A = (1<<WGM21);                                                        // CTC mode\n#       if AVR_PRESCALER == 8\n          TCCR2B = (1<<CS21);                                                       // start Timer 2, prescaler = 8\n#       else\n          TCCR2B = (1<<CS20);                                                       // start Timer 2, prescaler = 1\n#       endif\n#    elif IRSND_OCx == IRSND_OC0                                                    // use OC0\n        TCCR0 = (1<<WGM01);                                                         // CTC mode\n#       if AVR_PRESCALER == 8\n          TCCR0 |= (1<<CS01);                                                       // start Timer 0, prescaler = 8\n#       else\n          TCCR0 |= (1<<CS00);                                                       // start Timer 0, prescaler = 1\n#       endif\n#    elif IRSND_OCx == IRSND_OC0A || IRSND_OCx == IRSND_OC0B                        // use OC0A or OC0B\n        TCCR0A = (1<<WGM01);                                                        // CTC mode\n#       if AVR_PRESCALER == 8\n          TCCR0B = (1<<CS01);                                                       // start Timer 0, prescaler = 8\n#       else\n          TCCR0B = (1<<CS00);                                                       // start Timer 0, prescaler = 1\n#       endif\n#    else\n#      error wrong value of IRSND_OCx\n#    endif\n        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                         // default frequency\n#  endif //PIC_C18\n#endif // ANALYZE\n}\n\n#if IRSND_USE_CALLBACK == 1\nvoid\nirsnd_set_callback_ptr (void (*cb)(uint8_t))\n{\n    irsnd_callback_ptr = cb;\n}\n#endif // IRSND_USE_CALLBACK == 1\n\n#endif // ARDUINO\n\n#  ifdef __cplusplus\nbool\n#else\nuint8_t\n#endif\nirsnd_is_busy(void)\n{\n    return irsnd_busy;\n}\n\nstatic uint16_t bitsrevervse(uint16_t x, uint8_t len)\n{\n    uint16_t xx = 0;\n\n    while (len)\n    {\n        xx <<= 1;\n        if (x & 1)\n        {\n            xx |= 1;\n        }\n        x >>= 1;\n        len--;\n    }\n    return xx;\n}\n\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\nstatic uint8_t  sircs_additional_bitlen;\n#endif // IRSND_SUPPORT_SIRCS_PROTOCOL == 1\n\n/**\n * @param  do_wait - true: Wait for last command to have ended sending its trailing space before start of new sending.\n *                   For Arduino: Additionally wait for sent command to have ended (including trailing gap).\n *                   false: Return directly and do sending in background.\n *                   Keep in mind not to send next frame in background before this frame and its trailing space has ended!\n * @return false if protocol was not found or do_wait was false and sending (of former frame and its trailing space) is still in progress.\n */\n#  ifdef __cplusplus\nbool\n#else\nuint8_t\n#endif\nirsnd_send_data(IRMP_DATA *irmp_data_p, uint8_t do_wait)\n{\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\n    static uint8_t  toggle_bit_recs80;\n#endif\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\n    static uint8_t  toggle_bit_recs80ext;\n#endif\n#if IRSND_SUPPORT_RC5_PROTOCOL == 1\n    static uint8_t  toggle_bit_rc5;\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1\n    static uint8_t  toggle_bit_rc6;\n#endif\n#if IRSND_SUPPORT_THOMSON_PROTOCOL == 1\n    static uint8_t  toggle_bit_thomson;\n#endif\n    uint16_t address;\n    uint16_t command;\n    // to avoid [-Wunused-variable] compiler warnings, e.g. if only NUBERT is activated.\n    (void) address;\n    (void) command;\n\n    if (do_wait)\n    {\n        while (irsnd_busy)\n        {\n            // wait for last command to have ended\n        }\n    }\n    else if (irsnd_busy)\n    {\n        // Here we do not want to wait, but sending is still in progress and we may overwrite current frame data if not returning here.\n        return (FALSE);\n    }\n\n    irsnd_protocol = irmp_data_p->protocol;\n    irsnd_repeat = irmp_data_p->flags & IRSND_REPETITION_MASK;\n#if !defined(ARDUINO) // never send a trailing space for Arduino\n    irsnd_suppress_trailer  = (irmp_data_p->flags & IRSND_SUPPRESS_TRAILER) ? TRUE : FALSE;\n#endif\n\n    switch (irsnd_protocol)\n    {\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\n        case IRMP_SIRCS_PROTOCOL:\n        {\n            // uint8_t  sircs_additional_command_len;\n            uint8_t  sircs_additional_address_len;\n\n            sircs_additional_bitlen = (irmp_data_p->address & 0xFF00) >> 8;                             // additional bitlen\n\n            if (sircs_additional_bitlen > 15 - SIRCS_MINIMUM_DATA_LEN)\n            {\n                // sircs_additional_command_len = 15 - SIRCS_MINIMUM_DATA_LEN;\n                sircs_additional_address_len = sircs_additional_bitlen - (15 - SIRCS_MINIMUM_DATA_LEN);\n            }\n            else\n            {\n                // sircs_additional_command_len = sircs_additional_bitlen;\n                sircs_additional_address_len = 0;\n            }\n\n            command = bitsrevervse (irmp_data_p->command, 15);\n\n            irsnd_buffer[0] = (command & 0x7F80) >> 7;                                                  // CCCCCCCC\n            irsnd_buffer[1] = (command & 0x007F) << 1;                                                  // CCCC****\n\n            if (sircs_additional_address_len > 0)\n            {\n                address = bitsrevervse (irmp_data_p->address, 5);\n                irsnd_buffer[1] |= (address & 0x0010) >> 4;\n                irsnd_buffer[2] =  (address & 0x000F) << 4;\n            }\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n        case IRMP_APPLE_PROTOCOL:\n        {\n            command = irmp_data_p->command | (irmp_data_p->address << 8);                               // store address as ID in upper byte of command\n            address = 0x87EE;                                                                           // set fixed NEC-lookalike address (customer ID of apple)\n\n            address = bitsrevervse (address, NEC_ADDRESS_LEN);\n            command = bitsrevervse (command, NEC_COMMAND_LEN);\n\n            irsnd_protocol = IRMP_NEC_PROTOCOL;                                                         // APPLE protocol is NEC with id instead of inverted command\n\n            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\n            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\n            irsnd_buffer[3] = (command & 0x00FF);                                                               // cccccccc (ID)\n            irsnd_busy      = TRUE;\n            break;\n        }\n        case IRMP_NEC_PROTOCOL:\n        {\n            if (irmp_data_p->flags & IRSND_RAW_REPETITION_FRAME)\n            {\n                irsnd_protocol = IRMP_NEC_REPETITION_PROTOCOL;                                          // send a raw repetition frame\n                irsnd_buffer[0] = 0x00;                                                                 // no address, no command\n            }\n            else\n            {\n                address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);\n                command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);\n\n                irsnd_buffer[0] = (address & 0xFF00) >> 8;                                              // AAAAAAAA\n                irsnd_buffer[1] = (address & 0x00FF);                                                   // AAAAAAAA\n                irsnd_buffer[2] = (command & 0xFF00) >> 8;                                              // CCCCCCCC\n                irsnd_buffer[3] = ~((command & 0xFF00) >> 8);                                           // cccccccc\n            }\n            irsnd_busy = TRUE;\n            break;\n        }\n        case IRMP_ONKYO_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);\n\n            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\n            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\n            irsnd_buffer[3] = (command & 0x00FF);                                                               // CCCCCCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_NEC16_PROTOCOL == 1\n        case IRMP_NEC16_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, NEC16_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, NEC16_COMMAND_LEN);\n\n            irsnd_buffer[0] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[1] = (command & 0x00FF);                                                               // CCCCCCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_NEC42_PROTOCOL == 1\n        case IRMP_NEC42_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, NEC42_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, NEC42_COMMAND_LEN);\n\n            irsnd_buffer[0] = ( (address & 0x1FE0) >> 5);                                                       // AAAAAAAA\n            irsnd_buffer[1] = ( (address & 0x001F) << 3) | ((~address & 0x1C00) >> 10);                         // AAAAAaaa\n            irsnd_buffer[2] =                              ((~address & 0x03FC) >> 2);                          // aaaaaaaa\n            irsnd_buffer[3] = ((~address & 0x0003) << 6) | ( (command & 0x00FC) >> 2);                          // aaCCCCCC\n            irsnd_buffer[4] = ( (command & 0x0003) << 6) | ((~command & 0x00FC) >> 2);                          // CCcccccc\n            irsnd_buffer[5] = ((~command & 0x0003) << 6);                                                       // cc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_MELINERA_PROTOCOL == 1\n        case IRMP_MELINERA_PROTOCOL:\n        {\n            command = irmp_data_p->command;\n\n            irsnd_buffer[0] = (command & 0x00FF);                                                               // CCCCCCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_LGAIR_PROTOCOL == 1\n        case IRMP_LGAIR_PROTOCOL:\n        {\n            address = irmp_data_p->address;\n            command = irmp_data_p->command;\n\n            irsnd_buffer[0] = ( (address & 0x00FF));                                                            // AAAAAAAA\n            irsnd_buffer[1] = ( (command & 0xFF00) >> 8);                                                       // CCCCCCCC\n            irsnd_buffer[2] = ( (command & 0x00FF));                                                            // CCCCCCCC\n            irsnd_buffer[3] = (( ((command & 0xF000) >> 12) +                                                   // checksum\n                                 ((command & 0x0F00) >> 8) +\n                                 ((command & 0x00F0) >>4 ) +\n                                 ((command & 0x000F))) & 0x000F) << 4;\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n        case IRMP_SAMSUNG_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);\n\n            irsnd_buffer[0] =  (address & 0xFF00) >> 8;                                                         // AAAAAAAA\n            irsnd_buffer[1] =  (address & 0x00FF);                                                              // AAAAAAAA\n            irsnd_buffer[2] =  (command & 0x00F0) | ((command & 0xF000) >> 12);                                 // IIIICCCC\n            irsnd_buffer[3] = ((command & 0x0F00) >> 4) | ((~(command & 0xF000) >> 12) & 0x0F);                 // CCCCcccc\n            irsnd_buffer[4] = (~(command & 0x0F00) >> 4) & 0xF0;                                                // cccc0000\n            irsnd_busy      = TRUE;\n            break;\n        }\n        case IRMP_SAMSUNG32_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);\n\n            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\n            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[2] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\n            irsnd_buffer[3] = (command & 0x00FF);                                                               // CCCCCCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_SAMSUNG48_PROTOCOL == 1\n        case IRMP_SAMSUNG48_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, 16);\n\n            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\n            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[2] = ((command & 0xFF00) >> 8);                                                        // CCCCCCCC\n            irsnd_buffer[3] = ~((command & 0xFF00) >> 8);                                                       // cccccccc\n            irsnd_buffer[4] = (command & 0x00FF);                                                               // CCCCCCCC\n            irsnd_buffer[5] = ~(command & 0x00FF);                                                              // cccccccc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\n        case IRMP_MATSUSHITA_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);\n\n            irsnd_buffer[0] = (command & 0x0FF0) >> 4;                                                          // CCCCCCCC\n            irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8);                            // CCCCAAAA\n            irsnd_buffer[2] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\n        case IRMP_TECHNICS_PROTOCOL:\n        {\n            command = bitsrevervse (irmp_data_p->command, TECHNICS_COMMAND_LEN);\n\n            irsnd_buffer[0] = (command & 0x07FC) >> 3;                                                          // CCCCCCCC\n            irsnd_buffer[1] = ((command & 0x0007) << 5) | ((~command & 0x07C0) >> 6);                           // CCCccccc\n            irsnd_buffer[2] = (~command & 0x003F) << 2;                                                         // cccccc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\n        case IRMP_KASEIKYO_PROTOCOL:\n        {\n            uint8_t xor_value;\n            uint16_t genre2;\n\n            address = bitsrevervse (irmp_data_p->address, KASEIKYO_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, KASEIKYO_COMMAND_LEN + 4);\n            genre2 = bitsrevervse ((irmp_data_p->flags & ~IRSND_REPETITION_MASK) >> 4, 4);\n\n            xor_value = ((address & 0x000F) ^ ((address & 0x00F0) >> 4) ^ ((address & 0x0F00) >> 8) ^ ((address & 0xF000) >> 12)) & 0x0F;\n\n            irsnd_buffer[0] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\n            irsnd_buffer[1] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[2] = xor_value << 4 | (command & 0x000F);                                              // XXXXCCCC\n            irsnd_buffer[3] = (genre2 << 4) | (command & 0xF000) >> 12;                                         // ggggCCCC\n            irsnd_buffer[4] = (command & 0x0FF0) >> 4;                                                          // CCCCCCCC\n\n            xor_value = irsnd_buffer[2] ^ irsnd_buffer[3] ^ irsnd_buffer[4];\n\n            irsnd_buffer[5] = xor_value;\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\n        case IRMP_PANASONIC_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, PANASONIC_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, PANASONIC_COMMAND_LEN);\n\n            irsnd_buffer[0] = 0x40;                                                                             // 01000000\n            irsnd_buffer[1] = 0x04;                                                                             // 00000100\n            irsnd_buffer[2] = 0x01;                                                                             // 00000001\n            irsnd_buffer[3] = (address & 0xFF00) >> 8;                                                          // AAAAAAAA\n            irsnd_buffer[4] = (address & 0x00FF);                                                               // AAAAAAAA\n            irsnd_buffer[5] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\n            irsnd_buffer[6] = (command & 0x00FF);                                                               // CCCCCCCC\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n        case IRMP_MITSU_HEAVY_PROTOCOL:\n        {\n            address = irmp_data_p->address;\n            command = irmp_data_p->command;\n\n            irsnd_buffer[0] = 0x4A;\n            irsnd_buffer[1] = 0x75;\n            irsnd_buffer[2] = 0xC3;\n            irsnd_buffer[3] = 0x64;\n            irsnd_buffer[4] = 0x9B;\n            irsnd_buffer[5] = ~(address & 0xFF00) >> 8;\n            irsnd_buffer[6] = (address & 0xFF00) >> 8;\n            irsnd_buffer[7] = ~(address & 0x00FF);\n            irsnd_buffer[8] = (address & 0x00FF);\n            irsnd_buffer[9] = ~(command & 0x00FF);\n            irsnd_buffer[10] = (command & 0x00FF);\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\n        case IRMP_RECS80_PROTOCOL:\n        {\n            toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x80;\n\n            irsnd_buffer[0] = toggle_bit_recs80 | ((irmp_data_p->address & 0x000F) << 4) |\n                              ((irmp_data_p->command & 0x003C) >> 2);                                           // TAAACCCC\n            irsnd_buffer[1] = (irmp_data_p->command & 0x03) << 6;                                               // CC000000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\n        case IRMP_RECS80EXT_PROTOCOL:\n        {\n            toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;\n\n            irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |\n                                ((irmp_data_p->command & 0x0030) >> 4);                                         // STAAAACC\n            irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4;                                               // CCCC0000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RC5_PROTOCOL == 1\n        case IRMP_RC5_PROTOCOL:\n        {\n            toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;\n\n            irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |\n                                ((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5);  // CTAAAAAC\n            irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3;                                               // CCCCC000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n        case IRMP_RC6_PROTOCOL:\n        {\n            toggle_bit_rc6 = toggle_bit_rc6 ? 0x00 : 0x08;\n\n            irsnd_buffer[0] = 0x80 | toggle_bit_rc6 | ((irmp_data_p->address & 0x00E0) >> 5);                   // 1MMMTAAA, MMM = 000\n            irsnd_buffer[1] = ((irmp_data_p->address & 0x001F) << 3) | ((irmp_data_p->command & 0xE0) >> 5);    // AAAAACCC\n            irsnd_buffer[2] = (irmp_data_p->command & 0x1F) << 3;                                               // CCCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RC6A_PROTOCOL == 1\n        case IRMP_RC6A_PROTOCOL:\n        {\n            toggle_bit_rc6 = toggle_bit_rc6 ? 0x00 : 0x08;\n\n            irsnd_buffer[0] = 0x80 | 0x60 | ((irmp_data_p->address & 0x3000) >> 12);                                                // 1MMMT0AA, MMM = 110\n            irsnd_buffer[1] = ((irmp_data_p->address & 0x0FFF) >> 4) ;                                                              // AAAAAAAA\n            irsnd_buffer[2] = ((irmp_data_p->address & 0x000F) << 4) | ((irmp_data_p->command & 0xF000) >> 12) | toggle_bit_rc6;    // AAAACCCC\n            irsnd_buffer[3] = (irmp_data_p->command & 0x0FF0) >> 4;                                                                 // CCCCCCCC\n            irsnd_buffer[4] = (irmp_data_p->command & 0x000F) << 4;                                                                 // CCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_DENON_PROTOCOL == 1\n        case IRMP_DENON_PROTOCOL:\n        {\n            irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7);    // AAAAACCC (1st frame)\n            irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1;                                               // CCCCCCC\n            irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAAccc (2nd frame)\n            irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1;                                            // ccccccc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_THOMSON_PROTOCOL == 1\n        case IRMP_THOMSON_PROTOCOL:\n        {\n            toggle_bit_thomson = toggle_bit_thomson ? 0x00 : 0x08;\n\n            irsnd_buffer[0] = ((irmp_data_p->address & 0x0F) << 4) | toggle_bit_thomson | ((irmp_data_p->command & 0x0070) >> 4);   // AAAATCCC (1st frame)\n            irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4;                                                                   // CCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\n        case IRMP_BOSE_PROTOCOL:\n        {\n            command = bitsrevervse (irmp_data_p->command, BOSE_COMMAND_LEN);\n\n            irsnd_buffer[0] = (command & 0xFF00) >> 8;                                                                      // CCCCCCCC\n            irsnd_buffer[1] = ~((command & 0xFF00) >> 8);                                                                   // cccccccc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\n        case IRMP_NUBERT_PROTOCOL:\n        {\n            irsnd_buffer[0] = irmp_data_p->command >> 2;                                                        // CCCCCCCC\n            irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6;                                             // CC000000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_FAN_PROTOCOL == 1\n        case IRMP_FAN_PROTOCOL:\n        {\n            irsnd_buffer[0] = irmp_data_p->command >> 3;                                                        // CCCCCCCC\n            irsnd_buffer[1] = (irmp_data_p->command & 0x0007) << 5;                                             // CCC00000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\n        case IRMP_SPEAKER_PROTOCOL:\n        {\n            irsnd_buffer[0] = irmp_data_p->command >> 2;                                                        // CCCCCCCC\n            irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6;                                             // CC000000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n        case IRMP_BANG_OLUFSEN_PROTOCOL:\n        {\n            irsnd_buffer[0] = irmp_data_p->command >> 11;                                                       // SXSCCCCC\n            irsnd_buffer[1] = irmp_data_p->command >> 3;                                                        // CCCCCCCC\n            irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5;                                             // CCC00000\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\n        case IRMP_GRUNDIG_PROTOCOL:\n        {\n            command = bitsrevervse (irmp_data_p->command, GRUNDIG_COMMAND_LEN);\n\n            irsnd_buffer[0] = 0xFF;                                                                             // S1111111 (1st frame)\n            irsnd_buffer[1] = 0xC0;                                                                             // 11\n            irsnd_buffer[2] = 0x80 | (command >> 2);                                                            // SCCCCCCC (2nd frame)\n            irsnd_buffer[3] = (command << 6) & 0xC0;                                                            // CC\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n        case IRMP_TELEFUNKEN_PROTOCOL:\n        {\n            irsnd_buffer[0] = irmp_data_p->command >> 7;                                                        // CCCCCCCC\n            irsnd_buffer[1] = (irmp_data_p->command << 1) & 0xff;                                               // CCCCCCC\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_IR60_PROTOCOL == 1\n        case IRMP_IR60_PROTOCOL:\n        {\n            command = (bitsrevervse (0x7d, IR60_COMMAND_LEN) << 7) | bitsrevervse (irmp_data_p->command, IR60_COMMAND_LEN);\n#if 1\n            irsnd_buffer[0] = command >> 6 | 0x01;                                                              // 1011111S (start instruction frame)\n            irsnd_buffer[1] = (command & 0x7F) << 1;                                                            // CCCCCCC_ (2nd frame)\n#else\n            irsnd_buffer[0] = ((command & 0x7F) << 1) | 0x01;                                                   // CCCCCCCS (1st frame)\n            irsnd_buffer[1] = command >> 6;                                                                     // 1011111_ (start instruction frame)\n#endif\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n        case IRMP_NOKIA_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, NOKIA_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, NOKIA_COMMAND_LEN);\n\n            irsnd_buffer[0] = 0xBF;                                                                             // S0111111 (1st + 3rd frame)\n            irsnd_buffer[1] = 0xFF;                                                                             // 11111111\n            irsnd_buffer[2] = 0x80;                                                                             // 1\n            irsnd_buffer[3] = 0x80 | command >> 1;                                                              // SCCCCCCC (2nd frame)\n            irsnd_buffer[4] = (command << 7) | (address >> 1);                                                  // CAAAAAAA\n            irsnd_buffer[5] = (address << 7);                                                                   // A\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1\n        case IRMP_SIEMENS_PROTOCOL:\n        {\n            irsnd_buffer[0] = ((irmp_data_p->address & 0x07FF) >> 3);                                           // AAAAAAAA\n            irsnd_buffer[1] = ((irmp_data_p->address & 0x0007) << 5) | ((irmp_data_p->command >> 5) & 0x1F);    // AAACCCCC\n            irsnd_buffer[2] = ((irmp_data_p->command & 0x001F) << 3) | ((~irmp_data_p->command & 0x01) << 2);   // CCCCCc\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RUWIDO_PROTOCOL == 1\n        case IRMP_RUWIDO_PROTOCOL:\n        {\n            irsnd_buffer[0] = ((irmp_data_p->address & 0x01FF) >> 1);                                           // AAAAAAAA\n            irsnd_buffer[1] = ((irmp_data_p->address & 0x0001) << 7) | ((irmp_data_p->command & 0x7F));         // ACCCCCCC\n            irsnd_buffer[2] = ((~irmp_data_p->command & 0x01) << 7);                                            // c\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_FDC_PROTOCOL == 1\n        case IRMP_FDC_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, FDC_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, FDC_COMMAND_LEN);\n\n            irsnd_buffer[0] = (address & 0xFF);                                                                 // AAAAAAAA\n            irsnd_buffer[1] = 0;                                                                                // 00000000\n            irsnd_buffer[2] = 0;                                                                                // 0000RRRR\n            irsnd_buffer[3] = (command & 0xFF);                                                                 // CCCCCCCC\n            irsnd_buffer[4] = ~(command & 0xFF);                                                                // cccccccc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1\n        case IRMP_RCCAR_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, 2);                                                   //                            A0 A1\n            command = bitsrevervse (irmp_data_p->command, RCCAR_COMMAND_LEN - 2);                               // D0 D1 D2 D3 D4 D5 D6 D7 C0 C1 V\n\n            irsnd_buffer[0] = ((command & 0x06) << 5) | ((address & 0x0003) << 4) | ((command & 0x0780) >> 7);  //          C0 C1 A0 A1 D0 D1 D2 D3\n            irsnd_buffer[1] = ((command & 0x78) << 1) | ((command & 0x0001) << 3);                              //          D4 D5 D6 D7 V  0  0  0\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_JVC_PROTOCOL == 1\n        case IRMP_JVC_PROTOCOL:\n        {\n            address = bitsrevervse (irmp_data_p->address, JVC_ADDRESS_LEN);\n            command = bitsrevervse (irmp_data_p->command, JVC_COMMAND_LEN);\n\n            irsnd_buffer[0] = ((address & 0x000F) << 4) | (command & 0x0F00) >> 8;                              // AAAACCCC\n            irsnd_buffer[1] = (command & 0x00FF);                                                               // CCCCCCCC\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_NIKON_PROTOCOL == 1\n        case IRMP_NIKON_PROTOCOL:\n        {\n            irsnd_buffer[0] = (irmp_data_p->command & 0x0003) << 6;                                             // CC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_LEGO_PROTOCOL == 1\n        case IRMP_LEGO_PROTOCOL:\n        {\n            uint8_t crc = 0x0F ^ ((irmp_data_p->command & 0x0F00) >> 8) ^ ((irmp_data_p->command & 0x00F0) >> 4) ^ (irmp_data_p->command & 0x000F);\n\n            irsnd_buffer[0] = (irmp_data_p->command & 0x0FF0) >> 4;                                             // CCCCCCCC\n            irsnd_buffer[1] = ((irmp_data_p->command & 0x000F) << 4) | crc;                                     // CCCCcccc\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_IRMP16_PROTOCOL == 1\n        case IRMP_IRMP16_PROTOCOL:\n        {\n            command = bitsrevervse (irmp_data_p->command, IRMP16_COMMAND_LEN);\n\n            irsnd_buffer[0] = (command & 0xFF00) >> 8;                                                          // CCCCCCCC\n            irsnd_buffer[1] = (command & 0x00FF);                                                               // CCCCCCCC\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1\n        case IRMP_A1TVBOX_PROTOCOL:\n        {\n            irsnd_buffer[0] = 0x80 | (irmp_data_p->address >> 2);                                               // 10AAAAAA\n            irsnd_buffer[1] = (irmp_data_p->address << 6) | (irmp_data_p->command >> 2);                        // AACCCCCC\n            irsnd_buffer[2] = (irmp_data_p->command << 6);                                                      // CC\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\n        case IRMP_ROOMBA_PROTOCOL:\n        {\n            irsnd_buffer[0] = (irmp_data_p->command & 0x7F) << 1;                                               // CCCCCCC.\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\n        case IRMP_PENTAX_PROTOCOL:\n        {\n            irsnd_buffer[0] = (irmp_data_p->command & 0x3F) << 2;                                               // CCCCCC..\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n#if IRSND_SUPPORT_ACP24_PROTOCOL == 1\n#       define ACP_SET_BIT(acp24_bitno, c, irmp_bitno)                                          \\\n        do                                                                                      \\\n        {                                                                                       \\\n            if ((c) & (1<<(irmp_bitno)))                                                        \\\n            {                                                                                   \\\n                irsnd_buffer[((acp24_bitno)>>3)] |= 1 << (((7 - (acp24_bitno)) & 0x07));        \\\n            }                                                                                   \\\n        } while (0)\n\n        case IRMP_ACP24_PROTOCOL:\n        {\n            uint16_t    cmd = irmp_data_p->command;\n            uint8_t     i;\n\n            address = bitsrevervse (irmp_data_p->address, ACP24_ADDRESS_LEN);\n\n            for (i = 0; i < 8; i++)\n            {\n                irsnd_buffer[i] = 0x00;                                                                         // CCCCCCCC\n            }\n\n            // ACP24-Frame:\n            //           1         2         3         4         5         6\n            // 0123456789012345678901234567890123456789012345678901234567890123456789\n            // N VVMMM    ? ???    t vmA x                 y                     TTTT\n            //\n            // irmp_data_p->command:\n            //\n            //         5432109876543210\n            //         NAVVvMMMmtxyTTTT\n\n            ACP_SET_BIT( 0, cmd, 15);\n            ACP_SET_BIT(24, cmd, 14);\n            ACP_SET_BIT( 2, cmd, 13);\n            ACP_SET_BIT( 3, cmd, 12);\n            ACP_SET_BIT(22, cmd, 11);\n            ACP_SET_BIT( 4, cmd, 10);\n            ACP_SET_BIT( 5, cmd,  9);\n            ACP_SET_BIT( 6, cmd,  8);\n            ACP_SET_BIT(23, cmd,  7);\n            ACP_SET_BIT(20, cmd,  6);\n            ACP_SET_BIT(26, cmd,  5);\n            ACP_SET_BIT(44, cmd,  4);\n            ACP_SET_BIT(66, cmd,  3);\n            ACP_SET_BIT(67, cmd,  2);\n            ACP_SET_BIT(68, cmd,  1);\n            ACP_SET_BIT(69, cmd,  0);\n\n            irsnd_busy      = TRUE;\n            break;\n        }\n#endif\n// @formatter:off\n        default:\n        {\n            return (FALSE); // Error here: we called irsnd_send_data with a non enabled protocol!\n            break;\n        }\n// @formatter:on\n    }\n#if defined(ARDUINO)\n    storeIRTimer(); // store current timer state to enable alternately send and receive with the same timer\n    initIRTimerForSend(); // Setup timer and interrupts for sending\n    if (do_wait)\n    {\n        while (irsnd_busy)\n        {\n            // Wait for frame and leading space to be sent;\n        }\n    }\n    return true; // next frame may start immediately if do_wait was true\n\n#else\n    return irsnd_busy;\n#endif\n}\n\nvoid irsnd_stop(void)\n{\n    irsnd_repeat = 0;\n}\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n *  ISR routine\n *  @details  ISR routine, called from 10000 to 20000, typically 15000 times per second\n *  If new frame starts, check for autorepeat gap, then check for trailing space gap, then initialize frame.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#  ifdef __cplusplus\nbool\n#else\nuint8_t\n#endif\nirsnd_ISR(void)\n{\n// @formatter:off\n#if !defined(ARDUINO) // never send a trailing space for Arduino\n    static uint8_t              send_last_trailer                    = FALSE;    // Only for last trailer after n repeats. if TRUE, we send the trailing space as defined in repeat_frame_pause_len\n#endif\n    static uint8_t              current_bit                     = 0xFF;     // 0xFF => send start bit\n    static uint8_t              pulse_counter                   = 0;\n    static IRSND_PAUSE_LEN      pause_counter                   = 0;\n    static uint8_t              startbit_pulse_len              = 0;\n    static IRSND_PAUSE_LEN      startbit_pause_len              = 0;\n    static uint8_t              pulse_1_len                     = 0;\n    static uint8_t              pause_1_len                     = 0;\n    static uint8_t              pulse_0_len                     = 0;\n    static uint8_t              pause_0_len                     = 0;\n    static uint8_t              has_stop_bit                    = 0;\n    static uint8_t              new_frame                       = TRUE;\n    static uint8_t              complete_data_len               = 0;\n    static uint8_t              n_repeat_frames                 = 0;        // number of repetition frames\n    static uint8_t              n_auto_repetitions              = 0;        // number of frames inclusive auto_repetition frames\n    static uint8_t              auto_repetition_counter         = 0;        // auto_repetition counter\n    static uint16_t             auto_repetition_pause_len       = 0;        // pause before auto_repetition, uint16_t!\n    static uint16_t             auto_repetition_pause_counter   = 0;        // pause before auto_repetition, uint16_t!\n    static uint8_t              repeat_counter                  = 0;        // repeat counter\n    static uint16_t             repeat_frame_pause_len          = 0;        // pause before repeat, uint16_t!\n    static uint16_t             packet_repeat_pause_counter     = 0;        // pause before repeat, uint16_t!\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n    static uint8_t              last_bit_value;\n#endif\n    static uint8_t              pulse_len = 0xFF;\n    static IRSND_PAUSE_LEN      pause_len = 0xFF;\n// @formatter:on\n\n    if (irsnd_busy)\n    {\n        if (current_bit == 0xFF && new_frame) // start of transmission...\n        {\n//            check for autorepeat gap, then check for trailing space gap, then initialize frame.\n            if (auto_repetition_counter > 0)\n            {\n                /*\n                 * Send gap between auto repetitions\n                 */\n                auto_repetition_pause_counter++; // count gap duration\n\n                if (auto_repetition_pause_counter >= auto_repetition_pause_len)\n                {\n                    auto_repetition_pause_counter = 0; // end of auto repetition space\n\n#if IRSND_SUPPORT_DENON_PROTOCOL == 1\n                    if (irsnd_protocol == IRMP_DENON_PROTOCOL)                              // n'th denon frame\n                    {\n                        current_bit = 16;\n                        complete_data_len   = 2 * DENON_COMPLETE_DATA_LEN + 1;\n                    }\n                    else\n#endif\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\n                    if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL)                            // n'th grundig frame\n                    {\n                        current_bit = 15;\n                        complete_data_len   = 16 + GRUNDIG_COMPLETE_DATA_LEN;\n                    }\n                    else\n#endif\n#if IRSND_SUPPORT_IR60_PROTOCOL == 1\n                    if (irsnd_protocol == IRMP_IR60_PROTOCOL)                               // n'th IR60 frame\n                    {\n                        current_bit = 7;\n                        complete_data_len   = 2 * IR60_COMPLETE_DATA_LEN + 1;\n                    }\n                    else\n#endif\n#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n                    if (irsnd_protocol == IRMP_NOKIA_PROTOCOL)                              // n'th nokia frame\n                    {\n                        if (auto_repetition_counter + 1 < n_auto_repetitions)\n                        {\n                            current_bit = 23;\n                            complete_data_len   = 24 + NOKIA_COMPLETE_DATA_LEN;\n                        }\n                        else                                                                // nokia stop frame\n                        {\n                            current_bit = 0xFF;\n                            complete_data_len   = NOKIA_COMPLETE_DATA_LEN;\n                        }\n                    }\n                    else\n#endif\n                    {\n                        ;\n                    }\n                }\n                else\n                {\n#if defined(ANALYZE)\n                    if (irsnd_is_on)\n                    {\n                        putchar('0');\n                    }\n                    else\n                    {\n                        putchar('1');\n                    }\n#endif\n                    // auto repetition pause here\n                    return irsnd_busy;\n                }\n            }\n\n            /*\n             * Send trailing space\n             */\n            else if (packet_repeat_pause_counter < repeat_frame_pause_len)\n            {\n                /*\n                 * Send trailing space, especially for repeats\n                 */\n                packet_repeat_pause_counter++; // count trailing space duration\n#if defined(ANALYZE)\n                if (irsnd_is_on)\n                {\n                    putchar ('0');\n                }\n                else\n                {\n                    putchar ('1');\n                }\n#endif\n                return irsnd_busy;\n            }\n\n            else\n            {\n                // End of trailing space here => initialize new frame\n#if !defined(ARDUINO) // never send a trailing space for Arduino\n                if (send_last_trailer)\n                {\n                    irsnd_busy = FALSE;     // Trailing space sent complete, stop sending\n                    send_last_trailer = FALSE;\n                    return irsnd_busy;\n                }\n#endif\n\n                n_repeat_frames = irsnd_repeat;\n\n                if (n_repeat_frames == IRSND_ENDLESS_REPETITION)\n                {\n                    n_repeat_frames = 255;\n                }\n\n                packet_repeat_pause_counter = 0;\n                pulse_counter = 0;\n                pause_counter = 0;\n\n                /*\n                 * Initialize new frame for selected protocol\n                 */\n                switch (irsnd_protocol)\n                {\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\n                    case IRMP_SIRCS_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_SIRCS_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_SIRCS_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_SIRCS_1_PULSE_LEN;\n                        pause_1_len                 = IRSND_SIRCS_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_SIRCS_0_PULSE_LEN;\n                        pause_0_len                 = IRSND_SIRCS_PAUSE_LEN - 1;\n                        has_stop_bit                = SIRCS_STOP_BIT;\n                        complete_data_len           = SIRCS_MINIMUM_DATA_LEN + sircs_additional_bitlen;\n                        n_auto_repetitions          = (repeat_counter == 0) ? SIRCS_FRAMES : 1;             // 3 frames auto repetition if first frame\n                        auto_repetition_pause_len   = IRSND_SIRCS_AUTO_REPETITION_PAUSE_LEN;                // 25ms pause\n                        repeat_frame_pause_len      = IRSND_SIRCS_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_40_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n                    case IRMP_NEC_PROTOCOL:\n                    case IRMP_NEC_REPETITION_PROTOCOL:\n                    case IRMP_ONKYO_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_NEC_START_BIT_PULSE_LEN;\n\n                        if (repeat_counter > 0 || irsnd_protocol == IRMP_NEC_REPETITION_PROTOCOL)\n                        {\n                            startbit_pause_len      = IRSND_NEC_REPEAT_START_BIT_PAUSE_LEN - 1;\n                            complete_data_len       = 0;\n                        }\n                        else\n                        {\n                            startbit_pause_len      = IRSND_NEC_START_BIT_PAUSE_LEN - 1;\n                            complete_data_len       = NEC_COMPLETE_DATA_LEN;\n                        }\n\n                        pulse_1_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_1_len                 = IRSND_NEC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_0_len                 = IRSND_NEC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = NEC_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_NEC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_NEC16_PROTOCOL == 1\n                    case IRMP_NEC16_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_NEC_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_NEC_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_1_len                 = IRSND_NEC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_0_len                 = IRSND_NEC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = NEC_STOP_BIT;\n                        complete_data_len           = NEC16_COMPLETE_DATA_LEN + 1;                          // 1 more: sync bit\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_NEC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_NEC42_PROTOCOL == 1\n                    case IRMP_NEC42_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_NEC_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_NEC_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_1_len                 = IRSND_NEC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_0_len                 = IRSND_NEC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = NEC_STOP_BIT;\n                        complete_data_len           = NEC42_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_NEC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_MELINERA_PROTOCOL == 1\n                    case IRMP_MELINERA_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_MELINERA_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_MELINERA_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_MELINERA_1_PULSE_LEN;\n                        pause_1_len                 = IRSND_MELINERA_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_MELINERA_0_PULSE_LEN;\n                        pause_0_len                 = IRSND_MELINERA_0_PAUSE_LEN - 1;\n                        has_stop_bit                = MELINERA_STOP_BIT;\n                        complete_data_len           = MELINERA_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_MELINERA_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_LGAIR_PROTOCOL == 1\n                    case IRMP_LGAIR_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_NEC_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_NEC_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_1_len                 = IRSND_NEC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_NEC_PULSE_LEN;\n                        pause_0_len                 = IRSND_NEC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = NEC_STOP_BIT;\n                        complete_data_len           = LGAIR_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_NEC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n                    case IRMP_SAMSUNG_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_SAMSUNG_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_SAMSUNG_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_SAMSUNG_PULSE_LEN;\n                        pause_1_len                 = IRSND_SAMSUNG_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_SAMSUNG_PULSE_LEN;\n                        pause_0_len                 = IRSND_SAMSUNG_0_PAUSE_LEN - 1;\n                        has_stop_bit                = SAMSUNG_STOP_BIT;\n                        complete_data_len           = SAMSUNG_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_SAMSUNG_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n\n                    case IRMP_SAMSUNG32_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_SAMSUNG_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_SAMSUNG_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_SAMSUNG_PULSE_LEN;\n                        pause_1_len                 = IRSND_SAMSUNG_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_SAMSUNG_PULSE_LEN;\n                        pause_0_len                 = IRSND_SAMSUNG_0_PAUSE_LEN - 1;\n                        has_stop_bit                = SAMSUNG_STOP_BIT;\n                        complete_data_len           = SAMSUNG32_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = SAMSUNG32_FRAMES;                                     // 1 frame\n                        auto_repetition_pause_len   = IRSND_SAMSUNG32_AUTO_REPETITION_PAUSE_LEN;            // 47 ms pause\n                        repeat_frame_pause_len      = IRSND_SAMSUNG32_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_SAMSUNG48_PROTOCOL == 1\n                    case IRMP_SAMSUNG48_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_SAMSUNG_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_SAMSUNG_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_SAMSUNG_PULSE_LEN;\n                        pause_1_len                 = IRSND_SAMSUNG_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_SAMSUNG_PULSE_LEN;\n                        pause_0_len                 = IRSND_SAMSUNG_0_PAUSE_LEN - 1;\n                        has_stop_bit                = SAMSUNG_STOP_BIT;\n                        complete_data_len           = SAMSUNG48_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = SAMSUNG48_FRAMES;                                     // 1 frame\n                        auto_repetition_pause_len   = IRSND_SAMSUNG48_AUTO_REPETITION_PAUSE_LEN;            // 47 ms pause\n                        repeat_frame_pause_len      = IRSND_SAMSUNG48_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\n                    case IRMP_MATSUSHITA_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_MATSUSHITA_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_MATSUSHITA_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_MATSUSHITA_PULSE_LEN;\n                        pause_1_len                 = IRSND_MATSUSHITA_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_MATSUSHITA_PULSE_LEN;\n                        pause_0_len                 = IRSND_MATSUSHITA_0_PAUSE_LEN - 1;\n                        has_stop_bit                = MATSUSHITA_STOP_BIT;\n                        complete_data_len           = MATSUSHITA_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_MATSUSHITA_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\n                    case IRMP_TECHNICS_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_MATSUSHITA_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_MATSUSHITA_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_MATSUSHITA_PULSE_LEN;\n                        pause_1_len                 = IRSND_MATSUSHITA_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_MATSUSHITA_PULSE_LEN;\n                        pause_0_len                 = IRSND_MATSUSHITA_0_PAUSE_LEN - 1;\n                        has_stop_bit                = MATSUSHITA_STOP_BIT;\n                        complete_data_len           = TECHNICS_COMPLETE_DATA_LEN;                           // here TECHNICS\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_MATSUSHITA_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\n                    case IRMP_KASEIKYO_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_KASEIKYO_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_KASEIKYO_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_KASEIKYO_PULSE_LEN;\n                        pause_1_len                 = IRSND_KASEIKYO_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_KASEIKYO_PULSE_LEN;\n                        pause_0_len                 = IRSND_KASEIKYO_0_PAUSE_LEN - 1;\n                        has_stop_bit                = KASEIKYO_STOP_BIT;\n                        complete_data_len           = KASEIKYO_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = KASEIKYO_FRAMES;                                      // 1 frame\n                        auto_repetition_pause_len   = IRSND_KASEIKYO_AUTO_REPETITION_PAUSE_LEN;             // 75 ms pause\n                        repeat_frame_pause_len      = IRSND_KASEIKYO_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\n                    case IRMP_PANASONIC_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_PANASONIC_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_PANASONIC_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_PANASONIC_PULSE_LEN;\n                        pause_1_len                 = IRSND_PANASONIC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_PANASONIC_PULSE_LEN;\n                        pause_0_len                 = IRSND_PANASONIC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = PANASONIC_STOP_BIT;\n                        complete_data_len           = PANASONIC_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = PANASONIC_FRAMES;                                     // 1 frame\n                        auto_repetition_pause_len   = IRSND_PANASONIC_AUTO_REPETITION_PAUSE_LEN;            // 40 ms pause\n                        repeat_frame_pause_len      = IRSND_PANASONIC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n                    case IRMP_MITSU_HEAVY_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_MITSU_HEAVY_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_MITSU_HEAVY_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_MITSU_HEAVY_PULSE_LEN;\n                        pause_1_len                 = IRSND_MITSU_HEAVY_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_MITSU_HEAVY_PULSE_LEN;\n                        pause_0_len                 = IRSND_MITSU_HEAVY_0_PAUSE_LEN - 1;\n                        has_stop_bit                = MITSU_HEAVY_STOP_BIT;\n                        complete_data_len           = MITSU_HEAVY_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = MITSU_HEAVY_FRAMES;                                   // 1 frame\n                        auto_repetition_pause_len   = 0;;\n                        repeat_frame_pause_len      = IRSND_MITSU_HEAVY_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_40_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\n                    case IRMP_RECS80_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RECS80_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_RECS80_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_RECS80_PULSE_LEN;\n                        pause_1_len                 = IRSND_RECS80_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_RECS80_PULSE_LEN;\n                        pause_0_len                 = IRSND_RECS80_0_PAUSE_LEN - 1;\n                        has_stop_bit                = RECS80_STOP_BIT;\n                        complete_data_len           = RECS80_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RECS80_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\n                    case IRMP_RECS80EXT_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RECS80EXT_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_RECS80EXT_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_RECS80EXT_PULSE_LEN;\n                        pause_1_len                 = IRSND_RECS80EXT_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_RECS80EXT_PULSE_LEN;\n                        pause_0_len                 = IRSND_RECS80EXT_0_PAUSE_LEN - 1;\n                        has_stop_bit                = RECS80EXT_STOP_BIT;\n                        complete_data_len           = RECS80EXT_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RECS80EXT_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n                    case IRMP_TELEFUNKEN_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_TELEFUNKEN_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_TELEFUNKEN_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_TELEFUNKEN_PULSE_LEN;\n                        pause_1_len                 = IRSND_TELEFUNKEN_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_TELEFUNKEN_PULSE_LEN;\n                        pause_0_len                 = IRSND_TELEFUNKEN_0_PAUSE_LEN - 1;\n                        has_stop_bit                = TELEFUNKEN_STOP_BIT;\n                        complete_data_len           = TELEFUNKEN_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frames\n                        auto_repetition_pause_len   = 0;                                                    // IRSND_TELEFUNKEN_AUTO_REPETITION_PAUSE_LEN; xx ms pause\n                        repeat_frame_pause_len      = IRSND_TELEFUNKEN_FRAME_REPEAT_PAUSE_LEN;              // 117 msec pause\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RC5_PROTOCOL == 1\n                    case IRMP_RC5_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RC5_BIT_LEN;\n                        startbit_pause_len          = IRSND_RC5_BIT_LEN;\n                        pulse_len                   = IRSND_RC5_BIT_LEN;\n                        pause_len                   = IRSND_RC5_BIT_LEN;\n                        has_stop_bit                = RC5_STOP_BIT;\n                        complete_data_len           = RC5_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RC5_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n                    case IRMP_RC6_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RC6_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_RC6_START_BIT_PAUSE_LEN - 1;\n                        pulse_len                   = IRSND_RC6_BIT_LEN;\n                        pause_len                   = IRSND_RC6_BIT_LEN;\n                        has_stop_bit                = RC6_STOP_BIT;\n                        complete_data_len           = RC6_COMPLETE_DATA_LEN_SHORT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RC6_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RC6A_PROTOCOL == 1\n                    case IRMP_RC6A_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RC6_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_RC6_START_BIT_PAUSE_LEN - 1;\n                        pulse_len                   = IRSND_RC6_BIT_LEN;\n                        pause_len                   = IRSND_RC6_BIT_LEN;\n                        has_stop_bit                = RC6_STOP_BIT;\n                        complete_data_len           = RC6_COMPLETE_DATA_LEN_LONG;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RC6_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_DENON_PROTOCOL == 1\n                    case IRMP_DENON_PROTOCOL:\n                    {\n                        startbit_pulse_len          = 0x00;\n                        startbit_pause_len          = 0x00;\n                        pulse_1_len                 = IRSND_DENON_PULSE_LEN;\n                        pause_1_len                 = IRSND_DENON_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_DENON_PULSE_LEN;\n                        pause_0_len                 = IRSND_DENON_0_PAUSE_LEN - 1;\n                        has_stop_bit                = DENON_STOP_BIT;\n                        complete_data_len           = DENON_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = DENON_FRAMES;                                         // 2 frames, 2nd with inverted command\n                        auto_repetition_pause_len   = IRSND_DENON_AUTO_REPETITION_PAUSE_LEN;                // 65 ms pause after 1st frame\n                        repeat_frame_pause_len      = IRSND_DENON_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);                                                 // in theory 32kHz, in practice 36kHz is better\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_THOMSON_PROTOCOL == 1\n                    case IRMP_THOMSON_PROTOCOL:\n                    {\n                        startbit_pulse_len          = 0x00;\n                        startbit_pause_len          = 0x00;\n                        pulse_1_len                 = IRSND_THOMSON_PULSE_LEN;\n                        pause_1_len                 = IRSND_THOMSON_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_THOMSON_PULSE_LEN;\n                        pause_0_len                 = IRSND_THOMSON_0_PAUSE_LEN - 1;\n                        has_stop_bit                = THOMSON_STOP_BIT;\n                        complete_data_len           = THOMSON_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = THOMSON_FRAMES;                                       // only 1 frame\n                        auto_repetition_pause_len   = IRSND_THOMSON_AUTO_REPETITION_PAUSE_LEN;\n                        repeat_frame_pause_len      = IRSND_THOMSON_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\n                    case IRMP_BOSE_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_BOSE_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_BOSE_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_BOSE_PULSE_LEN;\n                        pause_1_len                 = IRSND_BOSE_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_BOSE_PULSE_LEN;\n                        pause_0_len                 = IRSND_BOSE_0_PAUSE_LEN - 1;\n                        has_stop_bit                = BOSE_STOP_BIT;\n                        complete_data_len           = BOSE_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = BOSE_FRAMES;                                          // 1 frame\n                        auto_repetition_pause_len   = IRSND_BOSE_AUTO_REPETITION_PAUSE_LEN;                 // 40 ms pause\n                        repeat_frame_pause_len      = IRSND_BOSE_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\n                    case IRMP_NUBERT_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_NUBERT_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_NUBERT_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_NUBERT_1_PULSE_LEN;\n                        pause_1_len                 = IRSND_NUBERT_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_NUBERT_0_PULSE_LEN;\n                        pause_0_len                 = IRSND_NUBERT_0_PAUSE_LEN - 1;\n                        has_stop_bit                = NUBERT_STOP_BIT;\n                        complete_data_len           = NUBERT_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = NUBERT_FRAMES;                                        // 2 frames\n                        auto_repetition_pause_len   = IRSND_NUBERT_AUTO_REPETITION_PAUSE_LEN;               // 35 ms pause\n                        repeat_frame_pause_len      = IRSND_NUBERT_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_FAN_PROTOCOL == 1\n                    case IRMP_FAN_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_FAN_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_FAN_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_FAN_1_PULSE_LEN;\n                        pause_1_len                 = IRSND_FAN_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_FAN_0_PULSE_LEN;\n                        pause_0_len                 = IRSND_FAN_0_PAUSE_LEN - 1;\n                        has_stop_bit                = FAN_STOP_BIT;\n                        complete_data_len           = FAN_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = FAN_FRAMES;                                           // only 1 frame\n                        auto_repetition_pause_len   = IRSND_FAN_AUTO_REPETITION_PAUSE_LEN;                  // 35 ms pause\n                        repeat_frame_pause_len      = IRSND_FAN_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\n                    case IRMP_SPEAKER_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_SPEAKER_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_SPEAKER_START_BIT_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_SPEAKER_1_PULSE_LEN;\n                        pause_1_len                 = IRSND_SPEAKER_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_SPEAKER_0_PULSE_LEN;\n                        pause_0_len                 = IRSND_SPEAKER_0_PAUSE_LEN - 1;\n                        has_stop_bit                = SPEAKER_STOP_BIT;\n                        complete_data_len           = SPEAKER_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = SPEAKER_FRAMES;                                       // 2 frames\n                        auto_repetition_pause_len   = IRSND_SPEAKER_AUTO_REPETITION_PAUSE_LEN;              // 35 ms pause\n                        repeat_frame_pause_len      = IRSND_SPEAKER_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n                    case IRMP_BANG_OLUFSEN_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_BANG_OLUFSEN_START_BIT1_PULSE_LEN;\n                        startbit_pause_len          = IRSND_BANG_OLUFSEN_START_BIT1_PAUSE_LEN - 1;\n                        pulse_1_len                 = IRSND_BANG_OLUFSEN_PULSE_LEN;\n                        pause_1_len                 = IRSND_BANG_OLUFSEN_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_BANG_OLUFSEN_PULSE_LEN;\n                        pause_0_len                 = IRSND_BANG_OLUFSEN_0_PAUSE_LEN - 1;\n                        has_stop_bit                = BANG_OLUFSEN_STOP_BIT;\n                        complete_data_len           = BANG_OLUFSEN_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN;\n                        last_bit_value              = 0;\n                        irsnd_set_freq (IRSND_FREQ_455_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\n                    case IRMP_GRUNDIG_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        startbit_pause_len          = IRSND_GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN - 1;\n                        pulse_len                   = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        pause_len                   = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        has_stop_bit                = GRUNDIG_NOKIA_IR60_STOP_BIT;\n                        complete_data_len           = GRUNDIG_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = GRUNDIG_FRAMES;                                       // 2 frames\n                        auto_repetition_pause_len   = IRSND_GRUNDIG_AUTO_REPETITION_PAUSE_LEN;              // 20m sec pause\n                        repeat_frame_pause_len      = IRSND_GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_IR60_PROTOCOL == 1\n                    case IRMP_IR60_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        startbit_pause_len          = IRSND_GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN - 1;\n                        pulse_len                   = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        pause_len                   = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        has_stop_bit                = GRUNDIG_NOKIA_IR60_STOP_BIT;\n                        complete_data_len           = IR60_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = IR60_FRAMES;                                          // 2 frames\n                        auto_repetition_pause_len   = IRSND_IR60_AUTO_REPETITION_PAUSE_LEN;                 // 20m sec pause\n                        repeat_frame_pause_len      = IRSND_GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause\n                        irsnd_set_freq (IRSND_FREQ_30_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n                    case IRMP_NOKIA_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        startbit_pause_len          = IRSND_GRUNDIG_NOKIA_IR60_PRE_PAUSE_LEN - 1;\n                        pulse_len                   = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        pause_len                   = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                        has_stop_bit                = GRUNDIG_NOKIA_IR60_STOP_BIT;\n                        complete_data_len           = NOKIA_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = NOKIA_FRAMES;                                         // 2 frames\n                        auto_repetition_pause_len   = IRSND_NOKIA_AUTO_REPETITION_PAUSE_LEN;                // 20 msec pause\n                        repeat_frame_pause_len      = IRSND_GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_LEN;      // 117 msec pause\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1\n                    case IRMP_SIEMENS_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_SIEMENS_BIT_LEN;\n                        startbit_pause_len          = IRSND_SIEMENS_BIT_LEN;\n                        pulse_len                   = IRSND_SIEMENS_BIT_LEN;\n                        pause_len                   = IRSND_SIEMENS_BIT_LEN;\n                        has_stop_bit                = SIEMENS_OR_RUWIDO_STOP_BIT;\n                        complete_data_len           = SIEMENS_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_SIEMENS_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RUWIDO_PROTOCOL == 1\n                    case IRMP_RUWIDO_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RUWIDO_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_RUWIDO_START_BIT_PAUSE_LEN;\n                        pulse_len                   = IRSND_RUWIDO_BIT_PULSE_LEN;\n                        pause_len                   = IRSND_RUWIDO_BIT_PAUSE_LEN;\n                        has_stop_bit                = SIEMENS_OR_RUWIDO_STOP_BIT;\n                        complete_data_len           = RUWIDO_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RUWIDO_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_36_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_FDC_PROTOCOL == 1\n                    case IRMP_FDC_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_FDC_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_FDC_START_BIT_PAUSE_LEN - 1;\n                        complete_data_len           = FDC_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_FDC_PULSE_LEN;\n                        pause_1_len                 = IRSND_FDC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_FDC_PULSE_LEN;\n                        pause_0_len                 = IRSND_FDC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = FDC_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_FDC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1\n                    case IRMP_RCCAR_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_RCCAR_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_RCCAR_START_BIT_PAUSE_LEN - 1;\n                        complete_data_len           = RCCAR_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_RCCAR_PULSE_LEN;\n                        pause_1_len                 = IRSND_RCCAR_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_RCCAR_PULSE_LEN;\n                        pause_0_len                 = IRSND_RCCAR_0_PAUSE_LEN - 1;\n                        has_stop_bit                = RCCAR_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_RCCAR_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_JVC_PROTOCOL == 1\n                    case IRMP_JVC_PROTOCOL:\n                    {\n                        if (repeat_counter != 0)                                                            // skip start bit if repetition frame\n                        {\n                            current_bit = 0;\n                        }\n\n                        startbit_pulse_len          = IRSND_JVC_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_JVC_START_BIT_PAUSE_LEN - 1;\n                        complete_data_len           = JVC_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_JVC_PULSE_LEN;\n                        pause_1_len                 = IRSND_JVC_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_JVC_PULSE_LEN;\n                        pause_0_len                 = IRSND_JVC_0_PAUSE_LEN - 1;\n                        has_stop_bit                = JVC_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_JVC_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_NIKON_PROTOCOL == 1\n                    case IRMP_NIKON_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_NIKON_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_NIKON_START_BIT_PAUSE_LEN;\n                        complete_data_len           = NIKON_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_NIKON_PULSE_LEN;\n                        pause_1_len                 = IRSND_NIKON_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_NIKON_PULSE_LEN;\n                        pause_0_len                 = IRSND_NIKON_0_PAUSE_LEN - 1;\n                        has_stop_bit                = NIKON_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_NIKON_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_LEGO_PROTOCOL == 1\n                    case IRMP_LEGO_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_LEGO_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_LEGO_START_BIT_PAUSE_LEN - 1;\n                        complete_data_len           = LEGO_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_LEGO_PULSE_LEN;\n                        pause_1_len                 = IRSND_LEGO_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_LEGO_PULSE_LEN;\n                        pause_0_len                 = IRSND_LEGO_0_PAUSE_LEN - 1;\n                        has_stop_bit                = LEGO_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_LEGO_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_IRMP16_PROTOCOL == 1\n                    case IRMP_IRMP16_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_IRMP16_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_IRMP16_START_BIT_PAUSE_LEN - 1;\n                        complete_data_len           = IRMP16_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_IRMP16_PULSE_LEN;\n                        pause_1_len                 = IRSND_IRMP16_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_IRMP16_PULSE_LEN;\n                        pause_0_len                 = IRSND_IRMP16_0_PAUSE_LEN - 1;\n                        has_stop_bit                = IRMP16_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_IRMP16_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1\n                    case IRMP_A1TVBOX_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_A1TVBOX_BIT_PULSE_LEN;                          // don't use A1TVBOX_START_BIT_PULSE_LEN\n                        startbit_pause_len          = IRSND_A1TVBOX_BIT_PAUSE_LEN;                          // don't use A1TVBOX_START_BIT_PAUSE_LEN\n                        pulse_len                   = IRSND_A1TVBOX_BIT_PULSE_LEN;\n                        pause_len                   = IRSND_A1TVBOX_BIT_PAUSE_LEN;\n                        has_stop_bit                = A1TVBOX_STOP_BIT;\n                        complete_data_len           = A1TVBOX_COMPLETE_DATA_LEN + 1;                        // we send stop bit as data\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_A1TVBOX_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\n                    case IRMP_ROOMBA_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_ROOMBA_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_ROOMBA_START_BIT_PAUSE_LEN;\n                        pulse_1_len                 = IRSND_ROOMBA_1_PULSE_LEN;\n                        pause_1_len                 = IRSND_ROOMBA_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_ROOMBA_0_PULSE_LEN;\n                        pause_0_len                 = IRSND_ROOMBA_0_PAUSE_LEN - 1;\n                        has_stop_bit                = ROOMBA_STOP_BIT;\n                        complete_data_len           = ROOMBA_COMPLETE_DATA_LEN;\n                        n_auto_repetitions          = ROOMBA_FRAMES;                                        // 8 frames\n                        auto_repetition_pause_len   = IRSND_ROOMBA_FRAME_REPEAT_PAUSE_LEN;\n                        repeat_frame_pause_len      = IRSND_ROOMBA_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\n                    case IRMP_PENTAX_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_PENTAX_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_PENTAX_START_BIT_PAUSE_LEN;\n                        complete_data_len           = PENTAX_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_PENTAX_PULSE_LEN;\n                        pause_1_len                 = IRSND_PENTAX_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_PENTAX_PULSE_LEN;\n                        pause_0_len                 = IRSND_PENTAX_0_PAUSE_LEN - 1;\n                        has_stop_bit                = PENTAX_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_PENTAX_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n#if IRSND_SUPPORT_ACP24_PROTOCOL == 1\n                    case IRMP_ACP24_PROTOCOL:\n                    {\n                        startbit_pulse_len          = IRSND_ACP24_START_BIT_PULSE_LEN;\n                        startbit_pause_len          = IRSND_ACP24_START_BIT_PAUSE_LEN - 1;\n                        complete_data_len           = ACP24_COMPLETE_DATA_LEN;\n                        pulse_1_len                 = IRSND_ACP24_PULSE_LEN;\n                        pause_1_len                 = IRSND_ACP24_1_PAUSE_LEN - 1;\n                        pulse_0_len                 = IRSND_ACP24_PULSE_LEN;\n                        pause_0_len                 = IRSND_ACP24_0_PAUSE_LEN - 1;\n                        has_stop_bit                = ACP24_STOP_BIT;\n                        n_auto_repetitions          = 1;                                                    // 1 frame\n                        auto_repetition_pause_len   = 0;\n                        repeat_frame_pause_len      = IRSND_ACP24_FRAME_REPEAT_PAUSE_LEN;\n                        irsnd_set_freq (IRSND_FREQ_38_KHZ);\n                        break;\n                    }\n#endif\n// @formatter:off\n                    default:\n                    {\n                        irsnd_busy = FALSE; // no enabled protocol is selected -> stop immediately\n                        break;\n                    }\n// @formatter:on\n\n                }\n            }\n        } // if (current_bit == 0xFF && new_frame)\n\n        if (irsnd_busy)\n        {\n            new_frame = FALSE; // we just have sent start bit here\n\n            switch (irsnd_protocol)\n            {\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\n                case IRMP_SIRCS_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n                case IRMP_NEC_PROTOCOL:\n                case IRMP_NEC_REPETITION_PROTOCOL:\n                case IRMP_ONKYO_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_NEC16_PROTOCOL == 1\n                case IRMP_NEC16_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_NEC42_PROTOCOL == 1\n                case IRMP_NEC42_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_LGAIR_PROTOCOL == 1\n                case IRMP_LGAIR_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n                case IRMP_SAMSUNG_PROTOCOL:\n                case IRMP_SAMSUNG32_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_SAMSUNG48_PROTOCOL == 1\n                case IRMP_SAMSUNG48_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\n                case IRMP_MATSUSHITA_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\n                case IRMP_TECHNICS_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\n                case IRMP_KASEIKYO_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\n                case IRMP_RECS80_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\n                case IRMP_RECS80EXT_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_DENON_PROTOCOL == 1\n                case IRMP_DENON_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\n                case IRMP_NUBERT_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_FAN_PROTOCOL == 1\n                case IRMP_FAN_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\n                case IRMP_SPEAKER_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n                case IRMP_BANG_OLUFSEN_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_FDC_PROTOCOL == 1\n                case IRMP_FDC_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1\n                case IRMP_RCCAR_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_JVC_PROTOCOL == 1\n                case IRMP_JVC_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_NIKON_PROTOCOL == 1\n                case IRMP_NIKON_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_LEGO_PROTOCOL == 1\n                case IRMP_LEGO_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_THOMSON_PROTOCOL == 1\n                case IRMP_THOMSON_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\n                case IRMP_ROOMBA_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n                case IRMP_TELEFUNKEN_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\n                case IRMP_PENTAX_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\n                case IRMP_PANASONIC_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_ACP24_PROTOCOL == 1\n                case IRMP_ACP24_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\n                case IRMP_BOSE_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n                case IRMP_MITSU_HEAVY_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_IRMP16_PROTOCOL == 1\n                case IRMP_IRMP16_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_MELINERA_PROTOCOL == 1\n                case IRMP_MELINERA_PROTOCOL:\n#endif\n\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1  || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_NEC16_PROTOCOL == 1 || IRSND_SUPPORT_NEC42_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_LGAIR_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 || IRSND_SUPPORT_TECHNICS_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1 || IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_FAN_PROTOCOL == 1 || IRSND_SUPPORT_SPEAKER_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 || IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_LEGO_PROTOCOL == 1 || IRSND_SUPPORT_THOMSON_PROTOCOL == 1 || IRSND_SUPPORT_ROOMBA_PROTOCOL == 1 || IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_PENTAX_PROTOCOL == 1 || IRSND_SUPPORT_PANASONIC_PROTOCOL == 1 || IRSND_SUPPORT_ACP24_PROTOCOL == 1 || IRSND_SUPPORT_BOSE_PROTOCOL == 1 || \\\n    IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1 || IRSND_SUPPORT_IRMP16_PROTOCOL == 1 || IRSND_SUPPORT_MELINERA_PROTOCOL // guard for content of case\n                {\n                    if (pulse_counter == 0)\n                    {\n                        if (current_bit == 0xFF)                                                        // send start bit\n                        {\n                            pulse_len = startbit_pulse_len;\n                            pause_len = startbit_pause_len;\n                        }\n                        else if (current_bit < complete_data_len)                                       // send n'th bit\n                        {\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n                            if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)\n                            {\n                                if (current_bit < SAMSUNG_ADDRESS_LEN)                                  // send address bits\n                                {\n                                    pulse_len = IRSND_SAMSUNG_PULSE_LEN;\n                                    pause_len = (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 7)))) ?\n                                                    (IRSND_SAMSUNG_1_PAUSE_LEN - 1) : (IRSND_SAMSUNG_0_PAUSE_LEN - 1);\n                                }\n                                else if (current_bit == SAMSUNG_ADDRESS_LEN)                            // send SYNC bit (16th bit)\n                                {\n                                    pulse_len = IRSND_SAMSUNG_PULSE_LEN;\n                                    pause_len = IRSND_SAMSUNG_START_BIT_PAUSE_LEN - 1;\n                                }\n                                else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN)                       // send n'th bit\n                                {\n                                    uint8_t cur_bit = current_bit - 1;                                  // sync skipped, offset = -1 !\n\n                                    pulse_len = IRSND_SAMSUNG_PULSE_LEN;\n                                    pause_len = (irsnd_buffer[cur_bit >> 3] & (1<<(7-(cur_bit & 7)))) ?\n                                                    (IRSND_SAMSUNG_1_PAUSE_LEN - 1) : (IRSND_SAMSUNG_0_PAUSE_LEN - 1);\n                                }\n                            }\n                            else\n#endif\n\n#if IRSND_SUPPORT_NEC16_PROTOCOL == 1\n                            if (irsnd_protocol == IRMP_NEC16_PROTOCOL)\n                            {\n                                if (current_bit < NEC16_ADDRESS_LEN)                                    // send address bits\n                                {\n                                    pulse_len = IRSND_NEC_PULSE_LEN;\n                                    pause_len = (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 7)))) ?\n                                                    (IRSND_NEC_1_PAUSE_LEN - 1) : (IRSND_NEC_0_PAUSE_LEN - 1);\n                                }\n                                else if (current_bit == NEC16_ADDRESS_LEN)                              // send SYNC bit (8th bit)\n                                {\n                                    pulse_len = IRSND_NEC_PULSE_LEN;\n                                    pause_len = IRSND_NEC_START_BIT_PAUSE_LEN - 1;\n                                }\n                                else if (current_bit < NEC16_COMPLETE_DATA_LEN + 1)                     // send n'th bit\n                                {\n                                    uint8_t cur_bit = current_bit - 1;                                  // sync skipped, offset = -1 !\n\n                                    pulse_len = IRSND_NEC_PULSE_LEN;\n                                    pause_len = (irsnd_buffer[cur_bit >> 3] & (1<<(7-(cur_bit & 7)))) ?\n                                                    (IRSND_NEC_1_PAUSE_LEN - 1) : (IRSND_NEC_0_PAUSE_LEN - 1);\n                                }\n                            }\n                            else\n#endif\n\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n                            if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)\n                            {\n                                if (current_bit == 0)                                                   // send 2nd start bit\n                                {\n                                    pulse_len = IRSND_BANG_OLUFSEN_START_BIT2_PULSE_LEN;\n                                    pause_len = IRSND_BANG_OLUFSEN_START_BIT2_PAUSE_LEN - 1;\n                                }\n                                else if (current_bit == 1)                                              // send 3rd start bit\n                                {\n                                    pulse_len = IRSND_BANG_OLUFSEN_START_BIT3_PULSE_LEN;\n                                    pause_len = IRSND_BANG_OLUFSEN_START_BIT3_PAUSE_LEN - 1;\n                                }\n                                else if (current_bit == 2)                                              // send 4th start bit\n                                {\n                                    pulse_len = IRSND_BANG_OLUFSEN_START_BIT2_PULSE_LEN;\n                                    pause_len = IRSND_BANG_OLUFSEN_START_BIT2_PAUSE_LEN - 1;\n                                }\n                                else if (current_bit == 19)                                             // send trailer bit\n                                {\n                                    pulse_len = IRSND_BANG_OLUFSEN_PULSE_LEN;\n                                    pause_len = IRSND_BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN - 1;\n                                }\n                                else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN)                  // send n'th bit\n                                {\n                                    uint8_t cur_bit_value = (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 7)))) ? 1 : 0;\n                                    pulse_len = IRSND_BANG_OLUFSEN_PULSE_LEN;\n\n                                    if (cur_bit_value == last_bit_value)\n                                    {\n                                        pause_len = IRSND_BANG_OLUFSEN_R_PAUSE_LEN - 1;\n                                    }\n                                    else\n                                    {\n                                        pause_len = cur_bit_value ? (IRSND_BANG_OLUFSEN_1_PAUSE_LEN - 1) : (IRSND_BANG_OLUFSEN_0_PAUSE_LEN - 1);\n                                        last_bit_value = cur_bit_value;\n                                    }\n                                }\n                            }\n                            else\n#endif\n                            if (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 7))))\n                            {\n                                pulse_len = pulse_1_len;\n                                pause_len = pause_1_len;\n                            }\n                            else\n                            {\n                                pulse_len = pulse_0_len;\n                                pause_len = pause_0_len;\n                            }\n                        }\n                        else if (has_stop_bit)                                                          // send stop bit\n                        {\n                            pulse_len = pulse_0_len;\n\n                            if (auto_repetition_counter < n_auto_repetitions)\n                            {\n                                pause_len = pause_0_len;\n                            }\n                            else\n                            {\n                                pause_len = 255;                                                        // last frame: pause of 255\n                            }\n                        }\n                    }\n\n                    if (pulse_counter < pulse_len)\n                    {\n                        if (pulse_counter == 0)\n                        {\n                            irsnd_on ();\n                        }\n                        pulse_counter++;\n                    }\n                    else if (pause_counter < pause_len)\n                    {\n                        if (pause_counter == 0)\n                        {\n                            irsnd_off ();\n                        }\n                        pause_counter++;\n                    }\n                    else\n                    {\n                        current_bit++;\n\n                        if (current_bit >= complete_data_len + has_stop_bit)\n                        {\n                            /*\n                             * End of current frame, prepare for a new frame\n                             */\n                            current_bit = 0xFF;\n                            new_frame = TRUE;\n                            auto_repetition_counter++;\n\n                            if (auto_repetition_counter == n_auto_repetitions)\n                            {\n                                irsnd_busy = FALSE;\n                                auto_repetition_counter = 0;\n                            }\n                        }\n\n                        pulse_counter = 0;\n                        pause_counter = 0;\n                    }\n                    break;\n                }\n#endif\n\n#if IRSND_SUPPORT_RC5_PROTOCOL == 1\n                case IRMP_RC5_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n                case IRMP_RC6_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_RC6A_PROTOCOL == 1\n                case IRMP_RC6A_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1\n                case IRMP_SIEMENS_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_RUWIDO_PROTOCOL == 1\n                case IRMP_RUWIDO_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\n                case IRMP_GRUNDIG_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_IR60_PROTOCOL == 1\n                case IRMP_IR60_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n                case IRMP_NOKIA_PROTOCOL:\n#endif\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1\n                case IRMP_A1TVBOX_PROTOCOL:\n#endif\n\n#if IRSND_SUPPORT_RC5_PROTOCOL      == 1 || \\\n    IRSND_SUPPORT_RC6_PROTOCOL      == 1 || \\\n    IRSND_SUPPORT_RC6A_PROTOCOL     == 1 || \\\n    IRSND_SUPPORT_RUWIDO_PROTOCOL   == 1 || \\\n    IRSND_SUPPORT_SIEMENS_PROTOCOL  == 1 || \\\n    IRSND_SUPPORT_GRUNDIG_PROTOCOL  == 1 || \\\n    IRSND_SUPPORT_IR60_PROTOCOL     == 1 || \\\n    IRSND_SUPPORT_NOKIA_PROTOCOL    == 1 || \\\n    IRSND_SUPPORT_A1TVBOX_PROTOCOL  == 1 // guard for content of case\n                {\n                    if (pulse_counter == pulse_len && pause_counter == pause_len)\n                    {\n                        current_bit++;\n\n                        if (current_bit >= complete_data_len)\n                        {\n                            current_bit = 0xFF;\n\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_IR60_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n                            if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_IR60_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)\n                            {\n                                auto_repetition_counter++;\n\n                                if (repeat_counter > 0)\n                                {                                           // set 117 msec pause time\n                                    auto_repetition_pause_len = IRSND_GRUNDIG_NOKIA_IR60_FRAME_REPEAT_PAUSE_LEN;\n                                }\n\n                                if (repeat_counter < n_repeat_frames)       // tricky: repeat n info frames per auto repetition before sending last stop frame\n                                {\n                                    n_auto_repetitions++;                   // increment number of auto repetitions\n                                    repeat_counter++;\n                                }\n                                else if (auto_repetition_counter == n_auto_repetitions)\n                                {\n                                    irsnd_busy = FALSE;\n                                    auto_repetition_counter = 0;\n                                }\n                            }\n                            else\n#endif\n                            {\n                                irsnd_busy  = FALSE;\n                            }\n\n                            new_frame = TRUE;\n                            irsnd_off ();\n                        }\n\n                        pulse_counter = 0;\n                        pause_counter = 0;\n                    }\n\n                    if (! new_frame)\n                    {\n                        uint8_t first_pulse;\n\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_IR60_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n                        if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_IR60_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)\n                        {\n                            if (current_bit == 0xFF ||                                                                  // start bit of start-frame\n                                (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) ||                       // start bit of info-frame (Grundig)\n                                (irsnd_protocol == IRMP_IR60_PROTOCOL && current_bit == 7) ||                           // start bit of data frame (IR60)\n                                (irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47)))    // start bit of info- or stop-frame (Nokia)\n                            {\n                                pulse_len = startbit_pulse_len;\n                                pause_len = startbit_pause_len;\n                                first_pulse = TRUE;\n                            }\n                            else                                                                                        // send n'th bit\n                            {\n                                pulse_len = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                                pause_len = IRSND_GRUNDIG_NOKIA_IR60_BIT_LEN;\n                                first_pulse = (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 7)))) ? TRUE : FALSE;\n                            }\n                        }\n                        else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_RC6_PROTOCOL || irsnd_protocol == IRMP_RC6A_PROTOCOL ||\n                             //     irsnd_protocol == IRMP_SIEMENS_PROTOCOL || irsnd_protocol == IRMP_RUWIDO_PROTOCOL)\n#endif\n                        {\n                            if (current_bit == 0xFF)                                                                    // 1 start bit\n                            {\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1\n                                if (irsnd_protocol == IRMP_RC6_PROTOCOL || irsnd_protocol == IRMP_RC6A_PROTOCOL)\n                                {\n                                    pulse_len = startbit_pulse_len;\n                                    pause_len = startbit_pause_len;\n                                }\n                                else\n#endif\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1\n                                if (irsnd_protocol == IRMP_A1TVBOX_PROTOCOL)\n                                {\n                                    current_bit = 0;\n                                }\n                                else\n#endif\n                                {\n                                    ;\n                                }\n\n                                first_pulse = TRUE;\n                            }\n                            else                                                                                        // send n'th bit\n                            {\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1 || IRSND_SUPPORT_RC6A_PROTOCOL == 1\n                                if (irsnd_protocol == IRMP_RC6_PROTOCOL || irsnd_protocol == IRMP_RC6A_PROTOCOL)\n                                {\n                                    pulse_len = IRSND_RC6_BIT_LEN;\n                                    pause_len = IRSND_RC6_BIT_LEN;\n\n                                    if (irsnd_protocol == IRMP_RC6_PROTOCOL)\n                                    {\n                                        if (current_bit == 4)                                                           // toggle bit (double len)\n                                        {\n                                            pulse_len = IRSND_RC6_BIT_2_LEN;                                            // = 2 * RC_BIT_LEN\n                                            pause_len = IRSND_RC6_BIT_2_LEN;                                            // = 2 * RC_BIT_LEN\n                                        }\n                                    }\n                                    else // if (irsnd_protocol == IRMP_RC6A_PROTOCOL)\n                                    {\n                                        if (current_bit == 4)                                                           // toggle bit (double len)\n                                        {\n                                            pulse_len = IRSND_RC6_BIT_3_LEN;                                            // = 3 * RC6_BIT_LEN\n                                            pause_len = IRSND_RC6_BIT_2_LEN;                                            // = 2 * RC6_BIT_LEN\n                                        }\n                                        else if (current_bit == 5)                                                      // toggle bit (double len)\n                                        {\n                                            pause_len = IRSND_RC6_BIT_2_LEN;                                            // = 2 * RC6_BIT_LEN\n                                        }\n                                    }\n                                }\n#endif\n                                first_pulse = (irsnd_buffer[current_bit >> 3] & (1<<(7-(current_bit & 7)))) ? TRUE : FALSE;\n                            }\n\n                            if (irsnd_protocol == IRMP_RC5_PROTOCOL)\n                            {\n                                first_pulse = first_pulse ? FALSE : TRUE;\n                            }\n                        }\n\n                        if (first_pulse)\n                        {\n                            // printf (\"first_pulse: current_bit: %d  %d < %d  %d < %d\\n\", current_bit, pause_counter, pause_len, pulse_counter, pulse_len);\n\n                            if (pulse_counter < pulse_len)\n                            {\n                                if (pulse_counter == 0)\n                                {\n                                    irsnd_on ();\n                                }\n                                pulse_counter++;\n                            }\n                            else // if (pause_counter < pause_len)\n                            {\n                                if (pause_counter == 0)\n                                {\n                                    irsnd_off ();\n                                }\n                                pause_counter++;\n                            }\n                        }\n                        else\n                        {\n                            // printf (\"first_pause: current_bit: %d  %d < %d  %d < %d\\n\", current_bit, pause_counter, pause_len, pulse_counter, pulse_len);\n\n                            if (pause_counter < pause_len)\n                            {\n                                if (pause_counter == 0)\n                                {\n                                    irsnd_off ();\n                                }\n                                pause_counter++;\n                            }\n                            else // if (pulse_counter < pulse_len)\n                            {\n                                if (pulse_counter == 0)\n                                {\n                                    irsnd_on ();\n                                }\n                                pulse_counter++;\n                            }\n                        }\n                    }\n                    break;\n                }\n#endif // IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_RC6_PROTOCOL == 1 || || IRSND_SUPPORT_RC6A_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 ||\n            // IRSND_SUPPORT_RUWIDO_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_IR60_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n// @formatter:off\n                default:\n                {\n                    // Just in case ...\n                    irsnd_busy = FALSE;\n                    break;\n                }\n// @formatter:on\n            }\n        }\n\n        if (!irsnd_busy)\n        {\n            /*\n             * Check if we are really finished or if we must send a repeat or a trailing space\n             */\n            if (repeat_counter < n_repeat_frames)\n            {\n                // repeat again\n#if IRSND_SUPPORT_FDC_PROTOCOL == 1\n                if (irsnd_protocol == IRMP_FDC_PROTOCOL)\n                {\n                    irsnd_buffer[2] |= 0x0F;\n                }\n#endif\n                repeat_counter++;\n                irsnd_busy = TRUE;\n            }\n            else\n            {\n#if !defined(ARDUINO) // never send a trailing space for Arduino\n                if (!irsnd_suppress_trailer)\n                {\n                    /*\n                     * Switch to mode: send last trailing space\n                     */\n                    irsnd_busy = TRUE;\n                    send_last_trailer = TRUE;\n                }\n#endif\n                // cleanup for ending transmission\n                n_repeat_frames = 0;\n                repeat_counter = 0;\n                repeat_frame_pause_len = 0;\n            }\n        }\n    }\n\n#if defined(ANALYZE)\n    if (irsnd_is_on)\n    {\n        putchar ('0');\n    }\n    else\n    {\n        putchar ('1');\n    }\n#endif\n\n    return irsnd_busy;\n}\n\n#if defined(ANALYZE)\n\n// main function - for unix/linux + windows only!\n// AVR: see main.c!\n// Compile it under linux with:\n// cc irsnd.c -o irsnd\n//\n// usage: ./irsnd protocol hex-address hex-command >filename\n\nint\nmain (int argc, char ** argv)\n{\n    int         protocol;\n    int         address;\n    int         command;\n    IRMP_DATA   irmp_data;\n\n    if (argc != 4 && argc != 5)\n    {\n        fprintf (stderr, \"usage: %s protocol hex-address hex-command [repeat] > filename\\n\", argv[0]);\n        return 1;\n    }\n\n    if (sscanf (argv[1], \"%d\", &protocol) == 1 &&\n        sscanf (argv[2], \"%x\", &address) == 1 &&\n        sscanf (argv[3], \"%x\", &command) == 1)\n    {\n        irmp_data.protocol = protocol;\n        irmp_data.address = address;\n        irmp_data.command = command;\n\n        if (argc == 5)\n        {\n            irmp_data.flags = atoi (argv[4]);\n        }\n        else\n        {\n            irmp_data.flags = 0;\n        }\n\n        irsnd_init ();\n\n        (void) irsnd_send_data (&irmp_data, TRUE);\n\n        while (irsnd_busy)\n        {\n            irsnd_ISR ();\n        }\n\n        putchar ('\\n');\n\n#if 0 // enable here to send twice\n        (void) irsnd_send_data (&irmp_data, TRUE);\n\n        while (irsnd_busy)\n        {\n            irsnd_ISR ();\n        }\n\n        putchar ('\\n');\n#endif\n    }\n    else\n    {\n        fprintf (stderr, \"%s: wrong arguments\\n\", argv[0]);\n        return 1;\n    }\n    return 0;\n}\n\n#endif // ANALYZE\n"
  },
  {
    "path": "src/irsndArduinoExt.h",
    "content": "/*\n * irsndArduinoExt.h  Arduino extensions to the original irsnd.h\n *\n *  Copyright (C) 2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#if defined(ARDUINO)\n#ifndef _IRSND_ARDUINO_EXT_H\n#define _IRSND_ARDUINO_EXT_H\n\n#include \"irmpVersion.h\"\n\n#include \"digitalWriteFast.h\" // we use pinModeFast() and digitalReadFast() and digitalWriteFast() in turn\n\n#if defined(IR_OUTPUT_IS_ACTIVE_LOW) || defined(IRSND_GENERATE_NO_SEND_RF)\n#define IR_OUTPUT_ACTIVE_LEVEL      LOW\n#define IR_OUTPUT_INACTIVE_LEVEL    HIGH\n#else\n#define IR_OUTPUT_ACTIVE_LEVEL      HIGH\n#define IR_OUTPUT_INACTIVE_LEVEL    LOW\n#endif\n//\n/*\n * Set hardware pin defaults for Arduino IDE if no IRSND_OUTPUT_PIN specified\n */\n#if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\nextern uint_fast8_t irsnd_output_pin;\n\n#undef IRSND_OUTPUT_PIN\n#define IRSND_OUTPUT_PIN        irsnd_output_pin\n\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin);\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin, uint_fast8_t aFeedbackLedPin);\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin, uint_fast8_t aFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow);\n\n#else // defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n#  if !defined(IRSND_OUTPUT_PIN)                // Arduino IDE uses IRSND_OUTPUT_PIN instead of PORT and BIT\n#define IRSND_OUTPUT_PIN            4\n#  endif\n#endif // defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n\nvoid irsnd_data_print(Print *aSerial, IRMP_DATA *aIRMPDataPtr);\n\n#if defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE + Sparkfun Apollo3\n#include \"mbed.h\"\n#define F_CPU 0 // dummy definition to avoid warning at irsnd.hpp:27 #error F_CPU unkown\n#endif\n\n#if !defined(IR_TIMING_TEST_PIN)              // Only for test purposes\n#define IR_TIMING_TEST_PIN        5\n#endif\n\n#if ! defined(IRSND_IR_FREQUENCY)\n#define IRSND_IR_FREQUENCY          38000\n#endif\n#define IRSND_INTERRUPT_FREQUENCY   (IRSND_IR_FREQUENCY * 2)  // *2 to toggle output pin at each interrupt\n\n/*\n * For Arduino AVR use timer 2 with FIXED 38000 * 2 = 76000 interrupts per second to toggle output pin.\n * ISR is called each 4. interrupt at a rate of 19000 interrupts per second.\n * (Re)define F_INTERRUPTS to the resulting call value in order to generate correct values for all the protocols.\n */\n#  undef  F_INTERRUPTS\n#  define F_INTERRUPTS              (IRSND_IR_FREQUENCY / 2)   // 19000 interrupts per second\n\nextern volatile uint8_t irsnd_is_on;                // Used by IRTimer.hpp\nextern volatile uint8_t irsnd_busy;                 // Used by IRTimer.hpp\n\n#endif /* _IRSND_ARDUINO_EXT_H */\n#endif // ARDUINO\n"
  },
  {
    "path": "src/irsndArduinoExt.hpp",
    "content": "/*\n * irsndArduinoExt.hpp - Arduino extensions to the original irsnd.c\n *\n *  Copyright (C) 2020  Armin Joachimsmeyer\n *  armin.joachimsmeyer@gmail.com\n *\n *  This file is part of IRMP https://github.com/IRMP-org/IRMP.\n *\n *  IRMP is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 3 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n *  See the GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.\n *\n */\n\n#if defined(ARDUINO)\n\n#undef _IRMP_H_                 // We are in IRSND now! Remove old symbol set from former including irmp.hpp if we use receive and send in the same user program.\n#include \"IRTimer.hpp\"          // include code for timer\n#include \"IRFeedbackLED.hpp\"    // include code for Feedback LED\n#include \"irmpprotocols.hpp\"    // include protocol strings and array of strings\n\n#if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\nuint_fast8_t irsnd_output_pin;\n\n/*\n * Initialize, and activate feedback LED function\n * @param aFeedbackLedPin - if 0 feedback function is disabled\n */\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin, uint_fast8_t aFeedbackLedPin, bool aIrmpLedFeedbackPinIsActiveLow)\n{\n    irsnd_output_pin = aIrsndOutputPin;\n#if !defined(NO_LED_FEEDBACK_CODE)\n    irmp_irsnd_LedFeedbackPin = aFeedbackLedPin;\n    irmp_irsnd_LedFeedbackPinIsActiveLow = aIrmpLedFeedbackPinIsActiveLow;\n\n    /*\n     * enable feedback LED if (aFeedbackLedPin != 0)\n     */\n    irmp_irsnd_LEDFeedback(aFeedbackLedPin);\n#else\n    (void) aFeedbackLedPin; // to avoid compiler warnings\n    (void) aIrmpLedFeedbackPinIsActiveLow; // to avoid compiler warnings\n#endif\n\n    // Do not call irsnd_init_and_store_timer() here, it is done at irsnd_send_data().\n    pinMode(irsnd_output_pin, OUTPUT);\n#  if defined(IRMP_MEASURE_TIMING)\n    pinModeFast(IR_TIMING_TEST_PIN, OUTPUT);\n#  endif\n}\n\n/*\n * Initialize, and activate feedback LED function\n * @param aFeedbackLedPin - if 0 feedback function is disabled\n */\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin, uint_fast8_t aFeedbackLedPin)\n{\n#if defined(NO_LED_FEEDBACK_CODE)\n    irsnd_init(aIrsndOutputPin, aFeedbackLedPin, false);\n#else\n    irsnd_init(aIrsndOutputPin, aFeedbackLedPin, irmp_irsnd_LedFeedbackPinIsActiveLow);\n#endif\n}\n\n/*\n * Initialize, use  feedback LED by using 0 as led pin\n */\nvoid irsnd_init(uint_fast8_t aIrsndOutputPin)\n{\n#if defined(NO_LED_FEEDBACK_CODE)\n    irsnd_init(aIrsndOutputPin, 0, false);\n#else\n    irsnd_init(aIrsndOutputPin, irmp_irsnd_LedFeedbackPin, irmp_irsnd_LedFeedbackPinIsActiveLow);\n#endif\n\n#  if defined(IRMP_FEEDBACK_LED_PIN)\n    // set pin if we have one at hand\n    irmp_irsnd_LedFeedbackPin = IRMP_FEEDBACK_LED_PIN;\n#  endif\n}\n\n#else // defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n/*\n * Init function for defined pins\n */\nvoid irsnd_init(void)\n{\n    // Do not call irsnd_init_and_store_timer() here, it is done at irsnd_send_data().\n    pinModeFast(IRSND_OUTPUT_PIN, OUTPUT);\n#  if defined(IRMP_MEASURE_TIMING)\n    pinModeFast(IR_TIMING_TEST_PIN, OUTPUT);\n#  endif\n}\n#endif // defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n\nstatic void irsnd_set_freq(IRSND_FREQ_TYPE freq __attribute__((unused)))\n{\n    // not supported by now\n}\n\n/*\n * Called from irsnd_ISR to set the IR output\n */\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR irsnd_on(void)\n#else\nvoid irsnd_on(void)\n#endif\n{\n    if (!irsnd_is_on)\n    {\n#if !defined(NO_LED_FEEDBACK_CODE)\n        if (irmp_irsnd_LedFeedbackEnabled)\n        {\n#  if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n            irmp_irsnd_SetFeedbackLED(true);\n#  else\n#    if defined(IRMP_FEEDBACK_LED_PIN)\n#      if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n            // If the built in LED on the board is active LOW\n            digitalWriteFast(IRMP_FEEDBACK_LED_PIN, LOW);\n#      else\n            digitalWriteFast(IRMP_FEEDBACK_LED_PIN, HIGH);\n#      endif\n#    endif\n#  endif\n        }\n#endif\n        irsnd_is_on = TRUE; // evaluated at ISR\n    }\n}\n\n#if defined(ESP8266) || defined(ESP32)\nvoid IRAM_ATTR irsnd_off(void)\n#else\nvoid irsnd_off(void)\n#endif\n{\n    if (irsnd_is_on)\n    {\n#if !defined(NO_LED_FEEDBACK_CODE)\n        // Manage feedback LED\n        if (irmp_irsnd_LedFeedbackEnabled)\n        {\n#  if defined(IRMP_IRSND_ALLOW_DYNAMIC_PINS)\n            irmp_irsnd_SetFeedbackLED(false);\n#  else\n#    if defined(IRMP_FEEDBACK_LED_PIN)\n#      if defined(FEEDBACK_LED_IS_ACTIVE_LOW)\n            // If the built in LED on the board is active LOW\n            digitalWriteFast(IRMP_FEEDBACK_LED_PIN, HIGH);\n#      else\n            digitalWriteFast(IRMP_FEEDBACK_LED_PIN, LOW);\n#      endif\n#    endif\n#  endif\n        }\n#endif\n        irsnd_is_on = FALSE; // evaluated at ISR\n    }\n}\n\n/*\n * irsnd_used_protocol_index holds the protocol numbers (from irsndprotocols.h)\n * for the included protocol name entries of the irsnd_used_protocol_names array below\n * E.g. irmp_used_protocol_index=2,7 and irmp_used_protocol_names=\"NEC\",\"RC5\".\n *\n * Both arrays together are generally smaller than the complete irmp_protocol_names array\n * allowing them to be used on ATtinies even if program code for access is bigger.\n * Flash size is more than 100 bytes less (for 15 protocols) using these arrays.\n */\nconst uint8_t irsnd_used_protocol_index[] PROGMEM =\n{\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\n    IRMP_SIRCS_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n    IRMP_NEC_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n    IRMP_SAMSUNG_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\n    IRMP_MATSUSHITA_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\n    IRMP_KASEIKYO_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\n    IRMP_RECS80_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RC5_PROTOCOL == 1\n    IRMP_RC5_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_DENON_PROTOCOL == 1\n    IRMP_DENON_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n    IRMP_RC6_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n    IRMP_SAMSUNG32_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n    IRMP_APPLE_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\n    IRMP_RECS80EXT_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\n    IRMP_NUBERT_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n    IRMP_BANG_OLUFSEN_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\n    IRMP_GRUNDIG_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n    IRMP_NOKIA_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_SIEMENS_PROTOCOL  == 1\n    IRMP_SIEMENS_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_FDC_PROTOCOL == 1\n    IRMP_FDC_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1\n    IRMP_RCCAR_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_JVC_PROTOCOL == 1\n    IRMP_JVC_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n    IRMP_RC6A_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NIKON_PROTOCOL == 1\n    IRMP_NIKON_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RUWIDO_PROTOCOL == 1\n    IRMP_RUWIDO_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_IR60_PROTOCOL == 1\n    IRMP_IR60_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_KATHREIN_PROTOCOL == 1\n    IRMP_KATHREIN_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NETBOX_PROTOCOL == 1\n    IRMP_NETBOX_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NEC16_PROTOCOL == 1\n    IRMP_NEC16_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NEC42_PROTOCOL == 1\n    IRMP_NEC42_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_LEGO_PROTOCOL == 1\n    IRMP_LEGO_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_THOMSON_PROTOCOL == 1\n    IRMP_THOMSON_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\n    IRMP_BOSE_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1\n    IRMP_A1TVBOX_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_ORTEK_PROTOCOL == 1\n    IRMP_ORTEK_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n    IRMP_TELEFUNKEN_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\n    IRMP_ROOMBA_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RCMM_PROTOCOL  == 1\n    IRMP_RCMM12_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\n    IRMP_SPEAKER_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_LGAIR_PROTOCOL == 1\n    IRMP_LGAIR_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_SAMSUNG48_PROTOCOL == 1\n    IRMP_SAMSUNG48_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_MERLIN_PROTOCOL == 1\n    IRMP_MERLIN_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\n    IRMP_PENTAX_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_FAN_PROTOCOL == 1\n    IRMP_FAN_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_S100_PROTOCOL == 1\n    IRMP_S100_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_ACP24_PROTOCOL  == 1\n    IRMP_ACP24_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\n    IRMP_TECHNICS_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\n    IRMP_PANASONIC_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n    IRMP_MITSU_HEAVY_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_VINCENT_PROTOCOL == 1\n    IRMP_VINCENT_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n    IRMP_SAMSUNGAH_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_IRMP16_PROTOCOL == 1\n    IRMP_IRMP16_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_GREE_PROTOCOL == 1\n    IRMP_GREE_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RCII_PROTOCOL == 1\n    IRMP_RCII_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_METZ_PROTOCOL == 1\n    IRMP_METZ_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n    IRMP_ONKYO_PROTOCOL,\n#endif\n#if IRSND_SUPPORT_RF_GEN24_PROTOCOL == 1\n    RF_GEN24_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RF_X10_PROTOCOL == 1\n    RF_X10_PROTOCOL,\n#endif\n#if IRMP_SUPPORT_RF_MEDION_PROTOCOL == 1\n    RF_MEDION_PROTOCOL\n#endif\n#if IRSND_SUPPORT_MELINERA_PROTOCOL == 1\n    IRMP_MELINERA_PROTOCOL\n#endif\n};\n\nconst char * const irsnd_used_protocol_names[] PROGMEM =\n{\n#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1\n    proto_sircs,\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n    proto_nec,\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n    proto_samsung,\n#endif\n#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1\n    proto_matsushita,\n#endif\n#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1\n    proto_kaseikyo,\n#endif\n#if IRSND_SUPPORT_RECS80_PROTOCOL == 1\n    proto_recs80,\n#endif\n#if IRSND_SUPPORT_RC5_PROTOCOL == 1\n    proto_rc5,\n#endif\n#if IRSND_SUPPORT_DENON_PROTOCOL == 1\n    proto_denon,\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n    proto_rc6,\n#endif\n#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1\n    proto_samsung32,\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n    proto_apple,\n#endif\n#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1\n    proto_recs80ext,\n#endif\n#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1\n    proto_nubert,\n#endif\n#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1\n    proto_bang_olufsen,\n#endif\n#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1\n    proto_grundig,\n#endif\n#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1\n    proto_nokia,\n#endif\n#if IRSND_SUPPORT_SIEMENS_PROTOCOL  == 1\n    proto_siemens,\n#endif\n#if IRSND_SUPPORT_FDC_PROTOCOL == 1\n    proto_fdc,\n#endif\n#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1\n    proto_rccar,\n#endif\n#if IRSND_SUPPORT_JVC_PROTOCOL == 1\n    proto_jvc,\n#endif\n#if IRSND_SUPPORT_RC6_PROTOCOL == 1\n    proto_rc6a,\n#endif\n#if IRSND_SUPPORT_NIKON_PROTOCOL == 1\n    proto_nikon,\n#endif\n#if IRSND_SUPPORT_RUWIDO_PROTOCOL == 1\n    proto_ruwido,\n#endif\n#if IRSND_SUPPORT_IR60_PROTOCOL == 1\n    proto_ir60,\n#endif\n#if IRSND_SUPPORT_KATHREIN_PROTOCOL == 1\n    proto_kathrein,\n#endif\n#if IRSND_SUPPORT_NETBOX_PROTOCOL == 1\n    proto_netbox,\n#endif\n#if IRSND_SUPPORT_NEC16_PROTOCOL == 1\n    proto_nec16,\n#endif\n#if IRSND_SUPPORT_NEC42_PROTOCOL == 1\n    proto_nec42,\n#endif\n#if IRSND_SUPPORT_LEGO_PROTOCOL == 1\n    proto_lego,\n#endif\n#if IRSND_SUPPORT_THOMSON_PROTOCOL == 1\n    proto_thomson,\n#endif\n#if IRSND_SUPPORT_BOSE_PROTOCOL == 1\n    proto_bose,\n#endif\n#if IRSND_SUPPORT_A1TVBOX_PROTOCOL == 1\n    proto_a1tvbox,\n#endif\n#if IRSND_SUPPORT_ORTEK_PROTOCOL == 1\n    proto_ortek,\n#endif\n#if IRSND_SUPPORT_TELEFUNKEN_PROTOCOL == 1\n    proto_telefunken,\n#endif\n#if IRSND_SUPPORT_ROOMBA_PROTOCOL == 1\n    proto_roomba,\n#endif\n#if IRSND_SUPPORT_RCMM_PROTOCOL  == 1\n    proto_rcmm12,\n#endif\n#if IRSND_SUPPORT_SPEAKER_PROTOCOL == 1\n    proto_speaker,\n#endif\n#if IRSND_SUPPORT_LGAIR_PROTOCOL == 1\n    proto_lgair,\n#endif\n#if IRSND_SUPPORT_SAMSUNG48_PROTOCOL == 1\n    proto_samsung48,\n#endif\n#if IRSND_SUPPORT_MERLIN_PROTOCOL == 1\n    proto_merlin,\n#endif\n#if IRSND_SUPPORT_PENTAX_PROTOCOL == 1\n    proto_pentax,\n#endif\n#if IRSND_SUPPORT_FAN_PROTOCOL == 1\n    proto_fan,\n#endif\n#if IRSND_SUPPORT_S100_PROTOCOL == 1\n    proto_s100,\n#endif\n#if IRSND_SUPPORT_ACP24_PROTOCOL  == 1\n    proto_acp24,\n#endif\n#if IRSND_SUPPORT_TECHNICS_PROTOCOL == 1\n    proto_technics,\n#endif\n#if IRSND_SUPPORT_PANASONIC_PROTOCOL == 1\n    proto_panasonic,\n#endif\n#if IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL == 1\n    proto_mitsu_heavy,\n#endif\n#if IRSND_SUPPORT_VINCENT_PROTOCOL == 1\n    proto_vincent,\n#endif\n#if IRSND_SUPPORT_SAMSUNGAH_PROTOCOL == 1\n    proto_samsungah,\n#endif\n#if IRSND_SUPPORT_IRMP16_PROTOCOL == 1\n    proto_irmp16,\n#endif\n#if IRSND_SUPPORT_GREE_PROTOCOL == 1\n    proto_gree,\n#endif\n#if IRSND_SUPPORT_RCII_PROTOCOL == 1\n    proto_rcii,\n#endif\n#if IRSND_SUPPORT_METZ_PROTOCOL == 1\n    proto_metz,\n#endif\n#if IRSND_SUPPORT_NEC_PROTOCOL == 1\n    proto_onkyo,\n#endif\n#if IRSND_SUPPORT_RF_GEN24_PROTOCOL == 1\n    proto_rf_gen24,\n#endif\n#if IRSND_SUPPORT_RF_X10_PROTOCOL == 1\n    proto_rf_x10,\n#endif\n#if IRSND_SUPPORT_RF_MEDION_PROTOCOL == 1\n    proto_rf_medion\n#endif\n#if IRSND_SUPPORT_MELINERA_PROTOCOL == 1\n    proto_melinera\n#endif\n};\n\nvoid irsnd_print_protocol_name(Print *aSerial, uint8_t aProtocolNumber)\n{\n#  if defined(__AVR__)\n    for (uint_fast8_t i = 0; i < sizeof(irsnd_used_protocol_index); ++i)\n    {\n        if (pgm_read_byte(&irsnd_used_protocol_index[i]) == aProtocolNumber)\n        {\n            const char* tProtocolStringPtr = (char*) pgm_read_word(&irsnd_used_protocol_names[i]);\n            aSerial->print((__FlashStringHelper *) (tProtocolStringPtr));\n            break;\n        }\n    }\n#  else\n    // no need to save space\n    aSerial->print(irmp_protocol_names[aProtocolNumber]);\n#  endif\n}\n\nvoid irsnd_data_print(Print *aSerial, IRMP_DATA *aIRMPDataPtr)\n{\n    /*\n     * Print protocol name or number\n     */\n    aSerial->print(F(\"Protocol=\"));\n#if IRSND_PROTOCOL_NAMES == 1\n    irsnd_print_protocol_name(aSerial, aIRMPDataPtr->protocol);\n    aSerial->print(' ');\n#else\n    aSerial->print(F(\"0x\"));\n    aSerial->print(aIRMPDataPtr->protocol, HEX);\n#endif\n\n    /*\n     * Print address, code and repetition flag\n     */\n    aSerial->print(F(\" Address=0x\"));\n    aSerial->print(aIRMPDataPtr->address, HEX);\n    aSerial->print(F(\" Command=0x\"));\n    aSerial->print(aIRMPDataPtr->command, HEX);\n    if (aIRMPDataPtr->flags & IRSND_REPETITION_MASK)\n    {\n        aSerial->print(F(\" Repeats=\"));\n        aSerial->print(aIRMPDataPtr->flags & IRSND_REPETITION_MASK);\n\n    }\n    aSerial->println();\n}\n\n#endif // defined(ARDUINO)\n"
  },
  {
    "path": "src/irsndSelectAllProtocols.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irsndSelectAllProtocols.h\n * 39 protocols supported\n *\n *\n * Copyright (c) 2010-2019 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRSND_SELECT_PROTOCOLS_H\n#define _IRSND_SELECT_PROTOCOLS_H\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 if you want to disable one or more encoders.\n * This saves program memory.\n * 1 enable  encoder\n * 0 disable encoder\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_SIRCS_PROTOCOL            1       // Sony SIRCS           >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_NEC_PROTOCOL              1       // NEC + APPLE          >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_SAMSUNG_PROTOCOL          1       // Samsung + Samsung32  >= 10000                 ~300 bytes\n#define IRSND_SUPPORT_KASEIKYO_PROTOCOL         1       // Kaseikyo             >= 10000                 ~300 bytes\n\n// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_JVC_PROTOCOL              1       // JVC                  >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NEC16_PROTOCOL            1       // NEC16                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NEC42_PROTOCOL            1       // NEC42                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL       1       // Matsushita           >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_DENON_PROTOCOL            1       // DENON, Sharp         >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_RC5_PROTOCOL              1       // RC5                  >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_RC6_PROTOCOL              1       // RC6                  >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_RC6A_PROTOCOL             1       // RC6A                 >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_GRUNDIG_PROTOCOL          1       // Grundig              >= 10000                 ~300 bytes\n#define IRSND_SUPPORT_SIEMENS_PROTOCOL          1       // Siemens, Gigaset     >= 15000                 ~150 bytes\n#define IRSND_SUPPORT_NOKIA_PROTOCOL            1       // Nokia                >= 10000                 ~400 bytes\n\n// exotic protocols, enable here!               Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_IR60_PROTOCOL             0       // IR60 (SDA2008)       >= 10000                 ~250 bytes // IR frequency 30 kHz\n#define IRSND_SUPPORT_BOSE_PROTOCOL             1       // BOSE                 >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_KATHREIN_PROTOCOL         0       // Kathrein             >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_NUBERT_PROTOCOL           1       // NUBERT               >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_FAN_PROTOCOL              1       // FAN (ventilator)     >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_SPEAKER_PROTOCOL          1       // SPEAKER              >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL     0       // Bang&Olufsen         >= 10000                 ~250 bytes // IR frequency 455 kHz\n#define IRSND_SUPPORT_RECS80_PROTOCOL           1       // RECS80               >= 15000                 ~100 bytes\n#define IRSND_SUPPORT_RECS80EXT_PROTOCOL        1       // RECS80EXT            >= 15000                 ~100 bytes\n#define IRSND_SUPPORT_THOMSON_PROTOCOL          1       // Thomson              >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_NIKON_PROTOCOL            1       // NIKON                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NETBOX_PROTOCOL           0       // Netbox keyboard      >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_ORTEK_PROTOCOL            0       // ORTEK (Hama)         >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_TELEFUNKEN_PROTOCOL       1       // Telefunken 1560      >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_FDC_PROTOCOL              1       // FDC IR keyboard      >= 10000 (better 15000)  ~150 bytes\n#define IRSND_SUPPORT_RCCAR_PROTOCOL            1       // RC CAR               >= 10000 (better 15000)  ~150 bytes\n#define IRSND_SUPPORT_ROOMBA_PROTOCOL           1       // iRobot Roomba        >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_RUWIDO_PROTOCOL           1       // RUWIDO, T-Home       >= 15000                 ~250 bytes\n#define IRSND_SUPPORT_A1TVBOX_PROTOCOL          1       // A1 TV BOX            >= 15000 (better 20000)  ~200 bytes\n#define IRSND_SUPPORT_LEGO_PROTOCOL             1       // LEGO Power RC        >= 20000                 ~150 bytes\n#define IRSND_SUPPORT_RCMM_PROTOCOL             0       // RCMM 12,24, or 32    >= 20000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_LGAIR_PROTOCOL            1       // LG Air Condition     >= 10000                 ~150 bytes.\n#define IRSND_SUPPORT_SAMSUNG48_PROTOCOL        1       // Samsung48            >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_PENTAX_PROTOCOL           1       // Pentax               >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_S100_PROTOCOL             0       // S100                 >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_ACP24_PROTOCOL            1       // ACP24                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_TECHNICS_PROTOCOL         1       // TECHNICS             >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_PANASONIC_PROTOCOL        1       // PANASONIC Beamer     >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL      1       // Mitsubishi-Heavy Aircondition, similar Timing to Panasonic beamer\n#define IRSND_SUPPORT_IRMP16_PROTOCOL           0       // IRMP specific        >= 15000                 ~250 bytes\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Protocols Part 2: RF decoders\n * If you use an IR sensor, deactivate all RF protocols!\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#define IRMP_SUPPORT_RF_GEN24_PROTOCOL          0       // RF GEN24 (generic)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_X10_PROTOCOL            0       // RF PC X10 (Medion)   >= 15000                 ~250 bytes\n#define IRMP_SUPPORT_RF_MEDION_PROTOCOL         0       // RF PC Medion         >= 15000                 ~250 bytes\n\n#endif // _IRSND_SELECT_PROTOCOLS_H\n"
  },
  {
    "path": "src/irsndSelectMain15Protocols.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irsndSelectMain15Protocols.h\n *\n *\n * Copyright (c) 2010-2019 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRSND_SELECT_PROTOCOLS_H\n#define _IRSND_SELECT_PROTOCOLS_H\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 if you want to disable one or more encoders.\n * This saves program memory.\n * 1 enable  decoder\n * 0 disable decoder\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_SIRCS_PROTOCOL            1       // Sony SIRCS           >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_NEC_PROTOCOL              1       // NEC + APPLE          >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_SAMSUNG_PROTOCOL          1       // Samsung + Samsung32  >= 10000                 ~300 bytes\n#define IRSND_SUPPORT_KASEIKYO_PROTOCOL         1       // Kaseikyo             >= 10000                 ~300 bytes\n\n// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_JVC_PROTOCOL              1       // JVC                  >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NEC16_PROTOCOL            1       // NEC16                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NEC42_PROTOCOL            1       // NEC42                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL       1       // Matsushita           >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_DENON_PROTOCOL            1       // DENON, Sharp         >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_RC5_PROTOCOL              1       // RC5                  >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_RC6_PROTOCOL              1       // RC6                  >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_RC6A_PROTOCOL             1       // RC6A                 >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_GRUNDIG_PROTOCOL          1       // Grundig              >= 10000                 ~300 bytes\n#define IRSND_SUPPORT_SIEMENS_PROTOCOL          1       // Siemens, Gigaset     >= 15000                 ~150 bytes\n#define IRSND_SUPPORT_NOKIA_PROTOCOL            1       // Nokia                >= 10000                 ~400 bytes\n\n#endif // _IRSND_SELECT_PROTOCOLS_H\n"
  },
  {
    "path": "src/irsndconfig.h",
    "content": "/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * irsndconfig.h\n *\n * DO NOT INCLUDE THIS FILE, WILL BE INCLUDED BY IRSND.H!\n *\n * Copyright (c) 2010-2020 Frank Meyer - frank(at)fli4l.de\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n#ifndef _IRSNDCONFIG_H_\n#define _IRSNDCONFIG_H_\n\n#if !defined(_IRSND_H_)\n#  error please include only irsnd.h, not irsndconfig.h\n#endif\n\n// #define IRSND_DEBUG 1                                // activate debugging\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * F_INTERRUPTS: number of interrupts per second, should be in the range from 10000 to 20000, typically 15000\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(F_INTERRUPTS)\n#  define F_INTERRUPTS                          15000   // interrupts per second\n#endif\n\n#if ! defined(ARDUINO)\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Change settings from 1 to 0 if you want to disable one or more encoders.\n * This saves program memory.\n * 1 enable  encoder\n * 0 disable encoder\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n\n// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_SIRCS_PROTOCOL            1       // Sony SIRCS           >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_NEC_PROTOCOL              1       // NEC + APPLE          >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_SAMSUNG_PROTOCOL          1       // Samsung + Samsung32  >= 10000                 ~300 bytes\n#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL       1       // Matsushita           >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_KASEIKYO_PROTOCOL         1       // Kaseikyo             >= 10000                 ~300 bytes\n\n// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_DENON_PROTOCOL            0       // DENON, Sharp         >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_RC5_PROTOCOL              0       // RC5                  >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_RC6_PROTOCOL              0       // RC6                  >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_RC6A_PROTOCOL             0       // RC6A                 >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_JVC_PROTOCOL              0       // JVC                  >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NEC16_PROTOCOL            0       // NEC16                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NEC42_PROTOCOL            0       // NEC42                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_IR60_PROTOCOL             0       // IR60 (SDA2008)       >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_GRUNDIG_PROTOCOL          0       // Grundig              >= 10000                 ~300 bytes\n#define IRSND_SUPPORT_SIEMENS_PROTOCOL          0       // Siemens, Gigaset     >= 15000                 ~150 bytes\n#define IRSND_SUPPORT_NOKIA_PROTOCOL            0       // Nokia                >= 10000                 ~400 bytes\n\n// exotic protocols, enable here!               Enable  Remarks                 F_INTERRUPTS            program memory\n#define IRSND_SUPPORT_BOSE_PROTOCOL             0       // BOSE                 >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_KATHREIN_PROTOCOL         0       // Kathrein             >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_NUBERT_PROTOCOL           0       // NUBERT               >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_FAN_PROTOCOL              0       // FAN (ventilator)     >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_SPEAKER_PROTOCOL          0       // SPEAKER              >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL     0       // Bang&Olufsen         >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_RECS80_PROTOCOL           0       // RECS80               >= 15000                 ~100 bytes\n#define IRSND_SUPPORT_RECS80EXT_PROTOCOL        0       // RECS80EXT            >= 15000                 ~100 bytes\n#define IRSND_SUPPORT_THOMSON_PROTOCOL          0       // Thomson              >= 10000                 ~250 bytes\n#define IRSND_SUPPORT_NIKON_PROTOCOL            0       // NIKON                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_NETBOX_PROTOCOL           0       // Netbox keyboard      >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_ORTEK_PROTOCOL            0       // ORTEK (Hama)         >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_TELEFUNKEN_PROTOCOL       0       // Telefunken 1560      >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_FDC_PROTOCOL              0       // FDC IR keyboard      >= 10000 (better 15000)  ~150 bytes\n#define IRSND_SUPPORT_RCCAR_PROTOCOL            0       // RC CAR               >= 10000 (better 15000)  ~150 bytes\n#define IRSND_SUPPORT_ROOMBA_PROTOCOL           0       // iRobot Roomba        >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_RUWIDO_PROTOCOL           0       // RUWIDO, T-Home       >= 15000                 ~250 bytes\n#define IRSND_SUPPORT_A1TVBOX_PROTOCOL          0       // A1 TV BOX            >= 15000 (better 20000)  ~200 bytes\n#define IRSND_SUPPORT_LEGO_PROTOCOL             0       // LEGO Power RC        >= 20000                 ~150 bytes\n#define IRSND_SUPPORT_RCMM_PROTOCOL             0       // RCMM 12,24, or 32    >= 20000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_LGAIR_PROTOCOL            0       // LG Air Condition     >= 10000                 ~150 bytes.\n#define IRSND_SUPPORT_SAMSUNG48_PROTOCOL        0       // Samsung48            >= 10000                 ~100 bytes\n#define IRSND_SUPPORT_PENTAX_PROTOCOL           0       // Pentax               >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_S100_PROTOCOL             0       // S100                 >= 10000                 DON'T CHANGE, NOT SUPPORTED YET!\n#define IRSND_SUPPORT_ACP24_PROTOCOL            0       // ACP24                >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_TECHNICS_PROTOCOL         0       // TECHNICS             >= 10000                 ~200 bytes\n#define IRSND_SUPPORT_PANASONIC_PROTOCOL        0       // PANASONIC Beamer     >= 10000                 ~150 bytes\n#define IRSND_SUPPORT_MITSU_HEAVY_PROTOCOL      0       // Mitsubishi-Heavy Aircondition, similar Timing to Panasonic beamer\n#define IRSND_SUPPORT_IRMP16_PROTOCOL           0       // IRMP specific        >= 15000                 ~250 bytes\n#endif // ! defined(ARDUINO)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * AVR XMega section:\n *\n * Change hardware pin here:                    IRSND_XMEGA_OC0A = OC0A on ATxmegas  supporting OC0A, e.g. ATxmega128A1U\n *                                              IRSND_XMEGA_OC0B = OC0B on ATxmegas  supporting OC0B, e.g. ATxmega128A1U\n *                                              IRSND_XMEGA_OC0C = OC0C on ATxmegas  supporting OC0C, e.g. ATxmega128A1U\n *                                              IRSND_XMEGA_OC0D = OC0D on ATxmegas  supporting OC0D, e.g. ATxmega128A1U\n *                                              IRSND_XMEGA_OC1A = OC1A on ATxmegas  supporting OC1A, e.g. ATxmega128A1U\n *                                              IRSND_XMEGA_OC1B = OC1B on ATxmegas  supporting OC1B, e.g. ATxmega128A1U\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if defined(__AVR_XMEGA__)                                              // XMEGA\n#  define IRSND_PORT_PRE                        PORTD\n#  define XMEGA_Timer                           TCD0\n#  define IRSND_OCx                             IRSND_XMEGA_OC0B        // use OC0B\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * AVR ATmega/ATTiny section:\n *\n * Change hardware pin here:                    IRSND_OC2  = OC2  on ATmegas         supporting OC2,  e.g. ATmega8\n *                                              IRSND_OC2A = OC2A on ATmegas         supporting OC2A, e.g. ATmega88\n *                                              IRSND_OC2B = OC2B on ATmegas         supporting OC2B, e.g. ATmega88\n *                                              IRSND_OC0  = OC0  on ATmegas         supporting OC0,  e.g. ATmega162\n *                                              IRSND_OC0A = OC0A on ATmegas/ATtinys supporting OC0A, e.g. ATtiny84, ATtiny85, ATtiny87/167\n *                                              IRSND_OC0B = OC0B on ATmegas/ATtinys supporting OC0B, e.g. ATtiny84, ATtiny85\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined(ATMEL_AVR)\n#  define IRSND_OCx                             IRSND_OC2B              // use OC2B\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * PIC C18 or XC8 section:\n *\n * Change hardware pin here:                    IRSND_PIC_CCP1 = RC2 on PIC 18F2550/18F4550, ...\n *                                              IRSND_PIC_CCP2 = RC1 on PIC 18F2550/18F4550, ...\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined(PIC_C18)                                                  // C18 or XC8 compiler\n#  if defined(__12F1840)                                                // XC8 compiler\n#    define Pre_Scaler                          1                       // define prescaler for timer2 e.g. 1,4,16\n#    define F_CPU                               32000000UL              // PIC frequency: set your freq here\n#    define PIC_Scaler                          2                       // PIC needs /2 extra in IRSND_FREQ_32_KHZ calculation for right value\n\n#  else                                                                 // C18 compiler\n#    define IRSND_OCx                           IRSND_PIC_CCP2          // Use PWMx for PIC\n                                                                        // change other PIC C18 specific settings:\n#    define F_CPU                               48000000UL              // PIC frequency: set your freq here\n#    define Pre_Scaler                          4                       // define prescaler for timer2 e.g. 1,4,16\n#    define PIC_Scaler                          2                       // PIC needs /2 extra in IRSND_FREQ_32_KHZ calculation for right value\n#  endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * ARM STM32 section:\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (ARM_STM32)                                               // use B6 as IR output on STM32\n#  define IRSND_PORT_LETTER                     B\n#  define IRSND_BIT_NUMBER                      6\n#  define IRSND_TIMER_NUMBER                    4\n#  define IRSND_TIMER_CHANNEL_NUMBER            1                       // only channel 1 can be used at the moment, others won't work\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * ARM STM32 with HAL section - don't change here, define IRSND_Transmit_GPIO_Port & IRSND_Transmit_Pin in STM32Cube (Main.h)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (ARM_STM32_HAL)                                           // IRSND_Transmit_GPIO_Port & IRSND_Transmit_Pin must be defined in STM32Cube\n#  define IRSND_PORT_LETTER                     IRSND_Transmit_GPIO_Port//Port of Transmit PWM Pin e.g.\n#  define IRSND_BIT_NUMBER                      IRSND_Transmit_Pin      //Pim of Transmit PWM Pin e.g.\n#  define IRSND_TIMER_HANDLER                   htim2                   //Handler of Timer e.g. htim (see tim.h)\n#  define IRSND_TIMER_CHANNEL_NUMBER            TIM_CHANNEL_2           //Channel of the used Timer PWM Pin e.g. TIM_CHANNEL_2\n#  define IRSND_TIMER_SPEED_APBX                64000000                //Speed of the corresponding APBx. (see STM32CubeMX: Clock Configuration)\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Teensy 3.x with teensyduino gcc compiler\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (TEENSY_ARM_CORTEX_M4)\n#  define IRSND_PIN                             5                       // choose an arduino pin with PWM function!\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * ESP8266 (Arduino, see IRSEND.ino)\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif defined (__xtensa__)\n#  define IRSND_PIN                             0                       // choose an arduino pin with PWM function!\n\n#elif defined(ARDUINO)\n// specified here to avoid else case\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Other target systems\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#elif !defined (UNIX_OR_WINDOWS)\n#  error target system not defined.\n#endif\n\n/*---------------------------------------------------------------------------------------------------------------------------------------------------\n * Use Callbacks to indicate output signal or something else\n *---------------------------------------------------------------------------------------------------------------------------------------------------\n */\n#if !defined(IRSND_USE_CALLBACK)\n#  define IRSND_USE_CALLBACK                    0                       // flag: 0 = don't use callbacks, 1 = use callbacks, default is 0\n#endif\n\n#endif // _IRSNDCONFIG_H_\n"
  }
]