From b75a05a05381827af8eb5ee3390dab8f92ab11fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jurij=20Podgor=C5=A1ek?= Date: Fri, 23 Aug 2024 15:47:42 +0200 Subject: [PATCH] platformio source, dokumentacija krmilnika --- .gitignore | 2 + LICENSE | 661 + doc/ESP32-S2-DevKit-Lipo_Rev_B1.pdf | Bin 0 -> 910120 bytes flash.sh | 5 + lib/MPU6050/LICENSE | 21 + lib/MPU6050/README.md | 49 + lib/MPU6050/examples/IMU_Zero/IMU_Zero.ino | 358 + lib/MPU6050/examples/IMU_Zero/Makefile | 20 + .../MCU_Powercycle_DMP6.ino | 134 + .../examples/MPU6050_DMP6/MPU6050_DMP6.ino | 345 + .../Processing/MPUTeapot/MPUTeapot.pde | 242 + .../MPU6050_DMP6_ESPWiFi.ino | 377 + .../Processing/MPUOSCTeapot/MPUOSCTeapot.pde | 187 + .../MPU6050_DMP6_Ethernet.ino | 545 + .../MPU6050_DMP6_ImuData_for_ROS.ino | 122 + .../MPU6050_DMP6_using_DMP_V6v12.ino | 368 + .../MPUplane/MPUplane.pde | 189 + .../MPUplane/data/biplane.obj | 2239 + .../MPUplane/data/diffuse_512.png | Bin 0 -> 361095 bytes .../examples/MPU6050_raw/MPU6050_raw.ino | 152 + lib/MPU6050/examples/MPU6050_raw/Makefile | 20 + lib/MPU6050/keywords.txt | 151 + lib/MPU6050/library.properties | 10 + lib/MPU6050/src/I2Cdev.cpp | 1473 + lib/MPU6050/src/I2Cdev.h | 311 + lib/MPU6050/src/MPU6050.cpp | 3478 ++ lib/MPU6050/src/MPU6050.h | 874 + .../src/MPU6050_6Axis_MotionApps20.cpp | 632 + lib/MPU6050/src/MPU6050_6Axis_MotionApps20.h | 154 + .../src/MPU6050_6Axis_MotionApps612.cpp | 627 + lib/MPU6050/src/MPU6050_6Axis_MotionApps612.h | 158 + .../src/MPU6050_9Axis_MotionApps41.cpp | 902 + lib/MPU6050/src/MPU6050_9Axis_MotionApps41.h | 153 + lib/MPU6050/src/helper_3dmath.h | 216 + lib/OSC/API.md | 395 + .../MaxMSP/examples/OSCEsplora.maxpat | 306 + .../MaxMSP/examples/SerialCallResponse.maxpat | 974 + .../MaxMSP/examples/SerialEcho.maxpat | 304 + .../MaxMSP/examples/SerialOscuino.maxpat | 6632 +++ .../MaxMSP/examples/SerialReceive.maxpat | 428 + .../examples/SerialReceivewithServo.maxpat | 297 + .../MaxMSP/examples/SerialSend.maxpat | 227 + .../MaxMSP/examples/UDPCallResponse.maxpat | 947 + .../MaxMSP/examples/UDPEcho.maxpat | 215 + .../MaxMSP/examples/UDPOscuino.maxpat | 4894 ++ .../MaxMSP/examples/UDPReceive.maxpat | 319 + .../MaxMSP/examples/UDPSend.maxpat | 159 + lib/OSC/Applications/PD/SerialOscuino.pd | 312 + lib/OSC/Applications/PD/o.io.slipserial.pd | 22 + .../Processing/SLIPSerialToUDP/GUI.pde | 148 + .../SLIPSerialToUDP/SLIPSerialToUDP.pde | 56 + .../Processing/SLIPSerialToUDP/Serial.pde | 101 + .../Processing/SLIPSerialToUDP/UDP.pde | 27 + .../Applications/Processing/SLIPSerialToUDPp3 | 375 + .../UDPReceiveBundle/UDPReceiveBundle.pde | 74 + .../UDPReceiveMessage/UDPReceiveMessage.pde | 42 + .../Processing/serialSend/code/javaosc.jar | Bin 0 -> 10927 bytes .../Processing/serialSend/serialSend.pde | 50 + .../Processing/serialSend/sketch.properties | 1 + lib/OSC/LICENSE | 20 + lib/OSC/OSCBoards.cpp | 191 + lib/OSC/OSCBoards.h | 56 + lib/OSC/OSCBundle.cpp | 357 + lib/OSC/OSCBundle.h | 175 + lib/OSC/OSCData.cpp | 335 + lib/OSC/OSCData.h | 156 + lib/OSC/OSCMatch.c | 307 + lib/OSC/OSCMatch.h | 78 + lib/OSC/OSCMessage.cpp | 791 + lib/OSC/OSCMessage.h | 350 + lib/OSC/OSCTiming.cpp | 178 + lib/OSC/OSCTiming.h | 30 + lib/OSC/README.md | 235 + lib/OSC/SLIPEncodedSerial.h | 292 + .../ESP8266ReceiveBundle.ino | 103 + .../ESP8266ReceiveMessage.ino | 100 + .../ESP8266sendMessage/ESP8266sendMessage.ino | 66 + lib/OSC/examples/OSCEsplora/OSCEsplora.ino | 287 + .../PatternMatching/PatternMatching.ino | 91 + .../SerialCallResponse/SerialCallResponse.ino | 108 + lib/OSC/examples/SerialEcho/SerialEcho.ino | 48 + ...noAdaFruitPlayGroundExpresswithBundles.ino | 332 + .../SerialOscuinoForFubarino.ino | 292 + .../SerialOscuinoGemmaM0.ino | 311 + .../SerialOscuinowithBundles.ino | 323 + .../SerialOscuinowithMessages.ino | 338 + .../examples/SerialReceive/SerialReceive.ino | 66 + .../SerialReceiveInfiniteLoop.ino | 77 + .../SerialReceivewithServo.ino | 67 + .../SerialSendBundle/SerialSendBundle.ino | 47 + .../SerialSendBundleWithTimeTag.ino | 47 + .../SerialSendMessage/SerialSendMessage.ino | 33 + .../SerialSendMessageInfiniteLoop.ino | 44 + .../UDPCallResponse/UDPCallResponse.ino | 164 + lib/OSC/examples/UDPEcho/UDPEcho.ino | 84 + lib/OSC/examples/UDPOscuino/UDPOscuino.ino | 378 + lib/OSC/examples/UDPReceive/UDPReceive.ino | 106 + .../examples/UDPSendBundle/UDPSendBundle.ino | 55 + .../UDPSendBundlewithTimeTag.ino | 62 + .../UDPSendMessage/UDPSendMessage.ino | 41 + lib/OSC/keywords.txt | 91 + lib/OSC/library.json | 25 + lib/OSC/library.properties | 9 + .../test/OSCBundle_test/OSCBundle_test.ino | 123 + lib/OSC/test/OSCBundle_test/TestPrint.h | 36 + lib/OSC/test/OSCData_test/OSCData_test.ino | 96 + .../OSCMessage_encode_decode_test.ino | 182 + .../OSCMessage_encode_decode_test/TestPrint.h | 36 + .../OSCMessage_match_test.ino | 86 + .../test/OSCMessage_test/OSCMessage_test.ino | 104 + monitor.sh | 5 + platformio.ini | 33 + requirements.txt | 1 + src/debug.cfg | 14 + src/debug.svd | 46087 ++++++++++++++++ src/debug_custom.json | 19 + src/detect.cpp | 169 + src/kalibracija.cpp | 364 + src/main.cpp | 267 + src/sprejemnik.cpp | 162 + 120 files changed, 87610 insertions(+) create mode 100644 LICENSE create mode 100644 doc/ESP32-S2-DevKit-Lipo_Rev_B1.pdf create mode 100755 flash.sh create mode 100644 lib/MPU6050/LICENSE create mode 100644 lib/MPU6050/README.md create mode 100755 lib/MPU6050/examples/IMU_Zero/IMU_Zero.ino create mode 100644 lib/MPU6050/examples/IMU_Zero/Makefile create mode 100644 lib/MPU6050/examples/MCU_Powercycle_DMP6/MCU_Powercycle_DMP6.ino create mode 100644 lib/MPU6050/examples/MPU6050_DMP6/MPU6050_DMP6.ino create mode 100755 lib/MPU6050/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde create mode 100644 lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino create mode 100755 lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde create mode 100755 lib/MPU6050/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino create mode 100644 lib/MPU6050/examples/MPU6050_DMP6_ImuData_for_ROS/MPU6050_DMP6_ImuData_for_ROS.ino create mode 100644 lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino create mode 100644 lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde create mode 100644 lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj create mode 100644 lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/diffuse_512.png create mode 100755 lib/MPU6050/examples/MPU6050_raw/MPU6050_raw.ino create mode 100644 lib/MPU6050/examples/MPU6050_raw/Makefile create mode 100755 lib/MPU6050/keywords.txt create mode 100755 lib/MPU6050/library.properties create mode 100644 lib/MPU6050/src/I2Cdev.cpp create mode 100644 lib/MPU6050/src/I2Cdev.h create mode 100644 lib/MPU6050/src/MPU6050.cpp create mode 100644 lib/MPU6050/src/MPU6050.h create mode 100644 lib/MPU6050/src/MPU6050_6Axis_MotionApps20.cpp create mode 100644 lib/MPU6050/src/MPU6050_6Axis_MotionApps20.h create mode 100644 lib/MPU6050/src/MPU6050_6Axis_MotionApps612.cpp create mode 100644 lib/MPU6050/src/MPU6050_6Axis_MotionApps612.h create mode 100644 lib/MPU6050/src/MPU6050_9Axis_MotionApps41.cpp create mode 100644 lib/MPU6050/src/MPU6050_9Axis_MotionApps41.h create mode 100755 lib/MPU6050/src/helper_3dmath.h create mode 100644 lib/OSC/API.md create mode 100644 lib/OSC/Applications/MaxMSP/examples/OSCEsplora.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/SerialCallResponse.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/SerialEcho.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/SerialOscuino.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/SerialReceive.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/SerialReceivewithServo.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/SerialSend.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/UDPCallResponse.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/UDPEcho.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/UDPOscuino.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/UDPReceive.maxpat create mode 100644 lib/OSC/Applications/MaxMSP/examples/UDPSend.maxpat create mode 100644 lib/OSC/Applications/PD/SerialOscuino.pd create mode 100644 lib/OSC/Applications/PD/o.io.slipserial.pd create mode 100644 lib/OSC/Applications/Processing/SLIPSerialToUDP/GUI.pde create mode 100644 lib/OSC/Applications/Processing/SLIPSerialToUDP/SLIPSerialToUDP.pde create mode 100644 lib/OSC/Applications/Processing/SLIPSerialToUDP/Serial.pde create mode 100644 lib/OSC/Applications/Processing/SLIPSerialToUDP/UDP.pde create mode 100644 lib/OSC/Applications/Processing/SLIPSerialToUDPp3 create mode 100644 lib/OSC/Applications/Processing/UDPReceiveBundle/UDPReceiveBundle.pde create mode 100644 lib/OSC/Applications/Processing/UDPReceiveMessage/UDPReceiveMessage.pde create mode 100755 lib/OSC/Applications/Processing/serialSend/code/javaosc.jar create mode 100644 lib/OSC/Applications/Processing/serialSend/serialSend.pde create mode 100644 lib/OSC/Applications/Processing/serialSend/sketch.properties create mode 100644 lib/OSC/LICENSE create mode 100644 lib/OSC/OSCBoards.cpp create mode 100644 lib/OSC/OSCBoards.h create mode 100644 lib/OSC/OSCBundle.cpp create mode 100644 lib/OSC/OSCBundle.h create mode 100644 lib/OSC/OSCData.cpp create mode 100644 lib/OSC/OSCData.h create mode 100644 lib/OSC/OSCMatch.c create mode 100644 lib/OSC/OSCMatch.h create mode 100644 lib/OSC/OSCMessage.cpp create mode 100644 lib/OSC/OSCMessage.h create mode 100644 lib/OSC/OSCTiming.cpp create mode 100644 lib/OSC/OSCTiming.h create mode 100644 lib/OSC/README.md create mode 100644 lib/OSC/SLIPEncodedSerial.h create mode 100644 lib/OSC/examples/ESP8266ReceiveBundle/ESP8266ReceiveBundle.ino create mode 100644 lib/OSC/examples/ESP8266ReceiveMessage/ESP8266ReceiveMessage.ino create mode 100644 lib/OSC/examples/ESP8266sendMessage/ESP8266sendMessage.ino create mode 100644 lib/OSC/examples/OSCEsplora/OSCEsplora.ino create mode 100644 lib/OSC/examples/PatternMatching/PatternMatching.ino create mode 100644 lib/OSC/examples/SerialCallResponse/SerialCallResponse.ino create mode 100644 lib/OSC/examples/SerialEcho/SerialEcho.ino create mode 100644 lib/OSC/examples/SerialOscuinoAdaFruitPlayGroundExpresswithBundles/SerialOscuinoAdaFruitPlayGroundExpresswithBundles.ino create mode 100644 lib/OSC/examples/SerialOscuinoForFubarino/SerialOscuinoForFubarino.ino create mode 100644 lib/OSC/examples/SerialOscuinoGemmaM0/SerialOscuinoGemmaM0.ino create mode 100644 lib/OSC/examples/SerialOscuinowithBundles/SerialOscuinowithBundles.ino create mode 100644 lib/OSC/examples/SerialOscuinowithMessages/SerialOscuinowithMessages.ino create mode 100644 lib/OSC/examples/SerialReceive/SerialReceive.ino create mode 100644 lib/OSC/examples/SerialReceiveInfiniteLoop/SerialReceiveInfiniteLoop.ino create mode 100644 lib/OSC/examples/SerialReceivewithServo/SerialReceivewithServo.ino create mode 100644 lib/OSC/examples/SerialSendBundle/SerialSendBundle.ino create mode 100644 lib/OSC/examples/SerialSendBundleWithTimeTag/SerialSendBundleWithTimeTag.ino create mode 100644 lib/OSC/examples/SerialSendMessage/SerialSendMessage.ino create mode 100644 lib/OSC/examples/SerialSendMessageInfiniteLoop/SerialSendMessageInfiniteLoop.ino create mode 100644 lib/OSC/examples/UDPCallResponse/UDPCallResponse.ino create mode 100644 lib/OSC/examples/UDPEcho/UDPEcho.ino create mode 100644 lib/OSC/examples/UDPOscuino/UDPOscuino.ino create mode 100644 lib/OSC/examples/UDPReceive/UDPReceive.ino create mode 100644 lib/OSC/examples/UDPSendBundle/UDPSendBundle.ino create mode 100644 lib/OSC/examples/UDPSendBundlewithTimeTag/UDPSendBundlewithTimeTag.ino create mode 100644 lib/OSC/examples/UDPSendMessage/UDPSendMessage.ino create mode 100644 lib/OSC/keywords.txt create mode 100644 lib/OSC/library.json create mode 100644 lib/OSC/library.properties create mode 100644 lib/OSC/test/OSCBundle_test/OSCBundle_test.ino create mode 100644 lib/OSC/test/OSCBundle_test/TestPrint.h create mode 100644 lib/OSC/test/OSCData_test/OSCData_test.ino create mode 100644 lib/OSC/test/OSCMessage_encode_decode_test/OSCMessage_encode_decode_test.ino create mode 100644 lib/OSC/test/OSCMessage_encode_decode_test/TestPrint.h create mode 100644 lib/OSC/test/OSCMessage_match_test/OSCMessage_match_test.ino create mode 100644 lib/OSC/test/OSCMessage_test/OSCMessage_test.ino create mode 100755 monitor.sh create mode 100644 platformio.ini create mode 100644 requirements.txt create mode 100644 src/debug.cfg create mode 100644 src/debug.svd create mode 100644 src/debug_custom.json create mode 100644 src/detect.cpp create mode 100644 src/kalibracija.cpp create mode 100644 src/main.cpp create mode 100644 src/sprejemnik.cpp diff --git a/.gitignore b/.gitignore index 06e67be..6c23809 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ .~lock*# .*.swp node_modules +.pio +.venv diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..be3f7b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/doc/ESP32-S2-DevKit-Lipo_Rev_B1.pdf b/doc/ESP32-S2-DevKit-Lipo_Rev_B1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7f1215a236e69f4f34720a59d143b39f302d264b GIT binary patch literal 910120 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

7-(;z3JC;l`JG^6eNp?02^n*gGmP-^`tY@H) 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

pz!A+&tO+%PZh1b_vFFeqJ=| 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
Oka03Z!cGZkHBs3&r*FXE@Yu^cHG54)ebqbk zw~gA7`Yc68oJCvggnIYsbRV+M^icg~hfCcjmVa6TM$axb1On&b#K1M+!~o|JyEzQH zk2U|LQtCsmbdfL8ArD!o4{Iqgl_=Au+6{&})xJRmCvPWTcrof`l&d7xXr@qOE|+IO z%(bN^JCKt7WZ!!cUhl7`L&quOAp z#&k98cGO^c>vnpocKfJxdhHzYS7v%DG@GNmqk)SkxCw9rCE1?az!SG`{< zF;?fu6ti=rvuC2WuB%3Q7h{*`CR4GkPT~U2f_%2Th~;X;nt!#8#1>urHZ5tqsv<>R zMnaw{w38yZLt_2zt%#){V!amGC%n=IL4MdtRPHC$Mr=;I-9z zSGERk>Ix*Z*%2o!<%e~onpN@hZrTGz()Gr~R5t=Q?oLjDH{N`@9U5 z+?i@_IHXd%P3a?J!&q9CU;h ztp4moH#+7LYTuVSU~UBFr(kvrX8NJCFfYuaJj$~4v>nubgvR)ed&d{w-6{w)hs5ZX z_m?W397p9L{C@k?*M6qH5GLB8zpUw!U%rDvmJvP9Og{a5@Yfp=FRui=jXwC`+Tpls z$2(7lms)A08_L0#d(c-03)7PmTm;#)dIkR~WVMWp42eWwP^c6fPD+Z%kfJbXiVUg> zou)#kD^jJ&R9Oj)SVdUa%33-OpvVM6n$`h{+C+xS>Dab_w>b~^Cm z1(YU3RVL@nE!L~6P!b1IwVd)#3r%06oT)ICb|XUZN{CcV+iUfjM^q z*MkDC46r7Ht~f_)Tc5FDqsiuKz4cYvYX@!cea2Ygi*{|17G3;+o7U3VQ26p}`or`7 zZ||Fb#lleE!ax`HAh8F2KfZb0+W4uN{u@KBciPJDR2APSE5vB-eq^9=*;wmQpl8*$ zS1lQFooTVPpPxkg*)~g@^bz+ZAGee+#KlGi4@kcQG z0U!m~S##e%y*09ZYwz&N&2BO-1}mP`^Jnhs-M3!4kGynY;1BAjq1>6OFNKayXht2m zGORLnNfDG6K~*8tw*G+yCd{{w+>7iEHmP$~jW<xQR>bq$dtbyHzI6ZC zyC;{5jt3OD=q6by&VRiP<4xS9i2?Q$vT_5$yAfHnQfjxXqzsNGPi9Et=~N*GMVvvD zq7$&<=2Vglg(gm+3lgaO1d0$!LLyNP1&K^0(Y8@&n`wltQUqZJL6U?+g&~ zju}Mou~N-2*pXnRlM(I>#mUf7jy#<$|50xRqo*AnLIld$BETHHRwBG?phv5v!PRkEI z{L0BWF)DQITMWjIrh@qoche8Jy$^E$<{ubqfT`Zg5kZf_4!qkR^)4*vQ@G#9Aip=h zd!G7vJqq%=8S4I5sNHG4zX)`X+3WUfkIPdZx0pcRmtg@f!UJAJhTI8odl2Xx6XE(Q z-2PRVT}-Hbw7*TXzstjYevd+e9)t!wJrwxnRPd`4KGBg*4^MdBIqZ2k(CzJoqf0&2 zSR(7L%%OXM@AbDfL~2z>>GfZ7gh%^F512Q)ZvW#ZJ9008^X5obq-COo>-zo(^ImFyL++>KV=j#^!l3yR)W$+h z5{$Ie-8zp&+UNYpJmQYdUC{V>t}+HjGTT3&ueuq@O??ObRWRP3`~7WyP3e4RQ)lW= z=C>Hu$H(v89DamH{ycmC%f)Bk_qjrK0XhlChX%(5@4sp7Q2X*N^!D5c@h$j@RUS`z za|s4ZdJ5iGf4_q=y6o`YG(T6UEQjWnxsnnX=!E*LrmI0&5ys880)8B@N;~U|ZJjIp zK5;Rq+e3ZERf=OLIcqCEZ!3Xi2XY~S8y-9)I1ZcVY&I<0ZC~SSff^QYn{sGIY*sVUFAM6_eyV1NJ)f}9QgT}b?I=uxx%20REwoZ zlLbGPVL*Eo+i=^Et|ZG{C*4fxy^B`SwQwjz=Y-FdPP$!=J4gK}oDlM;v&5vm_=2+# zxNZdZ6-#c&ve)`~*KM;-v{~ov3(hJWhn)*{GGI%=>Mz(3m&{0$I%1QWo2K@fYgT$&W_mk@w9btGi?-C{w$zlih$e=?NI` zgWAl&`-l6E+ts*Av%*xmT!}1C@_@5A(?x99mB8`cwX|2O#Z+=|pGKmC6qLS(nF<)q zZ%?_p-24ujU;X8)^z5wP*GIQvZalqx{^5&%znm>z19(Z1SUISW^inJ z7+cs|kF6XC%ZiIiNs#Dd)S;yO^ZENl3#O{(}mk&09b z>7Voe`9t~_{<(`rB}vin3JijREQu&f7L%oj(#c{35>bLcK5^m{s#3FGJ%GAGC`wH^ zw*Px%52wsD+=7qH+`>ZA>E%9T3jL;x#cFyb56MS8T5UXwKwHWJ{j39e@CW_nd_HVvmE zDlQ!=I=na0WJjkCd0bm)$ZT`3>8c?^WY%y6sPitW2{AQD4OS|zjO0@fxg`W!e>G98 z(A_?4E;s2aIqNMl?}7t2)E_2-t1!6oE;%Ag?rXVjLL3*_1t&GGv(|#6GS`8=;OEF{-TOYxf#J#wTbhN2f0s7zFMV z%nZO-7cg5{dmO(eoCn+NPSO#@ZG(Mz&`U9`CED#sq0g<A9l z;6h$Te?Si+crd_*4h{l;aV+V5TRpcdeX%Ab=CFP4;|OT^ zHTvt$J1@h6Q~SATs6rWUD@bgrh#zL=byme;rI)G;Kl}Kn95|JJ?tbFAN5vPzpdpu& z9Xp$w0PVHQ<;A7<@4?V8B&M*QK2PxSyse=ErMZi#-)1x8ptm|cz%Dy-FVt2;bNkzn z(7MNWpem{3PH^E7i;8p3Q1Bjm3-|L`)6qTo_Pa*+YR)>5mTiTXtb~^>MgOkvBMx@x zQ!T``)MCJn29kv!;Tl(t;%k^n}1bVBTcIi1FG1Tfs?hnOaq0 zwvTCpk0s=Mg4Q$`&WFzAski4lw57+ki_I95hIRNSwE4hTctL*Sf}-S%fm*wbX_~ur z$GuBfS-1S;Rx9H!EyZzbxe;R$*FqVrG{Ia2Ok}_kzhtrnY($ssNMNrBcFI`h5Ie@- zIRW^W>^3Yr2rWC17p%#%=G*4YHgOF2=C$~T8T=F5i5$J{y=vrYZLt~$`S~jm3$O3O zXdiSn!c;emw?cIWJLb-KR7AD8Nwb&pFDFxM3-fZ9u8pFUI&m#J;cr?kz>A;|T#E?u zBHPxk6k5AlXf3bsx^;r9*KS+0PIxV!$hr+Egx0PVSiO2H56?DUUKB!W{%b3;b{%?` zFz;HlC)%RNqU+X+^6~xqng7ymTfIhb%^I}*XM}(H3vJlA0^wP|j-Pk+dYUBR_KB0w z(gYR71J_SCdYH8tD=gWoF6dJ@TKH*Y;VBhima6E04xz_{(ris^@{-AQp-nvsf{X`H z6jON3Ww!XnbnOjR(|wr9;f~hK^rI4J6Z)$zAz9w^7Ta9)j-IJgULb8*dXeK zV(aE>5J@RXJPpqv)1@&#lkqPCGARFvfdALD{fmQy|2+p8R0^sw1Vs<>CElz@hUo>$Qro9b#)&m4on7N|^`j=R%#|KLYYJ;+al^o0DY zmtcaGfA8|kPCs`TZWUQ{!BH)51=r zo_P>|{_#UIB`Ey`!!_uzoWgi$Eb4xFA1aEv&mPZlw99w2O0hD4(v-!YPm6AZqtXD1 z-$T)7_>(^V<16#cOZbxs!{wZ>7yBOVoBntLnv)>^1H|5i_m|ou47TGSU@(AhX#HorN%82TOIZSPLbeJ1z7EcgW7#s`u)XhYfIGw|zujY*bmc zQB|eX+8PpmLT4kYf}yggFEpgyNN31aqf=XI)?A;hr#Y>yGNmEQF{I2IijElwOc+bB zP3YrB^l?Mdl!?Tw1^=uS?~LUdj_u|}M_!GJugMdMm3^_x&D zO+*Uqh^Y?ppBz-a2Dx0ZH@v;q`fZfwuL!pUXQKi`je0Y~97E0A0B0DfUgoxG+wDX) zA-saCc-J8U8&?RfM}*LWb%@}aRa<#iqg>m9V&&@1JZl7ac(<;>$g*V(&sLsQ{5&f+ zuUU;UfdUjB9K`1ts?3T)%sxPb>j z91IL*8|$F2z3s-i9D9QzJ%vtVr6B|PL2c@>!0=Ushrn z?$Ws)J9GBz{^`z`O^h1OKL|4~u?X|!0?teeEDiy5F3lAHWKMTIX?)=R$zJ+*kONc} zFS7<$p!{EjtXzcO;V^&0-fV>4&gC#cARnv%NHr%>N=?Ec|IH~I2|+IeAG@aHq+{iwTp6&h;h zvwqKI{es4V;ct&1<>S=HC$pboprr!!=RbtoL&Z+M&=pgf__MLWY-uEcI_5rr( zraJCjpdI{4fszDhOM|kv(1EJdx6l#~#qXg0I}|-_JE+#-L!5Eh0uCFnC~iB!B^wd0 zjTqNPV$oK7*->J_Np#43L%Z?X7OO3#rW$3L z{CAFpSk}3l^q!Bz^5u>+!cYzLm!VTiiM3U+ib{inQMQ3>p&_H)QN4I4tz26jZrz5a zR%oh+=`omRLr-h{waf7q`ejzT3e|BvmZ~+XQcPnd)H@xuCa`QpJ4`lqS_pNS6I%^Q z9foA48D-cC$FdX{GhIDxxegVxsA64o5Sq2-n>1TBX2i=jlWf-#YPG~Sdr?b*hy_Qt z|A^f6F;wSgxO-C6z8}Z-KJ_*K>StMX(D#pxVXm%vN2u>dM`LUm4hA)CRZypEquAyh zyA_P})y#BN%yraEb<|C@)QmONO*Ax&HMLAMw2U+~jnvc()zysDRgE-N(5oi8>V`TR zdb*khI-38b)zebf(N@>j*3i|_KwI?qznu9mt)Z@#zMd9(FM9kRdupgFZ&#F+mS(Kx zK}__uxx>9M%ldj`UsAYxs<&Cbhki?_eNBKx@gBo`U(;N)bJgiY4 zsb1v3D6*rK?2&?!Gt(7euyC6TuUYVU3i6i$wSa}N91rk)aqxEc3#T8Bv{)B?s3}EV zFJ5HDI%E}U2~n?-M#9Sy>2f4#I*Eaa!GB}l|C@vV223RW?>I=L(*B9(N2w=8m0(aM z$P~OdMM{h;{p8Ve7#}KrcBLFOJ*f{N{}mK}fp3q7j~s&3Ut>oci=7C~VX`&*Wg-1C zq~EW+61tH77JE@MSPbQ#ejT-&NxTR3Nl=plzhkC9UTsImDf$ALpCCP+bLvd4wO4-N z$@J3?;?6xwG25MFxvR+E_?LrHqN`H8i%gO;9i7nPjQG2cX;g$TiX&*<&x}$p(chmD zdw5Fp@p;*|mo(oUQ2XGyGe6LzBEYo5Pq+QBWuhG;-%q7xzsVnO^|lb*u0WMyv(2Nv zc#iWXaN+|efkh{gc}LuwJz?IS%)xS8h)mducA9SJbl5TyF4Gy#sN6?vJ}OlavavI2 z%lL6|?nP;MZUpb0`_JpfSxbI0q}|_5$%+gb`2Mjo^;cQ^x2BBWac53F&@yW2I-iq@HQ0G~T}RC+0Q zgr;pbj9c;yny=|H+S+D=ABs?hAN!#205qL}uG`T287fd;q8M89C(GlZE)81qMx!tG zTs%7X@Y)?G6JU2N!?=RB(k4lf?TWiX_U`j=u=Q}X^m4TEbh7bwwD)#)+~efD$Jxcl z*#$lJa--rw8Z!Pdgk%5?4e)s|K!{oM^PH~9VTnWURh$>#$KuZLi@)ml@aBOUs( zp*tJPSk?3kI^RPjY6xya+R?5sWh`H`y&x1vK}*o${Bbs1V!^!`_^<%6Q&Uftm!ASW z^RHb+ig$U>GGJAF_HKvXV|Fpd6GV{ELJCiGcqz2mkfH<$uLN5gJW` zL8H)dQgm?|4M(C7#fVa3IH@~V@4(1FeazL5?y7|$+I5lo^@mJL+|?!mTqnJ)yB!tB zLUvTS2_~8&t!H*-giBp9=BeLwEfvoif1jaKSScFI*YGIefJX{LNRuA6iHwzS`r z$Eu37hrn<+Oon2~{{f3zn`;dEb(a3gOQ0rVN1E2=QEyeIr3}k%`?#Chw4cF*pJBI+ zVxI+l!Ceu&WWWuFRakb}vg9r{=T2g~(#Kt7*lr5b?g}%WvTP4Zr-Q)w0Xlqfhs*#- z_l9ae=yZg3GibELc5sXwfzIRgpPZkBDtCJGQ3 z2#+Fy$ge>ds}SiGh$0WN8$lFTA{qpVEt}S@CJ19%OMC-aO96Ftr~>Q65JUn&RQVAV zJ|y#|9WUp}D5YTBIpd7XF-st~1bi5=QPWjeUl>nuW>M@#(s$g(iUZxzRr#uZG25J(&FH z;!p$XgH3e|cIKB=tU&k-q>X(IJiM&!Tpg_39jx3OZ9N_B-JR^c9GyIzoKOOKI6HVb zIk-F7q4acjw(@ee^l-6uakfL5^55a=;^5}$=?Vkg8 zX9rJvTQ@svTN?}Bbv(z<9A&b)0LI6dm8GfAli!_5e0dngasleN%as#Lm9v}*m?(wu zY?%Bq)qNd?Z$b6(@<99_d;UMJ8=*89#v@=UY#t)V;n4WRQTE6w_SmV##fzN9W6Q() zyC171Ig2H`X+cgJFj@bHx%U8TDs9(BGvnARp!AYL5<2$YMWhGP6GG@kM6qMSN8|Jr}Kkf;{%hO@_fhgN_3FU>J%U zR_+*9oCMWv(4=d{c`zhsZ>b;Dj?{H4%Da@st!fMV`9yQO1$a9*oVg2Ox{LKBC$n+$ zt&Ckwr_FbBHY3v=~2Q6z2IgCdf|@4{R7w zGxS3q0BZm|K<|xKrB{aQS~=Q}zO`ZF+kMA(dQ6x3+v%BDlnN=6B>|Ir0<2qT_^&KW z__Q5b4nWHu82k%VZ$McI!@U3OFfrt?@R0FmI*=|~_a2nLb+d=3o>9^0SG^yM&o*o;6nJ?K9S4ui^N zqBug1$R&#w$fQz`oBt2-EgBgR+8G(RvB#@o#9lm4G z{$Iy`g28`@|0)J;9Emm#SOU?UOfVzktsU%%B+_gb(%e6fo`JSz&C}m=L*{hF&JxEt ziJ~3k;bavZJIo>v(8(psCuMs6(y$w^eX$fokst{MeJny!2H8eXCK;q#kmm|?dqJ>A zl@$r;kwx*A6?Ef@Wt00n92yro*ZcXF$0lSRKK<`2c)V!eoa< zWRi=!J>G?g{4Fh=ab~V|rZcU~-K{L$NcNUkTXQ#O%Xu@69Pl;{_*sr5H!C|AbNkh< zb5}XwT#YdWPmphV4zveA$%A2k&@BVqLQpLP=^7YdKqm{be2X}vs(r?H`PmFm9ni81 zffggaM$%>D)!w+C)izR|GhF4u>nM24fQ%jR`2ys?$3ENQk#)|Wq;BA zvzpdI815g^iRCI;x1fK@PbMpIt2R?NZ48g*vI0YStZ+Vu9_WvNB04-Qf*(So_#qL( zWrT$=IZO(d?H3Y^0Lq7t5G9lT-w%XmQLW3QBcS_n8O~va1+%#v7AKhN>E|jzkfOs33<2S%WbH5rYd@XTE*r*gU@&L#U~U68=xW!o>4%< zWHT{P%7?ySv69wfpsFBDE9HP{!*E~3P#+&u5zrkfxi&X9*!(qpE|eD`7@U9^KLImw z^r&%2{)Z#sN%llXdk1?gj)=pfenIv`G7&Y%`xp4&a6d4J#p7)8I0Q|&@8|zj4C0)K zct;!}L|yDHTnM&KI1(A>?quV3b?>hr>C@dwu8mwE2(}k7OofywQkoIc0~@&3eKc%U zpk>QeC&&wjW;z)7FhtcV=mza(r6Nf#P3rE61=yk=ia|>|>5f2cjNtOj>WE452)tmG zX`i=yjql3hh|mxF4m>?}YG^)IGT+n?Ocuvl3l3OAIS)i}+TKu+BnIGgU4O#0lzG=4 z&pmgYtk55qD|P^E7uK&DK_1cGKxktMjX(>E@Gr!|YX|c%WN@ zuemP3S{Ld*yu-I=vyWh3C_MiizP^TUsqp43WSwf*;*cKsGgJjb7ems$R;#B2M5whK zp^Pt-Bm!I;Qa=Pko_wIFTUym7X>A`6HHzg;lA(IZNR0xfIm|^mOGgq8$*B<`;Y6@; z##+1E*tpu*y5I?TEY8k>jB|FvB3V5iKMzNkV`*z|V&!6MOE#NeH4gLf-d08PMUbD- zixYKn?y$-ahCRXH0V*$0(4m8=&+z%e8&mE#softpKy}tp2oPWcUNe+SCaIR&O4i_e zeX)`V$JQu|(h#G{4Gu+NbE+a4*;LBcsF2UmoYy?x+%3GnsY{+GGAr($7MFhn9YT@H zmoHO{r<%?qE!q^akxdDtQoN90Q2pbg!hbz{;MA|jwr@_1i3t5cY6v_L404$MJZ=D& z>5t}&40;%y{@*-?GZ_E+P8gGc+~Kp?fz%*BDs|!NRpX4NoH~6Hh6X_+QI}+io?UM} zyX#YQK>23YN8akZc*=(;pESO2F`r%(=99N|{+o?6-o{}v!ZDu$FjXO=`i>AGkNw>m zWk;8cA{(TGCI+N2Xt9$1Xi!8#M~LdmoFa}{DrF|*XMs>W4l{o2PZNJ0HP+67U`xi^ zlZXi75MBCxP=<(N@COefEsIBplJMOoh=epQ5(F}dKz6{|BVv^B4G$fLWfOStPvO5pQXwBqupK4rX28$PIsQj0=hXgjpUR3=WS zXN(s5n^i0@Df69Q6v0V5u;;~z6X5TxUT0b3`E#l_CjZ1Vd8OZoHemz~H}`KTu1UCf zWyQpan8ouk3+7;04D(Y*W(`ZW10)UWSTMo`*wFCnxK=7gwB%>-#DSl)hT|gP5yd<^ zO|UIcZ6UxGIL{K*m3<;{_J&mHC_JKa3tV^iw6e&BUGNFQiBYhtYv#}@I z5$%zt!#d-zsL7!n-qFU+g^xJec{VoAu2|wMD?5krQ%x|}u5Nsr zy1%;oLS60A>iYQ3-YD&GB=T#3jtkoGk)AMRHYJxozQTWMyPy4Fp!={t3H)*3Z8^Af zTGuR--nFDgZ|e%0dAdL5J#%z+l+Bw!+iHeK!O}&g9?Ki)zD4U6l{41lQ!HH1`UBs1fBlhJciT$Z=VxNqak;AGuhTGK_MLkTcITmHOQ?EhRciV!wA{TMerpD!QdFo z*wH^D>EKvIv{<7{%}~Ul03=|MF7&%e3GQDOz|B4(% zX%xY%y`2-z97$)~ur}zzZ97*tTjwXoFF>DQ;QY?7K3HME3_WUIZ3;YFDP?kt-}vm+ zn9hT4(3S+k7|@2I77)X`FaN#J)eSSl1Y>K1vBP4*Vlgd!;dZX$iNl#)VPlRDF1^ZEu!$cS*WCRl*)^TPL&%phaNl>T$BOArLL?$d*{5 zErE!xP(pf3B#&@Jl5=ZYS2EH|Vu@DPbM1+9Y_Ky;%;(^6RwQ#%ml+n0Q!(Q)QSpJn z{59tGj8rrL`MH>I5xB>JSX-LPtblnmo$qka1PMQw2WuYKr@a-**i9Sjkr! z^{vGVsID~}V#l6&MLTS=lB_cKIepkNr*a#kG?ZG(3lJpo>%#o%V*v%BKDkF^J#}IY;R42L?lfg1A9cE-#qQ<*x8rH_6!8)zx*NM*st& zjO4@V+oE$~S*=MiEt`3@>lrl(oWclN9xtdaCagTnuYLdO#(l(Z8-HooJi0o3OkNO1 zc4`&m?J?wS?0mK%^QxFYPW1VU_NUxX6j@N-pa_CFb!*gaUx^l z5;28MYjhB$Rk6{cLgfr`GPyKhY%7!Wl`^L&nwh?D$E#z9J62Bbq*;9Q$5frRfp*T2 zDomt_ZdW86J%bAiof<{Qao5=MJ?6zzy|(gM)>F}v6UR=QNnxi1qIDyoh+wPQYgQdJ zxzE#T$e*lZI}UQO{oLuI;OT>0GjvH9o80Yw;bKN{6}`!uwaKy?w+6u*n3=ftde zMYs64ei}4|!yr#2T`>s3N;uS|Jom>N-lbQYF5XJ=_F4EXFIO(?7xedc^>s@{J<85@ zXlsSmR)e735o=~kGBbCyuy#Q7B_2ycqy-tBV|8#c$Jr8{$v6Vm&eqbMOmsn7(A?Yw zVMRwbYiBomH}}a##_{Vn1^QAhpFjUP<@%E+I}1yAf2-9^OlN za4$bI{o2LfHpj*xp!ku#1=9jU7}QV}DjokRS`+~tpHBOsLXjhK9)e(y8b}YMP^r{a zYgS`^8AYWB^$FTRD*STqTEXwXzS$93dww_MKZo`rv>Z%B9=bjjIX1ik`2%$SNL2(> zgu;EV>aFBY5l-F7!9}}0?outE2hPZ*TDEW;x>)wLfks6EKYiw6sw2j?Qzo_f*j2LD zLQx?IMdJ}395n{{e{CGF)+8Hy0uE_EXFS0Pk40gKG$;;>4w<6ECL{!0h*-sw$aVyK zTLO}eINFgNZBg|}{x{0=UrW<}H%Cvx5*=`;{iQXU4-##h5m=L4ob8>j>^}tJ&XHTk zTEiA7xemirYlE+ufoj*Z)})SOU6p7C%45(M4*HFH*ni{c3NsvL;$+OSc}`4EPwL9~ zk(9YH3|t5kv+Gw(k17yJuRtCOz478dW<8pZ`4(tfOkGeE#m?H3^ybLX1|QotKJjzN zMEJ}C?N%7spjJoJG%>FKJu~^&IVm^eo?qR0?eK;>r}v-U5l5JgaU@`vAsC_lkQlaU zN8&&dU3|zUW8Kd^J~+L<6VM%iX{%vRALN+~@GVrqHd2pi8je$A==`ePtd#A%ueUA~ z-MCzMG5JG6=-c3xxe@NAyU0+?1|eIk_Cpk@7LIofT)6T+;_Ca|H&f2~Q#{HF%ld_i zR zwhm+h(sl$pTci`UAh=AnB+RhJj~PE@WBfM%bwSsDzy9Rz)s&|PO3U^tR9g)O9%v8@ z27;J2@_FsIU`)%pabi!T2^_%(2LW~vU?KK2?hLa39AJ^Vfdp+Qz7I$5QTHAMcy54N zJs?S6H(IP=s1cM^nYRvHOrkdzK5Qs{3i?i^toc*+Yh#niW;RwK5qv%`FoG8l9_+t0 zA?)uz&V79SJndD=i--45A2}Ky9uZ7Mrz%3|=x}8yi}7Rp{N+5TMIJJ52T;o0bM1aYJ-7hPqY=wvC%U9qfL5>|hCe?vs8mZ&DR*r99X8Fx) zDZG6LLditTn6abBj2itj&H<4xwg>|{VR3FGdsiaC(H`f3P8#CS{kiBS2$bE>Y>tTV zCBX)dXdu*P7CEuQqW|jx`XZasmvN`DKzpAE2G>epJ9v#pyB*g<0$^r6LB>f1M45HUvPsD;$tP5jiq z&OQ5W@2$g8PfthRyWoBEj!mc3Pj83-86P^L;3K0r)T}vjZhp|hq9|U@o_+5QpUCsH zEu`7L4;&3Oo6&NOy}`o*T2bblvnQv$dlT5)aOTcmVTD;|^WUA_8MSn_9maMdX2o30 z%jW@7=}xI29Mtu7-^*`Y0B?}(6}HQCwH(Z$lq(Tqeu7acm1 z5V3*$!O7qINy4mI=8gn{JJHy3a?-BNf&N~1Z~Xc6!G)CPN#81V4yw0|j6{H%iHLmY ziPoo6zVUu(@%lyLX))qU0B;-cwE}-r<=Sb@t4zN6Sr*0Mp<)koYzHaQWXHgeif-Cf zt3jm%A)?~?K+%(O_2h#q$J*=jQKt(~!ic`JsdN0OsY@1kv4TQ)4F6!dM=;GZl;yW| zeZ<9+NB=mJd^l<6_V^7EY)%N38OGr7X{<0N3%LvcJ3z$0rUjwW^q&ztHsjx1B7x+d z>;ONepO5$2)e|O+%g)O&j0^#&VMspM{H^xg!{=vqLth=}dxxaWhGB^T!~k8Wlj=w+ zNRpv@2Q+OQPLEc<+XW48&>f4&S8gnVg11ok7V=-0h5Gh-x=NRub$CtbqnK#cnhp8R z6mo+guK5jqenck$Q640c|G|R@ z3EGjJY`^c){Qa2C<@5rtavK zi+kjfZn;pbu(l^7nIF1P@cTX#bb}|l!v$SnPej-di$(Hu2iKW4I6TsFF3w~;&c@2d z+RDb##RYFReN^K5pk)ipu3k#Gb2IMo6Mjiqj9j?^?Xt9Nbg)afUY$lM;f+Bsh?Y(F zA%KrHx}k$&q*^zzbLCVai_jEJgjb=4mjO@|4f%;sbZ#j7mF^Rg^OmaLra?g=lomhS zyEXsr)tc-#U>MX7$Ur+R77UESOj$h7j~x^q9l~W(JrDqfa|4tgJu&GoZFK;6w zqmq&m&}l%U0HsJ?oZ0vB$@5(?Q1Ve<@===qT3h#}x8TiC^+##mHE~XoDklmGqlRD7 zTTgiOTnLBv*PyWgI;)gr*&sx1^EGeoe&KoQ7z+?NF+{V_v8)khQBvGn*y|wkJ@od@ z_-WL%U&c%r{j(DZB|dj75eZuhQ>?WG$p(u+auxwQhh#h3(Q=lfHM*&gjAVb#SfZm1 z*}=})8SCVNP@#i^lM~U=@y9F%o`}bha7Zd?_XCi2M3Om~G~Iz{>O`<`#@Qk2$j%;X zOSB;pOvyMCdz>*2H^T~VWrwxAe<>N19esc7{N!)ny6NFlKgky7jCbjNd0R>m!%U`J{qJP`QdUj?TG=74n^whWo?-B^mkO<8*7-p(< zzP(C%T{r#H*MO`~+>}TBgs_<w5e9gi>Wkw_Mb(m3ApLJz7PJd_HcjyQQnE zwVQ+8Y)AZTXM&qMfjkdux4_1Ft}PZhCzEGk9p>0MxZ0BlE_l`bFa(1#N}jncn~Le7n#w&8^f_wRnLvom zFl(}ojXH&je9ansrsaE&$_&JO2>3b6+oaInxgcQKn{`Xa+&2zkThFBY7^CFqgrK|A28G9qRxc<{e}4EaucA>Y}M_kCJFm`P(ZS!{M#AdR=$BXHVe)APs9fK&;C zgOH!ydFh1o{Qe@|x{S5%UxOBBuXagW;gsV!E6;a+nlI@k%Op3^?uid3-FtGQuXDw6 zr&7N~P5a``hj_laeDHWIEo;{CRtleGBvZBZf$35Wou$)HN(tuhPBxYyy*<0sVVA9V>}&WWsO<0a`KFE z81i(C^R%&qDdTZgqwTCP4yG6vJl9GJY10^-b(#wXC9Hdub< z+IdoUPi#+51Sk?gxfec%G=|w!`4S5#EApaZGWVW(cl3`gFUxPs#(Z3iX*)p#O_El( z0U$}-8~^05Ic;UTG?GUk`6&Hz_vMKVzwV$TUwqzF%>9!tgTsf!!&}s{4WRn9Vhg#{ z*Q|p|8sIpgd&<}|fHoP}CPSfi(kN0(B)(;%8(ay6g3D0-7|NeQRVvhdfVLbcdH6Kc zH6_XdTDPILW)Lz6J_A4(1Gj%LVqkEmwEKAW+l?yGN2R2^v#X|GChC(8h-GR)YrmpL zscezVHglS5HOtjvHoN;S=>kUKe-HMJlJ_cg$+n!DzU?~-D_ zWtH@`8LMXJ`YnIsvot4)l^PfPcWf{;RSq`Q1yd+f#!n{NI|T(YxlGoN6j31Z5{~Lqckcc2Q-(y|CxY3h>1L^A4RuHt8UOb)_ z&-uE6_TI}i*W0Dke`cBA%u?^!6+Uw-*Uc@b&&&w5NDZ6x$QRQR<*MVZRQWE?BwGv~ z+XgL#ZC_GB+&WyG2A`jFux85FO#;6Oh)n8P^^=%k-4o_oAG-oFZb3(x^y3QI_UV+wv$;M=%fyvDW_Wva!vb~MlwFR zo@v>z*$(=TfpFuMRd-ikcU@d|`01TRTJ3?M zp&g*v4xKTTzuGjgr#Jeb7|e-^ez!0A`Oz!d04EL8p)<(1KHdbHV^D8=dHk?w!>uzG zcP=^K_;c~!7nh}8^m%o`_rkHoE8H<>qNalW52a*-P8kPXVNf3RVHswC;~@3L>jQ~E zvjfU>v_41xf<){vhtwWq)*Isl2Yeuz55I4O$EV=kHF);h$ip+bzxRHLnwP(k1ht9K z7bTMWbtqSAfHDMBojw$XcYyxBX~vnfa}U`%qKdn)-nbW$LP13G0*LzI^ zt_6e`LxdGjZG>y5cXDmJch4+6M9Mzskh6Qi+r;JRdw6L(BeQlyeAykHvz1?dWYgPt z#pd|igFQjq0OA(<%6S&!FuqF{tmkw2-`Ax5`#^B_?=gsS;y)FG|N0KPOpZn6 zg)kUwe^2j~zl^~wnCIBrUWMdzw~i&;*ulBKje0F?N$wH;`y_hiKHlq{oVObpMG3*> zNsLb?7rZ=Z@n-w9_QURFYfX#inD>PE!^6Ko-mk2yf<6H>e}i{_RC?R>EjJ!nYoS|X zAzfx7T4mGiNfNS_Y4@&&SN9-49dbX4KRj0yeh?MDk(a;MG`$wr{h?^O+?jhG`d_{H z&7(4dr4jAu?cUzfakfj8+9$8*6Sa!_+LisiI-zK=vtQaL=@pBF(w=TvPq$RmEs+Vu za*?QSKwOWOypcawRh)RWZ?Wk9cF24TX-}c#Ig~wt;%89!5(-~I(Q7D6h4L3r{R*C) zY6w}>6XZC|bR6)UHo`R1g_#$v!hB_6%C=5`JRcB88I;jtWqg-*_xu11b{>WkWq#tM z=ga%iX%C_vpYwiramjCIECqrvbX^(jhpx!%cuXhXw9dyapSmn#eRRsD^yI1ONzs^t8!^WYPdT!8EQk*4o8m#Y z1%~3GH!45zXGyGW=c>t?0OD{U38+|fhoJX#G%NH$&Iwu$UdG0$LR<#JL0u*il(bl2CPy_H`I1p6+Am_s1HV_{L$zLP=&xOq?I$f(Tbs3R^nleO(eU7Dpi1;E1+FJ9{Tss6EGdE=QRU|VJHz`gFzJw>h&547cH4O$N)J* z+f0YHxRxzb``MG_tEXvKn5dUe(0Yv5`Hu&-8HBnk*$NQqwFCVzJClW+;+Mdd-5wwXI%pwOY%LmB>|1V1V*MZ;; zU9-($qH>W*`^V)!3xoe*1hZ*;K9$B;=jFG2^mt4F)kD}@4~E|7w@;-#IQi_-)|88h zAjs7=r9@Fq4p*8oHq!!qx0`&35{X6Hkx}I&kG*jhPnoAMeX~u=ezG* z?cBj^@wFfDz^fPA49qhJUw8Ft$L85qU7mAlycZV-d6vWmzmI0U+ZK^_bp7*#{AWja z*_T3#ulhgTNxICpDY`9BH8anxXCOqN82%N8R%Lp8l$SL9M)_Rox_zHFgPm zyV}L=?UJT;NkhA&xkKD6=x^=quaWiV8Twv9?^S3ynX%oWaKp^T^}fvs^!(Vhxp8a0 zMy)N2^em6^`WoYvzX1u)yvRk(aVvT`vqso6!5=%~IUTrIJ=>%|+^Cd``I_)^&MpiH z!eMYdYJ3fQq;TwIF7?Fkt_fR>Bf~}=-;clh+x)^b>eqa4jeG+P#6lZanld|+ixDuU zHhbF?(wAi0yz~m+(syMU~7+nhMIe~uyW%u4fL@>Utk!ZOxqnN}+m~>^9fco;;I8Bs(}^N%mHFOIy5=i^JqO zZboF{G-o%0rOV984zrBh<{LS?n38QsbMPj%Q=Dfb*qvf+iD_#-uNge4kZe$hBh;b| zpxB}7jz*P$EC%}4Lq!BMBz1(3QPC0kWDBcobjyw8i^nN_ChHhh3ST=xAQmoCpyn|2 z?uUV6FmfAoZ_#RHAOVdKbp;&ggx>l$S571+^6PS6G!(ywp?>wCpfEpU>{!e!S0_G~ z^&bN82k!pCRzHN|kIVnF7-Z4IBY0FsfS14b*h%9~olEW$_2_i+nzB!M?;qScx9jfN zouF<7Wh=THSJ#Ky`D(gA{#mKIGB~&wU3uHKqc+;EiRPHQ(m{?EAZ`Sq9GV5t*#Uo_ zY+Pca_HY_pgq6*+2I}G=?^*pGF2m7*P1Kd$iQ!*kSy^$c_lca;t;}cJDYp|=zerrs zb&gTFZAsTjUdKh=tF3rpW)Mi%YgJnZ4Zq8VU-k_Z_bM9t#jUb_p{iRxAdn#EJ@T5K zfr_4iG9-ip-}(khq_WR?RhqW@PiQ*?t$T{LTNDSIG%`v3VM|&==C_2*7jWnIaux`K z7j}g#Xp5NN5;?buW-nkm3j`Y!GU~#Sl3##MS|~Z*c9P zmadV+qQjxec<2lNuoIKV#|W5H1_CXWOtPHeC}I<39Fm4b9Hx?h;si8j@G%F98PEto zwb!7u=&lNx+Y>|{iCEm{W!t~TtbNUt!A;I>yU7Jd@t;mvH(s%?PPQpKN~}v>T6x^B z_$Wu8braf()HS&<*sYRvb#}Kl3A!ZOkrv^g@pP=Kot>MtCDFzTXJbjgnz@jtFLa%{ zeAZNV+!$xVG%{L&(ACD?37wT7T9OFHM2m?F9W3lkM%hlqAey0}a#vw4{rQ8rcP_gZ zyb8#?zUb8u?zfq?=Hj5V$8bD*N^$D0bZTg4w9F1lOhV`J9>AUJmpWn#8 zbq@V%@>YH7CV?`~+=BS>&9Uu)eT>s=Zekdd@G_x!n*dru%e z4Q^lP445lkPSCHm*R8QP1h`1N9ALc<+&T*9w||YJ2`?W)r!bnofUFi|6;S^U(tdx( zoz<|D0zLKBEvM=qjJr)KE_S*Vd*K9sT-odZk^Dw-dGkz(1f}wIIb$T`w+w3KzB7T zT@Wf640crT$U_mX3aYKn*BX57z{3&^e}r7@d)7^BqnNa?%$s7c9Ysl1|X@E1+cKd#Hpz^Y92`z z=FlEwAqujQB6^jAg8W9&v@JP4TCCYVK5 z(^lK#7g$*?#agc+na(%D&~T~ce?Ol17 zXPFx|_E76$+I=c59c%?V=i{25`(J%c7qvwHU?8}tBL9Vnzwme+CT z_v%wSN1p!)FRnw%-;nkM-aLRuS0L{WeA)+T(U8K2+hGIz*^R60%6-U6n<_lI@8a&N_K~OOWO#v2)J)V$x4vKHxjag?Xegz%h2EM!-Da{r< zy#-~Tq4{gewS&-*1znZev}qfF*+aef6%s@8 zr&`4Wt>PXM>cKmM>YED9RmIS61Iok0s$B?&LQ6=&&YzkSCy1ga558FN zu?0UXgTJ|!VyX_DuA`f){7i-^2w&SHkFkCo9_fK0c)?JR3&gD!1vxkP;j-6E8@|kh zf?d$O2O1*u-F&T-GolYu4048aVIw1Pdc}I^+XYpL%6n^T`zfYX1TV$){u4r6=`?kd5tEWvl&-pFOGH2J!w&!dR{;Cn~8XnlK>5c`} zHgwsoFagBLuMRp~`q^obUyr+3%AVK3o6{aXU&x;=VLBTqWS}4! zqV>qSiQs2~$Y~uHE9F}EhuQUqS`SB)lmXMVE2kg=Pvc=#H-Azy!=WI^F5PEJQ7|^2 z>5#{sTO8(fdzq`~{GrCvd)jZD{QBqq!du6ozZ#K1-A$EX81AU48)|9R)Kn{~>a|TR zn&z73PtRVQk2@7T@7}I;DSN1*S68945^BF1KE0~Cw*L}q@zsDuHv&CgtdAAFe1aOq z4^^Yv-wc(YZv$<|P~N??_!VUlj&&519*-HV9>zt?8Mz#6O~~p>j+gq>_L1xR^w+mF zZu7}ng)8+Ylu~9CF~$`{j>-!kRluB3#J0^0cFPQ3`i?y}D{OgI=&H0(kH?(l&DW09 zKDeN+%ZDK`BJHl+`g`(fH5buY!CK z`g%sb|y0XH+M+kGw##>6cFr2SayJ z>!%mrQtm=mOT&Zv@U0B$s@^8WLstz{lql05KH0ro_=yMo9FTg0HUu4jdnppBhpm>jqB#h#|!ZweqM!dqA#B(!oxhE)HF+(#6f+jj4&p^hJ#y3NZmB zQKI}<{$vFK2r0~fKw}6p2Cg-*taUWI!2qm|Jxj-1B=mFZ_H!Me&yq1_b@)0-_{)2u zR_9U(89aP?A_01iL+?&?YZw@IY5Lw6C{VSZm!Kbwd5V&EX#L-G}5Wp(;QZj zwTs+^UTbS2qSFo>x_>gcVU0tZw_Ei}QpGAqNw`muw_7%KR#xw7I{@`AV?eoAon4N6!4>j}>xesaXpoe(ud{9mKJowJ|H}w|M5z zNzyH=5H<_mPM_3HU*bTGI4IWc~f`=d{!8#J`4=Liz zsf?Q|IOv_ubZXqiXg?hNB|hjScg3@?zZMC~ED&b`Gy(`T;>O{gcIfH` z@c{Jn4|g_zxcb(ipp@g@HxrznZJ5<}EphnaF=$AKj;xLgk>3vZ-}1wLj9qu1K(c<6kURx$J(d2p}7Rg)1c}l zWMAvp%FJ46S;w@gWKAe!V(KDB6?Y0;W?Qjr^56`@JtQCv@pU`rOxB z>Ax};qZZj}0W)BYg@uu`s}r5c2xc+=Ps`5#@4;cynZXQB7>CBDj~(-q*NTM$EtMc` zeRphQ`fkpv(8aH5&RHy%^2o(+*V+`aXP0mmr>~n?$XbxHZc;wqqJ(K)o;982RJ8_&_9^(nNzhpvL> zzaK$;Stb2wo7T5>-FfgPe*N3^8=#^QzGU1?STIzz8AJ>i2|z-x_tyeTY@o}5r+`?& zNb~?~SLqVKuw6Tl0NQN;yOo2{N?p`|Axs6K0Finz1KOFHTQGv%Q~RSQhyzDMkU0d| z0RszkD|BZBfj}NW9yLb7e?Tao&yT6N?m%7%vg67(^ z)~SwYAz8Gr&BLoQH0I;M!%xnfsiMy*4V($bH=y>I>Ce;GE^6KxixvtjONG+Mjel+X zjpYnQ*P!U?EuMQX(zCU{9e8&R-d#!yUQrq81xMDSTLO1*<%v}Icoj1LL|tCXZ$a+) z_HY+P2tmg*1Nw9ngEaFYrj?RwIlwm`2sM?_#sk+B^%~_msp+ob@Rd;d66)SU=^e=X zqhuGo`P2p|dx!cqm%peyA90nBFTP6GRvZV_Q(4P(MPF)rOX|1c=LP96ia&g)|6G{) z_-VuE4=`BWl6M+9u0Z_>$lj{E716TGLwb}UJ{FW6PAK0uU;Qjv_jXUs$v*1A>oLc}l{jWvipeY5a^3iq0--?=3ZVF!g z0c9z*TNpV$_N{SF@&!Bx1l>{r0n&b-O;_D zQem(ks>|S8@rR^s&m(vRyLUiZW?#y!^oy*HFChk5(2#aHfR7&5jzG{L_{zXX20@)e zl)e#;0@x!Eq0#bmLt%(4)M!{kz?NvdrFuW5CJ=@qp*ON*-^9xBpJb7fAkqSPGJ$4; zK8Gv|w17Kp8qke^X{M!`LX2xyuw!$~LijxqUi=1cZ%TjPS#_8KFO$&8?r#so=Qri9 z_l1nVAm`c{3clucB2@nkEl<8&j=#BnEqs0i6>n8_ul4n*koV{Vca+m z+5F^vXeM5jfw~KR%aYu<*n9pk)aFCsi^1fL-A5wf{bkgCsw)k|=}>s#6Q3Z6A`WoO z4G0e+y-lDs1lf+zZ1gO118c^2pPA`EG11cPni0x~TnZ(Rq3juadj@Seig$m(msBJ> zkbk%h;$o<||76cXLFOiq{bdkdYOYMKt-ZEwuixC|)@BwHtt?GvyUaA3GBt`D@Gb9F z#g}8ye+l}Mp<-L};n^8MlS@Nv>*5`SCl*7~LFn2y(tfBleRuQw41N^mHnLcp= zlu!@GE?!*T!z(3EcQw4EgJ=iTaR$=-UY=YHjqjnZ21IIT7xcV-(V21;>OKlj#<%V8 z)&I?ciY?Hw0bMfDwh!8`fZ!waeuJJ;sLMh37qk_APTu)PWWa}WyY3v^plK;V$af=; zZaRLHvyF8$hr?(755gdyNsHt%LZ|`$YgQSL8^iEh*WXez+}HZyuX8DC3_j<; zz2w~G=JiXA^;9whyA81%Btf`lUt3B1N_cn(N}mtiJ(;yVSn={t`3v+iDsTnnNSXv#1YzW`}H zT59Cu3n3s7BI@;g(-m#CgWHR(Pp5&7XC=ii$#TZkQLhb zP^STPs@iMf0MoWLYF_Cs3RJ)7$h(vI`yOa1(iLYwML~Dk%hY4rq4Kr1-8duN z4^vE^^qDrkWj`5OcY*#W7?MGC2Sh3N&hYP_j=ynq^PS^IUtYR%dEXID*VkdubAA6I zM9;uLD0Ig@J+!3o!VdYPXV4^uJ_Ty3+*k-z?<=>_>UMZ)?y;foC=Bf#l5K;L%K#r> zq#1?>Kqp0OAu0Pn+5773;cL4RYCop56=kTqn?NnO|JRji}U4>y#>;fTak~dxD9O?(D-<${Y-TUMGpwI ztpQj!q(|702E!DPdxC}u3O*=#N}wx%Dn%V>g=Q=dx^<3Ull@yl0 zi7UK$0V=Yg`4fElt0H1vt-pnWZ9PP@KsVH*qfbQeCqkedP%XiC60l8yX`$hf8p7t3 z?xlgK0Ho#6Q30*BAI~O_R91mVJn$tO1PG_3+}tw1FFOgkufo7%Vbg6SA7qDlJIp0b zw>5EabtK?O&P4LY^&tSw?VVRNvNIsw53O5D6Q-21$JK>Q|H2qwwZj(5)*A-*d@qxl z0-ATXFYumT-t^?cjyKoNzPxhn+OJ0>?KuG1O$~86ePXXLNGFV~zsdd(>sP<~VEd6v z-Is4QUHVP&^zxf%kG!y@W%2VBe^F3ei?;N4Zv_1{fLs_Bz>pgBI#8=%P!8hWH&=d7 zyY-i#;wu=`>H&$tpsR0g89iZ&>&!(#L7ZR~`+pDy8Ejr4mlw$QUrn7ndiv+|V!eC> z1`VJZ8fhY{3$*iLWI1S-0r-K^)1X)j!)(w-=nauF z16>JBsVD$l<|JXEo+KK781fw%MBW(=eLJD)NNxHf3+tXDlLuZD!y+`J6^6_w|=-twFKAw2No=Ge5In;`cU)O-|d@{xtl z8D!d_bMzDf_&b1~69hN{l?XK3VI=1bwgQf=j!UX%xfX5khMM>K$_!|)fXaePk)hvi z+<=A#XsJbYUDe|=O!J0^d}ufg%IAZvk71-SG$Ls3k~t(t{K} z$CpD2t^bu*Ybr&YxkK^gium)3{@joHk}rnh&qKMHy|13VJ+?pR&kIdi?_f|oq8R|t zxA*jnnP%*=V40^sjq^VVgGh(KpmJD@Fkf%x__5PVzEpx1U}zXLYFTk^+v^8kE+6Z8 zb#tUB4N9|hg_&sigS^L(c^a}eh#q<>pZG#bNLr**{c(QJ-Q#t4E@b|3vHE!md_!6= z7g7#ZL^(J5S<3^kdYV1Dq{`0%d@X=t3qg3^LJ0c)Rkq*+NcL)#y2|WZz0a8dp+B(Ve z&YU^r`Q!a&&iUSFW=|%QVJ1U<`&!ppd#`m}9hX+Iy^f4x)dV3&2l2|i&YSCSd%CXZ zNcMc|kL*IG7V1YCuz${fc_AP!>9SOfUVChb5Nq7bfOy8z1!Bv{~M z1yn51!l5Uo>*mEahy7IhJxrvs*k-L5y_}0(#=$NZU{=Vi*MRXl&{vt)S7SS9_W53d z_6#7G342NvH=&HN+}Icx9)yktX;}t6Ill6mBM_?uRhjgv??4|(xpV!~?EpC4&`JP^i#Z`IvX5Wtb7bB4PxS8 zUOX@N8I+}oOY;dYpDG0K3FRaHX7e6r`6zWMQl5V*uI#1e`^CupLiDZ$n=NePC4gK5 zrfUGRbKdDJBM<|%dF;$L{m*Xzt7k0bY1yryh4SwT3%seC@lQUbR}XT(JHkjDOumA# zRLOL;H{M)bZT)uTbtlv{jw|mp*mEqx#Q_9;Bg7{ld<6`7iQz)_TuruK(yaX}!E!ax zZ#&dp0ahZ9BPaTw3-s!OHd;RQH>@C*tPk?3+eWa1R`D1}VyG2g2 zfZRx^FRb)&OTw6B_@kv2&!Og7pX2f7v&+Yk>qf1Xw3_}x#3>QY4h&f9w4=3Ztu-60 zPgfWpt+6;&VRf$F&Ajv2n7;*!&0OqBb@tq&?Qm z9;a(!{Kw*dUOay+Vo_mcc&$} zc6B-Gub=4EeLlyF&G!vPy7xT}8qIjp{P{^{?Df=8zlz&_Z8xlIY_?KN)-sJ(h|x-b z-5|19CNNzrwO%8!*&w!6=b*Q6Y&5|86yOg_?RL>Gt(-Ddn)W&Z32uUWA)=?Z>OHlk zX|7Oa1vQ3HsSoW~sI#IL=(0L-qeOgRiFs`ex+eQDjJwQNnL`yyR;UlnX7d&Mg&n5^ zgT`!%?Qo6rR7J>F_k-iH7<%Z1G3+KGdZpBQ5g)UNk6kLku2Sqt{k3p@J(%rdSRU?n z)q&zfm}&-c%>uCo`a3Fv1A#gU?;q7U=+`@F|G;TN^=BZIrC;#?-t0tUZT06jFiR$V zix=0whPrpGudkpW2YR}vlU_Ewdrh&&q$wc&DVZ`i8|mDfl!in(;WtWz|>D5 zWx!A_Z~`GUR3+djAam0%RqMo<&e&oZ)L!cPNH(!xhHcpec7Q7XMv;UA4`6R;)IZ2J$mJ zq%}{)gzsq&Zs5)I?F_VSv^1@bY1*DS|0W_-9)f!FZ_HF(hC(~|Y)E%r$Fto)y72e3 z({{%7lh76mGwCp20)kE{v$Hzq*@JNBgh?+HVt3U7`$|({(^eF z@pc00V56}{yVZe8lbtQDTHkDrq~Om#b-p0zuY~z=7kkU!en)KEp@Fu+$}#xgpE>&9 za5rIrwKhbXYhKj)^)H02t@+Ft0VX@^UWLE0KULzRU5MLTV!dtrnnA7gj!N_Gjktrg zm;;3tDpmHYo86R3%$HS}Z)!vxg)jGDxB_|$V6qJ+y2VXZiXnxv_Z5a)s1~XWy+!lp zD*(GrhF&Q~uMpX;<=U)cSgG)w_Vr&}FHcq{kh{mscZj{tjo2Qmus$~V=-N+TuW~Q9 zH^#@R{B=4)4|N1=l0%*xxUIuqrNnbp&s*)*Ze^Zi+7L>h&>g19L zS9X1#LIjf03v+F+gD*ngTNuv*$`5ERl)b+9-SW&Q^vObRW9a_ThDX(!nl?DN73ceiK89{d!2`jOA! z#y9>Ct#^L&*jMPJHhB3M+%ZLt=^OIn4Qf78|=W>SX>pe{CZ}=EYAfx&(b?qV;Ot z?fsl*M@R1LrCvWbc?;PWgX_9y-yMS`$2*YjVS8fH#K(4(k;u;X!Ediy!CWtJ$547Y zYyVk#aO(lADb^Nc^WUGn{r?t;|Bu$V|B@HBGPiKDv%jc&Vg2eAdoc_5?eH_&f$-4tXE?U;Hhw%Qs`>`LHpZdtxh>(7N$ZQ_q=zSF;xBdDXo$kCL~%~+ zXF=@T#JSR}x%_-+X_9zVZy=>q%UtriVNE^GBe`ulqN>d%b$viqZsk%DL*Z~?)I~|}PclDU>9(C1~#5nS9Taz75 zbDhnGbx#PeMzd(`9$gKB`CiEbm+$D^uTeXmIvwmtybhpq_@C*MzXN8s zz;fdZZu^Ai@iAW=IRg$^@0vlbmY~-zpf(Gwwuq3MMaYc{D3y8iIyQPG+iJN4x1Mdf zc+PYw*J|~g)q0-IW+8gZjM;h)c7qtNF0k3cF;oQ;dHr|@&TB|dD02?2pdMVx(BD3R zJ(Y7#Js+b7WBoAJ4bx2^=!S(s#d#f@2KD9THpcaahe_HhQ|Fe74VFqw7ES6PNZJT8 zay`NC@YfsXsXZS++z-MbdDIdq`W}ZBM|`7XgbP;h z^#D8ygxt4K^#zJvOx|}Ud22KAT6Cu)@WcSRf`J|e!XRFlfCt=)QXZ zy{i+wx7PV=_mitLrQasLWeq%fT8l$B>K>(E+QZgTnZKYUHc=8=t`}IZoyV!N9d`^{ zYYf|+l0;c;NjfKUJuE(qlhs|7|Y6kaOXuex;98QASi54B!j zrSbqZ)E30PzYwRC5X^G_BDeJo$VD=bJyMrF(>{l*?Y4GD>9;>dnr=jFMIf{_5N+=* zTD(;00V*TTh+!85*?Bq9c>@8zsl#Psx5qk?&zdI8Z$oZM+{;H|jAZ=w_CjSg{556knY@5YbQWl}rgf{A8^j7(s1(d1)ts=lEi?AC3ufa80J+J6t+Xl88 zVDm4BdaTB{!BW2CHt;wM4hQByXyz^*TZlZbT>hJH54V6V>Jmbhq`ea$+%Sn^IzM|e`_&XGK@Vjh`G>* z)1`VEjys$hMednJA7;tRmRBY~@CACXXf_OZZ$MI|NYpuFaz+Lw6_``d+f)AZS$1q3 zv9N?(T?--+okIEW?Afwke^p<%4rgYj&`kRu%0>ST2CXc89G!7yNCR!%C4c^X=k~3c zY1-W6NPkP!Y=2APoBLnyUxTq;U`_y!1N;TxvVh$U^Q9no4YScO5ec1P1D^XDOg5I7 zY!ZCB2Glwj?*vL8^mIYS$3~OWjEnpDr#A|9m4pVXn0kLq8UH$g{F{PY+Ge!8(Nu-x zp#z!sVYCLAZ7|;he0c;I2R?s7$-od2 ztTV4(Y)N#Y=UuOfx>z1~jB?wU_u7q_;-4R=SsZYDCfSqt$fV%b;pQR>2E}uvSPQz) z&}O6118;GHCI@IlL$fioYeVN5s5=D(nviEcd*{T2_il#!E{3hL%zZ22Bm(^R&R8k6 zpZR3~xw6M;MFtW9RCi!H!mO=u-i^!m<_oR>M1vrd(Ps~wyU^p$`EqJLLh=Na2|L^AH%5r)L*)kce8nKcu!=!i$H%WS_)hJJ&{S4!4Dk-7Z9JS6J>^ zZ<3mBkXmk3Ofy-k%HJrQZ82)#uw7=oiEFr;Z>B6mZxvXm@=TSb*6LulTV%I$)_U`V z(S}JgRVHfNknw8brN4%)mv);Yh_-)KTOev27S(vFrl3})IcubN9ZYcD{mk`HmapD- ztWLR^PK(L;#`F8h<_C!8DkBam6FwXI@rxVG5p^aA0(y0=`&Rq~gux}mVReM^uZW!c z=%N_hN7wUToODub&Sc?EcU`k6vfJ6}zdO(B*9MP81owa1%n-eoeq~tfnKnE+VQ^4@ zIkSL1w1C_*XQ<9|ISikyU?2qK0OUjh`z_2BEAGn_#L5CD9oRfz@~fYI_#XF?Ll_1D zEYR5?0X}=?&)*QIj_$`;ncAX}|5GP0|CR>>-MnnftW5PxS1nyxUQ!A&@xt6Bh*-j* zwx+KyN}k*4}cFyJ;huf2{!=P zelUXvrUfvyVeSZUj)3qIOq;=wSMUA94Q^ZeTz3s&Hci{BLe!~F`ChX8tKIs~23v$e z&T+~P80H|b6iYC4jy)ejc@ROL3zEui06!FX*MNQ*x}6q2oNP2j3>hwAUfeQ#_F$i} zMVrf&vWRC{G4Eu@R9FX=j-6e~_SutbihveZm<<;*0%>EeVreA6V}T$pKU?op;t7Dy z!s$qu3sg)F3eX^O8+frRT^m8r-ZiIt2J{Yt(Kab^ofx%BY`sANI+Kl{uLL^F;Nl9< zU!_=jtHE%+!i^WT70}y+NL4vG3giVKQkiYDiEF1ei&EuV?*NBm;C^}@f4I+Fsq)e< zBwrQCv49o_=?{HrlZBwodZf~HxE4dMa~|#rXs*Y1)OyituT7?Ub%p5FVE5JH)QO>o zp~elmU13oE6S>2P8>iGjTx1E%yP~<<(Xs0vMJx4}V}N?E_RjGnlf^Z@hfAHdw}%{u z^2^W~0=)r}3KJM~fO>O?KQMjix5;D6#TWO1=@GI1PWHLAV7!HUUWH|$HXCu2pK8P` zGMo8f2gRXK7&n_8M@_%a$xostKbp@=Wo3TJz7kw^|2~Y3El|fnBAT0}4-Au*tXsTl z(<&U^Mlm+~zoJR_|8qTvLRr{cIB$6F?8U$TTwGCF22!DvF$}_S7_6e^CH#!VOMWEI zWj&CVB?aFnk~WbvyqU78SvO!X{21|dIVbEfvBgSR601+s-UyE z?wUwja=3ZD!}j)|?UOH0Qs3?weXl-|vWxs$o%D1sHv`pqSBLlrP5X3t^h3y7yA#_H*`K|sF0 z&-XN8VHZeLLADLxjFe|4neuN*Hl?QrLS7ss`1Cp-Z*@OXgxlB{w7tlCanV%-^y`5L zy}-CI$Fc;tJ31BmHODk9-FSc~r^463xylAHe|G z>JaiHBq8TU5}Z|oi>hNffA`w_O^i|nsvmH#3WYZS-qSb_V;-K`wFj|X6|rRqfN>+Is1>PvJFfx$LK%PaD4uw1UV=rr007uSKoDuv9N z$x1L;14e5U7&K7<^G)EiPlVYfulwYcprROb*v7HnG;Feli#b9!J4i9yPO{kAg;i^D zRhfEv3VM8C&=ba8fQAQd5J+yzg9CT^`aCyA2v2120%o4fmU=Z_JMj&V~~eAk!`J+Yp0vzYC7;Xwm)p31`{;GxxN<`0d+_W1&tC1IRGDTm_7|ixU>lbKv z+J5_NTf#{g_5)!cuxw!l2eYn<5xnsT7=HqsY#@IT{Cx2}%redHc$drRPR#yx=cAP_ z`zo&=;MaHo@0n=q28f@rXo3HdAF*Z39tW_HiSUAP51`zd$q$BsEaf@oM{}FyaertYE=hEHDMIr-KaxZ1`XaQhg8|1(60wRb{XpKt}|Ql7-mm z?t3s*3B!$w=93Q(`X2=Y@oRaU_P0o75Xeh25B8L){Hrgdn#vsQRa{4vc8A|! zLQcv7B5vR`C#;~xY4=IQq2maZ4Tv3^5J%MiTK^Y9a}OfG?ROg0P9U?9h>!lb)SqDfpiRBhPN}XZ0 zk%!(Yv)i>`sme87$F^3YqqmKrHK*OpnEqz{_|t_(Yg6@q?~6GKlyIP41y)!~+R@V2 zyVBxRzsB#XPtkA8N6I4)ix)l8=usGTFv)z${nLopbBNnUh=TVA+dGky(%^W5q1$e$gC^JP$h46L*Lvry!CL0|rF>mw>Y3$3R%^$DxA%l>taDo3WS~^1wXxBB zPl^7fAD1@On5#Eo_Ee#F?{5tz;Mqm5qn<}3dBZP&IP7)y-3HR`{l zv;RBme**>$4b1H9+%+|I5QyKACMFZa4i2fQ{CRl(4Q#sW$&VJBn*22zy^iNuZq7DU zDKg(tWpS+1VsAcjS%drPN>fCa@#0Ct%{=R4WV8J}?uIoty;84wCi!`HJbNroeh!(B z;B#M3M-;x6;3F1VDn_KvjxNUT{4MI>vip0N zJUzAf&N1aM%{6a4&pdEHeR3<}?4e(F??A*o+D2nJiDhW%g1Ll=QAEzMpy_Ycv&FYy zuo{MXVSoheN$9MAuTO>pbX#nfLK_Zv82-G`EX!~~jOEH~1b_vZEr`*uU<3>2L81v# zt%=EVT%M0Y8-YDtII|fM?!1`XW(WcY$qWYOT%Zlv7p-1ry{^;jK&zpCJI<#*Ag(;* z85r#yI<>gR{Eud@-xZc;^YV()e*x~@d3toUDq@2&LS-Fdv2!z` zsNm9^STPC0p0Eb)yF06yj-4aT>RFwJ;&qX0Yvgg!;Y4q&H|5$c%#nyR^zW-M?bhV zzCtG5J>(y_>|?$`<4DkpRIL}UPuCVZmt-K5Kc2Z9h!8Wd3dx!QtC8nhhvE(tyRQA} zycC-Jhl{KUC6=8(F+U0~Wn~>^4|s^b;d)&6HJR-uqEC$CHEAvfCr}%?sLdQ*r7_K= zV>TP+V@}MxIy3oPOZdndo_I=MT$xX}Jpa&FmKeZ!Xh)4PXC*mJr+5(GyJbX~0k;tr z$X0qM79kLacO0;@z&Tji{4Zhf|3eu5I}BPG8=Cm}2I=bPFIlwo%<y1`0`7@7 z>*8mEGkY(qSd!3J;qy~64#9pP`@hZpdu5(=uT~@Gw5=u-I4qtOvp1@hK z;3X3Tfgn&J4#RTMW7zfZfZMTt+~H26oeZ~&z1Wj&-WSI1J3?_hbf?xh9xp)cq$bJ(#aoza z1!kYZ8>KsQ;M3*%Rw{XsS}>Rp<+g5y`~U>s=;LpvsHsyES;ORv9|d>28($B#d=T`0 z2XYk<$`!LAtwk_gO{skOApxJ25i&6Fna`~fvMR?r(^#Z$6U3yxh9Ey{L~qtUdF4Ct zPN&#s|HNDG>NxY!;!tMKgW1tU&h%&M$V-rBw3K?udY`_>A8LwnY7EB;(y!Hd92gHc z#C6}hV5z}0+{g|%09D>FeM3qKgt2%SO@+P+80iCYD-6`YOdBw&Gb7EfW42YM1-*M{ zC+5j_4i#ms`x^pr_T)K}OQ!bL|6>^Zx61*o5H+>2wEP``utQ@ehlXWytjxqG%=VgN zD-iE4I|G9Zy^X*aB;8w=D8My+555| zT}pDk&=h*5B_!-U#sUZx(EGjWmQLv%RS^3y7A^?o$>+Qcu-vD|{6>ebj}OOmwS|mQ zZcUDdiiKAec&;Gwl1#b6;I)OuC?Mw5T=B@ax9hkW$;8l&>KYPRcxCzGdLxdt;(eB z_6c{b(O_gP?`d3m1qGyBSRlegC#$nc z(WfnkVPE$5>jpIsZN%+QIfUo@@$|C%Tk#K_V;_1wcpm!n?VUTZSK?!WyzKQh z{A${*TPb1T??QrKUkfgL_v~p@@Z-B7cW(HEUvYg98S?h=-5;561k~EDk}%2O<-vk8 z&=)Y1?bv?b3A*L5Edgo)h#Np6hY1mc9Uy5O>PQq%7XiOnaa2B14)h}EeZhWaHj3An z(o-4NSwqEdg|@4T-ch?y2@wR;jEAws(J@8Qx6>b9 zOL=lF{b9t{xa*mBugKTedts@MBNZbXKwN-St}KiXR#K4j;6)KnUo6GeR%*?4JebaT zE=^CBrKF1UQee0Sx-!4{?#sNk3>auO=nKG7!pDlIeQQf`nJIR8xuGS+k!4l4QZuow z-A-cZmFZDakOjhAcx}R2${U}-=QkN2lDO$qtHDeR(B$Fh3YUfNZbL?0Swr}7nNRuxW2Ga_$;mIg!meM~ ztcp0fbJ_aEh!3eJ*b8nTbb@J@<{+g`>Ld`;Vg<`sMejLahsrEMME_Tpe3xgfqnW=eEw|T``Kxu}S zoB}7Uj$0ULmY3B98#79H0Kk`-v0P}i!)U#T_8&4h_?dFs=tN8P!hDqbUALCHr~w8 zSDnCahL&qUxeWAhn7pf)U4ns`(N2Y$)7+>+Kt@PUdvN2+<496-IRIB8<1WC$`1B;= zkH1v5?sUX^;LtYzQ)e>&7K85g82K{N)n2z^MNN4n2p53M0TF+GpnJT!C?(=D%+g?H z5(fKWWJJ+l#AyX-v25mn0)wm==(^q?u2qKFS?G93R`n7@17c<`i`)T>5g2Kzb~r<^ z-#_TS8Olt6X%B!Fh>c}p8xZ(NW@B?M7LPTH( zVw`NsspjKZaYq6$+F*JD=+p9DI$IR`DQqKfg5-H1j~5Ufz5DM!5S!Qky7nK$tzg?{ zv5w;d@5Q_<4kNX>@yd%AJDZvf1q*=ySAm9wL5Dh@KdX^{HzIemIh)pB39h^r)p}+_ zw}o00ego9Iz?2_ILgtyC(<9y=A0C`)i-Cy(pjNU7`RT7hqi$lhY(nf*K^W`&H98S2 zhc-xkfbP{7zPZEvpJ|I#3)V^!+f961wHe!OGxl3&?35{vyP-AHthrU_l;BhhVB7D7{7gL52R8VPXts=|7X+Ja>1eXQu+W3FW~L?(6*jZSs-)B1*ay@PYzWLhVAv|YXi$C}84wM0^LKc#zwMrHAa$7g!`srAjh z9mJt2wvaG9@iiywb$kRcid@F~Fa=ZmM}eiHEcVirrn<&%kn%a^P@u=j+#2$S>Re+~u} zRUy(GZE31=R&&{+e=3TLWjwAz&`CHe?rrSahD$O}7e49>Zi^Tf?`S(u|p&8cAJhiQ~y$^bVrky4iG1 zpxXjq<$MI-pwOKVze@XP#}Tv(r8If4O1^(LH{xc|&B(k5Pck1p{T82)5qB^3Zg|R_ z(BwN|pYGlQHdE2*BrO$)RNfr6vVqP;}WGT0X<~ z=R;oS+Z|WKusg_Xs59E~4a}U1DE{i1n;c%4{q$>kd|FQ2`z+svfk1}z3Lo4i8KyFR zAb&gpgg>~Q`IRr9H@9;&|FdzB#)!B*WC=n@5++Rp6-28B5rR4`Y5%lIVY3=J&`9IcMCxSA;9xz8)IKycFfm=<*4slG9U7t!4o(gX zj17)V5cGP}&2S9EAniP-kAkL(jxV0iWY<=H9ka}{jqY~@hXcW zy&hWmsAZ-0e^p}_cVgD}=xyvb*-Lad3!UHP&v$;Hfz#JIS((>z$LA;RB$O^SJQ&GpOufYkWlv`1lI9z}e9 zbUpd;?UcvysgDz31{4G>XaQcLjO!}nn<(Z4IcT5u2lKP;1B0djPwqr+*{}$q@+%_gy7z|& zFDbbIMw5a0Y?>VK=-wKDXtunx6odfxT7es))nO^wc~7IoktSzMWk^I}_&v6!()5M( zgSN`mZcBlC2e?<|e>}$wd=|I4rO1BxXE?X#?O4O>uP^-{MB1M`j_~zcL7%zI=DPs| zz_1h4+qdGD4_mC9HD4mKUMa#U&tud$R_c6|I-pdzHaiFLDEgClpmqVh1IC(~{j6JE z3`!l(eeygrR(Ka^RWMvvX=B#n;Vdo50>%*VS-hSG#boGY%}mbi9RE|Lkp@8e$R(v0 zXWg%^%_dI_lBo>JD33&%>+WR8Uy1$9o&kFA;8f4hWY-Y2b6~uqZ>*C@C6VdGzUh9_ zRAH$6#AV?ZyzN*kAi6yOb!k<<~@n>`0^qm`{CW9 z*vOig%TWf0fK8G1HvyaWJ=h`N_dI;{sWSRQ=CvEl)j3-0`p^AMuvl8_xad0y(STDf zH&N-ppQ*>4`gTsO-ulE(UiiPY5V^=#z5`n{^wT5$XIn z#^vLExA%|ylAlJUJ$njV06rHMM5zU=PUIVW_C>H4esNK^83$1qwyp?76^*%WF=lBf{;^JPX21 zHGX9EJR4~CD$hTg`eg@w0uOMDN3a5B7%Smep%$W1Z*!xmR-=cEcl|SCz-I{o3*OSNt&mNs~ar>>4Y%T*Yjt~Vx z7Z~!Kd~vo$?=PC!I?d<`oPH* zjHZry`Op` zCOh;-jt~Bk>6y9u9N>*YLwT8_DdPsZ#c;I@zfG!WIZ$8FRT;8eFMe*w$S@pC)1UZ= zqP}$>{SZ0+>G8;$JCmQHNYDJI(<26x0}08#qWrk(}N zCS7H`ygc^Mb0X1s?4!xp2kqIUi}1{pXtuS_Xm=0#RIbtC=DWd^FK?3F-3K4V!^;P~ zrY9+SJBUaXLW~A5yviMzP(HU&q7W({%6}93Jrqfd!4HJth}Ucy zt|1GigeeIU0+($-XYeOt}bW~JQ9V{ zJG^HrLRA@|yjF1~7v-u&OpclQ5IdiAn|j*`(j&(1TE4MRE{i-1BatAvIXPx14<@5S zW&v)9*wB6N;;r94#zfyb5f-WRCUwWh6xEq2dwGcm!+2=0@AgscvEDk2)@n31taI`$ z4vovY`4n{bESy*)N%mexgVfMGeog)Ru(#zss4{Ab2&_*1TRMQ48GouN;L@aC@o zxKFdr%fFOMG670R6JDuZcgeKjYM#Y15o(zTy@qeGL0}}`r8~iVhY)oDBJr*629*JN zgxi+XP=hv86)J8!39VX>-&*Usz2D;?JaJ-NPyw32RynB&u)zS7#8ZT z>G0U!9&s85UecN#73W6Pbbjxk5j$zrj1eRITt zc{u>vd)YmMq9(#@_W-|#Bu6M~bdXo~v*qrckp7-GeJwbEyU-n27JQ~J@(%QKVU*LJ z^dTuEAU*c>$LkR#vG+^Dul|g^4#SNS!VftYl;cbXU3F)i56xqh6<06@8`zgt_1mon z!Znz@0nBLGKnzg7!b~p=_b9?9tqlgtVY;gLg)%CtaRptdTEuqpM5 zJD?#s%~b&PGti$X?j|TVfpB}o=SV+hZ-v1ocpCw&Wk4oEFA2JdteZg{1_vp68iT0K zgEw}=Xpm&oew<)B*KIH8yv+D{i`DXWyd$gT`-_Q&jIq4uDGp~}Yj3JVovK8iDZ-yG z2r>Hc6xUX8mD=-4K+A!tQlNha`b(G&Q7tPc#~v);ReUg~nyd zF?eh}=x!O)UO8gB={xclUY;3@`vb>MUT=!o@~YWOUgrwu9Qg8oQxYtga|Rwt4nye( z3dRE^Nru&Dewnx4#x+(F*(otB{t{qTiBTH?bqG-B=q8$@PWp<*U2;a>W4B_wCeiJr zDBNHaziY^SA1PS7&glRFyOZZ~5Zw1sPatG28gy$Fk@KO>ql+QPkfN(RZn?eo;)=O@ zhENktD~T*g4lgZABMyxa$L87w7+r%50-4@JV#^_>cq2~z`)eNqi5rJshzoR zI!Zp3e0b3Q^XjEtgi)KJFtLXNh8UWtJr>MZpM-i1@pLbSg%}o*~N4wKf-u#9@oH%mO#nIt^ z$v5zSkG?3%(dNuW9mL;%MaMswn50dNP^(6QVyx_`}?|;*fKC1m@X_41rw> zl0slV18zJ_N5klyCj5pG`f7mCxlr2-y+r8zQDwZNM`!hb_M&lz&Bc~~ zXZR|m-`tZFu=l0UiFcRHx$XJDBIP`~5oLD%y|eizXM=n{tDgbbAAUBOzPJxTxaT3* zZ_h86y}w%a+@O;gm_k;kWo9%yt%u5P=#wkdvd>+^%dsg@sHw?J1iu-g_IQ@I@( zASA$eP3`^bd6zwtJ?;1XhM;u(7@~AC#~4$iZ04MJbcRQn;S91lL#(->X$FlkJIm!W zm@^b|KM3bI7-CPoePASP+^Kzi#dXcRwbWR8rDBnYoJr@>QNFNoe^;lwAJ~i zH!^iLO`*0ony(p&IzIAF8^(fw>CLC%K^% zemEYg^1sk`%eu?yP`~+x;Zq23+AP6tWLqmsU3Ri@YIMsjT-!sPI%{e!u9}TAg0APn zrsoaW@wH|706f%2>nzpoK@q0vbQ4@{~B}Y$^*5g5+mV`g$tPZ05Fhh1;Fc;ZzPx- zRE$*fUod!V)O)!p(paSAP?nPCvnMT5N{m{4Tb;u2uK07e{8BccDs@YVeU z+l_fvt6<Ab*3xt6l!;ByXiw$3Mq!?`FQx zWu~C1AF;&8R&`e|jX!i1eZ31UUt!?KZ1cD3r0BXQQG|C-o8P}uLLeF|%10?$NbrNA740jjuu0IEBoqZ@kaV7Nxqo*}7w19dN^d``-o_R1?qj>!Rr z%?XP8A)?=*5+h|u50^Z4F2!gNqAx+qBWZtXbLp$v%98%UsXhv)y+?5l(>E|pB>lHA zCR2K2$jD0{;1@{eJ_4i(rO8s^7aHYx z%5!Jgcpb1AbKeV~hoBJq?JtBMFW7jaIrPaPhn?`!l#_5q{K=G?WGnr4eKI+OlN+~C z@OU=;?)0bV(RWex_k#MU{L014>&q)(K?ou?Fv#NG3Q>FR_uGyWd5@W;FURr|XeEh+l<3jCN7S4f!}41A zjo#Gji!%>(`fW8DOg9&}?3?_43pfNhn)u_rFgFIB1yye6drUUzVvA?RH0p$4o(7U(m@I>y zcjX?31|0X%>~>AqYYPROwjzKoc^K&e2+N}Ua;V$xMdi* z)qO|v^C<+)Y3G!Q>X7DI+J!wNoukc$di8j>va6BV5pjGIO)*M`a(V~NOq1bi_+5Kr zxzoYV4x8fbm*pm$_>ypdJ$y|%aT_=ZuL3uGjo4ZD;zFX`%1q>XiqDxYBaKhiWy3nLzU=sDG1!+1Ys4Ox%_*-=AJr^t$p#5pjUl zJ22PL&FmXs^pojw3=&DRayI-g82&2}{l8(bW02lK{y#DJBjwf2x&CiF;)lXGQ_i=b z5=V^&jC#B6&I;6KQHBT1zF`mE5V2z=!h68IJJWZakQ2zLd;?QMK%D>*spe)d;l*_r zD4)cm2KA0toLkw3-B5x2r3t^h)=s$|zquo;0@C7XY%coD{zY%?3OoJtnAX;+G=*F+V9c_ zH|@rR5P=+71I_%FvbOl(c3+bb)B%R+cA@>re(U`W9%m?zT%kFwAeeuj5nbtt{K^M2ih=4*MBTd|;#vCP$=t zNKU6Zu=}f#o9gfymEPM%-Oe# z^qK7%Fgw_$x4*+er`pu0%E`Ux%FV3s*be=p?ItJ1F+q@(IR8E-1$VCFkq@+|z;KqR zJcjTL^TByLJ=4E0$>Fubj*OtQ(D4QuliGtV8tu-G`&zKC+d}QTTI-$d*j-&V+aSsq zN^Y?{4$xe7PPy+Zch~}xDU$hW5YnKr1*)4Ny8s%ip(!6~zd&0m^rb`5-HxD3oR^`{ zPzen`pes``bjfT2dMh-if5x9}dy0pt0#09MO+ivcX$i4^s*lX;>Yb63;D7Pp{~Lqy z^9hIyV$$fd+&wbrT1P_NeCpA zBoIOi31xnX`<{KyecyBM_ucW0JH{U4Kb{eBCAu`fHRpWhGv^eZ0YL(EC3L^?hq_mg z`w6N_Bq?t%JDUyU-i5Aw$(fzK!COk*70N@FWd8LneDYb99fV2sQp@nd zimIzT*1baeR*`OSKhy&pcr@9)*y(8tH!+r`PgW>Z2sEG;+@yJe4=70VQyW} z(rPa`vdfy`*ifiSpMH70Hp(xT;8wOP5d~za26%5aCy zNUN#cmQ4GVy?7N?gm%>q;0qa zf&X@}`8K2Uwxsdn$j6J1w`oH5Jy`>&AI~7;MJnDiD{@Ebp;O;ZTrDBmRD`=iT`rI+ zfKd;XnauY|&|U!TQsbKml76Jmos$SpqbtLVY@P)c~VP_~1-N;5MlI0!43m zS7K{|Y}%up;mZ|h`q&<4N7}u)Gh#z~oFxo@22r-4@yP+AX9ILL!$9+3@f%6WH{jDC``x<`+m}(Bq3PW?Ijth|c~NdI zmCmCuMa|^FR(gL6h0{*q|HWX-PX-(RTLy1j*x%Qh3OyA)$=9L%YfXp|gQ(I+SiuWX zfNNG`*S9tv)hj!ME#5ERbxBL~aFh565%QCOUYQ$Bd_%Npycs)DeIFVhl6P)x^2OCh zqx$ZwA4#^HEcckKkD98F7yUR44$ck+?7)%`m$7!(rh7ZmL2>AhtBV#~Gbq+e7R78G7SQ+w_R>vBT#?!dMk z#9BXRYJ}hTsrZJdz~(at+pg^7-E-&P`eX3E)xc#3YN#zdxCZ2EYTWh)yhqQD=(dOu zXsv^i3i^J~alRLX=>ncIWm1V9gvZ1xM{^B+05kgHHboE0s zsr_6cR2M^G>hmB+;5Gs+7rG0fzqI4iIUuD1ITM6b7-UR*e+?BG(3UH^V5C);`Qlr! zU)J_L>4y{3Pv6Xl_JD#f&|2{|BJi4>-OJ#Ric1$^p#R6EW9-zI&{gYt^4hpBF#uadcAu#i7!V&$s2Lj>y-GI z?EQP8tqs0?u8fN+Jm@Fel4doqnQK{JEfOz&y^FBq(&a+{g|WKasA zR2jKH9^XGP#wh_-8STwQsQX;*t~C~>3;xRE?n@v7*X50BaaFIiSFYT$i0!$&$6vXY zs3p1+3m@)O?g@B@|KmO$M|vMxf6KnyAJr77I&jAvNZVoT5Df1Z3>@e5U7ec9ni?(` z>rREyN*JsFe&y$j+uhg5)ulfE_T=Kv6QlxH2isqfSq3;GA9vrsRj+#j-pj++-O1a{ z!geb%=Qk%eR}QOlYLJ)n>dBkLBlhacz8#O1^{(t;0-ZEkR0sncS+6*&1v`~^IktxoYl88R{tha?*Es04ZdC5H!c0Xt^h7!WB@0+Zz$k;d zOrTW&vuZfyUj6l0*~7o)6Z91Vr=YJTYn0PC(Ahw(&IQQ;2pA(JpD7Oy@t?*(_Mx#? z?viAWuFsokSz8+Nty*jBTI;MRrR$kr^=9&{#3|-b?8$p;)$`o3{jvk+MQr=~v&z39 zRb|;+Zr}9CjF3Gx$`?!RAf>0HjZ0yRSOd`CJItbXk?5SR!3pv3)C{+;ANqPLZ{0`< zAii{VXnytx806M3@3{q8KyT{!_FNWX)Mt!VCqr*d@$Ew$?=Da0zlNIhCr%q`j~@Ug z2WrWAKH*K#dmcGjLUlR}lRxeYNeKwf3E!J>@O`W)z{zKsmeICuc4^{k9neU;x>`ER8EDQ)M^llGkz zCcOhXr{>LT3B5^DoZb`^*cjqN|9DYQ^N#iE+IKfg8o_#yXf6!f$lYb#w8x2bTvrvl^MVI23&J8ly4g`L9)Q*?XvwYp{<1JFtF@ie z)-ha17c_VCT3K8vgCvsR=g!PO+|mEcU?ZK|MExg&H?JQYWEF60QwFo110|Ofuy!Iq zbIN7Ol-=(V$CYH$g{-Zby-tSx_L>v+O5~06YJK$}Jqa3rh+f<(-tYZ9P#;<@LCGQ3 z-Zi~3`jgM>pnVq%#EE$OMUvaokUlzH`g1NDMY@W5%V3ID@bU7gSg*pghh>Ey`=xQs zF#FNVhw3;@6i$~I81lF3@heMK2IF0c9-ADjXD?fna4wNQJS3VJX|5?@HdUVAAD#a2 zI&fLQ<-i~h#FH?nkZ?9@$ZZFGQ!J1L5EH`d3^(2;DWuT}_XKS%>_fjN< zDNU!Mzx$fj9dSw7X(h~iEE`MFTPyW%`_Bb5?b$N@`4lh|-++`~@%d3zK_P|K*FfUe(gy1oJ&lasf6Jg$^)y~f=TJSh@6R-%6u@Rme_D3l z!}}-3`zwSk*_2n8q2>!E*mT@aLpB7;W3h1Syg_Glj}xxTPOHZjC9ql|^wmsr)r6J| zXs!OScY8{dN9rDj&i66Ed?ku^7DjD=BoAmh2As39F8YJ7VI&7et6_o!A~NvmVW0^n z=x@&LNPlvQ*_0s}@0bCB2u2&(WaRf*m<{V(0t5b5`=U|??Okl${k?3xoRI}{b4p7l z0VbzJ+@20V+}nEk`OVVEz&xVwbBm4ai|42}&Np8_ z2aT162x6$PKyDGDvV4yGlHV3Bp7Z;P`M)bJnXj^RzT%t(D-l%{L`@Dc#vu33Ys193 z>Cw2Esr^E6L_hcsf}e28M>K^W9QPa&dd~Pd+0m%ZLl_6ZuZ7%#2>t+M-V(rD%zX!#*7dSCPSlGA;f3ptA4>nci1N=KjfG6Qj5N zUl{xk3~4e38~z=G>DhVbPw(Qf znMC#4O-QZd+|ro!kbOrQsE)sT-gI(Ls>|fJA(Iu; z&Za%?o8Zes{-aAJvC*l4ekpig`1S=l+SzZOLknpQ@|%e&3ZtZKsHug+V$?BMWo=C* z10AK+Itqqp1syr8!D18!(ZnFJ-S_TF%eqZAS)N1KNY`wP=DTEkU{U0u?6^zs_gyS; z+1eIGgwiZvH2xerm{WEn0!luxZ|*PJY4_b{buwW!G<|^V+m$DYQ1b>TsnGldN?w)h zc8B^@s7nJzm8?Z)-X~I&Cnd(cJopbNOOo6qa-xk%L~O@i>#pP^vS$XDz{aNB&9zyEAQ#uQ+!I+a9b)T z{VLQxtc}EV1g+=^oX7P4rGMW__~Z(ieq&!8p=k%CZi5uZl(3bxN4G-O6R63RwIz|> zZ~IsHe!kChW0$p7tFv5{+uS^7q$*%`a|9~iOSv#;%@-Un(G@R-oU>L{&Hp0mV2Stptp^>^Eo2@MYM_V(Sn#b)lTInR^sPWSf9I*_+i z^WHt|x_L6i+d4;TzxJtUaFOS1S~^TLP1~djtm2-WXG105p|$+o?y%nEH_*o@ zx_K3<8rIEOxlY{(t%%b`8Kc$pRn&Bq&^jtwI5nKM8WyFlp{R|KUvH#hZY+21FrlI3 z(T$6KFQ4x2=fCM4Nfb`)n;7#4v72OklVsQo1a_jDt&L~&s`prCM0l-35HpO1iRoHJ zO|+c48V;?ar>=v=pfxbc7>v9&dX=7vyn(W^u9}9;W-BEnCA5lM&g;9fqJ#Q$s7V=1 zl*XYi;O3D!?@gWC-C6s5q3i>EzEXJ56KdbVXafw@LSOmCKnqEIGW3+gKqYkL!H?&H zm*=20MYiGJSp+rN@7z5ygJaX;E_^$Blk8yGVsAkrICRGbbQ}&z#cz1+u2Zzv@_Vpm zawsY#OszQ1Nboka{Ipfc8JpKTbg3UAyFY9%-EUDFX~8+<1CLIM5_iCjSa^1n9%$N0 z(4l!KOZJ;|5?3(&mX01UXeMBp2RzCT?HJ9;f}z2mo=i6kkcZoga?kIp+ZT}MV9eX& z%}t1q+G40Ll+=A6uX+zcGO%k#l5f6_Ft2+UHr@V6)b%AV?Rs%(W_w3>1G!&z{EXJu zM(Zb$2Ph-~NtU7bCxcS`TL!Z-^B&(k#v`SSkUz09PC?a`>OHth!u(<;&(r3wz;X65KjO*=O6}Z`|*;y4wat^^t1{Sx`Ptq|9ey zCEl`@Xj$#Orp#CCM}T6o?}AU>^YguyvRvhQ-IO^y46C9|+7qK>Rogvn>Bszs?)lL| zRR_Hk2Avg${MR-In?r9YQ1T^>Il!Zh<$s5cM&Ng}e|in=bdx2@hFYe|=+)|4W~$hA zN?2oMO+z(peGP403|0%PfdEH9xW6&f!Wv4!kzaA@&~6@w^y1}>yN?o?Jvl=0E10orV`-#m|E?9}%Biu)UG6sV4hyRZd)c_Mz8ddO1<1oU1_{i2u>M2VAx|` zzyCts9?cSORKo#p-lrEZC=j!lAQk{{0a!zQr32M3YmYd#hv-wBR!;8T0C#so`gK{a z_=+cxb8qzR>Fga=&+ypVTOQ)3D-&IB^U^OCm8G>YS#=aCgM%%yb27aD8G~6lSIUhpEQ+YRi)FmiNy=ETT&-1Ni|kR*0J-B=%kA_uK$ z+@{mxw1&D(qtRW3yWP0gNrhp*gcGMe^>)MbSJUa_4Up_2`bg}29o_PDSI>td?YATO zZw~jrj4wTbA4$8}{N#Ab*2gc2Zur zVxyknbRP$X`aYcATXE+|$`N1Yv%|di#~ZGPHQkCLKiu1JBdYE~5bJrgAS;ra7sxLT z?)&6Hi`CD!`8~sBN!8BvHT%2{>d4zKM)VM*Dbc+uKpi3t0IwzTHX4j}gq#=9Ahi*x z&{7L&pP{;7BKzY|VG592R{rwq3T@nqb!JNq*DcdGU7^2PPS03T&p=&QilH7>Qx}8M z*2LhH6;;k8o*f0zyX;R%U+%LdEq%iu#N*dN5DTI}5N(68%`oZ&&31L?SJQ5W*IhrY zKYN}o8oNktm6Sm(J#AezU8&Tu+KRdwD~(VqjnN8*8p`@wavB=TRkVIP1Xi1yjz2tZ*ACtA8{AI9=gUi)9%}##aOFMH&>!N zD7W~^x9nGi>LBQif{{pom~n9^yT?n`L2>dZh!25y7YuH1xUN|hqg3yz)a8PsTcgDx zW;}l^AFnWtUpZ`rfbS|GDoCQxjeZLGQHId+NtSu!vSC!vU6xak`Us|(vQtb$HBfP1 zbj}6h%_w%WN#2TeL`>VxjTOPBwV@m7`y5jo)iV7x+iy5bRiBz>JugT*S6r6T+Syr0 z>8+;?N~63s+J9nDs-GE(|B}JX?5t-G4v+PG>uJ4G^N|4LbHi`(?T1XL2hCa&%te_o z-)^macu#-t(fQ|+Fwfs?ZY&JprV&eaVh0Yo^m?01|CQM0@_jzaogPaeQfD|^Me^7T zXra&(0i9vMJ`TMPftL+q&A=%JZn@Ma0ZvKf!+3iX^7ZQOTk%1oUG%0e`PKyxu<10U>@a-di_pR$3-!v(bE@s}lygGoD?&8y^_DS^Z^#FLY)@ZvhO~ zz+@{-wSu?_B!w`LG{rgy{1eb|lzPIfkf8P>9M^Q*Vf@K4{2as>LHyNb_dkp8K594U zr8Z)}YARqIKhhpP-)7!Ao*U(#73f{FJ+N+X=<5J`+Upxrjb#e6kri5~Wu~ha>gq1h z(Os^MTd9Rp#Nt%Zx>DB^tER6er@2OVy^+D1Gl{3k-7V+tA3yUXzH_3KJ^XHX^yVb@ z01Sn~up2XW2!|mzV{p<0cXc4B^K9mh`ODR9McP8=cAwXP zreGiuWdkcGcXxMrj88;Kd6}M;+Tz{N6%O?Q^aKT(|AN*(5W2~{VY}5G8`m}3IMw*a z{MdgX`N&P)M$C|%-Y|YmyNgnx+dR>8>%niEfJFdNz|4r#^t3Cba}B_b;c3E;h{y=yJJ3xTeCz<5-Wdb+IiTN{&6OYN)>?QuBgy+!q;Xe51RL)- zXk`p820~9cvL!N2l;;O88-8UDJuxtRNHTN+CSJo#rOe7tO~B-+Y>teGFExBg@nMh8 z?RkASp{DFhZ+}Y%yZOochrcbEyI65mP(;|@DmUTh>lNUS_wn(vu-rUn-rTsu@v=Sq z{;tN#{LFXv&g}J*-Uy5{Wt~Z;xgg<9irG`Znt=)s-jSUpmRbSwkz9Y3q5wV7=eQ4% zYe*NvdLA63-%l(*5mOqAFY+|*a#x{Q&Z9bO6uRj_-RItn`~BY@Kui9QSVCr$%g2aq zq=(0$t$d68Qe$lmRgAi(E*7V&sjH){udQc@H8Mu8HBmQPr@mo5>JL-YYTPQtQ*lv4 z{ED3Xb7{G8{o}6%@L?35Oo&gz^r7kLkeMkWNP+|;_qPXD2r~~Qp9)Z)g{)k*P)$c~ zsj3zlYof1eY^Z94MaxW~vL;p;i$S3^(Q29)HBBk-f9Pl!ELA^HMKG~LXw!Pc=RWY3R-m%bdj*7FCJvjx*)v#Q>AMLH3YjlB?Thp~_eo-07K zK%k@0!bOEI*Uv*%D=fpQ zD(Yw`=wg)hF=_^AjFB47P(^>Wvhf;~)uw938?_A9Ybstl5jZiJT3dFYzA|!Z<_1r6 zo-aPb8;Ttp-#sRZ5Q`%~vU`9U^5lrhNcDx%S4UPMh>n)J5?WgtV`}0y;#7=vRSmUJ z`dEyfCRP`R(J|1_HAL$gV)aq-N>=OEtd^g5jj*9)j}yJL9v%565w3haOH zyksJ43Ox`D;=N)xN*W9ug|l3U>*5AWF`VJantzJNJwf6FQctqfmK5<@oh8z~ektG8 zvd+%2I(%Q@(Hq~6-R<7EhU;X~X0K4@{u}EG8rr--ya$940&euU=w$8>Z!-%-4TI6Z={K0MR>?a`+j$1+~ujg9bR(eq%SQEIZQLIe7ptzg?~aMT8Sb)L04 zb&D!L!i>Aud?3NH|FTQ6xWbv0(BF$cta z7~)AL#4N4=nX^D?{iZF%KyQM-3_u_J&(-H&VEhX@_kXN^%Ip8S^8Wz#|Iq(z7It7j zn6op%#@cPk0>$E-iYdVajEg|fKi*Wp&wKN3w_DfC69exO2VR_D-;V1{+DCgB+m;ka zzv)6bZ&7(bpLE9hgD+0}^%_tr?)iI7<>f;|BUD$)4$3y=J@e7aid0PvTlgkqVfMN8 z(De{T(m`A|utTGOxs;hz0MQcc- zIoS(Mbq&?u4Rn6Jba{1&*oURTsZw`W1MbzXGZFOXWDRS@8*51M6oxK4d34<;dX!d9f z`jsDm<~!lW+}4Z{Oh)_-1OzRix5lKGt}wt9>Yqc=BleLUjcztAmWG2~#uE`5-Nc3E z_H(-TSVG2U$o?^taGdV8c{D_CIz&$F`x_AFjpLUH{N*^IN{tcnkP!xLXSijj8uG8# zmZi6o=&clfGkH*I=^EO)r52FdE}*s#P)U3$iAyE-P{|w$rJGLg>Fnf_$!r?6k4ovM zkhv|becw{DZ{NF+mvcV##bya58U&Xw`z+<8K8E2D7#JR^u6ll8d*;Q%DQ6F*UOw^d z=J~zBF5=O4F{c`uE3(|32JsHyw-ualT(jjZ8{{d@`W(M?jke0=mJ6B*8kJFNOQOwl zJlB*4m{&$yW(J$Q#cLkXO z;{S=^f1=6#pTfKTZ!;)$jNQHQ9=-uqTb)-dSGsrgE=Z*x zuPhZa>@dv%f7JM{$#v7H4K>Vjm8%Uz*Mw-6Md+pY8A3}MbhX#ryg8Ct0By92D;I{d z-@{<-<8Zy+4<6z|-_bI{U|lFo+?g7=57S>IlJEV!kEg`%`90Tai}qx^i`17xR?E*{ zr-7Ezht^icYAI`Ks%m4^|CIE#s`5fLRm9W?xp&o0(sLDt&OrZ8;6(sG6gUK6v26)CTnCB|%7$%?$HGhuz^NSv zSEAP-ipI!nWkgvAQC3FGu*h~dM7D)85(s>M=)?mx@O|{0iU4%2t4Xz!b7fF$#=&dv zkKJclt1?}ct37{hjb8x6F~BE+FnDtO;PC_nV|_$R3Bf7O(pWkRy=c}3Ed|BJ$lCQt zTA@F8V(-*+7!0@q*}f_msoIS2U6n*0SdpK`XprhqfRccqBF5|Xhpz|LTi~USB;Txy z51U9j0_BgOD4}w%M(g>_;_ru{rxseu>cU-0T~K}D%SJ*F3E>wY&L8t#Jm|NoGg!Vh zbS0z*L(9ps_u)BTP8JuY)-=-_+J{=1lk^^-vBV_O2&Mf`34c1JGQX5U;*;9A6zZUq zJ2GW}Oc|uohNNC=dRpBgHg}ut=3y>V+}-x$e&U^gt)D|}zIvNh z1zXZ0ZQ8ues;qUXo~Ett7?O`_^|pB(1jU?9NDW@GG)S-ZfD^Rl1FH?XXh3Ot73pyG(<19!2No4$J&lBVZ5)N18>d8U$2Evo8bK) z@Y)pKZGi8#@YQAHlkY&vu7RrSFjhS}(1iSoC~2#ym>8@yF;q0tmwu+ywn{%zO$&$8 z(n4!#Xk%5SHdjXzYht)oLq$thUb*S*6QJZm%5jRn63uxw$>Z0Gh{e#l6Z)ej1rfbn z!7rbg8S5c)=OD`Jix;l=W$8*pT@lffL)N2_7Z3Eu`O*mS2y_O(*wM7Og=GP9<#y_| zE|!%+VHxpfJ{-T!*e1{NRV?>KNEepN+{~a z|6Iw#^{s;~6k%P9Gz=89Qis|*hFWQZX<4OLu3X}Em2jHRmA$eD_MIo;2BN&L!07{C ze|J&(yNfX|PX!h~IQso~MD~fDr`^_rs0li9fZp61NMsSWk=*rvI4o<7#7#a7YdEkm zJ5-%}&sOrusqc=d@U9Kxv~~CO9cdA^*}GlpFNS8vyQIcDJ>R~i^7h`6n+LNlAC%RD zi}-$)rkG{F>ZmQ;9_kV3MOPBkUP*L9J1q<-|=5JJwJR84sK{hj;jqYZmazr!Ic|hXB3mOHojn%uap% zEMehv>6$XQh$d8`e*kY?w@vldvRyx zz0#S0vBO-KJHRCQ1#HHeZ`2ynnKHru7 z-Uj3lE1)HVm?W$!_>ypf^y(e3nb6<(?p)aY;{h$H4}skQEOKF>4L!_Iykqf*HzM(z zHRHQ%*mo5-NQDutR=rzUHc7Di{2=FkS?&G&`rL*deq+x}5qYAdeYBb(s-O!i=z=Pm zu!1&HMIEi6jaN~}rE6{HWJC9q^mnV7!<7tvC4*N&VZTXFzxVh8hxx6$EureGEs#%s zkKb5-<0y1cLD)wvOSyYv_oc+3FON^YIJGPPV#0^`?PDE9FiHnz=SzFX6n{tf@c??i zgD?a7a-rb`Bp&;~uNk7SSfn!MktXhoq$+ zE-t!LSCg`8*h+1x_uBfMs!l`PZQ0p`e^p~pJtKsUeUWCeT4I##~5LBD*qQ>y~ zxpBY3%>Lm)S2AN;^4E>>^AKeOK_LrH?TmSQ_x#%@`|jT)KD-j}G|Bhji!EhU_#yUg zSyPMdNT~BK_CY#>)EZoIHKEQ~hhsmSOz5%0wAss*`ppOSK^Tvjm zFM+^cz~guDQjmBl4f&%w!_}&{E5MIH=s3=!U(U!m@g?VZEuG%ZnW&|XHFb>9`=@F; z`YV~em5hEFXdOe99mCbMF{x_k;|(lPC5>Oh;8!y^)y%Gn4%)}8Pd9Gt<}#mwD2b8h z0#&=yV~rY5OXG-c8153%iyl1MfAis<>(}eCanKCrRDvI@CvW%=rs2%a4x<$YRt($4eWfN zm&kTRc{FG(fYvmiXQYRqdp=tMKMaIkFzz}w>L3^=_6YZO4_xXUcysi){gI=dRaIX~ zN;Bl-6jsUMG_^KL8I(eY)iC%OwHZkz4cu@jJ>6AmRthR!%N8V=Vmkac3BC2fMF~7q zBrYlsi zzRxCdmK7#F~J-wclm0}R;!k*124IKR#ve+VPwCJA%EWjVO2 zgEMNz3p41CB89Gk41Z`l1dL0~g(u7Mo{(GW7-VU{&!E)ND9uzdoz}{vv@$wc8J(>i zvP?u9bwH|y*4|cXUws?1g~n*@ptg6CS{RMl+0T-n?V0RIg3g0vY3xwBi+Xe;=Wr0b zx(B&$rYV_~m3Q;%9%L3jtSSG{n)Zy5`>wq<86+HOvkt5=V2-0E!W=wtQ66iC%U>s;{r z{53|po^Fo+Z(Ml(f6%`w1lq8@nRzzqW~8sLhW z@zxdjn)EuG2=J~o+iZ&n!G9pg>Sb~!x_U~=sw&Fzrs^wA)t75(sw(MVmmA=g8sMZJ zsTxjwwSlh2@>PGRU|rSFyV3HLy*{1(`VHoDIPMr)AhzkOK5%5mS0-RDxhq0n7g>oQ zxcRfL?~l5X;MdQ1EE;+?KKP`vVrSw5-K=UifJ-x75x@wBT4DoXR-5CZW+&~sV5hA3 zJyJW!|HDw|X_m8P5$m=UbjMAM!~tCB89sRDo_<@+zH!D~5an{~Zoj_b_TrYi%1UId z5%T!C&j4HmIKv`40xzyE5<{|9AKjz}n{nWz1YXM|zRQORC?RnZJHi9&W`p@I;E4wl!?md?&zSkH!`U8 z9n=aswTRT7m7Q`S?_Df(-v!#f!8ALl*j?-;-{NC7a4@uNj|(sN()2_Ie>zhPP1Dc_ z1BLxfZ%~Rz^5-jE^(Df#=Hib}xlQ>ZN%||72iKzKXT~J?b}>hCydPuaYv%JVz#Bk{rykNTe9>Uo~j_vSJC(Utyd zdqqh*8)D4K`!}_2H(~GHQecOx@Y&iFvokd$3QB9Cw5sIv$-;fnSzcT7BaL}Q_8{?< zj9CFV3{KhdrvkbM4|0c}_4j36yA*T!*!IS{95S^G`3d_5U_s4 zYrPonLbG>h42*Q0HD7n`0z*wLB{g+JL;W@C3TxCAH8EIKEj@Xhk({oc3J#0XR@c|Z z>Yx*f1Fsu*s%sLeJ?!-xv zxdC&%3Ma(4CI$m7yJ7Uyl;jMZx$E?CWez2AlKmWdJ_%_rU*9Ao9<@-FLyWYMZ=bEF z;KNFD=%(%fGrq6B*h>w(m&ioWnz2JoduR(hHJHANO`*#m#|t|5 zNiCOvdZNAZd|^gn^6OKdpB_zl7MJ!aF7w;*l&{B=znuL3=}hX!%c&o(rG2=Q`aUV+ z!`;%Xmj%gp)8C)V`+7e6^NHMV$C}D-bdw&5d!L9q5@6^mlpkn|(r@!z-Risk?Y0#Y zKjL8Q@xbK6VfZ`_pT)xudGw1G>tv&ijaMNS3bUc{$Kycz>;t}}^Sj!QMvAV+)wt?p zoBh&^UsM&gI5S4!3PB#Ym9i#a0xGcU-z99922H~93|8)UVRIc!j7zvYn4B!h&Qe*v z)WX!**Tp`-+r!Vt<1e5B@LvBqlv6e%-rIvHyGHg}dV%y}KOeV$$m1^&yxgT11o-+& z<>&27lr;+dH%0n?4gHi|jQ0-wc|zdNKLzjU=Hc$_6W~LL3|eb#E{9P%dEppL4ZuV% zup1%&t?+7G?;f9K7t;!J&1Rd`ZB84QKGwAsx)i6?EP_d`tx~h23dvQwlVA?du0v%p z@VL;^4gD-ubq=fGZRO4Vk0bP{Ii4^a2~)uX!_MOnB!W1>_!WsHt%s3$|LWmWaZznG zMYOi6d2S+H4Y?rmFxj_q4Vy`+X! zb;?q?%UrI)OBtFIK(J>LV%TGTy`!<--UwO=iH)*+cykA@^Zf+(gOL7!-gM~xdn|i6 z0H$N1(+|i2q!Y@G&c9Q)s<+v0Z14}sI(YKkiA$rVn8D2&BzyT%!ZK(%0HcY(KM0c- zUfk8cc@}#u0r&ZV)5}{ncQ08aUAKteuh3lTD>amYJ`V}c188pf`{z&tQEV#>a99ua ztHDKe#&zMir!2uY<%gXKUd?va7z;KVC;TCBSv~2qZicv4OwgVR)*kXz72wqcc#O~s zEpk(taajc}i@|*vc%g+(YU6mlp&(s$m`2O?RgmHUt--)g0N(k@o;$;xPluVWMcr?q z{}l|rp5{D*zSq$EZj$wWl>Bz2_5B1ndAcKWtmP|oWJ*Y1CfeUa=jR#PtKr7mqvU%+ z_VekXmlKR*(0>8)V;X}nmDWln7Au;@x7rf4OZ=+=S@P zM(#&C!T@>T@%gI#_=Y$lWIlt!*R?LV$vqbR-trCGX63prDLJ?W25JTx(kq@N0=p8( z`Gse9a6a8(etZZV%1}ck@cYMldm{XZ^Q0b;j@GX55Gizl1n)l;MD+P7-(Wwyl#ah( z{EHpw4}*waQUww`rTPi%f9Ox9f(V2_JU+me;O`?_1Mx%|mH&9}ze-BnpJ@LDxKzGA z9$o}bzsSI~R_l@3h&RDudYA#-HQDk0bvqpET@8C(3X>*3a_aUKQ6sItEFjGV{Yjk^j$U@RUWc2a}~ z2og_j7w`{>hVH|7c4PjnvefHCtYT7K%A8*i0|T_7o|ZleYp90PLuuhOWLu*sEvzaI ztER1CXsl_9Q?SD>jNc%aAF`&zX(h#F5#4EayZaof%ddU5zwm64ZbziUbuQI&S*Hhz zZiQ*JTvO@oVv8V#$_v$X6<1(aE>T^orHPh)G8VNOgEGaat<_R9&_S!~V&xPR5DoON z2HJDitwOGBQEv?}5qqeCy&RY>0#{s{JGwUB2!@Uh4-)!>4ibo_bE2bmF5J6c_sV65 z8<#AvoifRJ;r{ZP!R7071;c*84FKV8s38;v%;FF+Jooh^TibfS9T^ADze>0+G*Rwb zzpBSYrQLr;|BW@!76JUd(7(N<)P~XGOK-%tRC<*D*w$RciM_nY zei3*rpYmNXNtBx)DvAgyVjtB>FIDhX1%mo?2u?uM;1aMsf!NM46m7R6q&Yx)D6nE= zdykAnU|a`Q60mPU?uo4cg!&7D*7M`63nPs?fD#8;5v<*MbT1UyS&kmE5|X{4bvMus0_zMgPC(~jpvSj7 zw3;eOpuLNS$`3#;sz`{qWuue5%Z-tA6snTp&G|m!x;{sZ=?HULutmi_Z=e=*ReWxG ze+9ZLMpN&l?)3N;?J=7E3c6a$Up$cQK}}8D+d9mdyFeRf;Oy+`>*iNqj6KoBv|!ouPg1hL#;G(@e1(GJS>ea#WuC~o=^{A%zu01upO_0j?5 zfsRlZ@`HhGAhCyOR~RG0#6Fn3JjFf@g1aF8#A?4UzZ5ahS*VXw(N$B^SHAhF!9RV9vK~TYhV(-28ihv-!DbhQk6GB1~(tGxQGxM!)eLw42StlnqhqK^3XFvOt zy_MJjO6+jum0-CA_pS5ZQd7QSg#Bg<2n|34pKBye|p7$~gX)aNZXWk%_E} zftqA^AH%)jj>*~C5~c7xNalN>{EsND;gp@2Ov~}Kor4Mby;0gC*?Gw5L%LGcF^#(H z&EqA?xNOZ{&$R>gYla>E>UT!C`ATr!2yWU5ANta6xiaqAQ|?&Lm7BefmZ?7ENc&I$ zzdrSx&1yfH_%SPhQF#wWn&~GqXCwEr;@!F(4f^9lo`ieDLLV#-0I?rt+Mn;+J8~-h zRj565Rtj3aJS)mx9v%>~xz29h$Zu;*ZC!msq5}g^j(Gm>vgiNWHIxw|c8H9cNM51^ z6lmrDY!v>B|Fc;7KUVVp*un6?(8%CW(cAw&@BII4Lx`I4{a5IsIyS)D1GS7Oc^!A{ z_45d^vvrn~l=gIS#P&1+VRYtl?rfGHI@>^~5qN6}_R4{qGS@>1{ItPc9lTW7-jZy; zO%N^v{xSjwX@RdXHpBrQo`+vmqNuzJjWGC*b~~pl)dFhJSuP6}&`H%9NPB_d3S>_p z1_Lnx=97SY3>Hqz_np#JM08cxsmV*C?9*0I(^CA0gR07^>MBYaDoUD)%9_%e8k@}Y z*A~T_lABHln{%Kk9a>}gzasdZ0Z`)#l@3tn2;ZHcaxXk`ASG$d1!>m1s>E(VEaebQ zWkg>S(NIFvR5z-rD{83gs;g|%lGD(Yl{HpbXQutTo;qTvhv=ywRcS)21Irg?y8>ihj&AN#%xJ#kNec4M1?=C;*AT?(%iFZ+2@=@w^`l~Ns z)qpoL>5sa`>!)2ryGS^n4dV_7)(;tXM#fzK7;)R&x=V5G|Gp;KbR>Yo#@`&7EBXV**eP2Dtz4?n79h_y1~3kx=yY{RjU4 z`gi|GN7N3wh`ti&fj*2X(tj1KNK%T-rN{yXdiw|Y1cdm8gaw44mH!g$U#8W0i}o0Xb%e7m^=^7nf0K>wwwLBNgnlxB5?+6?a1W_#&_s}|2r zf$N||vX!Ny^Qwa)ILV;ehV8l+cYR5=sA`Hp-H8LmF2CyD6EE9od2Xe#Tf zt7>VgXlW>`YpAG-F1)KMDXYoLDN4vIt})PCeLCMANN<367Z%O}u|&Yi1@-}0PKBj- zScwC23`_+mMr);RX z+1+YO#y<7jRQ0?RrC>WG&Kx;mj0}cpO9-2XbF%9^i$AxaI{c!AZ2U48#3lA!3@|wy-Ro0&Anq^%F81s zuO2P$+paQUp*3fxgZI=Ob=o=_Bw6G4pN`zE&>s$@6d@^^wHykZ1lpu14HMv_fmQ%N z5;_aEcV`-Zv|8V`dn5TD9YPORSPYY&j?u)X?xZA}G9q-rOBUSZz*UWHzJ+Bb!MBxV zT1&0iY$4iincKad<||7Ll%|Gkp@wXx21!r?r09O~41Za?`|rGPF{;}d2vdY$dGHbA zdHul;UPbl$lM=L%9HOuss)!GfS_)l<4@Za*2rYUYHBuY}C1Nu6OR8K_Ymv%-Ov}bdMF&3 zj6_B~kV(%!#=SQ6dT#g`wx-%2sR=-wihB{} z2HmxQ8-T7x?&v(QLBOCgmd0VOAI4e-k0;lJTEpjS(Dm_4l6Rr=P9V$xojg4`b11(= z$JoYrx8u&8M&>*9%#HO?SnS-6!qUVL#V%80OA{jtW8;5dg2HmADOzc2sAp!Zjef<# zWSgal!7kGsyUmPISnk}p%S7}H`lOkmiMf%frLm=z*)Fv5-=;*Z?KCtu-hsl*$iQ}& z`M;HDVULximAQ$HrI~}RoxH4uk?9_NQyc%teczjFK|qFu-mc?G9f9TpHi~pdHQ1xX zx0Vq)DAMd?nGOmZD=EPqNrLs?MEgHiY<{Dd{|Bt48CDvzo_6r$2H;1#KHPp&k;7_v z1>?>AK{gm~1B{14uj{II7vyI!GLp7>wqPw*nu;b$Lv*gWqDmaHFXUMBg4(-%YuPh&0V}k8!OKsY{fAqDvEzf+b(!Psi>AWIlP*NSZWEoD|NNFv#VksbVtb;?44~lgA^E6(yCF zWfh)CICUcI>zfSP%w<@)0mLh#pA&0}ZQceeO(hx6Ic zPTaO!x)Ykifp~;H?g0?Q1+V!fBM=6|R5)<1z|UitGj1Q8{%&<$)8)Qq+;tOauj0I| z&VZ9`Lqz1`LwT2ul`gpLop!V#x!KLx8FuJx8FkkD>7)8JSgxVaWpUWw6|2v_+Lru!q@WWd*C%4s{> zUIW}TQ5q8WtRXpVAh>QCvs*plv|++erq5e^GFomXL252#6E=C>V!|q1>}o>v214xm zso38rhc{1!{7p}gW5>v{BDO61{Xq>|wG_CD6e&qf(558nEyt=XMvE=RA=pG@DrwDl zqS!>zCQP#UbczIunWQb#@go0jI8bb6pW;Ha#;A|{h?f$^Uu)b^iQ%fpbJkqmBQasW z9-p{_dERs3y35!dOUy$}{Bte(eI0mWA$VvpN@e8b5t%`1X~!GzsuezUiUQ z<0tlwh8vGtZ>H@Q#25<%e!Sr4oVn1v3VDW&|2SSXR_#^O|sdF-?MSnVb!GD>VrRTUi#Wi4$*6q=|m-KMRfsw|=-C;>$>Jl7>NSN7nwi&;pPh-Z{l{p3NU@^ zqB9g~JnF47?kzLvB!;t*;P{*LI-Ar*`aj6dx_shzpSv^0--j3x28Xktv}iQI`LT)O z;L-5$I~mNbtH<_f=7cGYe>vK9C+UK>`tYU1&a!Z*z4aj`@N+<5e|XG@k2}1s7;%xG zjM_Gz5+}rNT#VjGIiSotZ3fr( z2<})5?wP`4^cf@0D^vPw3;IiQ##2+qBU9F6GtN^B-m~4T$5!kocJS7ZdfTl%Mdw?H zYFC`u^gipw-C8S_YKt~9Gk%J2JrKrD1M!6DEFUdGw8}&X1Z+4=gu`qkaN~jG4J2P^ zv4P9G`>lS*xJXWhYA+mj=s9Nh^SEbQY4Fs$A|N&V>by-@?xK^I@Uzo2!ZdNTe&9uM z-}&(A;|`2dj>8ekHG9^6_fcIgkAwb?(DO-@zi+AwNRy)DqqGTNOo&e7P%%KA1j;l} zW<^)?i1R>LfaOKN<3vCUD2P~~Pg=%F-O*W<^mz z$@4(N0s{-Q1)wefX#oiHqE8p+MOgXgh9e2J-6+ururedcYDAwGbzrUs76yPa0pm@g z)!pgZ`8>ac5TkjUEj;@zV6#zZvl^T>Qf>bt+OA%--L&K)Gw!s0(N7BX;-_pSR$L8w zE%f?AgJ&*ObUu1G+FC!|UdQWh#$UbA;$}5#r$({f!rd#$aNa_2+=Ta5oDbX96Ray* zJ*z6LK4LlYBnzhMR5$&tETf~WY9XzvC#kL>r>>@?ri%V(s;X(JscWgJYN#m7N^Me6 z+;Aw%ccAC~t0xI>pN1}C&n!|)nVe#vX9ET0V5mSC$e?;~hHYC@kf9``Efs;$2rfGv z%THxMHfA#Z%WLn-cTsP@BtHF|aR1}JH#Pf)29r6<*+4oBi@Acpj@cP+8=HY?RSYc5a>*R_1drg0wjrsK^cD!@{@b}n?6t#!pR`B5& z^VS8pd!fzKvd&h0KEs}nX%E*AlJ+?a`8u@6M!d>BeDiqWJ4YM-#k0^<4^55mqYIur zow{-su>C;p5nUM|)}79N4G`BHmB{(?Ble>dnvpZx%68H*f(=lDvmI&onTxqae#XN1oe68{Jq?n z2ZzUQrqABnkH3>jznTo?>2Nj+&K-i%{rscRoGkwZcLTnkA^7WohXT)Q3j}T!`fs3l z{!aG&gB7`f60)8Yycy>&gOA)X;Af1>PXz2JtSkTyGt&CCI5lMW|%#-8A|QLNrHhHqIrQ!_Rv#^!#O>=h5Kpy;T?I$LrRJBTA;*Ht*1u)K!w!k&)Gr zl+}`u(-K$I+M=i_rL3W-q@t{%q^hc@kaswPh#mOwyzKeygIxA^Johb$a~+sRfsw%C z`mn)=P50sU@9j-N@M&vD(|?1paA3sH1#w(XDwUW#HyJlQoiH&QGddqLx{x@%l(0gI z&6^DVI?(^P0!q0D^rSe9Qy(p9= zty`4t5c8$yd@9sGfu;}8-3&eL@cjOVP!AZWg4q_pw10BjQ)}zk5)k!ef6n7W1uw(h zq3#_F|7t7Bzv}1zJZ*p5l?r}u=i|bx?{~`p-`oA793~ps&99*OE&Qw+ynSZk)g74V z$9=C7MF|`2fWhkN6ER=n9iaUMOtlibzRte8+LIqP7iCKHQW6Gk;{<7u!j*gcS54$A zKu;LZQh^o<>;Nv`lOu3v3!L~oCty1QbFV1;4lfE;f&t=r5GtUC!f?Q^0{~h;rN82% z@nVA!f3?IQ&}9uYcNWieh3z7s2cedW1>Q{X5b(T!=?Am`pauXV5IFt-5masfz!5wl zr7&Yt-OV6o!*yc$A;^h?NZZ9AjUSPl@DI&^7zcEJD#L*T&Ky8r9eLow7kYCA{%k=I zmmdV+5A;A75AQ#)dMr$0K6Q>J#WY?HTky}$k&7v&EgY8~;W{pq^~5-nQYb(`IE`cfC2<>>C4ctK(iyg?Z7Cq(=ui29rC{U5U5hNS@6#h9I#Om}E}3d4Bd0AXt1T|8EheY487(VlDM~5GDXVL3+qV7Wi6Sy_^23{p z5AS9ZR;p)c&lhMHgp5PLieT_vS>VoQ`tk-`2Gjn+C$AkzLSV=TD540!Ty8jn9!{Y} zQ5exHtWXqWdK8Tj&E-S_KNxtvK#JfF=fmWCn4WGredT^i%-!_BPbXqvrtaJAQ(tda z0F5$JT?51Y)T(#OmCsQj@#FsGwwveSM}x5X_0svGH-3&CCv!!K>^ocLUOWUAmN?S% z>rO>yUQV@hV0&mvO;+KnL&tBYxWY<5wf)`C2NiAiuY5jNO6_O^5(&C~!Q33o&bOUD z3%`0;-|C_L7Yq%5E6o2~fKKndOI4rARc{HeZoqU)@2Q05lgXkhV=J>jMJ3Z1@9F93 zXcPWE1DdM>)m;W3Bt0D~!Mkk%W3i$myR0xF&z}t*EYTv8Ghg5&+%7pY)2YVd%>LXtH7u*yirYWQUbqP)XyeDDB40Pq7D;7$cs4)}o37kK_6@cq!Y z6!4@#&;lcX#@HWVkL3BU^N~VIHUFM-)yLY({jgp0)$6zE+dD)XHxR=EAC9OICoVV$ zgnNYo7e3#e%lG2*eApBhz`8+?OUFT^zhu?;Jw;%k1T0=5lmP!TgZv{oKE%|_P+LRU zTvtI~ev9mSnbg>5fd0XeqX1_C3Tf<|{@$30o*bY(=k%T-e%L>7+~$kV#&6DR=JNER zJ`nmsR~nu1U#*}!9NyV?#;)SdI~ce97w&mezD7XbA?QrzzW3?NQR$CU!bWHcMMt2w3Egz* zo_cuy?S!Bmbl>d|XaK(2LN^(%n>hGx0)KJvS<83*4+N|cc&~$K6@Hw-Y?R@z1Z!w} z1mxbgm$F+v-xQJtVR^9od4(Z@U@sh)^3__g*$j4aEVHd#M=eg|?wL%-`+llB{)?DN zBPpKpKi`!Cwnua0pN1;xy2?75%DQUGTB@q*%Bl*AYVwMja`Kvr3YsdSWC2>LYWk`N zjwKDv);;==fA>x54DJ4+;2KGA4ETv4K!<@H8ys154_2Q;Px>F2g#UDlIOqgS=YIyC zXxOlXk!;Zbh!hB;gq(O3z>gL}s1O2a%zYz0$<&$WurOS8`EvWcOXDBz{Jeh-7KcTL zX6GkicJAlR`!F~IEj<(WpTg8^Sy*sI{63hSpw(5EyScwgPkVIi0Dr2N*WC*9qcq$A z13v&$y)(D2e(?@%h|c(sUGyNQs3OS$#w*#wUwc2I7JQyP)LD1o3=l~$Faf_tI8Q&n z3`u~W!`!;|>GxHzfV&bA`Z@0){OW|s;Vb)mXw^?(;(O24>09Wof+7*EaYE59yjzza)a_xcRiJCtexKYr#4t#kKAcP=P z|Fgl52Hq>+O@$yTMDkea)@n$kF5Q99!w8e-`-Ze%!4vc+diaQs4 zx!@&0sg3qT;4b8Q2>D(@bTZ^e05b;00)Av8-wz_qXMShT_y8}PMm~dEe9EGYSzGPe zxOuCEg@uyTdi$LQHai>(GV=f?x(A9V!m?$^9VhL7S+&>M9np|QOk|Ny$4#1#=zfpb z)D^mscGeW;4go%0v>}U&24V_~MU9`3`WA|GXNbYq0GP>vnM{~X1@d8-N`jYrx}&A5 zJlA3_>=MOqA>_g00a(ft#k8r4?~hlgb@-zzL;~K1!FVo^3V@O)y6Zig2i*tTegDGx zZ(Z`-GHk!P$488N+Y^S5i4Nl8@&TIzlNm6cIeJWWJWh!mrVT#Y;D$m|;H$&lw?mL@ zPI6P=d#Qkr8hFZqhZJ~i1-H%Mv>yDnLZ~9RN$|bosQ&6x{@PuUCeUyb#=g*c-T`A6 zD1$xku2+}mX(0&ZX3=EOb_h3MS}72=NwV#>kC-YB`WwRg<5RbzN1vuZ->u$9xzJZ@ zwsF0&xRSP*hQ6G!w)_rl1$_+#ZB=Cr)qgG$DywT~>gp({$tY_}WaI`8&AqN}EBxBN zf1Y&?FFZ~a><2+O2+{wk4LYx~=w8eor(YSXMiTz$$w2)Dnu?EdFD$FAfZEk^|gZ2-n=Dk}~yx4+@`*0R2T0L<`6!LhflUhR>IuRQ&r zzJXC!)$#N;YHgb@ofx=#0hTcH?;gC(jU(4Qgu&09_Y2=%IQ;SYsgJiVJx6_w;b!>p zs@6qHm}x?ETnABVkf=Nw_80x?c9=^Bay*+Dz~+b1Acz9~H1KB${rN&a;01^vM5mx| zCaM4-3@D*6moOB+o*XAn*e5v=zZ$ySfEI+ZmC147v)zRPKZekU4yZ{D=0X@(7{L~X z(jbrwK4kEnr8^KQ-aw7VR=e$!Mow!Za3vMzp+*T%>G9l9AGvn&o|&jW!owU+ELXUX zCkPdy;*%c$TwfvI8zms08^|CA!(tS4cy}H8y*&#VI4=fM!NAVvE}jNx1|crc!*kbe zyVdJASeWPE-Xw0l+NITn4yABOjnG=hVG-aWg@7Zbs}jBUL%Z^=Yc@aWcKp zlH_x{pf7_th8os#;2fpSCc=Ey%CkMyQGeIOZ-Dw3pq>WyDFHPPDA|BXTDoIe8@l0* z_o}87dO#>4&82f0M}eFVOUI#Yf8Tz!=73FoNlNf79_Ee$FmI>RLh58Ywp5M%y`$XG8OhS>~Q$f=25HJzxz2-gQ6U2xR|7iEr{+_H}} z-d~#JwuOsQ&r<>1Wx+!Z+~vSo1{|eeuMGI>pihFcvcOA+6=s47HHKS9VDK#reiUU^ zBK4wnO>~2)tMS!7*Ma2S-EOiND`mR95o4Dz&uJGc$a+59bSS~F`+!Ajw*B0LJbugj zU1A%x*GOAw+Um=i>dKnw%I?&bGtidP*H+Ne79Ahe(pFMdlG$LWCw{IhjK{59S-F8H zlrVY6m$_LKZnS71@!bUA0N^cTMe>J&Iy1$F(>9G1Y=kjy9?d}j&MQJ=D&ImV@Bw}p z@Iv{Va1K3&LyKoKW4WAY0e2s;)8~3qxf7`8RX_6dI*hi%On*au0br)b&mR8}>HRL) z?YXZTv~<9STEc^us99Y3{CM)kCDiV>JvjfQv;+u?D|3AXiM|)&gJA3j5QaXU%@N&S zsQvcAC+JIj>chOF=L!mHW4s$u0^r97Q6>w*4`_bebvyyu-ciov)OhZ03w3_&Wez`H zkeaSPEDz=5z5t_Jw7@>q-jE$FIt9`78K#<0XA}43F84Qn~z8wjh}bu@nd= z0XmO`1ElaL{N^5-RR;dOa@dv{)tO1!K6z*T!5+Q&mA# zUP(p5$UxJ4yG2EDF?FsQ+kZlIt#vvDut#U!hgKc6p17URUgWiOJF)Yi<$IqkUwya0 z+Z5<6nfY-DyKriHp>S&K5a3SJE8|~=Z~2g@N~lc1j}%Q!7mZ*J&y5}A4rEQ-arzpo zQj?5}2m#ajT{n}5#GMwf^wDH3Jp7aUK;gKJ)^!`kkJJpb;*b|{P=dH$ZR00Pj zaF*k{N#fkr&FuXz(_5VHAt7|$%H1nTcaovIDDvDi!9#Dxa3j-RmG6iWR#)Jx3jt;m zb}E=aycpB2dHs**A9us=w&4N=wMkePUD5G7E>~pur19 z>_u)q(-zoHK=l(Xi8G?Oj5sPaWo0FezLLx(CIKr0mJSdrBgn6_p#3Fu)&PD8+N)`o zFGJ6-m7ISjJ;avdJMctF1{DIlcGELL(Of+ z(nM)JXS$%i65hP2^7Q)}pLYM~v9m?T=Dq#qgZx)ADCcQ}6I|9g4(BwNd5X&_;&6_#I5`Y%HiMgoc8oK1jQKeFN1$?tvqZ0- z)JU3QQ=<6yBG+9x??w@EhdP6u>1 z6t}jO^bVXI?JgVtUNH4K^Kqy~d&15hFI9}$W`gm0u8lZ&Y+?F}lRekcT~@Ok*D~$J zR_wPf>{Xa@Qb#@OMX#N+?mH$Ob!V+L7A;h!wKub^HE}zo7pxVBoz#B%8oY7SeGz6g zbnQ6I4^vy}0n-KZ)zJR{>h8hw%OpR?nH>sv<1OH&IcT=3d#_ZZ|Biv;WazHf693!K zP-}~_q>PS|w3f20rmCE}nxd*2szo)GRrQn=%{1h8Nd0$@3X&hF(sC0YaVs@;C-jDx{Yb_CAm)jL}fk|XDWokyIsa3R}z z+$36jB$ms)7p{lg3Y1!W5`%pZH1oix<-G0f!@8Z7nPaV|=RcR??&i@e4tIpvE#&Tl zrxlQ&g$oaDarUT%W_WBx-}!4CSZ|7OBEO z3e2VfWj~h?&KJb6$x%-Zt?n$){@^Lr;I1$gy1U6#1#*){J$Fq7S&w)b;=?Vl-ns-Q z6$so8-rC@$GHZ(PBV-}Ra5PqO_KXS4o?2{;O^^FeQu?asj14iF;&J=8CZ|iMr^p>h zR!mP-4nLsep0YOL&>tly*Rn*Jk#dyWi42?sn%IV2UX(_QpsuJ3F#Z+GS;97jr#3Ws$y-T zMe|3Z~fO*WZ_Ff5>0= zJ$L=Lq|I%q2JoO5s^78i-GZ;5R-W8ue|joPI^0tuKve`x2)Nxs-Y^^1y5- zv-JZIM_I%H04&ibi5HI*=+g(KO3O088DrlZ>|7Lp}$(lA3|S&&?$<-@#~E!@%Q~h zoOoN3z5L4VjTGBei?+zL1wyby$d<%V1}I$U*IT#TCCOgaOtn_PB`dRwjp z?ZH}W3*3xXb}M3cOXEB>TJ5Cje03{hY(@K_i|D+BgXLM^VSqOTOI^_VdMeIo#94L9 zUVOn-eA-X`ho1)d!a?})6=wRfqP(T$epB1NQCWAjiuM{+%?;{mV%o|Q`bv_<@{+q` zCG2I^?cIWet0E5HdhDLHO1C8#x+;(8+;$~GD`f5 z%YTR5H_z;qopaLYF;yIQGeLoMF=qK1^Zj*+UR&rXisPx9uR9@+lacS`Dlnf5L#XFo z3gZU>TLARZhvnP9=9_h8S-syahD+StVk6zPTOMPsHL}y-hn@ZR$e1Vjh2_VOFKkf< z2REk04yN1oSr3_78)Ptb^Kh{&Oe6t51=yL(L-xRr6fnF2BDf3>poIY;v9@4qYl?iU zk6gdI&a|g7Ib;_hK%W$*DM-{=^4-J=mF0)2L8O5oOphL@Fy}2c;3L)*CChjm3SGxN z^bt*2L|p?>&_on95hYDTT@BGvMl@v*d1*vy`yan6A=_*aH8q4eoC;I9-5Js|2erFm z<@<9DgzcH*_3DAlk}^h8m)#g=lCaCPqlff!}~! z0NwGusav}}*RZ4X`2pHwJMl$_O;Z6Xm2Ohyb{kw|5q)t)UJTJzK{QlFJyBH`bxB?e zk<>w?wGm}4WUnqVSQs%7Y>)A<__<4FB2x8dxcEqxT7RA~^xOb^69{IO=@=>ySi)tX z&I0i#v8U`&vC{V&YBd$|jTcQ|^ahZ+Vd#e_>rLMPU>8Jp>xe|!uhuEl3t$g2mRo?? z&7H5EZGHflMwt3R?`iyS^-Okho<`#c8T|Ry|Z+}$z z$(-`zhfimxUN1Pv9Q*~?X(49l#?eD(bJI(5(+jgxO7k;{GZQLrUgeLC!XgfE%Ya=% z3uOlnTrDdu&d$nBOSo2Y^y1;HJ4X(~biXJMOYQlAKqHd3F56Ru>n6eS*vN4D3&NEk zRF&(k)^D|SB-(nZENvh^vA-mv;b2%}hX2aBgX8h;kQ>>xOJ>$hZO%)1&`qi@Ok*_L zal9gN=4H7k(FSfF7!2Ukc=!<@48nZN$eG|@2Mrn`H&h1xQ4_E5>!c5-;Th0zFf#4)XI^FpqxAk6j&%+ZlFRqN=I{PTp{h_zba}SeBU!(RggCBuPE$(Z3 z{nm^p$xjwqwx(>G2oTJxDO4)h_V7q%>XUn3^)?aoA4i(Imt}rG#?~NbxLPavbet=Xu z*@rM=0}#h!d;O!aqkGS&cE!sL2dXXlZR3ROr1>bpK4plLCId!JubiE)ot|r+o$bU<_bg)iaie{cW4(AGwF}qr zvEhWd5dzEQFn_!mun{Z*TV1Qcal7gZ@K(*;+jjas%!%M1P%SN9kD`@je&%?ih3K+f&f} z60jXW8D5<3TA1yfpX;5O@5U_t9L04E;G2hWH3Z7%_g5l*6@*pV>vTA4QIFWew+!gd zgTdqQqj=@p*}3MYr;9URe|(yK{K&a;MHi1A>iu|?H+`GXp9LgT=oT#Y9R%8kzPj5$ zo)HihOR};S`+7yAk;xu!tUX&0|LA&l#nJG)Cu8pyML#$iElStO!UAzNKX#vyva+0* zn2v&iv5vN`l0tjc7g$*aB7UU4KElbxP(jI9S#`Udf`yirzpc&k@Bna_=mQxMVI~@= z$E0e$ZToh04LdXQ=eO?yiw{gbZ~#^~=;Z6T$+O1)GY{mzRvCe7%E&=ea0O4e|2M=PnOR>N&f%z0s z@J2XDBLo5=6Nb{@dl0!u<(oCqZH3V7rAfBhLrzxBk&!R5k6tS*#hR!S?RAFC)=vj* z?TK0iRc)gjtAkyUOLM0I zT2SFfWy~@;r1p*m06KAQ6jpGfZB?Z?(T^`3d03Y6sp8O!qJ%RsE`re}AWQ(8k`*52 zveUv;L*Htf>23paiPan1zkOpbP79W%XFFTN_t@`N(cG=3rN2dbx3*SlNC43Az#?(T z3wh~@);kOgRn$=$s>n#GDaqH>R`IxO00Em$<1^WO3Zw4rCp~FJ8*L*?WgRP3Jwqww z(-}Fyp#f(^*#E3M)p;@8oa&>+bd?hLYyqFm5TgSgazsxx+5sflfvmaesu}E>&s^Wr;pPn0cHQE9*0jOcX zM-5Zt>~rI3rYzvHr0VxSYyIN?Q<(J>=%`Ve5HAlSdk;i2gt?%4;!gL|TQi=aWB3Wh7x-&&f>p>-GAjo)P|MpJt1%L9^)uY!XVNZsUkDACp#BQ(-Dw!B2G%r? zCq?Yzp%XG6*#8g^#Xp5bq5x&&{AAspZ3s-9g|U-0dHT?G5`J9x`810>{v5dd)RkeB zv2+R__#g^+^3PXUfN}=~j}1gVVCLpuJi6rz)JN>z;+AqJz`cf+ORf7%Y7N)p0(TCC znm5NeLr*0z=0&Hh`8*JyBUIEHUnuGe9W@uC*618o@7G(YzfMQK^jCNvCH~{QCVMO# zm^r|zz)oEU-juhyo0^uftim=OHGOk!qa9mRZx>_(xq&o(j)5%%xW0nB+|hChV3NyQ zqR_B7{FIQl417EYmdTSpOR^#!lpcI}=5X!x5cYul7XLE_hb~{ng{uPdSrafFJBbT}#xf zoo@j4514s;E>rXMBwmt>Fea@hcG!G zSp3Ue{!u=Z;K=2p3r~ss1*(7{1Tu5!`(pbMz#jo-B9|Glj13lYvH{LwhU1CYTnZr{ zJDo;e%3!QyawwU6S|*>8!N#W&=HixVnKPuM72#nrKTQbf1g1BG=fh$6H-FHk4aPEh zjyx|i#x-RE`8;rn*_Z>b&Uk%3e<;<~GF;yz&eSeI-_*;*JSD^@E5-Zk`~1&O-2tB? z%17B7KNKd}Zu&dHMQnP{Url=uY?(3Oa@eFKCS=S(Vm~M0UY+gfn`S%Ak(4y)i0D5q z-qHdnrSno3<~)HN3$uP5Wvklbk={KBX0QBD4~zQfaFm0$@=DuG*N*wg_3o2sN?8K~ zA;3RKBgfB@(nxSI?~1XcHnLeBQItb;W19$~7=r%+OUU902_VGar{A`J&H?Nr-oS;47wNF{32@(f3WAzkwBSVi%E`or z41ad>8(19V5$8e3Lz&O#0{V)AD*&btXdqw;DSXy&hcftlTpyIFmuYhIX>I|@^mb<@4*qNHhZ?)4_GnCzIsw|Nn=m0CDKpW%ZdPB((0RFyN|uCZNDdfT?mAKzX9z|pX%0>Lxq`hbLacKO71x%Fo1TP?L@bfwlfY*#rL zfx0sju<{F!<@v$Vyuht==XGpUm!{b@I;+9w%c3N$vpujhI{o26 z|D*Fj9>X_1>3Me&cugH&k}e+CVG&LO`@-U6Ar*g@OK*1HyF*@5T3^e=K*vm9*H}|q zqp&1}FKFPi?=Da8r!F1<_U(y@dsO~B3!Qz~vm|^qelUlJO$5kd(7c$8FjU$xm}zYt zd&rFRWm+Obki>vEsxX|y4W#fwnGnqu#?d&@EM5Yc9>o-9BxB}X-5BSjrqNr{vrF(mjovWQNe zC8FJpHjlwrsWA`9MR$oQFR>a=1inY0ET&TTGoTO)$DY)BZBRnAcOt7dAyV>)v;wki z2eL*Sp$YR?kV>P435dahewWrmfAx6&cidI6-NXFbzVH_Z^Y7%9O}Q&z0u>qq{`)=# zfyr>7CkWvP3r^;pRofsdYHia-L{kCTp}Jb^KZwF6#KIE!+U!e%f@MMU{N!GsWWEpi zyVgyn(b-@rF9AB91MMfUI$`J)Og7+OUHnuK42&+Au7l~O?kDFtgDoq4ZOi??sF*R* z!~|h{f`Gv+Pfil1CzmG2aG25QzFtgQ^{-baWP9NYJLI)3^^A%S z$1~>N0r?(~PQ%hEZcj10>juyuiaHqb$uA0(@H9a4m!SXPW2eGa13u6N;)n!an zqzx4|TdGOiC`g2bpFkghg&)t#vrW~u7^upqD{fLz{&TzD>ap&(z?%fl6o0G%<~m`% zYk8nrT>>%J6|*sv(v$l`Tk^N7$I^g0j*38NyfYeZMe;LddaAQLW!S+|oY1Wht4{Zm z6Q=I&^wELJE216Yj}KwElk)k+lZ24>N8(={iRyb?3=5x{A4feoV+!~(Ae9N0D@fB< z0s4cyEKLjy&5f*8uY%ez5k4+2W zbK?bqWT7yL&IqMZgQzPJ(GiHbA)>2@Z2kjTo;<;)l#nTr{X<@T{Ut(XZ*F|JnT(3z zW)*wAT_(Eb8oK&E2|+{{8DF`;=H>!62s+(I6J${ij_+AF7b@8jw;D#0U^$h=JWQk( ze5wxC(n7Q}5qVieVhf_Af+#5=s!E8SHgfrzh5(MNQ1^*)5i&DsGk%|r+&btW+vaXj z7a95bK>q#QvN;>+VF$5aA!~@Y3`MuD$WeT5#`sL^wr$8(al~>vBDWq9`wdZ(`%_hU zm7+AFvK~1YD@kJJ&k}-x9|g;CeaEyLe6=ufkx*F&;}iU!jX)Zksd*wAOQW5iP9_1h z2PnNj>VHvo@b%e(XJ-nZoG!j|qUhGiq8ld*ZtU&e;gUq9SBlpOT1qU_4?yu0N`ML1V{@9c?( zr%ygDD}G&?|LJ6Au9IfV>FA&3QO}btq2rz?OE_id*QxaJyh!ML4IM8(=7m2m-GA%+ zky9rQXXj<)7i1UY=N`|^F3ve}Jnv9ZZbm^~dO==%d0A@3f#A`LC!3RlVBjtMIt!R= z`oezJayFNGo`iiIbQFQT@1@1uG+v7RaC54rziteAtx_L6?_4Om2&&x!|9tP^6xBmTwyr4i! zv%OlDZaS_$MzOx;vvp4Z)!~D64L46cI+YXbyvxnXDAaj(il6=aGuex^Php}(&{Na) zT!*HdR7(z$Agb8y}NleG%HLV6Fo;nlp^9)Q3NX@nDz=g2lMq!C2UB zHB%S6bNL1z=hf?%1n%FwdF#e)Z#M@jdYCw$2kUQOJr3354Ljd~G7GScBTkYq)f0_o zfcM0qwE&FCRO3aY?ADHEbKCXpU4`YZ2UAuOJTkzVY zn-|$Hb6vfuWURS;IEu!9qWeLNHMA>D>NAXrpP6|6_q4|G0rwNIVoq<5g3z5gKYt6J ziwK0kKZwic5SLkwaWVW)fbCz_qX@1O2&ub>xo%Y;dBK4XOd2&i{W~agbXopNx2$lZ zf$^mLqnF4qYj%j^*cek>@pfJIp@{?a)qGwXDO=N@( zKhF{Vvk0Nfh_FaDGPnWNfI6=<7%tGLC0H&g22H~-x4rVS959=MdGF{t4l}*O1q>RkePyj$5a^f_=#rlhoRtuol@#_RIrPh`pwG!Z?~^p-vLP?&iUsUO`U2j%Icq-VQmrVc7Zf!^uFHa)3b_LX!(1zrkR|-1j_KoP)vs zsm#=o)Py`ogQi!0)X{o+9R+R*_J?4z1Jje=6>C#yDqiKKMd>ZrUib|#wsqLHi*Eoz z+gP4|cZ7M3hhCwVKJ1N9cZZ0(1JvCCSZ#&bn%*~VWu6)p{<@^TuRCM31Lx7Wo`b{Y zy_Eu(FC;Xl)O#xCYTaw~)!HhKfQhfzxndx7;n|#s<3D)G5Cm) zs3>@#%(W+XZcFRjros7bLngcx|BmUE1*4nzaBZl3U7_=6CB_lz3MRd+4?o7hXd_gl zx9dJ^P~)3)dH_G|q23c}yeK^>l=axz z2R8v80NkTsuLI^D97+L&hC%JURju`DE!4arElvZx7wiS>P5G34mUq@T-~Qbiw-`&s z(44G)Td&;c6fN2uu`!Xq#&J=QjpNzFCj!@QF>!O*dD&s`gSd@%u;v3Zrtni{L7iN#PEYj7c^jDEZI&Ht^5c#0 zShWmn+QX&|?6|^|>xAO*MQNTsnI|p!M!%i>^E{$aVjSC=e2uDq13nH=He_%lg3qsp zXCL2P%ZPgP(d|h|xIt;MbIDt;lt^W+z%y;u{0-{j z@IC{oT3}%brg~wZf(AWO?Ux^cPO!fOxJlAz$xlCxVteUEKmFgnMujo1pA&r269PZS z2j<53<;1&xeC?2)?2sSs+!E`VB+Qb2|LBC)HLwrx<^CKR-9`059(#Z~s7_&>-LF0G}j(?@vBX z-`tJ8t~3AAQz_L|fy!KHO)s+*sP`8r^W`q~5-f{W0pbL4ehP?y+de#?4dOs1Q5WiB zbhJ(X5)p*J3e4rx;+FV!-rcFcEIU~jmdjX{7rCsYQ(@G4B znk+bn8;b_4z3R*p_RlL71xF1YAPw*B8{S6Avd=$0w(#U6SUnw47HHOgSZpB)$S#0Q z9AL0Oru|YkFlgjDY^)5v3N2B7+#t%)D#x9pz)k7Pg2M?sy>eh4weYPuT?dxK0YWhQ z*7HM3uNcl$K@p;-qv`GIF9BY;G446B|6wpPBtIfNKQbgI z#`8y{ZHy30z6g7d*4=jFCx>-!V7nKlhgLtm&NqJvL*Jn5>sJTOS6VWk>`Y#}*uDz# ziwFq}2n+HFry(#PFwj5T*C)=y>w}X`fr*kM>ybQVv2tS-===s9X{B}oHC}v$Hs|Xj z9>Y)ueM%6&N1s_bfaTRK)Zrdb=ArLniv<@d{&u(BscG*!yU7OKK8CH{wxjU@<6$lb zQLeZk{aV9oEwL{Saj68z1AHZH)WB*TbZ55M-W|5TTBCd%>OEj9orHXi#eBq|5^((v z)H373C;#i!y}XjF4h!$7E6G63222X(syXPC9)m^ZyRXT{TJ!4B=-Fdq+FZ(u70_A+22b?KY=ZzHZTRrUjIK~U$X3$Lqj zk@PR2%mk+ldDlIJ+EiHP^)GK4T*aDR+t%e=)xJRXxIb!il^CWzs>+QszrC-05SMrNW-$9JKqSJ-8eq3!efq1eOpE+Otlo=hnX9GB zH=#Qp$kS;2)B%2i2F72(O0b#%s3_P8gc%PYzJ*wmm4jZtIiK4mWwmc3!h1qNMk9~Jwp_!^auO;|Fm`Enn=7a8}vTkH8G z*8IWd;7{y83#PxDFgFPY7}Uy=DHo@vIa-D!mTz#tx6Z4V$aAWq2rrsEKMqir4P4Y-;IE^MiU*;B)`O%OC!y$ zu=N{u+h?lMY0r6DyxS!f#C0x2<~v2gUMPLlV^JA~6qdvI>t#>%D&0f5SwLSsDm6Sy zPpryQAL_qRD!)}ng~9v??2G`iuE<@wz~V`Rhhmkl*4Jq3%mk;*I8Pd6iX)whqpfoi zjj|KXzD0YKc-v$tJxaTIVb@H)SMkyO8y|Z2@y_6EZEjPbW2U-PQ>1&omraI;OMZA@ zZZz!-?m5u`xshS{5s@@km>uK$J<=iIE@PpT;DCu}yV(nR@VV3jQ`3Z^;-A(!FhYCO zD}UG-zfxC9v$1~d=$z~y80sJB7ZmIr8bb4e!NGx%f&Pj9{%Kw=l^*7PH<+?D#q*7% zpgS9;(wDyJz>w2sgTYp_11#p#&`qA|$Bd00tgIcZBj@_+=!?8P(Udwv=u(0){qZ2~ zdbKliX3qx{A9pK0Y!UJGkTYP~yz63?uj}Oz7MhH4|$xl4^9+8A}NRI#1~;y?0=ycex@DHV5Mj zMKa{BjT$^1dd9Y(e6!C+5+*9(a1~&eus8yf9VNEPzs-eySP1;G;QFS<*kW_7$@O-t z-$TrIV<1Br7 z!(1(_)$R0V?M=OV|N8nC+6f?%jI{!seWll*H7^mZB1c=4@70>>eDn0n@{3* zc3AJ<9*?uI;R0xTBGz#S?f&uYjfIf_67tLTa2D*e=Du^B$elV!W){UaHbl?Wc>zYUV3goE`s?1Iu%;H4aNHX;zY7OrMv# zD3|%_e~q@M#gN%C-ucmi*?V93CN8OEr^ULhziY#_4yX<;B%j` zK=FE;{<8{$r_fUj3q3G9NB;i1%t9XqnxLsH-%#s~no5zIXPSq1th-mRudi=lfOiPp z4+e(@M1}+;hWMrVxu$4J_};x(Xepm%Dnjji4P&v}-PW)j1lX9?V)bClYZ<|YZmMD- zMw;3WZ&*tUhgfR7^-*uh)_v=98YrFzlWH(%x8ZqfOp0?#L~u#r&Z6AaJth7fWsYg( za~R*N@J#|5)u7oD+T5Vt5el^X4FB%cMeKxdL9Nzon_hXn%C|b@*%4dlcU<=1?UOn( zp>lr1?;-RCz-)NuccuPnt^FZq%uk&$Pk|w|e~~(8A?_(%D5q8v+6|#r7k=wPw#u3@ zGfs~Mr^8}AMs+-;ntY!g?TXsj5HU>@>3;wXh3f@w<_cZK-=3(G@3 zQ$GRO3$P8$UoFxCq+aBU37DBlg%xC^LO82>SB_-N<_ePOHDUJ6(B39!ps z6N9j^3Nw@6G-O)M<$f64tT4Y_YjCH<^64+*J9*lIr6$+D%P|b8vdze!pO!g3Ds!Yq z;jeDRe}?7$9g#b;?eKWgK?GYEzWz0)Gt#WaS>~Ji^+w|-+i|uVzB(17@I1ktK#UldE5!k-%^cbb(SR+{VP`}n5@MPubIP6{6xS3lNeaTIzDV9p$H9=I*X z!Y{Y;zdUO!H=6Db@2K)lO;Cvsefjh*Vqwf2Ae_2qez2emi*}v&vT|yizn?i&ueYPVfY)MhGBjhnfmdo zx-4{5LCw!>b%kU(sc#*JrJ)e?egq zs1OUp0I1OG(_!xuW}6hHB~y3D^) zo#KBF${iokXQ31r7r&NtauY~+^YVL&a<}cHF-5Ko%}awXPPNFL08c=$zgdZtTFp0% zGCr3V|2Wa^Vq?I=RzvPdIYy-T$tAI)Te=L>7K}(gzIivEDRahs8y>6X%pa??Q$b z441<1bSOxJFCVv}LZG*4I>x)yS_OtGDc_Px?c`vh6gFF%UfE>&sN#l;fiyP!;}u}1 z*Q)YXe`eFww1<1P^U{c4Q@&eBY?UU$LIsR`{r!S%*G6<)`xg9&8hr0l80!s$J=j50 zzLh{(bn-(j2pL>{Ifbb22jA zuB=46!QL{g&cMtN)cyRX@p8=98rsXD{PU3d!wq>pqR_uPHxc{t7m@n6+D*lw?K@!C zfV@Kj{LbMnejf$MB^Vx?cC|nn-#xJ60rTU#N(h45#lCAtwiWNRJU-QFczhy>6$s`8 zl*;a&AuVa`A2j9XMua$X#<^XYtoGgPeBD(Lu-yMDE%)&XftH+x;1`Wy)3wU%k5Q%5 zv;nzI@kynbVUDl=+tBD`q0{Rx85cDeYNQazxGT`E4dh_rvPDYF>HOTAp`qu~)9yxx z^JIQ}78lCjSg8O+JM5MUfID$Y3)TZCBJMRPGEC`T?^fl6VpkYXgx&~BSL{YvG;EAO zPgl8bD2&e1Il&f&)2y_rLmYqkSeJ!+evPDsk>Pn!5nm(1e}xAA4)ZCAaQzzX`Z3(0 z_?5eZD07*sk04Sid1RHaE_-D9*7k-Z4AD zBRk%g<`xTMd~*|>3KPv-MNcedm_w;Qw#Wk}@?fVEkfX?tugdjgpr;aAewCW2d{CAs za57K#a(wOY5*6YW9PZ&C;qDvZ?jPn76zUWjWS`(?mEmMi;HcRYWBtbT4!$P@7DIp# zhTnE0>_?GtnE?GIpToYt3i%x$(D>S~B+BJ&ko)p{8vz>Uuu03rKq@f^`aK5pxYt!~ zqZJ;`%UtVw$~5rs)Pg9}su&yX=96R?K!XDp5)p@6M1>1D_GSyjbBM{105TX|l>z^%V9ffz*Zyv~A zI(W$rI+u{zjFUR&S54W+WRIfM7|7}uL6x2K;`HX@|DmN$ElD0*Qa-b+#jvD#VMX~Y zO5rR?fe}=gsX7<2il;%92^44-#<`=+wrO!6y3?UEr`17qz|*qEOlRXwEKGF6Kpnm& zAErAN^HZ{&bm=^AsIi@)nkW}t*qes^*_;Hw|MUmv=*v~hGfm+kc?Oza0*_#P@4V zrwTWkarSHSE$H9wmcQ6%#0y0xfP4$n?_nYf`o5J~X*K(}!T1Qw4Z~pFFK<)i*Ecm$ zuK7MTMbUwIF=2Vpk%du_-y%awA_Bihc^Afdeu#7~Ne{4-VeLuPht3FS4;@HSh21hh z*K9V%?lr{#rXt1td1kC$?rWF#p%z7P_B0HBN%Y7}^riu@FxDeG**fo)uB8})(is3- zSul}|?T&`cGFWe)edFI^A_1lEpfJAD^ku%$%X}A|cdq*HLhM8RE&YRSe8TL!!|naU z9fHCg!owVsg6)!Q)W7+djHLVg@RESZ1eo*zd=$NY3G*7D5@4$4>!%c7x2zD)3=gAU z5sum3PAi=y01aEDcL48z6agG4?*JuSt8@_FfW6CuoqxO)VlcM`F!FTNovFe%DBr@~Ehh~vh0 z$Gjx$FCnfY5RVav)kKpPIf1eJEUULKfD|w2-`qD9SkPvn+TF%zavo~&lIR@Kr*NWY z_QXySm05Qb88+3JHno{|bXd{q3>by8be0$uMyfswUi~C!GmvHfJyf}{rNX#sbpysS zp)sYz^m(0wdY-n#RB{09Ou^n5%(TGX(s*9lWPUbXN@HXkRyPARbYN)(CME&159{ka zsUKjlA9}h|4GiccMNM_zwG@B4SspZ%KwV*>hH$%uqzfxT<_v-pf#CcHFNPxgweBp#cRWoR|Z7*yG8lN6mQR|-CB_q*b`zsc+7bCl$jvPy7iKCU7BZG zl7CL-*83aGQ2PzGH)rdbVSNXBhpMgZ5A*Y(p^ApVR@;}28eF5=XQwRA*IJ+bV#D&; zTX?B66E)t1nH!yLZo>4Bk~&AJox_y&)}`-B%fBpP&;pueAc}4K1p9{!NfAIB!iLT256SO(r#kg`#}x%oI`=mX?;$O357}KQH)1I<;%K(N z*J&m+WGmNTEDM9RFj)^x*(EN@sIrvCR~|p(Y5vP6FD^JQE}Uisv7tq=K}E5CdGUU! zF}~kEhnvc=c4iyEb{Z_k4J3=f@;ks4qpCe%Jf1S0k{zdznP~VS%I5345E|%c;p^u_ z-;Bh-e3~DO^~_GP&3&zFEQLUKdBRjAbb8H|Il#^jm@6xHQ1~r>Wj9b~$U*Ll{IzeE z(qBDvk{#7vhgijg*@cEX21Gdfg}eBMIQa!R`Ug0K`&h-=YUFzxcEsDhR^whw(-?jI z6h@q2Eu18ET53fE97T#G8K{i3H=O>RSiUX_lZ#RbH2k^#JTSTPi$s68Z! zaFaz?F_IV1hFtsRe0$35IC(D6x=NO2-?;Y=Ui1Q8pjM9gQ1=o>gB_*Hgw|lisxe~~ zE|BFJ4po`4+ALUIW-#N$DV`;2v7+=i=dG{7zS}_KVVIbPky%*B_J7KOfe9F$gvA9I8A!7=+i$FZiN4PF$!mo+@Dm z=b)<;gj{a?go286!+gPdsJkLJ4HjMUn!6n~0xPbl7;d(MLwzkVQg z1M~dyzQh%p!J#7-rGL0>02CKM8qm1{W~_cV zooI6A>^BjZ*0{Q-c7Np=&yK|XO>Zq}U0$&hg;Xc#%S64k z?2XjeDvkK$D)sY~U3RQ}R-F6ic)yH<0Gg%6`DDa+rbc^bBqt<=dFV*7g<0~#L=dcm zS9-CnXURafXGhXAT#pZB=}ok|(D%=tS+7FghX&+Dh0dG7|B2cDI?hS=)#um z%M}l;9-Rj>8r&pJ^$?w)zFM9@o0jr8y)19xcu> z9EXzJgy$?+VJ3no3rUil@bcpB3r1QtgjMAvXmHU@nH{fqk*s);pvr;Pzp|mtx34Wg z(7m#*!a1hOzU(7PDRhJBudvff*V^d*-Wp{~OAW@pMtt^CgOMs!WiBj?5bLT|iVC2& zmrhhW(gVXS1L=`4+kovZE>H1*y%9iR%vQL$V%l0^V~ws(xHv)R_zjrxk=E?t z{+}~rZEGXF=;k`?@1nz!RQUA@Vyxz0US7S+j=j%AdcsGQ5TF5Y<-tEhsk7)8e{U%q zTh%x{rF?u^{`88-nc)Y=2h{{2(+}plX}KrN58x|vf4J%V^3;XyAJAV|>LXI_cWtLa zf!^guiNY-h&J4xF;efld7C+a8`vRBv&zyh3bw!BjVyG?6?~H6?QVuBruwekBngd2B zQ0iRU_baQAp=nl zTGY>=t#0(*`D^VF%N{=`Jbu3ROlDlis>IFjV?fBP_>&Dqsd3>4U5_sJzr3^JAeSL} zs?z0Fo+s}IUzXh|NAkKCP~ul;dE%1iezSh2&ELOVS-$9;Y&7R@kYjIrz<^e`5Bic| zD2dS(UNL;SVEky+?C!AmX|g5p9CH_rTL`rT%bXKf)Mv}R{;;97hE3oqRpxxI` z?%yn@C%KlAX|i|QwVt&rKB!fFlB@9GqqgWL2hDdrR`I^}u_3;Zp+VuH5n-XxVIlEh zA&FrjNio4;-llSz*Z!??SF6&wS0}+Ztinw2y-!J!osUgG<8$v*Y7)b7OOJ zEnCQT^mH3+4#L>i*$lf{hX>#F1k0?SA>X>t9$jet3SUz?W$#eqTa>i$r132Abp3*k{F#r=m4Wim z`xe`tknSNq`8$$4@e^k2mkZz3#|G>ScILiL{E`q`k&#-NmYDxGD6cRv=i7(k9|h$_ z#Z771t*=wM-$qS;2<&oF=+}C*ruYc;{091&08aAqx)}4i?1c@56Z5ivOsM@atnp`` z@*lG*Cy5HId(zCqGUwrY0DOBja8Pvl6IvDW`06X0=mkCI%Yc&+Y&A-#41q-h9RAt!>J7z{%u&sD4*!NaESM}_$ z4qx}vb12o@8zPrMQWSOb{^GNjgL>v)-F@B!1vcKh(k=RMNn3T#(1R9D_t zU(?xG-`w2T)YQ~o*Vs|rI@U5Z)Yx59l>C4fL06+&4eRpZ?zLeWwB`C?aAB*#1v~qp zqcmo?rKG#MwYO|wtgLUae4wd*gl2;kedFaV!!^GL8nY^Yd1t>>gyppEH|ihEZoxt| zROJ5FQEreGZIu;i)Rd_*)0|6x)&4PQp!91`ZADEPK~#C))!{nZz4J_&9@-VxTnQ|wY$}2aUcWqOZ1EV9jF3X5|@%O3_f~0s3G})+{T%dhv zUz!;$dX6a0xN+xig6KK2G!y7v+E-=5>an1d&J!h>Nza+F!i*SECbT&7?tcK>d46F} zm;v{k>EHz$$nb!o0H|K3>j^3eg8VIzy$xcQ;1LrDU!cmdZK_`!Qezr3zdU7sZ`I}b zvhCwJv%7N^w?{3njTl}=YTRnPa(qW$WK{M>hm=6QGUbK@L{xz`o> zpv3t~uKCpjS&lEJ&-2|BUppwj3U#<}_RsSt{`v=jxNsEl*B=PPNd)3J0&(Q{u|Ll- zAWpL&j<6sQJbxf={*CYzVy#jWZW6gQAaQF_?nb*9!-yKwpvv)X6-0+NqD>Rgu7H@8 z|C{vU^xort7UWKBSzjmms4UvZjoQ4N_t!urnxbD@LSYnCCK58uK5G7ns#Bm(lHfx( zX8e#-pMWxIZLQ2Nc#(sfSx|uI@$DN=?p$@X(FPdW-T#Ec2OsP?Z1$*qb>pls5g63D z*($=_^y0>flVPu!a;L3wvBASM%}YOBpM5kC$g;TeMw_oYUMEF^y(v^A-H@%o`dY2s z!+!1ClPY%_9Y8EjP+T_^fr6ZW@Z9|JfXg+Rg`9N@^5 z13U#VKsO?JZM^LHO$25!9M(cR9GIsq*|xpzwpsF`YFx1Mp8(ehluaN|4>u^VOFsll z20ZD%W6@;5Z31~>pzn1;gfMJok7gKuv3Lv!0mbI58y6fE48-hzk;gIWb}v4^3_?sIx8^@h@v} z9%yjwh#uQlVBA$=-d13u>hMt%II*IPWC@y&W2R^dY%8(vYx80C`6;H?SEbJE%d?=R z8P=uFBBjo($Xr;HV?@a@)BFWSlz||^ND*U!mppXnsa>V23Q`sLK%5gqIN`xr@^!@i zJp^9iB*uz;!-KEimT}aLw@vTNyd&SF8Pk*{)1cYuO*<}nOe@T?_Jm>d(Mhb;{eAC8 zxVXpobXvr&3d^Bdf%l~oALLKE$?lAd~o#l(mino!Og>Z^29&vtY>-n zSkGNzKF+~ z5!rh8a6A3sZu095R}4fZv>(hE2~FtVoiTW@YA)HU zaCOD?*|hIXQi(jJQx6vX&|@J>!>OdbUMo|@dw2MGFR|UcCCJaq#>H~lL`Mo}BPuEl zu(7c3M;f;s`m70Uuc12=%HCFMNkB;sbkst59{m3F%~}Tk>us^MN~^y!)K$<|RVwrI z)E=O-{OAotTdnXlxk2*gsHrqmet~zf{V$$%N=dYsn`ZgCMF)FSX+4LALMSWTdX?~9 zN59dc2;Gw3UW#g3U+`*x#;D9f9)Z=4p@;G}M>h+G?%d01y64?Pt?LejfUX-_^0 z3kP_h5)XiUKvylI(EpN%urs|ioiF_qLB+%Y(s#g?Wmf0Hw&j%x#~b8MKRhxOC@nx5 z0}>j@WIB7pAsz>00__Y3L?G_M;Ud5w1oojGc%C*rpOU4~Zx$VV6qSqvH3ecS9F{(`W3%Tw_H_50Kx+k{Ls`t9fB2MzB<%bmE2B>(JFU>`SpiYbVO zq4FdXnKZqZB~p*KXykFZy!45E1!j^oGgay$ z$Z~@+Kd1@fR4?r)bL=Ux5@_+Z;+ak9Kc?gm)0Tg&y%E4y)9$1#z3_6<6t=to=>#1r zLvLAI?EdV&ivab@`^sG7QpaaaS>d-feO`T58#dKoLkU*ZVaJIu>P#AngpuqVFXf)E z{;28i@8A1fU_HUf%^@Hlz{7EoiS<0kb$(VsK~A3AS9pZ(@jSi7d!P66W!~#N0)nii zSt*+pB@F>C3+WNik%4Infr&6!3IwDJY&inT4%X~o%o4u5STnmovf!p#-a)F}!CJ~K zDL>fKc(fsR9VsDzR(=X@`m@s9U84U&hAIpNLc8BanLF$?0%6j@NcF*GUI7lKXAf@N zxypNmi!t2Ij5J>ZYhPeJ5mtltYfPa3158&?D&AoVlZ#ALVYCN2>Y?sCEOm88JHf_y zXG9P*^~2yQ6g9x?#zI5@bpBq<2#4O^(EMxG)s&Wrz(fP&rqsNA(j+V1YGs_`?;0QI z^2yRLTGM3sBDFaiF{wZ+yEU| zAENony`RO<(E!tJUEx;0e08XUKVg5G-oP?Y4n?txR?o;*4+)Aqpm77V9xP}+tTK9r zYfcA3KNi&iq*=NK0eOx}nZv_85f*^53pLY&VBKJuzJU8r)xST1J?^*S>5C^MA5U_L0P zZ5*qLbuO}0Y1fpkdnpXXpJ93kwzerV0XyE5eb<6v)%omNG7qs$8Zfp%amMVK!@dJNoE&VIFLT_y$#IL1i~qbJ)48h*XD^;9%uJoCF3Syc>i?DqyVXS0 zXE;m+LKxuPfM5e83plieJv*on8?`^tFN)aJx!JF9b5dUd?Vz@6CN=boonZ2!`x#%a zDF65i9-Qet+Gp&SJ=tq^wZTK`YlJasqMnw&Otdym_O#87_6)Sw_0;{Eto+*hG3c-| zWbcdiewK2T-6fbSTg^`Bc@>aqqWaND2WBVsOABGR0an_p!^~m2y*?}mHVziwmsVKQ zg2Nu@YR%V{`C_JuE6Ikje#lOxM~VHVl$^vt8|^wdu{JBCB45YXeh!IBH(_rW`YO>) zrF7=2+1ZA-@9ElDLtXURhLM&xDx%QeM5!$~tgoUaG9N4@KRYVGXcx4!b%ZA%(=uVQ zcl=#IvZ)xL2VifaB`2A#oYnH9Rq^h$3LMuT(PA))pF8pu$8NUfz(XjTJ~{=>?9yAI{MQ;#_JMKA72 z{BPF~0cqTT)B?N}nPj`QYY7kx2kx6lJu=>jxM4*e(7_eR&f4DmEydLv=LE<;{9qla z0wM#N

8K}&Ur?LkXQH|VHk$@J@z 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

1h^-PsCB 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 literal 0 HcmV?d00001 diff --git a/flash.sh b/flash.sh new file mode 100755 index 0000000..aeab805 --- /dev/null +++ b/flash.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +source venv/bin/activate + +pio run --target=upload diff --git a/lib/MPU6050/LICENSE b/lib/MPU6050/LICENSE new file mode 100644 index 0000000..669a814 --- /dev/null +++ b/lib/MPU6050/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 ElectronicCats + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/MPU6050/README.md b/lib/MPU6050/README.md new file mode 100644 index 0000000..6756d46 --- /dev/null +++ b/lib/MPU6050/README.md @@ -0,0 +1,49 @@ +# MPU6050 by Electronic Cats - Library for Arduino + + + + + +

+ + + +

+ +[![LibraryBuild](https://github.com/ElectronicCats/mpu6050/actions/workflows/LibraryBuild.yml/badge.svg)](https://github.com/ElectronicCats/mpu6050/actions/workflows/LibraryBuild.yml) + +Arduino library for controlling MPU6050 module. + +MPU6050 Combines a 3-axis gyroscope and a 3-axis accelerometer on the same silicon die together with +an onboard Digital Motion Processor(DMP) which processes complex 6-axis MotionFusion algorithms. + +## Features of this version + +- ### Supported Chipsets + - AVR + - SAM + - SAMD21 + - ARM + - ESP32 + - ESP8266 + - RENESAS + + +#### Original Library + +Based in the work of [jrowberg/i2cdevlib](https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050) + +## Quick Installing + +To install, use the [Arduino Library Manager](https://support.arduino.cc/hc/en-us/articles/5145457742236-Add-libraries-to-Arduino-IDE) and search for "MPU6050" and install the MPU6050 by Electronic Cats library. + + +## Maintainer + + +

+ +

+
+ +Electronic Cats invests time and resources providing this open source design, please support Electronic Cats and open-source hardware by purchasing products from Electronic Cats! diff --git a/lib/MPU6050/examples/IMU_Zero/IMU_Zero.ino b/lib/MPU6050/examples/IMU_Zero/IMU_Zero.ino new file mode 100755 index 0000000..a9f46ea --- /dev/null +++ b/lib/MPU6050/examples/IMU_Zero/IMU_Zero.ino @@ -0,0 +1,358 @@ +// MPU6050 offset-finder, based on Jeff Rowberg's MPU6050_RAW +// 2016-10-19 by Robert R. Fenichel (bob@fenichel.net) + +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class +// 10/7/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2019-07-11 - added PID offset generation at begninning Generates first offsets +// - in @ 6 seconds and completes with 4 more sets @ 10 seconds +// - then continues with origional 2016 calibration code. +// 2016-11-25 - added delays to reduce sampling rate to ~200 Hz +// added temporizing printing during long computations +// 2016-10-25 - requires inequality (Low < Target, High > Target) during expansion +// dynamic speed change when closing in +// 2016-10-22 - cosmetic changes +// 2016-10-19 - initial release of IMU_Zero +// 2013-05-08 - added multiple output formats +// - added seamless Fastwire support +// 2011-10-07 - initial release of MPU6050_RAW + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2011 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + If an MPU6050 + * is an ideal member of its tribe, + * is properly warmed up, + * is at rest in a neutral position, + * is in a location where the pull of gravity is exactly 1g, and + * has been loaded with the best possible offsets, +then it will report 0 for all accelerations and displacements, except for +Z acceleration, for which it will report 16384 (that is, 2^14). Your device +probably won't do quite this well, but good offsets will all get the baseline +outputs close to these target values. + + Put the MPU6050 on a flat and horizontal surface, and leave it operating for +5-10 minutes so its temperature gets stabilized. + + Run this program. A "----- done -----" line will indicate that it has done its best. +With the current accuracy-related constants (NFast = 1000, NSlow = 10000), it will take +a few minutes to get there. + + Along the way, it will generate a dozen or so lines of output, showing that for each +of the 6 desired offsets, it is + * first, trying to find two estimates, one too low and one too high, and + * then, closing in until the bracket can't be made smaller. + + The line just above the "done" line will look something like + [567,567] --> [-1,2] [-2223,-2223] --> [0,1] [1131,1132] --> [16374,16404] [155,156] --> [-1,1] [-25,-24] --> [0,3] [5,6] --> [0,4] +As will have been shown in interspersed header lines, the six groups making up this +line describe the optimum offsets for the X acceleration, Y acceleration, Z acceleration, +X gyro, Y gyro, and Z gyro, respectively. In the sample shown just above, the trial showed +that +567 was the best offset for the X acceleration, -2223 was best for Y acceleration, +and so on. + + The need for the delay between readings (usDelay) was brought to my attention by Nikolaus Doppelhammer. +=============================================== +*/ + +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include "I2Cdev.h" +#include "MPU6050.h" + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include "Wire.h" +#endif + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 accelgyro; +//MPU6050 accelgyro(0x69); // <-- use for AD0 high + + +const char LBRACKET = '['; +const char RBRACKET = ']'; +const char COMMA = ','; +const char BLANK = ' '; +const char PERIOD = '.'; + +const int iAx = 0; +const int iAy = 1; +const int iAz = 2; +const int iGx = 3; +const int iGy = 4; +const int iGz = 5; + +const int usDelay = 3150; // empirical, to hold sampling to 200 Hz +const int NFast = 1000; // the bigger, the better (but slower) +const int NSlow = 10000; // .. +const int LinesBetweenHeaders = 5; + int LowValue[6]; + int HighValue[6]; + int Smoothed[6]; + int LowOffset[6]; + int HighOffset[6]; + int Target[6]; + int LinesOut; + int N; + +void ForceHeader() + { LinesOut = 99; } + +void GetSmoothed() + { int16_t RawValue[6]; + int i; + long Sums[6]; + for (i = iAx; i <= iGz; i++) + { Sums[i] = 0; } +// unsigned long Start = micros(); + + for (i = 1; i <= N; i++) + { // get sums + accelgyro.getMotion6(&RawValue[iAx], &RawValue[iAy], &RawValue[iAz], + &RawValue[iGx], &RawValue[iGy], &RawValue[iGz]); + if ((i % 500) == 0) + Serial.print(PERIOD); + delayMicroseconds(usDelay); + for (int j = iAx; j <= iGz; j++) + Sums[j] = Sums[j] + RawValue[j]; + } // get sums +// unsigned long usForN = micros() - Start; +// Serial.print(" reading at "); +// Serial.print(1000000/((usForN+N/2)/N)); +// Serial.println(" Hz"); + for (i = iAx; i <= iGz; i++) + { Smoothed[i] = (Sums[i] + N/2) / N ; } + } // GetSmoothed + +void Initialize() + { + // join I2C bus (I2Cdev library doesn't do this automatically) + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + + Serial.begin(9600); + + // initialize device + Serial.println("Initializing I2C devices..."); + accelgyro.initialize(); + + // verify connection + Serial.println("Testing device connections..."); + Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); + Serial.println("PID tuning Each Dot = 100 readings"); + /*A tidbit on how PID (PI actually) tuning works. + When we change the offset in the MPU6050 we can get instant results. This allows us to use Proportional and + integral of the PID to discover the ideal offsets. Integral is the key to discovering these offsets, Integral + uses the error from set-point (set-point is zero), it takes a fraction of this error (error * ki) and adds it + to the integral value. Each reading narrows the error down to the desired offset. The greater the error from + set-point, the more we adjust the integral value. The proportional does its part by hiding the noise from the + integral math. The Derivative is not used because of the noise and because the sensor is stationary. With the + noise removed the integral value lands on a solid offset after just 600 readings. At the end of each set of 100 + readings, the integral value is used for the actual offsets and the last proportional reading is ignored due to + the fact it reacts to any noise. + */ + accelgyro.CalibrateAccel(6); + accelgyro.CalibrateGyro(6); + Serial.println("\nat 600 Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("700 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("800 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("900 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("1000 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println("\n\n Any of the above offsets will work nice \n\n Lets proof the PID tuning using another method:"); + } // Initialize + +void SetOffsets(int TheOffsets[6]) + { accelgyro.setXAccelOffset(TheOffsets [iAx]); + accelgyro.setYAccelOffset(TheOffsets [iAy]); + accelgyro.setZAccelOffset(TheOffsets [iAz]); + accelgyro.setXGyroOffset (TheOffsets [iGx]); + accelgyro.setYGyroOffset (TheOffsets [iGy]); + accelgyro.setZGyroOffset (TheOffsets [iGz]); + } // SetOffsets + +void ShowProgress() + { if (LinesOut >= LinesBetweenHeaders) + { // show header + Serial.println("\tXAccel\t\t\tYAccel\t\t\t\tZAccel\t\t\tXGyro\t\t\tYGyro\t\t\tZGyro"); + LinesOut = 0; + } // show header + Serial.print(BLANK); + for (int i = iAx; i <= iGz; i++) + { Serial.print(LBRACKET); + Serial.print(LowOffset[i]), + Serial.print(COMMA); + Serial.print(HighOffset[i]); + Serial.print("] --> ["); + Serial.print(LowValue[i]); + Serial.print(COMMA); + Serial.print(HighValue[i]); + if (i == iGz) + { Serial.println(RBRACKET); } + else + { Serial.print("]\t"); } + } + LinesOut++; + } // ShowProgress + +void PullBracketsIn() + { boolean AllBracketsNarrow; + boolean StillWorking; + int NewOffset[6]; + + Serial.println("\nclosing in:"); + AllBracketsNarrow = false; + ForceHeader(); + StillWorking = true; + while (StillWorking) + { StillWorking = false; + if (AllBracketsNarrow && (N == NFast)) + { SetAveraging(NSlow); } + else + { AllBracketsNarrow = true; }// tentative + for (int i = iAx; i <= iGz; i++) + { if (HighOffset[i] <= (LowOffset[i]+1)) + { NewOffset[i] = LowOffset[i]; } + else + { // binary search + StillWorking = true; + NewOffset[i] = (LowOffset[i] + HighOffset[i]) / 2; + if (HighOffset[i] > (LowOffset[i] + 10)) + { AllBracketsNarrow = false; } + } // binary search + } + SetOffsets(NewOffset); + GetSmoothed(); + for (int i = iAx; i <= iGz; i++) + { // closing in + if (Smoothed[i] > Target[i]) + { // use lower half + HighOffset[i] = NewOffset[i]; + HighValue[i] = Smoothed[i]; + } // use lower half + else + { // use upper half + LowOffset[i] = NewOffset[i]; + LowValue[i] = Smoothed[i]; + } // use upper half + } // closing in + ShowProgress(); + } // still working + + } // PullBracketsIn + +void PullBracketsOut() + { boolean Done = false; + int NextLowOffset[6]; + int NextHighOffset[6]; + + Serial.println("expanding:"); + ForceHeader(); + + while (!Done) + { Done = true; + SetOffsets(LowOffset); + GetSmoothed(); + for (int i = iAx; i <= iGz; i++) + { // got low values + LowValue[i] = Smoothed[i]; + if (LowValue[i] >= Target[i]) + { Done = false; + NextLowOffset[i] = LowOffset[i] - 1000; + } + else + { NextLowOffset[i] = LowOffset[i]; } + } // got low values + + SetOffsets(HighOffset); + GetSmoothed(); + for (int i = iAx; i <= iGz; i++) + { // got high values + HighValue[i] = Smoothed[i]; + if (HighValue[i] <= Target[i]) + { Done = false; + NextHighOffset[i] = HighOffset[i] + 1000; + } + else + { NextHighOffset[i] = HighOffset[i]; } + } // got high values + ShowProgress(); + for (int i = iAx; i <= iGz; i++) + { LowOffset[i] = NextLowOffset[i]; // had to wait until ShowProgress done + HighOffset[i] = NextHighOffset[i]; // .. + } + } // keep going + } // PullBracketsOut + +void SetAveraging(int NewN) + { N = NewN; + Serial.print("averaging "); + Serial.print(N); + Serial.println(" readings each time"); + } // SetAveraging + +void setup() + { Initialize(); + for (int i = iAx; i <= iGz; i++) + { // set targets and initial guesses + Target[i] = 0; // must fix for ZAccel + HighOffset[i] = 0; + LowOffset[i] = 0; + } // set targets and initial guesses + Target[iAz] = 16384; + SetAveraging(NFast); + + PullBracketsOut(); + PullBracketsIn(); + + Serial.println("-------------- done --------------"); + } // setup + +void loop() + { + } // loop diff --git a/lib/MPU6050/examples/IMU_Zero/Makefile b/lib/MPU6050/examples/IMU_Zero/Makefile new file mode 100644 index 0000000..58286bd --- /dev/null +++ b/lib/MPU6050/examples/IMU_Zero/Makefile @@ -0,0 +1,20 @@ +# BOARD_TAG = arduino:mbed_rp2040:pico +# BOARD_TAG = rp2040:rp2040:rpipico +BOARD_TAG = esp32:esp32:XIAO_ESP32C3 +MONITOR_PORT = /dev/cu.usbmodem132401 +ARDUINO_CLI_PATH := arduino-cli + +compile: + $(ARDUINO_CLI_PATH) compile --fqbn $(BOARD_TAG) --export-binaries + +upload: + @$(ARDUINO_CLI_PATH) upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + @$(ARDUINO_CLI_PATH) monitor -p $(MONITOR_PORT) --config baudrate=9600 + # screen $(MONITOR_PORT) 9600 + +clean: + @$(ARDUINO_CLI_PATH) cache clean + +all: compile upload monitor diff --git a/lib/MPU6050/examples/MCU_Powercycle_DMP6/MCU_Powercycle_DMP6.ino b/lib/MPU6050/examples/MCU_Powercycle_DMP6/MCU_Powercycle_DMP6.ino new file mode 100644 index 0000000..2664c36 --- /dev/null +++ b/lib/MPU6050/examples/MCU_Powercycle_DMP6/MCU_Powercycle_DMP6.ino @@ -0,0 +1,134 @@ +// This sample code shows how to use dmpSetFIFOPacketSize() so as not to waste time +// initializaing the MPU6050 when the MCU has been reset or powercycled but the MPU6050 has not. +// Instead we just need to set the FIFOPacketSize, since this is the only setting needed +// that was stored in the MCU RAM. + +// This example code was written for the LGT8F328. In this example the LGT8F328 goes into +// a deep sleep for 1 second which erases its ram and thus causes the MCU to restart on wakeup. +// The code is based off a simplication of example code "MPU6050_DMP6". + +// Code and comments related to demonstrating how to use dmpSetFIFOPacketSize() are preceded +// by a line of asterisks (***************************************************************). + +#include "I2Cdev.h" +#include "MPU6050_6Axis_MotionApps20.h" +#include + +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE +#include "Wire.h" +#endif + +MPU6050 mpu; + +// MPU control/status vars +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint8_t fifoBuffer[42]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorFloat gravity; // [x, y, z] gravity vector +float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector +uint32_t startTime; + +// ================================================================ +// === INITIAL SETUP === +// ================================================================ + +void setup() { +// join I2C bus (I2Cdev library doesn't do this automatically) +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties +#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); +#endif + + Serial.begin(115200); + Serial.println(F("Starting setup")); + + // *************************************************************** + // if MotionDetectionDuration is not the default value (0) but is instead a value we have set previously (1) + // then we know that the mpu6050 has not been reset or powercycled only the MCU has been, so we don't need + // to waste time reininitializing the mpu6050. Instead we just have to set the MCU to know the packet size + // since this value was only retained previously in the MCU RAM: + if (mpu.getMotionDetectionDuration() == 1) { + Serial.println("Skipping MPU6050 initialization"); + mpu.dmpSetFIFOPacketSize(42); + return; + } + + // *************************************************************** + // if we got here then the MPU6050 has been power cycled or reset so we have to do a full initialization + Serial.println(F("Initializing I2C devices...")); + mpu.initialize(); + + // verify connection + Serial.println(F("Testing device connections...")); + Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); + + // load and configure the DMP + Serial.println(F("Initializing DMP...")); + devStatus = mpu.dmpInitialize(); + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + // Calibration Time: generate offsets and calibrate our MPU6050 + mpu.CalibrateAccel(6); + mpu.CalibrateGyro(6); + Serial.println(F("Enabling DMP...")); + mpu.setDMPEnabled(true); + + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + } else { + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + Serial.print(F("DMP Initialization failed (code ")); + Serial.print(devStatus); + Serial.println(F(")")); + } + + // *************************************************************** + // set MotionDetectionDuration to a value other than the default (0). + // Note that we could set any value other than default in the MPU6050 + // and test for that instead of MotionDetectionDuration. We chose + // MotionDetectionDuration to set in this example only as an example + // of how to test for reset/powerup on the MPU6050. + mpu.setMotionDetectionDuration(1); + + startTime = millis(); +} + + + +// ================================================================ +// === MAIN PROGRAM LOOP === +// ================================================================ + +void loop() { + if ((millis() - startTime) < 5000) { // show YPR values for 5 seconds + if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + Serial.print("ypr\t"); + Serial.print(ypr[0] * 180 / M_PI); + Serial.print("\t"); + Serial.print(ypr[1] * 180 / M_PI); + Serial.print("\t"); + Serial.println(ypr[2] * 180 / M_PI); + } + } else { + // *************************************************************** + // 5 seconds have passed + // put the MCU into a deep sleep for 1 second. All RAM is lost + // however the MPU6050 will continue to operate. + Serial.println("going to sleep for 1 Sec."); + delay(100); // give the MCU a chance to print the above message + LowPower.deepSleep2(SLEEP_1S); + } +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6/MPU6050_DMP6.ino b/lib/MPU6050/examples/MPU6050_DMP6/MPU6050_DMP6.ino new file mode 100644 index 0000000..3ebe2ee --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6/MPU6050_DMP6.ino @@ -0,0 +1,345 @@ +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) +// 6/21/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2019-07-08 - Added Auto Calibration and offset generator +// - and altered FIFO retrieval sequence to avoid using blocking code +// 2016-04-18 - Eliminated a potential infinite loop +// 2013-05-08 - added seamless Fastwire support +// - added note about gyro calibration +// 2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error +// 2012-06-20 - improved FIFO overflow handling and simplified read process +// 2012-06-19 - completely rearranged DMP initialization code and simplification +// 2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly +// 2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING +// 2012-06-05 - add gravity-compensated initial reference frame acceleration output +// - add 3D math helper file to DMP6 example sketch +// - add Euler output and Yaw/Pitch/Roll output formats +// 2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee) +// 2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250 +// 2012-05-30 - basic DMP initialization working + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include "I2Cdev.h" + +#include "MPU6050_6Axis_MotionApps20.h" +//#include "MPU6050.h" // not necessary if using MotionApps include file + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include "Wire.h" +#endif + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 mpu; +//MPU6050 mpu(0x69); // <-- use for AD0 high + +/* ========================================================================= + NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch + depends on the MPU-6050's INT pin being connected to the Arduino's + external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is + digital I/O pin 2. + * ========================================================================= */ + +/* ========================================================================= + NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error + when using Serial.write(buf, len). The Teapot output uses this method. + The solution requires a modification to the Arduino USBAPI.h file, which + is fortunately simple, but annoying. This will be fixed in the next IDE + release. For more info, see these links: + + http://arduino.cc/forum/index.php/topic,109987.0.html + http://code.google.com/p/arduino/issues/detail?id=958 + * ========================================================================= */ + + + +// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual +// quaternion components in a [w, x, y, z] format (not best for parsing +// on a remote host such as Processing or something though) +//#define OUTPUT_READABLE_QUATERNION + +// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles +// (in degrees) calculated from the quaternions coming from the FIFO. +// Note that Euler angles suffer from gimbal lock (for more info, see +// http://en.wikipedia.org/wiki/Gimbal_lock) +//#define OUTPUT_READABLE_EULER + +// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ +// pitch/roll angles (in degrees) calculated from the quaternions coming +// from the FIFO. Note this also requires gravity vector calculations. +// Also note that yaw/pitch/roll angles suffer from gimbal lock (for +// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) +#define OUTPUT_READABLE_YAWPITCHROLL + +// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration +// components with gravity removed. This acceleration reference frame is +// not compensated for orientation, so +X is always +X according to the +// sensor, just without the effects of gravity. If you want acceleration +// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. +//#define OUTPUT_READABLE_REALACCEL + +// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration +// components with gravity removed and adjusted for the world frame of +// reference (yaw is relative to initial orientation, since no magnetometer +// is present in this case). Could be quite handy in some cases. +//#define OUTPUT_READABLE_WORLDACCEL + +// uncomment "OUTPUT_TEAPOT" if you want output that matches the +// format used for the InvenSense teapot demo +//#define OUTPUT_TEAPOT + + + +#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards +#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) +bool blinkState = false; + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements +VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector +float euler[3]; // [psi, theta, phi] Euler angle container +float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector + +// packet structure for InvenSense teapot demo +uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' }; + + + +// ================================================================ +// === INTERRUPT DETECTION ROUTINE === +// ================================================================ + +volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high +void dmpDataReady() { + mpuInterrupt = true; +} + + + +// ================================================================ +// === INITIAL SETUP === +// ================================================================ + +void setup() { + // join I2C bus (I2Cdev library doesn't do this automatically) + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + + // initialize serial communication + // (115200 chosen because it is required for Teapot Demo output, but it's + // really up to you depending on your project) + Serial.begin(115200); + while (!Serial); // wait for Leonardo enumeration, others continue immediately + + // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino + // Pro Mini running at 3.3V, cannot handle this baud rate reliably due to + // the baud timing being too misaligned with processor ticks. You must use + // 38400 or slower in these cases, or use some kind of external separate + // crystal solution for the UART timer. + + // initialize device + Serial.println(F("Initializing I2C devices...")); + mpu.initialize(); + pinMode(INTERRUPT_PIN, INPUT); + + // verify connection + Serial.println(F("Testing device connections...")); + Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); + + // wait for ready + Serial.println(F("\nSend any character to begin DMP programming and demo: ")); + while (Serial.available() && Serial.read()); // empty buffer + while (!Serial.available()); // wait for data + while (Serial.available() && Serial.read()); // empty buffer again + + // load and configure the DMP + Serial.println(F("Initializing DMP...")); + devStatus = mpu.dmpInitialize(); + + // supply your own gyro offsets here, scaled for min sensitivity + mpu.setXGyroOffset(220); + mpu.setYGyroOffset(76); + mpu.setZGyroOffset(-85); + mpu.setZAccelOffset(1788); // 1688 factory default for my test chip + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + // Calibration Time: generate offsets and calibrate our MPU6050 + mpu.CalibrateAccel(6); + mpu.CalibrateGyro(6); + mpu.PrintActiveOffsets(); + // turn on the DMP, now that it's ready + Serial.println(F("Enabling DMP...")); + mpu.setDMPEnabled(true); + + // enable Arduino interrupt detection + Serial.print(F("Enabling interrupt detection (Arduino external interrupt ")); + Serial.print(digitalPinToInterrupt(INTERRUPT_PIN)); + Serial.println(F(")...")); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); + mpuIntStatus = mpu.getIntStatus(); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + Serial.println(F("DMP ready! Waiting for first interrupt...")); + dmpReady = true; + + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + } else { + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + Serial.print(F("DMP Initialization failed (code ")); + Serial.print(devStatus); + Serial.println(F(")")); + } + + // configure LED for output + pinMode(LED_PIN, OUTPUT); +} + + + +// ================================================================ +// === MAIN PROGRAM LOOP === +// ================================================================ + +void loop() { + // if programming failed, don't try to do anything + if (!dmpReady) return; + // read a packet from FIFO + if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet + #ifdef OUTPUT_READABLE_QUATERNION + // display quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); + Serial.print("quat\t"); + Serial.print(q.w); + Serial.print("\t"); + Serial.print(q.x); + Serial.print("\t"); + Serial.print(q.y); + Serial.print("\t"); + Serial.println(q.z); + #endif + + #ifdef OUTPUT_READABLE_EULER + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetEuler(euler, &q); + Serial.print("euler\t"); + Serial.print(euler[0] * 180/M_PI); + Serial.print("\t"); + Serial.print(euler[1] * 180/M_PI); + Serial.print("\t"); + Serial.println(euler[2] * 180/M_PI); + #endif + + #ifdef OUTPUT_READABLE_YAWPITCHROLL + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + Serial.print("ypr\t"); + Serial.print(ypr[0] * 180/M_PI); + Serial.print("\t"); + Serial.print(ypr[1] * 180/M_PI); + Serial.print("\t"); + Serial.println(ypr[2] * 180/M_PI); + #endif + + #ifdef OUTPUT_READABLE_REALACCEL + // display real acceleration, adjusted to remove gravity + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + Serial.print("areal\t"); + Serial.print(aaReal.x); + Serial.print("\t"); + Serial.print(aaReal.y); + Serial.print("\t"); + Serial.println(aaReal.z); + #endif + + #ifdef OUTPUT_READABLE_WORLDACCEL + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); + Serial.print("aworld\t"); + Serial.print(aaWorld.x); + Serial.print("\t"); + Serial.print(aaWorld.y); + Serial.print("\t"); + Serial.println(aaWorld.z); + #endif + + #ifdef OUTPUT_TEAPOT + // display quaternion values in InvenSense Teapot demo format: + teapotPacket[2] = fifoBuffer[0]; + teapotPacket[3] = fifoBuffer[1]; + teapotPacket[4] = fifoBuffer[4]; + teapotPacket[5] = fifoBuffer[5]; + teapotPacket[6] = fifoBuffer[8]; + teapotPacket[7] = fifoBuffer[9]; + teapotPacket[8] = fifoBuffer[12]; + teapotPacket[9] = fifoBuffer[13]; + Serial.write(teapotPacket, 14); + teapotPacket[11]++; // packetCount, loops at 0xFF on purpose + #endif + + // blink LED to indicate activity + blinkState = !blinkState; + digitalWrite(LED_PIN, blinkState); + } +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde b/lib/MPU6050/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde new file mode 100755 index 0000000..881132d --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6/Processing/MPUTeapot/MPUTeapot.pde @@ -0,0 +1,242 @@ +// I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output +// 6/20/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2012-06-20 - initial release + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +import processing.serial.*; +import processing.opengl.*; +import toxi.geom.*; +import toxi.processing.*; + +// NOTE: requires ToxicLibs to be installed in order to run properly. +// 1. Download from https://github.com/postspectacular/toxiclibs/releases +// 2. Extract into [userdir]/Processing/libraries +// (location may be different on Mac/Linux) +// 3. Run and bask in awesomeness + +ToxiclibsSupport gfx; + +Serial port; // The serial port +char[] teapotPacket = new char[14]; // InvenSense Teapot packet +int serialCount = 0; // current packet byte position +int synced = 0; +int interval = 0; + +float[] q = new float[4]; +Quaternion quat = new Quaternion(1, 0, 0, 0); + +float[] gravity = new float[3]; +float[] euler = new float[3]; +float[] ypr = new float[3]; + +void setup() { + // 300px square viewport using OpenGL rendering + size(300, 300, OPENGL); + gfx = new ToxiclibsSupport(this); + + // setup lights and antialiasing + lights(); + smooth(); + + // display serial port list for debugging/clarity + println(Serial.list()); + + // get the first available port (use EITHER this OR the specific port code below) + String portName = Serial.list()[0]; + + // get a specific serial port (use EITHER this OR the first-available code above) + //String portName = "COM4"; + + // open the serial port + port = new Serial(this, portName, 115200); + + // send single character to trigger DMP init/start + // (expected by MPU6050_DMP6 example Arduino sketch) + port.write('r'); +} + +void draw() { + if (millis() - interval > 1000) { + // resend single character to trigger DMP init/start + // in case the MPU is halted/reset while applet is running + port.write('r'); + interval = millis(); + } + + // black background + background(0); + + // translate everything to the middle of the viewport + pushMatrix(); + translate(width / 2, height / 2); + + // 3-step rotation from yaw/pitch/roll angles (gimbal lock!) + // ...and other weirdness I haven't figured out yet + //rotateY(-ypr[0]); + //rotateZ(-ypr[1]); + //rotateX(-ypr[2]); + + // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!) + // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of + // different coordinate system orientation assumptions between Processing + // and InvenSense DMP) + float[] axis = quat.toAxisAngle(); + rotate(axis[0], -axis[1], axis[3], axis[2]); + + // draw main body in red + fill(255, 0, 0, 200); + box(10, 10, 200); + + // draw front-facing tip in blue + fill(0, 0, 255, 200); + pushMatrix(); + translate(0, 0, -120); + rotateX(PI/2); + drawCylinder(0, 20, 20, 8); + popMatrix(); + + // draw wings and tail fin in green + fill(0, 255, 0, 200); + beginShape(TRIANGLES); + vertex(-100, 2, 30); vertex(0, 2, -80); vertex(100, 2, 30); // wing top layer + vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30); // wing bottom layer + vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70); // tail left layer + vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70); // tail right layer + endShape(); + beginShape(QUADS); + vertex(-100, 2, 30); vertex(-100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); + vertex( 100, 2, 30); vertex( 100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); + vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2, 30); vertex(100, 2, 30); + vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, -30, 98); vertex(-2, -30, 98); + vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, 0, 70); vertex(-2, 0, 70); + vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2, 0, 70); vertex(-2, 0, 70); + endShape(); + + popMatrix(); +} + +void serialEvent(Serial port) { + interval = millis(); + while (port.available() > 0) { + int ch = port.read(); + + if (synced == 0 && ch != '$') return; // initial synchronization - also used to resync/realign if needed + synced = 1; + print ((char)ch); + + if ((serialCount == 1 && ch != 2) + || (serialCount == 12 && ch != '\r') + || (serialCount == 13 && ch != '\n')) { + serialCount = 0; + synced = 0; + return; + } + + if (serialCount > 0 || ch == '$') { + teapotPacket[serialCount++] = (char)ch; + if (serialCount == 14) { + serialCount = 0; // restart packet byte position + + // get quaternion from data packet + q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f; + q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f; + q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f; + q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f; + for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i]; + + // set our toxilibs quaternion to new data + quat.set(q[0], q[1], q[2], q[3]); + + /* + // below calculations unnecessary for orientation only using toxilibs + + // calculate gravity vector + gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]); + gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]); + gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]; + + // calculate Euler angles + euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); + euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]); + euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1); + + // calculate yaw/pitch/roll angles + ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); + ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2])); + ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2])); + + // output various components for debugging + //println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f); + //println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI); + //println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI); + */ + } + } + } +} + +void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) { + float angle = 0; + float angleIncrement = TWO_PI / sides; + beginShape(QUAD_STRIP); + for (int i = 0; i < sides + 1; ++i) { + vertex(topRadius*cos(angle), 0, topRadius*sin(angle)); + vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle)); + angle += angleIncrement; + } + endShape(); + + // If it is not a cone, draw the circular top cap + if (topRadius != 0) { + angle = 0; + beginShape(TRIANGLE_FAN); + + // Center point + vertex(0, 0, 0); + for (int i = 0; i < sides + 1; i++) { + vertex(topRadius * cos(angle), 0, topRadius * sin(angle)); + angle += angleIncrement; + } + endShape(); + } + + // If it is not a cone, draw the circular bottom cap + if (bottomRadius != 0) { + angle = 0; + beginShape(TRIANGLE_FAN); + + // Center point + vertex(0, tall, 0); + for (int i = 0; i < sides + 1; i++) { + vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle)); + angle += angleIncrement; + } + endShape(); + } +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino b/lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino new file mode 100644 index 0000000..6e1fea6 --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/MPU6050_DMP6_ESPWiFi.ino @@ -0,0 +1,377 @@ +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +/* This driver reads quaternion data from the MPU6060 and sends + Open Sound Control messages. + + GY-521 NodeMCU + MPU6050 devkit 1.0 + board Lolin Description + ======= ========== ==================================================== + VCC VU (5V USB) Not available on all boards so use 3.3V if needed. + GND G Ground + SCL D1 (GPIO05) I2C clock + SDA D2 (GPIO04) I2C data + XDA not connected + XCL not connected + AD0 not connected + INT D8 (GPIO15) Interrupt pin + +*/ + +#if defined(ESP8266) +#include +#else +#include +#endif +#include +#include +#include +#include +#include //https://github.com/tzapu/WiFiManager + +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include "I2Cdev.h" + +#include "MPU6050_6Axis_MotionApps20.h" +//#include "MPU6050.h" // not necessary if using MotionApps include file + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include "Wire.h" +#endif + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 mpu; +//MPU6050 mpu(0x69); // <-- use for AD0 high + +/* ========================================================================= + NOTE: In addition to connection 5/3.3v, GND, SDA, and SCL, this sketch + depends on the MPU-6050's INT pin being connected to the ESP8266 GPIO15 + pin. + * ========================================================================= */ + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements +VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector + + +// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual +// quaternion components in a [w, x, y, z] format (not best for parsing +// on a remote host such as Processing or something though) +//#define OUTPUT_READABLE_QUATERNION + +// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles +// (in degrees) calculated from the quaternions coming from the FIFO. +// Note that Euler angles suffer from gimbal lock (for more info, see +// http://en.wikipedia.org/wiki/Gimbal_lock) +//#define OUTPUT_READABLE_EULER + +// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ +// pitch/roll angles (in degrees) calculated from the quaternions coming +// from the FIFO. Note this also requires gravity vector calculations. +// Also note that yaw/pitch/roll angles suffer from gimbal lock (for +// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) +//#define OUTPUT_READABLE_YAWPITCHROLL + +// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration +// components with gravity removed. This acceleration reference frame is +// not compensated for orientation, so +X is always +X according to the +// sensor, just without the effects of gravity. If you want acceleration +// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. +//#define OUTPUT_READABLE_REALACCEL + +// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration +// components with gravity removed and adjusted for the world frame of +// reference (yaw is relative to initial orientation, since no magnetometer +// is present in this case). Could be quite handy in some cases. +//#define OUTPUT_READABLE_WORLDACCEL + +// uncomment "OUTPUT_TEAPOT_OSC" if you want output that matches the +// format used for the InvenSense teapot demo +#define OUTPUT_TEAPOT_OSC + + +#ifdef OUTPUT_READABLE_EULER +float euler[3]; // [psi, theta, phi] Euler angle container +#endif +#ifdef OUTPUT_READABLE_YAWPITCHROLL +float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector +#endif + +#define INTERRUPT_PIN 15 // use pin 15 on ESP8266 + +const char DEVICE_NAME[] = "mpu6050"; + +WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP +const IPAddress outIp(192, 168, 1, 11); // remote IP to receive OSC +const unsigned int outPort = 9999; // remote port to receive OSC + +// ================================================================ +// === INTERRUPT DETECTION ROUTINE === +// ================================================================ + +volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high +void ICACHE_RAM_ATTR dmpDataReady() { + mpuInterrupt = true; +} + +void mpu_setup() +{ + // join I2C bus (I2Cdev library doesn't do this automatically) +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties +#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); +#endif + + // initialize device + Serial.println(F("Initializing I2C devices...")); + mpu.initialize(); + pinMode(INTERRUPT_PIN, INPUT); + + // verify connection + Serial.println(F("Testing device connections...")); + Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); + + // load and configure the DMP + Serial.println(F("Initializing DMP...")); + devStatus = mpu.dmpInitialize(); + + // supply your own gyro offsets here, scaled for min sensitivity + mpu.setXGyroOffset(220); + mpu.setYGyroOffset(76); + mpu.setZGyroOffset(-85); + mpu.setZAccelOffset(1788); // 1688 factory default for my test chip + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + // turn on the DMP, now that it's ready + Serial.println(F("Enabling DMP...")); + mpu.setDMPEnabled(true); + + // enable Arduino interrupt detection + Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); + mpuIntStatus = mpu.getIntStatus(); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + Serial.println(F("DMP ready! Waiting for first interrupt...")); + dmpReady = true; + + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + } else { + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + Serial.print(F("DMP Initialization failed (code ")); + Serial.print(devStatus); + Serial.println(F(")")); + } +} + +void setup(void) +{ + Serial.begin(115200); + Serial.println(F("\nOrientation Sensor OSC output")); Serial.println(); + + //WiFiManager + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + //reset saved settings + //wifiManager.resetSettings(); + + //fetches ssid and pass from eeprom and tries to connect + //if it does not connect it starts an access point with the specified name + //and goes into a blocking loop awaiting configuration + wifiManager.autoConnect(DEVICE_NAME); + + Serial.print(F("WiFi connected! IP address: ")); + Serial.println(WiFi.localIP()); + + mpu_setup(); +} + +void mpu_loop() +{ + // if programming failed, don't try to do anything + if (!dmpReady) return; + + // wait for MPU interrupt or extra packet(s) available + if (!mpuInterrupt && fifoCount < packetSize) return; + + // reset interrupt flag and get INT_STATUS byte + mpuInterrupt = false; + mpuIntStatus = mpu.getIntStatus(); + + // get current FIFO count + fifoCount = mpu.getFIFOCount(); + + // check for overflow (this should never happen unless our code is too inefficient) + if ((mpuIntStatus & 0x10) || fifoCount == 1024) { + // reset so we can continue cleanly + mpu.resetFIFO(); + Serial.println(F("FIFO overflow!")); + + // otherwise, check for DMP data ready interrupt (this should happen frequently) + } else if (mpuIntStatus & 0x02) { + // wait for correct available data length, should be a VERY short wait + while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); + + // read a packet from FIFO + mpu.getFIFOBytes(fifoBuffer, packetSize); + + // track FIFO count here in case there is > 1 packet available + // (this lets us immediately read more without waiting for an interrupt) + fifoCount -= packetSize; + +#ifdef OUTPUT_READABLE_QUATERNION + // display quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); + Serial.print("quat\t"); + Serial.print(q.w); + Serial.print("\t"); + Serial.print(q.x); + Serial.print("\t"); + Serial.print(q.y); + Serial.print("\t"); + Serial.println(q.z); +#endif + +#ifdef OUTPUT_TEAPOT_OSC +#ifndef OUTPUT_READABLE_QUATERNION + // display quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); +#endif + // Send OSC message + OSCMessage msg("/imuquat"); + msg.add((float)q.w); + msg.add((float)q.x); + msg.add((float)q.y); + msg.add((float)q.z); + + Udp.beginPacket(outIp, outPort); + msg.send(Udp); + Udp.endPacket(); + + msg.empty(); +#endif + +#ifdef OUTPUT_READABLE_EULER + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetEuler(euler, &q); + Serial.print("euler\t"); + Serial.print(euler[0] * 180/M_PI); + Serial.print("\t"); + Serial.print(euler[1] * 180/M_PI); + Serial.print("\t"); + Serial.println(euler[2] * 180/M_PI); +#endif + +#ifdef OUTPUT_READABLE_YAWPITCHROLL + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + Serial.print("ypr\t"); + Serial.print(ypr[0] * 180/M_PI); + Serial.print("\t"); + Serial.print(ypr[1] * 180/M_PI); + Serial.print("\t"); + Serial.println(ypr[2] * 180/M_PI); +#endif + +#ifdef OUTPUT_READABLE_REALACCEL + // display real acceleration, adjusted to remove gravity + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + Serial.print("areal\t"); + Serial.print(aaReal.x); + Serial.print("\t"); + Serial.print(aaReal.y); + Serial.print("\t"); + Serial.println(aaReal.z); +#endif + +#ifdef OUTPUT_READABLE_WORLDACCEL + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); + Serial.print("aworld\t"); + Serial.print(aaWorld.x); + Serial.print("\t"); + Serial.print(aaWorld.y); + Serial.print("\t"); + Serial.println(aaWorld.z); +#endif + } +} + +/**************************************************************************/ +/* + Arduino loop function, called once 'setup' is complete (your own code + should go here) +*/ +/**************************************************************************/ +void loop(void) +{ + if (WiFi.status() != WL_CONNECTED) { + Serial.println(); + Serial.println("*** Disconnected from AP so rebooting ***"); + Serial.println(); + #if defined(ESP8266) + ESP.reset(); + #else + ESP.restart(); + #endif + } + + mpu_loop(); +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde b/lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde new file mode 100755 index 0000000..d7dd7f1 --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_ESPWiFi/Processing/MPUOSCTeapot/MPUOSCTeapot.pde @@ -0,0 +1,187 @@ +// I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output +// 6/20/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2012-06-20 - initial release + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +/** + * MPUOSCTeapot Processing demo for MPU6050 DMP modified for OSC + * https://gitub.com/jrowberg/i2cdevlib + * The original demo uses serial port I/O which has been replaced with + * OSC UDP messages in this sketch. + * + * The MPU6050 is connected to an ESP8266 with battery so it is completely + * wire free. + * + * Tested on Processing 3.3.5 running on Ubuntu Linux 14.04 + * + * Dependencies installed using Library Manager + * + * Open Sound Control library + * oscP5 website at http://www.sojamo.de/oscP5 + * ToxicLibs + * quaternion functions https://github.com/postspectacular/toxiclibs/ + */ + +// Install oscP5 using the IDE library manager. +// From the IDE menu bar, Sketch | Import Library | Add library. +// In the search box type "osc". +import oscP5.*; +import netP5.*; +// 1. Download from https://github.com/postspectacular/toxiclibs/releases +// 2. Extract into [userdir]/Processing/libraries +// (location may be different on Mac/Linux) +import toxi.geom.*; +import toxi.processing.*; + +ToxiclibsSupport gfx; + +Quaternion quat = new Quaternion(1, 0, 0, 0); + +OscP5 oscP5; + +void setup() { + // 300px square viewport using OpenGL rendering + size(300, 300, P3D); + gfx = new ToxiclibsSupport(this); + + // setup lights and antialiasing + lights(); + smooth(); + + /* start oscP5, listening for incoming messages at port 9999 */ + oscP5 = new OscP5(this, 9999); + + oscP5.plug(this, "imu", "/imuquat"); +} + +/* incoming osc message are forwarded to the oscEvent method. */ +void oscEvent(OscMessage theOscMessage) { + /* print the address pattern and the typetag of the received OscMessage */ + //print("### received an osc message."); + //print(" addrpattern: "+theOscMessage.addrPattern()); + //println(" typetag: "+theOscMessage.typetag()); +} + +public void imu(float quant_w, float quant_x, float quant_y, float quant_z) { + //println(quant_w, quant_x, quant_y, quant_z); + quat.set(quant_w, quant_x, quant_y, quant_z); +} + +void draw() { + // black background + background(0); + + // translate everything to the middle of the viewport + pushMatrix(); + translate(width / 2, height / 2); + + // 3-step rotation from yaw/pitch/roll angles (gimbal lock!) + // ...and other weirdness I haven't figured out yet + //rotateY(-ypr[0]); + //rotateZ(-ypr[1]); + //rotateX(-ypr[2]); + + // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!) + // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of + // different coordinate system orientation assumptions between Processing + // and InvenSense DMP) + float[] axis = quat.toAxisAngle(); + rotate(axis[0], -axis[1], axis[3], axis[2]); + + // draw main body in red + fill(255, 0, 0, 200); + box(10, 10, 200); + + // draw front-facing tip in blue + fill(0, 0, 255, 200); + pushMatrix(); + translate(0, 0, -120); + rotateX(PI/2); + drawCylinder(0, 20, 20, 8); + popMatrix(); + + // draw wings and tail fin in green + fill(0, 255, 0, 200); + beginShape(TRIANGLES); + vertex(-100, 2, 30); vertex(0, 2, -80); vertex(100, 2, 30); // wing top layer + vertex(-100, -2, 30); vertex(0, -2, -80); vertex(100, -2, 30); // wing bottom layer + vertex(-2, 0, 98); vertex(-2, -30, 98); vertex(-2, 0, 70); // tail left layer + vertex( 2, 0, 98); vertex( 2, -30, 98); vertex( 2, 0, 70); // tail right layer + endShape(); + beginShape(QUADS); + vertex(-100, 2, 30); vertex(-100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); + vertex( 100, 2, 30); vertex( 100, -2, 30); vertex( 0, -2, -80); vertex( 0, 2, -80); + vertex(-100, 2, 30); vertex(-100, -2, 30); vertex(100, -2, 30); vertex(100, 2, 30); + vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, -30, 98); vertex(-2, -30, 98); + vertex(-2, 0, 98); vertex(2, 0, 98); vertex(2, 0, 70); vertex(-2, 0, 70); + vertex(-2, -30, 98); vertex(2, -30, 98); vertex(2, 0, 70); vertex(-2, 0, 70); + endShape(); + + popMatrix(); +} + +void drawCylinder(float topRadius, float bottomRadius, float tall, int sides) { + float angle = 0; + float angleIncrement = TWO_PI / sides; + beginShape(QUAD_STRIP); + for (int i = 0; i < sides + 1; ++i) { + vertex(topRadius*cos(angle), 0, topRadius*sin(angle)); + vertex(bottomRadius*cos(angle), tall, bottomRadius*sin(angle)); + angle += angleIncrement; + } + endShape(); + + // If it is not a cone, draw the circular top cap + if (topRadius != 0) { + angle = 0; + beginShape(TRIANGLE_FAN); + + // Center point + vertex(0, 0, 0); + for (int i = 0; i < sides + 1; i++) { + vertex(topRadius * cos(angle), 0, topRadius * sin(angle)); + angle += angleIncrement; + } + endShape(); + } + + // If it is not a cone, draw the circular bottom cap + if (bottomRadius != 0) { + angle = 0; + beginShape(TRIANGLE_FAN); + + // Center point + vertex(0, tall, 0); + for (int i = 0; i < sides + 1; i++) { + vertex(bottomRadius * cos(angle), tall, bottomRadius * sin(angle)); + angle += angleIncrement; + } + endShape(); + } +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino b/lib/MPU6050/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino new file mode 100755 index 0000000..c6891f7 --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_Ethernet/MPU6050_DMP6_Ethernet.ino @@ -0,0 +1,545 @@ +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) over Ethernet +// 2/27/2016 by hellphoenix +// Based on I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) (6/21/2012 by Jeff Rowberg ) +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2016-04-18 - Eliminated a potential infinite loop +// 2016-02-28 - Cleaned up code to be in line with other example codes +// - Added Ethernet outputs for Quaternion, Euler, RealAccel, WorldAccel +// 2016-02-27 - Initial working code compiled +// Bugs: +// - There is still a hangup after some time, though it only occurs when you are reading data from the website. +// If you only read the data from the serial port, there are no hangups. +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ +#include +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include "I2Cdev.h" + +#include "MPU6050_6Axis_MotionApps20.h" +//#include "MPU6050.h" // not necessary if using MotionApps include file + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#include "Wire.h" +#include "avr/wdt.h"// Watchdog library + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 mpu; +//MPU6050 mpu(0x69); // <-- use for AD0 high + +// MAC address from Ethernet shield sticker under board +byte mac[] = { + 0x90, 0xA2, 0xDA, 0x10, 0x26, 0x82 +}; +// assign an IP address for the controller: +IPAddress ip(192,168,1,50); +// the router's gateway address: +byte gateway[] = { 192, 168, 1, 1 }; +// the subnet: +byte subnet[] = { 255, 255, 0, 0 }; + +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): +EthernetServer server(80); + +String HTTP_req; // stores the HTTP request + +/* ========================================================================= + NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch + depends on the MPU-6050's INT pin being connected to the Arduino's + external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is + digital I/O pin 2. + * ========================================================================= */ + +/* ========================================================================= + NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error + when using Serial.write(buf, len). The Teapot output uses this method. + The solution requires a modification to the Arduino USBAPI.h file, which + is fortunately simple, but annoying. This will be fixed in the next IDE + release. For more info, see these links: + + http://arduino.cc/forum/index.php/topic,109987.0.html + http://code.google.com/p/arduino/issues/detail?id=958 + * ========================================================================= */ + + +// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual +// quaternion components in a [w, x, y, z] format (not best for parsing +// on a remote host such as Processing or something though) +//#define OUTPUT_READABLE_QUATERNION + +// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles +// (in degrees) calculated from the quaternions coming from the FIFO. +// Note that Euler angles suffer from gimbal lock (for more info, see +// http://en.wikipedia.org/wiki/Gimbal_lock) +//#define OUTPUT_READABLE_EULER + +// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ +// pitch/roll angles (in degrees) calculated from the quaternions coming +// from the FIFO. Note this also requires gravity vector calculations. +// Also note that yaw/pitch/roll angles suffer from gimbal lock (for +// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) +#define OUTPUT_READABLE_YAWPITCHROLL + +// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration +// components with gravity removed. This acceleration reference frame is +// not compensated for orientation, so +X is always +X according to the +// sensor, just without the effects of gravity. If you want acceleration +// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. +//#define OUTPUT_READABLE_REALACCEL + +// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration +// components with gravity removed and adjusted for the world frame of +// reference (yaw is relative to initial orientation, since no magnetometer +// is present in this case). Could be quite handy in some cases. +//#define OUTPUT_READABLE_WORLDACCEL + +// uncomment "OUTPUT_TEAPOT" if you want output that matches the +// format used for the InvenSense teapot demo +//#define OUTPUT_TEAPOT + +#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards +#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) +bool blinkState = false; + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements +VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector +float euler[3]; // [psi, theta, phi] Euler angle container +float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector + +// packet structure for InvenSense teapot demo +uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' }; + + + +// ================================================================ +// === INTERRUPT DETECTION ROUTINE === +// ================================================================ + +volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high +void dmpDataReady() { + mpuInterrupt = true; +} +// ================================================================ +// === INITIAL SETUP === +// ================================================================ + +void setup() { + wdt_enable(WDTO_1S); //Watchdog enable. + //WDTO_1S sets the watchdog timer to 1 second. The time set here is approximate. + // You can find more time settings at http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html . + + // join I2C bus (I2Cdev library doesn't do this automatically) + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); // 400kHz I2C clock (200kHz if CPU is 8MHz). Comment this line if having compilation difficulties + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + + // initialize serial communication + // (115200 chosen because it is required for Teapot Demo output, but it's + // really up to you depending on your project) + Serial.begin(115200); + // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino + // Pro Mini running at 3.3V, cannot handle this baud rate reliably due to + // the baud timing being too misaligned with processor ticks. You must use + // 38400 or slower in these cases, or use some kind of external separate + // crystal solution for the UART timer. + + Ethernet.begin(mac, ip, gateway, subnet); + server.begin(); + Serial.print("server is at "); + Serial.println(Ethernet.localIP()); + while (!Serial); // wait for Leonardo enumeration, others continue immediately + + // initialize device + Serial.println(F("Initializing I2C devices...")); + mpu.initialize(); + pinMode(INTERRUPT_PIN, INPUT); + + // verify connection + Serial.println(F("Testing device connections...")); + Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); + + // load and configure the DMP + Serial.println(F("Initializing DMP...")); + devStatus = mpu.dmpInitialize(); + + // supply your own gyro offsets here, scaled for min sensitivity + mpu.setXGyroOffset(220); + mpu.setYGyroOffset(76); + mpu.setZGyroOffset(-85); + mpu.setZAccelOffset(1788); // 1688 factory default for my test chip + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + // turn on the DMP, now that it's ready + Serial.println(F("Enabling DMP...")); + mpu.setDMPEnabled(true); + + // enable Arduino interrupt detection + Serial.print(F("Enabling interrupt detection (Arduino external interrupt ")); + Serial.print(digitalPinToInterrupt(INTERRUPT_PIN)); + Serial.println(F(")...")); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); + mpuIntStatus = mpu.getIntStatus(); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + Serial.println(F("DMP ready! Waiting for first interrupt...")); + dmpReady = true; + + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + } else { + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + Serial.print(F("DMP Initialization failed (code ")); + Serial.print(devStatus); + Serial.println(F(")")); + } + + // configure LED for output + pinMode(LED_PIN, OUTPUT); +} + + + +// ================================================================ +// === MAIN PROGRAM LOOP === +// ================================================================ + +void loop() { + // if programming failed, don't try to do anything + if (!dmpReady) return; + + wdt_reset();//Resets the watchdog timer. If the timer is not reset, and the timer expires, a watchdog-initiated device reset will occur. + // wait for MPU interrupt or extra packet(s) available + while (!mpuInterrupt && fifoCount < packetSize) { + if (mpuInterrupt && fifoCount < packetSize) { + // try to get out of the infinite loop + fifoCount = mpu.getFIFOCount(); + } + // other program behavior stuff here + // . + // . + // if you are really paranoid you can frequently test in between other + // stuff to see if mpuInterrupt is true, and if so, "break;" from the + // while() loop to immediately process the MPU data + // . + // . + // . + } + + // reset interrupt flag and get INT_STATUS byte + mpuInterrupt = false; + mpuIntStatus = mpu.getIntStatus(); + + // get current FIFO count + fifoCount = mpu.getFIFOCount(); + + // check for overflow (this should never happen unless our code is too inefficient) + if ((mpuIntStatus & _BV(MPU6050_IMU::MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) { + // reset so we can continue cleanly + mpu.resetFIFO(); + fifoCount = mpu.getFIFOCount(); + Serial.println(F("FIFO overflow!")); + + // otherwise, check for DMP data ready interrupt (this should happen frequently) + } else if (mpuIntStatus & _BV(MPU6050_IMU::MPU6050_INTERRUPT_DMP_INT_BIT)) { + // wait for correct available data length, should be a VERY short wait + while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); + + // read a packet from FIFO, then clear the buffer + mpu.getFIFOBytes(fifoBuffer, packetSize); + //mpu.resetFIFO(); + + // track FIFO count here in case there is > 1 packet available + // (this lets us immediately read more without waiting for an interrupt) + fifoCount -= packetSize; + + #ifdef OUTPUT_READABLE_QUATERNION + // display quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); + Serial.print("quat\t"); + Serial.print(q.w); + Serial.print("\t"); + Serial.print(q.x); + Serial.print("\t"); + Serial.print(q.y); + Serial.print("\t"); + Serial.println(q.z); + #endif + #ifdef OUTPUT_READABLE_EULER + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetEuler(euler, &q); + Serial.print("euler\t"); + Serial.print(euler[0] * 180/M_PI); + Serial.print("\t"); + Serial.print(euler[1] * 180/M_PI); + Serial.print("\t"); + Serial.println(euler[2] * 180/M_PI); + #endif + #ifdef OUTPUT_READABLE_YAWPITCHROLL + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + Serial.print("ypr\t"); + Serial.print(ypr[0] * 180/M_PI); + Serial.print("\t"); + Serial.print(ypr[1] * 180/M_PI); + Serial.print("\t"); + Serial.println(ypr[2] * 180/M_PI); + #endif + #ifdef OUTPUT_READABLE_REALACCEL + // display real acceleration, adjusted to remove gravity + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + Serial.print("areal\t"); + Serial.print(aaReal.x); + Serial.print("\t"); + Serial.print(aaReal.y); + Serial.print("\t"); + Serial.println(aaReal.z); + #endif + #ifdef OUTPUT_READABLE_WORLDACCEL + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); + Serial.print("aworld\t"); + Serial.print(aaWorld.x); + Serial.print("\t"); + Serial.print(aaWorld.y); + Serial.print("\t"); + Serial.println(aaWorld.z); + #endif + #ifdef OUTPUT_TEAPOT + // display quaternion values in InvenSense Teapot demo format: + teapotPacket[2] = fifoBuffer[0]; + teapotPacket[3] = fifoBuffer[1]; + teapotPacket[4] = fifoBuffer[4]; + teapotPacket[5] = fifoBuffer[5]; + teapotPacket[6] = fifoBuffer[8]; + teapotPacket[7] = fifoBuffer[9]; + teapotPacket[8] = fifoBuffer[12]; + teapotPacket[9] = fifoBuffer[13]; + Serial.write(teapotPacket, 14); + teapotPacket[11]++; // packetCount, loops at 0xFF on purpose + #endif + serversend(); + // blink LED to indicate activity + blinkState = !blinkState; + digitalWrite(LED_PIN, blinkState); + } +} + +void serversend(){ + + EthernetClient client = server.available(); // try to get client + + if (client) { // got client? + //boolean currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { // client data available to read + char c = client.read(); // read 1 byte (character) from client + HTTP_req += c; // save the HTTP request 1 char at a time + // last line of client request is blank and ends with \n + // respond to client only after last line received + if (c == '\n') { + // send a standard http response header + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + //client.println("Connection: keep-alive"); + client.println(); + // AJAX request for switch state + if (HTTP_req.indexOf("ajax_switch") > -1) { + // read switch state and analog input + GetAjaxData(client); + } + else { // HTTP request for web page + // send web page - contains JavaScript with AJAX calls + client.println(""); + client.println(""); + client.println(""); + client.println("Arduino Web Page"); + client.println(""); + client.println(""); + client.println(""); + client.println("

MPU6050 Output

"); + client.println("
"); + client.println("
"); + client.println(""); + client.println(""); + } + // display received HTTP request on serial port + Serial.print(HTTP_req); + HTTP_req = ""; // finished with request, empty string + client.stop(); // close the connection + break; + } + } + } + } +} + +void GetAjaxData(EthernetClient cl) +{ + #ifdef OUTPUT_READABLE_QUATERNION + // display quaternion values in easy matrix form: w x y z + cl.print("Quaternion Values:\t"); + cl.print("

w:"); + cl.print(q.w); + cl.print("\t"); + cl.println("

"); + cl.print("

x:"); + cl.print(q.x); + cl.print("\t"); + cl.println("

"); + cl.print("

y:"); + cl.print(q.y); + cl.print("\t"); + cl.println("

"); + cl.print("

z:"); + cl.print(q.z); + cl.print("\t"); + cl.println("

"); + #endif + #ifdef OUTPUT_READABLE_EULER + // display Euler angles in degrees + cl.print("Euler Angles:\t"); + cl.print("

Yaw:"); + cl.print(euler[0] * 180/M_PI); + cl.print("\t"); + cl.println("

"); + cl.print("

Pitch:"); + cl.print(euler[2] * 180/M_PI); + cl.print("\t"); + cl.println("

"); + cl.print("

Roll:"); + cl.print(euler[1] * 180/M_PI); + cl.print("\t"); + cl.println("

"); + #endif + #ifdef OUTPUT_READABLE_YAWPITCHROLL + // display Yaw/Pitch/Roll values in degrees + cl.print("Yaw, Pitch, and Roll:\t"); + cl.print("

Yaw:"); + cl.print(ypr[0] * 180/M_PI); + cl.print("\t"); + cl.println("

"); + cl.print("

Pitch:"); + cl.print(ypr[2] * 180/M_PI); + cl.print("\t"); + cl.println("

"); + cl.print("

Roll:"); + cl.print(ypr[1] * 180/M_PI); + cl.print("\t"); + cl.println("

"); + #endif + #ifdef OUTPUT_READABLE_REALACCEL + // display real acceleration, adjusted to remove gravity + cl.print("Real Accel:\t"); + cl.print("

Yaw:"); + cl.print(aaReal.x); + cl.print("\t"); + cl.println("

"); + cl.print("

Pitch:"); + cl.print(aaReal.z); + cl.print("\t"); + cl.println("

"); + cl.print("

Roll:"); + cl.print(aaReal.y); + cl.print("\t"); + cl.println("

"); + #endif + #ifdef OUTPUT_READABLE_WORLDACCEL + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + cl.print("World Accel:\t"); + cl.print("

Yaw:"); + cl.print(aaWorld.x); + cl.print("\t"); + cl.println("

"); + cl.print("

Pitch:"); + cl.print(aaWorld.z); + cl.print("\t"); + cl.println("

"); + cl.print("

Roll:"); + cl.print(aaWorld.y); + cl.print("\t"); + cl.println("

"); + #endif + #ifdef OUTPUT_TEAPOT + cl.print("

teapotpacket:"); + cl.write(teapotPacket, 14); + cl.print("\t"); + cl.println("

"); + #endif +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6_ImuData_for_ROS/MPU6050_DMP6_ImuData_for_ROS.ino b/lib/MPU6050/examples/MPU6050_DMP6_ImuData_for_ROS/MPU6050_DMP6_ImuData_for_ROS.ino new file mode 100644 index 0000000..3c47e20 --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_ImuData_for_ROS/MPU6050_DMP6_ImuData_for_ROS.ino @@ -0,0 +1,122 @@ +#include "I2Cdev.h" +#include "MPU6050_6Axis_MotionApps20.h" +//#include "MPU6050.h" // not necessary if using MotionApps include file + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include "Wire.h" +#endif + +MPU6050 mpu; + +#define EARTH_GRAVITY_MS2 9.80665 // m/s2 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorInt16 gg; // [x, y, z] gyro sensor measurements +VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements +VectorInt16 ggWorld; // [x, y, z] world-frame accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector +float euler[3]; // [psi, theta, phi] Euler angle container +float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector + +void setup() { + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + + Serial.begin(115200); + + mpu.initialize(); + devStatus = mpu.dmpInitialize(); + + // supply your own gyro offsets here, scaled for min sensitivity + mpu.setXGyroOffset(-156); + mpu.setYGyroOffset(-11); + mpu.setZGyroOffset(-14); + mpu.setXAccelOffset(-3699); + mpu.setYAccelOffset(-2519); + mpu.setZAccelOffset(1391); // 1688 factory default for my test chip + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + + mpu.CalibrateAccel(6); + mpu.CalibrateGyro(6); + mpu.PrintActiveOffsets(); + mpu.setDMPEnabled(true); + + mpuIntStatus = mpu.getIntStatus(); + + dmpReady = true; + packetSize = mpu.dmpGetFIFOPacketSize(); + } +} + +void loop() { + if (!dmpReady) return; + if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet + + // display quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); + Serial.print("quat\t"); + Serial.print(q.w); + Serial.print("\t"); + Serial.print(q.x); + Serial.print("\t"); + Serial.print(q.y); + Serial.print("\t"); + Serial.println(q.z); + + mpu.dmpGetGravity(&gravity, &q); + + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpConvertToWorldFrame(&aaWorld, &aa, &q); + Serial.print("aworld\t"); + Serial.print(aaWorld.x * mpu.get_acce_resolution() * EARTH_GRAVITY_MS2); + Serial.print("\t"); + Serial.print(aaWorld.y * mpu.get_acce_resolution() * EARTH_GRAVITY_MS2); + Serial.print("\t"); + Serial.println(aaWorld.z * mpu.get_acce_resolution() * EARTH_GRAVITY_MS2); + + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + mpu.dmpGetGyro(&gg, fifoBuffer); + mpu.dmpConvertToWorldFrame(&ggWorld, &gg, &q); + Serial.print("ggWorld\t"); + Serial.print(ggWorld.x * mpu.get_gyro_resolution() * DEG_TO_RAD); + Serial.print("\t"); + Serial.print(ggWorld.y * mpu.get_gyro_resolution() * DEG_TO_RAD); + Serial.print("\t"); + Serial.println(ggWorld.z * mpu.get_gyro_resolution() * DEG_TO_RAD); + + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + Serial.print("ypr\t"); + Serial.print(ypr[0] * RAD_TO_DEG); + Serial.print("\t"); + Serial.print(ypr[1] * RAD_TO_DEG); + Serial.print("\t"); + Serial.println(ypr[2] * RAD_TO_DEG); + + Serial.println(); + + delay(100); + } +} \ No newline at end of file diff --git a/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino new file mode 100644 index 0000000..fd7ebf9 --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPU6050_DMP6_using_DMP_V6v12.ino @@ -0,0 +1,368 @@ +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v6.12) +// 6/21/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2019-07-10 - Uses the new version of the DMP Firmware V6.12 +// - Note: I believe the Teapot demo is broken with this versin as +// - the fifo buffer structure has changed +// 2016-04-18 - Eliminated a potential infinite loop +// 2013-05-08 - added seamless Fastwire support +// - added note about gyro calibration +// 2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error +// 2012-06-20 - improved FIFO overflow handling and simplified read process +// 2012-06-19 - completely rearranged DMP initialization code and simplification +// 2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly +// 2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING +// 2012-06-05 - add gravity-compensated initial reference frame acceleration output +// - add 3D math helper file to DMP6 example sketch +// - add Euler output and Yaw/Pitch/Roll output formats +// 2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee) +// 2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250 +// 2012-05-30 - basic DMP initialization working + +/* ============================================ + I2Cdev device library code is placed under the MIT license + Copyright (c) 2012 Jeff Rowberg + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + =============================================== +*/ + +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include "I2Cdev.h" + +#include "MPU6050_6Axis_MotionApps612.h" +//#include "MPU6050.h" // not necessary if using MotionApps include file + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE +#include "Wire.h" +#endif + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 mpu; +//MPU6050 mpu(0x69); // <-- use for AD0 high + +/* ========================================================================= + NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch + depends on the MPU-6050's INT pin being connected to the Arduino's + external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is + digital I/O pin 2. + ========================================================================= */ + +/* ========================================================================= + NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error + when using Serial.write(buf, len). The Teapot output uses this method. + The solution requires a modification to the Arduino USBAPI.h file, which + is fortunately simple, but annoying. This will be fixed in the next IDE + release. For more info, see these links: + + http://arduino.cc/forum/index.php/topic,109987.0.html + http://code.google.com/p/arduino/issues/detail?id=958 + ========================================================================= */ + + + +// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual +// quaternion components in a [w, x, y, z] format (not best for parsing +// on a remote host such as Processing or something though) +//#define OUTPUT_READABLE_QUATERNION + +// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles +// (in degrees) calculated from the quaternions coming from the FIFO. +// Note that Euler angles suffer from gimbal lock (for more info, see +// http://en.wikipedia.org/wiki/Gimbal_lock) +//#define OUTPUT_READABLE_EULER + +// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/ +// pitch/roll angles (in degrees) calculated from the quaternions coming +// from the FIFO. Note this also requires gravity vector calculations. +// Also note that yaw/pitch/roll angles suffer from gimbal lock (for +// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock) +#define OUTPUT_READABLE_YAWPITCHROLL + +// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration +// components with gravity removed. This acceleration reference frame is +// not compensated for orientation, so +X is always +X according to the +// sensor, just without the effects of gravity. If you want acceleration +// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead. +//#define OUTPUT_READABLE_REALACCEL + +// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration +// components with gravity removed and adjusted for the world frame of +// reference (yaw is relative to initial orientation, since no magnetometer +// is present in this case). Could be quite handy in some cases. +//#define OUTPUT_READABLE_WORLDACCEL + +// uncomment "OUTPUT_TEAPOT" if you want output that matches the +// format used for the InvenSense teapot demo +//#define OUTPUT_TEAPOT + + + +#define INTERRUPT_PIN 2 // use pin 2 on Arduino Uno & most boards +#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) +bool blinkState = false; + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorInt16 gy; // [x, y, z] gyro sensor measurements +VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements +VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector +float euler[3]; // [psi, theta, phi] Euler angle container +float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector + +// packet structure for InvenSense teapot demo +uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' }; + + + +// ================================================================ +// === INTERRUPT DETECTION ROUTINE === +// ================================================================ + +volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high +void dmpDataReady() { + mpuInterrupt = true; +} + + + +// ================================================================ +// === INITIAL SETUP === +// ================================================================ + +void setup() { + // join I2C bus (I2Cdev library doesn't do this automatically) +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties +#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); +#endif + + // initialize serial communication + // (115200 chosen because it is required for Teapot Demo output, but it's + // really up to you depending on your project) + Serial.begin(115200); + while (!Serial); // wait for Leonardo enumeration, others continue immediately + + // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3V or Arduino + // Pro Mini running at 3.3V, cannot handle this baud rate reliably due to + // the baud timing being too misaligned with processor ticks. You must use + // 38400 or slower in these cases, or use some kind of external separate + // crystal solution for the UART timer. + + // initialize device + Serial.println(F("Initializing I2C devices...")); + mpu.initialize(); + pinMode(INTERRUPT_PIN, INPUT); + + // verify connection + Serial.println(F("Testing device connections...")); + Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); + + // wait for ready + Serial.println(F("\nSend any character to begin DMP programming and demo: ")); + while (Serial.available() && Serial.read()); // empty buffer + while (!Serial.available()); // wait for data + while (Serial.available() && Serial.read()); // empty buffer again + + // load and configure the DMP + Serial.println(F("Initializing DMP...")); + devStatus = mpu.dmpInitialize(); + + // supply your own gyro offsets here, scaled for min sensitivity + mpu.setXGyroOffset(51); + mpu.setYGyroOffset(8); + mpu.setZGyroOffset(21); + mpu.setXAccelOffset(1150); + mpu.setYAccelOffset(-50); + mpu.setZAccelOffset(1060); + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + // Calibration Time: generate offsets and calibrate our MPU6050 + mpu.CalibrateAccel(6); + mpu.CalibrateGyro(6); + Serial.println(); + mpu.PrintActiveOffsets(); + // turn on the DMP, now that it's ready + Serial.println(F("Enabling DMP...")); + mpu.setDMPEnabled(true); + + // enable Arduino interrupt detection + Serial.print(F("Enabling interrupt detection (Arduino external interrupt ")); + Serial.print(digitalPinToInterrupt(INTERRUPT_PIN)); + Serial.println(F(")...")); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); + mpuIntStatus = mpu.getIntStatus(); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + Serial.println(F("DMP ready! Waiting for first interrupt...")); + dmpReady = true; + + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + } else { + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + Serial.print(F("DMP Initialization failed (code ")); + Serial.print(devStatus); + Serial.println(F(")")); + } + + // configure LED for output + pinMode(LED_PIN, OUTPUT); +} + + + +// ================================================================ +// === MAIN PROGRAM LOOP === +// ================================================================ + +void loop() { + // if programming failed, don't try to do anything + if (!dmpReady) return; + // read a packet from FIFO + if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet + +#ifdef OUTPUT_READABLE_QUATERNION + // display quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); + Serial.print("quat\t"); + Serial.print(q.w); + Serial.print("\t"); + Serial.print(q.x); + Serial.print("\t"); + Serial.print(q.y); + Serial.print("\t"); + Serial.println(q.z); +#endif + +#ifdef OUTPUT_READABLE_EULER + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetEuler(euler, &q); + Serial.print("euler\t"); + Serial.print(euler[0] * 180 / M_PI); + Serial.print("\t"); + Serial.print(euler[1] * 180 / M_PI); + Serial.print("\t"); + Serial.println(euler[2] * 180 / M_PI); +#endif + +#ifdef OUTPUT_READABLE_YAWPITCHROLL + // display Euler angles in degrees + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + Serial.print("ypr\t"); + Serial.print(ypr[0] * 180 / M_PI); + Serial.print("\t"); + Serial.print(ypr[1] * 180 / M_PI); + Serial.print("\t"); + Serial.print(ypr[2] * 180 / M_PI); + /* + mpu.dmpGetAccel(&aa, fifoBuffer); + Serial.print("\tRaw Accl XYZ\t"); + Serial.print(aa.x); + Serial.print("\t"); + Serial.print(aa.y); + Serial.print("\t"); + Serial.print(aa.z); + mpu.dmpGetGyro(&gy, fifoBuffer); + Serial.print("\tRaw Gyro XYZ\t"); + Serial.print(gy.x); + Serial.print("\t"); + Serial.print(gy.y); + Serial.print("\t"); + Serial.print(gy.z); + */ + Serial.println(); + +#endif + +#ifdef OUTPUT_READABLE_REALACCEL + // display real acceleration, adjusted to remove gravity + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + Serial.print("areal\t"); + Serial.print(aaReal.x); + Serial.print("\t"); + Serial.print(aaReal.y); + Serial.print("\t"); + Serial.println(aaReal.z); +#endif + +#ifdef OUTPUT_READABLE_WORLDACCEL + // display initial world-frame acceleration, adjusted to remove gravity + // and rotated based on known orientation from quaternion + mpu.dmpGetQuaternion(&q, fifoBuffer); + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); + Serial.print("aworld\t"); + Serial.print(aaWorld.x); + Serial.print("\t"); + Serial.print(aaWorld.y); + Serial.print("\t"); + Serial.println(aaWorld.z); +#endif + +#ifdef OUTPUT_TEAPOT + // display quaternion values in InvenSense Teapot demo format: + teapotPacket[2] = fifoBuffer[0]; + teapotPacket[3] = fifoBuffer[1]; + teapotPacket[4] = fifoBuffer[4]; + teapotPacket[5] = fifoBuffer[5]; + teapotPacket[6] = fifoBuffer[8]; + teapotPacket[7] = fifoBuffer[9]; + teapotPacket[8] = fifoBuffer[12]; + teapotPacket[9] = fifoBuffer[13]; + Serial.write(teapotPacket, 14); + teapotPacket[11]++; // packetCount, loops at 0xFF on purpose +#endif + + // blink LED to indicate activity + blinkState = !blinkState; + digitalWrite(LED_PIN, blinkState); + } +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde new file mode 100644 index 0000000..7aded8f --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/MPUplane.pde @@ -0,0 +1,189 @@ +// I2C device class (I2Cdev) demonstration Processing sketch for MPU6050 DMP output +// 6/20/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2012-06-20 - initial release +// 2016-10-28 - Changed to bi-plane 3d model based on tutorial at +// https://forum.processing.org/two/discussion/24350/display-obj-file-in-3d +// https://opengameart.org/content/low-poly-biplane + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +import processing.serial.*; +//import processing.opengl.*; +import toxi.geom.*; +import toxi.processing.*; + +// NOTE: requires ToxicLibs to be installed in order to run properly. +// 1. Download from https://github.com/postspectacular/toxiclibs/releases +// 2. Extract into [userdir]/Processing/libraries +// (location may be different on Mac/Linux) +// 3. Run and bask in awesomeness + +ToxiclibsSupport gfx; + +Serial port; // The serial port +char[] teapotPacket = new char[14]; // InvenSense Teapot packet +int serialCount = 0; // current packet byte position +int synced = 0; +int interval = 0; + +float[] q = new float[4]; +Quaternion quat = new Quaternion(1, 0, 0, 0); + +float[] gravity = new float[3]; +float[] euler = new float[3]; +float[] ypr = new float[3]; + + +PShape plane; // 3d model + +void setup() { + // 640x480 px square viewport + size(640, 480, P3D); + gfx = new ToxiclibsSupport(this); + + // setup lights and antialiasing + lights(); + smooth(); + + // display serial port list for debugging/clarity + println(Serial.list()); + + // get a specific serial port + String portName = "COM12"; + + // open the serial port + port = new Serial(this, portName, 115200); + + // send single character to trigger DMP init/start + // (expected by MPU6050_DMP6 example Arduino sketch) + port.write('r'); + + // Load Plane object + // The file must be in the \data folder + // of the current sketch to load successfully + plane = loadShape("biplane.obj"); + + + // apply its texture and set orientation + PImage img1=loadImage("diffuse_512.png"); + plane.setTexture(img1); + plane.scale(30); + plane.rotateX(PI); + plane.rotateY(PI+HALF_PI); + + +} + +void draw() { + if (millis() - interval > 1000) { + // resend single character to trigger DMP init/start + // in case the MPU is halted/reset while applet is running + port.write('r'); + interval = millis(); + } + + // black background + background(0); + + + // translate everything to the middle of the viewport + pushMatrix(); + translate(width / 2, height / 2); + + // toxiclibs direct angle/axis rotation from quaternion (NO gimbal lock!) + // (axis order [1, 3, 2] and inversion [-1, +1, +1] is a consequence of + // different coordinate system orientation assumptions between Processing + // and InvenSense DMP) + float[] axis = quat.toAxisAngle(); + rotate(axis[0], -axis[1], axis[3], axis[2]); + + // draw plane + shape(plane, 0, 0); + + popMatrix(); +} + +void serialEvent(Serial port) { + interval = millis(); + while (port.available() > 0) { + int ch = port.read(); + + if (synced == 0 && ch != '$') return; // initial synchronization - also used to resync/realign if needed + synced = 1; + print ((char)ch); + + if ((serialCount == 1 && ch != 2) + || (serialCount == 12 && ch != '\r') + || (serialCount == 13 && ch != '\n')) { + serialCount = 0; + synced = 0; + return; + } + + if (serialCount > 0 || ch == '$') { + teapotPacket[serialCount++] = (char)ch; + if (serialCount == 14) { + serialCount = 0; // restart packet byte position + + // get quaternion from data packet + q[0] = ((teapotPacket[2] << 8) | teapotPacket[3]) / 16384.0f; + q[1] = ((teapotPacket[4] << 8) | teapotPacket[5]) / 16384.0f; + q[2] = ((teapotPacket[6] << 8) | teapotPacket[7]) / 16384.0f; + q[3] = ((teapotPacket[8] << 8) | teapotPacket[9]) / 16384.0f; + for (int i = 0; i < 4; i++) if (q[i] >= 2) q[i] = -4 + q[i]; + + // set our toxilibs quaternion to new data + quat.set(q[0], q[1], q[2], q[3]); + + + // below calculations unnecessary for orientation only using toxilibs + + // calculate gravity vector + gravity[0] = 2 * (q[1]*q[3] - q[0]*q[2]); + gravity[1] = 2 * (q[0]*q[1] + q[2]*q[3]); + gravity[2] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3]; + + // calculate Euler angles + euler[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); + euler[1] = -asin(2*q[1]*q[3] + 2*q[0]*q[2]); + euler[2] = atan2(2*q[2]*q[3] - 2*q[0]*q[1], 2*q[0]*q[0] + 2*q[3]*q[3] - 1); + + // calculate yaw/pitch/roll angles + ypr[0] = atan2(2*q[1]*q[2] - 2*q[0]*q[3], 2*q[0]*q[0] + 2*q[1]*q[1] - 1); + ypr[1] = atan(gravity[0] / sqrt(gravity[1]*gravity[1] + gravity[2]*gravity[2])); + ypr[2] = atan(gravity[1] / sqrt(gravity[0]*gravity[0] + gravity[2]*gravity[2])); + + // output various components for debugging + println("q:\t" + round(q[0]*100.0f)/100.0f + "\t" + round(q[1]*100.0f)/100.0f + "\t" + round(q[2]*100.0f)/100.0f + "\t" + round(q[3]*100.0f)/100.0f); + println("euler:\t" + euler[0]*180.0f/PI + "\t" + euler[1]*180.0f/PI + "\t" + euler[2]*180.0f/PI); + println("ypr:\t" + ypr[0]*180.0f/PI + "\t" + ypr[1]*180.0f/PI + "\t" + ypr[2]*180.0f/PI); + + } + } + } +} diff --git a/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj new file mode 100644 index 0000000..6867928 --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/biplane.obj @@ -0,0 +1,2239 @@ +v 4.500000 0.176989 0.367522 +v 4.500000 0.318923 0.254332 +v 4.500000 0.397690 0.090770 +v 4.500000 0.397690 -0.090770 +v 4.500000 0.318923 -0.254333 +v 4.500000 0.176989 -0.367521 +v 4.500000 0.000000 -0.407918 +v 4.500000 -0.176989 -0.367521 +v 4.500000 -0.318923 -0.254332 +v 4.500000 -0.397691 -0.090770 +v 4.500000 -0.397691 0.090770 +v 4.500000 -0.318923 0.254333 +v 4.500001 -0.176989 0.367522 +v 4.500000 0.000000 0.407918 +v 2.700000 0.259478 0.538812 +v 2.700000 0.467563 0.372869 +v 2.700000 0.583042 0.133076 +v 2.700000 0.583042 -0.133076 +v 2.700000 0.467563 -0.372869 +v 2.700000 0.259478 -0.538812 +v 2.700000 0.000000 -0.598036 +v 2.700000 -0.259478 -0.538812 +v 2.700000 -0.467563 -0.372869 +v 2.700000 -0.583042 -0.133075 +v 2.700000 -0.583042 0.133075 +v 2.700000 -0.467563 0.372870 +v 2.700000 -0.259478 0.538812 +v 2.700000 0.000000 0.598036 +v 0.900000 0.323112 0.670950 +v 0.900000 0.582229 0.464312 +v 0.900000 0.726027 0.165711 +v 0.900000 0.726027 -0.165711 +v 0.900000 0.582229 -0.464312 +v 0.900000 0.323113 -0.670950 +v 0.900000 0.000000 -0.744698 +v 0.900000 -0.323112 -0.670950 +v 0.900000 -0.582229 -0.464312 +v 0.900000 -0.726027 -0.165711 +v 0.900000 -0.726027 0.165711 +v 0.900000 -0.582229 0.464312 +v 0.900000 -0.323113 0.670950 +v 0.900000 0.000000 0.744699 +v -0.900000 0.384390 0.798195 +v -0.900000 0.692647 0.552368 +v -0.475444 0.863717 0.197138 +v -0.475445 0.863717 -0.197138 +v -0.900000 0.692647 -0.552368 +v -0.900000 0.384390 -0.798194 +v -0.900000 0.000000 -0.885929 +v -0.900000 -0.384390 -0.798195 +v -0.900000 -0.692647 -0.552368 +v -0.900000 -0.863717 -0.197138 +v -0.900000 -0.863717 0.197138 +v -0.900000 -0.692647 0.552368 +v -0.900000 -0.384390 0.798195 +v -0.900000 0.000000 0.885929 +v -2.700000 0.433883 0.900969 +v -2.700000 0.781831 0.623490 +v -2.885778 0.974928 0.222521 +v -2.885778 0.974928 -0.222521 +v -2.700000 0.781832 -0.623490 +v -2.699999 0.433884 -0.900969 +v -2.699999 0.000000 -1.000000 +v -2.700000 -0.433883 -0.900969 +v -2.700000 -0.781831 -0.623490 +v -2.700000 -0.974928 -0.222521 +v -2.700000 -0.974928 0.222521 +v -2.700000 -0.781832 0.623489 +v -2.700000 -0.433884 0.900969 +v -2.700000 0.000000 1.000000 +v 4.500000 0.000000 -0.000000 +v -5.181942 0.000000 -0.000000 +v 5.269916 1.092397 0.090771 +v 5.269916 1.092397 -0.090770 +v 3.399458 1.972455 0.000001 +v 5.551387 0.000000 -0.000000 +v 4.141554 0.176989 1.784806 +v 4.500000 0.318923 1.235124 +v 2.700000 0.467563 1.342699 +v 3.058446 0.259478 1.802116 +v 4.500000 0.318923 -1.235123 +v 4.141554 0.176989 -1.784806 +v 3.058446 0.259478 -1.802116 +v 2.700000 0.467563 -1.342699 +v -1.300000 1.103771 0.487962 +v -1.125000 1.252653 0.195352 +v -2.475000 1.333997 0.213918 +v -2.300000 1.156989 0.519851 +v -1.125000 1.252653 -0.195351 +v -2.475000 1.333997 -0.213917 +v -1.300000 1.103772 -0.487962 +v -2.300000 1.156989 -0.519851 +v -1.799999 1.281724 0.398879 +v -1.125000 1.187470 0.380784 +v -1.800000 1.350005 0.204635 +v -2.475000 1.262618 0.416974 +v -1.800000 1.156763 0.540666 +v -1.800000 1.372766 0.000000 +v -1.125000 1.274381 0.000000 +v -1.800000 1.350006 -0.204634 +v -2.475000 1.357790 0.000000 +v -1.800000 1.281724 -0.398879 +v -1.125000 1.187470 -0.380784 +v -1.800000 1.156763 -0.540666 +v -2.475000 1.262618 -0.416974 +v -0.825593 1.004904 0.374753 +v -0.475445 0.778182 0.374753 +v -0.825593 1.069055 0.192257 +v -1.125000 0.951901 0.516854 +v -2.700000 1.105101 0.423005 +v -2.885779 0.878380 0.423006 +v -2.475000 1.021542 0.564478 +v -2.700000 1.177512 0.217012 +v -1.800000 0.963961 0.587929 +v -1.800000 0.737239 0.587929 +v -0.825593 1.090439 0.000000 +v -0.475445 0.863717 0.000000 +v -0.825593 1.069055 -0.192257 +v -2.700000 1.201650 0.000000 +v -2.885779 0.974928 0.000000 +v -2.700000 1.177513 -0.217012 +v -0.825592 1.004904 -0.374753 +v -0.475444 0.778182 -0.374753 +v -1.125000 0.951901 -0.516854 +v -1.800000 0.963961 -0.587929 +v -1.800000 0.737239 -0.587929 +v -2.475000 1.021542 -0.564478 +v -2.700000 1.105101 -0.423005 +v -2.885778 0.878380 -0.423005 +v 2.700000 0.583042 0.000000 +v 0.900000 0.726027 0.005801 +v -5.181943 -0.629401 -0.501931 +v -4.986976 -0.781831 -0.623490 +v -5.181942 -0.784850 -0.179137 +v -4.986976 -0.974928 -0.222521 +v -5.181942 -0.784850 0.179137 +v -4.986976 -0.974928 0.222521 +v -5.181942 -0.629401 0.501930 +v -4.986977 -0.781831 0.623490 +v -5.181942 -0.349291 0.725311 +v -4.986976 -0.433884 0.900969 +v -4.986976 0.000000 1.000000 +v -5.181942 0.000000 0.805034 +v -5.181942 0.629401 -0.501930 +v -4.987885 0.789991 -0.606546 +v -4.986976 0.781832 -0.623490 +v -5.181942 0.349291 -0.725310 +v -4.986977 0.433884 -0.900968 +v -4.986976 0.433884 0.900969 +v -5.181942 0.349291 0.725311 +v -4.986976 0.781831 0.623490 +v -4.987885 0.789991 0.606546 +v -5.181942 0.629401 0.501931 +v -4.986976 0.974928 0.222521 +v -5.181942 0.784301 0.179012 +v -5.181942 0.000000 -0.805034 +v -4.986976 0.000000 -1.000000 +v -5.181942 -0.349291 -0.725310 +v -4.986976 -0.433884 -0.900969 +v -5.181942 0.784301 -0.179011 +v -4.986976 0.974928 -0.222521 +v -5.181942 0.779962 0.000001 +v -4.986976 0.974928 0.000000 +vt 0.455704 0.153054 +vt 0.419776 0.128644 +vt 0.383319 0.143119 +vt 0.328896 0.143119 +vt 0.292439 0.128644 +vt 0.256511 0.153054 +vt 0.245563 0.201018 +vt 0.256511 0.248981 +vt 0.287184 0.287445 +vt 0.331509 0.308790 +vt 0.380706 0.308790 +vt 0.425031 0.287445 +vt 0.455704 0.248981 +vt 0.466652 0.201018 +vt 0.005173 0.359445 +vt 0.016095 0.354912 +vt 0.061664 0.354281 +vt 0.166522 0.327467 +vt 0.186034 0.323730 +vt 0.219371 0.310411 +vt 0.248725 0.289652 +vt 0.263886 0.273262 +vt 0.275993 0.321494 +vt 0.305445 0.321494 +vt 0.334898 0.321494 +vt 0.364351 0.321494 +vt 0.393803 0.321494 +vt 0.423256 0.321494 +vt 0.452709 0.321494 +vt 0.019054 0.449768 +vt 0.082140 0.442189 +vt 0.099276 0.445505 +vt 0.128729 0.445505 +vt 0.158182 0.445505 +vt 0.187634 0.445505 +vt 0.217087 0.445505 +vt 0.246540 0.445505 +vt 0.275993 0.445505 +vt 0.305445 0.445505 +vt 0.334898 0.445505 +vt 0.364351 0.445505 +vt 0.393803 0.445505 +vt 0.423256 0.445505 +vt 0.452709 0.445505 +vt 0.040371 0.569517 +vt 0.069824 0.569517 +vt 0.099276 0.569517 +vt 0.128729 0.569517 +vt 0.158182 0.569517 +vt 0.187634 0.569517 +vt 0.217087 0.569517 +vt 0.246540 0.569517 +vt 0.275993 0.569517 +vt 0.305445 0.569517 +vt 0.334898 0.569517 +vt 0.364351 0.569517 +vt 0.393803 0.569517 +vt 0.423256 0.569517 +vt 0.452709 0.569517 +vt 0.040371 0.693528 +vt 0.073505 0.709029 +vt 0.099276 0.685777 +vt 0.128729 0.685777 +vt 0.154500 0.709029 +vt 0.187634 0.693528 +vt 0.217087 0.693528 +vt 0.246540 0.693528 +vt 0.275993 0.693528 +vt 0.305445 0.693528 +vt 0.334898 0.693528 +vt 0.364351 0.693528 +vt 0.393803 0.693528 +vt 0.423256 0.693528 +vt 0.452709 0.693528 +vt 0.040371 0.817539 +vt 0.073505 0.802038 +vt 0.154500 0.802038 +vt 0.356107 0.180046 +vt 0.098756 0.319100 +vt 0.114003 0.445505 +vt 0.087917 0.323202 +vt 0.360587 0.109025 +vt 0.356108 0.136215 +vt 0.351628 0.109025 +vt 0.023534 0.441375 +vt 0.044323 0.425256 +vt 0.082140 0.442189 +vt 0.019054 0.449768 +vt 0.204695 0.353513 +vt 0.203181 0.378966 +vt 0.187634 0.445505 +vt 0.158182 0.445505 +vt 0.076369 0.721086 +vt 0.099276 0.709029 +vt 0.099276 0.802038 +vt 0.076369 0.789982 +vt 0.128729 0.709029 +vt 0.128729 0.802038 +vt 0.151637 0.721086 +vt 0.151637 0.789982 +vt 0.084550 0.755534 +vt 0.084550 0.709029 +vt 0.099276 0.755534 +vt 0.084550 0.802038 +vt 0.073505 0.755534 +vt 0.114003 0.755534 +vt 0.114003 0.709029 +vt 0.128729 0.755534 +vt 0.114003 0.802038 +vt 0.143455 0.755534 +vt 0.143455 0.709029 +vt 0.154500 0.755534 +vt 0.143455 0.802038 +vt 0.084550 0.693528 +vt 0.084550 0.693528 +vt 0.099276 0.693528 +vt 0.073505 0.709029 +vt 0.084550 0.817539 +vt 0.073505 0.802038 +vt 0.099276 0.817539 +vt 0.069824 0.755534 +vt 0.069824 0.755534 +vt 0.114003 0.693528 +vt 0.114003 0.693528 +vt 0.128729 0.693528 +vt 0.114003 0.817539 +vt 0.128729 0.817539 +vt 0.143455 0.693528 +vt 0.143455 0.693528 +vt 0.154500 0.709029 +vt 0.158182 0.755534 +vt 0.158182 0.755534 +vt 0.154500 0.802038 +vt 0.143455 0.817539 +vt 0.114003 0.445505 +vt 0.113487 0.569517 +vt 0.084550 0.817539 +vt 0.063450 0.938935 +vt 0.275993 0.817539 +vt 0.060733 0.120401 +vt 0.305445 0.817539 +vt 0.104650 0.099252 +vt 0.334898 0.817539 +vt 0.153395 0.099252 +vt 0.364351 0.817539 +vt 0.197313 0.120401 +vt 0.423256 0.925429 +vt 0.393803 0.817539 +vt 0.423256 0.817539 +vt 0.143455 0.817539 +vt 0.060733 0.291667 +vt 0.030341 0.253557 +vt 0.449688 0.935863 +vt 0.452709 0.817539 +vt 0.053984 0.934786 +vt 0.017895 0.932919 +vt 0.100219 0.950069 +vt 0.102123 0.931740 +vt 0.099276 0.825290 +vt 0.217087 0.817539 +vt 0.187634 0.817539 +vt 0.019494 0.206034 +vt 0.030341 0.158511 +vt 0.246540 0.817539 +vt 0.104667 0.312738 +vt 0.129023 0.201653 +vt 0.128729 0.825290 +vt 0.114003 0.817539 +vt 0.129023 0.312124 +vt 0.275993 0.931809 +vt 0.273121 0.941551 +vt 0.249411 0.941551 +vt 0.278864 0.941551 +vt 0.305445 0.931809 +vt 0.302574 0.941551 +vt 0.308316 0.941551 +vt 0.334898 0.931809 +vt 0.332027 0.941551 +vt 0.337769 0.941551 +vt 0.364351 0.931809 +vt 0.361480 0.941551 +vt 0.367222 0.941551 +vt 0.396310 0.932910 +vt 0.390932 0.941551 +vt 0.227704 0.158511 +vt 0.153378 0.312738 +vt 0.066951 0.949302 +vt 0.411698 0.969294 +vt 0.007495 0.983733 +vt 0.156937 0.931070 +vt 0.155311 0.941551 +vt 0.131609 0.941551 +vt 0.161053 0.941551 +vt 0.187634 0.931809 +vt 0.184763 0.941551 +vt 0.190506 0.941551 +vt 0.217087 0.931809 +vt 0.214216 0.941551 +vt 0.437979 0.994491 +vt 0.197313 0.291667 +vt 0.050289 0.993403 +vt 0.393883 0.992961 +vt 0.238551 0.206034 +vt 0.102156 0.941551 +vt 0.114003 0.931021 +vt 0.219958 0.941551 +vt 0.246540 0.931809 +vt 0.243669 0.941551 +vt 0.128729 0.931680 +vt 0.125850 0.941551 +vt 0.114003 0.941551 +vt 0.158299 0.939937 +vt 0.157893 0.930592 +vt 0.227704 0.253557 +vt 0.046355 0.992034 +vt 0.421247 0.969294 +vn 0.089573 0.940981 0.326392 +vn 0.089573 0.940981 0.326392 +vn 0.089573 0.940981 0.326392 +vn 0.089573 0.940981 0.326392 +vn 0.089574 0.940981 -0.326392 +vn 0.089574 0.940981 -0.326392 +vn 0.089574 0.940981 -0.326392 +vn 0.089574 0.940981 -0.326392 +vn 0.150361 -0.955640 -0.253265 +vn 0.180233 0.000001 -0.983624 +vn 0.091281 0.000000 -0.995825 +vn -0.150994 -0.690915 -0.706992 +vn 0.180233 -0.426779 -0.886214 +vn 0.091281 -0.432073 -0.897208 +vn 0.180233 -0.769028 -0.613280 +vn 0.091281 -0.778567 -0.620887 +vn 0.180233 -0.958962 -0.218877 +vn 0.091281 -0.970858 -0.221593 +vn 0.180233 -0.958962 0.218877 +vn 0.091281 -0.970858 0.221592 +vn 0.180233 -0.769028 0.613280 +vn 0.091281 -0.778567 0.620887 +vn 0.180234 -0.426778 0.886214 +vn 0.091281 -0.432072 0.897208 +vn 0.180233 -0.000000 0.983624 +vn 0.091281 0.000000 0.995825 +vn 0.150361 -0.955640 0.253265 +vn 0.016625 -0.653805 0.756481 +vn 0.079554 0.000000 -0.996831 +vn 0.079554 0.432509 -0.898113 +vn 0.079554 -0.432508 -0.898113 +vn 0.079554 -0.779353 -0.621514 +vn 0.079554 -0.971838 -0.221816 +vn 0.079554 -0.971838 0.221816 +vn 0.079554 -0.779354 0.621514 +vn 0.079554 -0.432509 0.898113 +vn 0.079554 0.000000 0.996831 +vn 0.070121 -0.432816 -0.898751 +vn 0.070121 0.000000 -0.997539 +vn 0.070121 -0.779907 -0.621955 +vn 0.070121 -0.972528 -0.221973 +vn 0.070121 -0.972528 0.221973 +vn 0.070121 -0.779907 0.621955 +vn 0.070121 -0.432816 0.898751 +vn 0.130833 0.712633 0.689229 +vn 0.130833 0.712633 0.689229 +vn 0.130833 0.712633 0.689229 +vn 0.130833 0.712633 0.689229 +vn 0.143365 0.983605 0.109401 +vn 0.143365 0.983605 0.109401 +vn 0.143365 0.983605 0.109401 +vn 0.143365 0.983605 0.109401 +vn 0.139254 0.934218 -0.328397 +vn 0.139254 0.934218 -0.328397 +vn 0.139254 0.934218 -0.328397 +vn 0.139254 0.934218 -0.328397 +vn 0.026848 -0.433727 -0.900644 +vn 0.026848 0.000000 -0.999640 +vn 0.026848 -0.781550 -0.623265 +vn 0.026848 -0.974576 -0.222441 +vn 0.026848 -0.974577 0.222441 +vn 0.026848 -0.781550 0.623265 +vn 0.026848 -0.433728 0.900644 +vn -0.064587 -0.972892 -0.222057 +vn -0.064587 -0.780199 -0.622188 +vn -0.064587 -0.972892 0.222056 +vn -0.064587 -0.780199 0.622188 +vn -0.064587 -0.432978 0.899088 +vn 0.870350 -0.485974 0.079502 +vn 1.000000 -0.000000 -0.000000 +vn 1.000000 0.000002 -0.000003 +vn 0.870349 -0.485975 -0.079503 +vn 1.000000 -0.000003 0.000000 +vn 0.733799 -0.670454 0.109683 +vn 0.733799 -0.670454 0.109683 +vn 0.082297 0.996608 0.000000 +vn 0.082297 0.996608 0.000000 +vn 0.082297 0.996608 0.000000 +vn 0.082297 0.996608 0.000000 +vn -0.842065 -0.522167 0.135162 +vn -0.842065 -0.522167 0.135162 +vn -0.842065 -0.522167 0.135162 +vn -0.842065 -0.522167 0.135162 +vn -0.057129 -0.998367 0.000000 +vn -0.057129 -0.998367 0.000000 +vn 0.733799 -0.670455 -0.109683 +vn 0.733799 -0.670455 -0.109683 +vn -0.057129 -0.998367 -0.000000 +vn -0.057129 -0.998367 -0.000000 +vn -0.045744 0.737399 -0.673906 +vn -0.842065 -0.522167 -0.135162 +vn -0.842065 -0.522167 -0.135162 +vn 0.082297 0.996608 0.000000 +vn 0.082297 0.996608 0.000000 +vn 0.082297 0.996608 0.000000 +vn 0.082297 0.996608 0.000000 +vn 0.139254 0.934218 0.328398 +vn 0.139254 0.934218 0.328398 +vn 0.139254 0.934218 0.328398 +vn 0.139254 0.934218 0.328398 +vn -0.017811 0.943260 0.331576 +vn -0.017811 0.943260 0.331576 +vn -0.017811 0.943260 0.331576 +vn -0.017811 0.943260 0.331576 +vn -0.013215 0.722929 0.690796 +vn -0.013215 0.722929 0.690796 +vn -0.013215 0.722929 0.690796 +vn -0.013215 0.722929 0.690796 +vn 0.143365 0.983605 -0.109401 +vn 0.143365 0.983605 -0.109401 +vn 0.143365 0.983605 -0.109401 +vn 0.143365 0.983605 -0.109401 +vn -0.022046 0.993630 -0.110516 +vn -0.022046 0.993630 -0.110516 +vn -0.022046 0.993630 -0.110516 +vn -0.022046 0.993630 -0.110516 +vn -0.022046 0.993630 0.110516 +vn -0.022046 0.993630 0.110516 +vn -0.022046 0.993630 0.110516 +vn -0.022046 0.993630 0.110516 +vn 0.130833 0.712634 -0.689229 +vn 0.130833 0.712634 -0.689229 +vn 0.130833 0.712634 -0.689229 +vn 0.130833 0.712634 -0.689229 +vn -0.013215 0.722930 -0.690795 +vn -0.013215 0.722930 -0.690795 +vn -0.013215 0.722930 -0.690795 +vn -0.013215 0.722930 -0.690795 +vn -0.017811 0.943260 -0.331576 +vn -0.017811 0.943260 -0.331576 +vn -0.017811 0.943260 -0.331576 +vn -0.017811 0.943260 -0.331576 +vn -0.545911 0.790429 -0.277854 +vn -0.545911 0.790429 -0.277854 +vn -0.545911 0.790429 -0.277854 +vn -0.545911 0.790429 -0.277854 +vn -0.264463 0.503333 -0.822627 +vn -0.264463 0.503333 -0.822627 +vn -0.264463 0.503333 -0.822627 +vn -0.264463 0.503333 -0.822627 +vn 0.071428 0.391121 -0.917563 +vn -0.022348 0.280539 -0.959582 +vn -0.022348 0.280539 -0.959582 +vn -0.022348 0.280539 -0.959582 +vn -0.022348 0.280539 -0.959582 +vn -0.727792 0.633269 -0.263228 +vn -0.727792 0.633269 -0.263228 +vn -0.727792 0.633269 -0.263228 +vn -0.727792 0.633270 -0.263228 +vn 0.024936 0.422951 -0.905809 +vn 0.020457 0.652869 -0.757194 +vn 0.064463 0.552835 -0.830794 +vn -0.064587 0.432978 -0.899088 +vn -0.051952 0.691351 -0.720648 +vn -0.430065 0.475818 -0.767230 +vn -0.430065 0.475818 -0.767230 +vn -0.430065 0.475818 -0.767230 +vn -0.430065 0.475818 -0.767230 +vn 0.015304 0.118231 -0.992868 +vn 0.015304 0.118231 -0.992868 +vn 0.015304 0.118231 -0.992868 +vn 0.015304 0.118231 -0.992868 +vn -0.064587 -0.432978 -0.899088 +vn -0.064587 0.000000 -0.997912 +vn -0.567759 0.818150 -0.090998 +vn -0.567759 0.818150 -0.090998 +vn -0.567759 0.818150 -0.090998 +vn -0.567759 0.818150 -0.090998 +vn -0.755415 0.654260 -0.035929 +vn -0.755415 0.654260 -0.035929 +vn -0.755415 0.654260 -0.035929 +vn -0.755415 0.654260 -0.035929 +vn 0.000000 0.900969 -0.433884 +vn -0.072505 0.898614 -0.432707 +vn -0.082933 0.960669 -0.265023 +vn 0.000000 0.964593 -0.263742 +vn -0.924988 0.164874 0.342364 +vn -0.927519 0.290707 0.234942 +vn -1.000000 -0.000000 0.000000 +vn -0.925651 0.362381 0.108856 +vn -0.924989 -0.000000 -0.379995 +vn -0.924988 -0.164873 -0.342365 +vn -0.924989 -0.297092 -0.236923 +vn -0.924989 -0.370468 -0.084556 +vn -0.924989 -0.370467 0.084557 +vn -0.924989 -0.297092 0.236923 +vn -0.924989 -0.164874 0.342363 +vn -0.924989 0.000000 0.379995 +vn -0.727792 0.633269 0.263229 +vn -0.727792 0.633269 0.263229 +vn -0.727792 0.633269 0.263229 +vn -0.727792 0.633269 0.263229 +vn -0.545911 0.790429 0.277853 +vn -0.545911 0.790429 0.277853 +vn -0.545911 0.790429 0.277853 +vn -0.545911 0.790429 0.277853 +vn -0.755415 0.654260 0.035930 +vn -0.755415 0.654260 0.035930 +vn -0.755415 0.654260 0.035930 +vn -0.755415 0.654260 0.035930 +vn -0.567759 0.818150 0.090998 +vn -0.567759 0.818150 0.090998 +vn -0.567759 0.818150 0.090998 +vn -0.567759 0.818150 0.090998 +vn -0.076076 0.997102 0.000000 +vn -0.082933 0.960669 0.265024 +vn 0.000000 0.964593 0.263742 +vn 0.000000 1.000000 0.000000 +vn -0.942446 0.334359 0.000000 +vn -0.925651 0.362381 -0.108857 +vn -0.927519 0.290707 -0.234942 +vn -0.924989 0.164874 -0.342364 +vn -0.072505 0.898614 0.432707 +vn 0.000000 0.900969 0.433884 +vn 0.070121 -0.000000 0.997539 +vn 0.026848 -0.000000 0.999640 +vn -0.064587 0.000000 0.997912 +vn 0.015304 0.118232 0.992868 +vn 0.015304 0.118232 0.992868 +vn 0.015304 0.118232 0.992868 +vn 0.015304 0.118232 0.992868 +vn -0.022348 0.280539 0.959583 +vn -0.022348 0.280539 0.959583 +vn -0.022348 0.280539 0.959583 +vn -0.022348 0.280539 0.959583 +vn -0.051952 0.691351 0.720648 +vn -0.064587 0.432978 0.899088 +vn 0.024936 0.422951 0.905809 +vn 0.020457 0.652869 0.757194 +vn -0.430065 0.475818 0.767230 +vn -0.430065 0.475818 0.767230 +vn -0.430065 0.475818 0.767230 +vn -0.430065 0.475818 0.767230 +vn -0.264462 0.503332 0.822628 +vn -0.264462 0.503332 0.822628 +vn -0.264462 0.503332 0.822628 +vn -0.264462 0.503332 0.822628 +vn 0.079554 0.432509 0.898113 +vn 0.081210 0.779249 0.621431 +vn 0.083582 0.756709 0.648386 +vn 0.090884 0.864154 0.494952 +vn 0.074379 0.588458 0.805099 +vn 0.299258 0.416890 0.858282 +vn 0.299258 0.416890 0.858282 +vn 0.299258 0.416890 0.858282 +vn 0.299258 0.416890 0.858282 +vn 0.502967 0.815394 0.286628 +vn 0.502967 0.815394 0.286628 +vn 0.502967 0.815394 0.286628 +vn 0.502967 0.815394 0.286628 +vn 0.296862 0.477629 0.826888 +vn 0.296862 0.477629 0.826888 +vn 0.296862 0.477629 0.826888 +vn 0.296862 0.477629 0.826888 +vn 0.071428 0.391121 0.917564 +vn 0.064463 0.552834 0.830794 +vn 0.070946 0.105332 0.991903 +vn 0.070946 0.105332 0.991903 +vn 0.115643 0.269922 0.955913 +vn 0.115643 0.269922 0.955913 +vn 0.115643 0.269922 0.955913 +vn 0.115643 0.269922 0.955913 +vn 0.083582 0.756710 -0.648386 +vn 0.090884 0.864154 -0.494952 +vn 0.074379 0.588458 -0.805099 +vn 0.070946 0.105332 -0.991903 +vn 0.070946 0.105332 -0.991903 +vn 0.299258 0.416891 -0.858281 +vn 0.299258 0.416891 -0.858281 +vn 0.299258 0.416891 -0.858281 +vn 0.299258 0.416891 -0.858281 +vn 0.296862 0.477628 -0.826888 +vn 0.296862 0.477628 -0.826888 +vn 0.296862 0.477628 -0.826888 +vn 0.296862 0.477628 -0.826888 +vn 0.115643 0.269922 -0.955913 +vn 0.115643 0.269922 -0.955913 +vn 0.115643 0.269922 -0.955913 +vn 0.115643 0.269922 -0.955913 +vn 0.102431 0.896230 0.431601 +vn 0.102431 0.896230 0.431601 +vn 0.102431 0.896230 0.431601 +vn 0.102431 0.896230 0.431601 +vn 0.425735 0.904848 0.000000 +vn 0.425735 0.904848 0.000000 +vn 0.425735 0.904848 0.000000 +vn 0.102431 0.896230 -0.431601 +vn 0.102431 0.896230 -0.431601 +vn 0.102431 0.896230 -0.431601 +vn 0.102431 0.896230 -0.431601 +vn 0.968371 0.249514 0.000000 +vn 0.968371 0.249514 0.000000 +vn 0.968371 0.249514 0.000000 +vn 0.004416 0.060621 -0.998151 +vn 0.004416 0.060621 -0.998151 +vn 0.004416 0.060621 -0.998151 +vn 0.004416 0.060621 -0.998151 +vn -0.893202 0.449656 0.000001 +vn -0.893202 0.449656 0.000001 +vn -0.893202 0.449656 0.000001 +vn 0.004416 0.060620 0.998151 +vn 0.004416 0.060620 0.998151 +vn 0.004416 0.060620 0.998151 +vn 0.004416 0.060620 0.998151 +vn 0.043031 -0.112813 0.992684 +vn 0.043031 -0.112813 0.992684 +vn 0.043031 -0.112813 0.992684 +vn 0.043031 -0.112813 0.992684 +vn 0.043030 -0.112812 -0.992684 +vn 0.043030 -0.112812 -0.992684 +vn 0.043030 -0.112812 -0.992684 +vn 0.043030 -0.112812 -0.992684 +vn 0.524265 0.850274 0.046693 +vn 0.524265 0.850274 0.046693 +vn 0.524265 0.850274 0.046693 +vn 0.524265 0.850274 0.046693 +vn 0.521127 0.848248 -0.094347 +vn 0.521127 0.848248 -0.094347 +vn 0.521127 0.848248 -0.094347 +vn 0.521127 0.848248 -0.094347 +vn 0.521127 0.848248 0.094347 +vn 0.521127 0.848248 0.094347 +vn 0.521127 0.848248 0.094346 +vn 0.521127 0.848248 0.094347 +vn 0.090218 0.955033 0.282440 +vn 0.080965 0.951518 0.296745 +vn 0.493255 0.803255 0.333887 +vn 0.493255 0.803255 0.333887 +vn 0.493255 0.803255 0.333887 +vn 0.493255 0.803255 0.333887 +vn 0.102044 0.959117 0.263971 +vn 0.089030 0.996029 0.000000 +vn 0.079187 0.996860 0.000000 +vn 0.080989 0.952672 -0.293015 +vn 0.090239 0.956082 -0.278863 +vn 0.102059 0.960038 -0.260596 +vn 0.099608 0.995027 -0.000000 +vn 0.493255 0.803256 -0.333886 +vn 0.493255 0.803256 -0.333886 +vn 0.493255 0.803256 -0.333886 +vn 0.493255 0.803256 -0.333886 +vn 0.524265 0.850274 -0.046693 +vn 0.524265 0.850274 -0.046693 +vn 0.524265 0.850274 -0.046693 +vn 0.524265 0.850274 -0.046693 +vn 0.502968 0.815395 -0.286627 +vn 0.502968 0.815395 -0.286627 +vn 0.502968 0.815395 -0.286627 +vn 0.502968 0.815395 -0.286627 +vn -0.893202 0.449656 0.000002 +vn -0.893202 0.449656 0.000002 +vn -0.893202 0.449656 0.000002 +s off +f 77/85/1 78/86/2 79/87/3 80/88/4 +f 81/89/5 82/90/6 83/91/7 84/92/8 +s 1 +f 6/20/9 7/21/10 21/36/11 20/35/12 +f 7/21/10 8/22/13 22/37/14 21/36/11 +f 8/22/13 9/23/15 23/38/16 22/37/14 +f 9/23/15 10/24/17 24/39/18 23/38/16 +f 10/24/17 11/25/19 25/40/20 24/39/18 +f 11/25/19 12/26/21 26/41/22 25/40/20 +f 12/26/21 13/27/23 27/42/24 26/41/22 +f 13/27/23 14/28/25 28/43/26 27/42/24 +f 14/28/25 1/29/27 15/44/28 28/43/26 +f 20/35/12 21/36/11 35/51/29 34/50/30 +f 21/36/11 22/37/14 36/52/31 35/51/29 +f 22/37/14 23/38/16 37/53/32 36/52/31 +f 23/38/16 24/39/18 38/54/33 37/53/32 +f 24/39/18 25/40/20 39/55/34 38/54/33 +f 25/40/20 26/41/22 40/56/35 39/55/34 +f 26/41/22 27/42/24 41/57/36 40/56/35 +f 27/42/24 28/43/26 42/58/37 41/57/36 +f 35/51/29 36/52/31 50/67/38 49/66/39 +f 36/52/31 37/53/32 51/68/40 50/67/38 +f 37/53/32 38/54/33 52/69/41 51/68/40 +f 38/54/33 39/55/34 53/70/42 52/69/41 +f 39/55/34 40/56/35 54/71/43 53/70/42 +f 40/56/35 41/57/36 55/72/44 54/71/43 +s off +f 97/105/45 85/93/46 94/102/47 93/101/48 +f 95/103/49 86/94/50 99/107/51 98/106/52 +f 100/108/53 89/97/54 103/111/55 102/110/56 +s 1 +f 49/66/39 50/67/38 64/164/57 63/160/58 +f 50/67/38 51/68/40 65/139/59 64/164/57 +f 51/68/40 52/69/41 66/141/60 65/139/59 +f 52/69/41 53/70/42 67/143/61 66/141/60 +f 53/70/42 54/71/43 68/145/62 67/143/61 +f 54/71/43 55/72/44 69/148/63 68/145/62 +f 65/139/59 66/141/60 135/174/64 133/170/65 +f 66/141/60 67/143/61 137/177/66 135/174/64 +f 67/143/61 68/145/62 139/180/67 137/177/66 +f 68/145/62 69/148/63 141/183/68 139/180/67 +f 2/2/69 1/1/27 71/78/70 +f 3/3/71 2/2/69 71/78/70 +f 5/5/72 4/4/73 71/78/70 +f 6/6/9 5/5/72 71/78/70 +f 7/7/10 6/6/9 71/78/70 +f 8/8/13 7/7/10 71/78/70 +f 9/9/15 8/8/13 71/78/70 +f 10/10/17 9/9/15 71/78/70 +f 11/11/19 10/10/17 71/78/70 +f 12/12/21 11/11/19 71/78/70 +f 13/13/23 12/12/21 71/78/70 +f 14/14/25 13/13/23 71/78/70 +f 1/1/27 14/14/25 71/78/70 +f 1/15/27 2/16/69 78/86/74 77/85/75 +s off +f 2/16/76 16/31/77 79/87/78 78/86/79 +f 16/31/80 15/30/81 80/88/82 79/87/83 +s 1 +f 15/30/28 1/15/27 77/85/84 80/88/85 +f 5/19/72 6/20/9 82/90/86 81/89/87 +f 6/20/9 20/35/12 83/91/88 82/90/89 +f 20/35/12 19/34/90 84/92/91 83/91/92 +s off +f 19/34/93 5/19/94 81/89/95 84/92/96 +f 94/102/97 86/94/98 95/103/99 93/101/100 +f 95/103/101 87/95/102 96/104/103 93/101/104 +f 96/104/105 88/96/106 97/105/107 93/101/108 +f 99/107/109 89/97/110 100/108/111 98/106/112 +f 100/108/113 90/98/114 101/109/115 98/106/116 +f 101/109/117 87/95/118 95/103/119 98/106/120 +f 103/111/121 91/99/122 104/112/123 102/110/124 +f 104/112/125 92/100/126 105/113/127 102/110/128 +f 105/113/129 90/98/130 100/108/131 102/110/132 +f 121/127/133 90/98/134 105/113/135 128/134/136 +f 105/113/137 92/100/138 127/133/139 128/134/140 +s 1 +f 48/65/141 34/50/30 35/51/29 49/66/39 +s off +f 125/131/142 127/133/143 92/100/144 104/112/145 +f 128/134/146 129/150/147 60/167/148 121/127/149 +s 1 +f 62/161/150 61/77/151 126/132/152 48/65/141 +f 63/160/58 62/161/150 48/65/141 49/66/39 +f 148/194/153 146/213/154 61/77/151 62/161/150 +s off +f 128/134/155 127/133/156 61/77/157 129/150/158 +f 126/132/159 61/77/160 127/133/161 125/131/162 +s 1 +f 159/207/163 157/197/164 63/160/58 64/164/57 +f 133/170/65 159/207/163 64/164/57 65/139/59 +s off +f 119/126/165 101/109/166 90/98/167 121/127/168 +f 121/127/169 60/167/170 120/168/171 119/126/172 +s 1 +f 63/160/58 157/197/164 148/194/153 62/161/150 +f 129/150/173 145/190/174 161/209/175 60/167/176 +f 150/214/177 153/200/178 72/166/179 +f 153/200/178 155/186/180 72/166/179 +f 156/162/181 158/163/182 72/166/179 +f 158/163/182 132/140/183 72/166/179 +f 132/140/183 134/142/184 72/166/179 +f 134/142/184 136/144/185 72/166/179 +f 136/144/185 138/146/186 72/166/179 +f 138/146/186 140/185/187 72/166/179 +f 140/185/187 143/203/188 72/166/179 +f 143/203/188 150/214/177 72/166/179 +s off +f 110/118/189 113/120/190 59/159/191 111/137/192 +f 96/104/193 87/95/194 113/120/195 110/118/196 +f 120/168/197 59/159/198 113/120/199 119/126/200 +f 119/126/201 113/120/202 87/95/203 101/109/204 +s 1 +f 163/205/205 154/158/206 59/159/207 120/168/208 +f 155/186/180 162/169/209 72/166/179 +f 160/165/210 144/151/211 72/166/179 +f 144/151/211 147/152/212 72/166/179 +f 147/152/212 156/162/181 72/166/179 +f 154/158/206 152/138/213 111/137/214 59/159/207 +f 161/209/175 163/205/205 120/168/208 60/167/176 +f 72/166/179 162/169/209 160/165/210 +f 55/72/44 41/57/36 42/58/37 56/73/215 +f 69/148/63 55/72/44 56/73/215 70/149/216 +f 142/147/217 141/183/68 69/148/63 70/149/216 +s off +f 112/119/218 58/76/219 115/122/220 114/121/221 +f 114/121/222 97/105/223 88/96/224 112/119/225 +s 1 +f 151/155/226 149/156/227 57/75/228 58/76/229 +f 111/137/214 152/138/213 151/155/226 58/76/229 +f 149/153/227 142/147/217 70/149/216 57/154/228 +s off +f 110/118/230 111/137/231 58/76/232 112/119/233 +f 112/119/234 88/96/235 96/104/236 110/118/237 +s 1 +f 29/45/238 15/30/28 16/31/239 30/46/240 +f 42/58/37 28/43/26 15/44/28 29/59/238 +f 30/46/240 107/115/241 44/61/242 +s off +f 106/114/243 109/117/244 44/61/245 107/115/246 +f 108/116/247 86/94/248 94/102/249 106/114/250 +f 94/102/251 85/93/252 109/117/253 106/114/254 +s 1 +f 44/61/242 43/60/255 29/45/238 30/46/240 +f 43/74/255 56/73/215 42/58/37 29/59/238 +f 115/122/256 58/76/229 57/75/228 43/60/255 +f 57/154/228 70/149/216 56/73/215 43/74/255 +f 115/122/256 44/61/242 109/117/257 114/121/258 +s off +f 114/121/259 109/117/260 85/93/261 97/105/262 +s 1 +f 115/122/256 43/60/255 44/61/242 +f 33/49/263 19/34/90 20/35/12 34/50/30 +f 123/129/264 33/49/263 47/64/265 +f 48/65/141 47/64/265 33/49/263 34/50/30 +f 124/130/266 47/64/265 126/132/152 125/131/267 +s off +f 122/128/268 123/129/269 47/64/270 124/130/271 +f 124/130/272 91/99/273 103/111/274 122/128/275 +f 125/131/276 104/112/277 91/99/278 124/130/279 +s 1 +f 48/65/141 126/132/152 47/64/265 +s off +f 16/31/280 2/16/281 3/17/282 17/32/283 +f 73/81/284 74/79/285 75/80/286 +f 18/33/287 4/18/288 5/19/289 19/34/290 +f 74/84/291 73/82/292 76/83/293 +f 4/18/294 18/33/295 75/80/296 74/79/297 +f 130/135/298 75/80/299 18/33/300 +f 75/80/301 17/32/302 3/17/303 73/81/304 +f 3/3/305 71/78/306 76/83/307 73/82/308 +f 76/83/309 71/78/310 4/4/311 74/84/312 +f 108/116/313 45/62/314 117/124/315 116/123/316 +f 116/123/317 118/125/318 89/97/319 99/107/320 +f 116/123/321 99/107/322 86/94/323 108/116/324 +s 1 +f 31/47/325 30/46/240 16/31/239 17/32/326 +s off +f 106/114/327 107/115/328 45/62/329 108/116/330 +s 1 +f 107/115/241 30/46/240 31/47/325 45/62/331 +f 131/136/332 130/135/333 18/33/334 32/48/335 +f 33/49/263 32/48/335 18/33/334 19/34/90 +f 32/48/335 46/63/336 117/124/337 131/136/332 +s off +f 122/128/338 118/125/339 46/63/340 123/129/341 +f 117/124/342 46/63/343 118/125/344 116/123/345 +f 103/111/346 89/97/347 118/125/348 122/128/349 +s 1 +f 32/48/335 33/49/263 123/129/264 46/63/336 +f 131/136/332 117/124/337 45/62/331 31/47/325 +f 130/135/333 131/136/332 31/47/325 17/32/326 +s off +f 75/80/350 130/135/351 17/32/352 +s 1 +f 146/213/154 145/190/174 129/150/173 61/77/151 +f 133/170/65 132/171/183 158/172/182 159/207/163 +f 132/173/183 133/170/65 135/174/64 134/175/184 +f 134/176/184 135/174/64 137/177/66 136/178/185 +f 136/179/185 137/177/66 139/180/67 138/181/186 +f 138/182/186 139/180/67 141/183/68 140/184/187 +f 140/202/187 141/183/68 142/147/217 143/188/188 +f 143/216/188 142/147/217 149/153/227 150/199/177 +f 145/190/174 144/191/211 160/192/210 161/209/175 +f 144/193/211 146/213/154 148/194/153 147/195/212 +f 147/196/212 148/194/153 157/197/164 156/198/181 +f 150/189/177 149/156/227 151/155/226 153/215/178 +f 153/187/178 152/138/213 154/158/206 155/157/180 +f 155/204/180 154/158/206 163/205/205 162/211/209 +f 156/206/181 157/197/164 159/207/163 158/208/182 +f 161/209/175 160/210/210 162/211/209 163/205/205 +f 144/212/211 145/190/174 146/213/154 +f 151/155/226 152/138/213 153/201/178 +v -4.526886 2.025292 -6.500000 +v -4.526886 2.025292 6.500000 +v -2.453123 1.990687 -6.229743 +v -2.453123 1.990687 6.229743 +v -4.716847 1.835833 -6.500000 +v -4.716847 1.835833 6.500000 +v -2.453123 1.835833 6.229743 +v -2.453123 1.835833 -6.229743 +v -4.526886 2.025292 5.055555 +v -2.453123 1.835833 5.055555 +v -4.853122 1.835833 5.055555 +v -4.526886 2.025292 3.611111 +v -2.453123 1.990687 3.611111 +v -2.453123 1.835833 3.611111 +v -4.853122 1.835833 3.611111 +v -4.526886 2.025292 2.166667 +v -2.453123 1.835833 2.166667 +v -4.853123 1.835833 2.166667 +v -4.526886 2.025292 0.722222 +v -2.453123 1.990687 0.722222 +v -2.453123 1.835833 0.722222 +v -4.853123 1.835833 0.722222 +v -4.526886 2.025292 -0.722222 +v -2.453123 1.990687 -0.722222 +v -2.453123 1.835833 -0.722222 +v -4.853123 1.835833 -0.722222 +v -4.526886 2.025292 -2.166667 +v -2.453123 1.835833 -2.166667 +v -4.853123 1.835833 -2.166667 +v -4.526886 2.025292 -3.611112 +v -2.453123 1.990687 -3.611112 +v -2.453123 1.835833 -3.611112 +v -4.853123 1.835833 -3.611112 +v -4.526886 2.025292 -5.055555 +v -2.453123 1.835833 -5.055556 +v -4.853123 1.835833 -5.055556 +vt 0.616150 0.306151 +vt 0.610251 0.992489 +vt 0.731520 0.325838 +vt 0.725886 0.974777 +vt 0.591047 0.313683 +vt 0.585284 0.984520 +vt 0.476020 0.976054 +vt 0.481594 0.320254 +vt 0.605471 0.315123 +vt 0.599736 0.983336 +vt 0.717845 0.974434 +vt 0.723467 0.326044 +vt 0.579649 0.910291 +vt 0.724217 0.318026 +vt 0.720447 0.913504 +vt 0.472481 0.914051 +vt 0.598060 0.909419 +vt 0.578999 0.836511 +vt 0.718456 0.982458 +vt 0.730267 0.838710 +vt 0.471391 0.837979 +vt 0.722220 0.838546 +vt 0.598433 0.836444 +vt 0.579018 0.761838 +vt 0.602520 0.389018 +vt 0.723365 0.763360 +vt 0.470415 0.761959 +vt 0.598696 0.761928 +vt 0.579544 0.686680 +vt 0.476998 0.382224 +vt 0.732302 0.688095 +vt 0.471265 0.685937 +vt 0.724215 0.688011 +vt 0.599234 0.686836 +vt 0.580196 0.611444 +vt 0.725022 0.387043 +vt 0.732967 0.612676 +vt 0.471912 0.610366 +vt 0.724881 0.612612 +vt 0.599876 0.611634 +vt 0.580951 0.536288 +vt 0.584126 0.387830 +vt 0.725344 0.537251 +vt 0.472346 0.534318 +vt 0.600626 0.536533 +vt 0.582223 0.461596 +vt 0.601648 0.461993 +vt 0.733547 0.462028 +vt 0.474637 0.458282 +vt 0.725502 0.462044 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.050020 0.997007 0.058958 +vn 0.050020 0.997007 0.058958 +vn 0.050020 0.997007 0.058958 +vn 0.050020 0.997007 0.058958 +vn -0.591510 0.805815 -0.027903 +vn -0.591510 0.805815 -0.027903 +vn -0.591510 0.805815 -0.027903 +vn -0.591510 0.805815 -0.027903 +vn 0.122841 -0.067773 0.990110 +vn 0.122841 -0.067773 0.990110 +vn 0.122841 -0.067773 0.990110 +vn 0.122841 -0.067773 0.990110 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.122841 -0.067773 -0.990110 +vn 0.122841 -0.067773 -0.990110 +vn 0.122841 -0.067773 -0.990110 +vn 0.122841 -0.067773 -0.990110 +vn 0.050020 0.997006 -0.058958 +vn 0.050020 0.997007 -0.058958 +vn 0.050020 0.997007 -0.058958 +vn 0.050020 0.997007 -0.058958 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.591512 0.805814 0.027903 +vn -0.591512 0.805814 0.027903 +vn -0.591511 0.805814 0.027903 +vn -0.591512 0.805814 0.027903 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502197 0.864753 0.000000 +vn -0.502197 0.864753 0.000000 +vn -0.502197 0.864753 0.000000 +vn -0.502197 0.864753 0.000000 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.016684 0.999861 0.000000 +vn 0.016684 0.999861 0.000000 +vn 0.016684 0.999861 0.000000 +vn 0.016684 0.999861 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +s off +f 168/225/353 171/228/354 198/252/355 199/241/356 +f 164/221/357 197/258/358 198/246/359 166/224/360 +f 164/221/361 168/225/362 199/241/363 197/258/364 +f 165/218/365 169/226/366 170/227/367 167/235/368 +f 198/252/369 171/228/370 166/219/371 +f 166/230/372 171/228/373 168/225/374 164/217/375 +f 172/229/376 165/222/377 167/223/378 173/232/379 +f 167/220/380 170/227/381 173/231/382 +f 174/233/383 173/231/384 170/227/385 169/226/386 +f 172/229/387 174/233/388 169/226/389 165/222/390 +f 175/234/391 172/229/392 173/232/393 176/237/394 +f 173/231/395 177/238/396 176/236/397 +f 178/239/398 177/238/399 173/231/400 174/233/401 +f 175/234/402 178/239/403 174/233/404 172/229/405 +f 179/240/406 175/234/407 176/237/408 180/243/409 +f 176/236/410 177/238/411 180/242/412 +f 181/244/413 180/242/414 177/238/415 178/239/416 +f 179/240/417 181/244/418 178/239/419 175/234/420 +f 182/245/421 179/240/422 180/243/423 183/248/424 +f 180/242/425 184/249/426 183/247/427 +f 185/250/428 184/249/429 180/242/430 181/244/431 +f 182/245/432 185/250/433 181/244/434 179/240/435 +f 186/251/436 182/245/437 183/248/438 187/254/439 +f 183/247/440 184/249/441 188/255/442 187/253/443 +f 189/256/444 188/255/445 184/249/446 185/250/447 +f 186/251/448 189/256/449 185/250/450 182/245/451 +f 190/257/452 186/251/453 187/254/454 191/260/455 +f 187/253/456 188/255/457 191/259/458 +f 192/261/459 191/259/460 188/255/461 189/256/462 +f 190/257/463 192/261/464 189/256/465 186/251/466 +f 193/262/467 190/257/468 191/260/469 194/265/470 +f 191/259/471 195/266/472 194/264/473 +f 196/263/474 195/266/475 191/259/476 192/261/477 +f 193/262/478 196/263/479 192/261/480 190/257/481 +f 197/258/482 193/262/483 194/265/484 198/246/485 +f 194/264/486 195/266/487 198/252/488 +f 199/241/489 198/252/490 195/266/491 196/263/492 +f 197/258/493 199/241/494 196/263/495 193/262/496 +v -3.559415 -0.491252 -6.500000 +v -3.559415 -0.491252 6.500000 +v -1.485652 -0.525856 -6.229743 +v -1.485653 -0.525856 6.229743 +v -3.749376 -0.680711 -6.500000 +v -3.749376 -0.680711 6.500000 +v -1.485653 -0.680711 6.229743 +v -1.485652 -0.680711 -6.229743 +v -3.559415 -0.491252 5.055555 +v -1.485652 -0.680711 5.055555 +v -3.885653 -0.680711 5.055555 +v -3.559415 -0.491252 3.611110 +v -1.485652 -0.525856 3.611110 +v -1.485652 -0.680711 3.611110 +v -3.885652 -0.680711 3.611110 +v -3.559415 -0.491252 2.166667 +v -1.485652 -0.680711 2.166667 +v -3.885653 -0.680711 2.166667 +v -3.559415 -0.491252 0.722222 +v -1.485652 -0.525856 0.722222 +v -1.485652 -0.680711 0.722222 +v -3.885652 -0.680711 0.722222 +v -3.559416 -0.491252 -0.722223 +v -1.485652 -0.525856 -0.722222 +v -1.485652 -0.680711 -0.722222 +v -3.885653 -0.680711 -0.722223 +v -3.559416 -0.491252 -2.166667 +v -1.485652 -0.680711 -2.166667 +v -3.885653 -0.680711 -2.166667 +v -3.559415 -0.491252 -3.611112 +v -1.485652 -0.525856 -3.611111 +v -1.485652 -0.680711 -3.611111 +v -3.885653 -0.680711 -3.611111 +v -3.559415 -0.491252 -5.055556 +v -1.485652 -0.680711 -5.055556 +v -3.885652 -0.680711 -5.055556 +vt 0.878803 0.306151 +vt 0.872904 0.992489 +vt 0.994173 0.325838 +vt 0.988539 0.974777 +vt 0.853700 0.313683 +vt 0.847937 0.984520 +vt 0.738673 0.976054 +vt 0.744247 0.320254 +vt 0.868124 0.315123 +vt 0.862389 0.983336 +vt 0.980498 0.974434 +vt 0.986120 0.326044 +vt 0.842302 0.910291 +vt 0.986870 0.318026 +vt 0.983099 0.913504 +vt 0.735134 0.914051 +vt 0.860713 0.909419 +vt 0.841652 0.836511 +vt 0.981109 0.982458 +vt 0.992920 0.838710 +vt 0.734044 0.837979 +vt 0.984873 0.838546 +vt 0.861086 0.836444 +vt 0.841671 0.761838 +vt 0.865172 0.389018 +vt 0.986018 0.763360 +vt 0.733068 0.761959 +vt 0.861349 0.761928 +vt 0.842197 0.686680 +vt 0.739650 0.382224 +vt 0.994955 0.688095 +vt 0.733917 0.685937 +vt 0.986868 0.688011 +vt 0.861887 0.686836 +vt 0.842849 0.611444 +vt 0.987675 0.387043 +vt 0.995620 0.612676 +vt 0.734565 0.610366 +vt 0.987534 0.612612 +vt 0.862529 0.611634 +vt 0.843604 0.536288 +vt 0.846779 0.387830 +vt 0.987996 0.537251 +vt 0.734999 0.534318 +vt 0.863279 0.536533 +vt 0.844876 0.461596 +vt 0.864301 0.461993 +vt 0.996200 0.462028 +vt 0.737290 0.458282 +vt 0.988155 0.462044 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.050020 0.997007 0.058959 +vn 0.050020 0.997007 0.058959 +vn 0.050020 0.997006 0.058959 +vn 0.050020 0.997007 0.058959 +vn -0.591510 0.805815 -0.027903 +vn -0.591510 0.805815 -0.027903 +vn -0.591510 0.805815 -0.027903 +vn -0.591510 0.805815 -0.027903 +vn 0.122841 -0.067773 0.990110 +vn 0.122841 -0.067773 0.990110 +vn 0.122841 -0.067773 0.990110 +vn 0.122841 -0.067773 0.990110 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.122841 -0.067772 -0.990110 +vn 0.122841 -0.067772 -0.990110 +vn 0.122841 -0.067772 -0.990110 +vn 0.122841 -0.067772 -0.990110 +vn 0.050020 0.997007 -0.058959 +vn 0.050020 0.997007 -0.058959 +vn 0.050020 0.997007 -0.058959 +vn 0.050020 0.997007 -0.058959 +vn 1.000000 0.000000 0.000001 +vn 1.000000 0.000000 0.000001 +vn 1.000000 0.000000 0.000001 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.591510 0.805815 0.027903 +vn -0.591510 0.805815 0.027903 +vn -0.591510 0.805815 0.027903 +vn -0.591510 0.805815 0.027903 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.502195 0.864754 -0.000000 +vn -0.502195 0.864754 -0.000000 +vn -0.502195 0.864754 -0.000000 +vn -0.502195 0.864754 -0.000000 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn 0.016684 0.999861 0.000000 +vn 0.016684 0.999861 0.000000 +vn 0.016684 0.999861 0.000000 +vn 0.016684 0.999861 0.000000 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn -0.502196 0.864754 0.000000 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 0.053867 0.997117 0.053449 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 0.053867 0.997117 -0.053449 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 -1.000000 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +vn -0.502196 0.864754 -0.000000 +s off +f 204/275/497 207/278/498 234/302/499 235/291/500 +f 200/271/501 233/308/502 234/296/503 202/274/504 +f 200/271/505 204/275/506 235/291/507 233/308/508 +f 201/268/509 205/276/510 206/277/511 203/285/512 +f 234/302/513 207/278/514 202/269/515 +f 202/280/516 207/278/517 204/275/518 200/267/519 +f 208/279/520 201/272/521 203/273/522 209/282/523 +f 203/270/524 206/277/525 209/281/526 +f 210/283/527 209/281/528 206/277/529 205/276/530 +f 208/279/531 210/283/532 205/276/533 201/272/534 +f 211/284/535 208/279/536 209/282/537 212/287/538 +f 209/281/539 213/288/540 212/286/541 +f 214/289/542 213/288/543 209/281/544 210/283/545 +f 211/284/546 214/289/547 210/283/548 208/279/549 +f 215/290/550 211/284/551 212/287/552 216/293/553 +f 212/286/554 213/288/555 216/292/556 +f 217/294/557 216/292/558 213/288/559 214/289/560 +f 215/290/561 217/294/562 214/289/563 211/284/564 +f 218/295/565 215/290/566 216/293/567 219/298/568 +f 216/292/569 220/299/570 219/297/571 +f 221/300/572 220/299/573 216/292/574 217/294/575 +f 218/295/576 221/300/577 217/294/578 215/290/579 +f 222/301/580 218/295/581 219/298/582 223/304/583 +f 219/297/584 220/299/585 224/305/586 223/303/587 +f 225/306/588 224/305/589 220/299/590 221/300/591 +f 222/301/592 225/306/593 221/300/594 218/295/595 +f 226/307/596 222/301/597 223/304/598 227/310/599 +f 223/303/600 224/305/601 227/309/602 +f 228/311/603 227/309/604 224/305/605 225/306/606 +f 226/307/607 228/311/608 225/306/609 222/301/610 +f 229/312/611 226/307/612 227/310/613 230/315/614 +f 227/309/615 231/316/616 230/314/617 +f 232/313/618 231/316/619 227/309/620 228/311/621 +f 229/312/622 232/313/623 228/311/624 226/307/625 +f 233/308/626 229/312/627 230/315/628 234/296/629 +f 230/314/630 231/316/631 234/302/632 +f 235/291/633 234/302/634 231/316/635 232/313/636 +f 233/308/637 235/291/638 232/313/639 229/312/640 +v -4.142218 0.492005 -0.689421 +v -4.278798 0.483220 -0.711072 +v -4.229631 0.565988 -0.611412 +v -4.039907 1.892682 -1.903144 +v -4.176487 1.883898 -1.924795 +v -4.127320 1.966665 -1.825134 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn 0.159359 -0.653124 -0.740293 +vn 0.159359 -0.653124 -0.740293 +vn 0.159359 -0.653124 -0.740293 +vn 0.159359 -0.653124 -0.740293 +vn -0.933302 0.271664 0.234831 +vn -0.933302 0.271664 0.234831 +vn -0.933302 0.271664 0.234831 +vn -0.933302 0.271664 0.234831 +vn 0.773945 0.381464 0.505464 +vn 0.773945 0.381464 0.505464 +vn 0.773945 0.381464 0.505464 +vn 0.773945 0.381464 0.505464 +s off +f 236/317/641 237/318/642 240/322/643 239/321/644 +f 237/318/645 238/319/646 241/323/647 240/322/648 +f 238/319/649 236/320/650 239/324/651 241/323/652 +v -3.239272 0.526544 -0.759048 +v -3.375609 0.514178 -0.780479 +v -3.327950 0.606955 -0.689259 +v -3.143238 1.854496 -2.131890 +v -3.279576 1.842130 -2.153321 +v -3.231915 1.934906 -2.062101 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn 0.171460 -0.714084 -0.678738 +vn 0.171460 -0.714084 -0.678738 +vn 0.171460 -0.714084 -0.678738 +vn 0.171460 -0.714084 -0.678738 +vn -0.937813 0.279982 0.205223 +vn -0.937813 0.279982 0.205223 +vn -0.937813 0.279982 0.205223 +vn -0.937813 0.279982 0.205223 +vn 0.766343 0.434134 0.473546 +vn 0.766343 0.434134 0.473546 +vn 0.766343 0.434134 0.473546 +vn 0.766343 0.434134 0.473546 +s off +f 242/325/653 243/326/654 246/330/655 245/329/656 +f 243/326/657 244/327/658 247/331/659 246/330/660 +f 244/327/661 242/328/662 245/332/663 247/331/664 +v -3.163166 -0.512404 -4.366673 +v -3.288760 -0.570938 -4.366673 +v -3.225963 -0.541671 -4.246673 +v -4.291037 1.907626 -4.366673 +v -4.416630 1.849092 -4.366673 +v -4.353833 1.878359 -4.246673 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn 0.000000 -0.000001 -1.000000 +vn 0.000000 -0.000001 -1.000000 +vn 0.000000 -0.000001 -1.000000 +vn 0.000000 -0.000001 -1.000000 +vn -0.784961 -0.365836 0.500000 +vn -0.784961 -0.365836 0.500000 +vn -0.784961 -0.365836 0.500000 +vn -0.784961 -0.365836 0.500000 +vn 0.784961 0.365837 0.500000 +vn 0.784961 0.365837 0.500000 +vn 0.784961 0.365837 0.500000 +vn 0.784961 0.365837 0.500000 +s off +f 248/333/665 249/334/666 252/338/667 251/337/668 +f 249/334/669 250/335/670 253/339/671 252/338/672 +f 250/335/673 248/336/674 251/340/675 253/339/676 +v -2.090913 -0.552991 -4.366673 +v -2.216506 -0.611525 -4.366673 +v -2.153710 -0.582258 -4.246673 +v -3.269892 1.976702 -4.366673 +v -3.395485 1.918168 -4.366673 +v -3.332688 1.947435 -4.246673 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn -0.000005 0.000000 -1.000000 +vn -0.000005 0.000000 -1.000000 +vn -0.000005 0.000000 -1.000000 +vn -0.000005 0.000000 -1.000000 +vn -0.784960 -0.365836 0.500001 +vn -0.784960 -0.365836 0.500001 +vn -0.784960 -0.365836 0.500001 +vn -0.784960 -0.365836 0.500001 +vn 0.784962 0.365835 0.499999 +vn 0.784962 0.365835 0.499999 +vn 0.784962 0.365835 0.499999 +vn 0.784962 0.365835 0.499999 +s off +f 254/341/677 255/342/678 258/346/679 257/345/680 +f 255/342/681 256/343/682 259/347/683 258/346/684 +f 256/343/685 254/344/686 257/348/687 259/347/688 +v -4.142218 0.492005 0.689421 +v -4.278798 0.483220 0.711072 +v -4.229631 0.565988 0.611412 +v -4.039907 1.892682 1.903144 +v -4.176487 1.883898 1.924795 +v -4.127320 1.966665 1.825134 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn -0.159359 0.653124 -0.740293 +vn -0.159359 0.653124 -0.740293 +vn -0.159359 0.653124 -0.740293 +vn -0.159359 0.653124 -0.740293 +vn 0.933302 -0.271664 0.234831 +vn 0.933302 -0.271664 0.234831 +vn 0.933302 -0.271664 0.234831 +vn 0.933302 -0.271664 0.234831 +vn -0.773945 -0.381464 0.505464 +vn -0.773945 -0.381464 0.505464 +vn -0.773945 -0.381464 0.505464 +vn -0.773945 -0.381464 0.505464 +s off +f 260/349/689 261/350/690 264/354/691 263/353/692 +f 261/350/693 262/351/694 265/355/695 264/354/696 +f 262/351/697 260/352/698 263/356/699 265/355/700 +v -3.239272 0.526544 0.759048 +v -3.375609 0.514178 0.780479 +v -3.327950 0.606955 0.689259 +v -3.143239 1.854496 2.131890 +v -3.279576 1.842130 2.153321 +v -3.231915 1.934906 2.062101 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn -0.171462 0.714082 -0.678739 +vn -0.171462 0.714082 -0.678739 +vn -0.171462 0.714082 -0.678739 +vn -0.171462 0.714082 -0.678739 +vn 0.937813 -0.279982 0.205223 +vn 0.937813 -0.279982 0.205223 +vn 0.937813 -0.279982 0.205223 +vn 0.937813 -0.279982 0.205223 +vn -0.766344 -0.434134 0.473546 +vn -0.766344 -0.434133 0.473546 +vn -0.766344 -0.434134 0.473546 +vn -0.766344 -0.434133 0.473546 +s off +f 266/357/701 267/358/702 270/362/703 269/361/704 +f 267/358/705 268/359/706 271/363/707 270/362/708 +f 268/359/709 266/360/710 269/364/711 271/363/712 +v -3.163167 -0.512404 4.366673 +v -3.288760 -0.570938 4.366673 +v -3.225963 -0.541671 4.246673 +v -4.291037 1.907626 4.366672 +v -4.416630 1.849092 4.366673 +v -4.353833 1.878359 4.246673 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn 0.000000 -0.000001 -1.000000 +vn 0.000000 -0.000001 -1.000000 +vn 0.000000 -0.000001 -1.000000 +vn 0.000000 -0.000001 -1.000000 +vn 0.784961 0.365836 0.500000 +vn 0.784961 0.365836 0.500000 +vn 0.784961 0.365836 0.500000 +vn 0.784961 0.365836 0.500000 +vn -0.784963 -0.365836 0.499998 +vn -0.784963 -0.365836 0.499998 +vn -0.784963 -0.365836 0.499998 +vn -0.784963 -0.365836 0.499998 +s off +f 272/365/713 273/366/714 276/370/715 275/369/716 +f 273/366/717 274/367/718 277/371/719 276/370/720 +f 274/367/721 272/368/722 275/372/723 277/371/724 +v -2.090913 -0.552991 4.366673 +v -2.216506 -0.611525 4.366673 +v -2.153710 -0.582258 4.246673 +v -3.269892 1.976702 4.366673 +v -3.395485 1.918168 4.366673 +v -3.332688 1.947435 4.246673 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn 0.000005 0.000000 -1.000000 +vn 0.000005 0.000000 -1.000000 +vn 0.000005 0.000000 -1.000000 +vn 0.000005 0.000000 -1.000000 +vn 0.784961 0.365837 0.499999 +vn 0.784961 0.365837 0.499999 +vn 0.784961 0.365837 0.499999 +vn 0.784961 0.365837 0.499999 +vn -0.784962 -0.365835 0.500000 +vn -0.784962 -0.365835 0.500000 +vn -0.784962 -0.365835 0.500000 +vn -0.784962 -0.365835 0.500000 +s off +f 278/373/725 279/374/726 282/378/727 281/377/728 +f 279/374/729 280/375/730 283/379/731 282/378/732 +f 280/375/733 278/376/734 281/380/735 283/379/736 +v -5.517155 0.803553 -1.563271 +v -5.487778 -0.252819 -0.145963 +v -5.274500 -0.974333 1.464671 +v -5.274499 0.952056 -1.477533 +v -5.487779 0.252819 0.145963 +v -5.517155 -0.781276 1.576133 +v -5.303876 0.252819 0.145963 +v -5.303876 -0.252819 -0.145963 +v -5.502548 0.333527 -0.821039 +v -5.374407 0.570041 -0.684488 +v -5.289107 0.544277 -0.699363 +v -5.417247 0.307763 -0.835914 +v -5.374407 -0.585636 0.675485 +v -5.502548 -0.320803 0.828386 +v -5.417247 -0.292169 0.844918 +v -5.289107 -0.557001 0.692017 +vt 0.751894 0.271249 +vt 0.688242 0.270269 +vt 0.624590 0.269288 +vt 0.742593 0.186217 +vt 0.689223 0.206617 +vt 0.636506 0.184582 +vt 0.690203 0.142965 +vt 0.723500 0.047977 +vt 0.691184 0.079313 +vt 0.659848 0.046996 +vt 0.692165 0.015661 +vt 0.715908 0.196417 +vt 0.720068 0.270759 +vt 0.716398 0.164591 +vt 0.707342 0.063645 +vt 0.707832 0.031819 +vt 0.662864 0.195599 +vt 0.656416 0.269778 +vt 0.663355 0.163773 +vt 0.675516 0.063154 +vt 0.676006 0.031328 +vn -0.990061 0.139469 -0.018114 +vn -0.822500 0.528726 0.209628 +vn 0.317694 0.344286 -0.883481 +vn -0.317702 0.592979 -0.739893 +vn 0.822500 -0.445906 -0.353075 +vn 0.990061 -0.054049 -0.129840 +vn -0.948960 0.273223 0.157558 +vn -0.948215 -0.273253 -0.161933 +vn -0.991413 -0.129753 0.016270 +vn -0.842918 -0.500011 -0.198694 +vn 0.260994 -0.414547 0.871799 +vn -0.260998 -0.547769 0.794877 +vn 0.948215 0.276863 0.155677 +vn 0.842917 0.422079 0.333676 +vn 0.948960 -0.273060 -0.157838 +vn 0.991413 0.050787 0.120506 +s 1 +f 292/393/737 293/392/738 287/384/739 284/381/740 +f 295/395/741 292/396/737 284/388/740 +f 294/394/742 295/395/741 284/388/740 287/384/739 +f 293/392/738 294/394/742 287/384/739 +f 288/385/743 293/392/738 292/393/737 285/382/744 +f 297/397/745 296/398/746 286/383/747 289/386/748 +f 290/387/749 294/394/742 293/392/738 288/385/743 +f 298/399/750 297/397/745 289/386/748 +f 291/389/751 295/395/741 294/394/742 290/387/749 +f 299/400/752 298/399/750 289/386/748 286/390/747 +f 285/391/744 292/396/737 295/395/741 291/389/751 +f 296/401/746 299/400/752 286/390/747 +f 296/398/746 297/397/745 288/385/743 285/382/744 +f 299/400/752 296/401/746 285/391/744 291/389/751 +f 298/399/750 299/400/752 291/389/751 290/387/749 +f 297/397/745 298/399/750 290/387/749 288/385/743 +v -4.728155 0.086603 0.050000 +v -4.728154 0.086603 -0.050000 +v -4.728155 0.000000 -0.100000 +v -4.728154 -0.086603 -0.050000 +v -4.728155 -0.086603 0.050000 +v -4.728154 0.000000 0.100000 +v -5.628155 0.086603 0.050000 +v -5.628154 0.086603 -0.050000 +v -5.628155 0.000000 -0.100000 +v -5.628154 -0.086603 -0.050000 +v -5.628155 -0.086603 0.050000 +v -5.628154 0.000000 0.100000 +v -5.628154 0.000000 -0.000000 +vt 0.988488 0.024988 +vt 0.988520 0.041334 +vt 0.988552 0.057679 +vt 0.988584 0.074025 +vt 0.988616 0.090371 +vt 0.988648 0.106717 +vt 0.988680 0.123062 +vt 0.841008 0.025277 +vt 0.841040 0.041623 +vt 0.841072 0.057968 +vt 0.841104 0.074314 +vt 0.841136 0.090659 +vt 0.841168 0.107005 +vt 0.841200 0.123351 +vt 0.830926 0.091661 +vt 0.830824 0.039274 +vt 0.785404 0.013169 +vt 0.740087 0.039452 +vt 0.740190 0.091839 +vt 0.785609 0.117943 +vt 0.787602 0.065552 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.000000 0.499997 -0.866027 +vn -0.000000 0.499997 -0.866027 +vn -0.000000 0.499997 -0.866027 +vn -0.000000 0.499997 -0.866027 +vn 0.000000 -0.499999 -0.866026 +vn 0.000000 -0.499999 -0.866026 +vn 0.000000 -0.499999 -0.866026 +vn 0.000000 -0.499999 -0.866026 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 -0.499997 0.866027 +vn 0.000000 -0.499997 0.866027 +vn 0.000000 -0.499997 0.866027 +vn 0.000000 -0.499997 0.866027 +vn 0.000000 0.499999 0.866026 +vn 0.000000 0.499999 0.866026 +vn 0.000000 0.499999 0.866026 +vn 0.000000 0.499999 0.866026 +vn -1.000000 -0.000007 -0.000005 +vn -1.000000 0.000003 -0.000002 +vn -1.000000 0.000001 -0.000002 +vn -1.000000 0.000003 0.000005 +vn -1.000000 0.000000 -0.000002 +vn -1.000000 0.000007 -0.000005 +vn -1.000000 0.000000 0.000000 +s off +f 300/402/753 301/403/754 307/410/755 306/409/756 +f 301/403/757 302/404/758 308/411/759 307/410/760 +f 302/404/761 303/405/762 309/412/763 308/411/764 +f 303/405/765 304/406/766 310/413/767 309/412/768 +f 304/406/769 305/407/770 311/414/771 310/413/772 +f 305/407/773 300/408/774 306/415/775 311/414/776 +s 1 +f 306/420/777 307/419/778 312/422/779 +f 307/419/778 308/418/780 312/422/779 +f 308/418/780 309/417/781 312/422/779 +f 309/417/781 310/416/782 312/422/779 +f 310/416/782 311/421/783 312/422/779 +f 311/421/783 306/420/777 312/422/779 +v -3.373292 -2.034549 -1.257066 +v -3.511857 -2.034549 -1.257066 +v -3.442574 -2.094549 -1.153143 +v -3.373292 -0.302498 -0.257066 +v -3.511857 -0.302498 -0.257066 +v -3.442574 -0.362498 -0.153143 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn 0.866025 0.250000 -0.433013 +vn -0.866027 0.250000 -0.433011 +vn -0.866026 0.250000 -0.433011 +vn 0.866025 0.250001 -0.433013 +vn -0.000000 -0.499999 0.866026 +vn -0.000000 -0.499999 0.866026 +s 1 +f 313/423/784 314/424/785 317/428/786 316/427/787 +f 314/424/785 315/425/788 318/429/789 317/428/786 +f 315/425/788 313/426/784 316/430/787 318/429/789 +v -3.250543 -1.665037 -1.076869 +v -3.141562 -1.815037 -1.076869 +v -3.141562 -2.000447 -1.076869 +v -3.250544 -2.150447 -1.076869 +v -3.426880 -2.207742 -1.076869 +v -3.603215 -2.150447 -1.076869 +v -3.712196 -2.000447 -1.076869 +v -3.712196 -1.815037 -1.076869 +v -3.603215 -1.665037 -1.076869 +v -3.426879 -1.607742 -1.076869 +v -3.250543 -1.665037 -1.376869 +v -3.141562 -1.815037 -1.376869 +v -3.141562 -2.000447 -1.376869 +v -3.250544 -2.150447 -1.376869 +v -3.426880 -2.207742 -1.376870 +v -3.603215 -2.150447 -1.376869 +v -3.712196 -2.000447 -1.376870 +v -3.712196 -1.815037 -1.376869 +v -3.603215 -1.665037 -1.376869 +v -3.426879 -1.607742 -1.376869 +v -3.426879 -1.907742 -1.076869 +v -3.426879 -1.907742 -1.271261 +vt 0.252891 0.122706 +vt 0.283344 0.107201 +vt 0.298868 0.076756 +vt 0.293532 0.043002 +vt 0.269375 0.018830 +vt 0.235623 0.013474 +vt 0.205170 0.028980 +vt 0.189646 0.059424 +vt 0.194982 0.093179 +vt 0.219140 0.117351 +vt 0.987153 0.141536 +vt 0.986865 0.156219 +vt 0.986578 0.170901 +vt 0.986290 0.185584 +vt 0.986003 0.200266 +vt 0.985715 0.214949 +vt 0.985428 0.229631 +vt 0.985140 0.244313 +vt 0.984853 0.258995 +vt 0.984565 0.273678 +vt 0.984278 0.288360 +vt 0.766365 0.137213 +vt 0.766077 0.151896 +vt 0.765790 0.166578 +vt 0.765503 0.181260 +vt 0.765215 0.195943 +vt 0.764927 0.210625 +vt 0.764640 0.225307 +vt 0.764352 0.239990 +vt 0.764065 0.254672 +vt 0.763777 0.269355 +vt 0.763490 0.284037 +vt 0.498215 0.317674 +vt 0.521155 0.305994 +vt 0.532848 0.283062 +vt 0.528828 0.257636 +vt 0.510632 0.239429 +vt 0.485208 0.235394 +vt 0.462269 0.247074 +vt 0.450576 0.270006 +vt 0.454595 0.295432 +vt 0.472792 0.313640 +vt 0.246228 0.069095 +vt 0.493196 0.277291 +vn 0.545745 0.751153 0.371391 +vn 0.883034 0.286915 0.371391 +vn 0.859567 0.279290 -0.427950 +vn 0.531242 0.731191 -0.427951 +vn 0.883033 -0.286916 0.371391 +vn 0.859567 -0.279291 -0.427951 +vn 0.545744 -0.751154 0.371391 +vn 0.531242 -0.731191 -0.427951 +vn -0.000000 -0.928477 0.371390 +vn -0.000000 -0.903802 -0.427952 +vn -0.545746 -0.751153 0.371391 +vn -0.531243 -0.731191 -0.427950 +vn -0.883034 -0.286914 0.371391 +vn -0.859567 -0.279289 -0.427952 +vn -0.883034 0.286915 0.371390 +vn -0.859567 0.279290 -0.427951 +vn -0.545745 0.751153 0.371391 +vn -0.531242 0.731191 -0.427951 +vn 0.000000 0.928477 0.371390 +vn 0.000000 0.903802 -0.427951 +vn -0.000000 -0.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +s 1 +f 319/441/790 320/442/791 330/453/792 329/452/793 +f 320/442/791 321/443/794 331/454/795 330/453/792 +f 321/443/794 322/444/796 332/455/797 331/454/795 +f 322/444/796 323/445/798 333/456/799 332/455/797 +f 323/445/798 324/446/800 334/457/801 333/456/799 +f 324/446/800 325/447/802 335/458/803 334/457/801 +f 325/447/802 326/448/804 336/459/805 335/458/803 +f 326/448/804 327/449/806 337/460/807 336/459/805 +f 327/449/806 328/450/808 338/461/809 337/460/807 +f 328/450/808 319/451/790 329/462/793 338/461/809 +f 320/432/791 319/431/790 339/473/810 +f 321/433/794 320/432/791 339/473/810 +f 322/434/796 321/433/794 339/473/810 +f 323/435/798 322/434/796 339/473/810 +f 324/436/800 323/435/798 339/473/810 +f 325/437/802 324/436/800 339/473/810 +f 326/438/804 325/437/802 339/473/810 +f 327/439/806 326/438/804 339/473/810 +f 328/440/808 327/439/806 339/473/810 +f 319/431/790 328/440/808 339/473/810 +f 329/471/793 330/470/792 340/474/811 +f 330/470/792 331/469/795 340/474/811 +f 331/469/795 332/468/797 340/474/811 +f 332/468/797 333/467/799 340/474/811 +f 333/467/799 334/466/801 340/474/811 +f 334/466/801 335/465/803 340/474/811 +f 335/465/803 336/464/805 340/474/811 +f 336/464/805 337/463/807 340/474/811 +f 337/463/807 338/472/809 340/474/811 +f 338/472/809 329/471/793 340/474/811 +v -3.373292 -2.034549 1.257066 +v -3.511857 -2.034549 1.257066 +v -3.442574 -2.094549 1.153143 +v -3.373292 -0.302498 0.257066 +v -3.511857 -0.302498 0.257066 +v -3.442574 -0.362498 0.153143 +vt 0.475306 0.012993 +vt 0.524059 0.012993 +vt 0.572811 0.012993 +vt 0.621564 0.012993 +vt 0.475306 0.232930 +vt 0.524059 0.232930 +vt 0.572811 0.232930 +vt 0.621564 0.232930 +vn -0.866025 -0.250000 -0.433013 +vn 0.866027 -0.249999 -0.433011 +vn 0.866026 -0.249999 -0.433011 +vn -0.866025 -0.250001 -0.433014 +vn 0.000000 0.500000 0.866025 +vn -0.000000 0.500000 0.866026 +s 1 +f 341/475/812 342/476/813 345/480/814 344/479/815 +f 342/476/813 343/477/816 346/481/817 345/480/814 +f 343/477/816 341/478/812 344/482/815 346/481/817 +v -3.250543 -1.665037 1.076869 +v -3.141562 -1.815037 1.076869 +v -3.141562 -2.000447 1.076869 +v -3.250543 -2.150447 1.076869 +v -3.426879 -2.207742 1.076869 +v -3.603214 -2.150447 1.076869 +v -3.712196 -2.000447 1.076869 +v -3.712196 -1.815037 1.076869 +v -3.603214 -1.665037 1.076869 +v -3.426879 -1.607742 1.076869 +v -3.250544 -1.665037 1.376869 +v -3.141562 -1.815037 1.376869 +v -3.141562 -2.000447 1.376869 +v -3.250544 -2.150447 1.376869 +v -3.426879 -2.207742 1.376869 +v -3.603215 -2.150447 1.376869 +v -3.712196 -2.000447 1.376869 +v -3.712196 -1.815037 1.376869 +v -3.603215 -1.665037 1.376869 +v -3.426879 -1.607742 1.376869 +v -3.426879 -1.907742 1.076869 +v -3.426879 -1.907742 1.271261 +vt 0.252891 0.122706 +vt 0.283344 0.107201 +vt 0.298868 0.076756 +vt 0.293532 0.043002 +vt 0.269375 0.018830 +vt 0.235623 0.013474 +vt 0.205170 0.028980 +vt 0.189646 0.059424 +vt 0.194982 0.093179 +vt 0.219140 0.117351 +vt 0.987153 0.141536 +vt 0.986865 0.156219 +vt 0.986578 0.170901 +vt 0.986290 0.185584 +vt 0.986003 0.200266 +vt 0.985715 0.214949 +vt 0.985428 0.229631 +vt 0.985140 0.244313 +vt 0.984853 0.258995 +vt 0.984565 0.273678 +vt 0.984278 0.288360 +vt 0.766365 0.137213 +vt 0.766077 0.151896 +vt 0.765790 0.166578 +vt 0.765503 0.181260 +vt 0.765215 0.195943 +vt 0.764927 0.210625 +vt 0.764640 0.225307 +vt 0.764352 0.239990 +vt 0.764065 0.254672 +vt 0.763777 0.269355 +vt 0.763490 0.284037 +vt 0.498215 0.317674 +vt 0.521155 0.305994 +vt 0.532848 0.283062 +vt 0.528828 0.257636 +vt 0.510632 0.239429 +vt 0.485208 0.235394 +vt 0.462269 0.247074 +vt 0.450576 0.270006 +vt 0.454595 0.295432 +vt 0.472792 0.313640 +vt 0.246228 0.069095 +vt 0.493196 0.277291 +vn -0.545745 -0.751153 0.371390 +vn -0.883034 -0.286915 0.371390 +vn -0.859567 -0.279290 -0.427951 +vn -0.531241 -0.731192 -0.427951 +vn -0.883034 0.286915 0.371390 +vn -0.859567 0.279290 -0.427952 +vn -0.545745 0.751154 0.371390 +vn -0.531240 0.731191 -0.427952 +vn 0.000000 0.928477 0.371391 +vn -0.000000 0.903802 -0.427952 +vn 0.545745 0.751153 0.371392 +vn 0.531242 0.731191 -0.427951 +vn 0.883034 0.286914 0.371391 +vn 0.859567 0.279290 -0.427951 +vn 0.883034 -0.286915 0.371391 +vn 0.859567 -0.279290 -0.427951 +vn 0.545745 -0.751154 0.371391 +vn 0.531242 -0.731191 -0.427950 +vn 0.000000 -0.928477 0.371391 +vn -0.000000 -0.903802 -0.427951 +vn -0.000000 0.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +s 1 +f 347/493/818 348/494/819 358/505/820 357/504/821 +f 348/494/819 349/495/822 359/506/823 358/505/820 +f 349/495/822 350/496/824 360/507/825 359/506/823 +f 350/496/824 351/497/826 361/508/827 360/507/825 +f 351/497/826 352/498/828 362/509/829 361/508/827 +f 352/498/828 353/499/830 363/510/831 362/509/829 +f 353/499/830 354/500/832 364/511/833 363/510/831 +f 354/500/832 355/501/834 365/512/835 364/511/833 +f 355/501/834 356/502/836 366/513/837 365/512/835 +f 356/502/836 347/503/818 357/514/821 366/513/837 +f 348/484/819 347/483/818 367/525/838 +f 349/485/822 348/484/819 367/525/838 +f 350/486/824 349/485/822 367/525/838 +f 351/487/826 350/486/824 367/525/838 +f 352/488/828 351/487/826 367/525/838 +f 353/489/830 352/488/828 367/525/838 +f 354/490/832 353/489/830 367/525/838 +f 355/491/834 354/490/832 367/525/838 +f 356/492/836 355/491/834 367/525/838 +f 347/483/818 356/492/836 367/525/838 +f 357/523/821 358/522/820 368/526/839 +f 358/522/820 359/521/823 368/526/839 +f 359/521/823 360/520/825 368/526/839 +f 360/520/825 361/519/827 368/526/839 +f 361/519/827 362/518/829 368/526/839 +f 362/518/829 363/517/831 368/526/839 +f 363/517/831 364/516/833 368/526/839 +f 364/516/833 365/515/835 368/526/839 +f 365/515/835 366/524/837 368/526/839 +f 366/524/837 357/523/821 368/526/839 +v 3.068942 -0.472892 0.150000 +v 3.068942 -0.658302 0.150000 +v 2.959961 -0.808302 0.150000 +v 2.783625 -0.865597 0.150000 +v 2.607290 -0.808302 0.150000 +v 2.498308 -0.658302 0.150000 +v 2.498308 -0.472892 0.150000 +v 3.068942 -0.472892 -0.150000 +v 3.068942 -0.658302 -0.150000 +v 2.959961 -0.808302 -0.150000 +v 2.783625 -0.865597 -0.150000 +v 2.607290 -0.808302 -0.150000 +v 2.498308 -0.658302 -0.150000 +v 2.498308 -0.472892 -0.150000 +v 2.783625 -0.565597 0.150000 +v 2.783625 -0.565597 -0.044391 +vt 0.283344 0.107201 +vt 0.298868 0.076756 +vt 0.293532 0.043002 +vt 0.269375 0.018830 +vt 0.235623 0.013474 +vt 0.205170 0.028980 +vt 0.189646 0.059424 +vt 0.986865 0.156219 +vt 0.986578 0.170901 +vt 0.986290 0.185584 +vt 0.986003 0.200266 +vt 0.985715 0.214949 +vt 0.985428 0.229631 +vt 0.985140 0.244313 +vt 0.766077 0.151896 +vt 0.765790 0.166578 +vt 0.765503 0.181260 +vt 0.765215 0.195943 +vt 0.764927 0.210625 +vt 0.764640 0.225307 +vt 0.764352 0.239990 +vt 0.521155 0.305994 +vt 0.532848 0.283062 +vt 0.528828 0.257636 +vt 0.510632 0.239429 +vt 0.485208 0.235394 +vt 0.462269 0.247074 +vt 0.450576 0.270006 +vt 0.246228 0.069095 +vt 0.493196 0.277291 +vn 0.934652 0.000000 0.355563 +vn 0.883034 -0.286915 0.371391 +vn 0.859567 -0.279290 -0.427951 +vn 0.911810 0.000000 -0.410612 +vn 0.545745 -0.751153 0.371391 +vn 0.531242 -0.731191 -0.427951 +vn -0.000000 -0.928477 0.371391 +vn -0.000000 -0.903802 -0.427951 +vn -0.545745 -0.751154 0.371391 +vn -0.531241 -0.731191 -0.427951 +vn -0.883034 -0.286915 0.371391 +vn -0.859567 -0.279291 -0.427951 +vn -0.934652 0.000000 0.355563 +vn -0.911810 0.000000 -0.410612 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.186532 -0.982449 +s 1 +f 369/534/840 370/535/841 377/542/842 376/541/843 +f 370/535/841 371/536/844 378/543/845 377/542/842 +f 371/536/844 372/537/846 379/544/847 378/543/845 +f 372/537/846 373/538/848 380/545/849 379/544/847 +f 373/538/848 374/539/850 381/546/851 380/545/849 +f 374/539/850 375/540/852 382/547/853 381/546/851 +f 370/528/841 369/527/840 383/555/854 +f 371/529/844 370/528/841 383/555/854 +f 372/530/846 371/529/844 383/555/854 +f 373/531/848 372/530/846 383/555/854 +f 374/532/850 373/531/848 383/555/854 +f 375/533/852 374/532/850 383/555/854 +f 376/554/843 377/553/842 384/556/855 +f 377/553/842 378/552/845 384/556/855 +f 378/552/845 379/551/847 384/556/855 +f 379/551/847 380/550/849 384/556/855 +f 380/550/849 381/549/851 384/556/855 +f 381/549/851 382/548/853 384/556/855 diff --git a/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/diffuse_512.png b/lib/MPU6050/examples/MPU6050_DMP6_using_DMP_V6v12/MPUplane/data/diffuse_512.png new file mode 100644 index 0000000000000000000000000000000000000000..930d910b947a7e494fc5430018e4f2dc33344fee GIT binary patch literal 361095 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

U5qFeB;E@mN(p95UK+~c+orTlU99_FAxn?B(Q{ zPRMa5q~&7^v&hM?O2qLw1)R@6RE{kL?;`SjjaDja>{9<@flsx07qvXDU6=oAZa&c* zxaxtXWf|VMXWaE+pY;ftX6+T!H6o^g@i?`rsWPk8ay&G7u8EaA9qiLdu5P?Tg%jm$ zq`BB1<=)6ax!EA}I--furM30&A08aI#&IEm!{H#c2}2(f(u_dkms@XR{+r1-a9$nO z`}%7qK5Qcm$0$7~;x%^o;_%bK-C&^+q8-P7|9$-a!r>0=wzT>D4A(mCvzMvow6OfN z-nW$St6Tt9b~|Jhdh-8;G2eomCwvg!LYAiwA-7``CE#zs17^Zw$_=_Eb$80e_AP)r zVZfB)5E&5IR!TTaAppg;9Sz{JeNYw-BN+c?&$-3!zej@k%7)skgd`ZJfacHVufgtKPNcY z6yG%hAweHNk0+lgGta=3ULjZ>y-(nvaD}z((LOzSg3G=Up%$mFr(i-GPQ8TL>>rGE z>QGIl+2ikfZWKHo=2;h#$`O*jd^>MLgY^pKPM4% zg??m7c!~U#Z#})#Fd?gchE>v9lRdc-q6ru0sWWEeRDIoRS28}osnLf)b)=#jYD1=# zP)ee!Ah@3L{ zfd=kX%2GExfTD_KvA14tr~K>E>*uEtpiCxk7&4vE8TawJmfGrgMCzviI+2~@DetbD zx2kztLra8)-<@9g>NJjx;q3Al3rA}_y;28`AnPhg2r0>TCZpp23bDFCmfd{9I_oZ0 zBXu;m_Jx+C*ohO8Nk8U8+AD^9>fz$)D3kg;Du2mwl~f2NEu{`Gp?dIv!XMfPU7>{# zcr2%hd*pufw9Tj3oyqVCoX;y;^kdCWZ0g9w`hYuj5;34KLy}BP=7+8~wOGp!_peNz zBcRw5OyBJ_NO>bhobk&Kwj+YG8M>`7gq9S42gs*#iYiyXK z$r{;wl($0fB@Fo7?l;k+yagQZo1E*L;ZqXk{*`Jgrq`U)0sxm6(-0sm%X*D`VBlIH z$T1^=JB#K=*-%2v$cO(DjQPy!^Q(~H&L#-J|9l21hAmWr{&gkA9B?3^wkFl1V_g(# zGvZ9Jpb?=PhAulMh&&cMoC8zmW}z~n*fBxvwnO^OQxyk0?2IEoyGiF;&G+RtsBqP2 z!KjU||NMk}hx4YCMH^zTuYPe85anyI9_;tn?%*2SjvHyxc~PF9gv(Jr!M=ZzUzpug z7fAEH^Rnonm7G`Wo9LCL*o$jwbsfX=XRww($c;?SsGl4ZnA3xv1I4q|SbV@XfeGNL zI=nfpFlSIO-&g1H9yh($+Gi(_{xmVjVGB+$8)BrR3zCZH&fx<+*30(Yz3*eEPa`fR zQ3w1ZzsGJb=^o5dSBknn_)fWW+H&n42FxZ5#M^y=96S}}jxyZ~0FWCM#X0M8u@H6Y zG#QG}6#IRn(|GWw$?ZG4WUC1!82TZH!+YCtQm-^JkwgkDiWq;C>=cgC!r_ra()OZ_ z2Gt1z9umlg7?B00`bDZCs_s8r9Ei2%+DIn_(zA;p3&0E3j@N)r>8qi5U3zEaNAcj< zv*6kfEnB#N^uYu!61D1om(Y!$1`cljQm(vLjvG^Bn>uAE=qoUbAWb9HDbQ3AVN&fb z`W*a7~k#%~l z)#$H^lmFca*wV0b{#EmZb`TV7E0)@}8kT9b{-MVd^sny-AUxQ$U2=hNm2U$82Tt_UpN`{o6C6Y`)GcY&LOoU{$7-%l9sYd}gD|ag=Sr0iiDw zAkEzM4BGy>U>EIT+zkId(%mLHDI`V!Wn2Q`v8QhXy6fHqEGc#0R7@W?aDmJ33-R1-JxW7#jA;Zi~H?g$}>gcZO>H zsiX7jSN1;QY(y$W$3K!D2Nb!fm!-{=JVEAy8gJK6R9t)jqz=YXufAPLFIw%!*2mVX z>?;cd@81Rcm(6i_9KH{ec=2o^BBxZEEO2W-D!w3n@VNn^;h}isFICh|c!$`;Fm6&9 zm7c$7J&-VMrx)SZ=!s+G89Q>GlOXDs64FT2Iob2zI6axdL@~vQ{z)Ose26|vFhqlK z&jhaRDiLAnkdHE*9VraB9QgsT~erFnWG<91)jesL>AYz8YzQRBi7(%kt^tEC$*xU zit!tvC#jV{hX|4o>;AOVXZ`jbd9P6ZuO4JCIcSxYHsDnLMaeF72j>!{6r*_MUJHEl z!U6K7`|DkTEHR%Eqra4C4(M@mn;rlGV-Nfo zvrjlID#tRbm&DqzrFXobb$%2~Upl4Nlpi&Cz1zx3rWfs-toLyv9LP`dQ`d*5U-T?TwBc5e*aJ%6e~MYW1!DCZ;c+`HKLX5yxo!f2{cUz=M%H-fSQ+r6MY* zuRsj!>!DZ%)~|I>LYb5q5w(H{41=!_YUrk|^ujpk-+7QOMQIX6Rq4da$J0<_O@aXR z@BI|`XGfFKz9QZaTHpI1F+4}Td;umZ3xBPtPx5p0dPMu=X=~b>drh3f5{%R`-Rt8P z^I%CF3V)Mgj#d)UKIZQ_gtkJ`W0qyUdImEn-zZsx_ji0=Dd7WswE6lB&ugM-%UWtQ ztQG5z^<3=9Sjy=Frdw1&t2g>hxjH5;LzwsMA`yHvDLkl=^iNA6=8?p49V>z-A>epl z7Xku{o5X3?FCdYjLIjE2;_DGog!s1bXC9q~D&oOU+308@lW5||y7gglZA@`XRPkg53C%Q$g zEpHL%dMfDSB?oK=Mp7AxmrxaU-;5HhGyjw3lneQGjV>gBEiJfrUUc=F3eKHTkeYk} z%NQ95hXDlwW-)G8vk-qafiAlL#uHU>AGVu{6DTX^wy15!_i zQgx4dg_m}~1(fI{c-je2s351!K=unv-t{0Sby6mW4 zD6#5W*WBUejMXE)oOIppU~Yej%;^xRiw^N23{9LMD2_OdV`9>S za{E4Za(@6+X^iTSp7nT4ix_VFYoPLRWBQ9Ux85s}c*lv?-wlYU7^%lYytC87G*be8r_W(E=&lj5?k!- zzey#H%%@p@@&taCjZ^0coD(10Hgc#N&zZ>3dMH-*oq+x;(4pbkZ@Jwf``@S_$OVq) z(w!T;Kae7v6)%_Y?ctwKyPhAscxk(shrctkZ*|KYyelZDR7IR+6VtlETJz>zfABHM z7T0lqm?1a#G(K5LK&rHVm{|$xy{2H8*7Xgyp%5CM^#LxN@pqoc&m`ahcI|h)81JdZ z`{o;4%K;;g<@|=`yc(8Qt#S>LPQrmiw)fG-IvV`7Z$~_6aoYYvl zme7hJ%R%>PUvW(Y*AG^HqUqqA#fAvWDR$TSt@FcqFZ0MbG@~!SVQ;9^gP9FaCzx?J zWg>hF$#oI6mv_>xRUN{KB7O2%J`LGiZcp&DYpIt{=`s$Si?d&+=DfdccWakl$l1pm zY?j*j_+F> zuN1_ZIs~n5{t|+2Jb+m=rKE*)0DLDIIt2zC3C~&y)X^~lZK`u*euxS!Bl`Du`yT4P=k3BK#%^(3xTEwd%qV7hlX>eG;l*tm3}|kOA$W~1=~}}K-Mhl zQF~@2HG^*3jzuD6?}F+rH6KRCi}GB%^LHhSpQU$Ra>7e!=F(*fH*%OVg|l699hCMX zm_Ra|$nl8%w*%NGrD7$3MIZj2KM7mH`JK<6n}cItw4igjapr8ggUSfbsQsPvUHoD5 z>+y8)RvpMD&-Ytzo=NOhxWk`cas8;1@-%J;Ut{~z$=HRzLx8|P+@SBapn{dL!%f*m zyjcVjXqF+E&@L|1za1Y*?P&dk-@;7)i5XUuDK)c#B+4k0T!8Bi_QRmqg-2JcN$!stivBpfnca~9 zLf{}jPkKKvFm-5GK&(#E$`1+-dHG>3hu1k!8`Uu$2f_&DJ`W7En+71*yViC&35O009wi0eJr=cX5b{})J0uW;XH|m)@?au+s05OFj!M8fQNL~ z4svj`)m~(m5%DM5y_T)vbHJ~X-ZfIG+|mf=J;KxNr#`uXK1w4iU)*NDm10cXUYc@@zyt-=N46c4E?hi01S(3MG)|TDk8Xp;Z@h#@EBK* zhiQaP1`<{KpwW5h^%l=n&Q_xk^i)TCIR#gu_=%gWXN7<2rf0pE(op0x6Fwz?vRB@+c7-Q9i%j8dmu z^UxmX3%!P0`zz^h-iu&ru#1_2~O-kt)(jlEnhln7lNHdVGAqEoCDcv#RJ$!%Hdwu=`uCa6WJoo*% z&3tLTD?=X{_WnF$A{8)h8&IdzBb(t&-tdV(^#?nQgjJ-IRYEza_cI6Y0x^Sbv@UdlC+*7vI2isoVBYP+>LddpH3kl+m|xc40B8>y;dX5Xdx zbZP&stP`F-aqLj|S*8#^otWRgq@XvZVmp`~!ZmAlKg0CDSu3EfUGh(O0R`Z=OUDu4 znKijp*R+ZL^!2cgr7C`d6UR%iXbcz>`D^eB$w? z;Q^*SY_}2#Xcp;gD5*qN5jeTsz~u5{jGnk~-%&5!ll+2BqOX6Ceri`Al*GH=fb1r@ z14DjW_vukK95Tu=typ=%C-)`}9Zhj^w!ilAjwQRzLBE1;UKiQH=*u)j4wYg&*2Gl; z3}<|a1iX@cUlh+4g?z)CV|;Q|e4&b!WCjQ8cNEDsiE}OD#;+cij80FLqxrd-O+F~o z{^G{)^qYG%F0mYvJF+Ln>s(e>&vP*HJA&xP-_q;0fFeNJ3uT3*={mscs5 zM(*%X?mQO&q-Q%hlUi~>$oxNlO`y(m^4e3|!{7O?-`|{!&#Ay;5y=<8fwyLN;=o?@ zfO3Qy>hC9Jzr(wBY{25&gLlNch;Wz%{SAcc$r1wTN|Vm|u?rIym4L-soq&rKH= z&GPTQ2Un__cG2see=C~c^*V+ky4}}G67|~e&qA>bvkK>41#;h+G5^iwVia7#fi>V- z>Hoh?g|Hv?M5v#I3=x(-)sFUOjE zP08!8ugd9o{@M;RUW+m&(Tm9-)Or7&{TlyRi`uN6aQcEp&kcQh7a@hW9Ul~Qj#~(B zUj#e(3<5;{b}xVzo#eX|u^5nw3e(BY zUfaw~{nw16Wv_k+xfia=@9^QcDw+2?QCJ1VADUyd0Bhuuf(=6B+_;MR_lRA#-zv#}oQI4eD zAHU$D18V(iS-d5XzuY>(BFfmz`Z{XFhwK8f7~(JNrhep&uAlU_@z5*?y(3 z5~}N}>s$ghU&{TxOSoYnH#YpH_Tq>5_J2ZR8!6f(v>_ixaMF0^f1PL5i+e#o$y3xE z?wP|#az*?*b`Yr3_PvlL!r;y+5R1-NjSQd57^Q5v$(y6g>WT6S6CQS6{GgaUwJU8g z-^_x({mi&5fWAAwS_OUCczO019~~ctYdCgRB;O<@cik?-es<#R<7Ugshojf#F1J^N zz~7Ss5MhD&e0JEX;P${F8e3XBFul+$33I>8FhTNnU-Tcba^9-K zzpp75G77NOqp=i)de-YH_5TEMOj12VyJk@t3G2mI!9b8t<@6opJk9tE#4juoE?Mg4 z$&a*Z33(Fpk9^{XfQeGh)uP+-*ws4GhaY#>NO1!_60F8YyJCkHax{sBkq8&U{S(1X z(!i{&`@q#bXBQvbW42C6I6C0dO;d8^j_6-_gWq<}2l=`Upp^;JEL5=8D?jC?5uWj9 zLPDu7FF6y_y@!rlfA9mXv5EA8o)Lc^c>xWy*I@EG6CCXC^!7n9dw!Hs1%z|zHtFH9 zyj&9p8xKVb{9mA3*r~Np`iL(9ALx74*x4LRApFGT&%71sFnnFW?+>I&L_j85@prDF zq;De_q3fNxrz^gV)2^q$;Wt<^V5n7qRnpfLuEEE#PjY>OVzYDUbJCBQg@_?RonbLa zIGz09St%mzEYEP_x^3aqXJI7u`u}(aOJ$g;Sghv%Fi;VuKsCfW0;B(Rkcv#OQb{92 zy;=McV#_hR0;s61n&r$$rZUr`9gckcUd=ck`(t0p%+ zo0$JMLRj7Ned`-`)@eSFqxw!r*!We;>mphE94+UQjZO(&u{m`e<$j)QKJdoc3L3-` zFEDRN!mBgy>90BEW8)zpk+2&4xyEYTy>H7JG&MeFQW-F~y=8%)8{IqRKJ0hQVq?5gri-`=CRXF7Nb}^|_s!@9S`vz1k7Z0V=*2AxC^8kLX z01;8SuyoRAg+~FEBy4$xzg{;pi)oKD7b@e1OvP=KM3Dwv2Yz`noc@Z!4O_-zbaLO; z0y2*E<&5J73Fpfm?gm`&N9oFl8EYvg44R4mjt#@MILNmBJT1P9$$EA=DHOyg^2+-0 zi8dbk?CZaokAziq25FPe-94t5fHAJqbPA%aJY%`O`q%+rtC?}38?(aXDmO*;6%S(v zdPo2qu@?MqxbiBEq;~ACIkP1%=*Ld>-7vY0v$utU@@imb>b626)Ucq)%8`_ zN8PP^bG~NL#b!i#tf2G-rKD~rfo6GGK<#=wr7A_~%8bud3*HTK0#iCnLWa#rRm)c; ziAQx8Jd|T&Zp>qlEU?h7p7lfhGIt?ns7P<3XfCxjBf2z$D3A7&a~S!j!z=yf(~D8X z%9UILdaPNPi5Y%|=Z_Z?b7i3oVA5?8k@rc2B@_84+hb))hRuTm1nOOb>)YaKg3Na3 zF!}+rUQ}(#yukZm?2cIAJ$O)Yhzam~(aR=oimq7i-$S?F zZP8A%y%hmWh^H(lhhzO-u9Uth(x8Oc|LHQST(|dgocKs;A^_V8)0Jh=6S(-6MfxJ& zR)p`bQ)D~+DejN!!hZD?ZT_9Pfurgv*6sKer9u+=%NO~3npIPU6awEHs;oKKll=Fx zeTV?!S;r5r6@<*M#@>E$d`?M0p|3b_F{cQ+($HXWd12?UdDE(CY%2`A#k?5>3Mzmm z>{cxf{o(eLHxCx*9b!9pW1+f?frM>Fsuqd$^o8B{3Rfo4Y!n@#S`+~dtViTrsdBVG zEWlf;7U#e0B0EF^;WmFs5OU~!rhfE!W#OukTqevv%6C<&?PFsY9|skL+&n>_sAf}JZk$u1=zIkKzgPdx)0d<^!^ z2&&*QRd9?b(>~YR%a7_IF%IfaX+%m5QQ&pC;CyUOztt&Ta?tm0SSGOT{y0eFb5hdj zjZ>V3+MirwoKChos@xDAkir4AZ}yGy3Tb3fDA>ys#VR(eoV!~2=}463#Au@j*bR=f zf-;MI^4(8H@B*~5zp{hI-JYzAKpx~s%VM+1UwwV&HgE8^4vFvQvW}IdV{5+2<)}a- zr+K>>f#die=UGw1H#syTVk#@eqb5yq=U|r>39n>st$&9Sh;vkfBAWr)g zq(TX7YtN^3Y8id!(|nCK0Hn&8PhZ8L-oQct+R8ktt|H;D6WgFfd-knG@>6J)4jiUf z!dsQ0ntHsD+?dwnZc4_gy_D0mvgLEH=03N%Lt7-rz>>xA5+FhMG0g|6+TZPqi!(9L z7)%XH&k|~lCdNf*|46(DTNVxu)kgZ|Pe)I^N zfh8rCP+%cvBB}tL6HNCcq?z^RnW9#-$nx~U5CtG=U+}bF#GEnkXz8W~c;b7-5>?a$ zZZ;9uzuS7>g!nUXZ5_?nUv8EmuaDU(Xo6?l0CNkrV5=4M5%mDb zC-D=7o|v54l?@p-St{nJIN*hDu-mbgz~kA!B*BS1Y2J(8lqy0=yFCd6+w58qp~PHc zh@09yI^C~I1IPj0H)0=}zU^+=ot9dBBu3b}U}lUlA-SxlZ@$b{JB=$2uXv7aO~kmr z=yl?M>6}ngE;In%#e9Cc`JkyzQ_J{J8Wq}5}PD_ z^Bk|$irTlb?GLD_8SL5C%b8X%h3}2 z&bx#hyAd}{t)tI7VEw|)3kXE$c2DYjco{{5GbPzj%D3KRb^uQJ7)>(fK_Tyte+ynajZr%(7gbNhJzNK)y}<7q@`+he<^92Q zVP;-lB@`b+$iT5O;BcOyN$^4*6hIJSn0A?1cvH$eH^Zh_6&or6xr=OGTaY zdCbbR9! zpZ+{pM5ImW=X{{RjrvV3d7W?kry)dpNJn^xy4lucK6hk9i_(XPqQM+@W9n`IZa3kj zRywQ-Ag*G|ak>nsB4P3vam`KpXng7C8#DrBEWE>I#mQWKM!juY@bR{4(f4no1ZKAO z2dY3N*WBv`Gq={UJC5+84u-_pxulws1g|h$E@inZIGe%7q|n< zLBuU$1Q&K({2Gi#nL7yjn3cx`=>iA`mhaR)*|it*?8CcfQWuvLAfS88?(`Gz*b#TE z;kds|q;Pm}?uQmc^_Cm56w~F4wYSN4$7RDapRx+PAIOF$Zxv6#-cF|StYq>SLb>1e z9XI!!yY;Rn_Z@c_rh?!MFIgXIbFB5&Z ze=$)EPx0)^E6cEAjZy2%r$Fdx(<26M^!e#;7<3Y59!eIA*o>wvv5S7oP|SsGRQqkP z&^`Aq{~@GX3f}8C*rCCk|GU4t;ST8&#h#CwMOB{`-2VR7OnE~piFzwk4pOi6BIzCM z&-#hhxqYJ8d_Gg@&sCF!PdrRYp06}vCmW4|@hV;6yc)VsF>*66^7-m;O0K96lu%u+i*k_9g zm;Tu$STX$iQ%LAcaOE(EQ%g2dMLJYPjo@fq9x9R5;P!*FFe&zJ@^X<317i}XJ#u{C zl_TcSktM=2tFou*pE0>y*I;RHFk+_`k`+!&dYlL~SgoF)QF4Kz@Ca^l_y-0qUy(Zm zji8qTVk9PXH1OFn!W{F>>HX+i2%krR4kiGUAO2x+GUplDN9iGJ-VeOYtf=33`kDU$ z?Wbs!_Cdv3>;~T8bsUVa>aK15cy6;b^wzW#sfMC(FuBSwtlk%!2au4Tt8w%PM1|)b zt7^BME!II(;PAim%3CB#;QUCz>#&7EJRCz(p>6iVmERDv$S^Z{>ctmXj4Rz;oiPs= z!L%fr8v1%+Qs7A_`rGrV?oEz(DXazxIr?&W*hj5jaH(8=uBMdj*D~%<^&7qgCamCi zU{{Q>R+Q28`ns8&z>p=Q@4|*5?GeLlTs`L&9Ic=%54YLJpn98wY(<`bB^3e3vj$7` z$RNZf#9^%#=_hiD(zSyhgQmrmLtW1kBlDcHwCBEsAqTA5QF(pGAEK&>w_Z0Hykw?I zKR}Oi_Mdic_xbj?X{x2O@*oL(SUIYDZkD&-#B6}ljA?p|A2{Hn6eR|g%={V{km0nP z>7%w@-pu3C3zqVL@*dxE;kVY%MJVALQ?J1I?KcbI^$EW`XxNU}g>Jv^{z-EYw=#Dqjct1f zJNP=;`fcU7ZN+=Jb#Qm^P~|s+^>f|sRGueh%kj8k3aw?jLE#MR$d!=)JYb^1&XVtj z96c!SuEbUv^r|r2pT8%mk5#$$6HO;lNSKwgi%5h`SM>S4`2@y z(GyGTJ3}!mqfT#bnG&I$`V;K;WOq-*5E1(7n%FBJE{AnuE=#L|{%6gDmooYgbI=Qf z^sG%?+;D?yw$SKvweL0%4GXA2w^y7N{mf-9^-gi7OZ!2Ig-E-D>X61}?OO+e8dtd# z&S&o7gB7_(m=tW^6jajq#tD7>(|mU{%VTaiH~zJPTl<=bN1ug|P+pMRAg~LIbD%w}aKAxVRvw5N&y7-J_M_ocX94{Y@jB z1Q|1%$S%QGK-d?#$t2e^%tu6ef(e*aj2y#*BFT5G#+;q0dBwQ*ESqDzVtz-F{dgp6 zo2QRiQ@963>U}Ad{DoeBnO#u}r~i(j05D>aiVUUR@a8*r@iz94FgyP8N~GSqgS#!> zcy7FS20Y@U1d62MqUa%x+Fn8a2SIA0kM6%sb#%}@@g?U~DEPtk`#w6%)c=(#^F2bF z>u)1&8!>J>F*Q|+Tn%alCOZFHRO;s}5RoVz_Lo)4wuQwv!w4@^jDPI&Z9mkBYT;0i zbaJ`=pI8SK8G?M!W@zl1IfqEQ?e1Wu+taDH^$)^%m{$2pc#>EiP75Ot(^A_;k)-N4y02Y!FgovTK0b)@7#;hQ`qSUs9h6j6qqgE_e1K z(t|fLK7jKL$Y&(b}8zNW|O zd;4B-Q#E5#%x~tLTvXJ4*62$rk zIk>0AyTVodZ;ZI2QkmxDFi|xmRwYQm_rav@JHFO9`L8n0WN$-6MHhOQu{_6ie$V1J zqdW)_oW-0589d%QpPMv2F}0+rQCH)Ok^z6sG?Y`^Y>mB*OWoI5Xv~M(WH*H$-9j+u zc=19lsO!&}8G|>yz}35EINIg-^ox7A1{MAkdA*|B)PVo&x$SCf4_}fBI-kjcM^p11 zMBIiTx`HQEKt)sW;)Z^R8bO`h^;+X@chb9Spd|7_f)XJdcd!?cNuCv?q%s5cfqMBI zXwfSl-*YXbNa$?T9`Z1PfJdRf^;YwFT=lZz`y7^%n7PCTpjjhli3I--&bP1@lvt(t zhVUGmD04rv=L3u{?7DKFUQV3aq(0$m8!fmnfO&pn=<>_JcE_3Ft^Owb$&N;wsn%$^x|L z_F&_`f!~8hIjUlp60T--E+Lb%k~CV%eC?DW*_auyx}uxdzC>zh&gLxLYP%{)2M2Of zKFDl1={FmPs*>T_O*PCI_@(^eZ~CWou}@XiR1qK3CcNx&vr2wDTw4BSSl+4-jkSmbPpcy|K2KT9O7nTAxUB7D-U@*GB3O zX>~;ZMJ$ftSp2^LEiHpc)=F-o!OEE}zg}@EOgFVu%mfWe%HB6SXUnitIdwl9MN_CH zHC!J%spUv_6AT21m(?G$MLPXtY-|q7hW*>;0K5Ygl}K%U$ncEJ-i3<+J}fuOB~p0b z6on>*D+H4VD|j?sD{Tb#Vyjp?Is5mXDl*EcKtc^fB8DD$&|~gybPgA+@3(#)4N)b( z$|YdUjo8+KlXRnfHSK(Kp+OMTi@WS=SxV$8YWUvX#moxnP#75h`K2c$<{H+!4}^Ed0Z)`(tUY$o zkei4B3^myMvUmuJuFNk~uKxOMsoHKSl%MO`qO13sgP;LWKHm*E>~Zga-!87T(=&Zj zX!2nl-3RmgwdIZsBd+;#%HQy3?=2K|YrMhWvbVij!Nl;^HJ#A}`apC1@opgHPTt@A zvV<)D(7Pw}L2-0YwIjkHp6xKzFml8n9(GRHFcdYVtTnHJ8r+BH9fy+8B2s!inyC{K zPUh=x^ojLk$LI54!e>~CSd93E>f=NszyU(F?<&Qw$stq@Z;mqz?{vH};d>*0Ptz|R ztsjZxw`;D6RQ*G1(VohIGX$Ep>2l(=Y57?`OwCHuMx>g`8jP!iQFw?{kqFHYBdmPi z(vC>HO7fe31w$LY#!(OsC+8RK?8yaUdAd0BF0I1y0!m<*uekFavR36Q{*JKq9Mb~V zzZ`dT=HF_QnOhe=|6b?Jm>_)(p!)pY!=E=I=)w4vaj#}C{7UKcxfiUq2&{*kr-9sH zGc^?n6@%*5988JxjUSE_ZYBR6GR+BsxDWo$p^kU3Lf=ZxqePwU1sEyow^5e*zwBeQ z3j56p^_f%*z4JC{yNxH8Vf|K)_rA*B@q3C$-}ttQGMpL29{Mw=lm-qxU{1a=(AHmq za#ic{f5>&QT@CJG$9|^08T_hkk16K3f5hW1`fl;-kK!BaN29fai@~q7A?;bjr0gPx z4Z!fn<5Ov5q(5(j=6Ui{WiI8Hx`%|RBq_Zy?x9)%f~n9B=Sc_8Ow0S78P#N!no0`E zgKcB)e2vI6h>RZbN8b>+>#E)PMDJ7S8wLEqe@~C+tQV~5DAgG7&vPT9i8+t4dr9|R z!Rs{-s+vhWgimCL{^q|9XQxqQZ~&j(UL%?b50>A5AXC68mad~Ype&)Vib~t|k%9ni zN)_9fF|M8T3=8hbml0F!ULPVU>NjpR4Y++FCoc*Gc2J>9@@fX`CTvaneb7xi|U!FYbhE*lpD43wYu!%9x?NIA z69KwgS|AYqulHYknj-pnUi&ua{yrAnAC*cizys|oyhe?PdV*S6BqLW!$tAGWnTd** zYR4^y+PSvP`RhP{4@whfUz7QayC<5AAAe95R7l1soLb#$Uw6y;@eNA>SNm+>yB%e` zZ1u?JK7T`oYC;3=>SJ2IR`Tki*G_HYE=N5u(7>zV3e&Jvexr48e$g+xnye@;`HuZ| z%B)dT*DG|6>GC;Sb@ye<^&GicKY@>a$~0~lYjMlsN@Cd7ZkUK_dL9wzFztF?J+oH2 zeAfAjaC%FSf_U&1Dk61yMoX0}j8Msr3=n?I3SA|C#TxYdXvpjA{OzCFlZEElOT7Zk zh}B&MZMe2=5QtL3L?#F#<-%}WIQ4=m!7331f_&D&Ett@j26CUKfQ$Xfpu@p<8DKE+ z4Z)%78fXo|y0d2y9EAf1B!lPnJRm2O3Qf9JUPcfUq{aubbBe#`mqtf}dZ$zZ+_Fs3JarXK=fpP5P#Rmy$Cu#pe%S%=fCZwqTCs2h@AIxY+&}eJ4sK) z<#=7HyW!)>TbzhAPz+BHEutFeAx%(4TdzJ|g)ekx+*_uv64)SWf-3gBrj(rQ$JxQ7 zN=bV}5%k*)mE`fdHJY}uo#{NX(l3zd_{opexj6EEwq}ziqAt`lC497kOf&(5zJ=tk zjx_A3HKi80@)&1`iA*7wD=p9Q=F^ng|RdydtPnSvEfDbw1T zp;xV0V}9zqnZub`eO>60W)b1R7!GpB%C*}qkz7p$Ogp14sm6~rv8k7GxO4(!a=K^~ zr`->idd4kvk`K)X+2|a0-V|H$<+m&zzVnEz$AH*?gk5uGy}*`sB2~D_?Hq9XT*iiz zaU2c~1+_~8FJ7>h=3%ukK5VFPR96oZ^$6uG0@wk_$1*1$;Y2Ikv%ieQ4y&uXheYrRVq4Rl?d6Z)1zUHUez_(H zFe-Ho`ezr28k?IqNUgK~euK0=d^P-LP}UefUk>?g4t7l7vb4+sXkk{n7^Z;iy81Z) zQJl+w!FZQ~>s)|qRupHKfYHe`;#uiP((XJhA2KB)Icg#1qUy%eYRMx(KXhLpr^tH_ z6>7S2+dMe0K7FsW*!qxfZ7c6V@_y{PaC~_U3L~IJ+rsgt&t6StVN;JPAgTO^X+T~{ z#zNwiK0YA=?oDWOM@FTKKZ-eyyp?s!RJTLMm;|?yoo(&+)4E!?L(Dg5b8|m1aBDIv zg5ce4H()sfmdc=a~Om`(JI|C-IDO2LhDsYV{q%0`c5SUpyeCKussw;Di{}lBsZ^kZkNLr}h>c(~;AkE1SZ_g9!b^Tk0 z7!%F4%bSV&%n6Yjj;md;egE#4y!;NUOV8x)ZlD8KOam5zaYtwMq&SPI&R&mX+;Fh0 zc$r$UM_uC(bRRrdv%fh#$cOrN6e(jHN3+=mLrIMA71M^jj+dcT`KeQw$&`Q&&e_@a zgrfr$q2%4uhBZnwkoFmB?;k((@o#X|9@rb6X-1W4Rx)_#=Dt4U?AJCm??Q2N5b62VIG9AAz_&#p}p$v`%s$Gt@XEQT)f!Wk#QvB0aNbYGiyj7d+Se(~+%2ef z#DC`kMm*a^B{}084E-Gmf{>HT)7$y^wLisIfMjDT-bA+9!xR6(=O}!D7QsYL^4M(i ze$y|t&{7UX`Fos8`4^3aDn8D1?yZJeY8}x)PL5}su=Xi~HfLuRRMVHanKwz1KGKHFhQ~2GUIZRxu2<;6pB$@y60m|meR%> zbng=SLBZ6o;)rQy3)_P8*uG@i`OVsT7~yikzGHusJg)DEhqq4no4lOR-N^%l(v&o5 z_k3I?@U8@z$fE*xFAtF5;9-!vdE57i_yA%24@=+-qFI2hoZS_^^uwrXr?{qcWqOj! zxU7hz7f?3{3IQ3>(%!$S_IJ^R`_n(%4*u+&Wfn9Yfb1!BS9+?9=`%BSEOy+J(XQl6 zlv+^HuQg?hB?)Fg;PJ3LvJTgW+_%G+_^Fe>>2 z=}J_o@TXtJ_w6G|L-&6OxZe#8b+GDwW%c`${L0~c0#Jpd${@BetRMF6Fo8d;m9^-R zhwzK`AAMGMu8;Sh!iNsRu)8=31|pC)+v9#mR^>1o-O9}>=DI>&p2$Jdn>$vGd{q9& z$y+>s^>6stI>Un=Kv8~*&M4x9!|K3!nT4|j1zD(T%c99|Mvw0n5_B;nuHBd7Ftqt6 zA8NKPL(ld$BJ%rb0!u_c@|UJy*D!)h$O1&(>UaAZ1>cuG)`Cvz+?%dr%n-lH>AJ5FTt{n_aI}0_V>Dj!CE{N9`b6x|pLsLiWs(Hh zRjaf9Jy$_GO>p)Q-|%c`1c(wnX1NVj@_oi-UdYqBcyT(y(%r4YV7;C1FpNjV2h&bD zs?DNP0qCD%%hzN1cxH=W0k1P{xM^gdA692ioHF&7mDzyVLz!Dh!gN;Q&ple9r9Nv4 z3%Ud)!Q~WyVkVOZ*+@k`&pQ_P?tTvzk5&;nd;}j<-y}SNNZZ;nESe%5R#h&b0+?C8 z{sqs7b&r^w^P~xTVmQu0L{5H=Z{SBRprS=@PoGOu zsJ-El&KP_H1CniOf-WUH5`ajEy~5ZdhA5Ln}(#QrH=lvRN~;b z6Ce-r_SRFaE6-&U9=ro#j2E8Jn!d+w!mp?R$*Vna=S-r%aZ9j4?;6zm#+{2S&BM*g zaP(VXoM`q7l*A*cXsZ}Vv4Xt5fIi#jSaOv4T6A8aOVaCp*~SZFiw3kmwzzTUJWDgG zwI5yb+h4D{Jo(T)h(s@g<|u*| z|IXdB{bCAs*65A`4R}aAJOy8*SqN*%9i8w<87P8@sOl1V8~WUO_bmB2w4nQg=o7(- zKbeBjh6Y-rU8JK<$8;g7EFGr*o+RhL52opv4iAl@xTS7epqCEagDLl@6m-WAJpI?A z01tjw2_0dj5>@mmij9brq4gB7E&DmGJBuA*=03LjLfgG%q{X=)CcGdi+&180HDlP8 z?v_~swQ1#e))1J$o9wgR^00>Gk0iJ(Y0Foka2pMsKHKs}bsH%Mke&K)VHR@Z` zj*a5pp$qv*jepgDA#hx28#2VRQoytKDm-TRvh1HbPVj=`&S8=f)E-hE8*m6jum~*^ z<+-CV1_A)RhyJ$&49aizOMa2Bg({~J*VsP+T{Z1x~j^d&0k_|!fC zCL4QUO69!&Q~q`rc)aSy)DwdyvpYrPy%a0Q67Q7Ze7TNtS^P^C=M>(;l0H@Z`ob}+ zem5kM>P6bIZKf<#D)9*}!!NCU@#OuUntb!MHCd_$h>d0-pVCVC&Z&o$&eceIzZ=-{ zGp7>`&{*fb&C!8MavxGh)w7oP2O-7a5~Xkk2XMqe4HF9^MktsQX1pB!&%4Yq%O`rt z!fW(eC$G~@nN2;O*>3aktjA?yZ{g2$c0^+=bE;z7^T5e-Ns2dd>KcW15uE}H;xU3X zY8OM7EApH+i}glY%@^`3^~=(>ZDKsop5$TQyI_J=SVf^zbl&bKV$u8}xGz=h@oe(% zKEDH1lAxXhidKDgi-6T&3Tvx71-7_=7X(yB&BFY|8H~zFVQ&YPYZ@#L0`A57;79fk zZ$&XdUsafv-(trlnMNlV+?XGrwrO@T(d%E4eY8cQb+(fH)bI|fBSe*TMqoy~hjb;g z+rt+$TR!)lS#194;2psMSbYr&n9g^p^dYl$2;EQbr=)^DXn?vLX{3aRLr68Tti%`^er7@3UfDOWyqs09sgcq>~D~R~E zZ@#;;!WFK>dAw^FiB{Z|Z>8wS*O#9~>c%{dDlYzB?tEXOj5m`sncK1^eWN(z(J}Q!oyFA)&8n(g#6f^2 zfn8py1sgj`_-~8BrJOuT7|B)K$*qpop&gDl{gcmT? zu{_D=-@obG2*d2HXdt>1+E~Q_%$Zn4P25?QK$D6?w7y|~mVf{)WMJ`iQuB|BFHbio z3Kk6yB1KMfd0|u6+tfnZ%NijGeK4-l%m91VaSb)1U?0z%Y*ScN4rJj7^w?|;iwQnF~J_FqP4B-%rVJ*7Cq{BQ}cl0y8#nF@#nj? z8eC9FdK#2m4H%h4&Y|X2c@$Cv7p7f{k!eIcrO~r?N3ZsjDr)_$63N=2y=EE@)3;g8)>h62H# z=V1xblc1VP+~z;c>+JmolNYo$`V+}V_V>*1@EgNJ*R*Z`gXOD=ecTEuDT1{`kRF~H zMqGpp<*NA&e6(p&mD0Gi7E5sMKb3qA1?1K&GYZ$)Sm3pAuPe>2#5EiBHL z;}g_|v?-09^Iw$3>}4RKniOIT94fieWTm{14(Yfnk@?++@!K)l#8fl~s~#-|p?s;F zEErK!2&DBqTlHp?Wz!6}bhB`Iu#l#TCUV}}$aX?Fu{EFK&_SM^ooE+Wbm-=J-*iZdN zSdSnJ))hA}UYx}_1$X|67hwK6PBn}xdU}%qydluh++C@tD2chyK~U;Mw)|C%Y++gW zRHC#WAn&r3Ye==|gc}c(oFzY1xulp?+5)k<<7#BivH##0VxHdS07a89a3SQ~2yBZ< z9n{+_(JvzGGjyQd?$D7x+pS38i%L-OY{4emWeHTUP8x6p8oGW7z^C*+WRKxENYM2rotN9A9}h`@wc~NR&l5lOA2JN z9(gD#FQ^|d^M&^YkfsD6L^~v7wBZ!MOmr$SZ2Ey1hAtH*%orBpuQ-WUbK~!BD>0^M zEq9WZn(5>ReJ_FNu1=?4{({pIFDg$(F`YYMP}fu^!IEnsuY}?*e$KH=-;Cay+%_sY zrc=Z951Wtv%w$%yz*I>F|17KBc%U>KzrRouW{F2-o^bBj_SXdqrE5%Cke>KX_8d=3 zjd)Tb3B_?I^lqm}gZT@>C(o~7R zKyA+~fS78g7pFbI3+kg0o8^L(e#s-TH{;afJ759h z=%sK#Z?@t~dCJ>KAR1_z{?&9Ajdgkq#j_>gwWNfT$Y*LLqphAcWws~P-JfW62?rZm z_Gq1_$B2`)q`O8+1mN78m`F)y`t24ZeXP#KCrZy< zaEq#~@pD}vNsydnqrM1Z+Er2U!MbJ+H&bdAPZ=8_r3C}g$scZyq1OE5FD<2WbM&#M zFXa+EJ+%!CYKDBYU&nnpgZ9$yh==Ib-iF*T*5$p2fxYE5+#5Pw_7^u0|LXW+$Rckn z{_w2YN{Qg7?#E1HafJ8F{qI8>V4rQ=(lcFPo|vCdQ&7_j@_ayZzN0SHE(-QEZoE5* z!9R|iDrPV==5>djXY$|0=n72>DfkD(jv7PPQK?}2=%I&t2Bo9%=TxMqz?TyVClh@# ze!ifyLBZ!FUJjo_j6TQz_4D4sr`*5e2@d~D96N$PaD3Jz# z?C0BRv#{PgG=sifhe_m92zbr#afRN7)D=6)TU*gpzJo~~W3MN#viLSW>+vi=`R6`Z z+(;h%3a(KGcTsbN2*et@v&ked0TZw)#WdZsA3?%I!y3?^s}F8THK_Kr*w1IfvaAB{ z!m7R|qW*B^a%L7uLiqK$PWFs!OP|~kJM@99T0ymr-LtexqG*dx9wcK)_=6XJp9H*Z z;MyrRpWHF4(dLtPD0nihF)JxDTy;-&z|*(Aexpnb9ols!ovcph{~XU-?y`mRj@u|N z{$i`_y(iL+8yXCGjZ)mmgNwm)o%a*MvBBymRTeYZ8T9|msHuS{AflN`Nj0h;D zRG#&bx#CaD(A4wizqKHY~bMX6gpDZR_t?y4EYr^3L5o z1*`6R32I{Sdnt6NRZ~y9Pk%qG-dKGcm(v~OLw$5XOCax%8RFReo znl%2?(+P_H5wq5HU`tS?Ikmg}&8Y)~ACSTOCAAN%YC}+fP9BcRszZkscn4t;mmyii z@2yqs`%V83_dGl}$HD^~ujD!rWKjk~J zK8J*Zqh(9?O#ntuyo5T72h>9+p~19x{Fl$-UA$(;On|3i>5rb9G5)>}Xo}Jqv9&*N z{#_BHYThKK#VEJgcGu{^c=}5w9miZQ(Y|PVwHm1AEuQq`0n})g1kVs^LSI+1i^KpS z5T_3%JIcI)AD1T9d+I#nYt4o+g=xM?W|pCz&7pE5Nu8$8gPR}pL73ig|20Rl6v zm(v{p7mkYd90OA&-#c8;yZh>b1OR@ z43sEL*$TGx0QqzEJyut;Npr*^$%-RoqP8eB)0awy$>sebdek<}m}@`Dr%#@(A$#iX z3%s=p_pIUtGwp{dW=r06mh@&~9k2Se+e+DN(;>cA32bw+1Ec(<7b}Nl?suADFPQ`p zIvq(w`ji!{dlnZ2ZS5`}L}H4|l!`Bq<={JPiiTqDLQ3(C2ZnbXX!W!jrjzoJm-A;D z%28Zpg7~v%wy6fjfo95kEgu24osy0^0p*bW6dcqV34MlWm%~4Q{+KLi`E=jusiJmQ z5BJx;=lwKpmr+6UxyCQWsk@T?6XlpU&tLz6t{$=jyq|2A(Rfje4fg6ft&2J=-iAh! zc>Z?IhwuOCVeI-~3Oz^uDhni3ma~uN?^9sR1gKUU+qw6rDVDRTI|*CC z`#M}6*>I6f8n#LHP@NiCZuCbrgrQKIu%=_1dJ3rmz8Q_CvwyCCJcVSjgXs6U#lRDj zzK`~_v)A6`=V_;7v5a`nwHrh4EJG`{evy<9LDx%gYpor+edI?W7dC9nrfECXlh7#6 z)aM8rcVkDU+uCnFiGEkERo90;(~_^0AL1ToNlbc{>0-5QshOIMR`G zv8^St@0(4UySI`EQM+#F=aA_{6o0EB;V(Xy5Y~x#EGl&Wv$)+G9-NpCrYr!XMIwTE zFL6XX2SQ6_sJ;1k`d4a{l_?8AB9d8J*vIg9JriPw8X%FKRNCD)6VSvw8eIOI%>bco zOAqD}C$_{l@MqO4MpA$J(r?*tvhU^%)Tf9BPVN_|c~PLR05$sl)a1%D^-#PhLs zw;|NZ)HLZX4(Ih?uWv;Y=!lgOKOQuQ{%JJyBeZJNGt@t){7Xsb+fnDbrosbrK)X@y zZ}t{JQbXUA{jG!zog*$Bdh`+`kj*DSUX#WCedfQ$TbUYM&eB$y`St{LFxI4oO9ICU9G=2M%lP%4sMK$%CX-!KK)ifp!}@LUSGW8W&4UZmq_7w z2>|C0nF{cl`CBPMnwA9pIsn!qYe*_Dt-6JJ?#yX|zzv$}JfCkq$h&mESUMX(4e8t# z{?!aybXfsWDwDv_?W*}#zh31`RAsxv5w{+CkBxUnF7}(Wg`0ILkSD`B$!S>KzM?Kn z2Dxc$TtxabwA7rf3M)ps}l{3<ccRN$2>>#zuRM=aa(LZT41Xk{GIj>e-A1{CXquK%2+hGqWdy* z(asLnr74|&yAAYDrRF)7l?FLpMQw2%eBS0P3KySOR`g}gz?JCFYMp!DNE|Db&UVqa zn*FW;3O$*$v%Wd5f8Q(+@w$qVIvh5TqxSy(7M7LP+z~M@*NCbCT_!B#{s{@969YdM z1Ah|(Gk_R&Ro0qz30gF`oSTIqX#|wvpvzhWy2_znWa8#Fu9=ps~4Vt&puyh z<~6hMwIa6~7SBe!2~n-*!V(W5xC4c1eWr>((Tk1j@eA>gbeeDP7C1_PP4FMsa)MYV za&nbGY$Lo!k;I=TzycLh|*iJetV_AQb zL%UUw#>kqdiKL1E4S{Eo$>CcGX;h=*++90ts`>w}4jf^>{5`k~9!GrXAN%8|5T&ke zk~pnrcQ^twP2@0^N`JevD(0bG; zmc?||`*C^G%wbdxm_hJKW6C0yM%|~{+^@*te~rUF!zr+|=OK6(v*#b+XG3!r{g+ZN zvhd(~n9vbRm^s4nu)Rheg^mq_f#cfle4Q1eUr}Hf_2{!?8S4(w*k(ivkPXJL7VZiW zB@u`V)h$GPCH~*w8t8&4U?`vj~;33os62X7d7=;y_lo#0RZR(6q5>weJF&lRhXs zCgeD4V&w;ru}DL3!NR?rY8~q=Bt5ao@^3P~&ms)yFuwZT|YO%&If5DG)F9F28m3XRh1(#)bzZdWtA=DmzQ|5^O6fuCq)vXXHpC zD^=z?K`ED*a!HLm97lL$Zda<7xwHS)$Mc?y)Sjipu}-n{?1xeFT7<{Iz;{kO5`&=w zN=D->DsIab%Y*S?-3_OA#NvC$Uf1y#=)%NWx$uoVlb6gV{Ml|e1KWOdg$^I?7AK9U z;cv(kalf$T+uE*aQ|RkCswaVxSV4n_6J2UB&22DzLERlSw)M~3I|7>W^=Cr=*q;$-VC!11m+Fk5b>|0g-_UvPq>)nW|5WpRF3R{9}^7ek{l z7M4R`5{PgrrNa*5Yb?j;#h5pbPy6yF^5i|=-A!oYgn0s=N~+!XvG=R=KEwP^=J+gL z>Jf1*bNDrOSj)Z_gv;P><@;r=c;7y{eVI4X-WeH`Nam;QJ;jQ<{>(}x^eBa(_LD6a z)SrAsQ4_Sh@+1gjW%K$nM0y2i5!e@M`17Vyg>9ymY2He442aP$FEa z*S&{dZXIRBpD4|Jgd=b#2}~qeZ&+mdHGko}B&C^iOQ6>ka$?c`^{VSEtBZfeOInE( z=RhC6e0#N#LxeYLmO)U<4|a=9FOht9nZ&I`~! z%imV$oUqn>Cq@>B1+oE2TuHaM}xW>vd`|yq6&q3*3 zm)>I6inLl`oq*()swfOAgmpR-5ox%S2x@{2V`OKZ#9_K&!xCgIN=C-%onG9F>Ohj? zR6DIulRP$g5&9dn`{}}g9X%v)BEx?d$lGs3PA1Bw;K2KgbwA&#Z(uDYRn7X-z05eV z_^DdnX}0`CLK;fhuz-74?u8?GTsuxa?daX3iB2hlvCzW~K?5yP#nV5#e_JmkEAL#LmZNcrdp>$(V44lK3ON zq|NnUbjGclUu`A*Ofw-9R<3fCUO8y1(N>@~!(*vN9s#>N<-$EJN^^V1V4xpxzd} zNgP+%Dj@I+7y0pI_2UN`eXjMi%bVBW5Uj&f9Ab#};;`|x3K1lv!&S+V0+hg{Tgn;s zNN~)Y1T?6oQiKQ-cYcK%Q&BLMBwEst%l2-3TJv557Bj~dmoANHGj8o)pLbnDziz8w z2Z3pE!Tnn0l%T~W&e;@`zuqq5&*@CZzP@q0P2kkrXGJFj&f2lZ>|42RmF3 zSDag__pk_-9%ZK?YIojP{x!VRrzrAU`}~4gP8G_LUgRu|%Z0RYVpb{@W4(mJSVTEg zQU|%E2oUoRQ0LPCgS^USfY^ZF*un&_*T4cSucicm)2BHIfO_tD0m2qkn^Qgc!Odb1 z`jSG%@69){H&dBF4UaSFY0mG(syN$_>Jr|eeD`fE^fwF_GKZmBvV&uPKC)8W(>*ZG zln9AEYgrlL!L^e7*+mx{#4r-O*j553sYVq@muhZ@oww};&Z8lk?viasr&yznm9D1q z&+~4Lu4~V2jSX=dxd&wW0H9;T2X$2{cW*jY`0eCL$prpaK5W1N6?OafwNn}my=c6K z9LV5mrYn^_i_?Lcqgj9ETBuYP7^1vw{VlBn9WpX^TDtr`DZO^e6XR^l`OT_GZhu!H zvom7gUC1={!{=joq$H(zuG4s5V`xx&<8Pn^txD8_zuUP7e0jBxdku z$=xi_`5(2cCLpZuihn-eEFMpnN+d#ynbE+?3&7W+XG=o^gbIkq*NH;+b5; z@QiwSb|dhw|L9O~n2=^1zc||Dj&q9&W&2W& zFBZjv#k1SNbKCWGh%_`M=6&v8hf8B>_~;{5Drc-;Nh{3;H&S=ffo^VQ6)a;Ww}}E{ zWRJVLViI?>QoX?%Lbg!BhWa59(g>lk@f~jt49!gW5f%#6g_Uw z$bK^1vGAy8c?|l6*qN0HB_4k0@|gMDhl$oyd2~qt%G|2#L1*ODL)n`h!`&gyChF6+ z`rXp){fkekT=^xS#Iq%QlH|JU-snh>)z)-{odJy7%hG`IOna-uTMxNbxCGLJsHqee z=)y#{PmKb2qzts9)ljTeQ(L>T{!_p9Y#c0ET~p?LT+x=W*;2)3L1flA&)!QYRYLZpx-Y5(O%J!V}?`t~6`GqAgD z%_1ygK%1s=iCd56@LCye)OljDW$TKeMG9g8DtH(_VEeEaV@K?z4i9#ms%+G+0ECC$LleT9Ga%l2Q)JU17QKj+TfhReVRQauk7E5}=Qq&~07IYVFaXQ*V{?z$ z)0ODMwpygilQ7{*5+9six@05k~H}3~j;*7$H$ayej;YThOoSRupSy*wQzytXF zS>ulDOxQaI`W$~hEWftxv$C0T6gxxc@ew=22m(JKsG(OWFo?Y5T5qvici6puCBdpccNl>6f&BsM zN9}`(aFvnG#0wVbC;rBMM7V z=gl;E4kr2}DSEtuGdej7z-_pDxl`SE$F)*@Rer}cdg3J|GjrkvUwmjmZX=l7t(Y~g zC+o}Y2Y@{#yZ~UC@z~R+;LwTXQxS0JnB^%Y_uLw8-1J#k)Z?m9ml1~~c|=Ln4|uXb z#jJx0uBuvr{AZy80MwCTLb@oJV02?XC=(me`yemJAtL$#{74T#t|h7qNX+i&*g3dr zg}dni$m8Y{A7ppzi@-GWNfd$<$dpJ$^gR2%YZbm_brWmfz3MZh6h8gVkC6X9j{~yU zY%=+IkEDmZX1IGz25Q_`&KP}t*0ymgg#Kbv;?WGCF0n9ds|ujgGI{{IC=DsgHHjZB z*eWCLb^rLe#EFdNgg&7w*==b1O)7C@vd0w#&Szlfi!_-dAAM%dAciX z;IhWdR{9S9P(eb*QbuJ;8o4|HtVy9wU0vb+m{L>e#hHViTq1}YR!v1^@tLHZ;q$&^3b_gB}!9vf(|J>PXqKK{*_QS4bd z3FE(5@t27LY%fku;oYZK-h6l1!CHOHag&)8tdNZV_PX$)a+vl&{ z4lpuk9)NtOvwa-GHjAZX_AZ@_BU9l#zAyl3AKe2`P@?;>dU~d`6m&tOX=1N}u|@f} z));I|-J6UXB<}ogYm4zjzm3K&+on|3+8-b`TK^k>GkLFmyF7XSNUOdUX*<+Yas8fQ z1^WUF)Xwp*4^V8R=W9)#d%4{AHF_ugR+W<@BbO5r`22a?NBh(0V63aI#KdreASV4m z@OSi)#mZ9Ze(=^(Dyn)ir0|^kYv-4t*yl2H1mwOCKy5n#GiOy8h*0gT=y6NCE|*w) zsgyG#EOHB;??!$kebs}23P(fE^)z~%G90TX8yNd2iMUFovhR8C@YRJ>gvM;;2GQeh zxBfe|>i(9v52V(O$J+CQF-I510O0ROf$ld;PdczAFZ&W>B`s7q~~-AP=LQN+Wde+RwkWTtImB4`A*%T#rPn8dO2O?-qRNG!3+0hVfTxsyXZ9 zb^-(WY%|VP5_*0$GLlEMy$2#Y_9q%-pzk38qBTP3p+SP>if9n|yLPEUyM`_?mfAs1Pr@_=YnS&qL-QWa&1jTXOZrA&Ys5<+AAp71KMFnE&G1+x#&}Aw;`TxC1HyYDCK-%K zs!6fLVQTa$C@`Dntt&u{+?r*nbS?LGC2$di=c%9t*Nswse4ANt-v6ow{{QyrIyf7! zN$uzH2i!h*<`X`!Ou8L}1WSmADUFyd9G3#|@jn4=5=T5vd1Wr@bMGwe02iTk6C8FW zRyxs-TqbZ>B0QH>kFzBHO8aW?FwBP*2L*ARtn?TEeLWIIA;LgxllPAJ)mORi z2abz&`TYBmPmLfUs@n>%2>m9GS7F{qyG} z@XkRjq$a51Zuzh6RCT{s@~ecz%N$AwH~)wPKQw%qDpqyx4UCUXT!53!rY(k_e+M`{ zi_4oFXQrNUQ)q#ir(O=pWn>|D!s`Kj;#+*aKA{hilMBloxo-mFphK}DE3Av`(mFOb z$9*!tP7k`&29wN_jzwgWI^+;xPy|{WB-7lxr+`+1ZLth`vZu2qOjUZAC}_4Ro^h(- zCDz3Rws4py@j()F`%C|jj|vpnD)$oS`758qZ7_AVX)a%%wrOHm-p*Fv?HYzY_7h*- z3NI!@(Q^k@?ADU{S+C;bTNtRfi1LJOPIeYIl?t7drWgHx9I4WUSWwXEwRlw=xPS;i1KZ!F<2jEVcRW+M=QU9Y_5cp>MOzUcFJT@hSTp7q|70@YLr~tr0 zZPn;A)bbAcs*Pgf^I&KFqo=K*alc97Me^Wzal}?6qIa{U+09LHcP#t6Xbph)UxdX! z%)F5*>DH@VNWi5BMjg@Yb&=n zH0RFW0QTc(zwu%J_lo=V{N3}oeS~jeYu!F5$u9BzhEG|4UYfD=1ZyOhAFITQ$vQ^P%Z z#8PN65GMmmpeVa=(&>y)sbRY^0$aJPRp8LMOW^GqL0x0-6A}kWYNN97jNpUrqz`P) zT&%2&RnOs#x&F&}X^x{OU-_nZ1dLo^t6$AQ7tXIXQpaa%goh97Qw-|Wj-i~Z(7v6v?7#Fdd<7g0o9AV)a)yiH1Y-xmLRv3ifaN{%}-im!>^ zfNQi|78jKsIciEel8OFkV-;F)W939X1I|X<+Wv@^*Q{f1zt4vB&0{7#SB<=NmRq>} z5>%CXq{A;S*G7!_RZjHuB8C_Y3&DeF;ve5*rgvac7mGE1Ss)(q!hR9-YN`68;B|A9 z02p3Ppb3flQ2w|7*v`N4GbfW$y^wa16G|0+#26eWUE;{!bB?gVDokfV#Ibs)b!3Hz z-Fhm_!}~j57TuW&gN5)w!c6vT+OX9MUi(~^M`qvnj1!ltU^q$Rx?n43$5uReS{M`1 zQ)>XBF}+5VGOO237DVsOr>$L0k5$-us7Ck&^PL z$K5Upf5V#5s@3?t*?0Nh1xlV;{oijzJyI<1$`PU=0Orf9snhZ;?8$q*Tg|C^^3fCi zz&rbq4(O8K-p83GKVFQq)zlyS5thFOFB_f!{kV?vicH9hz)BT|Elk|hiB)e=bL|t& zJf0EFRvzW1#I2SZPDt%OW!O@C)4?9N=|5MGCw1dVYqJk3%H;yM+me?c2@IMc zl9#U-n==>G_mM>b+n91z1LK&8G@!G?>n=;iP!{D8ymn(fFSkbV>O`};aAw?@`tz5? zXGJW!37p2M@9m6WJk(e$7zyBh5aVq8uJUUT-HF78ub!Qm3WpEW4qURsTLz8P!_Ok=8XugBWFp&wh|D+_WtoTr8+C z)^uqgQf}lrM){$5Pw)X@Wy$*7lc_C)Wv)rY#{X#E6Vr2s(w0vKSmfrl4_dXS}c2)N$Vv zV!W^Jfqt0Yu#67-&PAxvGedbC3HtVOe@?Il(B#5dFKJ^q}v*)N%+< zk5vggv+O#}ziPW=MJGcgM>v*;hBTntd%;6+bh5F z6se4d-+Eh!^Jg2%vJ~+7I4LMvaotgc5`_03c@etS9zQL_hF(`Me@tdGIes=sjH_$I z{8^WrH5)c8F3sL+;Yp6ESWf&r_OEn1Q~1OVjEJHC1nnu4OQxVQ?>?}3-(l~k8Yx1O zmlpRegA60EX^hx=(B#9o66;^@D2DsRsO#jF&)7H=YHjOhvTcf0J@QB{s3kKxwoogI z7?}-=owGL&=INT)@jjtkD>TpXVm@Js_s@E7!%6}v?n@x~G*aYu`^)_UxQ#Th+wXfz zVQs>H^`{E&KhVx}`_zs{$$!aAQ&VFz0I4FLY(A{z#uQLOZ#OpZx(+}rGp@CdRdsoN z=GllzPDTztKlt$4h^4bIMQ^d}zBEh@2$Kwo*0JS)GQdwTaGrD;k;$|qsv?!aH22F` zjL&UdA=*+z=TWKB-8@61G#-c>*VghXNDVrp;og)L*eNl}n{7_0{A{4TfYdcZZ=6<3 zlAGKJ$HRUoB(_0m?kOfs$oJLWCn2;Px5zCK)ec-q`g^~d^&?~CR|ngXo}7>HRlf%j zPQ0p*M2R>`k&lFvVGHQ4shn|_mTc#FN2bw+wk%@uxrn#d0v$>($Ms>n>s7yt0oWxH zhQ3w%w5aa+ifdi${cxuYd2%RmL)h^JB8q>MkfWwq z#4fl}h6^FRIu4Xsibbz;=S<9cJkJ_J5dC}g`4=JBaXX%oIw17t@}UUoCIWz&=l2-^ z?z>mG<3A1sUpxwVyBzm57(W*mP)dbevBjQe+mo7Zma>glVbF-sUDfOM8SpPo9ar5d zRKrbPQava{*O97xO5E0+DlXFmKN@(FBEo~cu(=2bYoYUz*nSPlc9xiVU4`k{^Z>O@ zHziT#3%V?RfO-g~@6Fy!pJi;a{;D|j3y_o|yfC~izngNPc-HdieV2Kt<{Ry~o2{GA z@1j@8+Co_te)GBguZ&LrMOmcYBk;DtOl6g+`RXzME9;S0QoU!i*yIL}0S0N6xUvP| z^=T7a0=&Njq(yjnpUNuQyz4^wk(J1)+()3Pd2@tzbc~cK3YCRN3{ji{gn(!^P2kHXXTMbO0R(Y*u{Xfg`{vFatb*2BnRpaS(v2y}u> zk!9OMXkBCY51x1`6W z_XM-A`QmbC#9No2S}t-O8LTE$%OA*YzM?=q#s{x^K`y8nLHsiQ=te7NVh8evo`BDs z+Z-e3G^FmnKP0ck-Di2b9o{=!Mp@BA6$+TLihR3pWu>iDg_mVA?c{gRU7FFQ&9I0xh+`zS!| zM6(f-K#nS0|M*6;r>kT$K-cp5<^+w%v?QrfjZD3={zPO0lPhQ(m`mRSjW=&Cc)KZV z#DiHjc`=@IZjGU0z*6el|9;%>d6Mks{*&C%6#WQT{x{ z;Ehuh78aW~+Tq>{(Z#7BcGguLo74ZF*11CHEGV4(F9{t0S3x9qNTI~QW2*^uKX6`%f`GNkS>F(McG zVLloV_M?O6X5dFhg<~QRv-Hf2OU`?r{smDZHq0SL+4<{kJ|G*)tT#;j+iN*_WNasO zu)1}H?;Aec&HMo}ir%4CBmb~r`skO{X=WQXJSrxA%5Zz3E&1AJu+>!*egH~ zG9;krn_tzb*;X^D);9wH)}(9syg}0=N13IN@3(#%&-d^8ZsV_?GKz=+sQdVb0a%`? z4?xSnp|@!x-_iA?w{Z)xG|}SZSshsq}MGcpZBD7N~K38&*c5|FldI6v0o~Zg%0RNYHHV zmO7sdZmW@#EKZ3mwC1cMWoW*yngd$l7{8NS;PLAdvwY3hvoGaL790$!fAl#`v`nm^ zVw1(MWJQZPwKEr#lz!%GN{MPR)joXP>l>sYG+{p@u(ly0SkJl&%v<$z{IAOwuCEIq zI}Ex#IRjRoFQ1tH|8M6>uK%6jNGR4tZ~VRJF@qAMQrD!oK?9tC-T(H_e@${AkDtgq zD-mx*mVFo(9VY;6g55~yLWd(cXK{C80HztiJ^W%SI=?G+9-2Bdc$5i6*hMeR0fT(A)k{&yF{lvZ}8TkQEl8ws7DkRH#W`x@MuH$Kl z##Na}`1@d=t`Xsdk6_Ydd?6{dd)eWGrnMMm!Ah6do|ur|G>ws!6i=e;s)TfVUX5VB zb#1o$GEES6$~yfhTjwcX2`NXh;Zf$r5MBhd`t5jV|1KL$Q>S@f=%e6gJ@HX{^LYil zLk*xVG6eqVm{tN4{uTGtp*-v|7TPC*D|>XcR(E=${qswt(j&NoGk`lzA`^gL&{RgK zPxng_oRFLH1$fk~Vi%(#bJ^ADOrRP%%!v~0Zl(i*JhfQ2t@cmze<;D`R8+J4HA|u5 zRF)l8mUSwl+;28M;awie0J(diaOw#@llVjf48*u zF`_dtD`0=%Wm8@w(lCkWVxs`vY4XITL9vDXL@4NPUu&i z8m<~vA%U?2&J&|-b zEMdyElTjd%FXzx3TD^$z8+oXuCRro%J%f-YB8-$n=%Xo6xMz}o_);zA*_Zvu?wS8G zyoYuL``T!^DV}jj^Ec^-&48a@~#)eVSQMtm3wPWPm{0#;scYOA|0)>A= zIeM>;ZguM0j(&h9_EHI?oy+>Z)iZFbVz6K+dp&Y9o12ah_O&x&UH@ffM>l{C1-hOVj#U+sakUG z+L3?sd7Z1>d>>vZy)&jEA{E-ay!Fn86|RD^bbFzuHA?VIIk3h1h1y~Blz>3z{u7o4 z$yW8#kXVO1+|!6SM3?I4#G(*d20bmFXbOqBDfuK=6tMuSu_h@OG~CE~h7fp73}}%y zCraW=0YC~rKcGm@-8;kIp@gi;%?fAcaBCnSo^n)waW3pFT1I+yBBa?fD(e0q-pgcM z$@X9v^z2aKVpO%7kd8|LQ+-$qEF%5tWgM7{BtvSrLn)5KDp9q{+_UWl>Pg>XaT#?n ziP18UJ@=`sVdMoa%CBKuu|1bm76OMjWBsTQ_~Y+``MaRFd_1t9zh z3LF{Ctow?-y=x@faTg(3Oy0y-=dNr@(tGs6I3fr)Y+I#=e#K${;Si9u?>rUFd%cSuCdHf&dG$eC14lc5uaPhFVEydi*`_(21J&2Zxw9pA zY;QH~BShr8Ac?bV)}0w4{h%W5!C>;0KeKmL?`YGF3nsrMe~5uu75|A%K%pHD-pLlt(J*Ak;jk7r2J5l4&7q&~E}@6sA8gew2rVZ$xj=;Kt1S z4Giz&sI7de3Vz&^{x2Nb`Bn5wRxS;hyv9E85>P?w(X_M<1qogRuU}7dj#R#QUs=Fw z(BcO<-0;gupi*bC&3T{tf@_^^(FsQhm&*8ya$-?2I(I2FpyLfFbJF=$bvJ4!cR79; zO#WB$1FZUkPz1T$aP%AK{d2a*PWyeA1Dl(dfn2%a#IGhEfuFHhxPOPjxn3m?zH@6x zSVi_InYYc-t1c8Jk0!?CbIn(95^YKWEmloK-+a$(tcGGrK{yZ*^u&JgqNc-6Jj8#$ znm{k@h}CKnnDwJ;;Y+1Zy)~1Wsb)UujUjJ+^z6hDBG-~Ev#zLaBmZ6R6n#SrT!+n} z12>j?bQ^goFl4bJlg0%-93{NoN8w@#&<y5#s!V_$RQ5W*yhkM!n4R?!WsF!1@f;SAJ8yVK+GsDmuPPYl2^A zY^Bb5pS@)4bcn)?BFO0Ozbe`I@^n#Igw(@#fzG#>c|ubzd?%ckHzdk(E!7U{y#Mln z!O3pw_1_SGOfd7Sw>_%Q$$p)zj|A3I26C(Q*h`kKMY9r}Dt?B%g|f~gJ?YkhNbm8d7h)6e-O$~cy1L8Zrr z6JNv@6T~o2t7FZIN64Gbq%GI|J}HP}>?tz)C0<|f$LcEB7__J-{6KyFuxt=Qq`YZz<9554jv z#FA3e(73a`Vzn*|wTl&pN8HaFD|kNW=-hFsf<@ecT#{J=-Kb)X&SVhW8lMOnr*2`D z#6AcAYol7h%9x;g4{jhO+Qnl`cM}mEKIGOye!K^o|BGEO=)0&rGs+@@H@sl{?Q#aGsK5Qxi(mp0wWMa``Qwi{T#aZK4qK7%SNLE zkwc;mdb=R1q!gO!PP z&OWE%J?Wp%SxP6fy;HH}Vbj8u&L%UU>_Bm}_kRCXJ~tUBb>Fkr@1MEG7;pb@${r;7 zr_~LF6NBhH>0R?tD&Z>}zk;@yX3U?`gD=-><>coF_5x$cKwh@?n#^7HtrcXIaup3@ z1G1=B8a=Yf6(S1L;{!p;Dj=TUS;LHd07osomxDTTf(2buMy>Kx zth&(JA70Mm&SfahZ~VKxt1J3ItF++$ZJ0(7-j*xm&ccY?$o~2-KioRfpqHp{9P+23 zEtmMkT;oAP>mNS*1lx?YSKn)T#Ch-se$;&!6cKD(d(?S^D2zfFsZe>)9v}RZ8`hzB zGDNExg13-)>zX~q!;}yKr_i!QlA4;)0#VBff`ue~@tbmU@!c{Y(d7JS$N&)m>Ja&A5 zpqI6|uj7Uyid`pAy^G|Tj?VCT;f=&6LB|_2100nnc7{7I&0R77`*qa6$^C&?W{~LQ zC+tlR(b0>WxDQpFJjvwseclQ!%;sQWqA5PU{NJNG1WTHbfFqixtA(#pk^&r^*ygqI zR?Bu+aV@Av?&>;r`3?PG&%i9do;6DSSuV|&Q@c!JTo+xvNx0s;zG`oGe@-MS}L+#T0$pTWFx#GE9B#q2_`<9<;Q>OF;(dd(CX z(n=0Kzi!qf%k#QzqL*M<+4{_!9(pSo(2Wznfz|q-n}_0VIV5tgZ)=uW^iQQ1-NNtL zeFc_@U#JA?qAn$>u2YWyQ7HoNz8_=a9fL-Vsw<{X!940WI6+%9)xtYxY$&&nVKsL$ zl=bFVD3P8{!>~Pq7v!VKS*TN>COYjEvM5@3hz|9iGDGp`kWxbX~E(KZsH- zGALX-8M<9XyNk#}1P9)#ZM5^Taio#-dL|xq&^eHQZ9t(yZ7MoPuLBk&--Td#EW_kG zwO&|dJ@0h$C9s;^|6~qru(Ni`5-2cEBW1dm{iG+a+%vV841W_`&KYm5UbLsH)}zPb zh_|aS_wS|I$MSwu1d!|^@|Mf#tX?w=(|ccdDqDf0+$vrdT$FZMm|(5xL<7wK8x+Vv zlfoUh$RQOkdS-N~t1CqYTtnxOO+#*(kCF_M0bnOi-a=MJspK4lCb(+oYjY!B>8i6p zo?57OyL$m5^;btI>)nzPY=j}_li>2#;{|EPnVrA>hPCqH>#v4WUY|M-Cdyp=nEHrJM`ULeY#7AsY-1Erg(@v%{c z4bNvcNw{OsT_XUfbKy(%OLb!vmEyts{6Td14!Ju0U&#jVRoU-^tsU{}KFF-U9P4m( zjK5d^YDt4UVPd!!>v!K|EXGn|z_Cz+iZe}-;>?K;883Okap zax)O76ioy7Bi0cX8>&819I|Ki=Gn?+U&*afm;d_OyE^}GY^I!Q6P7cP(!lBpUWndT zK-(zvBqBX4#8L^Kg;CvGsIH3MIWhMg$-$Xe!BCUIE}i_!4oa1ljOkj{9_FS#Ub$($ zcvQ|w0-j{ccLv|y#iJPbsG9f?cHya9D`@noGQ^t|$hvq!l{{DiWdywtETlCgpqT<; zC-v#+XFv`ofh})ac`Cl_DSUCI-6 zSEbz52u&y{=(`0MkI@rN5I?nBFkz5IkW3q!5h>gz`~&%UZSiSVj?&-_!;#WWJkQCX z4_jOMlA1f@4kfcfWJgcH>amdjv%dj%sQ!1eTEF-t~>;o$m%f6q~GN0gr`%LsTN$yiz zXXgxO)suE(t9vB+<30a!H8j~zmxF0kKZ)#NyPEZYd}pE>jW3Re5odYXtbr=$8d))uellNK4h^{3N0I{4Lx;A z6hLBKF879&BmOh&>C6l(Lc&M7(hZU)XL=A|%tit;{@&D)n6?xSvzTSd#_q7vFM9s1 z{f@cs1<$PO`%lR@I$T1Q?b_Wdao^9Rp|hvpFLYWxU4+vQKW|)BqGdx9S2r(>PJU!> zv{PZe3&76$G!i|-Aa5+I2|gpv)3FX?BD^sBJ%kE>YnSHbYpbAqQJDsM#llnYT#?c& zU5nEUc+^GqG|S{pfqIzE%nGOJE>n|ZWd0C=rwX@qd~hA9CY}{p6O11Gyp>)!_}O{VmV0m;d~ zG9(YgEw!Sk<67Q%W!C|3VA2E}RHL2@BJy&nVZ*)%xy!{ekkt^3b&OUMdLGksVOC0R zg-j0<6-*uM6G&85k-jd%U)|fh019dqR5}ehrrd`>gsti|2Ie!kjbFax?^y*rlQI&} znC-~Qp&gVwZb@UJkW+0vAchmCeeh0RH>1EN_`|8PIYJOO8*->6N=~RhsGCB5*k1eC zWbX0HjgKF2L-4S+$Q@bWp26pcdwAdl4PH7dZy;H2k_6900u3o`~dkgoIH;T0KuW) z4S@`X3F3Sj7ZmuJ*2*Q4q?fxMLpd=t9cIa)jrwrI|8E) z=6lTv5y+#KLf~4)?L_vIciYBDQh_t5nR%F}l*Iz(w7nE7npnvS!gy3uB?9ysv=DVu z`wC;aM1#dxYbr2{XDJ2OO}M3(IG{-H_$~hQ6X&QA-68B)8b-~v2x^IG8-{4X8k3f1 zFgD3kX(~ZkR^m@-C-e62aglX1{Ug3>BVRbJxzd$VnE$x-BBE&3nKIW7e0L$TZ~jmi zd)PnK?$ki0LqQnq(}TvPj1&+Tw5$r<^(bDw`i6|ur-u-DXLdM2nAcY(P);;11}|OQ zX2$Uyj)#W5Sq)JTGx`h5NHxp4Nc^h|4b9@>i7+jO?H9qAZwKK~I+FFD-~H4H?0X)5 zZ+R&>T`+J~`~15($a;Y2Jp`U(n@MbHQMGd!+qX`U&n;$yDmTjwj9mwMvN^1uo>ZFS zl=bSY9Yrn_vl)k$*-N5HS>de<#Trb%JvY}cv+)ET;~jVFUGb!xWv0Wha0o6$Kg}*B zv!zt0VBlp)rkwY^`ahD+!=I}E@#E(X`-(_1vU2Tx%@Q}smXV!3t`)L3mt^mGuT3c= zB*}I&lTFzx*9ckJ`*%Oz-{biw+{eA=p7;CpdcMeyXN+Qi%0*8c}k+F}vdb|g2vTflhrtRwV?T;0ni0!$_!dZvw0iV_{Fi$gFj(9M_t zrf6Co5lCkNws)sIVsYRM?rVS6CILo=iNydpkM030LCe9Y#Q|@u{Jtk#+jiAlzGr-! zb~yGR7vK9|;8vH7pdoqcYu}lXIr`mCgK4b0R&;Z-l19I7#C8HkR_|#3K9+b~(zC#d z7eH(>_Z(e`6iRLpd0)*OrOsCQ7m#wE`Y*u?S%_cE^uRvV&pC5pw|A-<4d*^+ugfEx zH=ZET{oWayq=%y-pZVX?$uoh81RcS+`Y2c=8iG)cx_91W2;)2(oe zs^gE~!%B@svWuy$@HyUj!I;}R@Ba9$2ICvQpAQ^%Z`+&I;`PHb<$b@fn%IHbqV~f! z@5D$GgSAcd<+Nyk+^A8>pH;`3mjP_@_X#kT8XJGELBX}JORsb;?-lwy-in;2L>83| z>p6h$GyO*^9T?37lVVW|uh)(}jUE3{eOH|@{VWM7dHo;A_t5wk^h#d?lnwoQO#|FT zwYoI;GH^+{Q+m;_(sey(z!e#p=yZv#MAzvzc-R;Gkn<9(1x(QMO&@Ll!tlH#>AwsZ z0VcsxfsBz7HMzw|pVa2l^XZT-v zrcd(Pch*;@e7A05IMTNx&RsSBE6hKtoQG>)-juzGN~g{FlD;m=4onieS>}RPy-ThI zxavovlt66wG;@%^P1O~dlHy68PyB#7vC8tYge8yq)%O$6u&*eQ*+O24IUBJrVA+R= zW{$%_iV1Yh`P+=Fbptypyx05a!zydm)#55 zR-+|__EE}MGGJ)af@VmaCbpckP^$Z;nqr3VO2NEBW_4tNN^C6=$4e%lqzEvE%A4edpd`LgIa>MigyFbsLSiES+ zx92PnzqUd;4P4w2xkCiriOTuQ)znMJz};E^8kBN&n!G$aq6TGBSBJeHkWMMJ!fEmH zAd=p3nIIN@%%8DWcYkzuu0iJ`AJ1Jf_@$C&?JXUjUxtJlWG7c@PP}t2DuJ2M;DRIY zS?B^d45|l>2$HW#n$U9m0;qV)wEY*&pu;7j+{G7c$SBvOTA-MeH-ww6I|}s#<-(Ws zrNcM-skl_dIO;X8j0x8}oPQ@HlXYFYS)1kfSl)hsv@HbB5x9%B|F*N}yZeA)n98|h zy1K3%uXszx>VICq`o+H1k8th3HEe5|V7-#d^t$~ZPMb1(7*a{B{dYh^x^|do0R>`M z%(d3XY>Din+3G$j{E^tv^iwQNC>W0VYs~n>njiy|PjWdnQd8&^k8zRnWsp~^t)b*p zXMn!sP2t>E8A_6W#?En0LdPZWZRA|pQmDi>wtz6A$xqReK_xpX#yMS zl+bEcs;$O>D|s*5U?6tb4oJ1No{)V z&mvBjxo47LP@>N}T-|0B+7VK?uo3d%{39`ArG%+-J@EzpN2uv(5`WlxO|6`K$zXmK zz&6N1jty2duIP@_Ra0Hn;Y?fS{|{uDn@r()I!p>avTc{Th&ZqG*tW6C9mpK({y7~XQO-?g!Al|WtXoXtn9>z-3ZwAzb<4Z zOFr5^hf||iXDiK3hf81HB*QlT^oM9aD(SIYSx)L?IoFBV{Y`q%j8i zwkg&39`Wx_4u~t-x@g?0hQ_df!sbC*E5S@Q?FJJ=9sgw?Y8XStwQE*W&uKtnVM37G zjR~|W2;}?P{C+u5AJr1c-YdF-j?-P#s`AA{cn^(=7$W^S=0CoSjA{sipcC|0`D$>r zBeHnKhTV9vZ)$90Dx~#y0B`$$3wgqF@`=hc5207$ZTK^eSaFGkH}pV^Fii+E6(>eo zZk@vge#-fiCx)BgmF8xV&TdHe@yvFA?;EMI;B5ilQ*jjSX@awzhIC_T&>zCX_QUpb zu!OE@+NB|4fA)AieCT*Y;%=k)ui`qe!@sM2x#qe3p3Hb7qUiOVkH>kNw1`VRad+mI zd5fMa!O4}ZCZj5bXC&KUAO0{^;V|T!^PwmcNAn)Z7_XVN{o+#r__eGB4XHwHX`ft6 z&)bB2uoV|)>8zzMvD)=Yqqm$k*&}c~DkXmBPZv8}i2S0AdT~cJS(PKb1e`6h)Qa>( z(y(8!@R`|$d{BlUI{r?#*Qf6PmAZR(pD&?Bgj2PK`cD$>4A-hERqO}Bpv+x$U`PIXj#9v(z=(PR^=lUc*f*5*!=+EWtV$judm{ql~ z0dlg=u#xv>#SO8w=WdB*Hwym*Ihd4U9})HwX((SHBn7yDNlG-0In5ouxjfbdExx-L zQ3E!%sT*|?Z;W#v&=jyDuD1SNai{(c;#+%?b!yVkIz1yQawOjqU&KtLVjW{U3QPM) z!?cdNsT6V3N>OsJ78So;RncXG93aY}&0wlN@GoKDn3>WU)tb5$re(=BQA?rMMVtXV zupuIvx%cikq1aOWqG7tLNb{}rf`Dhgzo6Pp;m+4tFjsR85C!ehsSbR?P!L~{75_?c zzJR{HG|JSCu4gR%4$u3)t|JRP>hsRn>(;%XBaeb|yHXFdyDTuMSBZ|DU&bN&6TJrxZ$r+Dh?4)_r79mE>gKvxd zMpFUy)LgGDOGk~x;O5lv5^v+eW%?7M5Rh1zpl0hG%t&)g7(F6m_WKlzhSR@VK{g1K z&(bKT7sy7&q^gIo>~OD9K#0JCq9eaj@2S<49GO7Wi6<*WOHM0oX(YzFkF+l2)EAA( z?hU=?U$;5l%+m)?BIn1`|H-73rf$<)1sk!B-%Deo*ed}N@tL^ff+1aMop1+KIyx1X zjE^WGW!}+atPYIClsQt$Oi(7OgV|}o7p8;vP~#`3k=0``Zur_kGaJCYyDV#)>!e1K zzi$2QlnpQlE6!L>^~1|@6u$8n$$<8Yr#Y}K+R(rL@Y|_A8)UM1_OaxlSKM{PdBnNm z_>~r7j?>jY&+Xmp?@P|#svNKIPxBvuYU}cBIUFOHekT8nyTA|dVNl`3jpKVWg5iqT+OnTR@4*?@TA#J&kENXZCiH`j^9L2ZfOkgK6EOiCNHAqd#Zl5_i^U%CC7eeL*dvK;SH>5#kJviK9(ngIEw&8OG6#K$ zC99kqU1Ysj4XOd#PA~80yuRZ!M^Af0pHs2()@Yo!SGFl9HQQ;u8}GgxG!g`rXe|4VZb$TZFzv?nC)(6(`=PT46mc0OeB(+l!R8e4v?W zP+b>fdLj2B881u8!*C}ZBJ#Yi69;66398@Y{qnRA8K;<(wYTltsR+=4WExtXQvOZk z#)XMwNccAlhV!_~u9fgGg$E@DXyyhb@dE!MwbT65)4WT0A~0G0v#&N2O+%lq#=QUf zx<9Zk?X4~sH*SWB;ZO%P+ zERk%}B&%jsLW#BbOMl*l-IOpZ&@UcJAo{d>7KlxwKxw`&jP09VUZCT%{``O&`jL?I5H#}%mC zp&{i!bgL%RQLqNE%HZfb_ih&Z+&5&O&}OUqOG9%tL#=d5Q@N3ZM;kSx&}d8x)EwpR zaqdus-6lKfvT`@d4Ne3*jY(=g6io;Gl0D^(2FOF z_ifMPX_4w%jWka#LNjHDO|=?Th86W=K-n<0GSxc_N|7nX=MNLIRJ3XZVWR&hD`T!| zx*KGC*6u!Fa{A`CgS5#=W%B-Ded~v^`z^OhO+T3lom^|EFq9D{0$%1%U0!ZUy2EiR z$KFqjf||&H5a9`uM9)Er$|f^!(dv9@AGtk$&s>inrsfKBIRQ{{YGefCgmSlq_AI@> z==%Q3*(2+C7TVEn{ifg`nu1R5&xdHm$*+~bB95E(8_}@X7hBnh2nj1n?EoVJq_r+i zGe7Id{KVb`6->k5K4~PIS>&@%i;h5iLQOZGER`922=Ajeo}w0zyv1(L$3I86{=YeeRKF@N?$){(rD& z2;N@oyn7$n7FyB^-4B}R!QLn0J6;0JU-i!`#SF_E(3I+iuL(vZ6|h{l*ne!xHB?A@ zz&qlQwRWk8c4;zoqhgQ}SLP>oPrtT1HPulpB^Z8g^)4dPio=Md_=GwSpwy~GLbd6O zlSKIxKW~Sv?P8+Ce{Kgd&>w)=ZsM*Ey@G{j<6l$HAXQ;T61J+eXnEVhJ1NeZjF< zTGw;|Z!4~Tl>-UnSBZv!$|(uRY4Cp_i{5EJD+PH>coGORZ6hGh_Ar%2H3^uEPM9?M zBwX`Q2vOuUmdR+1sx^&sb{C|p9QpfMNHL+cZA79`$(9QRjh6)0CHDe-37>Ye_7CR) z2N}5{s5{ny%aXpZM~I%e$|Rf@Yb_{aym-5whz|Ye?Ub5;DzSdaoF4RL%bNG_!P8Zu zrp40YF5;64eQqmUC$;m*6jdHN6Ud2WM%gyVr=XK1^In9$D|5z!)?~y@iGEChtIBHyB3{3R+ z#^rxa!+X;Cpv()?O(!9wDj~Izm{|{ZRedcMejKybC7Hlk4pn(gWcA2M`_YBRhK?$x zPN?oce2Cb?aQn4faXz7;P0bdK8yuERG|gruu-k3_&ZUbm4QtZtW6u6?r6= zYQ)a|1fd?nN}GJa{2|CHsC#Wlh(*J4xG!pga6mL8`}yN19uG`mD50oLLQd}>bj!Aw z(xxZm4^(CS)xo1PfG0tK0QCM)26mbT@uXkm8Hf!XJsPZL>rX#!%tKYss0Rqv1YLL9^&_4W&;g?9y~_LB~?$Jz%HQ1Fb5P(lWf zpJuC{3xcIGc->uXTvn+H2;9fX0TKHzE8E{S=R-qHHpU4klijxv0eUt;Q1II zu>@9HiX+_H-k4QU4DWxPtsy)Yrjr!+V@IG2c~N`!}|?)Y`{2A<^&N%6EoQ)73iOo zr#*o-cEf?Br0G>|FJKYI=LHD3LVrAM^)stCYBw6%dKdke{rOA{dSbcZG{R^w^UjqEB|JW^3PJc&g9($FQ_R;$*Fe&z~86W79|>xXL8Nve`S z8ed};n$Ek{Iu6s(??lBTyJKDHDjuy}b?mW6Am&ybSKp!RF0fdOBTsscAB0JXxs_OC z8ka-Ao@cQAy8?VHE{0rc`xVqffDn$gD!HsP$i!oD$>(I(1;;UaaD-w1#eOsCt*P5L z7<tay88zv_nx<0EOUrQu_Hp-}+17a?)}b%VhVe2s&CG zV$9~DJM*L~RS*laJ?F4dc`xjK4@1vGO^E95_lq%q-XAn~doCUf($34X7{_v%kztDT zOBi-2h6?ae%7avLB?AqsMwW(pnd$J6+i|b0$iw0NEW)GH^m%jNj99>Lu#=&F* zb5IOCb)B4Wb;M}|o@b$199LW2|8#Lx1|5xoHpc*+=`6sxjpY_YJxwY3E-_?fRr=Zc z;BqoQix^OYT!nS6j_(URH;}&?nGI^T>MjFZGrC7Pwa{7tBeom7d*)8)f6hZHmOpmh zpJoAS%KMK|-&X>2fyXX8QcppTVa;rpgHIgA zCTLAzP^%34jg4iw!_+n77Uk`Q-aFA^_&-8C-=5u|t_NzkFbu@56{GXfTNiqKTnuCr ztJ9{>yK!RLzauC$?aCy=lts2Kz@XXV@BS?gx4^;rpQvxj25pP)j}6(l94(*hh(CKE z!*%PW$!!i|wRC|`kx5KUQZ$3-0Vy>9{6l%UTBTb_U$(qhlJR*h{eqMn)o5J)s3h7n zD{KEaP-8W8HZYzfxnEvW?DC`E70F;uoG7)=dutA{?`O)wq?wj~no)tz_zF9px0@L( z3A&!6oP`^#Jm-cQk?HdG**a|QbEfv)zp;LI@n_#@c=8MQvX&daT=HiKatefMPJH|4 z?+&r=j$jf^>aXw!@xzDbxeencK3)~SediBUjjy)ZYPA|^XkkA;K9`)}-d2YF<%O@wX|na6 zq{p&VQi*@b>~9-Xf8#f%OD;NKsi#uPk}jD#+$un#CEI);nkwHu#EpRP zu&2S0@k4viq12|^_yW`i_u>R816H1srl1SeP7@-!>-oXJd5fG!T!~^ooZ#_OLMg~Jd=}PL zr~A*95}TSr#BtOntgQe@D{vl~QJZfNN;X0$Yu?&DCWv@i)i`1|$$O|`?p$4e%>k;p z>f`C92Twk`^qio8{I$OQYg7|p^fmMYrl#a8Cyh+2CX*W6qfDT%J*rciCN){FU!CDU zhh4QUdHzX`nFvX`i2pj;3wa-KXfv6Q&VMS5zY!4s^Nn` zD2q9GcHm)+Y8UT&80;IZ#%vS5?3-)~p`U2}owinZR5E0!*&XZztNt_0G`Z?j29krF zDEBZ(dVKNy6@1W>Y&u#ZawrjI zm^Q57{SRUvrh4Yk5WXJ8LH-OHm@v99D#-N<4^QlpsX4z*l|efFYx7S_ka7HCaflmM zbtT;O9PSxb3`V0^nTPtTMfSg&e1}`98m015@aWiB5*`Vb2ktUL>G(b+Ec-EBfcqX# z4+$}w#2xsP7LYY3qo2I_FZbtM$og*zh><;oPNGyUy?alb>ZXCGr$GVFN~0oWSzTyV z$Yfi@x_cCv2H0At?acEZl>FQ9-eU*YL|{_ZXgLNPoUP1KsA#)DIs(C-2~gxICYXX~4l1#w>^?<^sK2 z!|?o7=Xa|GID;k+YTV0*?4SBmbwcv%ot(Mi6!Qcff8Xys@41Yfqb{vTfmPS#Jdg4= zG8`E<9PFX=g3RG!v;DIf%}EK>mRK0y8hnSJ4lVw`wi%}(Jn&dm{N=-&NNoOpSNn(w zU)0|zxB26vmS8tFd0_%nJc)t?i2iAwz6*M`YNF*vl=2jA3DtiBZi7_=3*7#KS#;JWsZW8ca!v1JU^qoWW< zn>ztf^F_X0L$p8Oma}aR3YEC0O9=0Yto@&glm!Jm^glJyVzsm9N1@rN0o$)$oGU+x za&hZ*w~3)Z?ehLw8|q#$%Xo7k2M+uoTeuYFE>J+V7DrSK-3XF*zZ(On1G}Ct)}`oZ za;w~w0HZ3}e5n?3mdL2z?5$gH;IGr3hN&|hh*PDJ1Lz;x@E*yqUVPp)adf7tlJc_p z2QOZ*NdDRSXrfOoo?*Wuv~jLO%6S^;nW}1~i-D#SXA%Irc>f0u|LCF5;Utl4M!zoy zw!9b^&4qUUYU9JsbJK{ZAx+`PSMSgjk5H(X)Mwd08Vog12@=<7)+=FZE4+F3ADdK+ zjnB27$$#8T(P&Ns^10kNIco2+mz?U|CVf>dwH^}`cs6(T+R5L- zJRjkF<-FWnzTD`Uv>a&P4Nc7EGuP%QVa6bKf2YI(u8Qf^IvhPj;bC<2H-xGUV!PuL zYX@LbyM)L#+hyqTea9bMcntg=C-~=OkhTVlci1fk@y&_GDE`{qYzF?Sa_jE<-f(LM zr$Ohdeq=mTKXeLL>UV0Wq$4K7LN(}>q|G+uFaB^a=tC-6Voz-F&+o9Q9UV3{{P0#n zhOFM76aL1Obc>phGUGpV`?+?xfqeY8yVdB;cBCz;9J>iC3om-y3^xO~R`}ZnbK>Qj z8mgJ%f>*LYa&3kwf0 zJ24-Z%@g|V*;oHjvGvsT^Fd&~cI6WTI2fUI0Jc(!(P++)`*$^6C*LnU+3zm38|v2D ze^sO==IFMX*o5Eqd%~54%s;2!d24&QChNa!Ajx6M7&TCYFM!I$x2OPyL zY;qs|<*IqdWJyFQo&t{+foqUGtJzbrM(*%G6pWDe;~MK5rO`n-sCHL~@b{NThcY^&XrLFNV^w*v6v0oQb^H{O*dHC6X8++F-4~+S~ zBupq6LeYe=>p!>AKKkI{Co@`GvBUbu;h{@$__;&xV6z1`YqJZK`k#5BF@rSg(zmsdMFb6~;JexU-8wfvW~26IIumli*S8l>$A$_*uEa(DJiSDpfp9NV zB983~c5k`^Ii!|b)VTeFuYEn-9Q2NKI16hfT``;tnb8-1^otOgOlWj%CXHVSp8q4vifimTyBC@t4ax?)l3ftKqmk(#zrs{26pRh~=%fnxD-w)7SbUL{Pu*0K)?PulV&UQ5u4!E#~CLaUIvN%bs;&AJ6xs0!@mfX||{f z=97jer@>!%n95)8@~T84gd>oNW?-f6SSq-XLFiIP!O2ThdCBD`$2#^)M;WWpt@R_X zz^?Xw^!sJC%F$(YC!xohrDPIFLa;H_6*T&vgo#pn`s4+>VDl-XXes`j!I*B8X!&P z(D!v^<{z>~%owYu^6&rk%fs3e1W1A$jOP*?@8YBx+T<@{{_PR5HNd=ehy;8Bq=$ok^#ydNCg=9!b9q`lp5qUtm5IJB z^sZ^0H4I(M+M{Qi3CObf-Y3wg;4wt0C8n{_E6Nv7{-y@GFz4+%H&@Y;_CH4rUFC(Y zXC6!|lDi{pb;02(VRZqxvg(t6aT+Cv`<306dytie4#mBqpb`R-hGgaTPhiP}-8fax zOe=w0egY6V>5Eq#^3u$A&I@}=SO^)8)J+D7Rwkyl0*e@)BNlaqqQ}uc)8Dm-U#3R@ zbdlwpX_v^B^m;cp$!p<)o>T?>e_nUm{cBbIzMnBqc6+%sCw(Zk*SL@i7XfV!zq@+u>}cthwrfeo)g(FMr8iEg-x~8TiChLQMBnL-$s~OmLrXVZhlxr5wHoA> z9nmM4Hu*bc?)`Ezxx!01?zIKBbBBzI9YHXkYoBMsJ$LPof1`v|W{+}9<4S{8ydABr zteNFEr2QP0y0Y+>SrL_dH9lQre0Sy?&r(0Dm~ z(X1uQV$AW~)xC=VsRkReF+zQ(( zbKqW`WKgt)t%*?%n{Lvwf(Ls8;N_FfP)8Hif84jAqpPtm0wO0uiMI({U-M$MYj*3@ zkyE`IHPH0+@;l!@XVB2!9;$?-Zy?5gXyAX}VS9iQ$yuUQ(F7Uy^$)!{WkY1w0QXVQ zq#lafGlA<13sMySocF@t3Qf!IQ0{@VN7J2sn$e#3o~fQ%ettRHx#Q8S!&mez!6v77 zF(nM|Kl)SqwvbvlFWorq$?c!H0$wlhhRJQhKTdBwp~=6N@o$@Dbz$}A3lZ{qPjMO<$m$n_2imqf{wt=r+X$#XXF&PPItIa5Ka_@DSBYA^(RFYo zT;UtFdvs813XF)XW=s!+E0Yn5DsNUaF&biR>5X(|Bl?&U_xw`h<*Gg%u)@INnDeVS z(DKg3p5No~;}jfzXQ&gI{4R0lFsrV|b|P7SFL>n0|9HSN>pacla>@mqd=*(}gFXvq z7XEXllL_eZp`6n{dWm>S2(_JcLy5woGYxclJKclDxejXMIzjMQ{LljilDB8pmfsmw zveQJzhC=$Wx+S>{H^a4@J?)wipR2Y6vHncU#0`%a+%@+_e7~8!%-Hht$#nkcZpxY7 z|6OFiXP=M~MO;bLwAOl&2+mc#D2SqVF!AU)T(pFB-ojB6O7g6eH+M(^ULbmInC;+g zrn`1p*tr68Y*;pZwags(X#$)uFKvp3|Cv~O_g1{aeDrgS5;H>rAUeb{0>?2!^r5Add!xI z1iNCmolW3+ z56f1OGRI1i|LFD^-%$=L1H#T+GJ5pkXOX^kTqUS+_+u>A!u#%;;;rs+GbzxyV~4=! zfkJ_1bF@j~sJ(IY&!6$;Adg^ih|L4J)&*6vh;0AhS?GAhmyCW7w&6@7O?7tLBF*K1 zKccw!8Z}RK(XqrX*%_0Q-$m#=!(J-|ZUO)E-9 z=T)BITX0wbzZ6G+qJtE4O2r|(lu25Om!;n`-w4vBSuSAzheWr@^B<|~YC60vwjVi5A}?QK{`^feZnW^L%X3X*hd#wfzxirB zbdDWrvI8~&NOUD;XOH-$c#aJrskBjcV4|Vu%*#Ye?>TVg^?-PqyrL3&>4cVH1;tL& zJz1j9R{AVh5fA~3$8(rbot_tiypAcg+Z-y-b7PzbvxC3f+4-OsB6edeBH|)1(?={Z z^|JNZQWm$z9M#H|?9H^r?4;gvdJN&H_^Tinm-r_P=S57 z<~_zMu4()0gLxB=ZyB*lK_hfb9Hj09cztr7B!A2^(X~gUX^-`zQ0i^hmF4;&{>{*( z`!2y5(2&Hi6csTc?Ky|HRzUW6dI#xQ+ZoBa>ZSDUeLMZsLCrc>wQbm?uKs1H+m8VP zjZ$e}%ex0)RNro{R*MM0AgO}AnYI+eb?;z2`J|txxPY=FR-(m^@gOee#;JveLqxkn zD?HO;<21fM5>%iLCH>+Si3~DzAFR7mDBgl;i2t@r(*h$eG_lCj*<69|GFV*0SSjHT z2U9}P9g1b2`cv1ti*2jfa~ilyY*nurXtr%2;fFBEEbD3jLHf2W)5iXl_@$>Otw%5@ z*Xz~g4V(*QRir*Z98p(&7uP-fAQ#$hVPj}S7QsEqmBGMvPYgVr&-PDYe(Yb;ApAWb`vR!{b8%+PDsZQB=Aoxl@# zz(>^Yw1h~Mn~d@9Kk&sqC)Bp%Uk!EnDKmWKl9Kufj1W3#_)p3$A!~D1LJklgc#+(u zWf}ldMG93HZ#X6?wIfY~I|i!}fBWTa0yWMpsEOj_jb zx1)Y?VcjKvK}9GdG1IIhv#>>pF+>lLbKkBSkIdWe&89c0B0nNbHnpjo$yhj+zs{SC z$wNQ?ZBS1~H=*gtH;&RJ46-~NK|n;T0w-DO9y{+$`e>iO`rP7R@Ys|K$nS)D9&ZLS z*58c_i$U>WN9OHUyYwJ_GV;2RigJ9gVaeYFV%#`W;iwexNxz75q*pxq4Mxf$+3Z7U`7LQz5zt=+Pcus5?@6&B){Fv--=YB2EU${|Hfm;!0I%Ee-N2mDxrAfxSt!@wfB{e$f%ut$c*l7 z{Bfz*ir-yZ^ttT z+piXsPh0D^4pj2{qV%NGwqtW%9kc-7b54Ql4)pvUJvHa+)+ByBjKO&nB} zu4K_QtHfNeL2kW%R1z4FkNop&uhULGz(wji<3`zDc!k72iylj9bCTTX&4y}n27 zkj!3qS)D}zuJ2k85aoGsaM7UKtgi}I(J!KW zDmK5_eEimC%jpT`6lj5vhzx2#-vk{*=2WgybG0~(}fT5XUTFG2^> z>#TlgnP9cub4Mu;o73znVz)TdI_RbE=KZnqOM3~%B@oqM?0OsBVzNn`_Q*mQ*GBGrMp z6|!~`8ZFV7Bx1==OEcb?#%1+*mRjm@_N+q-_Yv+mV{ILdi)VPAefQa;Qi%ilfdKb8=I4~uW-e&1iLen-_M)l~ zVxB?CwKiEUJ-SKHheagq-j6lrMbv}AoCwG5MDYo8<+Sl*FS|M4rK@0=X@%8{MrJnQkl9Vx zx832{tg+Q=hPDxB=W>S7S*gnGw#^XlHa@%q*W%R|=A1551Dd-#%_IPXolIcNdHu@) z<8VmrrNg;Sp~S}q9Zv|M^pSTE&)~kr-`XjX2TOkPFYWzQ?{&NshngO*s8&>GJTrH3 z*6Yc>@RgNFC#KdqKZSDVQ&CvE3fnQ8FK;L zLkW_=Um%yZNt;ej3!?jmbZ$R`h*VaW$LZxj5#Cq7W<$a4%*X!nU}Ou^Mkwn`&pFaI zdYskqwL1dzb@sC60o9@au_Yb)<0O+L*vk1NO@s`0GR$ZI{%usBb7c=mja{esfTiij z-#3AnRam*~L0`GcgfGPw&$+66E_k$?C+Zqks?gJonf{ua=={xWZppgm`C}U6O6efN`Pq*2`b(TL*Bq7v28MAQ94!4w2bw!^?{FPidr0+32wg6yK05%I4tW z+;qw1L?$p2NDkoFK9iUPiW7*b%{;PZ;iXLVjiX|V@A<1iM=$KlXdLSvTIVn&dNz8D z-aURP&3pqg8Qb=4K~Dv7{ecX3#()l)d2x$-puWHg?Zf(*O+XYI+bBK!&3S1_ZNhO+ za#)DC?jhS;JlW4DpB7s=dp>jRk6E{dYQqkAMr;P!%y(X6s7E)?T?5^7%_RvFw@Zqj zs}cKMM}^+*#7Z+6|E`_;{TA0OIy?lF$Lpd??t10jmU8p`k>~L~`PZ-%VJV50MD4y3 z7j`XF;6^lN#0x6h|5F7hohNy)q!CZtTrdh#X;{t2;h!L4S~d@^mxK4 zUX>o>qY`!Q7fum141u0X=JtHtD5iUK==+7eD83i`w*vVwc=u3~w9fqUqr3ih6U3DrZl$#P4CiKC*Ox+iZg*b6o=vle8@wKbnUVBJwyi+_3Xy;184Pfr<5 z^WDhdJQUD6)g#{F+P{wxop2BC%H8pY?2>fuN4t3GhgnX$ZF=X4C?cJ@@w+Gcde|P_ zTZzZ7xCR+qNWVC9T`{<}_FUv|H69*kS%+&ifho7lA2eCe33JsNGJ*9Q^P2a`fpJ+e zv~__2YtSz8{)4={L1MMFA3__vQq?^k>@_0isE$8_5)>NGnu{VVk_)cQLsr|>!@p&3 z4ttw|^@jQphzV%!yW71k9d|S!7u@6&ao))FtaDc;ahOB?Lx)wWN@A9Y@n0>w#)ZLw zhkvKrz@xfX$X}Lh6^GYVrWQa#h<@d5oKEh)EC5D0j(Z4A?jaHYs;RsyZ<2a``jG$< z>EH5>0v)(3SKq)n#CO~=CVdJqx}_8ugEYEJ9Q7JljZiIOz#*?=UNYfot2tmqBGLz% zQov-MJT@OP+EDZ+fSm9M-0&IjDr`AyIAxtAZvM3YivNBnga^i`eKG6?{^HD16}&4` zxVn6~rAdpPjk9RE@Vx|%JvL*NJ;PpdIr5qT)iN(A)cNmtg0q{AlP%&4-egg7Djz?~ zgbvFls!@Z;&B6CV*$3ktTxzyzkgFNNwNI9w9`A~X!zdpYt)i!iqb{*e6fQKHSQFh) zq*GP?p_8mf_cq@L(XsaQ@JqI)k_nvU;EEb4i05)Ny4O#3zI1Qf?H^}`wZgHgqUttW zKl6Ov&#nJGn}rUm#=cme@JMV9q%(W#jH4rzujIzXT6-ZxC-i~s?MoemlzcQ15t0kU6a2ELY%(?pl zgzumpmHBB6o^=H;US2k$#(U$4cfVrr zzwTJd+hqH9|7Cpwsm~se^BDR|HL!Zz-KTu*ss#hQ7p7PtbVQ3;{eG;>I};m6q4R)& zIeio33yFwT_~)eQanll^Bc1u4$BguyogI4^wvqT&YKnuPVsN5j1ySmT#NlwRp?9+! zaRZAFMD1EFM5{Pu?N}j5z7~p}I9+7gq22IsYZ4c6bxkN}%lB2kI6b=pMV8)mB#nB# z8dBrsIWP5;Iznlmxs;UQHtiBr(uCu)bT{a}+zSrtq$xw0!R;Psq+A=ogZmW4bI(1p@*TPKu<%E~PP+&bBI{!c! zu)TcK7Yv)4c=i^vKJDewc$-vsiTZ{vOy-^hX@@q6rL2J^GrGam4nt*0V-Wcf9msG`8!Q6h z7NL3hd^lbLaE;O|qI;=c{jdeRsCF`Nz`1Dt)Z*zlWZUwLRSgn0`uk$pI&^VF{nuk> z!W!avf!p76_rjizoz3eOAV23s$!zR?Vfm!rk=r1|^$-4orhV8;NtdUD%=VZa2(^{t zsx8K`zBD8mVlH<5f~04g{O^rI*ER8sG@|Kasj%pbPM1tMENAH?aWb|OB8`T8KLdZ> z*>EZ=xrr;>p&t|VzHH?X+O)o+J9-^##Y)Y%*K>j=$IUx|#cgQz`!%*im>8utP_&E2 z$My*M^q7KY!~w1!37TOrCSeMb&`*n=&|GYfcd(h#*Be;8Pr0YSb#Bl+(x}5_`9{w% zgUqjN){4uj!}qk^1yVdkP;09GRrFj?>I&mVT$zMF2CgI*#+LI${U)iIzH~hRIG>masuXF-_hnrK4*nk54=ni*{}Z11o zb)sWI*+GL66C*wSGYQ0n?w8i85cskbtjO4nv@0x9oA9%dHKqeOA=M*Gm&Bg?&H!bH z?%}E+0p}IFmSWq2h;r~}?B1F~F9^iyJkIcSTkLp%vpSt;(X-8Fd>}M=-`IL-Ry>j9 zV6ABH^3z0F=+NG$8EWuX8--{VigN9gwek|ka~ST3YuiC&=oKy(UPp86Jk!Q2`n&l2 z_kD;T3bVi5TJ!Vb?%I&?V=r$nQDLplp(pCBgW0F|yW{1#SX5ugi|qANBNhgG@CoE5 zf+bUOab8s_RoJ`}&o<9WWaR11|QrGRI`y1obk*zEQJT zy*r7r12d=Go6~R57K#ol7!M+>1~>4dq%#@_rjyT8Y!MB%n*L8oBW4SF_oSAMqEs;? z^^{%oA6NjFxR5`?@)popw@d8-s%zoGLyZCXDtV}-gR6@b-=Z5KhtB|vpA(&GqH}h3 zmURJtsku4gc4G}MZuBtIraOdGE|;w+>$*Kf{ERirm$pV+@(Qx7$qd2n>G>~3_%kSb{MikMye6g`mo8@F=(dP zts*j9=5Tf*Fnj40EC$709VnJD;5L>6ALIZqHCH-Au*>H-sd9O8uOt7;vMUSlm$kqh zClz#~ztrvKIv7vTj-iw5ER?V&D1GxOA#?Y9#lWu35IuyY6;q7w+AZ9vkBR#Kn(p7>*%kK$qY+oFaxmV1%l&(gci3?#_= zZZ3t|@oQz^>#PNC{^JYj#l_3wblsf-sG?K8^aOOi?yg}AnTqeGbbJ_M;9zhOHVC*D z%&Z-OTytht>p&sVtV>baAi4h8u07$ zAeVFU#oG}}9eepONbw5oqd6zl~)^VKgK90-=wLCiawoyc*)wgAVg0p!aWe~Ef zAOrxyvpR6m1XOLfKn0p68stPkUrU6SE+PiS>b*mI;Ujrbc<8zaZPUkj5WU9^zm$cJC8 zQ9$j(%H9V+Snskg6+(IU#9kWnS*1h(45O9U0QO44ahP}I8Pn-`qBt@s`I6RV3(~Z z0hE6r4+!_w>U5$`07Wz3s$S-TuH);&r!tbFD2qCPO$_JqJ4&y3%G60v93nH(61gqs zrWo?FFyuA9IM)E6q|lHR98M{7Hxj~gU#obuMFUqz+` z84_!~1#!=d$lqsf%e5sfHv18AcC%qDYJfYZKYXySik#*q1pFI<5zj61Tqn{w+~kTL z9xHqOQvc#oXtJAdV7wGy?zR1?s6RX&fZY-WS4#XPa_5?LLqhP zgQ@YwoSC~`(VnLE|6;B&Ctx{4XHO|qk7cimH*7Nhc2nZ?z5)8!>xdp=AI$$jV~fXU z-SYhM}e~A7B{5-U`7+(pZfQ9th_2vlUa1-%h22{A>M86cnUn_T`Fhiq|7= zSe=L>bVW;CaHbv2!SZASLyf|NBQC zJ8&Z+>DT>Q4=!WP=leL4a9SiNqD&YJ+#KA50Y^exNdV##AN}{X-0rcfciibD9&SNC z1dg6$FvyFjY*2tq=PL(E?e>*kzyA zv6t@~8L)wEd*vgydoEhA5PeGztGbEt!`uLysAW?~8AL71Qx)pL>{k~Qku4Wm4J3Vj|}?E zCTu_V>hUI!M@9ZF{Kb>|n2t3MX|zWx{ehbQ%;jusDvinGC#1j9ft|x$LtQ?C==qM< z*_eGXbLewO=OPh204mp5b2Cfh#I3jB1So$2RY<_CXzhV#A_^p#rWD9`QhRNNPzFgX zPLA(l>$k6)R`Ph@760C|&^*hTEDu1EDGNiz5#vCs^%xPQ^mCI7eJ$Y+ZM^uD=`t@6 zYQ47kmm&GzE#3a@z#A-yMfUzZ@#&T<{Zn^#SjqCd8Ufm!M?d^gmx8hgCYJ2aA}C z&POcwZOn?0m2K=4vbe=Uj7xMK0imbe{<%9t$Nqz)G6qg#af4kG*{Yn++DRwrIiyX; z<@ob1hxX*`@QTHvQ($s68M{{W3sUaKPRODMlWnx5=F=`5o3=rM$cA#aJ{tJ7ByiN?GYT-bh^F3Xo|0j9R}Ozm#LanbM>=Io$m_V+~9_RII452<(>OKA*O2pL1!A-*bmhGHI8*dl#gC#(FgCotgObIR)-drv|p;i z9E>D3N(Icih-bZs4eOjB#f`91Ej^_*<50z>cg27HP1zJ$y{6TXz?oW2+)3qq{3L2> z2{CUbj-}$$S@fv|2R|`U#H$z{E!L4eaX_6i)XC=IK~eIB?N8vB4GHG90`q5rkliF- z_4bW-?0~VXHhvjE@Xy3i3Nc-X8OGx0;I0h9F}B_PwbHt+`%ydR5BVlPg;JzW;=!Tlw@;`rly66fF^jV`*Ks*Egac5z6)1<)dmTJ7e-u?WQ-k-=jg#M8rr@{ewO(=o^5KlX@qgC=1`c8o3B=Be zQv3nffOozR2?#kU5TJDwwoC)GXnsQ3pzlo1IT&z0;zaoFI{^{_I@%EzEx>?WXV|?Q z>9aR&?_a9IbpdcDzz;g=^}L+RshXb#ff<(~P&lUh*Im%jT4)}=gITREv|kr%T6?#` z_c?ZL_Ly}J({{||kS5qZw1cer=H{26;C3)?T@R_FQlrie(6IKGLytwVNP?aRw9uJj zV}w3u=A2lV5apr|wjAi;HOJY+-NXevn)Cm_*-n9!F&AmNr07zZ6VaFVlz3rpJo8+^ z3jZP%F^2Xo{i>EYEJ#^0#sC1{6P#J;I33-mdYWR{TjO_Iw>)JP=wf8@L<3wx~}F z|EP*zI_(A~*Id~dKu+QVc8U&%b>#EZT`txqo@zuF$TWc9R-8|%?MU17zuHlfzzk-#Y&x+X8 zL?KH8yXKo0ukB!;Hp)eC1|C^X3{09F{`f;Pv=>HCo~$k~Tdu))9`oho6bvcm>YM*0 zaoRcIe0<6x@`d(B7B2Ts0xOl&@S|~RpkWsi=fLUHb1%-|&sCc_7a@L~{K6^}8(&M8 zv0xZqCC@Rp*9+ED-Y+_4(^Sl#i9daFVc!1_U2=#8Lgqbz7tYzq&q3Y?{CXG+`JclA z^4_qlfC23rnQiLP9QS-)zb^^^r8YaHz7e+BP9*T@hpy}&L?Ntsvk^DJ7z{WeIFwy zl@|?m32tGrk?=*i=Zjjo!%WQaOP(fW>hW*a-q&W8d;W}iFiUp@Mxswx52A-x(*wDO z&l^WrIsVk39As8q!4)wX_Y>~kEe^Y1aDjl2ozl@8;kl&5mDs`Ai(AJz*io)`4lPuz zJ*_**3iotJw-gF9A!88$LBn19+NJ}u+n&mGW5U`TMvAE_h>HXLAr_GiS1hUl7t7*Y z_-xSb546`I@;5o#G+@8*9=?a*&AxwR09jLOCG)Va2p}dVh8dGmMPUzJRR(+jm)?}P zVubmF9NFz8Q1!4x8z<7R6ahvH<|W2SES*4`tZK0&OGc)CN@o(x^+yt24?VB{U?G7= zy6BN=A=vs=3LlXM71mzs&8y}79I06~yN5P5A!p>yEN}xHi)bz`@x6e}<~~~N%omJ% zmSZ5~pE!t{=zY>2O(y^BajTvVP7QH#zYmii3dF*;=td)Juzn>KJZTq zr_1x64tfJ0vm#2I@$MBfiJ}E} z9!1(m*1PxT@Jx)p(xWlKxx2i*4D}*B3Pi@JB`)HJZYhRN7Tuv8K?S1`FOLa;O`IJJ z{m3k{gZX*G`?2!u#bMp&g=1^6Sbvlq$j`IJqjRt6Ov7vXv7*jeYH@9~@Ui>0f6O3(_NK)dS1Omh#qujDk9K)HT;3bqe(A}^ zabf%d{$_d2d-zoddgT11Tof%sstobj)k{ z1!z_>a2AkTx{M2Hp+6kxIHo1ZJ*WSm`dFp5#X3kdKfO!DZ(R(OY31U>FQ>nZS(J7|6jdhnyQ)&vg- zKTM`o3(i^OCKKDv`$}gG&bnL1$e)tAumsR|a*C-&TBITiPL{y{+6b!a*h1(5WsNi1 z!hI_L1T8AO7MMDg%FFORZt=}weDOc-6UYP{Uz58;(Fn43+GmmN_P=YB;E_-9D0Dy>C#Xcsm2i)W_ z!a?7KS(BB6q4iLM-u$*p!e%eLtH-Lv4h$Q<*@`x1W0`YG>KYIH?YeF88g$1_W1Jq& zhSS|%ND~m4Sb0TXQW5~IZEP;ewc^ct)`v8(7F#dp!t(cX`ha;N)CC`U!01;s8t%dq2aJ_j9JB4G!!&%vY5`zt1BuM7g#eiIXm8 z?a-oJVLj_E4o+6_hL?rZy!&V#*M#nFL zcy*bmAcu}xP!c-p?(YTjP)KWb{;|2;0R13ErhDa>9F03(IzIf4I3W(;2>m_Yx%pRK zyoZT?&_}aOkJgi?`y`r0) zd!k>R`m+W;WWY^Q=tH12z0G_4=Dqjj;|1P$_2;=90TiS42~)hxA2c|xl~dhCHYT(b zBSX{cx1yfhI_&*=NQQNbJ(RB%AvOh# z6iY8$CnN3k%GRNu6t+DRpKM}>$X5TtvQP*M+PqD0frz`|=s+_EWUX0G1wmZX-Gi4WBZCWv8sL|UP# z0UHAvN;L=M3w#8f(T0mCu$E`h;5xyXk$0zeHG0fXJL}2KKoFDCWMnsfB7Z}6$IVve z3km+}_Q2mZStK_(T;#YvPfQ?_MHuxUB3X2rZ7f32+gUaD=8Vk3T@H0?*E&&k-maCLptsSdZ=M*+wDIN#L=47o0vOU^fww3hHeby9yrL$DAxd zR-&+)uYgiIV#@ERlSNPk^qmJ*Z7ABAym@7Mo{@|lXJ$x#&!dc$63dK~WW)=;Pb80@ zjI$&${T41^IbUTkHT{|R^xkY;nr|$AgH~HhO9a+3L2Aif#vN8fcNn9|fUls7y~U!8 z#~=(8!sCPnyyElVNs_BAwegqIm^O(PB9- zz_$mhDbwo5c)JF6nMTxRkDa3n2#1zH#LVaE2q;JMGPkO-Z3gSx=fnglH6a8SC1Oj4 zC3_&UA^pv0{Fy*R55M7g`T7B)9U`WNC`7uN%d=-{?;jx#A`8`ib1C{JMM&u9-!#zb zbDScZNH?5(2cK}=tVHbgqjSn5Nu@0Vb4^+M5k)LSN_J&Bb&M`A#JEAxILUyx77LMf zN4C{3h)Pp^vjVu2yIE$celdp2FGDX28lk@)QeucNtp>zYDCtZ2xY%)rwk~>}e2uz- zS)zvixSoI@JwNJ^&t0zH_<%;_D+{MaJU!vjYZ&jYW1tZ})p`;?enxz#`v{_*Xe)@W*^Bx% zg=+IO35_v8gIhNU*1vS=sZfBc6w}CbtA9><7|!BzDdqmBF}llsC1M$<#D|B~T1atk zt+@XCb|o15^`%uO^`X_+Sz+9{-SRo!3?7m?|MnwK(zUOAy*o$)3-$Ki>byvjg1dpp zi|O>%59jD4XkQX>>Oy^-zr1BycKcoY@9+BXV^WhZ%|JVA80wAYUN;U zbU(J;poFxN(3A`^_{rt?_YvIG0`JqT`wNKu^vp}S8+PWb^svj#r zxT4*S`a_g<_y1qfqUjjES8Q|@Tv#)3S?a8|ttoT90!@cWe2GW2=Vc2d&l|4FT3!tK z;w~ENo5XhUw^j)|_$KdQoq3mf*FWBzY>x?ll%loYwDx8e*;Pb;(*X%5!VB~EA=C!Y zm0Mf@Lh;wAXgoy;ue61r`cXra{5$S=Brkq6$6<_&PBBgk#_^@>`$X+9nxFCPfzu0YrOWfK(Z5aAhV{W= z<}U$HiGc@4?}s$~WBHwxg1-COjl@T^^2G0roK%q0jd=UD%$5V_tgLsp%bINyqc#Mj zf@`*qsGPb`A$sEm#Rst2amF6V1?`_vQ+4nzE$Z7Bt@`pmcX-mqzrT8Y9aDf5M&iH@ zlXAVG{th}=U@PYUb=Hyj>tHLAGUaKO-4rNI)b(0;D@kh@X2Fc1uRd#~IKVd%gq(*;`@M z#wyM3ciW+iH0!(Vv=M&C7y7DGuK$HN3GtLRD-0%3bH{B&OS;WDOlfNc0VEN9um-Ee zZ)w`n7Ac@ud~TP^LF{`uneCu!s>ECoS&dHul$9_zsgg+mrm5Mg1wdhBn9S>V zPj#v#wID0?ATNKS`qnH=ZtnQH>qdSY|CDvUV~>-d#j^X3Vyj<(pVyJE_uZK^5LM@p za!{SsFzMm8h~_#Y4g>a;o{CZi%C*(js1r@q82=@afB-FHPvlPc_`MC}m+Ls0;Pca}}f6bfO@gkTd`+zhjZD)RKT>j9Q04=&9 zkB&3td3Q5g7AOSMSWQgBB{~VXK=Ra2bS%NkRBvM@Rv~$k#C-Ts(Gu4@>5n%p2 z;PSbe87SjZ+6~8y!W3_l+IanAg-m2kM)Ks~q<9|`AK?IJbN_AGcb{An#ED3|F0Z~+ zw^KUHokrw(A&Yap{VUO@6-x2Ii-8_E&ENn+1ybEM~yA5o+G1x%|thIug{OS3AUg_b(UPdk*GEVtSa?WY!~!sc{iR zH0^V^oCeLg6l^xXC}t3uRAdnjj5#+H zGDyIDBcS55x9`$|IbTurtGwmSj;1ep)pR0jSCWSnnPoiFcU=xvd!AOj=cx$!^^ATU zaqjqDMkmhb;FMXpOM{t8q0-MSz`Ad^6y=(slxKlpA;#uSg_vUGu-o4mL9>F=?@t{^ z1~>h^W!v8IWYiIM)b7dB`U`KU3`;D}4BGM!fOGhfZz(R+*Wc(ZIiw6*PzoV4px6y- z-zgB0pQx>KLxu(XYk&o-rgAv=XmbeZu6QN}+YRq-_k4l4_X3V~LS@p!bdrLGi*Qk$VMb>Jsg$If+Y8MtovPd4~q6Y%FZ1FNxfiu z_xx2dZH3=*{KfsTArpn%Z%ug-#zU70_2KQu6r{^@ux_^(gQZ_6KdHh^Fj93(79T{){JzR@;mq-~LVk|U0{>Gfn9Vlvmyx-sWg?_Yt=;BY^d6>R^ApH;OS?*y=^~S(+ zjmUdl2oTe^m#W#98wX$g=Zv$EZcO8bpyZfDRpRx<&?;@VwvoIZS5Q*gj0MH+*a78f zFTr8(GZGqvn(e7R6uR7Z(XCio>nd{IVn1g?j#a8{?y4z%7EW$_*Ll;qT(EOO^NWv6 zjIDcetnoC62e4u~q}Du2NJ#!IUppfgkj2p0k2H+r1$n*nS(zVOZR*D&eM(-ShlS-o zSZt)WLP|uT&7h=o^+F5yb-EVTW`oC=)Da_cTro1h0yig-n!GFsS~1d+3+4?kyb1ZM z`%$cKsLTUge4W{4YH#68-udGsfIK9*iEcRvzj|O%u*)t~7A*Uvk1YNZ{)l@2Rbps6Q0`na=+lHd76P?! z<5GM}USYrldKA8mdv~GE1)eSSDC)X9MJ!?LE8+9=D?!UuzOvz^x`z%i843uqeX5TBA<?Ff`r6^4{kUSBd-JW>>ZgtF zrJI`TH*e{@=CqPyK?&Gy2GY^8BE|YYdN|YZ-jjO=L;KFI@iQC;0HfsQ#@M|?fjTpC zie#QhDvph@jB1Hv+H)cdGkEJJ1GFGl^lAGZH}|j3oIGbNSZrAe(-H;bEc<8mN5zp- zoZA&w!Tn#4hpnIgC-=P(#bcTJQD7V=W_Vra4RW)7Z1i24YN$#Zb`d>W zyiJ5jL6=96MEy*5QNP^q_5`<8Wxjs35Mk36nyt$aE_R!FvQ4A59Rq>Ee&SfO6Lah! zYRvDaQtnC-OqZp6A(j^w%u;{-p>P}6Rj8BAKHG}V;i3eljO3#LO546 zma>yEr)_UqdJDDT`aTovDB{X+B2Iuj$ZTXGeqgM;GH%_|Pc6otQT8Gq`3(F;1w0{X za?f~gwYBj)SF!wkxpuiW48iRl1>lwI5^w;Ho;aA8;6$R&27sH|PM>X(ccN!fj>(NE z8sIR*4!#Qpbitj9g_9o{E{Yj6&h$ilCLj98fLaFsc!dD_-xT&g=^h9_*Kr_`cl?Eo z^Z+$g&&|FF1l8svnWct^z&9$2-*v|DM6-y|=f~F9NqA+i5t=bRuQCMRa7q_OOGGd&(8Bb`b21%}N1_lqG!z{#)30%))l8kMI2Z1AE zvGBJdUrVl;&r{=%@A|yH3F^6oOAm}yu88PWc#YU9<5@_mP-aS$60sn6nkL3J{)&*5 zFye68DJc!=_-NsIhwtv}?^`}vova}?i7>S<=wj(J82z0z|Hu;Z=rEw!w;9;|a`qya z5XnE*`#C^)i={jbI`#pY!wA8h3w$oRUztC-Htw)hz@px;Xn`-=pDxl*p6cO`Id^UAhNfxotXB(+;EYbJtYKn6X|5W0z?rUBvQh zY!v=5y;iiOx^Jt$AQEaQyOM`wjH{~f8nr@iqiQwk5z3>y&A`kR(nj^oz6$F-`$SuqZ z#;9>1%w5jSJm1yFUDw$&kd!eB7h$$D*XBowM8F~uR_uM@AB%ohz97XmsE@Umb|c8| zh8%X`hT?`l>>*~CvSWSf`td&IMviYHH3EC9BS00N0>=a2Y354EcBaUjJf#SuklDTii;L7>7 z;EscNvk;LVv!oOP?Zh7OQqhCtN8NX&CketB<) zv!H{?1khePi=@7fP*mWQT&UL9zT56Uej9$@n}hfLB60N`ITjNPLF4A_3}37^wi%Q} zaeTWS>z*5wQxErW*K*@I7XP^)WAM8mc1N{V6Cg*=RE9j-|g@ehNP)eDVfw zFC(x=dv10j{@v`mSxRKYYxMK4%ZG9x7av`C=noExLWQK)$g4fna>aRCmcbdYL2$F zk7{SSR#L~kvI~@XGN}I;{H}IYsaP_TJgz^n!P4Z$ja4>zDg=)dv-j!Zh==08dQ&e= zdi0bUTS}E`bXrW{wdhFsiS)Gn$*B7w`f7Mx&QQ{#nVS8`F&|kUuVBt3a>b&j>+u>} zstNk9SJ}$)Og)x%4Qh2jbWM5xsGYybG{0iwJszu92sk z4X4N3>qYC<)j7G#imi$3nb?4<;0?z<=5c#1aID2`3?1%D2gZT`Hr@!QcCY>LKc(J%pO3lZQH&2X@UILNU=i~=(>qt6w=V)b zhUpk^)L`$G($n|YLtiE_gL|XdGhKr7hH2na-ISDRP1OvY z^}vQOvV`x#6gLW%-|PZ&|Q$6j`=6@Ks_^sytCaqFEq9vu6E z{UU1Nl&Jfw6yQ;qzq1YUK+vOc3>X$U5SBp1!5!*W2A!l)HO64V#q+mvPjUS5rP#Rg zqz#CQdCy}?8|dt@fB{w6WwCKA6?UqY0i=o8-HGd* z`6t&qcSz1WExPlk`6NE1_5c%iUj_y#a7e$1?~!aE$&PQ|raz>_5*IsH9}i>yu2lZ+ zrU#y-p1-&2I+2Yv#OhG3KxN8uOB(ai&ZX};x$$O%sM{y!} zPA0@F_hZ+MlgxFI)XwHjAST7s^)I-vX|7@Yy1bmme3frw&x&Dk!Po&$u{vJkJ)19J zGk{uiA9ytCo8ASg<#VGClyY)WeNq0*ROF@fqfk__2rz$it~SU zK*CMBFghp|554oWY^-j(Nc}CS-o99AdJcC-Qgv|W4YOyMcMXY8f2`kjES8jnQNV%G z)pH=FakE|q)o3tL^-Gf%@$z<%`r2>~IJ~(b3|KwpP03r8M9-$fxCvVt!cOTWT<>^( z_A0FB=_{~u#?I8%!%csN>amZVABTl9F`K;m{Okqw%mIb&6HVbrMb)mEI>!+?wu*h1 zuahhYW`xaluLC6IPBV$0$eOpyt@weBckhFS=A=L5xmPvo8rMYW6XXOK^J|-BdAg6p zBnRJ9;tYl%NB$2^bp6xDXB-2Z=EMU1EiLeu#Pln99PyUd-07bgT8=7BuEf9p|lS#LHcaWzy>S+ zvhw;vl~d$`*GRmbmoWQrJbUmt6eDA_JS< z`ut+EzxgWBwwDQX|7<}v{4*=O!LCOm&bWeZRH20DEcC7!bmI)s+Ri_GhY8PB)lqzd zK3;Xf+k;@rQL63|3dDNHGVWAGQj0n8&LFNEr}Ga^+b`}l%hH4w?GW?i%0or*arj>- zrE)*zwHcC8NG{7Tkw5hA`gx~cNF8Ft>EEEqdO~@x`tQ%Mh=_{UBaXMGcCXaMcs|#bv)p=E*g>czkB3rV9^rOw!m%H!sD65gGSJuxE#5LpDnWK z&x8ICRHfiq7|dCD5kUW~G5Gu|hylj++n$Vg9RE-2vA0)?#>lmY2wjMGezPpMS_R*r zQVdngLjV>2W%&F%Wfj%BHB=4_e`B*K4^wr&u8`u5oIh0P>9Hjvy|OL)#Yl=gPd)uD zw5w~d!$pQH)%ZIww&XvPC zYmKQ6rT0g!Q9ZU_-^QcsgjaM?|1Eo!6_mJ6^{&GyXln1JmhMIDRDVX+(ZevQ(kP0{ zJG5!K+yasRYr>zg?*?&?zrLE;A%>jwv*>Cgc$M*d2UMt5Yb4+;M0WDS!s|0iDSMez zxF1v)KFl;@MiOc9pP%Y|e)I!#u8(D>Lz5BTrPWS}#8zA+KmRK^zO#(BJCEn6dpGky zQ%zC@izjtDtyY%Ha+sX>;OU$C|S09{Hy@&Huf> z>DCtUD#w^d?~h`D_b&?iO_1)M^e7yF+KY_(bnk_jA?6P4@$jT1R0+??S*ME6ul%JF zmhj)ATx@o5j#uq}PDIccWe3V$6Uh0kW1I5laa&SOedsDsvK}Zo$PJ;vCjAgSew=gh z{IAavaSF0uh10Mr^o5qRh^h(Obr=zh3|3$+dHu^40?jSaM)n)rVoDwrT;-fN+ zBbqK1EODEI7+vrt%LjxQT!F2?(~k22!0`F>Abs%y=1pt3cqwyDq`TEUnAS}(z(@c} zjn&B^yZ)C)D!ZCB-!l65kj4K-rj1x$f$RFLEXUeGTh{P`lGN<@>)r95As+%3`WAHX zWBinY$g_~b%5j_~$2#_n$pBNzW2dx#HORD_xsO zkm3H5@W~?Zfdwy*z^yg_L9u{7JN93UrDTaUu%9TfwzMw0XdLEgmS+0Emn|y<;>a`! zgB=SHWFAH+j%;>}ceQ>h)U2HQi- zgKg=P9u?$a;)0lJPS{rrN8HpV3o863`_D0ZfAmif#x%y5#8yP0g=TRdHi$>Mi4!d3 z(jMVsHsG`Z63H4FsT$psvQBhu($p`}240RT5)zLu+v%(ztuN+(o1R9g<&alI@eH-- zu!#sO{rsY_L?+Pno(&1bR#P!ukJa$HA;d>K#GzRgIgR~2_^yuatA7&RrK1`y+m=4x z_WyR{XtU7xm%}aEhPV}MmR284ytp~-XTOu-8g)>U9u)|mUf60ah+-RyJ-lfDXil#K z4p8h(K4K$KAyj`WIV`%%t6XO?40{fS#S&ZWShRTvYTkS&KKjeQ#qvFX_ERkZQg7I8 zPd|jP+(DKQ59CkCV*N{x9e7(>{BD7@A;NC}rVk>F-0r7IapwK!Vdps54;Y9A2h$dZ z4*^PZ%&W1H$rS^K3G-47Buz}$bjs$sw}rrQGssu112((JgEL4dIZcYi&R;!%RRVqv zwzr(jhNd{?!xnoQB@6sxU`+!k5*l!0%VGfa;B{BCO$JO=Z6DoLgb7&|_Hga!@fKxg z+3`{wexmc@60S}-x0wZgi33@Ob_B;WfvdWD-N(_~IX2zd$Z$Ax!B0UuG425+$EF?m zd}lXmes1(wOUq!_k8=IV^PL^~5~r@qV-Lcf4*fR>I4=34( zo}2{N$>NBCj9FV&_9vA*s|JvPV#&XJr1DSsvr^>quhp9B8sz=nB@6~469X{V@Xd_f z=5_oGV3WvRP_#DzAP2C>L&NO_^-EIUE54N?)pjVPQG5}T!80w?pV06qPb<}QJ?rWj zb4baFehm?9zWVIytOIa^HPp6f_vXFWNk}wfs@_s~ELmQqJc_Y!ZEkh=YaRX zFl)fjL!3u?NhbwAWW_(@qD8Rw0QMm)wJV>V-5B%IzPMq8 z4;@`6N;CgdF>k1n&WtaGZTt%Dw4`+UF-VH&eZt{7+4O%borPPI@8kWSZ7{mKK}rox)O4PUUT?QWRjlAa2LO#Q6f5Ly zW}R+Yh{`$1z~PLVQ1#mPx81Yoi6#OL8=IS*xh%+_H_7q->gU*Z5d&m`BZ~el_y% zB|32>iLd`OX+3w(61KGEL=(eye1=5CUOHAhtNl*Of4jmEhlLQ9jq2MSL37}3nX7Y* z|6&{mxwT^qekDym78a1gAh(^61=PITyg@Lk6jUa*U(7Nuwq2gygz}CSFV&2vg^M5~!y>v=}^ukSxp+v5jvl z7upr8=lK_>SW$BIFG1X4F0yqDAb)GauPGY$Nf4D`J;H#pvN=#3AO)?uz(jmc?d-k| zw2jr2({1n~T<(w$kSdF8ZC*Ve+=uZpTYt5tC%V0Zug2a%Nvqm}%duK6x_^ZJZ8d^h z{l0HLgbEC3djLJf(?6y)fSf?{15Y|!?X1?UR(Q?_3enzz8oo-%Bp2dN>x0g;0tSK? zA&Px!o1U`;ql#G>(}8i<6Fdkqyn^*vImP@BoB{vpDOv@^eM(t2LU%T#?AHHSR4drg=CY-7TMpfW`w zCm?j#>LdgH?*~R21%rL&`+>1Rc@9k!?5A1@ThLkhCDU(b4h%0|M#g9DG>@f-RZY*k z-`z(w+}MrDHv%oISo6-CpH4H^bX|$N@*=3&(Hvmh+g5pXSQt6T?kC&ms~(STI~ZB} zV~=j(ozID{J!NLtpJ3(XJMKv@`02!YK*C#+(xIbi)(bq#HNa0_{ntCe9itk zl>UpI=WXcN+u!b0^1=cxX7Y1?-Nls+ScH?>Y;OjJy5g=@1d!FjTvd%6#l|xHjW_*Q znFUjBlnL7b{6c;Dg`mwo$QTrUD5fmc$kQ}<^NpO*C(iEyOV-M;cjvKGjdDScbtI?Y zuM$xHGtA#1PYWmMmG!qJQ80arcw_=YzH`zZ$tC0tK#jN6AMm1Hw57RirLqFNWD1Qw zakbA46NtB(F3Sk?36qyx3GtYu({XW6M?+@pwWvg@PX?z;;ep&=uW$8qS?T`B??E9g zVX>0wOGFuWXG?GXNK`3~@3%D7WYgCB;diLxCO>P8TUhRUC2aetS?V}p;9)w$M$bc& zX#Y=`vtiyu<^&sph1xv;pIK{{GJ$znR0o>WyvH$`HEI5`T6#UZ|7?N|9V}Vw?q@h1 zR^48!U=k1NBKys3AjK67@ep3NzZZu~FL+r_yjPf)4O%_&2k7N*$4R;=a8(b`$iRCl z#7E<7OGohJ&eq?Iub?6;xtkMH;8V3upbtHKu1e6t4k+?UkydlnV)!5j>w0>CHus9->c*56Mm!z)m1f?T*rO1RY!uxXcsBYBV>m%x}F=R5TA(08MI0i zaK<^Zt#y*tEo`0K=fL=3KZNi&4j}wlNCQZ8iuo~-;qpX-q5-0RF+?TLbVQp>MCEn+ z`UN(`UL=k2_`*rKrTSRC&&{#D^LXHb)#HKU1K@?h3a4SEeQX$x{Wdg*$g^knao-1DuSKRC*X*mh zpQLnXTd>~64d(l!qH=qALmodqbgS)@x>zKZ)Qk?2Uz?b?5!S83f@8tiz-0pmT7iUv z*{Dursg}$#ct0pF=x;2^rbwIJh$33v+(p}U2)p<3<1~2h58A9mePJH4L_x>ep zO9*`HsbXL%|BbiqTQ$9HJcIbNxo;C91L04Zcj8kp+oGy4QbT%RZG@B%GTK;s7V$!{ zg|}<&T8=_?QoE%;ncvv9DfLN*;V+Slv0AejI9qEVDr$Rv-9tI%gNis4!ZO~=E9~GR zjZr5FXPMRbPY8(z!;g%QNm#dklWupCZXH;8(Vt(*HxS}F^ehX|Ai^$~Lk?|#{Y$o6 zQqlvFpz>dufE$yQcMuu;Zmf8$82F(yPDd8a;`hda(r|M`!D zI07=HdiU_rP_`{OP>IfFggn4Dj1T%Dds^qob+dWJ2Z{edNa`%AP%f8OA0R_cfp34Z z@?WA{rE7)FAiElGvNVPcv`HV|QwEMsOphdEFFE)WhxGIeO0xUnDF7Wv!5z$A+Zs@5 zP_MY=H18>X*OX@1YV|k0tr+h9FQJRt_fEr)C*Rd-#eZ#);sbD0c>7Sk0#4_! znXe4&19(t!VAX$zKqK7bWrKEG`0`X0uQ`ci;P(UZAT7@(DGcIuBa1n&Z?8t2d!dm7 z)pG2B`;aayja;Kd%b9}_`a3~P4gx}oLE?!AB0%hA_-e26r<>gW;br3M{PYFymmm8( zbA0UEHifX_i9EJLRB%3vPp%d?p9I4ovm!=ayj*;lHs51fnr1ex)E~9@?$A+CfauAp z-^cpp;8$Vc2Fv2tX+SGsCZu}Zj|O>;{U4$>Wo%-B9Zgjk{)SnbKT5c)1P!f8sh6zB z0`gp}4PyC&<8Sj`$M!t*%C8_2=yJvVx*COQC7YmV%#Y6$hV;bUev7}aE@u7rRU*kH zcFC}w*hIhMJ1N03NhD&X3babfb!ywA4iVEFyOnpf6rZbHTKw-SElE7W#3}9SWPso) zmevqP4~H(S%4gS6+1;D|T!bTA;jeo;@=OGDPTb`@Rz#PaQiQ z!E3VheJO6m=R}_(JYX{2%IqYT!?t}oJ#eKM8?e4VU|o-23%1nwEq zWBvis+sbwQo(W=AK#=@{pcPm#A&DL$gzo9gtq7|~^!6lS1ZMEn7;1zLqlvBz8QuR_Cv?scvxp~_)MEd7Sw#RZxvQ6D7M8`; zE5E8)8ZD(3o(SlV_>hi$e1k(5UEIv3#FPCo5zlPwBiT~PK0gn$Nh-yP{Qz;Jgh+8d z&voG&thE1u^8IUd2FVM)ht#l`PofKZj9TKrt{|0LQz3;OMUkg9FRIoqbAKl~g?YbT zG6F~EQUjVG`mF#YJ*yt$#Cd?61AOLy7SK0S+94P@%X|~cbe6n zD|u8e;-X3TnkRig%#c2XqvlJ?@~2BLlcj2`Z777$nD)z;;h=Gel~P-j^P*Dy3o~KR zG*s;c9m>jSkHgmbE0DhML3I22=%Rjq|25=Ri$U&5;c=m3XOAA&HxBTcGF7vQ6@{JF zI%AC&V3T!YwFbv$Znf7}lI#ck0aBl}G|i~onP1{)o`0IEF%pa^tjS4-&eEQvVI9BI zI={u6no-@hkcW1wTnFY1(%BWgbx9P*dE~KMvgkP8Tg3ABwP+6Ecix#lZ*op4TbUtS z%)V--(HUdjti)ioWzKk7Kn7^5HVgs?>V%faQuBu59~WbjZfkggTvy6o{uiQKJeK8t*vIZGKPa$dO39 z^w~d-;AdY7;WwtVgpcb_>BA&wCW!Xw6~4qPxO);m{6#p9()xawHVY%?nvWlwCydb2 zp(Ak<+(3O><;n4W;~R*uW0ixG?pG$6bmd%u~>XEw1)q0A?o! zqaj_5zcr99td4PM`XSXuD(&5W9G}Ejzw<%i)#l+BJh+xP+&crrD^BEZ@r(9orly9I%{8FUf$p`QhEGjP#9*%i|C5dgZtl4(&DBFuwwA{SCys?&>lr41&{po zE~$P}(j6kigMv?vF_1;>kTqKf>z@p_M6`*vsXQq}?;EE)?HUVJMj;n99{lUJT=T$9 zx3AYc`Qagl6Rjz7)D-O9WSUEPll|REXsD|o3%8z7(0b|mn^5-#Os2a`Qt{m*+6Ri& z$ni{xX(TddqLX4GkaM;y%qE76N^zNnVrLxs^Sb{OeyX*@jz@T0Ez=GnOw4c2rj|<5 z>1Z{bylNg=HpXlWKF%I@@a$mgLppbJB++myePC0#7&=HIPV!mK&~3(GaoR-rma6dR|x&sx>sF2S~`!N7Cluk3MW?k`BUj$h)%HO;B2lWH@t5FYGYn6}X)%P!)(J#BHJ-Ao?Geo~GKWfIm zYKp>`I?Zg|a-u);cR!?r@|-Y5L=moB+O$RQdLnE#IATg(L{p=jx)ch$umEXiE}QL`)~=BjA)1RZc|5*buIpvsBs zqAh~)oKLmJ&LQ+rUTqUPh(1*@!>jS`pSN8wNF{A+Hxs1QzLO2CLcea8xlpRphgGTq zC&}6!8^wc-KZiuZGqMfD&O%iQ)hJ*x9V6!5c2NQtz;_NU@TkB(YEaZm)-C%~+ZO%} zIOT*iFs!dtXOo>p4T*C;%*I3Ps@htAY0Zz#%GeW{qz%m{CruC}HGUdzD=y5^wO4{Cy77YeMn41dv)Y1mgJ36eF(!Kw@=Z1{hCA*l1+(O*Ujie{f{xElE{pj>_ zCXQ+MZ*3EAR#ebe`EIxfe+;8CkNad=*OI+HG54hMl-V)dcZOB zW@@8`ItTdIW0?!lAoe@dI0sb;murTAJqjOHJXQgPTo3(WFNM&aex3;WEv!Jhd09Y_&c4?7cBnc)_!Z$B2d0xjo$U8-_}^yDH*Izw=e3VU(|aMZZ^)@^=iw2)T; zZeMbKbAhY!cXzI-06@|yP9({fdFEGX33eEUXS$VliB}u`lr@c%_AFrs|BwgtsXCVF zsrDy18$eEcyqD{pV)SO5rwrSUd%v{0OH6NW)+daJmY4F`PZsU%_SO2$Q%b6Qsa($s zX|e7aWV4@7(=FkD@G#+U{cSR>NT%5oylGd`z~4v4IK0F>HcIaZzeCX0+{9%ToY*py zVJoy(*=CM<*w`naoBz-X_NR)eI^BuB;YYiniMx9bfn_qx+zij91@BZ!JO)>8t(*_! z=W}ynRe%tM%6FdhrJnR2KP6(qfu<3kRP+=3r(E{4A9n$5yPzE4M9bT>;B5q~6{I+Z@nm@s@^Gte=?u=ZI5%8S3Z z&43s)bioTK`zzHiP!?%&ebmC(@lQP6?aH>fpnd{}kGWJWeRB82&(F*{RD z&E86@EOE^6*s|9B%X;y@&%e3(#J(qJoCfmetjW&rd2#5?4fKUO5f25A4_&QhP_7cj zeq`FdK6@WpT{7ez7uF41=Y&dpP|J1*QpXIgas5_84LA8xer9Lu+kJGC5J!71UTrt9 z&a|QQqA#S~$#7`LF(LFT8~xw09pB6wdDe4hT2c;Bft*;d^FnlufTgZRvS}wTIQZJQ zSg>YdgV0}wjmzZUt@Z^W=UWZC+(Np?G^2<1TuSnkgTfLf8mTc%njy-0?nBs8wKRdX zG}*C?CDDIuq)4wLLq4xwa^synGJ5b-epJlXaa5S zUpqIo_d#Ax@{=oHowlT@frave;3{l{skqLxyYG&Pf}aN9ZH51sS;>SJ z@N$EHPYWIXKB7Qr!s6n<vnV9)bd{XlLO6_ zj5dCdt7|Ln?pLAa#rp(-6favBA6#lv%WWI)Vr?ro{ZO8&RaOW-HU*Mwx^M8EXJ^>}eKAT+wRrsSW z8`r;1DQ7k$dA93)sZ=f0~y^>VF_Uz3ezXtGzy|EM%4bflPvX~b1MP@`akH0 zetpRvU9@eoTO!pB(xys_EN&dfIM}&@@a`l@A)^XOAE99Cx9EVa6H69wkIMzlK{e># z;51|V_S`m5|CNH=rm$q(cn~m~`DUX)87BChYNA##QN{5L6sf1uO-wI#Y|^ptFnQ<9uy!${sx6~G4=Vp)*?;^xYI#k0Tj|At!-e~h9cXg+*QUoC zT3kpk0)zg>;HW(}oquLk@SQL0lh;ap$f_qI^B5TAR}rv`V{+jaL)5opFM;Y_=({AA z?iYqXA(mMp30SxcveW5E!omdPFsNN@z;f=h*(P=Cv&m_u6?ZjOb06cCpYQZpa;|39 zUz!u3Frdx@YPgp~v={uQ45No|D*Xpa2wfs<@<)`$n->O38!iV@(f7`bNS-7-ToNLs zUOm=jBEMdXGL0Ik0{PeB|*eSs@8HtpX`) zA73OVPo7e*^QNGMA0rOBWY+p8sBSW-*UFSbtOAmcr+(iYU1LrZZV7KO7_iy<#=kLx za{7T7*T7!tYx%kYUg%%D0wO?OsG(#3yYyhP);41 zcY(_Y6IP4{7jzliOFS%EPyUzo?KMl-xty@B{|Z;;l}G<&%cm$f>TvT);7HFI_gy5k zi~ungPe{(eOD16(w6g$(@W$`NE^5Pc^m5>wq@zU(6jtK>{7l<7qtC0ITiL|YsVwpx z-iXi!-YCTpO|0{tthALiHvflh{`@j9sT&KMx^eUSEt@y=;C%pF*U&C_2}HFlhFRKEva<`P+8X)&ukA+zgQ?U#d-qsqNPlw zeCeS1>cR(R&_yN>YpX0#JQK=Mv9i;8X#aZl;uG2N%%Qwp6}l#xl-NEri%wv~h1y4O zcZeK!<@SL7qJpO^tY4Oua$>xI+EO-o!}3j#h_pcQd= z^6=hoIl%fy#z3$mBRt1gKICiz;A#)`xCg9thaEKK2wFB|RnHmmT8aXlFJ1tUrKUz# zh=AhaeeAD`-CL<{Vl`jR_74{RM8MkG#RZyRu~2<;jp$AIase18A08TJhN7l?4T>4c zB!9_4UIa5?|J;4PGyUn$xVM91peQKH#)Xz)06d(ssrCkIh2!J;;-L+d&TkdU*2dnvfp=wLRFxh8>3Qq@~24C%*Y@Wp#Q$a_E8Dg&9`bKocx(B zg~&!k7Ox+XwH0}4x}^(&!7W<;$9=}&;mlC3gjP04!K|l>&K1)D0WOI`!q))I)I(wp zCLR?Mm7l`D^&P~B0Bvf5B92f2FTSwuPxDzM(+MDmJRm2w1r=1R#WM3@O!J_Er$9*k zR6`iJkdX|bMIdy7jC@@#+;r+m2FP8aK)hqGv{F#Lu)P7dP4;~Epgqv!w*`y+2s;4eXqmPgGoTMLPcs6yhpD>)V} zrDhKG;m_>213QI^#tozG8-KLhKvz;p1Vv1;o;8u2bG_Nv4zeGi^K7~7e0)t>giA&w z&7zAxWwf+%K03Z=bS>3q_B_hvJyw}*C?={`x-RZDC@K~*Nt@DkfwO!44j-WYY=|6Uf zugZM;vx+)A60nZt_7q2xd|yk-2i|60vIt|T0fawft6hif!0ntH?7^zCEA(m`EujA^c+kjN7#DIxuV|xXrE^uMo z*^Q3?y4MbI1pc1MRbPP2yXWfWgn;%pe>18~8UN`x8X$R3la!}v#eZsJ-`aN1^GB&b zQ?-Xn>?u&lo3jvExPe5Z!Q^P#B>hVzXT?Y5%9qPh&Ewx7Jts9Xyc5!ySj1fe$V+;} zMStjE=mb(FwYFp<HfgTNd6m@s-B$CpV1vl1H_-xx7-0CFLWOBt9l_a8Yswzmr+ zI-+4Xu9*Lh>=)dXTUeP}fkxojJk3ltZXdKJ96-qk7EDxAiw4ihydg64l!Hm94TufS zK-G(;gC{#IAG}_4jHClbb!^oEVf?tX131K#@Vw$wy5cp1<#KvjBHLe$s_a|NSE8ma7}jL;hDt4;l+Dn;GQ@ zBo50Bh&3-GU2e<{!m$FH>PPJ8Kg-QV2LNA-_IEId30u|$*m+Cy+ZtDnsH}qrqsc%B zGzkvqv5x60voSXO`}I8dP~MML(Q>6QX#j2jnlE`vf?RwB?h}Rz`1Zps4UPjDF#Cgq zdp1jWbtS76=bFl?w(ZyG+b%IBTEfIwJg7RQ-fApFA{Ibb0)I!rty*$e!OyU3&W>d!t*8G;NE8D%O>E{;gz!~rNHI>GjdXnHV_{_w zlA;ldD`#TkjJjtmtv^#i-XV$YL7Q!;PALEWX65DG2l(_2_eEM3J?3jlRK-A*!f_lR zYEEPfBJ5Kj#1a5e2z*Ak)3}xnssfXs2S*N1O0_t5Q(i zDB?wg>ZW9{ELlgD$Y*8~dWTfFyuFSNJ0hrJG5}R7-{*Szuya20F)q{=0dvq%)7m16 z7M=O0JE1iMlSru-IUm-j>)ZC^3RH5(&l2CJBE5^A*FK+)xqEPW+me|)Nr~RhOfY=< ztI1!^HLu&%(*19b;RdQra>AnZE4!mM&eJE!Ov!DV1CY1F_h0|LW^K4S3z0zilBh>< zz@2kWuXB;0+&A67LollqU9s+9lhwu&XCiot#hAqyAY~TPxMd7lzMF9jl_K)sM{hKQ z=0Xde&}GDrK)m=UD^{KDli{eU_T7W+8%!5SChk`Khi4gq&u3zfrDd^Z%u-EHkpNx= z9%>}Gl^>@=LXJ{tCc8sgFxid=?m)!k!**#RW_uCG$URVf!QsP^wy67_oi^T3kC*QW z11y%*nJ3>#yOH`et6D;XiXnI0IXFutHM_L1;dLd;AJj|oXi;`zq^xOpwI&{-Gebz7 z3nWDGpZ*u&P>?%YE2&9M#?1L#vap}^5`h%zY99D{iweX0W_5?3Gd^6Sm7cTQ{+teN z=&L@3_>ZO?T)wp0bq0k_vi!pVHLtk(EfHvd=2zerl4W;%bWbXnSa(--FJ{o*h<)Go z6*q)YyOXg6tJGW841YKpleL61uwiWkfYM1AIIuDuzvHqyE3^1L;+{}de)k$_$m%=9 ze!aTT#=ZF<_aDw%=A_rJx8vr$o-mOSWtI-qvQN@Ez`^X-ni!<+D?ojb(Y3FB3Xr%a z*GyoSoF#?2@CVM4;{2?i|%wAbCg+B&T}k=A(C{e*0K@O_g`?EJ)RUFPIwM{z-|ZxA_d8k7 z^f>Mh!GC-Q3Z-n8i=$-Q zK8|)fm(r#uHJp~*FQGx>mFx$81VmH8g2WMe1n^xGP4$w@i3>rp@2I>g;i^=Is2ZL` z2dA3;4hOF4d2IRNq?1BmbTDXi;;`DSu7M}-9Z%*7=H^sIffuBp@C=qGYV_DHyn^tN zfxAvWK^DRLb;G^K6{7`0E^dk4*!FGHEJybMs->Nc*WHvjqE+z2hY(|sF#83>wy?U# z)z}XHRY6K{N2@@4WB#6PV6Bj7A|zz`rTM z3d)_hLCku)-0%XaxBn|Qe*;|lR9vuX=yGaXS&c$4_$ETs|2R5%{-<_m6M5>R&Lhqs zyd&{3XpkgSj`!8^x>{Kb+0UOl45}!rey{%h_hIs3QNo`XL|&PRols7&?^jyonNKg>OQx=md{Wo+|5!_iI*gidyRL(LQJzTT8gFPU>gVAkxJM=ax}^5M$j0 zG_PVxpVm`Q>vkRWKgg>`u6#y&$*x$@7)qT4invwjKu-=bWPFKl1&Rp&Wi5gGKX6^f zga|@!s?J8ezZYt7JkJ@CxT7oE_dNJt-_*l+@bYW%#RO>2o`CcyRG{$ipsW4ZS~a8D z$>n)_Bkg;F^U!OYq(#qc6juu#JSTeuu*(@Lg^@~B$A-NF@0JVN6e(P_f!?-nOw8FW1Z7*yo5H5s&|RagJIO606fIr#e=E=MyOyr($#y= z@fA#-5wOxpq>v%aiJzm+hrbo@RnYEQWJZrixnC?a{!3GTWxmQVE&^{g6R&2PwqMJI zQqoP(bD^b}#Q91E;S4GxJ;TbuAm$^IXA`*++U?Q+>Ja?*%Q5?YON1%Y}Z3 zi>_k5(Fv1I-V{4cu#q9HSjiP2g8R{!i^3P})iC>kT{$!EIylK!%RBNH{y?u~&{n@O z;I|oR<^RhVh!3thYkdK@O0p(Z&2>AYr4gUXmR>XyA%50Iru29z?bjiipZAypJW;;Ydd4LuCWlOO9SP5mxIoFm9q?HU4u6{r zpT;sS$frw4W%9;*36uH*6%~t(#mhd8sfpHX1;HLwN^H9rs6373Z~4- zPv+*d8uP?3rS@l%U)!W2;=g5=*GTeESVQ}aNEE(_XObxteZ@d*b7mkXNL}}{5zk9ZcL?;hXRI9YUkNhj@q%{J|pJC-hGIN zoDpgy3;Yy#PDNW+5fNd^ZtZ;sMSX5gagt%Y7j{mhxJNUrWXQv!%K%aZXXHl}C4}Ct z#&(_)R?5e0a*CT@q5Y>3`#WX(N?+inWiAwzHv+=V^La;cS)ne%Ey&BDj->F7(7o`ccT;nTp&hor zH`WfejT0q0;d{0H!j>f&t@D>=xf(EuU;+>2{QS)u8`cJfmGlZdY7~KL|F{->QpW3> zXM`7A2~vMDka^^9mNaVvmk)beY9p#kZzsj< zbO(_sgfR#0n*KX)h9;d8*-Wv$x>G%6WMD6fF2tYecEyS*5}3v?qwh19bKBcy);E)tlLm zN6aU8KF5r+l9r4~(0PG%19!%9_pf#t>@T$O-mCPP{$LZeT`W0!<93&-cd|Yd;OWu1 zy!KI|kEf&vjpIM6mLXAT>7wma=&$uak#TZ1K#3B!_OtD~Pa*Lvkjnt8!`;*U>!8N! z^PfPI?c*luvW^kEaVyMNt~bFc7To`Fb(urFT!HYYL3&?@#vWYz7(ugw5va1q zsZyou||d8>iAXTcmR*OlUb(d)N_r$%l3Wh{uR%d+ka z+e8lVZ$I-vhoda+?!?B~T@Av9cWiMY{dey`xRmnFaZJxL<@WGp9tSCP?$l@PKp@Z1c zOus?@z}7RutI^u*2*4%%w=Q0nVA*{6)Unp!0J(K*NqOTXa&Dn!qK`7^FV!8uYIhP( z2CU2fS}Volf(nYsOIB=6$Z_lpb8NmHqqW+fVm@<@Vsut|F--f@9wN}53MC_&?)(Sg z71{#*q`H_2HF$i@y^ZvbKl!AUNWLnI24=c2UPEtBJVL{Vk#&k)6G9(Pvg8)@hl7i` zp(CR^_51fT*e@Xy?k<6)^Kvz_Xf~IM(L-8B3Q-QmvV5v|z6^2~yZ2oa^)iq8^UkT; zjW{C=l00Q6AqqR?;|8Bf;d`V1spI$Y1~=eh-`9j~uf44)_}hCrC*$w$7p~b1tiq6n z?Q*L<+*EbH98U-h5G2%KBM6Vrd9bP2Nt@r8{a|8sCO$d!TU!6ucP8JCxiq&-d)62wtpG_+)Xs6 z`zO|K=Xey49bpFLyBElhm7wMG8rCd4RL0TTJ4laQr6RpYVPO1$AU$I7Z|YBOkl!lH znJP&9vz^W0Q-r8P`m1zM3sqvI9Uzq&R|HltK(1DG0tXShzobZ|yj=H|Ma$9l;`rn8 z&q**a7DF7Cje!^?&*@M;GKns~b6>I{k{iFP_D*>;uzvV~TU$hF zgU9!a9NxTp}Z)%{C?D#@|zceI$i^?)7d%K80d1h77i-YF9`k;TdmO>tE?09Mr^> z*Bv7&DNa^mJF(Ty|G5sVrbSfpiymI0?0mQ^Ha*Rt7nvgr>ezSxU&gH~N~awN0%0hw z0Mbgsns4N6>x?682%UiZ1o!F+y1$$Ug}B&h^?r!rgs(}}z^t{uUmalhR}cYd?ibfX zQKWIRCJ*&wLovJVq>QuPQ(7sduNXzb;;Cv^kc;+mB@(8cY#;E-?30i~Y!}ve4+M&3 z$)@Glf%5mNrWeEi<|j_pAJ;_Id{F5ngm=7(Au2q`8@l4KRW;GfrwZjKvwA>QkV=)W zY*0|n`QXM**Ho9M*5Fm0uCD>FZjj{M^^CFlrYFqN1-Tq5(*3^Aw|aiOZgx0bz9Lyj z(=f0f@v$p8u=;pRWdNR9zHzC)N1(r}5v&k*UYq`@k6e@`U@#2FXiS~~5^Qvn&wOur zCWwdmwPOA13gRBPN21b)mG!hdMo4L~HZ7uB=2`CLh@u2dd=XeGYPja_V{tf#UXGpZ z3Sc3Ol(3HcYByoY$0-geujA!)tHs%`_qRI&v(_eDP^K{EWC0e!(u`Z(Y~x=eKgALhYkFAL(rig?yQ zs`_Ea#v#oH|8WNPx(3s+3L=|NR~44GpvIpWC_Xo8l=XhNeG7de!FlnNy%N1Km}km2 zn8y2q4EV~~*fjnB!M>H>*r|E{mI{Cwd zb}Z2=E=3KOZ)+MT{y|wuBGSCl|F!FmQg1or@en$DedD*MCLaxEU{OgqX^%ap&UB{a zr=U}6@|t04xEh=Dm`?RAE`Wo{&?QgY+Gt4k`{7DFb4e~g*U-BN?Kv%(@oCf96b>wV ze)QjCFOJ&-%>5<%HuQby4Q_XavQE3R-#+#QwxsQOED2cL)Nj!;9;+IQZ2sO%)E?`S z_F)tYRvK6_AMuWO8^8EBo?K-Rp)kNwP>B@s znH)gwL^9;hwO((}DU=(e6fzW03pu&sbg_Gks4l&&dSmKv(T{^6)pUgfbj>c3tvw>k ze|$4?5-jf&;{u!i790LV>*@uIhv9AePd+4lyLO;@_uOy&BdMnihI)3u4co@Xlh`mW zVS6Ldpd3(58Wa_{;RPcsU?#iyb$zYkRkS9=*W~x;Z!;2DG8o8UbPL+--}WOlQ0p^) zMjDv2Hdr}pcamvZwiKTf!YOApmY(L{tEGyT#n2jBJ&>e+ygqD#gM4&P6+A+N3%pyU z?$8>!+V3H}8rGGMuN5ZNS*O&?Ui4@U$982LVpBl~Uw!8NxP|^Ws0--%WQwL}Wl=^O z8sQ^th~@wtLyHw0TkDB`0oq%wOyRzK0(15}?9FhfF z7RC99CHR_tZI`VqiktAdSg{-HGPT^Z+!L<(rt!ukihdR-Bgbhnb(+~-4LRB82Iacm z>TN^=4Sty1GB$v@IIuz;#o-o%-vt;S{tcUC%vSP}s~hV2gV}KYEe4jznxVu+deK1- zDy4VF!M_wRO`gquNVz_<8|qny$z*6VkJ#<?x5A=BM!ze0jT(@xn{aRUVqlXvsRjCPgSW%J4t_u3l?qtM=GU1;c=uKce zyN!WV={7u_Tw1FY#x;juiHN)HC~e8Bo+w|YxGc3_E$U+~?fY(vANrE<RiP z-Ic_A<1d;3LA!C;W%?~26~xf<>+_-{6wfWl^vYmnneR@6!K!!_DuJLfJYC&{oUo=Yo<$hS`-$`6~(4E%l+sFms z5j#M0O=0Pb3@-dLukmcX*B%>D3%w(%rCCcS%yS=+8ppSOl!5-`+Re%bx6eL9U9Z{# za_rN~Ybu#*y}YV%cd_n$A%BKnL2#da%NM=o0bM%A)&%-@XZSW0gO_KX^43xEDeW_Y zB3z^^t}*40QG1GYMdvf!zU~QO=QmC+ex~?{^WvA58bnlAtK^QmW{(u=ln+w5C%IFO zSmH_4t)nOeBBD z?%fPaDvNUC$sP2FP=p{?Azaj0i_G>>1}|f?7^B)Xr2NAEy0sRNs_k_Jdl0A2nlOu~ zczpm3u@j9f(Mhjhbv?2kvaDm@@Or+nLR+7Lv64%>jN~7U8a4f_eVlI}AmQ zz?aCIq6^^+mkICJT5wyo1_7iS#HArwMp?Dt=1@gmXqVensouumM{> zp(Yp6K-){d#sjbbX?rb$2L)OhEgkls9r!r8QhScenZQYjj;#&F*FpgN*I}oUIHF9l z)vhfIukUVv;i@@3VcOMW!vdaV1Y{+=_H~&z5MNI)_2GOt`w*E6PR$-;Bep(Qwa*&5 zRv$6f6kgYJ1f+!>e0Qo+=lD_|+QbR}T+fnPmiB!s0(!VHmFOh=&pPeU;NxQJG9ZV$n*saV5K@-95P5XQM0qv{U zeZpaP0`j9Ikf0p*Q&;~75ykTK!x=HHU%h;)st{x=d~^UMb|=p|T&C_YsN9j}GGb<8 zg;9KPY?wl6G#98?MBGU~33j<~N-Ih(*aes$*{6?g9Klm)M$@Tm7AzxElZRd@iYOod6 z|NAP(mCxU$qHfor`{&xk=2pmwWb{3r8~Oi{be3^VzHc91Al=>FJz8=C(n>1b-Ca^c zkWOik5>0Pl$%aNBweP8O)ItEv>UXlLb}XPy(a-^`Nz(Ib9Gw**%r%&)8lKID`Nr^WqlcW4(O=q zm$-?*M{sAA5!xi}db^D%cDmWvwhS2&E#6KD!H%|ek$7jm1Kt#=ae=LSDJ%N+3*q05 zW>}5H2UQoU-|qjeGXW|v1!&Y?5|F48ddq@Pua7tSb!@M|B;ZPC&AUv*dy*iilh{Ly z)msn3otoxz=UhGjInkD+ub{0(uIA70zgrs_H?}T6Lqr~UW0t&obJA+_h2A5usSF$e z*IMBIoVdSKq^@7@=6_g_YDPy(M38j2#64;uC1>2;xWs__Fem8EAzyJRds*ySb8|d-%md=QQ$!lfXa5#`5xl#!h>ELrxa~ ztgRu(Pf{xhSoryD;p6ZV&(&>MwZwe3^NWRr9yVHZS$;w8-!%~KxcKYAPQBj>H?|HUH6(H~{I#`x4XZnRAIR73xz z6?3WTf~x5=?lD~9SY(lKs3s0J*)PZWC&3p{|vt5@PU`TS?y&l?jbGd zsj+HP^+5){VTMP@K^80rQ+_WG4x+i&_rPvRACI#jDsR002;_wHme z)5WO7_4UM)0R4YGaCwt}l`?ujst%ni09JveKo6cDf;8kD+kVr8=`vacGeU*Apv+AB z;!J=xLx5U_{L}G}^f<#++oK0I3Rllk>d^i_l!6dyqL6HVeMbPvw`=@nOT){s& ztMZPCjk<~9=LTvPZCSy&p2$Ky!#lQKmn_QQ7+OyEATd^rv`n*WfRADF<6H;1#0oZ} z`!j2@dJqff?VTC1T+rLVqNZ3WJAE>+vjg=?M*OjIjg*7&VswynM{Gt8fWPyUC!DzQax0Zzo*Z=ao1i*WlILa`(+$ilmXQ=^h`19mU0z; zuXwvFaD}km@&fLsKJdaDIY)(lU%Z!m(FXj`%P}=2C>K}r_Qr72J?y27VSd9944rc} zPedV+hHR?0kJDbLFUekAmb}_pIsI)E`82n>uOuK5+W{ye-8P8>T%c0soCP;qip5+4 z`jA;8UfAL6m6HVil$EZnE}4}+|K?E)gR`9*)o|a!=UBgph%tOhn3Z>}xPGqd^|tQq zyWn@UI|6c0U{_R${VrTd^j~~#jZLyuCV0&K}g{L>M2O z&I})?K$mw}E+sh_&HtUi7X_@kggwK67ay4TK}=`+bGg3Ti~evLZ^gyGABXAepAi!; zSuSQs*59?q=mJHhbwT0!wN>tPOzVFtu@=x~uhLOgA}th8YeuO`)^bi47PIK`Z_#1R zGLH)<+Y#FhRC+~G7@05(xMzw@u=SQMZTGbbhwdw?;qR7F&%c#^C}=4UYH#KPeoRW1 zWOo8A8rzEeOx|B5S5&lB+%W2cTo`cw8C`?)j_Y{pDu!Huyx0E3jPuVw0~6|tF2^ka zMXwSZQDK!r@O0^cm`p!<{%@{wW(S)=3ERr_Y|HtCzafw3eRSV48Kch$YVeBJTH{&C znNV6CAaQYrISLN}2&kR`tz#KD)ZgF;;kjm+9<4qdgxsi)k*1A$G<6pAm12GSQQ2A- z8axOHa$p)3m0rKignd0${fT4U&wgvZC|B)voeFw_~j9uzGq9-!vbz#$bJpXIV___5sZ2@{!*ImAb zV8*ORF;A+&>pfM&O{djVYuO00P`CL$^v@c0j9;^XX}ZdF=3GD*f(nyYc;}s4KA}V5 ziutAx18##{GzN63&=Z0s-hBE>uG5uydR3d05){EtPu`U#m7|ZR;}YV$(PRqJ3dwtz zkgx?(+)U1$zk~V77J1E9hb}ph*6uo_gOssLbUl+3qvL6qo`03Bbd%qg%nVE)%Q#1U zdT%L-yC)Te@xoGQhA4ensYrX;vgjuZfrqm&PPBbY({Rb#Pv*ChZ)B`eKjw>qpd126 zm`TzpE&B?fqsM_`D-n=heDV&b8{kilqZmUcsf(SYt4`{sMZ0F0!%`fI)ps&T< z#mM9#mIFaKK;-Qn6J#!8W9hS0qm#__$1|GS;hvPif9Cp~gbF{{%tb9+lO@a9RIeMM z^OmPBDPE>QJTJ@$Z}6ciil#SUEi-k{TdnE){P-cPYYjPZhdKoPS5LkrF5i&_4*q0{ zoJ-~r%)hCz+>GmcR=;6kGOq1x zI5f3Yv#Sn>xb7U(1$GW+AOjb+fqk}sG0&Z|-|DehUqY!*}KJn{td_TEPt6HNou7uSm zaq^k9^-(7JF;Z$YC_mA^Jpykn43Hix1J}YPP(GA8oc{iJSKprN?zw0r+O#4mYAGl} z7WG~$)|!FT!u;2LNsGM;& z*)reOpL&-@_FzZWvHpJjHQ(5yw5tdG$z86%lP-1t^XKW}>0W5oTFBg?{70Sxv?}Lw za-r4pDvJDpI}4Qb-JAQ;UrFXoU?#~!bQFEgU&EEOsPv+}aKkRwkb@xsw*qNiRTMoB zMyP0J!kcnos53a`BvuQWhJhCISx!k`RjX?|9Ax&>a0xCQ#8FDx8$%2D?RDYN7MF$iYBoOzTLl$=LOnP^AB zga+-w<)@IDn;qnVjjumI+qB3xSy@K{WmIecEU~Hy8PsU4qh9&D(kW!%zz0T{7kZ}n zh=G!VJh?q_ca_7Glcp$>4QE#RTbuXV)>{ay+=wv(E4op&V;4aA^-}Lp*NdBF)j7q7 z3VvrbTS~IJ=DC2Bva5NEt4X}*_|y`^`1sJKbo>hu#i>xi_=?}vF*G&F8l>6AXno{G z6BKn@<@Ap6;fGlYrvA zI1S)r>0s}G40!R&zJde)U0H0`c+FLNh}vLt5BZZIq>jcwzQb_helfUd`EXRR=i$FQ zVR%f@ryr{h&6wd{N|8eNxDjEi^so;TMYKrB4?M1&Q+nR0%#t$;jPhiKWWYn?k))kt-3j=-YbiwH(^`lY7yiwZV%^<7G>IV?C*#$<*EX8uVR%P|y)wH~=5f z6*&W=t)*2(pHS|Z_0cD(3EF-*spSpQRYUOuMQuWAHn<)|x^R>xzd2|L!(>*F9Ue*rbsdYXN~9EV}~n;ibGg;V!Mv-VM{ z#ETVASwOw24R*8(ZOf?pb4rw;u;fWJo1{DQ*;D%AzO0*ujz$$Y8jsdld4;p$H)km+ z?0>0{{tWj1zdwC`Ebf6cr{27jI3jKRqLT=IYE;U)6yK8zW|GSkP%4OieiYK3q zeEymrMi9}gs=i?^cWh_~rG~BSyf{ZQ|g*)$$I5PqE>X>F*<&xE=MV zQMTl(kt2i!ygYb5m3&2jaA?97B&rB)U`IV$Dy^>@$+M9&iG7szX(>c6AhQ_9ivqup zRl3UQfGgDAe%>QOg(ZP)C2bQ_!DH6g-niF-;5;n$wS=_?RCLY??}< zOMEnmmltGQG7oHWWX-e$l$TrxlH}#{T^VbS?hYMBV{qa4oZj!@5d3rcsDKk8wkt55 ze67s*q-Phn$+h(%Wry4)aPeoC)Zj4NX;~_@Sh0=5hKN{uC;C^`?rP`%u zS}w>}uJY`zu1BuUh0C(5SuF3TrtBd;!`g>f8BG?S8UQw8i9zSJtHCoovwlwp}7}myy6~!S_OTXATQ@!5@9ee9eIYoaQ|4M?C zS+_P9x|yw;Axwkz564(>u?y6Snql&t(2oDoup(cT*`UZ?j4l2zo#o8VW*^3pP;95G zlbX?XvTfN9IBxwM=cqPaSvSt$hapVeKK-8J;K1rD?C2rx=fnqzh=FTMM)^LoxsSPY; z;YeiU;xAA^FnXk0Df~1wcs01g^mrOPP_v=uQDN3u>Fu~U_wjaE$Io3Ui}Qf*R`rSS zjD;_DSUAaXxKYvS1I_&ptfX<`>ODWO73No$;onK$XMJ-yX4hcftSi$8FFA_`?<9H| z%%>vAQ)5~-J%_eI*MggGHs8SZ(>y0s_dE$EIA=3ih>R%uX+2~6Zk6NmJeHSP6DB1> zM10%XaAhYaW3osDLn}9HaJU9G=BnNg1O{quY4f?GbFt90tHEBCi5alSTBUge8^=U* zO~S|tCE^m!JKk^6eNyhNIrZoa4pCG2;64-h&Oy;Z@fE5{N7ePEzqjv~Uld)H#sH^wKKzNc zBGmKfs53-OBp$B_QDMavJbU^CHw~4RiR{W@3~7Htxsz1kpckyD_mZuL&Gc!`gJb)^ zf`E(1gDd!P4tsL256`N9a)Fs-E39Izvu>Q6L=8;FN++8~9; zX9O?t+IRHv%nW;s7+)Z)KnV5U)AYto@{I1kD;NSZkZ3~?Psp=y5P)z*jk*?*9`B#A zRV{r*e+4Ovf7B&8WJ+Q)E0InU?HQFlm*R0BQ|zUuvM?KpBkDAL-J|F5`=DUg9Uf}^ zqy5kD=SefXA=}-QxADLq>F8=A@W+zV>7(rZxJ)+-1vaMVa*4^&_NoPZkR^8L7!nH$ z3Vp>LL)A!0_XGp3m9)h=cw$FSH{G3y4*yLL#6NM34wVT@8Sq|jBSQ!xiRNU3)=wQL zL}z+i>UU1!%4{$EY%xn#Y8(Lkwdw`(H7w$?%;=@>l_HK2mfb^9m2c8ke_L58J6c@z zMW||bqkhsX#Bjr!V{6Dm;}ocBYW67rliW_xA83za12`ivXE25=SAL)XUc6CRf0M9l zg-1g)ye0M*A0(Ql79AScW{zh)jwxZubcl+03#O4SnY6d+`c<7p?X{(g=*xb~U4)y> z>&q*0#_X&^6#Da^*`5~2kL}%zmHNC#6*(sYc2V$ox0M2;inE_F8MBEbP{3pvw7oNl zpf4Bd$}Kx-f1k0aAxg}dK*0M+byX|0Rdilkxo0r(eEmU;-d>F|MPY-whE1G{&O7er4bNd`OhXAJ_j( z6sg))&&9oK8S$cl#ExvUbdg-aQb>VmStNCti-k}HMZ+A_FRsgTph~A1apWK3nt^8EF`dO7nsig(HNib1}T<=Kf46dM&G1U%p&SS zD8aI*@G0fAxzBl0^2xjb(g& zL-F(g!?S&Qg7{Z`+ap@w$Ikf({?*6!2Uy2Yyg4Meda*}Ie)o|M|Nd@IF;7(f(=e7z zISclM2A4&7*7x?ONDIcWxp&z>0m&<}vfFPgxG6En6&$hl6>FQT^cb0Zo2llgCwpDM ztS_Am&}=>u@-Fc!%qz2pUrhOvho~j~PYYe`btcCgbd*`z*ZXH#XOh@t-R|^8$CVvj zbbe3I^+8{qMcr(5^P@-e!PPS~6YM;qf-Wk)>%HX)q1&?G8~-@5J{tjrTFTzKu#N*8 zu0o84j~sIEll`=(KJbGsQnmtSv;%aVoMkUtilMkoo}5nAn4_g`{mT%NXnLCin1`hHWQr_p@2W&nKaSnym+ z(it*3X4y|E`__Bvrx-naZ$fgKUGe#TnYXd<{J5v^ThQajc2nvc+RvfyIM3O=Up6`) z7_3rg&N~6xqv4uXs?jhj0k@%8;9tm~-ie*Xp3M60K4gup@0 zx%7n_7`c(=7OiTe1z@gPrL5d+gV}L}%0D2-ixWH}v0<%Rx_c@>-~UASg~gI~q6F4I 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

bYExGB<> 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 literal 0 HcmV?d00001 diff --git a/lib/MPU6050/examples/MPU6050_raw/MPU6050_raw.ino b/lib/MPU6050/examples/MPU6050_raw/MPU6050_raw.ino new file mode 100755 index 0000000..2dc612d --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_raw/MPU6050_raw.ino @@ -0,0 +1,152 @@ +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class +// 10/7/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2013-05-08 - added multiple output formats +// - added seamless Fastwire support +// 2011-10-07 - initial release + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2011 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include "I2Cdev.h" +#include "MPU6050.h" + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include "Wire.h" +#endif + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 accelgyro; +//MPU6050 accelgyro(0x69); // <-- use for AD0 high +//MPU6050 accelgyro(0x68, &Wire1); // <-- use for AD0 low, but 2nd Wire (TWI/I2C) object + +int16_t ax, ay, az; +int16_t gx, gy, gz; + + + +// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated +// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read, +// not so easy to parse, and slow(er) over UART. +#define OUTPUT_READABLE_ACCELGYRO + +// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit +// binary, one right after the other. This is very fast (as fast as possible +// without compression or data loss), and easy to parse, but impossible to read +// for a human. +//#define OUTPUT_BINARY_ACCELGYRO + + +#define LED_PIN 13 +bool blinkState = false; + +void setup() { + // join I2C bus (I2Cdev library doesn't do this automatically) + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + + // initialize serial communication + // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but + // it's really up to you depending on your project) + Serial.begin(38400); + + // initialize device + Serial.println("Initializing I2C devices..."); + accelgyro.initialize(); + + // verify connection + Serial.println("Testing device connections..."); + Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); + + // use the code below to change accel/gyro offset values + /* + Serial.println("Updating internal sensor offsets..."); + // -76 -2359 1688 0 0 0 + Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76 + Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359 + Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688 + Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0 + Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0 + Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0 + Serial.print("\n"); + accelgyro.setXGyroOffset(220); + accelgyro.setYGyroOffset(76); + accelgyro.setZGyroOffset(-85); + Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76 + Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359 + Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688 + Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0 + Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0 + Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0 + Serial.print("\n"); + */ + + // configure Arduino LED pin for output + pinMode(LED_PIN, OUTPUT); +} + +void loop() { + // read raw accel/gyro measurements from device + accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); + + // these methods (and a few others) are also available + //accelgyro.getAcceleration(&ax, &ay, &az); + //accelgyro.getRotation(&gx, &gy, &gz); + + #ifdef OUTPUT_READABLE_ACCELGYRO + // display tab-separated accel/gyro x/y/z values + Serial.print("a/g:\t"); + Serial.print(ax); Serial.print("\t"); + Serial.print(ay); Serial.print("\t"); + Serial.print(az); Serial.print("\t"); + Serial.print(gx); Serial.print("\t"); + Serial.print(gy); Serial.print("\t"); + Serial.println(gz); + #endif + + #ifdef OUTPUT_BINARY_ACCELGYRO + Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); + Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); + Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); + Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF)); + Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF)); + Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF)); + #endif + + // blink LED to indicate activity + blinkState = !blinkState; + digitalWrite(LED_PIN, blinkState); +} diff --git a/lib/MPU6050/examples/MPU6050_raw/Makefile b/lib/MPU6050/examples/MPU6050_raw/Makefile new file mode 100644 index 0000000..58286bd --- /dev/null +++ b/lib/MPU6050/examples/MPU6050_raw/Makefile @@ -0,0 +1,20 @@ +# BOARD_TAG = arduino:mbed_rp2040:pico +# BOARD_TAG = rp2040:rp2040:rpipico +BOARD_TAG = esp32:esp32:XIAO_ESP32C3 +MONITOR_PORT = /dev/cu.usbmodem132401 +ARDUINO_CLI_PATH := arduino-cli + +compile: + $(ARDUINO_CLI_PATH) compile --fqbn $(BOARD_TAG) --export-binaries + +upload: + @$(ARDUINO_CLI_PATH) upload -p $(MONITOR_PORT) --fqbn $(BOARD_TAG) --verbose + +monitor: + @$(ARDUINO_CLI_PATH) monitor -p $(MONITOR_PORT) --config baudrate=9600 + # screen $(MONITOR_PORT) 9600 + +clean: + @$(ARDUINO_CLI_PATH) cache clean + +all: compile upload monitor diff --git a/lib/MPU6050/keywords.txt b/lib/MPU6050/keywords.txt new file mode 100755 index 0000000..5385949 --- /dev/null +++ b/lib/MPU6050/keywords.txt @@ -0,0 +1,151 @@ +####################################### +# Syntax Coloring Map For MPU6050 +####################################### + +####################################### +# Class (KEYWORD1) +####################################### +MPU6050 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +initialize KEYWORD2 +get_acce_resolution KEYWORD2 +get_gyro_resolution KEYWORD2 +testConnection KEYWORD2 + +getAuxVDDIOLevel KEYWORD2 +setAuxVDDIOLevel KEYWORD2 + +getRate KEYWORD2 +setRate KEYWORD2 + +getExternalFrameSync KEYWORD2 +setExternalFrameSync KEYWORD2 +getDLPFMode KEYWORD2 + +getFullScaleGyroRange KEYWORD2 +setFullScaleGyroRange KEYWORD2 + +getAccelXSelfTestFactoryTrim KEYWORD2 +getAccelYSelfTestFactoryTrim KEYWORD2 +getAccelZSelfTestFactoryTrim KEYWORD2 +getGyroXSelfTestFactoryTrim KEYWORD2 +getGyroYSelfTestFactoryTrim KEYWORD2 +getGyroZSelfTestFactoryTrim KEYWORD2 + +getAccelXSelfTest KEYWORD2 +getAccelYSelfTest KEYWORD2 +getAccelZSelfTest KEYWORD2 +getFullScaleAccelRange KEYWORD2 +setFullScaleAccelRange KEYWORD2 +getDHPFMode KEYWORD2 +setDHPFMode KEYWORD2 + +getMotion6 KEYWORD2 +getMotion9 KEYWORD2 +getAccelerationX KEYWORD2 +getAccelerationY KEYWORD2 +getAccelerationZ KEYWORD2 + +getTemperature KEYWORD2 + +getRotation KEYWORD2 +getRotationX KEYWORD2 +getRotationY KEYWORD2 +getRotationZ KEYWORD2 + +setI2CMasterModeEnabled KEYWORD2 +setI2CBypassEnabled KEYWORD2 +setSleepEnabled KEYWORD2 +getFreefallDetectionThreshold KEYWORD2 +setFreefallDetectionThreshold KEYWORD2 +getFreefallDetectionDuration KEYWORD2 +setFreefallDetectionDuration KEYWORD2 +getMotionDetectionThreshold KEYWORD2 +setMotionDetectionThreshold KEYWORD2 +getMotionDetectionDuration KEYWORD2 +setMotionDetectionDuration KEYWORD2 +getZeroMotionDetectionThreshold KEYWORD2 +setZeroMotionDetectionThreshold KEYWORD2 +getZeroMotionDetectionDuration KEYWORD2 +setZeroMotionDetectionDuration KEYWORD2 + +getTempFIFOEnabled KEYWORD2 +setTempFIFOEnabled KEYWORD2 +getXGyroFIFOEnabled KEYWORD2 +setXGyroFIFOEnabled KEYWORD2 +getYGyroFIFOEnabled KEYWORD2 +setYGyroFIFOEnabled KEYWORD2 +getZGyroFIFOEnabled KEYWORD2 +setZGyroFIFOEnabled KEYWORD2 +getAccelFIFOEnabled KEYWORD2 +setAccelFIFOEnabled KEYWORD2 +getSlave2FIFOEnabled KEYWORD2f +setSlave2FIFOEnabled KEYWORD2 +getSlave1FIFOEnabled KEYWORD2 +setSlave1FIFOEnabled KEYWORD2 +getSlave0FIFOEnabled KEYWORD2 +setSlave0FIFOEnabled KEYWORD2 + +getMultiMasterEnabled KEYWORD2 +setMultiMasterEnabled KEYWORD2 +getWaitForExternalSensorEnabled KEYWORD2 +setWaitForExternalSensorEnabled KEYWORD2 +getSlave3FIFOEnabled KEYWORD2 +setSlave3FIFOEnabled KEYWORD2 +getSlaveReadWriteTransitionEnabled KEYWORD2 +setSlaveReadWriteTransitionEnabled KEYWORD2 +getMasterClockSpeed KEYWORD2 +setMasterClockSpeed KEYWORD2 + +getSlaveAddress KEYWORD2 +setSlaveAddress KEYWORD2 +getSlaveRegister KEYWORD2 +setSlaveRegister KEYWORD2 +getSlaveEnabled KEYWORD2 +setSlaveEnabled KEYWORD2 +getSlaveWordByteSwap KEYWORD2 +setSlaveWordByteSwap KEYWORD2 +getSlaveWriteMode KEYWORD2 +setSlaveWriteMode KEYWORD2 +getSlaveWordGroupOffset KEYWORD2 +setSlaveWordGroupOffset KEYWORD2 +getSlaveDataLength KEYWORD2 +setSlaveDataLength KEYWORD2 + +getSlave4Address KEYWORD2 +setSlave4Address KEYWORD2 +getSlave4Register KEYWORD2 +setSlave4Register KEYWORD2 +setSlave4OutputByte KEYWORD2 +getSlave4Enabled KEYWORD2 +setSlave4Enabled KEYWORD2 +getSlave4InterruptEnabled KEYWORD2 +setSlave4InterruptEnabled KEYWORD2 +getSlave4WriteMode KEYWORD2 +setSlave4WriteMode KEYWORD2 +getSlave4MasterDelay KEYWORD2 +setSlave4MasterDelay KEYWORD2 +getSlate4InputByte KEYWORD2 + +getPassthroughStatus KEYWORD2 +getSlave4IsDone KEYWORD2 +getLostArbitration KEYWORD2 +getSlave4Nack KEYWORD2 +getSlave3Nack KEYWORD2 +getSlave2Nack KEYWORD2 +getSlave1Nack KEYWORD2 +getSlave0Nack KEYWORD2 + +CalibrateGyro KEYWORD2 +CalibrateAccel KEYWORD2 +PID KEYWORD2 +PrintActiveOffsets KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/lib/MPU6050/library.properties b/lib/MPU6050/library.properties new file mode 100755 index 0000000..64e09cc --- /dev/null +++ b/lib/MPU6050/library.properties @@ -0,0 +1,10 @@ +name=MPU6050 +version=1.3.1 +author=Electronic Cats +maintainer=Electronic Cats +sentence=MPU6050 Arduino Library. +paragraph=MPU-6050 6-axis accelerometer/gyroscope Arduino Library. +category=Sensors +url=https://github.com/electroniccats/mpu6050 +architectures=avr,samd,sam,esp8266,esp32,stm32,renesas,renesas_portenta,renesas_uno +includes=MPU6050.h diff --git a/lib/MPU6050/src/I2Cdev.cpp b/lib/MPU6050/src/I2Cdev.cpp new file mode 100644 index 0000000..359688d --- /dev/null +++ b/lib/MPU6050/src/I2Cdev.cpp @@ -0,0 +1,1473 @@ +// I2Cdev library collection - Main I2C device class +// Abstracts bit and byte I2C R/W functions into a convenient class +// 2013-06-05 by Jeff Rowberg +// +// Changelog: +// 2022-01-27 - workaround for the ESP32 Wire implementation (mcpicoli) +// 2020-01-20 - hardija : complete support for Teensy 3.x +// 2015-10-30 - simondlevy : support i2c_t3 for Teensy3.1 +// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications +// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan) +// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire +// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation +// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums) +// 2011-10-03 - added automatic Arduino version detection for ease of use +// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications +// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x) +// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default +// 2011-08-02 - added support for 16-bit registers +// - fixed incorrect Doxygen comments on some methods +// - added timeout value for read operations (thanks mem @ Arduino forums) +// 2011-07-30 - changed read/write function structures to return success or byte counts +// - made all methods static for multi-device memory savings +// 2011-07-28 - initial release + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2013 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#include "I2Cdev.h" + +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE + + #ifdef I2CDEV_IMPLEMENTATION_WARNINGS + #if ARDUINO < 100 + #warning Using outdated Arduino IDE with Wire library is functionally limiting. + #warning Arduino IDE v1.6.5+ with I2Cdev Fastwire implementation is recommended. + #warning This I2Cdev implementation does not support: + #warning - Repeated starts conditions + #warning - Timeout detection (some Wire requests block forever) + #elif ARDUINO == 100 + #warning Using outdated Arduino IDE with Wire library is functionally limiting. + #warning Arduino IDE v1.6.5+ with I2Cdev Fastwire implementation is recommended. + #warning This I2Cdev implementation does not support: + #warning - Repeated starts conditions + #warning - Timeout detection (some Wire requests block forever) + #elif ARDUINO > 100 + /*#warning Using current Arduino IDE with Wire library is functionally limiting. + #warning Arduino IDE v1.6.5+ with I2CDEV_BUILTIN_FASTWIRE implementation is recommended. + #warning This I2Cdev implementation does not support: + #warning - Timeout detection (some Wire requests block forever)*/ + #endif + #endif + +#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + + //#error The I2CDEV_BUILTIN_FASTWIRE implementation is known to be broken right now. Patience, Iago! + +#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE + + #ifdef I2CDEV_IMPLEMENTATION_WARNINGS + #warning Using I2CDEV_BUILTIN_NBWIRE implementation may adversely affect interrupt detection. + #warning This I2Cdev implementation does not support: + #warning - Repeated starts conditions + #endif + + // NBWire implementation based heavily on code by Gene Knight + // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html + // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html + TwoWire Wire; + +#endif + +/** Default constructor. + */ +I2Cdev::I2Cdev() { +} + +/** Read a single bit from an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to read from + * @param bitNum Bit position to read (0-7) + * @param data Container for single bit value + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Status of read operation (true = success) + */ +int8_t I2Cdev::readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout, void *wireObj) { + uint8_t b; + uint8_t count = readByte(devAddr, regAddr, &b, timeout, wireObj); + *data = b & (1 << bitNum); + return count; +} + +/** Read a single bit from a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to read from + * @param bitNum Bit position to read (0-15) + * @param data Container for single bit value + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Status of read operation (true = success) + */ +int8_t I2Cdev::readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout, void *wireObj) { + uint16_t b; + uint8_t count = readWord(devAddr, regAddr, &b, timeout, wireObj); + *data = b & (1 << bitNum); + return count; +} + +/** Read multiple bits from an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to read from + * @param bitStart First bit position to read (0-7) + * @param length Number of bits to read (not more than 8) + * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Status of read operation (true = success) + */ +int8_t I2Cdev::readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout, void *wireObj) { + // 01101001 read byte + // 76543210 bit numbers + // xxx args: bitStart=4, length=3 + // 010 masked + // -> 010 shifted + uint8_t count, b; + if ((count = readByte(devAddr, regAddr, &b, timeout, wireObj)) != 0) { + uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); + b &= mask; + b >>= (bitStart - length + 1); + *data = b; + } + return count; +} + +/** Read multiple bits from a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to read from + * @param bitStart First bit position to read (0-15) + * @param length Number of bits to read (not more than 16) + * @param data Container for right-aligned value (i.e. '101' read from any bitStart position will equal 0x05) + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Status of read operation (1 = success, 0 = failure, -1 = timeout) + */ +int8_t I2Cdev::readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout, void *wireObj) { + // 1101011001101001 read byte + // fedcba9876543210 bit numbers + // xxx args: bitStart=12, length=3 + // 010 masked + // -> 010 shifted + uint8_t count; + uint16_t w; + if ((count = readWord(devAddr, regAddr, &w, timeout, wireObj)) != 0) { + uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); + w &= mask; + w >>= (bitStart - length + 1); + *data = w; + } + return count; +} + +/** Read single byte from an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to read from + * @param data Container for byte value read from device + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Status of read operation (true = success) + */ +int8_t I2Cdev::readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout, void *wireObj) { + return readBytes(devAddr, regAddr, 1, data, timeout, wireObj); +} + +/** Read single word from a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to read from + * @param data Container for word value read from device + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Status of read operation (true = success) + */ +int8_t I2Cdev::readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout, void *wireObj) { + return readWords(devAddr, regAddr, 1, data, timeout, wireObj); +} + +/** Read multiple bytes from an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr First register regAddr to read from + * @param length Number of bytes to read + * @param data Buffer to store read data in + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Number of bytes read (-1 indicates failure) + */ +int8_t I2Cdev::readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout, void *wireObj) { + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print("I2C (0x"); + Serial.print(devAddr, HEX); + Serial.print(") reading "); + Serial.print(length, DEC); + Serial.print(" bytes from 0x"); + Serial.print(regAddr, HEX); + Serial.print("..."); + #endif + + uint8_t count = 0; + uint32_t t1 = millis(); + + #if (I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + TwoWire *useWire = &Wire; + if (wireObj) useWire = (TwoWire *)wireObj; + + #if (ARDUINO < 100) + // Arduino v00xx (before v1.0), Wire library + + // I2C/TWI subsystem uses internal buffer that breaks with large data requests + // so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in + // smaller chunks instead of all at once + for (int k = 0; k < length; k += min((int)length, I2CDEVLIB_WIRE_BUFFER_LENGTH)) { + useWire->beginTransmission(devAddr); + useWire->send(regAddr); + useWire->endTransmission(); + useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH)); + for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) { + data[count] = useWire->receive(); + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[count], HEX); + if (count + 1 < length) Serial.print(" "); + #endif + } + } + #elif (ARDUINO == 100) + // Arduino v1.0.0, Wire library + // Adds standardized write() and read() stream methods instead of send() and receive() + + // I2C/TWI subsystem uses internal buffer that breaks with large data requests + // so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in + // smaller chunks instead of all at once + for (int k = 0; k < length; k += min((int)length, I2CDEVLIB_WIRE_BUFFER_LENGTH)) { + useWire->beginTransmission(devAddr); + useWire->write(regAddr); + useWire->endTransmission(); + useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH)); + for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) { + data[count] = useWire->read(); + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[count], HEX); + if (count + 1 < length) Serial.print(" "); + #endif + } + } + #elif (ARDUINO > 100) + // Arduino v1.0.1+, Wire library + // Adds official support for repeated start condition, yay! + + // I2C/TWI subsystem uses internal buffer that breaks with large data requests + // so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in + // smaller chunks instead of all at once + for (int k = 0; k < length; k += min((int)length, I2CDEVLIB_WIRE_BUFFER_LENGTH)) { + useWire->beginTransmission(devAddr); + useWire->write(regAddr); + #ifdef ARDUINO_ARCH_ESP32 + useWire->endTransmission(false); + #else + useWire->endTransmission(); + #endif + useWire->requestFrom((uint8_t)devAddr, (uint8_t)min((int)length - k, I2CDEVLIB_WIRE_BUFFER_LENGTH)); + for (; useWire->available() && (timeout == 0 || millis() - t1 < timeout); count++) { + data[count] = useWire->read(); + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[count], HEX); + if (count + 1 < length) Serial.print(" "); + #endif + } + } + #endif + + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + + // Fastwire library + // no loop required for fastwire + uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, data, length); + if (status == 0) { + count = length; // success + } else { + count = -1; // error + } + + #endif + + // check for timeout + if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout + + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(". Done ("); + Serial.print(count, DEC); + Serial.println(" read)."); + #endif + + return count; +} + +/** Read multiple words from a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr First register regAddr to read from + * @param length Number of words to read + * @param data Buffer to store read data in + * @param timeout Optional read timeout in milliseconds (0 to disable, leave off to use default class value in I2Cdev::readTimeout) + * @return Number of words read (-1 indicates failure) + */ +int8_t I2Cdev::readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout, void *wireObj) { + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print("I2C (0x"); + Serial.print(devAddr, HEX); + Serial.print(") reading "); + Serial.print(length, DEC); + Serial.print(" words from 0x"); + Serial.print(regAddr, HEX); + Serial.print("..."); + #endif + + uint8_t count = 0; + uint32_t t1 = millis(); + +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE + TwoWire *useWire = &Wire; + if (wireObj) useWire = (TwoWire *)wireObj; + + #if (ARDUINO < 100) + // Arduino v00xx (before v1.0), Wire library + + // I2C/TWI subsystem uses internal buffer that breaks with large data requests + // so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in + // smaller chunks instead of all at once + for (uint8_t k = 0; k < length * 2; k += min(length * 2, I2CDEVLIB_WIRE_BUFFER_LENGTH)) { + useWire->beginTransmission(devAddr); + useWire->send(regAddr); + useWire->endTransmission(); + useWire->requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes + + bool msb = true; // starts with MSB, then LSB + for (; useWire->available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { + if (msb) { + // first byte is bits 15-8 (MSb=15) + data[count] = useWire->receive() << 8; + } else { + // second byte is bits 7-0 (LSb=0) + data[count] |= useWire->receive(); + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[count], HEX); + if (count + 1 < length) Serial.print(" "); + #endif + count++; + } + msb = !msb; + } + } + #elif (ARDUINO == 100) + // Arduino v1.0.0, Wire library + // Adds standardized write() and read() stream methods instead of send() and receive() + + // I2C/TWI subsystem uses internal buffer that breaks with large data requests + // so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in + // smaller chunks instead of all at once + for (uint8_t k = 0; k < length * 2; k += min(length * 2, I2CDEVLIB_WIRE_BUFFER_LENGTH)) { + useWire->beginTransmission(devAddr); + useWire->write(regAddr); + useWire->endTransmission(); + useWire->requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes + + bool msb = true; // starts with MSB, then LSB + for (; useWire->available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { + if (msb) { + // first byte is bits 15-8 (MSb=15) + data[count] = useWire->read() << 8; + } else { + // second byte is bits 7-0 (LSb=0) + data[count] |= useWire->read(); + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[count], HEX); + if (count + 1 < length) Serial.print(" "); + #endif + count++; + } + msb = !msb; + } + } + #elif (ARDUINO > 100) + // Arduino v1.0.1+, Wire library + // Adds official support for repeated start condition, yay! + + // I2C/TWI subsystem uses internal buffer that breaks with large data requests + // so if user requests more than I2CDEVLIB_WIRE_BUFFER_LENGTH bytes, we have to do it in + // smaller chunks instead of all at once + for (uint8_t k = 0; k < length * 2; k += min(length * 2, I2CDEVLIB_WIRE_BUFFER_LENGTH)) { + useWire->beginTransmission(devAddr); + useWire->write(regAddr); + useWire->endTransmission(); + useWire->requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes + + bool msb = true; // starts with MSB, then LSB + for (; useWire->available() && count < length && (timeout == 0 || millis() - t1 < timeout);) { + if (msb) { + // first byte is bits 15-8 (MSb=15) + data[count] = useWire->read() << 8; + } else { + // second byte is bits 7-0 (LSb=0) + data[count] |= useWire->read(); + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[count], HEX); + if (count + 1 < length) Serial.print(" "); + #endif + count++; + } + msb = !msb; + } + } + #endif + + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + + // Fastwire library + // no loop required for fastwire + uint8_t intermediate[(uint8_t)length*2]; + uint8_t status = Fastwire::readBuf(devAddr << 1, regAddr, intermediate, (uint8_t)(length * 2)); + if (status == 0) { + count = length; // success + for (uint8_t i = 0; i < length; i++) { + data[i] = (intermediate[2*i] << 8) | intermediate[2*i + 1]; + } + } else { + count = -1; // error + } + + #endif + + if (timeout > 0 && millis() - t1 >= timeout && count < length) count = -1; // timeout + + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(". Done ("); + Serial.print(count, DEC); + Serial.println(" read)."); + #endif + + return count; +} + +/** write a single bit in an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to write to + * @param bitNum Bit position to write (0-7) + * @param value New bit value to write + * @return Status of operation (true = success) + */ +bool I2Cdev::writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data, void *wireObj) { + uint8_t b; + readByte(devAddr, regAddr, &b, I2Cdev::readTimeout, wireObj); + b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); + return writeByte(devAddr, regAddr, b, wireObj); +} + +/** write a single bit in a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to write to + * @param bitNum Bit position to write (0-15) + * @param value New bit value to write + * @return Status of operation (true = success) + */ +bool I2Cdev::writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data, void *wireObj) { + uint16_t w; + readWord(devAddr, regAddr, &w, I2Cdev::readTimeout, wireObj); + w = (data != 0) ? (w | (1 << bitNum)) : (w & ~(1 << bitNum)); + return writeWord(devAddr, regAddr, w, wireObj); +} + +/** Write multiple bits in an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to write to + * @param bitStart First bit position to write (0-7) + * @param length Number of bits to write (not more than 8) + * @param data Right-aligned value to write + * @return Status of operation (true = success) + */ +bool I2Cdev::writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data, void *wireObj) { + // 010 value to write + // 76543210 bit numbers + // xxx args: bitStart=4, length=3 + // 00011100 mask byte + // 10101111 original value (sample) + // 10100011 original & ~mask + // 10101011 masked | value + uint8_t b; + if (readByte(devAddr, regAddr, &b, I2Cdev::readTimeout, wireObj) != 0) { + uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1); + data <<= (bitStart - length + 1); // shift data into correct position + data &= mask; // zero all non-important bits in data + b &= ~(mask); // zero all important bits in existing byte + b |= data; // combine data with existing byte + return writeByte(devAddr, regAddr, b, wireObj); + } else { + return false; + } +} + +/** Write multiple bits in a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register regAddr to write to + * @param bitStart First bit position to write (0-15) + * @param length Number of bits to write (not more than 16) + * @param data Right-aligned value to write + * @return Status of operation (true = success) + */ +bool I2Cdev::writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data, void *wireObj) { + // 010 value to write + // fedcba9876543210 bit numbers + // xxx args: bitStart=12, length=3 + // 0001110000000000 mask word + // 1010111110010110 original value (sample) + // 1010001110010110 original & ~mask + // 1010101110010110 masked | value + uint16_t w; + if (readWord(devAddr, regAddr, &w, I2Cdev::readTimeout, wireObj) != 0) { + uint16_t mask = ((1 << length) - 1) << (bitStart - length + 1); + data <<= (bitStart - length + 1); // shift data into correct position + data &= mask; // zero all non-important bits in data + w &= ~(mask); // zero all important bits in existing word + w |= data; // combine data with existing word + return writeWord(devAddr, regAddr, w, wireObj); + } else { + return false; + } +} + +/** Write single byte to an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register address to write to + * @param data New byte value to write + * @return Status of operation (true = success) + */ +bool I2Cdev::writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data, void *wireObj) { + return writeBytes(devAddr, regAddr, 1, &data, wireObj); +} + +/** Write single word to a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr Register address to write to + * @param data New word value to write + * @return Status of operation (true = success) + */ +bool I2Cdev::writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data, void *wireObj) { + return writeWords(devAddr, regAddr, 1, &data, wireObj); +} + +/** Write multiple bytes to an 8-bit device register. + * @param devAddr I2C slave device address + * @param regAddr First register address to write to + * @param length Number of bytes to write + * @param data Buffer to copy new data from + * @return Status of operation (true = success) + */ +bool I2Cdev::writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t* data, void *wireObj) { + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print("I2C (0x"); + Serial.print(devAddr, HEX); + Serial.print(") writing "); + Serial.print(length, DEC); + Serial.print(" bytes to 0x"); + Serial.print(regAddr, HEX); + Serial.print("..."); + #endif + uint8_t status = 0; + +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE + TwoWire *useWire = &Wire; + if (wireObj) useWire = (TwoWire *)wireObj; +#endif + + #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) + useWire->beginTransmission(devAddr); + useWire->send((uint8_t) regAddr); // send address + #elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \ + || (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \ + || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + useWire->beginTransmission(devAddr); + useWire->write((uint8_t) regAddr); // send address + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + Fastwire::beginTransmission(devAddr); + Fastwire::write(regAddr); + #endif + for (uint8_t i = 0; i < length; i++) { + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[i], HEX); + if (i + 1 < length) Serial.print(" "); + #endif + #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) + useWire->send((uint8_t) data[i]); + #elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \ + || (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \ + || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + useWire->write((uint8_t) data[i]); + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + Fastwire::write((uint8_t) data[i]); + #endif + } + #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) + useWire->endTransmission(); + #elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \ + || (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \ + || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + status = useWire->endTransmission(); + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + Fastwire::stop(); + //status = Fastwire::endTransmission(); + #endif + #ifdef I2CDEV_SERIAL_DEBUG + Serial.println(". Done."); + #endif + return status == 0; +} + +/** Write multiple words to a 16-bit device register. + * @param devAddr I2C slave device address + * @param regAddr First register address to write to + * @param length Number of words to write + * @param data Buffer to copy new data from + * @return Status of operation (true = success) + */ +bool I2Cdev::writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t* data, void *wireObj) { + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print("I2C (0x"); + Serial.print(devAddr, HEX); + Serial.print(") writing "); + Serial.print(length, DEC); + Serial.print(" words to 0x"); + Serial.print(regAddr, HEX); + Serial.print("..."); + #endif + uint8_t status = 0; + +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE + TwoWire *useWire = &Wire; + if (wireObj) useWire = (TwoWire *)wireObj; +#endif + + #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) + useWire->beginTransmission(devAddr); + useWire->send(regAddr); // send address + #elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \ + || (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \ + || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + useWire->beginTransmission(devAddr); + useWire->write(regAddr); // send address + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + Fastwire::beginTransmission(devAddr); + Fastwire::write(regAddr); + #endif + for (uint8_t i = 0; i < length; i++) { + #ifdef I2CDEV_SERIAL_DEBUG + Serial.print(data[i], HEX); + if (i + 1 < length) Serial.print(" "); + #endif + #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) + useWire->send((uint8_t)(data[i] >> 8)); // send MSB + useWire->send((uint8_t)data[i]); // send LSB + #elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \ + || (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \ + || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + useWire->write((uint8_t)(data[i] >> 8)); // send MSB + useWire->write((uint8_t)data[i]); // send LSB + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + Fastwire::write((uint8_t)(data[i] >> 8)); // send MSB + status = Fastwire::write((uint8_t)data[i]); // send LSB + if (status != 0) break; + #endif + } + #if ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO < 100) || I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE) + useWire->endTransmission(); + #elif ((I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE && ARDUINO >= 100) \ + || (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE && ARDUINO >= 100) \ + || I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE) + status = useWire->endTransmission(); + #elif (I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE) + Fastwire::stop(); + //status = Fastwire::endTransmission(); + #endif + #ifdef I2CDEV_SERIAL_DEBUG + Serial.println(". Done."); + #endif + return status == 0; +} + +/** Default timeout value for read operations. + * Set this to 0 to disable timeout detection. + */ +uint16_t I2Cdev::readTimeout = I2CDEV_DEFAULT_READ_TIMEOUT; + +#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + // I2C library + ////////////////////// + // Copyright(C) 2012 + // Francesco Ferrara + // ferrara[at]libero[point]it + ////////////////////// + + /* + FastWire + - 0.24 added stop + - 0.23 added reset + + This is a library to help faster programs to read I2C devices. + Copyright(C) 2012 Francesco Ferrara + occhiobello at gmail dot com + [used by Jeff Rowberg for I2Cdevlib with permission] + */ + + boolean Fastwire::waitInt() { + int l = 250; + while (!(TWCR & (1 << TWINT)) && l-- > 0); + return l > 0; + } + + void Fastwire::setup(int khz, boolean pullup) { + TWCR = 0; + #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__) + // activate internal pull-ups for twi (PORTC bits 4 & 5) + // as per note from atmega8 manual pg167 + if (pullup) PORTC |= ((1 << 4) | (1 << 5)); + else PORTC &= ~((1 << 4) | (1 << 5)); + #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) + // activate internal pull-ups for twi (PORTC bits 0 & 1) + if (pullup) PORTC |= ((1 << 0) | (1 << 1)); + else PORTC &= ~((1 << 0) | (1 << 1)); + #else + // activate internal pull-ups for twi (PORTD bits 0 & 1) + // as per note from atmega128 manual pg204 + if (pullup) PORTD |= ((1 << 0) | (1 << 1)); + else PORTD &= ~((1 << 0) | (1 << 1)); + #endif + + TWSR = 0; // no prescaler => prescaler = 1 + TWBR = F_CPU / 2000 / khz - 8; // change the I2C clock rate + TWCR = 1 << TWEN; // enable twi module, no interrupt + } + + // added by Jeff Rowberg 2013-05-07: + // Arduino Wire-style "beginTransmission" function + // (takes 7-bit device address like the Wire method, NOT 8-bit: 0x68, not 0xD0/0xD1) + byte Fastwire::beginTransmission(byte device) { + byte twst, retry; + retry = 2; + do { + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); + if (!waitInt()) return 1; + twst = TWSR & 0xF8; + if (twst != TW_START && twst != TW_REP_START) return 2; + + //Serial.print(device, HEX); + //Serial.print(" "); + TWDR = device << 1; // send device address without read bit (1) + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 3; + twst = TWSR & 0xF8; + } while (twst == TW_MT_SLA_NACK && retry-- > 0); + if (twst != TW_MT_SLA_ACK) return 4; + return 0; + } + + byte Fastwire::writeBuf(byte device, byte address, byte *data, byte num) { + byte twst, retry; + + retry = 2; + do { + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); + if (!waitInt()) return 1; + twst = TWSR & 0xF8; + if (twst != TW_START && twst != TW_REP_START) return 2; + + //Serial.print(device, HEX); + //Serial.print(" "); + TWDR = device & 0xFE; // send device address without read bit (1) + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 3; + twst = TWSR & 0xF8; + } while (twst == TW_MT_SLA_NACK && retry-- > 0); + if (twst != TW_MT_SLA_ACK) return 4; + + //Serial.print(address, HEX); + //Serial.print(" "); + TWDR = address; // send data to the previously addressed device + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 5; + twst = TWSR & 0xF8; + if (twst != TW_MT_DATA_ACK) return 6; + + for (byte i = 0; i < num; i++) { + //Serial.print(data[i], HEX); + //Serial.print(" "); + TWDR = data[i]; // send data to the previously addressed device + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 7; + twst = TWSR & 0xF8; + if (twst != TW_MT_DATA_ACK) return 8; + } + //Serial.print("\n"); + + return 0; + } + + byte Fastwire::write(byte value) { + byte twst; + //Serial.println(value, HEX); + TWDR = value; // send data + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 1; + twst = TWSR & 0xF8; + if (twst != TW_MT_DATA_ACK) return 2; + return 0; + } + + byte Fastwire::readBuf(byte device, byte address, byte *data, byte num) { + byte twst, retry; + + retry = 2; + do { + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); + if (!waitInt()) return 16; + twst = TWSR & 0xF8; + if (twst != TW_START && twst != TW_REP_START) return 17; + + //Serial.print(device, HEX); + //Serial.print(" "); + TWDR = device & 0xfe; // send device address to write + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 18; + twst = TWSR & 0xF8; + } while (twst == TW_MT_SLA_NACK && retry-- > 0); + if (twst != TW_MT_SLA_ACK) return 19; + + //Serial.print(address, HEX); + //Serial.print(" "); + TWDR = address; // send data to the previously addressed device + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 20; + twst = TWSR & 0xF8; + if (twst != TW_MT_DATA_ACK) return 21; + + /***/ + + retry = 2; + do { + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO) | (1 << TWSTA); + if (!waitInt()) return 22; + twst = TWSR & 0xF8; + if (twst != TW_START && twst != TW_REP_START) return 23; + + //Serial.print(device, HEX); + //Serial.print(" "); + TWDR = device | 0x01; // send device address with the read bit (1) + TWCR = (1 << TWINT) | (1 << TWEN); + if (!waitInt()) return 24; + twst = TWSR & 0xF8; + } while (twst == TW_MR_SLA_NACK && retry-- > 0); + if (twst != TW_MR_SLA_ACK) return 25; + + for (uint8_t i = 0; i < num; i++) { + if (i == num - 1) + TWCR = (1 << TWINT) | (1 << TWEN); + else + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); + if (!waitInt()) return 26; + twst = TWSR & 0xF8; + if (twst != TW_MR_DATA_ACK && twst != TW_MR_DATA_NACK) return twst; + data[i] = TWDR; + //Serial.print(data[i], HEX); + //Serial.print(" "); + } + //Serial.print("\n"); + stop(); + + return 0; + } + + void Fastwire::reset() { + TWCR = 0; + } + + byte Fastwire::stop() { + TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); + if (!waitInt()) return 1; + return 0; + } +#endif + +#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE + // NBWire implementation based heavily on code by Gene Knight + // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html + // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html + + /* + call this version 1.0 + + Offhand, the only funky part that I can think of is in nbrequestFrom, where the buffer + length and index are set *before* the data is actually read. The problem is that these + are variables local to the TwoWire object, and by the time we actually have read the + data, and know what the length actually is, we have no simple access to the object's + variables. The actual bytes read *is* given to the callback function, though. + + The ISR code for a slave receiver is commented out. I don't have that setup, and can't + verify it at this time. Save it for 2.0! + + The handling of the read and write processes here is much like in the demo sketch code: + the process is broken down into sequential functions, where each registers the next as a + callback, essentially. + + For example, for the Read process, twi_read00 just returns if TWI is not yet in a + ready state. When there's another interrupt, and the interface *is* ready, then it + sets up the read, starts it, and registers twi_read01 as the function to call after + the *next* interrupt. twi_read01, then, just returns if the interface is still in a + "reading" state. When the reading is done, it copies the information to the buffer, + cleans up, and calls the user-requested callback function with the actual number of + bytes read. + + The writing is similar. + + Questions, comments and problems can go to Gene@Telobot.com. + + Thumbs Up! + Gene Knight + + */ + + uint8_t TwoWire::rxBuffer[NBWIRE_BUFFER_LENGTH]; + uint8_t TwoWire::rxBufferIndex = 0; + uint8_t TwoWire::rxBufferLength = 0; + + uint8_t TwoWire::txAddress = 0; + uint8_t TwoWire::txBuffer[NBWIRE_BUFFER_LENGTH]; + uint8_t TwoWire::txBufferIndex = 0; + uint8_t TwoWire::txBufferLength = 0; + + //uint8_t TwoWire::transmitting = 0; + void (*TwoWire::user_onRequest)(void); + void (*TwoWire::user_onReceive)(int); + + static volatile uint8_t twi_transmitting; + static volatile uint8_t twi_state; + static uint8_t twi_slarw; + static volatile uint8_t twi_error; + static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; + static volatile uint8_t twi_masterBufferIndex; + static uint8_t twi_masterBufferLength; + static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; + static volatile uint8_t twi_rxBufferIndex; + //static volatile uint8_t twi_Interrupt_Continue_Command; + static volatile uint8_t twi_Return_Value; + static volatile uint8_t twi_Done; + void (*twi_cbendTransmissionDone)(int); + void (*twi_cbreadFromDone)(int); + + void twi_init() { + // initialize state + twi_state = TWI_READY; + + // activate internal pull-ups for twi + // as per note from atmega8 manual pg167 + sbi(PORTC, 4); + sbi(PORTC, 5); + + // initialize twi prescaler and bit rate + cbi(TWSR, TWPS0); // TWI Status Register - Prescaler bits + cbi(TWSR, TWPS1); + + /* twi bit rate formula from atmega128 manual pg 204 + SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) + note: TWBR should be 10 or higher for master mode + It is 72 for a 16mhz Wiring board with 100kHz TWI */ + + TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2; // bitrate register + // enable twi module, acks, and twi interrupt + + TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA); + + /* TWEN - TWI Enable Bit + TWIE - TWI Interrupt Enable + TWEA - TWI Enable Acknowledge Bit + TWINT - TWI Interrupt Flag + TWSTA - TWI Start Condition + */ + } + + typedef struct { + uint8_t address; + uint8_t* data; + uint8_t length; + uint8_t wait; + uint8_t i; + } twi_Write_Vars; + + twi_Write_Vars *ptwv = 0; + static void (*fNextInterruptFunction)(void) = 0; + + void twi_Finish(byte bRetVal) { + if (ptwv) { + free(ptwv); + ptwv = 0; + } + twi_Done = 0xFF; + twi_Return_Value = bRetVal; + fNextInterruptFunction = 0; + } + + uint8_t twii_WaitForDone(uint16_t timeout) { + uint32_t endMillis = millis() + timeout; + while (!twi_Done && (timeout == 0 || millis() < endMillis)) continue; + return twi_Return_Value; + } + + void twii_SetState(uint8_t ucState) { + twi_state = ucState; + } + + void twii_SetError(uint8_t ucError) { + twi_error = ucError ; + } + + void twii_InitBuffer(uint8_t ucPos, uint8_t ucLength) { + twi_masterBufferIndex = 0; + twi_masterBufferLength = ucLength; + } + + void twii_CopyToBuf(uint8_t* pData, uint8_t ucLength) { + uint8_t i; + for (i = 0; i < ucLength; ++i) { + twi_masterBuffer[i] = pData[i]; + } + } + + void twii_CopyFromBuf(uint8_t *pData, uint8_t ucLength) { + uint8_t i; + for (i = 0; i < ucLength; ++i) { + pData[i] = twi_masterBuffer[i]; + } + } + + void twii_SetSlaRW(uint8_t ucSlaRW) { + twi_slarw = ucSlaRW; + } + + void twii_SetStart() { + TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWSTA); + } + + void twi_write01() { + if (TWI_MTX == twi_state) return; // blocking test + twi_transmitting = 0 ; + if (twi_error == 0xFF) + twi_Finish (0); // success + else if (twi_error == TW_MT_SLA_NACK) + twi_Finish (2); // error: address send, nack received + else if (twi_error == TW_MT_DATA_NACK) + twi_Finish (3); // error: data send, nack received + else + twi_Finish (4); // other twi error + if (twi_cbendTransmissionDone) return twi_cbendTransmissionDone(twi_Return_Value); + return; + } + + + void twi_write00() { + if (TWI_READY != twi_state) return; // blocking test + if (TWI_BUFFER_LENGTH < ptwv -> length) { + twi_Finish(1); // end write with error 1 + return; + } + twi_Done = 0x00; // show as working + twii_SetState(TWI_MTX); // to transmitting + twii_SetError(0xFF); // to No Error + twii_InitBuffer(0, ptwv -> length); // pointer and length + twii_CopyToBuf(ptwv -> data, ptwv -> length); // get the data + twii_SetSlaRW((ptwv -> address << 1) | TW_WRITE); // write command + twii_SetStart(); // start the cycle + fNextInterruptFunction = twi_write01; // next routine + return twi_write01(); + } + + void twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait) { + uint8_t i; + ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars)); + ptwv -> address = address; + ptwv -> data = data; + ptwv -> length = length; + ptwv -> wait = wait; + fNextInterruptFunction = twi_write00; + return twi_write00(); + } + + void twi_read01() { + if (TWI_MRX == twi_state) return; // blocking test + if (twi_masterBufferIndex < ptwv -> length) ptwv -> length = twi_masterBufferIndex; + twii_CopyFromBuf(ptwv -> data, ptwv -> length); + twi_Finish(ptwv -> length); + if (twi_cbreadFromDone) return twi_cbreadFromDone(twi_Return_Value); + return; + } + + void twi_read00() { + if (TWI_READY != twi_state) return; // blocking test + if (TWI_BUFFER_LENGTH < ptwv -> length) twi_Finish(0); // error return + twi_Done = 0x00; // show as working + twii_SetState(TWI_MRX); // reading + twii_SetError(0xFF); // reset error + twii_InitBuffer(0, ptwv -> length - 1); // init to one less than length + twii_SetSlaRW((ptwv -> address << 1) | TW_READ); // read command + twii_SetStart(); // start cycle + fNextInterruptFunction = twi_read01; + return twi_read01(); + } + + void twi_readFrom(uint8_t address, uint8_t* data, uint8_t length) { + uint8_t i; + + ptwv = (twi_Write_Vars *)malloc(sizeof(twi_Write_Vars)); + ptwv -> address = address; + ptwv -> data = data; + ptwv -> length = length; + fNextInterruptFunction = twi_read00; + return twi_read00(); + } + + void twi_reply(uint8_t ack) { + // transmit master read ready signal, with or without ack + if (ack){ + TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 << TWEA); + } else { + TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWINT); + } + } + + void twi_stop(void) { + // send stop condition + TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA) | (1 << TWINT) | (1 << TWSTO); + + // wait for stop condition to be exectued on bus + // TWINT is not set after a stop condition! + while (TWCR & (1 << TWSTO)) { + continue; + } + + // update twi state + twi_state = TWI_READY; + } + + void twi_releaseBus(void) { + // release bus + TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWEA) | (1 << TWINT); + + // update twi state + twi_state = TWI_READY; + } + + SIGNAL(TWI_vect) { + switch (TW_STATUS) { + // All Master + case TW_START: // sent start condition + case TW_REP_START: // sent repeated start condition + // copy device address and r/w bit to output register and ack + TWDR = twi_slarw; + twi_reply(1); + break; + + // Master Transmitter + case TW_MT_SLA_ACK: // slave receiver acked address + case TW_MT_DATA_ACK: // slave receiver acked data + // if there is data to send, send it, otherwise stop + if (twi_masterBufferIndex < twi_masterBufferLength) { + // copy data to output register and ack + TWDR = twi_masterBuffer[twi_masterBufferIndex++]; + twi_reply(1); + } else { + twi_stop(); + } + break; + + case TW_MT_SLA_NACK: // address sent, nack received + twi_error = TW_MT_SLA_NACK; + twi_stop(); + break; + + case TW_MT_DATA_NACK: // data sent, nack received + twi_error = TW_MT_DATA_NACK; + twi_stop(); + break; + + case TW_MT_ARB_LOST: // lost bus arbitration + twi_error = TW_MT_ARB_LOST; + twi_releaseBus(); + break; + + // Master Receiver + case TW_MR_DATA_ACK: // data received, ack sent + // put byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + + case TW_MR_SLA_ACK: // address sent, ack received + // ack if more bytes are expected, otherwise nack + if (twi_masterBufferIndex < twi_masterBufferLength) { + twi_reply(1); + } else { + twi_reply(0); + } + break; + + case TW_MR_DATA_NACK: // data received, nack sent + // put final byte into buffer + twi_masterBuffer[twi_masterBufferIndex++] = TWDR; + + case TW_MR_SLA_NACK: // address sent, nack received + twi_stop(); + break; + + // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case + + // Slave Receiver (NOT IMPLEMENTED YET) + /* + case TW_SR_SLA_ACK: // addressed, returned ack + case TW_SR_GCALL_ACK: // addressed generally, returned ack + case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack + case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack + // enter slave receiver mode + twi_state = TWI_SRX; + + // indicate that rx buffer can be overwritten and ack + twi_rxBufferIndex = 0; + twi_reply(1); + break; + + case TW_SR_DATA_ACK: // data received, returned ack + case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack + // if there is still room in the rx buffer + if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { + // put byte in buffer and ack + twi_rxBuffer[twi_rxBufferIndex++] = TWDR; + twi_reply(1); + } else { + // otherwise nack + twi_reply(0); + } + break; + + case TW_SR_STOP: // stop or repeated start condition received + // put a null char after data if there's room + if (twi_rxBufferIndex < TWI_BUFFER_LENGTH) { + twi_rxBuffer[twi_rxBufferIndex] = 0; + } + + // sends ack and stops interface for clock stretching + twi_stop(); + + // callback to user defined callback + twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); + + // since we submit rx buffer to "wire" library, we can reset it + twi_rxBufferIndex = 0; + + // ack future responses and leave slave receiver state + twi_releaseBus(); + break; + + case TW_SR_DATA_NACK: // data received, returned nack + case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack + // nack back at master + twi_reply(0); + break; + + // Slave Transmitter + case TW_ST_SLA_ACK: // addressed, returned ack + case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack + // enter slave transmitter mode + twi_state = TWI_STX; + + // ready the tx buffer index for iteration + twi_txBufferIndex = 0; + + // set tx buffer length to be zero, to verify if user changes it + twi_txBufferLength = 0; + + // request for txBuffer to be filled and length to be set + // note: user must call twi_transmit(bytes, length) to do this + twi_onSlaveTransmit(); + + // if they didn't change buffer & length, initialize it + if (0 == twi_txBufferLength) { + twi_txBufferLength = 1; + twi_txBuffer[0] = 0x00; + } + + // transmit first byte from buffer, fall through + + case TW_ST_DATA_ACK: // byte sent, ack returned + // copy data to output register + TWDR = twi_txBuffer[twi_txBufferIndex++]; + + // if there is more to send, ack, otherwise nack + if (twi_txBufferIndex < twi_txBufferLength) { + twi_reply(1); + } else { + twi_reply(0); + } + break; + + case TW_ST_DATA_NACK: // received nack, we are done + case TW_ST_LAST_DATA: // received ack, but we are done already! + // ack future responses + twi_reply(1); + // leave slave receiver state + twi_state = TWI_READY; + break; + */ + + // all + case TW_NO_INFO: // no state information + break; + + case TW_BUS_ERROR: // bus error, illegal stop/start + twi_error = TW_BUS_ERROR; + twi_stop(); + break; + } + + if (fNextInterruptFunction) return fNextInterruptFunction(); + } + + TwoWire::TwoWire() { } + + void TwoWire::begin(void) { + rxBufferIndex = 0; + rxBufferLength = 0; + + txBufferIndex = 0; + txBufferLength = 0; + + twi_init(); + } + + void TwoWire::beginTransmission(uint8_t address) { + //beginTransmission((uint8_t)address); + + // indicate that we are transmitting + twi_transmitting = 1; + + // set address of targeted slave + txAddress = address; + + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + } + + uint8_t TwoWire::endTransmission(uint16_t timeout) { + // transmit buffer (blocking) + //int8_t ret = + twi_cbendTransmissionDone = NULL; + twi_writeTo(txAddress, txBuffer, txBufferLength, 1); + int8_t ret = twii_WaitForDone(timeout); + + // reset tx buffer iterator vars + txBufferIndex = 0; + txBufferLength = 0; + + // indicate that we are done transmitting + // twi_transmitting = 0; + return ret; + } + + void TwoWire::nbendTransmission(void (*function)(int)) { + twi_cbendTransmissionDone = function; + twi_writeTo(txAddress, txBuffer, txBufferLength, 1); + return; + } + + void TwoWire::send(uint8_t data) { + if (twi_transmitting) { + // in master transmitter mode + // don't bother if buffer is full + if (txBufferLength >= NBWIRE_BUFFER_LENGTH) { + return; + } + + // put byte in tx buffer + txBuffer[txBufferIndex] = data; + ++txBufferIndex; + + // update amount in buffer + txBufferLength = txBufferIndex; + } else { + // in slave send mode + // reply to master + //twi_transmit(&data, 1); + } + } + + uint8_t TwoWire::receive(void) { + // default to returning null char + // for people using with char strings + uint8_t value = 0; + + // get each successive byte on each call + if (rxBufferIndex < rxBufferLength) { + value = rxBuffer[rxBufferIndex]; + ++rxBufferIndex; + } + + return value; + } + + uint8_t TwoWire::requestFrom(uint8_t address, int quantity, uint16_t timeout) { + // clamp to buffer length + if (quantity > NBWIRE_BUFFER_LENGTH) { + quantity = NBWIRE_BUFFER_LENGTH; + } + + // perform blocking read into buffer + twi_cbreadFromDone = NULL; + twi_readFrom(address, rxBuffer, quantity); + uint8_t read = twii_WaitForDone(timeout); + + // set rx buffer iterator vars + rxBufferIndex = 0; + rxBufferLength = read; + + return read; + } + + void TwoWire::nbrequestFrom(uint8_t address, int quantity, void (*function)(int)) { + // clamp to buffer length + if (quantity > NBWIRE_BUFFER_LENGTH) { + quantity = NBWIRE_BUFFER_LENGTH; + } + + // perform blocking read into buffer + twi_cbreadFromDone = function; + twi_readFrom(address, rxBuffer, quantity); + //uint8_t read = twii_WaitForDone(); + + // set rx buffer iterator vars + //rxBufferIndex = 0; + //rxBufferLength = read; + + rxBufferIndex = 0; + rxBufferLength = quantity; // this is a hack + + return; //read; + } + + uint8_t TwoWire::available(void) { + return rxBufferLength - rxBufferIndex; + } + +#endif diff --git a/lib/MPU6050/src/I2Cdev.h b/lib/MPU6050/src/I2Cdev.h new file mode 100644 index 0000000..5b59c56 --- /dev/null +++ b/lib/MPU6050/src/I2Cdev.h @@ -0,0 +1,311 @@ +// I2Cdev library collection - Main I2C device class header file +// Abstracts bit and byte I2C R/W functions into a convenient class +// 2013-06-05 by Jeff Rowberg +// +// Changelog: +// 2021-09-28 - allow custom Wire object as transaction function argument +// 2020-01-20 - hardija : complete support for Teensy 3.x +// 2015-10-30 - simondlevy : support i2c_t3 for Teensy3.1 +// 2013-05-06 - add Francesco Ferrara's Fastwire v0.24 implementation with small modifications +// 2013-05-05 - fix issue with writing bit values to words (Sasquatch/Farzanegan) +// 2012-06-09 - fix major issue with reading > 32 bytes at a time with Arduino Wire +// - add compiler warnings when using outdated or IDE or limited I2Cdev implementation +// 2011-11-01 - fix write*Bits mask calculation (thanks sasquatch @ Arduino forums) +// 2011-10-03 - added automatic Arduino version detection for ease of use +// 2011-10-02 - added Gene Knight's NBWire TwoWire class implementation with small modifications +// 2011-08-31 - added support for Arduino 1.0 Wire library (methods are different from 0.x) +// 2011-08-03 - added optional timeout parameter to read* methods to easily change from default +// 2011-08-02 - added support for 16-bit registers +// - fixed incorrect Doxygen comments on some methods +// - added timeout value for read operations (thanks mem @ Arduino forums) +// 2011-07-30 - changed read/write function structures to return success or byte counts +// - made all methods static for multi-device memory savings +// 2011-07-28 - initial release + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2013 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#ifndef _I2CDEV_H_ +#define _I2CDEV_H_ + +// ----------------------------------------------------------------------------- +// Enable deprecated pgmspace typedefs in avr-libc +// ----------------------------------------------------------------------------- +#define __PROG_TYPES_COMPAT__ + +// ----------------------------------------------------------------------------- +// I2C interface implementation setting +// ----------------------------------------------------------------------------- +#ifndef I2CDEV_IMPLEMENTATION +#define I2CDEV_IMPLEMENTATION I2CDEV_ARDUINO_WIRE +//#define I2CDEV_IMPLEMENTATION I2CDEV_TEENSY_3X_WIRE +//#define I2CDEV_IMPLEMENTATION I2CDEV_BUILTIN_SBWIRE +//#define I2CDEV_IMPLEMENTATION I2CDEV_BUILTIN_FASTWIRE +#endif // I2CDEV_IMPLEMENTATION + +// comment this out if you are using a non-optimal IDE/implementation setting +// but want the compiler to shut up about it +#define I2CDEV_IMPLEMENTATION_WARNINGS + +// ----------------------------------------------------------------------------- +// I2C interface implementation options +// ----------------------------------------------------------------------------- +#define I2CDEV_ARDUINO_WIRE 1 // Wire object from Arduino +#define I2CDEV_BUILTIN_NBWIRE 2 // Tweaked Wire object from Gene Knight's NBWire project + // ^^^ NBWire implementation is still buggy w/some interrupts! +#define I2CDEV_BUILTIN_FASTWIRE 3 // FastWire object from Francesco Ferrara's project +#define I2CDEV_I2CMASTER_LIBRARY 4 // I2C object from DSSCircuits I2C-Master Library at https://github.com/DSSCircuits/I2C-Master-Library +#define I2CDEV_BUILTIN_SBWIRE 5 // I2C object from Shuning (Steve) Bian's SBWire Library at https://github.com/freespace/SBWire +#define I2CDEV_TEENSY_3X_WIRE 6 // Teensy 3.x support using i2c_t3 library + +// ----------------------------------------------------------------------------- +// Arduino-style "Serial.print" debug constant (uncomment to enable) +// ----------------------------------------------------------------------------- +//#define I2CDEV_SERIAL_DEBUG + +#ifdef ARDUINO + #if ARDUINO < 100 + #include "WProgram.h" + #else + #include "Arduino.h" + #endif + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include + #endif + #if I2CDEV_IMPLEMENTATION == I2CDEV_TEENSY_3X_WIRE + #include + #endif + #if I2CDEV_IMPLEMENTATION == I2CDEV_I2CMASTER_LIBRARY + #include + #endif + #if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_SBWIRE + #include "SBWire.h" + #endif +#endif + +#ifdef SPARK + #include "application.h" + #define ARDUINO 101 + #define BUFFER_LENGTH 32 +#endif + +#ifndef I2CDEVLIB_WIRE_BUFFER_LENGTH + #if defined(I2C_BUFFER_LENGTH) + // Arduino ESP32 core Wire uses this + #define I2CDEVLIB_WIRE_BUFFER_LENGTH I2C_BUFFER_LENGTH + #elif defined(BUFFER_LENGTH) + // Arduino AVR core Wire and many others use this + #define I2CDEVLIB_WIRE_BUFFER_LENGTH BUFFER_LENGTH + #elif defined(SERIAL_BUFFER_SIZE) + // Arduino SAMD core Wire uses this + #define I2CDEVLIB_WIRE_BUFFER_LENGTH SERIAL_BUFFER_SIZE + #else + // should be a safe fallback, though possibly inefficient + #define I2CDEVLIB_WIRE_BUFFER_LENGTH 32 + #endif +#endif + +// 1000ms default read timeout (modify with "I2Cdev::readTimeout = [ms];") +#define I2CDEV_DEFAULT_READ_TIMEOUT 1000 + +class I2Cdev { + public: + I2Cdev(); + + static int8_t readBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readWord(uint8_t devAddr, uint8_t regAddr, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + static int8_t readWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0); + + static bool writeBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data, void *wireObj=0); + static bool writeBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data, void *wireObj=0); + static bool writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data, void *wireObj=0); + static bool writeBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data, void *wireObj=0); + static bool writeByte(uint8_t devAddr, uint8_t regAddr, uint8_t data, void *wireObj=0); + static bool writeWord(uint8_t devAddr, uint8_t regAddr, uint16_t data, void *wireObj=0); + static bool writeBytes(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint8_t *data, void *wireObj=0); + static bool writeWords(uint8_t devAddr, uint8_t regAddr, uint8_t length, uint16_t *data, void *wireObj=0); + + static uint16_t readTimeout; +}; + +#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + ////////////////////// + // FastWire 0.24 + // This is a library to help faster programs to read I2C devices. + // Copyright(C) 2012 + // Francesco Ferrara + ////////////////////// + + /* Master */ + #define TW_START 0x08 + #define TW_REP_START 0x10 + + /* Master Transmitter */ + #define TW_MT_SLA_ACK 0x18 + #define TW_MT_SLA_NACK 0x20 + #define TW_MT_DATA_ACK 0x28 + #define TW_MT_DATA_NACK 0x30 + #define TW_MT_ARB_LOST 0x38 + + /* Master Receiver */ + #define TW_MR_ARB_LOST 0x38 + #define TW_MR_SLA_ACK 0x40 + #define TW_MR_SLA_NACK 0x48 + #define TW_MR_DATA_ACK 0x50 + #define TW_MR_DATA_NACK 0x58 + + #define TW_OK 0 + #define TW_ERROR 1 + + class Fastwire { + private: + static boolean waitInt(); + + public: + static void setup(int khz, boolean pullup); + static byte beginTransmission(byte device); + static byte write(byte value); + static byte writeBuf(byte device, byte address, byte *data, byte num); + static byte readBuf(byte device, byte address, byte *data, byte num); + static void reset(); + static byte stop(); + }; +#endif + +#if I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE + // NBWire implementation based heavily on code by Gene Knight + // Originally posted on the Arduino forum at http://arduino.cc/forum/index.php/topic,70705.0.html + // Originally offered to the i2cdevlib project at http://arduino.cc/forum/index.php/topic,68210.30.html + + #define NBWIRE_BUFFER_LENGTH 32 + + class TwoWire { + private: + static uint8_t rxBuffer[]; + static uint8_t rxBufferIndex; + static uint8_t rxBufferLength; + + static uint8_t txAddress; + static uint8_t txBuffer[]; + static uint8_t txBufferIndex; + static uint8_t txBufferLength; + + // static uint8_t transmitting; + static void (*user_onRequest)(void); + static void (*user_onReceive)(int); + static void onRequestService(void); + static void onReceiveService(uint8_t*, int); + + public: + TwoWire(); + void begin(); + void begin(uint8_t); + void begin(int); + void beginTransmission(uint8_t); + //void beginTransmission(int); + uint8_t endTransmission(uint16_t timeout=0); + void nbendTransmission(void (*function)(int)) ; + uint8_t requestFrom(uint8_t, int, uint16_t timeout=0); + //uint8_t requestFrom(int, int); + void nbrequestFrom(uint8_t, int, void (*function)(int)); + void send(uint8_t); + void send(uint8_t*, uint8_t); + //void send(int); + void send(char*); + uint8_t available(void); + uint8_t receive(void); + void onReceive(void (*)(int)); + void onRequest(void (*)(void)); + }; + + #define TWI_READY 0 + #define TWI_MRX 1 + #define TWI_MTX 2 + #define TWI_SRX 3 + #define TWI_STX 4 + + #define TW_WRITE 0 + #define TW_READ 1 + + #define TW_MT_SLA_NACK 0x20 + #define TW_MT_DATA_NACK 0x30 + + #define CPU_FREQ 16000000L + #define TWI_FREQ 100000L + #define TWI_BUFFER_LENGTH 32 + + /* TWI Status is in TWSR, in the top 5 bits: TWS7 - TWS3 */ + + #define TW_STATUS_MASK ((1 << TWS7)|(1 << TWS6)|(1 << TWS5)|(1 << TWS4)|(1 << TWS3)) + #define TW_STATUS (TWSR & TW_STATUS_MASK) + #define TW_START 0x08 + #define TW_REP_START 0x10 + #define TW_MT_SLA_ACK 0x18 + #define TW_MT_SLA_NACK 0x20 + #define TW_MT_DATA_ACK 0x28 + #define TW_MT_DATA_NACK 0x30 + #define TW_MT_ARB_LOST 0x38 + #define TW_MR_ARB_LOST 0x38 + #define TW_MR_SLA_ACK 0x40 + #define TW_MR_SLA_NACK 0x48 + #define TW_MR_DATA_ACK 0x50 + #define TW_MR_DATA_NACK 0x58 + #define TW_ST_SLA_ACK 0xA8 + #define TW_ST_ARB_LOST_SLA_ACK 0xB0 + #define TW_ST_DATA_ACK 0xB8 + #define TW_ST_DATA_NACK 0xC0 + #define TW_ST_LAST_DATA 0xC8 + #define TW_SR_SLA_ACK 0x60 + #define TW_SR_ARB_LOST_SLA_ACK 0x68 + #define TW_SR_GCALL_ACK 0x70 + #define TW_SR_ARB_LOST_GCALL_ACK 0x78 + #define TW_SR_DATA_ACK 0x80 + #define TW_SR_DATA_NACK 0x88 + #define TW_SR_GCALL_DATA_ACK 0x90 + #define TW_SR_GCALL_DATA_NACK 0x98 + #define TW_SR_STOP 0xA0 + #define TW_NO_INFO 0xF8 + #define TW_BUS_ERROR 0x00 + + //#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr)) + //#define _SFR_BYTE(sfr) _MMIO_BYTE(_SFR_ADDR(sfr)) + + #ifndef sbi // set bit + #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= (1 << bit)) + #endif // sbi + + #ifndef cbi // clear bit + #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~(1 << bit)) + #endif // cbi + + extern TwoWire Wire; + +#endif // I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_NBWIRE + +#endif /* _I2CDEV_H_ */ diff --git a/lib/MPU6050/src/MPU6050.cpp b/lib/MPU6050/src/MPU6050.cpp new file mode 100644 index 0000000..957ec2c --- /dev/null +++ b/lib/MPU6050/src/MPU6050.cpp @@ -0,0 +1,3478 @@ +// I2Cdev library collection - MPU6050 I2C device class +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 8/24/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021-09-27 - split implementations out of header files, finally +// 2019-07-08 - Added Auto Calibration routine +// ... - ongoing debug release + +// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE +// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF +// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#include "Arduino.h" +#include "MPU6050.h" +#if defined(ARDUINO_ARCH_MBED) +#include "api/deprecated-avr-comp/avr/dtostrf.c.impl" +#endif + +#ifndef DEBUG +// #define DEBUG 0 // Uncomment to enable debug output +#endif + +/** Specific address constructor. + * @param address I2C address, uses default I2C address if none is specified + * @see MPU6050_DEFAULT_ADDRESS + * @see MPU6050_ADDRESS_AD0_LOW + * @see MPU6050_ADDRESS_AD0_HIGH + */ +MPU6050_Base::MPU6050_Base(uint8_t address, void *wireObj):devAddr(address), wireObj(wireObj) { +} + +/** Power on and prepare for general usage. + * This will activate the device and take it out of sleep mode (which must be done + * after start-up). This function also sets both the accelerometer and the gyroscope + * to their most sensitive settings, namely +/- 2g and +/- 250 degrees/sec, and sets + * the clock source to use the X Gyro for reference, which is slightly better than + * the default internal clock source. + */ +void MPU6050_Base::initialize() { + setClockSource(MPU6050_CLOCK_PLL_XGYRO); + + setFullScaleGyroRange(MPU6050_GYRO_FS_250); + gyroscopeResolution = 250.0 / 16384.0; + + setFullScaleAccelRange(MPU6050_ACCEL_FS_2); + accelerationResolution = 2.0 / 16384.0; + + setSleepEnabled(false); // thanks to Jack Elston for pointing this one out! +} + +/** Power on and prepare for general usage. + * This will activate the device and take it out of sleep mode (which must be done + * after start-up). This function also sets both the accelerometer and the gyroscope + * to selected settings based on user perference. selection can be one of , + * + * Accelerometer: ACCEL_FS::A2G, ACCEL_FS::A4G, ACCEL_FS::A8G, ACCEL_FS::A16G, + * Gyroscope: GYRO_FS::G250DPS, GYRO_FS::G500DPS, GYRO_FS::G1000DPS, GYRO_FS::G2000DPS, + * + * the clock source to use the X Gyro for reference, which is slightly better than + * the default internal clock source. + */ +void MPU6050_Base::initialize(ACCEL_FS accelRange, GYRO_FS gyroRange) { + setClockSource(MPU6050_CLOCK_PLL_XGYRO); + + switch (accelRange) + { + case ACCEL_FS::A2G: + setFullScaleAccelRange(MPU6050_ACCEL_FS_2); + accelerationResolution = 2.0 / 16384.0; + + case ACCEL_FS::A4G: + setFullScaleAccelRange(MPU6050_ACCEL_FS_4); + accelerationResolution = 4.0 / 16384.0; + + case ACCEL_FS::A8G: + setFullScaleAccelRange(MPU6050_ACCEL_FS_8); + accelerationResolution = 8.0 / 16384.0; + + case ACCEL_FS::A16G: + setFullScaleAccelRange(MPU6050_ACCEL_FS_16); + accelerationResolution = 16.0 / 16384.0; + } + + switch (gyroRange) + { + case GYRO_FS::G250DPS: + setFullScaleGyroRange(MPU6050_GYRO_FS_250); + gyroscopeResolution = 250.0 / 16384.0; + + case GYRO_FS::G500DPS: + setFullScaleGyroRange(MPU6050_GYRO_FS_500); + gyroscopeResolution = 500.0 / 16384.0; + + case GYRO_FS::G1000DPS: + setFullScaleGyroRange(MPU6050_GYRO_FS_1000); + gyroscopeResolution = 1000.0 / 16384.0; + + case GYRO_FS::G2000DPS: + setFullScaleGyroRange(MPU6050_GYRO_FS_2000); + gyroscopeResolution = 2000.0 / 16384.0; + } + + setSleepEnabled(false); // thanks to Jack Elston for pointing this one out! +} + +/** Get the accelration resolution. + */ +float MPU6050_Base::get_acce_resolution() { + return accelerationResolution; +} + +/** Get the gyroscope resolution. + */ +float MPU6050_Base::get_gyro_resolution() { + return gyroscopeResolution; +} + +/** Verify the I2C connection. + * Make sure the device is connected and responds as expected. + * @return True if connection is valid, false otherwise + */ +bool MPU6050_Base::testConnection() { + uint8_t deviceId = getDeviceID(); + return (deviceId == 0x34) || (deviceId == 0xC); +} + +// AUX_VDDIO register (InvenSense demo code calls this RA_*G_OFFS_TC) + +/** Get the auxiliary I2C supply voltage level. + * When set to 1, the auxiliary I2C bus high logic level is VDD. When cleared to + * 0, the auxiliary I2C bus high logic level is VLOGIC. This does not apply to + * the MPU-6000, which does not have a VLOGIC pin. + * @return I2C supply voltage level (0=VLOGIC, 1=VDD) + */ +uint8_t MPU6050_Base::getAuxVDDIOLevel() { + I2Cdev::readBit(devAddr, MPU6050_RA_YG_OFFS_TC, MPU6050_TC_PWR_MODE_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the auxiliary I2C supply voltage level. + * When set to 1, the auxiliary I2C bus high logic level is VDD. When cleared to + * 0, the auxiliary I2C bus high logic level is VLOGIC. This does not apply to + * the MPU-6000, which does not have a VLOGIC pin. + * @param level I2C supply voltage level (0=VLOGIC, 1=VDD) + */ +void MPU6050_Base::setAuxVDDIOLevel(uint8_t level) { + I2Cdev::writeBit(devAddr, MPU6050_RA_YG_OFFS_TC, MPU6050_TC_PWR_MODE_BIT, level, wireObj); +} + +// SMPLRT_DIV register + +/** Get gyroscope output rate divider. + * The sensor register output, FIFO output, DMP sampling, Motion detection, Zero + * Motion detection, and Free Fall detection are all based on the Sample Rate. + * The Sample Rate is generated by dividing the gyroscope output rate by + * SMPLRT_DIV: + * + * Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) + * + * where Gyroscope Output Rate = 8kHz when the DLPF is disabled (DLPF_CFG = 0 or + * 7), and 1kHz when the DLPF is enabled (see Register 26). + * + * Note: The accelerometer output rate is 1kHz. This means that for a Sample + * Rate greater than 1kHz, the same accelerometer sample may be output to the + * FIFO, DMP, and sensor registers more than once. + * + * For a diagram of the gyroscope and accelerometer signal paths, see Section 8 + * of the MPU-6000/MPU-6050 Product Specification document. + * + * @return Current sample rate + * @see MPU6050_RA_SMPLRT_DIV + */ +uint8_t MPU6050_Base::getRate() { + I2Cdev::readByte(devAddr, MPU6050_RA_SMPLRT_DIV, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set gyroscope sample rate divider. + * @param rate New sample rate divider + * @see getRate() + * @see MPU6050_RA_SMPLRT_DIV + */ +void MPU6050_Base::setRate(uint8_t rate) { + I2Cdev::writeByte(devAddr, MPU6050_RA_SMPLRT_DIV, rate, wireObj); +} + +// CONFIG register + +/** Get external FSYNC configuration. + * Configures the external Frame Synchronization (FSYNC) pin sampling. An + * external signal connected to the FSYNC pin can be sampled by configuring + * EXT_SYNC_SET. Signal changes to the FSYNC pin are latched so that short + * strobes may be captured. The latched FSYNC signal will be sampled at the + * Sampling Rate, as defined in register 25. After sampling, the latch will + * reset to the current FSYNC signal state. + * + * The sampled value will be reported in place of the least significant bit in + * a sensor data register determined by the value of EXT_SYNC_SET according to + * the following table. + * + *

+ * EXT_SYNC_SET | FSYNC Bit Location
+ * -------------+-------------------
+ * 0            | Input disabled
+ * 1            | TEMP_OUT_L[0]
+ * 2            | GYRO_XOUT_L[0]
+ * 3            | GYRO_YOUT_L[0]
+ * 4            | GYRO_ZOUT_L[0]
+ * 5            | ACCEL_XOUT_L[0]
+ * 6            | ACCEL_YOUT_L[0]
+ * 7            | ACCEL_ZOUT_L[0]
+ * 
+ * + * @return FSYNC configuration value + */ +uint8_t MPU6050_Base::getExternalFrameSync() { + I2Cdev::readBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_EXT_SYNC_SET_BIT, MPU6050_CFG_EXT_SYNC_SET_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set external FSYNC configuration. + * @see getExternalFrameSync() + * @see MPU6050_RA_CONFIG + * @param sync New FSYNC configuration value + */ +void MPU6050_Base::setExternalFrameSync(uint8_t sync) { + I2Cdev::writeBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_EXT_SYNC_SET_BIT, MPU6050_CFG_EXT_SYNC_SET_LENGTH, sync, wireObj); +} +/** Get digital low-pass filter configuration. + * The DLPF_CFG parameter sets the digital low pass filter configuration. It + * also determines the internal sampling rate used by the device as shown in + * the table below. + * + * Note: The accelerometer output rate is 1kHz. This means that for a Sample + * Rate greater than 1kHz, the same accelerometer sample may be output to the + * FIFO, DMP, and sensor registers more than once. + * + *
+ *          |   ACCELEROMETER    |           GYROSCOPE
+ * DLPF_CFG | Bandwidth | Delay  | Bandwidth | Delay  | Sample Rate
+ * ---------+-----------+--------+-----------+--------+-------------
+ * 0        | 260Hz     | 0ms    | 256Hz     | 0.98ms | 8kHz
+ * 1        | 184Hz     | 2.0ms  | 188Hz     | 1.9ms  | 1kHz
+ * 2        | 94Hz      | 3.0ms  | 98Hz      | 2.8ms  | 1kHz
+ * 3        | 44Hz      | 4.9ms  | 42Hz      | 4.8ms  | 1kHz
+ * 4        | 21Hz      | 8.5ms  | 20Hz      | 8.3ms  | 1kHz
+ * 5        | 10Hz      | 13.8ms | 10Hz      | 13.4ms | 1kHz
+ * 6        | 5Hz       | 19.0ms | 5Hz       | 18.6ms | 1kHz
+ * 7        |   -- Reserved --   |   -- Reserved --   | Reserved
+ * 
+ * + * @return DLFP configuration + * @see MPU6050_RA_CONFIG + * @see MPU6050_CFG_DLPF_CFG_BIT + * @see MPU6050_CFG_DLPF_CFG_LENGTH + */ +uint8_t MPU6050_Base::getDLPFMode() { + I2Cdev::readBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_DLPF_CFG_BIT, MPU6050_CFG_DLPF_CFG_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set digital low-pass filter configuration. + * @param mode New DLFP configuration setting + * @see getDLPFBandwidth() + * @see MPU6050_DLPF_BW_256 + * @see MPU6050_RA_CONFIG + * @see MPU6050_CFG_DLPF_CFG_BIT + * @see MPU6050_CFG_DLPF_CFG_LENGTH + */ +void MPU6050_Base::setDLPFMode(uint8_t mode) { + I2Cdev::writeBits(devAddr, MPU6050_RA_CONFIG, MPU6050_CFG_DLPF_CFG_BIT, MPU6050_CFG_DLPF_CFG_LENGTH, mode, wireObj); +} + +// GYRO_CONFIG register + +/** Get full-scale gyroscope range. + * The FS_SEL parameter allows setting the full-scale range of the gyro sensors, + * as described in the table below. + * + *
+ * 0 = +/- 250 degrees/sec
+ * 1 = +/- 500 degrees/sec
+ * 2 = +/- 1000 degrees/sec
+ * 3 = +/- 2000 degrees/sec
+ * 
+ * + * @return Current full-scale gyroscope range setting + * @see MPU6050_GYRO_FS_250 + * @see MPU6050_RA_GYRO_CONFIG + * @see MPU6050_GCONFIG_FS_SEL_BIT + * @see MPU6050_GCONFIG_FS_SEL_LENGTH + */ +uint8_t MPU6050_Base::getFullScaleGyroRange() { + I2Cdev::readBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set full-scale gyroscope range. + * @param range New full-scale gyroscope range value + * @see getFullScaleRange() + * @see MPU6050_GYRO_FS_250 + * @see MPU6050_RA_GYRO_CONFIG + * @see MPU6050_GCONFIG_FS_SEL_BIT + * @see MPU6050_GCONFIG_FS_SEL_LENGTH + */ +void MPU6050_Base::setFullScaleGyroRange(uint8_t range) { + I2Cdev::writeBits(devAddr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range, wireObj); +} + +// SELF TEST FACTORY TRIM VALUES + +/** Get self-test factory trim value for accelerometer X axis. + * @return factory trim value + * @see MPU6050_RA_SELF_TEST_X + */ +uint8_t MPU6050_Base::getAccelXSelfTestFactoryTrim() { + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_X, &buffer[0], I2Cdev::readTimeout, wireObj); + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_A, &buffer[1], I2Cdev::readTimeout, wireObj); + return (buffer[0]>>3) | ((buffer[1]>>4) & 0x03); +} + +/** Get self-test factory trim value for accelerometer Y axis. + * @return factory trim value + * @see MPU6050_RA_SELF_TEST_Y + */ +uint8_t MPU6050_Base::getAccelYSelfTestFactoryTrim() { + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_Y, &buffer[0], I2Cdev::readTimeout, wireObj); + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_A, &buffer[1], I2Cdev::readTimeout, wireObj); + return (buffer[0]>>3) | ((buffer[1]>>2) & 0x03); +} + +/** Get self-test factory trim value for accelerometer Z axis. + * @return factory trim value + * @see MPU6050_RA_SELF_TEST_Z + */ +uint8_t MPU6050_Base::getAccelZSelfTestFactoryTrim() { + I2Cdev::readBytes(devAddr, MPU6050_RA_SELF_TEST_Z, 2, buffer, I2Cdev::readTimeout, wireObj); + return (buffer[0]>>3) | (buffer[1] & 0x03); +} + +/** Get self-test factory trim value for gyro X axis. + * @return factory trim value + * @see MPU6050_RA_SELF_TEST_X + */ +uint8_t MPU6050_Base::getGyroXSelfTestFactoryTrim() { + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_X, buffer, I2Cdev::readTimeout, wireObj); + return (buffer[0] & 0x1F); +} + +/** Get self-test factory trim value for gyro Y axis. + * @return factory trim value + * @see MPU6050_RA_SELF_TEST_Y + */ +uint8_t MPU6050_Base::getGyroYSelfTestFactoryTrim() { + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_Y, buffer, I2Cdev::readTimeout, wireObj); + return (buffer[0] & 0x1F); +} + +/** Get self-test factory trim value for gyro Z axis. + * @return factory trim value + * @see MPU6050_RA_SELF_TEST_Z + */ +uint8_t MPU6050_Base::getGyroZSelfTestFactoryTrim() { + I2Cdev::readByte(devAddr, MPU6050_RA_SELF_TEST_Z, buffer, I2Cdev::readTimeout, wireObj); + return (buffer[0] & 0x1F); +} + +// ACCEL_CONFIG register + +/** Get self-test enabled setting for accelerometer X axis. + * @return Self-test enabled value + * @see MPU6050_RA_ACCEL_CONFIG + */ +bool MPU6050_Base::getAccelXSelfTest() { + I2Cdev::readBit(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_XA_ST_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get self-test enabled setting for accelerometer X axis. + * @param enabled Self-test enabled value + * @see MPU6050_RA_ACCEL_CONFIG + */ +void MPU6050_Base::setAccelXSelfTest(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_XA_ST_BIT, enabled, wireObj); +} +/** Get self-test enabled value for accelerometer Y axis. + * @return Self-test enabled value + * @see MPU6050_RA_ACCEL_CONFIG + */ +bool MPU6050_Base::getAccelYSelfTest() { + I2Cdev::readBit(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_YA_ST_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get self-test enabled value for accelerometer Y axis. + * @param enabled Self-test enabled value + * @see MPU6050_RA_ACCEL_CONFIG + */ +void MPU6050_Base::setAccelYSelfTest(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_YA_ST_BIT, enabled, wireObj); +} +/** Get self-test enabled value for accelerometer Z axis. + * @return Self-test enabled value + * @see MPU6050_RA_ACCEL_CONFIG + */ +bool MPU6050_Base::getAccelZSelfTest() { + I2Cdev::readBit(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_ZA_ST_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set self-test enabled value for accelerometer Z axis. + * @param enabled Self-test enabled value + * @see MPU6050_RA_ACCEL_CONFIG + */ +void MPU6050_Base::setAccelZSelfTest(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_ZA_ST_BIT, enabled, wireObj); +} +/** Get full-scale accelerometer range. + * The FS_SEL parameter allows setting the full-scale range of the accelerometer + * sensors, as described in the table below. + * + *
+ * 0 = +/- 2g
+ * 1 = +/- 4g
+ * 2 = +/- 8g
+ * 3 = +/- 16g
+ * 
+ * + * @return Current full-scale accelerometer range setting + * @see MPU6050_ACCEL_FS_2 + * @see MPU6050_RA_ACCEL_CONFIG + * @see MPU6050_ACONFIG_AFS_SEL_BIT + * @see MPU6050_ACONFIG_AFS_SEL_LENGTH + */ +uint8_t MPU6050_Base::getFullScaleAccelRange() { + I2Cdev::readBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set full-scale accelerometer range. + * @param range New full-scale accelerometer range setting + * @see getFullScaleAccelRange() + */ +void MPU6050_Base::setFullScaleAccelRange(uint8_t range) { + I2Cdev::writeBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range, wireObj); +} +/** Get the high-pass filter configuration. + * The DHPF is a filter module in the path leading to motion detectors (Free + * Fall, Motion threshold, and Zero Motion). The high pass filter output is not + * available to the data registers (see Figure in Section 8 of the MPU-6000/ + * MPU-6050 Product Specification document). + * + * The high pass filter has three modes: + * + *
+ *    Reset: The filter output settles to zero within one sample. This
+ *           effectively disables the high pass filter. This mode may be toggled
+ *           to quickly settle the filter.
+ *
+ *    On:    The high pass filter will pass signals above the cut off frequency.
+ *
+ *    Hold:  When triggered, the filter holds the present sample. The filter
+ *           output will be the difference between the input sample and the held
+ *           sample.
+ * 
+ * + *
+ * ACCEL_HPF | Filter Mode | Cut-off Frequency
+ * ----------+-------------+------------------
+ * 0         | Reset       | None
+ * 1         | On          | 5Hz
+ * 2         | On          | 2.5Hz
+ * 3         | On          | 1.25Hz
+ * 4         | On          | 0.63Hz
+ * 7         | Hold        | None
+ * 
+ * + * @return Current high-pass filter configuration + * @see MPU6050_DHPF_RESET + * @see MPU6050_RA_ACCEL_CONFIG + */ +uint8_t MPU6050_Base::getDHPFMode() { + I2Cdev::readBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_ACCEL_HPF_BIT, MPU6050_ACONFIG_ACCEL_HPF_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the high-pass filter configuration. + * @param bandwidth New high-pass filter configuration + * @see setDHPFMode() + * @see MPU6050_DHPF_RESET + * @see MPU6050_RA_ACCEL_CONFIG + */ +void MPU6050_Base::setDHPFMode(uint8_t bandwidth) { + I2Cdev::writeBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_ACCEL_HPF_BIT, MPU6050_ACONFIG_ACCEL_HPF_LENGTH, bandwidth, wireObj); +} + +// FF_THR register + +/** Get free-fall event acceleration threshold. + * This register configures the detection threshold for Free Fall event + * detection. The unit of FF_THR is 1LSB = 2mg. Free Fall is detected when the + * absolute value of the accelerometer measurements for the three axes are each + * less than the detection threshold. This condition increments the Free Fall + * duration counter (Register 30). The Free Fall interrupt is triggered when the + * Free Fall duration counter reaches the time specified in FF_DUR. + * + * For more details on the Free Fall detection interrupt, see Section 8.2 of the + * MPU-6000/MPU-6050 Product Specification document as well as Registers 56 and + * 58 of this document. + * + * @return Current free-fall acceleration threshold value (LSB = 2mg) + * @see MPU6050_RA_FF_THR + */ +uint8_t MPU6050_Base::getFreefallDetectionThreshold() { + I2Cdev::readByte(devAddr, MPU6050_RA_FF_THR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get free-fall event acceleration threshold. + * @param threshold New free-fall acceleration threshold value (LSB = 2mg) + * @see getFreefallDetectionThreshold() + * @see MPU6050_RA_FF_THR + */ +void MPU6050_Base::setFreefallDetectionThreshold(uint8_t threshold) { + I2Cdev::writeByte(devAddr, MPU6050_RA_FF_THR, threshold, wireObj); +} + +// FF_DUR register + +/** Get free-fall event duration threshold. + * This register configures the duration counter threshold for Free Fall event + * detection. The duration counter ticks at 1kHz, therefore FF_DUR has a unit + * of 1 LSB = 1 ms. + * + * The Free Fall duration counter increments while the absolute value of the + * accelerometer measurements are each less than the detection threshold + * (Register 29). The Free Fall interrupt is triggered when the Free Fall + * duration counter reaches the time specified in this register. + * + * For more details on the Free Fall detection interrupt, see Section 8.2 of + * the MPU-6000/MPU-6050 Product Specification document as well as Registers 56 + * and 58 of this document. + * + * @return Current free-fall duration threshold value (LSB = 1ms) + * @see MPU6050_RA_FF_DUR + */ +uint8_t MPU6050_Base::getFreefallDetectionDuration() { + I2Cdev::readByte(devAddr, MPU6050_RA_FF_DUR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get free-fall event duration threshold. + * @param duration New free-fall duration threshold value (LSB = 1ms) + * @see getFreefallDetectionDuration() + * @see MPU6050_RA_FF_DUR + */ +void MPU6050_Base::setFreefallDetectionDuration(uint8_t duration) { + I2Cdev::writeByte(devAddr, MPU6050_RA_FF_DUR, duration, wireObj); +} + +// MOT_THR register + +/** Get motion detection event acceleration threshold. + * This register configures the detection threshold for Motion interrupt + * generation. The unit of MOT_THR is 1LSB = 2mg. Motion is detected when the + * absolute value of any of the accelerometer measurements exceeds this Motion + * detection threshold. This condition increments the Motion detection duration + * counter (Register 32). The Motion detection interrupt is triggered when the + * Motion Detection counter reaches the time count specified in MOT_DUR + * (Register 32). + * + * The Motion interrupt will indicate the axis and polarity of detected motion + * in MOT_DETECT_STATUS (Register 97). + * + * For more details on the Motion detection interrupt, see Section 8.3 of the + * MPU-6000/MPU-6050 Product Specification document as well as Registers 56 and + * 58 of this document. + * + * @return Current motion detection acceleration threshold value (LSB = 2mg) + * @see MPU6050_RA_MOT_THR + */ +uint8_t MPU6050_Base::getMotionDetectionThreshold() { + I2Cdev::readByte(devAddr, MPU6050_RA_MOT_THR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set motion detection event acceleration threshold. + * @param threshold New motion detection acceleration threshold value (LSB = 2mg) + * @see getMotionDetectionThreshold() + * @see MPU6050_RA_MOT_THR + */ +void MPU6050_Base::setMotionDetectionThreshold(uint8_t threshold) { + I2Cdev::writeByte(devAddr, MPU6050_RA_MOT_THR, threshold, wireObj); +} + +// MOT_DUR register + +/** Get motion detection event duration threshold. + * This register configures the duration counter threshold for Motion interrupt + * generation. The duration counter ticks at 1 kHz, therefore MOT_DUR has a unit + * of 1LSB = 1ms. The Motion detection duration counter increments when the + * absolute value of any of the accelerometer measurements exceeds the Motion + * detection threshold (Register 31). The Motion detection interrupt is + * triggered when the Motion detection counter reaches the time count specified + * in this register. + * + * For more details on the Motion detection interrupt, see Section 8.3 of the + * MPU-6000/MPU-6050 Product Specification document. + * + * @return Current motion detection duration threshold value (LSB = 1ms) + * @see MPU6050_RA_MOT_DUR + */ +uint8_t MPU6050_Base::getMotionDetectionDuration() { + I2Cdev::readByte(devAddr, MPU6050_RA_MOT_DUR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set motion detection event duration threshold. + * @param duration New motion detection duration threshold value (LSB = 1ms) + * @see getMotionDetectionDuration() + * @see MPU6050_RA_MOT_DUR + */ +void MPU6050_Base::setMotionDetectionDuration(uint8_t duration) { + I2Cdev::writeByte(devAddr, MPU6050_RA_MOT_DUR, duration, wireObj); +} + +// ZRMOT_THR register + +/** Get zero motion detection event acceleration threshold. + * This register configures the detection threshold for Zero Motion interrupt + * generation. The unit of ZRMOT_THR is 1LSB = 2mg. Zero Motion is detected when + * the absolute value of the accelerometer measurements for the 3 axes are each + * less than the detection threshold. This condition increments the Zero Motion + * duration counter (Register 34). The Zero Motion interrupt is triggered when + * the Zero Motion duration counter reaches the time count specified in + * ZRMOT_DUR (Register 34). + * + * Unlike Free Fall or Motion detection, Zero Motion detection triggers an + * interrupt both when Zero Motion is first detected and when Zero Motion is no + * longer detected. + * + * When a zero motion event is detected, a Zero Motion Status will be indicated + * in the MOT_DETECT_STATUS register (Register 97). When a motion-to-zero-motion + * condition is detected, the status bit is set to 1. When a zero-motion-to- + * motion condition is detected, the status bit is set to 0. + * + * For more details on the Zero Motion detection interrupt, see Section 8.4 of + * the MPU-6000/MPU-6050 Product Specification document as well as Registers 56 + * and 58 of this document. + * + * @return Current zero motion detection acceleration threshold value (LSB = 2mg) + * @see MPU6050_RA_ZRMOT_THR + */ +uint8_t MPU6050_Base::getZeroMotionDetectionThreshold() { + I2Cdev::readByte(devAddr, MPU6050_RA_ZRMOT_THR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set zero motion detection event acceleration threshold. + * @param threshold New zero motion detection acceleration threshold value (LSB = 2mg) + * @see getZeroMotionDetectionThreshold() + * @see MPU6050_RA_ZRMOT_THR + */ +void MPU6050_Base::setZeroMotionDetectionThreshold(uint8_t threshold) { + I2Cdev::writeByte(devAddr, MPU6050_RA_ZRMOT_THR, threshold, wireObj); +} + +// ZRMOT_DUR register + +/** Get zero motion detection event duration threshold. + * This register configures the duration counter threshold for Zero Motion + * interrupt generation. The duration counter ticks at 16 Hz, therefore + * ZRMOT_DUR has a unit of 1 LSB = 64 ms. The Zero Motion duration counter + * increments while the absolute value of the accelerometer measurements are + * each less than the detection threshold (Register 33). The Zero Motion + * interrupt is triggered when the Zero Motion duration counter reaches the time + * count specified in this register. + * + * For more details on the Zero Motion detection interrupt, see Section 8.4 of + * the MPU-6000/MPU-6050 Product Specification document, as well as Registers 56 + * and 58 of this document. + * + * @return Current zero motion detection duration threshold value (LSB = 64ms) + * @see MPU6050_RA_ZRMOT_DUR + */ +uint8_t MPU6050_Base::getZeroMotionDetectionDuration() { + I2Cdev::readByte(devAddr, MPU6050_RA_ZRMOT_DUR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set zero motion detection event duration threshold. + * @param duration New zero motion detection duration threshold value (LSB = 1ms) + * @see getZeroMotionDetectionDuration() + * @see MPU6050_RA_ZRMOT_DUR + */ +void MPU6050_Base::setZeroMotionDetectionDuration(uint8_t duration) { + I2Cdev::writeByte(devAddr, MPU6050_RA_ZRMOT_DUR, duration, wireObj); +} + +// FIFO_EN register + +/** Get temperature FIFO enabled value. + * When set to 1, this bit enables TEMP_OUT_H and TEMP_OUT_L (Registers 65 and + * 66) to be written into the FIFO buffer. + * @return Current temperature FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getTempFIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_TEMP_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set temperature FIFO enabled value. + * @param enabled New temperature FIFO enabled value + * @see getTempFIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setTempFIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_TEMP_FIFO_EN_BIT, enabled, wireObj); +} +/** Get gyroscope X-axis FIFO enabled value. + * When set to 1, this bit enables GYRO_XOUT_H and GYRO_XOUT_L (Registers 67 and + * 68) to be written into the FIFO buffer. + * @return Current gyroscope X-axis FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getXGyroFIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_XG_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set gyroscope X-axis FIFO enabled value. + * @param enabled New gyroscope X-axis FIFO enabled value + * @see getXGyroFIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setXGyroFIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_XG_FIFO_EN_BIT, enabled, wireObj); +} +/** Get gyroscope Y-axis FIFO enabled value. + * When set to 1, this bit enables GYRO_YOUT_H and GYRO_YOUT_L (Registers 69 and + * 70) to be written into the FIFO buffer. + * @return Current gyroscope Y-axis FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getYGyroFIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_YG_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set gyroscope Y-axis FIFO enabled value. + * @param enabled New gyroscope Y-axis FIFO enabled value + * @see getYGyroFIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setYGyroFIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_YG_FIFO_EN_BIT, enabled, wireObj); +} +/** Get gyroscope Z-axis FIFO enabled value. + * When set to 1, this bit enables GYRO_ZOUT_H and GYRO_ZOUT_L (Registers 71 and + * 72) to be written into the FIFO buffer. + * @return Current gyroscope Z-axis FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getZGyroFIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_ZG_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set gyroscope Z-axis FIFO enabled value. + * @param enabled New gyroscope Z-axis FIFO enabled value + * @see getZGyroFIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setZGyroFIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_ZG_FIFO_EN_BIT, enabled, wireObj); +} +/** Get accelerometer FIFO enabled value. + * When set to 1, this bit enables ACCEL_XOUT_H, ACCEL_XOUT_L, ACCEL_YOUT_H, + * ACCEL_YOUT_L, ACCEL_ZOUT_H, and ACCEL_ZOUT_L (Registers 59 to 64) to be + * written into the FIFO buffer. + * @return Current accelerometer FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getAccelFIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_ACCEL_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set accelerometer FIFO enabled value. + * @param enabled New accelerometer FIFO enabled value + * @see getAccelFIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setAccelFIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_ACCEL_FIFO_EN_BIT, enabled, wireObj); +} +/** Get Slave 2 FIFO enabled value. + * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) + * associated with Slave 2 to be written into the FIFO buffer. + * @return Current Slave 2 FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getSlave2FIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_SLV2_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Slave 2 FIFO enabled value. + * @param enabled New Slave 2 FIFO enabled value + * @see getSlave2FIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setSlave2FIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_SLV2_FIFO_EN_BIT, enabled, wireObj); +} +/** Get Slave 1 FIFO enabled value. + * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) + * associated with Slave 1 to be written into the FIFO buffer. + * @return Current Slave 1 FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getSlave1FIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_SLV1_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Slave 1 FIFO enabled value. + * @param enabled New Slave 1 FIFO enabled value + * @see getSlave1FIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setSlave1FIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_SLV1_FIFO_EN_BIT, enabled, wireObj); +} +/** Get Slave 0 FIFO enabled value. + * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) + * associated with Slave 0 to be written into the FIFO buffer. + * @return Current Slave 0 FIFO enabled value + * @see MPU6050_RA_FIFO_EN + */ +bool MPU6050_Base::getSlave0FIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_SLV0_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Slave 0 FIFO enabled value. + * @param enabled New Slave 0 FIFO enabled value + * @see getSlave0FIFOEnabled() + * @see MPU6050_RA_FIFO_EN + */ +void MPU6050_Base::setSlave0FIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_FIFO_EN, MPU6050_SLV0_FIFO_EN_BIT, enabled, wireObj); +} + +// I2C_MST_CTRL register + +/** Get multi-master enabled value. + * Multi-master capability allows multiple I2C masters to operate on the same + * bus. In circuits where multi-master capability is required, set MULT_MST_EN + * to 1. This will increase current drawn by approximately 30uA. + * + * In circuits where multi-master capability is required, the state of the I2C + * bus must always be monitored by each separate I2C Master. Before an I2C + * Master can assume arbitration of the bus, it must first confirm that no other + * I2C Master has arbitration of the bus. When MULT_MST_EN is set to 1, the + * MPU-60X0's bus arbitration detection logic is turned on, enabling it to + * detect when the bus is available. + * + * @return Current multi-master enabled value + * @see MPU6050_RA_I2C_MST_CTRL + */ +bool MPU6050_Base::getMultiMasterEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_MULT_MST_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set multi-master enabled value. + * @param enabled New multi-master enabled value + * @see getMultiMasterEnabled() + * @see MPU6050_RA_I2C_MST_CTRL + */ +void MPU6050_Base::setMultiMasterEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_MULT_MST_EN_BIT, enabled, wireObj); +} +/** Get wait-for-external-sensor-data enabled value. + * When the WAIT_FOR_ES bit is set to 1, the Data Ready interrupt will be + * delayed until External Sensor data from the Slave Devices are loaded into the + * EXT_SENS_DATA registers. This is used to ensure that both the internal sensor + * data (i.e. from gyro and accel) and external sensor data have been loaded to + * their respective data registers (i.e. the data is synced) when the Data Ready + * interrupt is triggered. + * + * @return Current wait-for-external-sensor-data enabled value + * @see MPU6050_RA_I2C_MST_CTRL + */ +bool MPU6050_Base::getWaitForExternalSensorEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_WAIT_FOR_ES_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set wait-for-external-sensor-data enabled value. + * @param enabled New wait-for-external-sensor-data enabled value + * @see getWaitForExternalSensorEnabled() + * @see MPU6050_RA_I2C_MST_CTRL + */ +void MPU6050_Base::setWaitForExternalSensorEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_WAIT_FOR_ES_BIT, enabled, wireObj); +} +/** Get Slave 3 FIFO enabled value. + * When set to 1, this bit enables EXT_SENS_DATA registers (Registers 73 to 96) + * associated with Slave 3 to be written into the FIFO buffer. + * @return Current Slave 3 FIFO enabled value + * @see MPU6050_RA_MST_CTRL + */ +bool MPU6050_Base::getSlave3FIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_SLV_3_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Slave 3 FIFO enabled value. + * @param enabled New Slave 3 FIFO enabled value + * @see getSlave3FIFOEnabled() + * @see MPU6050_RA_MST_CTRL + */ +void MPU6050_Base::setSlave3FIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_SLV_3_FIFO_EN_BIT, enabled, wireObj); +} +/** Get slave read/write transition enabled value. + * The I2C_MST_P_NSR bit configures the I2C Master's transition from one slave + * read to the next slave read. If the bit equals 0, there will be a restart + * between reads. If the bit equals 1, there will be a stop followed by a start + * of the following read. When a write transaction follows a read transaction, + * the stop followed by a start of the successive write will be always used. + * + * @return Current slave read/write transition enabled value + * @see MPU6050_RA_I2C_MST_CTRL + */ +bool MPU6050_Base::getSlaveReadWriteTransitionEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_I2C_MST_P_NSR_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set slave read/write transition enabled value. + * @param enabled New slave read/write transition enabled value + * @see getSlaveReadWriteTransitionEnabled() + * @see MPU6050_RA_I2C_MST_CTRL + */ +void MPU6050_Base::setSlaveReadWriteTransitionEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_I2C_MST_P_NSR_BIT, enabled, wireObj); +} +/** Get I2C master clock speed. + * I2C_MST_CLK is a 4 bit unsigned value which configures a divider on the + * MPU-60X0 internal 8MHz clock. It sets the I2C master clock speed according to + * the following table: + * + *
+ * I2C_MST_CLK | I2C Master Clock Speed | 8MHz Clock Divider
+ * ------------+------------------------+-------------------
+ * 0           | 348kHz                 | 23
+ * 1           | 333kHz                 | 24
+ * 2           | 320kHz                 | 25
+ * 3           | 308kHz                 | 26
+ * 4           | 296kHz                 | 27
+ * 5           | 286kHz                 | 28
+ * 6           | 276kHz                 | 29
+ * 7           | 267kHz                 | 30
+ * 8           | 258kHz                 | 31
+ * 9           | 500kHz                 | 16
+ * 10          | 471kHz                 | 17
+ * 11          | 444kHz                 | 18
+ * 12          | 421kHz                 | 19
+ * 13          | 400kHz                 | 20
+ * 14          | 381kHz                 | 21
+ * 15          | 364kHz                 | 22
+ * 
+ * + * @return Current I2C master clock speed + * @see MPU6050_RA_I2C_MST_CTRL + */ +uint8_t MPU6050_Base::getMasterClockSpeed() { + I2Cdev::readBits(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_I2C_MST_CLK_BIT, MPU6050_I2C_MST_CLK_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set I2C master clock speed. + * @reparam speed Current I2C master clock speed + * @see MPU6050_RA_I2C_MST_CTRL + */ +void MPU6050_Base::setMasterClockSpeed(uint8_t speed) { + I2Cdev::writeBits(devAddr, MPU6050_RA_I2C_MST_CTRL, MPU6050_I2C_MST_CLK_BIT, MPU6050_I2C_MST_CLK_LENGTH, speed, wireObj); +} + +// I2C_SLV* registers (Slave 0-3) + +/** Get the I2C address of the specified slave (0-3). + * Note that Bit 7 (MSB) controls read/write mode. If Bit 7 is set, it's a read + * operation, and if it is cleared, then it's a write operation. The remaining + * bits (6-0) are the 7-bit device address of the slave device. + * + * In read mode, the result of the read is placed in the lowest available + * EXT_SENS_DATA register. For further information regarding the allocation of + * read results, please refer to the EXT_SENS_DATA register description + * (Registers 73 - 96). + * + * The MPU-6050 supports a total of five slaves, but Slave 4 has unique + * characteristics, and so it has its own functions (getSlave4* and setSlave4*). + * + * I2C data transactions are performed at the Sample Rate, as defined in + * Register 25. The user is responsible for ensuring that I2C data transactions + * to and from each enabled Slave can be completed within a single period of the + * Sample Rate. + * + * The I2C slave access rate can be reduced relative to the Sample Rate. This + * reduced access rate is determined by I2C_MST_DLY (Register 52). Whether a + * slave's access rate is reduced relative to the Sample Rate is determined by + * I2C_MST_DELAY_CTRL (Register 103). + * + * The processing order for the slaves is fixed. The sequence followed for + * processing the slaves is Slave 0, Slave 1, Slave 2, Slave 3 and Slave 4. If a + * particular Slave is disabled it will be skipped. + * + * Each slave can either be accessed at the sample rate or at a reduced sample + * rate. In a case where some slaves are accessed at the Sample Rate and some + * slaves are accessed at the reduced rate, the sequence of accessing the slaves + * (Slave 0 to Slave 4) is still followed. However, the reduced rate slaves will + * be skipped if their access rate dictates that they should not be accessed + * during that particular cycle. For further information regarding the reduced + * access rate, please refer to Register 52. Whether a slave is accessed at the + * Sample Rate or at the reduced rate is determined by the Delay Enable bits in + * Register 103. + * + * @param num Slave number (0-3) + * @return Current address for specified slave + * @see MPU6050_RA_I2C_SLV0_ADDR + */ +uint8_t MPU6050_Base::getSlaveAddress(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readByte(devAddr, MPU6050_RA_I2C_SLV0_ADDR + num*3, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the I2C address of the specified slave (0-3). + * @param num Slave number (0-3) + * @param address New address for specified slave + * @see getSlaveAddress() + * @see MPU6050_RA_I2C_SLV0_ADDR + */ +void MPU6050_Base::setSlaveAddress(uint8_t num, uint8_t address) { + if (num > 3) return; + I2Cdev::writeByte(devAddr, MPU6050_RA_I2C_SLV0_ADDR + num*3, address, wireObj); +} +/** Get the active internal register for the specified slave (0-3). + * Read/write operations for this slave will be done to whatever internal + * register address is stored in this MPU register. + * + * The MPU-6050 supports a total of five slaves, but Slave 4 has unique + * characteristics, and so it has its own functions. + * + * @param num Slave number (0-3) + * @return Current active register for specified slave + * @see MPU6050_RA_I2C_SLV0_REG + */ +uint8_t MPU6050_Base::getSlaveRegister(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readByte(devAddr, MPU6050_RA_I2C_SLV0_REG + num*3, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the active internal register for the specified slave (0-3). + * @param num Slave number (0-3) + * @param reg New active register for specified slave + * @see getSlaveRegister() + * @see MPU6050_RA_I2C_SLV0_REG + */ +void MPU6050_Base::setSlaveRegister(uint8_t num, uint8_t reg) { + if (num > 3) return; + I2Cdev::writeByte(devAddr, MPU6050_RA_I2C_SLV0_REG + num*3, reg, wireObj); +} +/** Get the enabled value for the specified slave (0-3). + * When set to 1, this bit enables Slave 0 for data transfer operations. When + * cleared to 0, this bit disables Slave 0 from data transfer operations. + * @param num Slave number (0-3) + * @return Current enabled value for specified slave + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +bool MPU6050_Base::getSlaveEnabled(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the enabled value for the specified slave (0-3). + * @param num Slave number (0-3) + * @param enabled New enabled value for specified slave + * @see getSlaveEnabled() + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +void MPU6050_Base::setSlaveEnabled(uint8_t num, bool enabled) { + if (num > 3) return; + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_EN_BIT, enabled, wireObj); +} +/** Get word pair byte-swapping enabled for the specified slave (0-3). + * When set to 1, this bit enables byte swapping. When byte swapping is enabled, + * the high and low bytes of a word pair are swapped. Please refer to + * I2C_SLV0_GRP for the pairing convention of the word pairs. When cleared to 0, + * bytes transferred to and from Slave 0 will be written to EXT_SENS_DATA + * registers in the order they were transferred. + * + * @param num Slave number (0-3) + * @return Current word pair byte-swapping enabled value for specified slave + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +bool MPU6050_Base::getSlaveWordByteSwap(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_BYTE_SW_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set word pair byte-swapping enabled for the specified slave (0-3). + * @param num Slave number (0-3) + * @param enabled New word pair byte-swapping enabled value for specified slave + * @see getSlaveWordByteSwap() + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +void MPU6050_Base::setSlaveWordByteSwap(uint8_t num, bool enabled) { + if (num > 3) return; + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_BYTE_SW_BIT, enabled, wireObj); +} +/** Get write mode for the specified slave (0-3). + * When set to 1, the transaction will read or write data only. When cleared to + * 0, the transaction will write a register address prior to reading or writing + * data. This should equal 0 when specifying the register address within the + * Slave device to/from which the ensuing data transaction will take place. + * + * @param num Slave number (0-3) + * @return Current write mode for specified slave (0 = register address + data, 1 = data only) + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +bool MPU6050_Base::getSlaveWriteMode(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_REG_DIS_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set write mode for the specified slave (0-3). + * @param num Slave number (0-3) + * @param mode New write mode for specified slave (0 = register address + data, 1 = data only) + * @see getSlaveWriteMode() + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +void MPU6050_Base::setSlaveWriteMode(uint8_t num, bool mode) { + if (num > 3) return; + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_REG_DIS_BIT, mode, wireObj); +} +/** Get word pair grouping order offset for the specified slave (0-3). + * This sets specifies the grouping order of word pairs received from registers. + * When cleared to 0, bytes from register addresses 0 and 1, 2 and 3, etc (even, + * then odd register addresses) are paired to form a word. When set to 1, bytes + * from register addresses are paired 1 and 2, 3 and 4, etc. (odd, then even + * register addresses) are paired to form a word. + * + * @param num Slave number (0-3) + * @return Current word pair grouping order offset for specified slave + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +bool MPU6050_Base::getSlaveWordGroupOffset(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_GRP_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set word pair grouping order offset for the specified slave (0-3). + * @param num Slave number (0-3) + * @param enabled New word pair grouping order offset for specified slave + * @see getSlaveWordGroupOffset() + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +void MPU6050_Base::setSlaveWordGroupOffset(uint8_t num, bool enabled) { + if (num > 3) return; + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_GRP_BIT, enabled, wireObj); +} +/** Get number of bytes to read for the specified slave (0-3). + * Specifies the number of bytes transferred to and from Slave 0. Clearing this + * bit to 0 is equivalent to disabling the register by writing 0 to I2C_SLV0_EN. + * @param num Slave number (0-3) + * @return Number of bytes to read for specified slave + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +uint8_t MPU6050_Base::getSlaveDataLength(uint8_t num) { + if (num > 3) return 0; + I2Cdev::readBits(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_LEN_BIT, MPU6050_I2C_SLV_LEN_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set number of bytes to read for the specified slave (0-3). + * @param num Slave number (0-3) + * @param length Number of bytes to read for specified slave + * @see getSlaveDataLength() + * @see MPU6050_RA_I2C_SLV0_CTRL + */ +void MPU6050_Base::setSlaveDataLength(uint8_t num, uint8_t length) { + if (num > 3) return; + I2Cdev::writeBits(devAddr, MPU6050_RA_I2C_SLV0_CTRL + num*3, MPU6050_I2C_SLV_LEN_BIT, MPU6050_I2C_SLV_LEN_LENGTH, length, wireObj); +} + +// I2C_SLV* registers (Slave 4) + +/** Get the I2C address of Slave 4. + * Note that Bit 7 (MSB) controls read/write mode. If Bit 7 is set, it's a read + * operation, and if it is cleared, then it's a write operation. The remaining + * bits (6-0) are the 7-bit device address of the slave device. + * + * @return Current address for Slave 4 + * @see getSlaveAddress() + * @see MPU6050_RA_I2C_SLV4_ADDR + */ +uint8_t MPU6050_Base::getSlave4Address() { + I2Cdev::readByte(devAddr, MPU6050_RA_I2C_SLV4_ADDR, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the I2C address of Slave 4. + * @param address New address for Slave 4 + * @see getSlave4Address() + * @see MPU6050_RA_I2C_SLV4_ADDR + */ +void MPU6050_Base::setSlave4Address(uint8_t address) { + I2Cdev::writeByte(devAddr, MPU6050_RA_I2C_SLV4_ADDR, address, wireObj); +} +/** Get the active internal register for the Slave 4. + * Read/write operations for this slave will be done to whatever internal + * register address is stored in this MPU register. + * + * @return Current active register for Slave 4 + * @see MPU6050_RA_I2C_SLV4_REG + */ +uint8_t MPU6050_Base::getSlave4Register() { + I2Cdev::readByte(devAddr, MPU6050_RA_I2C_SLV4_REG, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the active internal register for Slave 4. + * @param reg New active register for Slave 4 + * @see getSlave4Register() + * @see MPU6050_RA_I2C_SLV4_REG + */ +void MPU6050_Base::setSlave4Register(uint8_t reg) { + I2Cdev::writeByte(devAddr, MPU6050_RA_I2C_SLV4_REG, reg, wireObj); +} +/** Set new byte to write to Slave 4. + * This register stores the data to be written into the Slave 4. If I2C_SLV4_RW + * is set 1 (set to read), this register has no effect. + * @param data New byte to write to Slave 4 + * @see MPU6050_RA_I2C_SLV4_DO + */ +void MPU6050_Base::setSlave4OutputByte(uint8_t data) { + I2Cdev::writeByte(devAddr, MPU6050_RA_I2C_SLV4_DO, data, wireObj); +} +/** Get the enabled value for the Slave 4. + * When set to 1, this bit enables Slave 4 for data transfer operations. When + * cleared to 0, this bit disables Slave 4 from data transfer operations. + * @return Current enabled value for Slave 4 + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +bool MPU6050_Base::getSlave4Enabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the enabled value for Slave 4. + * @param enabled New enabled value for Slave 4 + * @see getSlave4Enabled() + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +void MPU6050_Base::setSlave4Enabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_EN_BIT, enabled, wireObj); +} +/** Get the enabled value for Slave 4 transaction interrupts. + * When set to 1, this bit enables the generation of an interrupt signal upon + * completion of a Slave 4 transaction. When cleared to 0, this bit disables the + * generation of an interrupt signal upon completion of a Slave 4 transaction. + * The interrupt status can be observed in Register 54. + * + * @return Current enabled value for Slave 4 transaction interrupts. + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +bool MPU6050_Base::getSlave4InterruptEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_INT_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set the enabled value for Slave 4 transaction interrupts. + * @param enabled New enabled value for Slave 4 transaction interrupts. + * @see getSlave4InterruptEnabled() + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +void MPU6050_Base::setSlave4InterruptEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_INT_EN_BIT, enabled, wireObj); +} +/** Get write mode for Slave 4. + * When set to 1, the transaction will read or write data only. When cleared to + * 0, the transaction will write a register address prior to reading or writing + * data. This should equal 0 when specifying the register address within the + * Slave device to/from which the ensuing data transaction will take place. + * + * @return Current write mode for Slave 4 (0 = register address + data, 1 = data only) + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +bool MPU6050_Base::getSlave4WriteMode() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_REG_DIS_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set write mode for the Slave 4. + * @param mode New write mode for Slave 4 (0 = register address + data, 1 = data only) + * @see getSlave4WriteMode() + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +void MPU6050_Base::setSlave4WriteMode(bool mode) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_REG_DIS_BIT, mode, wireObj); +} +/** Get Slave 4 master delay value. + * This configures the reduced access rate of I2C slaves relative to the Sample + * Rate. When a slave's access rate is decreased relative to the Sample Rate, + * the slave is accessed every: + * + * 1 / (1 + I2C_MST_DLY) samples + * + * This base Sample Rate in turn is determined by SMPLRT_DIV (register 25) and + * DLPF_CFG (register 26). Whether a slave's access rate is reduced relative to + * the Sample Rate is determined by I2C_MST_DELAY_CTRL (register 103). For + * further information regarding the Sample Rate, please refer to register 25. + * + * @return Current Slave 4 master delay value + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +uint8_t MPU6050_Base::getSlave4MasterDelay() { + I2Cdev::readBits(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_MST_DLY_BIT, MPU6050_I2C_SLV4_MST_DLY_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Slave 4 master delay value. + * @param delay New Slave 4 master delay value + * @see getSlave4MasterDelay() + * @see MPU6050_RA_I2C_SLV4_CTRL + */ +void MPU6050_Base::setSlave4MasterDelay(uint8_t delay) { + I2Cdev::writeBits(devAddr, MPU6050_RA_I2C_SLV4_CTRL, MPU6050_I2C_SLV4_MST_DLY_BIT, MPU6050_I2C_SLV4_MST_DLY_LENGTH, delay, wireObj); +} +/** Get last available byte read from Slave 4. + * This register stores the data read from Slave 4. This field is populated + * after a read transaction. + * @return Last available byte read from to Slave 4 + * @see MPU6050_RA_I2C_SLV4_DI + */ +uint8_t MPU6050_Base::getSlate4InputByte() { + I2Cdev::readByte(devAddr, MPU6050_RA_I2C_SLV4_DI, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} + +// I2C_MST_STATUS register + +/** Get FSYNC interrupt status. + * This bit reflects the status of the FSYNC interrupt from an external device + * into the MPU-60X0. This is used as a way to pass an external interrupt + * through the MPU-60X0 to the host application processor. When set to 1, this + * bit will cause an interrupt if FSYNC_INT_EN is asserted in INT_PIN_CFG + * (Register 55). + * @return FSYNC interrupt status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getPassthroughStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_PASS_THROUGH_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Slave 4 transaction done status. + * Automatically sets to 1 when a Slave 4 transaction has completed. This + * triggers an interrupt if the I2C_MST_INT_EN bit in the INT_ENABLE register + * (Register 56) is asserted and if the SLV_4_DONE_INT bit is asserted in the + * I2C_SLV4_CTRL register (Register 52). + * @return Slave 4 transaction done status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getSlave4IsDone() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_SLV4_DONE_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get master arbitration lost status. + * This bit automatically sets to 1 when the I2C Master has lost arbitration of + * the auxiliary I2C bus (an error condition). This triggers an interrupt if the + * I2C_MST_INT_EN bit in the INT_ENABLE register (Register 56) is asserted. + * @return Master arbitration lost status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getLostArbitration() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_LOST_ARB_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Slave 4 NACK status. + * This bit automatically sets to 1 when the I2C Master receives a NACK in a + * transaction with Slave 4. This triggers an interrupt if the I2C_MST_INT_EN + * bit in the INT_ENABLE register (Register 56) is asserted. + * @return Slave 4 NACK interrupt status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getSlave4Nack() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_SLV4_NACK_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Slave 3 NACK status. + * This bit automatically sets to 1 when the I2C Master receives a NACK in a + * transaction with Slave 3. This triggers an interrupt if the I2C_MST_INT_EN + * bit in the INT_ENABLE register (Register 56) is asserted. + * @return Slave 3 NACK interrupt status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getSlave3Nack() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_SLV3_NACK_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Slave 2 NACK status. + * This bit automatically sets to 1 when the I2C Master receives a NACK in a + * transaction with Slave 2. This triggers an interrupt if the I2C_MST_INT_EN + * bit in the INT_ENABLE register (Register 56) is asserted. + * @return Slave 2 NACK interrupt status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getSlave2Nack() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_SLV2_NACK_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Slave 1 NACK status. + * This bit automatically sets to 1 when the I2C Master receives a NACK in a + * transaction with Slave 1. This triggers an interrupt if the I2C_MST_INT_EN + * bit in the INT_ENABLE register (Register 56) is asserted. + * @return Slave 1 NACK interrupt status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getSlave1Nack() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_SLV1_NACK_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Slave 0 NACK status. + * This bit automatically sets to 1 when the I2C Master receives a NACK in a + * transaction with Slave 0. This triggers an interrupt if the I2C_MST_INT_EN + * bit in the INT_ENABLE register (Register 56) is asserted. + * @return Slave 0 NACK interrupt status + * @see MPU6050_RA_I2C_MST_STATUS + */ +bool MPU6050_Base::getSlave0Nack() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_STATUS, MPU6050_MST_I2C_SLV0_NACK_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} + +// INT_PIN_CFG register + +/** Get interrupt logic level mode. + * Will be set 0 for active-high, 1 for active-low. + * @return Current interrupt mode (0=active-high, 1=active-low) + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_INT_LEVEL_BIT + */ +bool MPU6050_Base::getInterruptMode() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_LEVEL_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set interrupt logic level mode. + * @param mode New interrupt mode (0=active-high, 1=active-low) + * @see getInterruptMode() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_INT_LEVEL_BIT + */ +void MPU6050_Base::setInterruptMode(bool mode) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_LEVEL_BIT, mode, wireObj); +} +/** Get interrupt drive mode. + * Will be set 0 for push-pull, 1 for open-drain. + * @return Current interrupt drive mode (0=push-pull, 1=open-drain) + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_INT_OPEN_BIT + */ +bool MPU6050_Base::getInterruptDrive() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_OPEN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set interrupt drive mode. + * @param drive New interrupt drive mode (0=push-pull, 1=open-drain) + * @see getInterruptDrive() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_INT_OPEN_BIT + */ +void MPU6050_Base::setInterruptDrive(bool drive) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_OPEN_BIT, drive, wireObj); +} +/** Get interrupt latch mode. + * Will be set 0 for 50us-pulse, 1 for latch-until-int-cleared. + * @return Current latch mode (0=50us-pulse, 1=latch-until-int-cleared) + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_LATCH_INT_EN_BIT + */ +bool MPU6050_Base::getInterruptLatch() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_LATCH_INT_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set interrupt latch mode. + * @param latch New latch mode (0=50us-pulse, 1=latch-until-int-cleared) + * @see getInterruptLatch() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_LATCH_INT_EN_BIT + */ +void MPU6050_Base::setInterruptLatch(bool latch) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_LATCH_INT_EN_BIT, latch, wireObj); +} +/** Get interrupt latch clear mode. + * Will be set 0 for status-read-only, 1 for any-register-read. + * @return Current latch clear mode (0=status-read-only, 1=any-register-read) + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_INT_RD_CLEAR_BIT + */ +bool MPU6050_Base::getInterruptLatchClear() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_RD_CLEAR_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set interrupt latch clear mode. + * @param clear New latch clear mode (0=status-read-only, 1=any-register-read) + * @see getInterruptLatchClear() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_INT_RD_CLEAR_BIT + */ +void MPU6050_Base::setInterruptLatchClear(bool clear) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_INT_RD_CLEAR_BIT, clear, wireObj); +} +/** Get FSYNC interrupt logic level mode. + * @return Current FSYNC interrupt mode (0=active-high, 1=active-low) + * @see getFSyncInterruptMode() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT + */ +bool MPU6050_Base::getFSyncInterruptLevel() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set FSYNC interrupt logic level mode. + * @param mode New FSYNC interrupt mode (0=active-high, 1=active-low) + * @see getFSyncInterruptMode() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT + */ +void MPU6050_Base::setFSyncInterruptLevel(bool level) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT, level, wireObj); +} +/** Get FSYNC pin interrupt enabled setting. + * Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled setting + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_FSYNC_INT_EN_BIT + */ +bool MPU6050_Base::getFSyncInterruptEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_FSYNC_INT_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set FSYNC pin interrupt enabled setting. + * @param enabled New FSYNC pin interrupt enabled setting + * @see getFSyncInterruptEnabled() + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_FSYNC_INT_EN_BIT + */ +void MPU6050_Base::setFSyncInterruptEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_FSYNC_INT_EN_BIT, enabled, wireObj); +} +/** Get I2C bypass enabled status. + * When this bit is equal to 1 and I2C_MST_EN (Register 106 bit[5]) is equal to + * 0, the host application processor will be able to directly access the + * auxiliary I2C bus of the MPU-60X0. When this bit is equal to 0, the host + * application processor will not be able to directly access the auxiliary I2C + * bus of the MPU-60X0 regardless of the state of I2C_MST_EN (Register 106 + * bit[5]). + * @return Current I2C bypass enabled status + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_I2C_BYPASS_EN_BIT + */ +bool MPU6050_Base::getI2CBypassEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set I2C bypass enabled status. + * When this bit is equal to 1 and I2C_MST_EN (Register 106 bit[5]) is equal to + * 0, the host application processor will be able to directly access the + * auxiliary I2C bus of the MPU-60X0. When this bit is equal to 0, the host + * application processor will not be able to directly access the auxiliary I2C + * bus of the MPU-60X0 regardless of the state of I2C_MST_EN (Register 106 + * bit[5]). + * @param enabled New I2C bypass enabled status + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_I2C_BYPASS_EN_BIT + */ +void MPU6050_Base::setI2CBypassEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled, wireObj); +} +/** Get reference clock output enabled status. + * When this bit is equal to 1, a reference clock output is provided at the + * CLKOUT pin. When this bit is equal to 0, the clock output is disabled. For + * further information regarding CLKOUT, please refer to the MPU-60X0 Product + * Specification document. + * @return Current reference clock output enabled status + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_CLKOUT_EN_BIT + */ +bool MPU6050_Base::getClockOutputEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_CLKOUT_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set reference clock output enabled status. + * When this bit is equal to 1, a reference clock output is provided at the + * CLKOUT pin. When this bit is equal to 0, the clock output is disabled. For + * further information regarding CLKOUT, please refer to the MPU-60X0 Product + * Specification document. + * @param enabled New reference clock output enabled status + * @see MPU6050_RA_INT_PIN_CFG + * @see MPU6050_INTCFG_CLKOUT_EN_BIT + */ +void MPU6050_Base::setClockOutputEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_CLKOUT_EN_BIT, enabled, wireObj); +} + +// INT_ENABLE register + +/** Get full interrupt enabled status. + * Full register byte for all interrupts, for quick reading. Each bit will be + * set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_FF_BIT + **/ +uint8_t MPU6050_Base::getIntEnabled() { + I2Cdev::readByte(devAddr, MPU6050_RA_INT_ENABLE, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set full interrupt enabled status. + * Full register byte for all interrupts, for quick reading. Each bit should be + * set 0 for disabled, 1 for enabled. + * @param enabled New interrupt enabled status + * @see getIntFreefallEnabled() + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_FF_BIT + **/ +void MPU6050_Base::setIntEnabled(uint8_t enabled) { + I2Cdev::writeByte(devAddr, MPU6050_RA_INT_ENABLE, enabled, wireObj); +} +/** Get Free Fall interrupt enabled status. + * Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_FF_BIT + **/ +bool MPU6050_Base::getIntFreefallEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_FF_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Free Fall interrupt enabled status. + * @param enabled New interrupt enabled status + * @see getIntFreefallEnabled() + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_FF_BIT + **/ +void MPU6050_Base::setIntFreefallEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_FF_BIT, enabled, wireObj); +} +/** Get Motion Detection interrupt enabled status. + * Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_MOT_BIT + **/ +bool MPU6050_Base::getIntMotionEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_MOT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Motion Detection interrupt enabled status. + * @param enabled New interrupt enabled status + * @see getIntMotionEnabled() + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_MOT_BIT + **/ +void MPU6050_Base::setIntMotionEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_MOT_BIT, enabled, wireObj); +} +/** Get Zero Motion Detection interrupt enabled status. + * Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_ZMOT_BIT + **/ +bool MPU6050_Base::getIntZeroMotionEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_ZMOT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Zero Motion Detection interrupt enabled status. + * @param enabled New interrupt enabled status + * @see getIntZeroMotionEnabled() + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_ZMOT_BIT + **/ +void MPU6050_Base::setIntZeroMotionEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_ZMOT_BIT, enabled, wireObj); +} +/** Get FIFO Buffer Overflow interrupt enabled status. + * Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_FIFO_OFLOW_BIT + **/ +bool MPU6050_Base::getIntFIFOBufferOverflowEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_FIFO_OFLOW_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set FIFO Buffer Overflow interrupt enabled status. + * @param enabled New interrupt enabled status + * @see getIntFIFOBufferOverflowEnabled() + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_FIFO_OFLOW_BIT + **/ +void MPU6050_Base::setIntFIFOBufferOverflowEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_FIFO_OFLOW_BIT, enabled, wireObj); +} +/** Get I2C Master interrupt enabled status. + * This enables any of the I2C Master interrupt sources to generate an + * interrupt. Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_I2C_MST_INT_BIT + **/ +bool MPU6050_Base::getIntI2CMasterEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_I2C_MST_INT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set I2C Master interrupt enabled status. + * @param enabled New interrupt enabled status + * @see getIntI2CMasterEnabled() + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_I2C_MST_INT_BIT + **/ +void MPU6050_Base::setIntI2CMasterEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_I2C_MST_INT_BIT, enabled, wireObj); +} +/** Get Data Ready interrupt enabled setting. + * This event occurs each time a write operation to all of the sensor registers + * has been completed. Will be set 0 for disabled, 1 for enabled. + * @return Current interrupt enabled status + * @see MPU6050_RA_INT_ENABLE + * @see MPU6050_INTERRUPT_DATA_RDY_BIT + */ +bool MPU6050_Base::getIntDataReadyEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_DATA_RDY_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Data Ready interrupt enabled status. + * @param enabled New interrupt enabled status + * @see getIntDataReadyEnabled() + * @see MPU6050_RA_INT_CFG + * @see MPU6050_INTERRUPT_DATA_RDY_BIT + */ +void MPU6050_Base::setIntDataReadyEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_DATA_RDY_BIT, enabled, wireObj); +} + +// INT_STATUS register + +/** Get full set of interrupt status bits. + * These bits clear to 0 after the register has been read. Very useful + * for getting multiple INT statuses, since each single bit read clears + * all of them because it has to read the whole byte. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + */ +uint8_t MPU6050_Base::getIntStatus() { + I2Cdev::readByte(devAddr, MPU6050_RA_INT_STATUS, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Free Fall interrupt status. + * This bit automatically sets to 1 when a Free Fall interrupt has been + * generated. The bit clears to 0 after the register has been read. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + * @see MPU6050_INTERRUPT_FF_BIT + */ +bool MPU6050_Base::getIntFreefallStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_FF_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Motion Detection interrupt status. + * This bit automatically sets to 1 when a Motion Detection interrupt has been + * generated. The bit clears to 0 after the register has been read. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + * @see MPU6050_INTERRUPT_MOT_BIT + */ +bool MPU6050_Base::getIntMotionStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_MOT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Zero Motion Detection interrupt status. + * This bit automatically sets to 1 when a Zero Motion Detection interrupt has + * been generated. The bit clears to 0 after the register has been read. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + * @see MPU6050_INTERRUPT_ZMOT_BIT + */ +bool MPU6050_Base::getIntZeroMotionStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_ZMOT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get FIFO Buffer Overflow interrupt status. + * This bit automatically sets to 1 when a Free Fall interrupt has been + * generated. The bit clears to 0 after the register has been read. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + * @see MPU6050_INTERRUPT_FIFO_OFLOW_BIT + */ +bool MPU6050_Base::getIntFIFOBufferOverflowStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_FIFO_OFLOW_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get I2C Master interrupt status. + * This bit automatically sets to 1 when an I2C Master interrupt has been + * generated. For a list of I2C Master interrupts, please refer to Register 54. + * The bit clears to 0 after the register has been read. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + * @see MPU6050_INTERRUPT_I2C_MST_INT_BIT + */ +bool MPU6050_Base::getIntI2CMasterStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_I2C_MST_INT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Data Ready interrupt status. + * This bit automatically sets to 1 when a Data Ready interrupt has been + * generated. The bit clears to 0 after the register has been read. + * @return Current interrupt status + * @see MPU6050_RA_INT_STATUS + * @see MPU6050_INTERRUPT_DATA_RDY_BIT + */ +bool MPU6050_Base::getIntDataReadyStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_DATA_RDY_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} + +// ACCEL_*OUT_* registers + +/** Get raw 9-axis motion sensor readings (accel/gyro/compass). + * FUNCTION NOT FULLY IMPLEMENTED YET. + * @param ax 16-bit signed integer container for accelerometer X-axis value + * @param ay 16-bit signed integer container for accelerometer Y-axis value + * @param az 16-bit signed integer container for accelerometer Z-axis value + * @param gx 16-bit signed integer container for gyroscope X-axis value + * @param gy 16-bit signed integer container for gyroscope Y-axis value + * @param gz 16-bit signed integer container for gyroscope Z-axis value + * @param mx 16-bit signed integer container for magnetometer X-axis value + * @param my 16-bit signed integer container for magnetometer Y-axis value + * @param mz 16-bit signed integer container for magnetometer Z-axis value + * @see getMotion6() + * @see getAcceleration() + * @see getRotation() + * @see MPU6050_RA_ACCEL_XOUT_H + */ +void MPU6050_Base::getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz) { + (void)mx; // unused parameter + (void)my; // unused parameter + (void)mz; // unused parameter + + getMotion6(ax, ay, az, gx, gy, gz); + // TODO: magnetometer integration +} +/** Get raw 6-axis motion sensor readings (accel/gyro). + * Retrieves all currently available motion sensor values. + * @param ax 16-bit signed integer container for accelerometer X-axis value + * @param ay 16-bit signed integer container for accelerometer Y-axis value + * @param az 16-bit signed integer container for accelerometer Z-axis value + * @param gx 16-bit signed integer container for gyroscope X-axis value + * @param gy 16-bit signed integer container for gyroscope Y-axis value + * @param gz 16-bit signed integer container for gyroscope Z-axis value + * @see getAcceleration() + * @see getRotation() + * @see MPU6050_RA_ACCEL_XOUT_H + */ +void MPU6050_Base::getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz) { + I2Cdev::readBytes(devAddr, MPU6050_RA_ACCEL_XOUT_H, 14, buffer, I2Cdev::readTimeout, wireObj); + *ax = (((int16_t)buffer[0]) << 8) | buffer[1]; + *ay = (((int16_t)buffer[2]) << 8) | buffer[3]; + *az = (((int16_t)buffer[4]) << 8) | buffer[5]; + *gx = (((int16_t)buffer[8]) << 8) | buffer[9]; + *gy = (((int16_t)buffer[10]) << 8) | buffer[11]; + *gz = (((int16_t)buffer[12]) << 8) | buffer[13]; +} +/** Get 3-axis accelerometer readings. + * These registers store the most recent accelerometer measurements. + * Accelerometer measurements are written to these registers at the Sample Rate + * as defined in Register 25. + * + * The accelerometer measurement registers, along with the temperature + * measurement registers, gyroscope measurement registers, and external sensor + * data registers, are composed of two sets of registers: an internal register + * set and a user-facing read register set. + * + * The data within the accelerometer sensors' internal register set is always + * updated at the Sample Rate. Meanwhile, the user-facing read register set + * duplicates the internal register set's data values whenever the serial + * interface is idle. This guarantees that a burst read of sensor registers will + * read measurements from the same sampling instant. Note that if burst reads + * are not used, the user is responsible for ensuring a set of single byte reads + * correspond to a single sampling instant by checking the Data Ready interrupt. + * + * Each 16-bit accelerometer measurement has a full scale defined in ACCEL_FS + * (Register 28). For each full scale setting, the accelerometers' sensitivity + * per LSB in ACCEL_xOUT is shown in the table below: + * + *
+ * AFS_SEL | Full Scale Range | LSB Sensitivity
+ * --------+------------------+----------------
+ * 0       | +/- 2g           | 16384 LSB/mg
+ * 1       | +/- 4g           | 8192 LSB/mg
+ * 2       | +/- 8g           | 4096 LSB/mg
+ * 3       | +/- 16g          | 2048 LSB/mg
+ * 
+ * + * @param x 16-bit signed integer container for X-axis acceleration + * @param y 16-bit signed integer container for Y-axis acceleration + * @param z 16-bit signed integer container for Z-axis acceleration + * @see MPU6050_RA_GYRO_XOUT_H + */ +void MPU6050_Base::getAcceleration(int16_t* x, int16_t* y, int16_t* z) { + I2Cdev::readBytes(devAddr, MPU6050_RA_ACCEL_XOUT_H, 6, buffer, I2Cdev::readTimeout, wireObj); + *x = (((int16_t)buffer[0]) << 8) | buffer[1]; + *y = (((int16_t)buffer[2]) << 8) | buffer[3]; + *z = (((int16_t)buffer[4]) << 8) | buffer[5]; +} +/** Get X-axis accelerometer reading. + * @return X-axis acceleration measurement in 16-bit 2's complement format + * @see getMotion6() + * @see MPU6050_RA_ACCEL_XOUT_H + */ +int16_t MPU6050_Base::getAccelerationX() { + I2Cdev::readBytes(devAddr, MPU6050_RA_ACCEL_XOUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +/** Get Y-axis accelerometer reading. + * @return Y-axis acceleration measurement in 16-bit 2's complement format + * @see getMotion6() + * @see MPU6050_RA_ACCEL_YOUT_H + */ +int16_t MPU6050_Base::getAccelerationY() { + I2Cdev::readBytes(devAddr, MPU6050_RA_ACCEL_YOUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +/** Get Z-axis accelerometer reading. + * @return Z-axis acceleration measurement in 16-bit 2's complement format + * @see getMotion6() + * @see MPU6050_RA_ACCEL_ZOUT_H + */ +int16_t MPU6050_Base::getAccelerationZ() { + I2Cdev::readBytes(devAddr, MPU6050_RA_ACCEL_ZOUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} + +// TEMP_OUT_* registers + +/** Get current internal temperature. + * @return Temperature reading in 16-bit 2's complement format + * @see MPU6050_RA_TEMP_OUT_H + */ +int16_t MPU6050_Base::getTemperature() { + I2Cdev::readBytes(devAddr, MPU6050_RA_TEMP_OUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} + +// GYRO_*OUT_* registers + +/** Get 3-axis gyroscope readings. + * These gyroscope measurement registers, along with the accelerometer + * measurement registers, temperature measurement registers, and external sensor + * data registers, are composed of two sets of registers: an internal register + * set and a user-facing read register set. + * The data within the gyroscope sensors' internal register set is always + * updated at the Sample Rate. Meanwhile, the user-facing read register set + * duplicates the internal register set's data values whenever the serial + * interface is idle. This guarantees that a burst read of sensor registers will + * read measurements from the same sampling instant. Note that if burst reads + * are not used, the user is responsible for ensuring a set of single byte reads + * correspond to a single sampling instant by checking the Data Ready interrupt. + * + * Each 16-bit gyroscope measurement has a full scale defined in FS_SEL + * (Register 27). For each full scale setting, the gyroscopes' sensitivity per + * LSB in GYRO_xOUT is shown in the table below: + * + *
+ * FS_SEL | Full Scale Range   | LSB Sensitivity
+ * -------+--------------------+----------------
+ * 0      | +/- 250 degrees/s  | 131 LSB/deg/s
+ * 1      | +/- 500 degrees/s  | 65.5 LSB/deg/s
+ * 2      | +/- 1000 degrees/s | 32.8 LSB/deg/s
+ * 3      | +/- 2000 degrees/s | 16.4 LSB/deg/s
+ * 
+ * + * @param x 16-bit signed integer container for X-axis rotation + * @param y 16-bit signed integer container for Y-axis rotation + * @param z 16-bit signed integer container for Z-axis rotation + * @see getMotion6() + * @see MPU6050_RA_GYRO_XOUT_H + */ +void MPU6050_Base::getRotation(int16_t* x, int16_t* y, int16_t* z) { + I2Cdev::readBytes(devAddr, MPU6050_RA_GYRO_XOUT_H, 6, buffer, I2Cdev::readTimeout, wireObj); + *x = (((int16_t)buffer[0]) << 8) | buffer[1]; + *y = (((int16_t)buffer[2]) << 8) | buffer[3]; + *z = (((int16_t)buffer[4]) << 8) | buffer[5]; +} +/** Get X-axis gyroscope reading. + * @return X-axis rotation measurement in 16-bit 2's complement format + * @see getMotion6() + * @see MPU6050_RA_GYRO_XOUT_H + */ +int16_t MPU6050_Base::getRotationX() { + I2Cdev::readBytes(devAddr, MPU6050_RA_GYRO_XOUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +/** Get Y-axis gyroscope reading. + * @return Y-axis rotation measurement in 16-bit 2's complement format + * @see getMotion6() + * @see MPU6050_RA_GYRO_YOUT_H + */ +int16_t MPU6050_Base::getRotationY() { + I2Cdev::readBytes(devAddr, MPU6050_RA_GYRO_YOUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +/** Get Z-axis gyroscope reading. + * @return Z-axis rotation measurement in 16-bit 2's complement format + * @see getMotion6() + * @see MPU6050_RA_GYRO_ZOUT_H + */ +int16_t MPU6050_Base::getRotationZ() { + I2Cdev::readBytes(devAddr, MPU6050_RA_GYRO_ZOUT_H, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} + +// EXT_SENS_DATA_* registers + +/** Read single byte from external sensor data register. + * These registers store data read from external sensors by the Slave 0, 1, 2, + * and 3 on the auxiliary I2C interface. Data read by Slave 4 is stored in + * I2C_SLV4_DI (Register 53). + * + * External sensor data is written to these registers at the Sample Rate as + * defined in Register 25. This access rate can be reduced by using the Slave + * Delay Enable registers (Register 103). + * + * External sensor data registers, along with the gyroscope measurement + * registers, accelerometer measurement registers, and temperature measurement + * registers, are composed of two sets of registers: an internal register set + * and a user-facing read register set. + * + * The data within the external sensors' internal register set is always updated + * at the Sample Rate (or the reduced access rate) whenever the serial interface + * is idle. This guarantees that a burst read of sensor registers will read + * measurements from the same sampling instant. Note that if burst reads are not + * used, the user is responsible for ensuring a set of single byte reads + * correspond to a single sampling instant by checking the Data Ready interrupt. + * + * Data is placed in these external sensor data registers according to + * I2C_SLV0_CTRL, I2C_SLV1_CTRL, I2C_SLV2_CTRL, and I2C_SLV3_CTRL (Registers 39, + * 42, 45, and 48). When more than zero bytes are read (I2C_SLVx_LEN > 0) from + * an enabled slave (I2C_SLVx_EN = 1), the slave is read at the Sample Rate (as + * defined in Register 25) or delayed rate (if specified in Register 52 and + * 103). During each Sample cycle, slave reads are performed in order of Slave + * number. If all slaves are enabled with more than zero bytes to be read, the + * order will be Slave 0, followed by Slave 1, Slave 2, and Slave 3. + * + * Each enabled slave will have EXT_SENS_DATA registers associated with it by + * number of bytes read (I2C_SLVx_LEN) in order of slave number, starting from + * EXT_SENS_DATA_00. Note that this means enabling or disabling a slave may + * change the higher numbered slaves' associated registers. Furthermore, if + * fewer total bytes are being read from the external sensors as a result of + * such a change, then the data remaining in the registers which no longer have + * an associated slave device (i.e. high numbered registers) will remain in + * these previously allocated registers unless reset. + * + * If the sum of the read lengths of all SLVx transactions exceed the number of + * available EXT_SENS_DATA registers, the excess bytes will be dropped. There + * are 24 EXT_SENS_DATA registers and hence the total read lengths between all + * the slaves cannot be greater than 24 or some bytes will be lost. + * + * Note: Slave 4's behavior is distinct from that of Slaves 0-3. For further + * information regarding the characteristics of Slave 4, please refer to + * Registers 49 to 53. + * + * EXAMPLE: + * Suppose that Slave 0 is enabled with 4 bytes to be read (I2C_SLV0_EN = 1 and + * I2C_SLV0_LEN = 4) while Slave 1 is enabled with 2 bytes to be read so that + * I2C_SLV1_EN = 1 and I2C_SLV1_LEN = 2. In such a situation, EXT_SENS_DATA _00 + * through _03 will be associated with Slave 0, while EXT_SENS_DATA _04 and 05 + * will be associated with Slave 1. If Slave 2 is enabled as well, registers + * starting from EXT_SENS_DATA_06 will be allocated to Slave 2. + * + * If Slave 2 is disabled while Slave 3 is enabled in this same situation, then + * registers starting from EXT_SENS_DATA_06 will be allocated to Slave 3 + * instead. + * + * REGISTER ALLOCATION FOR DYNAMIC DISABLE VS. NORMAL DISABLE: + * If a slave is disabled at any time, the space initially allocated to the + * slave in the EXT_SENS_DATA register, will remain associated with that slave. + * This is to avoid dynamic adjustment of the register allocation. + * + * The allocation of the EXT_SENS_DATA registers is recomputed only when (1) all + * slaves are disabled, or (2) the I2C_MST_RST bit is set (Register 106). + * + * This above is also true if one of the slaves gets NACKed and stops + * functioning. + * + * @param position Starting position (0-23) + * @return Byte read from register + */ +uint8_t MPU6050_Base::getExternalSensorByte(int position) { + I2Cdev::readByte(devAddr, MPU6050_RA_EXT_SENS_DATA_00 + position, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Read word (2 bytes) from external sensor data registers. + * @param position Starting position (0-21) + * @return Word read from register + * @see getExternalSensorByte() + */ +uint16_t MPU6050_Base::getExternalSensorWord(int position) { + I2Cdev::readBytes(devAddr, MPU6050_RA_EXT_SENS_DATA_00 + position, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((uint16_t)buffer[0]) << 8) | buffer[1]; +} +/** Read double word (4 bytes) from external sensor data registers. + * @param position Starting position (0-20) + * @return Double word read from registers + * @see getExternalSensorByte() + */ +uint32_t MPU6050_Base::getExternalSensorDWord(int position) { + I2Cdev::readBytes(devAddr, MPU6050_RA_EXT_SENS_DATA_00 + position, 4, buffer, I2Cdev::readTimeout, wireObj); + return (((uint32_t)buffer[0]) << 24) | (((uint32_t)buffer[1]) << 16) | (((uint16_t)buffer[2]) << 8) | buffer[3]; +} + +// MOT_DETECT_STATUS register + +/** Get full motion detection status register content (all bits). + * @return Motion detection status byte + * @see MPU6050_RA_MOT_DETECT_STATUS + */ +uint8_t MPU6050_Base::getMotionStatus() { + I2Cdev::readByte(devAddr, MPU6050_RA_MOT_DETECT_STATUS, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get X-axis negative motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_XNEG_BIT + */ +bool MPU6050_Base::getXNegMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_XNEG_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get X-axis positive motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_XPOS_BIT + */ +bool MPU6050_Base::getXPosMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_XPOS_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Y-axis negative motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_YNEG_BIT + */ +bool MPU6050_Base::getYNegMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_YNEG_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Y-axis positive motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_YPOS_BIT + */ +bool MPU6050_Base::getYPosMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_YPOS_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Z-axis negative motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_ZNEG_BIT + */ +bool MPU6050_Base::getZNegMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_ZNEG_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get Z-axis positive motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_ZPOS_BIT + */ +bool MPU6050_Base::getZPosMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_ZPOS_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Get zero motion detection interrupt status. + * @return Motion detection status + * @see MPU6050_RA_MOT_DETECT_STATUS + * @see MPU6050_MOTION_MOT_ZRMOT_BIT + */ +bool MPU6050_Base::getZeroMotionDetected() { + I2Cdev::readBit(devAddr, MPU6050_RA_MOT_DETECT_STATUS, MPU6050_MOTION_MOT_ZRMOT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} + +// I2C_SLV*_DO register + +/** Write byte to Data Output container for specified slave. + * This register holds the output data written into Slave when Slave is set to + * write mode. For further information regarding Slave control, please + * refer to Registers 37 to 39 and immediately following. + * @param num Slave number (0-3) + * @param data Byte to write + * @see MPU6050_RA_I2C_SLV0_DO + */ +void MPU6050_Base::setSlaveOutputByte(uint8_t num, uint8_t data) { + if (num > 3) return; + I2Cdev::writeByte(devAddr, MPU6050_RA_I2C_SLV0_DO + num, data, wireObj); +} + +// I2C_MST_DELAY_CTRL register + +/** Get external data shadow delay enabled status. + * This register is used to specify the timing of external sensor data + * shadowing. When DELAY_ES_SHADOW is set to 1, shadowing of external + * sensor data is delayed until all data has been received. + * @return Current external data shadow delay enabled status. + * @see MPU6050_RA_I2C_MST_DELAY_CTRL + * @see MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT + */ +bool MPU6050_Base::getExternalShadowDelayEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_DELAY_CTRL, MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set external data shadow delay enabled status. + * @param enabled New external data shadow delay enabled status. + * @see getExternalShadowDelayEnabled() + * @see MPU6050_RA_I2C_MST_DELAY_CTRL + * @see MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT + */ +void MPU6050_Base::setExternalShadowDelayEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_MST_DELAY_CTRL, MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT, enabled, wireObj); +} +/** Get slave delay enabled status. + * When a particular slave delay is enabled, the rate of access for the that + * slave device is reduced. When a slave's access rate is decreased relative to + * the Sample Rate, the slave is accessed every: + * + * 1 / (1 + I2C_MST_DLY) Samples + * + * This base Sample Rate in turn is determined by SMPLRT_DIV (register * 25) + * and DLPF_CFG (register 26). + * + * For further information regarding I2C_MST_DLY, please refer to register 52. + * For further information regarding the Sample Rate, please refer to register 25. + * + * @param num Slave number (0-4) + * @return Current slave delay enabled status. + * @see MPU6050_RA_I2C_MST_DELAY_CTRL + * @see MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT + */ +bool MPU6050_Base::getSlaveDelayEnabled(uint8_t num) { + // MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT is 4, SLV3 is 3, etc. + if (num > 4) return 0; + I2Cdev::readBit(devAddr, MPU6050_RA_I2C_MST_DELAY_CTRL, num, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set slave delay enabled status. + * @param num Slave number (0-4) + * @param enabled New slave delay enabled status. + * @see MPU6050_RA_I2C_MST_DELAY_CTRL + * @see MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT + */ +void MPU6050_Base::setSlaveDelayEnabled(uint8_t num, bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_I2C_MST_DELAY_CTRL, num, enabled, wireObj); +} + +// SIGNAL_PATH_RESET register + +/** Reset gyroscope signal path. + * The reset will revert the signal path analog to digital converters and + * filters to their power up configurations. + * @see MPU6050_RA_SIGNAL_PATH_RESET + * @see MPU6050_PATHRESET_GYRO_RESET_BIT + */ +void MPU6050_Base::resetGyroscopePath() { + I2Cdev::writeBit(devAddr, MPU6050_RA_SIGNAL_PATH_RESET, MPU6050_PATHRESET_GYRO_RESET_BIT, true, wireObj); +} +/** Reset accelerometer signal path. + * The reset will revert the signal path analog to digital converters and + * filters to their power up configurations. + * @see MPU6050_RA_SIGNAL_PATH_RESET + * @see MPU6050_PATHRESET_ACCEL_RESET_BIT + */ +void MPU6050_Base::resetAccelerometerPath() { + I2Cdev::writeBit(devAddr, MPU6050_RA_SIGNAL_PATH_RESET, MPU6050_PATHRESET_ACCEL_RESET_BIT, true, wireObj); +} +/** Reset temperature sensor signal path. + * The reset will revert the signal path analog to digital converters and + * filters to their power up configurations. + * @see MPU6050_RA_SIGNAL_PATH_RESET + * @see MPU6050_PATHRESET_TEMP_RESET_BIT + */ +void MPU6050_Base::resetTemperaturePath() { + I2Cdev::writeBit(devAddr, MPU6050_RA_SIGNAL_PATH_RESET, MPU6050_PATHRESET_TEMP_RESET_BIT, true, wireObj); +} + +// MOT_DETECT_CTRL register + +/** Get accelerometer power-on delay. + * The accelerometer data path provides samples to the sensor registers, Motion + * detection, Zero Motion detection, and Free Fall detection modules. The + * signal path contains filters which must be flushed on wake-up with new + * samples before the detection modules begin operations. The default wake-up + * delay, of 4ms can be lengthened by up to 3ms. This additional delay is + * specified in ACCEL_ON_DELAY in units of 1 LSB = 1 ms. The user may select + * any value above zero unless instructed otherwise by InvenSense. Please refer + * to Section 8 of the MPU-6000/MPU-6050 Product Specification document for + * further information regarding the detection modules. + * @return Current accelerometer power-on delay + * @see MPU6050_RA_MOT_DETECT_CTRL + * @see MPU6050_DETECT_ACCEL_ON_DELAY_BIT + */ +uint8_t MPU6050_Base::getAccelerometerPowerOnDelay() { + I2Cdev::readBits(devAddr, MPU6050_RA_MOT_DETECT_CTRL, MPU6050_DETECT_ACCEL_ON_DELAY_BIT, MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set accelerometer power-on delay. + * @param delay New accelerometer power-on delay (0-3) + * @see getAccelerometerPowerOnDelay() + * @see MPU6050_RA_MOT_DETECT_CTRL + * @see MPU6050_DETECT_ACCEL_ON_DELAY_BIT + */ +void MPU6050_Base::setAccelerometerPowerOnDelay(uint8_t delay) { + I2Cdev::writeBits(devAddr, MPU6050_RA_MOT_DETECT_CTRL, MPU6050_DETECT_ACCEL_ON_DELAY_BIT, MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH, delay, wireObj); +} +/** Get Free Fall detection counter decrement configuration. + * Detection is registered by the Free Fall detection module after accelerometer + * measurements meet their respective threshold conditions over a specified + * number of samples. When the threshold conditions are met, the corresponding + * detection counter increments by 1. The user may control the rate at which the + * detection counter decrements when the threshold condition is not met by + * configuring FF_COUNT. The decrement rate can be set according to the + * following table: + * + *
+ * FF_COUNT | Counter Decrement
+ * ---------+------------------
+ * 0        | Reset
+ * 1        | 1
+ * 2        | 2
+ * 3        | 4
+ * 
+ * + * When FF_COUNT is configured to 0 (reset), any non-qualifying sample will + * reset the counter to 0. For further information on Free Fall detection, + * please refer to Registers 29 to 32. + * + * @return Current decrement configuration + * @see MPU6050_RA_MOT_DETECT_CTRL + * @see MPU6050_DETECT_FF_COUNT_BIT + */ +uint8_t MPU6050_Base::getFreefallDetectionCounterDecrement() { + I2Cdev::readBits(devAddr, MPU6050_RA_MOT_DETECT_CTRL, MPU6050_DETECT_FF_COUNT_BIT, MPU6050_DETECT_FF_COUNT_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Free Fall detection counter decrement configuration. + * @param decrement New decrement configuration value + * @see getFreefallDetectionCounterDecrement() + * @see MPU6050_RA_MOT_DETECT_CTRL + * @see MPU6050_DETECT_FF_COUNT_BIT + */ +void MPU6050_Base::setFreefallDetectionCounterDecrement(uint8_t decrement) { + I2Cdev::writeBits(devAddr, MPU6050_RA_MOT_DETECT_CTRL, MPU6050_DETECT_FF_COUNT_BIT, MPU6050_DETECT_FF_COUNT_LENGTH, decrement, wireObj); +} +/** Get Motion detection counter decrement configuration. + * Detection is registered by the Motion detection module after accelerometer + * measurements meet their respective threshold conditions over a specified + * number of samples. When the threshold conditions are met, the corresponding + * detection counter increments by 1. The user may control the rate at which the + * detection counter decrements when the threshold condition is not met by + * configuring MOT_COUNT. The decrement rate can be set according to the + * following table: + * + *
+ * MOT_COUNT | Counter Decrement
+ * ----------+------------------
+ * 0         | Reset
+ * 1         | 1
+ * 2         | 2
+ * 3         | 4
+ * 
+ * + * When MOT_COUNT is configured to 0 (reset), any non-qualifying sample will + * reset the counter to 0. For further information on Motion detection, + * please refer to Registers 29 to 32. + * + */ +uint8_t MPU6050_Base::getMotionDetectionCounterDecrement() { + I2Cdev::readBits(devAddr, MPU6050_RA_MOT_DETECT_CTRL, MPU6050_DETECT_MOT_COUNT_BIT, MPU6050_DETECT_MOT_COUNT_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Motion detection counter decrement configuration. + * @param decrement New decrement configuration value + * @see getMotionDetectionCounterDecrement() + * @see MPU6050_RA_MOT_DETECT_CTRL + * @see MPU6050_DETECT_MOT_COUNT_BIT + */ +void MPU6050_Base::setMotionDetectionCounterDecrement(uint8_t decrement) { + I2Cdev::writeBits(devAddr, MPU6050_RA_MOT_DETECT_CTRL, MPU6050_DETECT_MOT_COUNT_BIT, MPU6050_DETECT_MOT_COUNT_LENGTH, decrement, wireObj); +} + +// USER_CTRL register + +/** Get FIFO enabled status. + * When this bit is set to 0, the FIFO buffer is disabled. The FIFO buffer + * cannot be written to or read from while disabled. The FIFO buffer's state + * does not change unless the MPU-60X0 is power cycled. + * @return Current FIFO enabled status + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_FIFO_EN_BIT + */ +bool MPU6050_Base::getFIFOEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_FIFO_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set FIFO enabled status. + * @param enabled New FIFO enabled status + * @see getFIFOEnabled() + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_FIFO_EN_BIT + */ +void MPU6050_Base::setFIFOEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_FIFO_EN_BIT, enabled, wireObj); +} +/** Get I2C Master Mode enabled status. + * When this mode is enabled, the MPU-60X0 acts as the I2C Master to the + * external sensor slave devices on the auxiliary I2C bus. When this bit is + * cleared to 0, the auxiliary I2C bus lines (AUX_DA and AUX_CL) are logically + * driven by the primary I2C bus (SDA and SCL). This is a precondition to + * enabling Bypass Mode. For further information regarding Bypass Mode, please + * refer to Register 55. + * @return Current I2C Master Mode enabled status + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_I2C_MST_EN_BIT + */ +bool MPU6050_Base::getI2CMasterModeEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set I2C Master Mode enabled status. + * @param enabled New I2C Master Mode enabled status + * @see getI2CMasterModeEnabled() + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_I2C_MST_EN_BIT + */ +void MPU6050_Base::setI2CMasterModeEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled, wireObj); +} +/** Switch from I2C to SPI mode (MPU-6000 only) + * If this is set, the primary SPI interface will be enabled in place of the + * disabled primary I2C interface. + */ +void MPU6050_Base::switchSPIEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_IF_DIS_BIT, enabled, wireObj); +} +/** Reset the FIFO. + * This bit resets the FIFO buffer when set to 1 while FIFO_EN equals 0. This + * bit automatically clears to 0 after the reset has been triggered. + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_FIFO_RESET_BIT + */ +void MPU6050_Base::resetFIFO() { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_FIFO_RESET_BIT, true, wireObj); +} +/** Reset the I2C Master. + * This bit resets the I2C Master when set to 1 while I2C_MST_EN equals 0. + * This bit automatically clears to 0 after the reset has been triggered. + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_I2C_MST_RESET_BIT + */ +void MPU6050_Base::resetI2CMaster() { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_RESET_BIT, true, wireObj); +} +/** Reset all sensor registers and signal paths. + * When set to 1, this bit resets the signal paths for all sensors (gyroscopes, + * accelerometers, and temperature sensor). This operation will also clear the + * sensor registers. This bit automatically clears to 0 after the reset has been + * triggered. + * + * When resetting only the signal path (and not the sensor registers), please + * use Register 104, SIGNAL_PATH_RESET. + * + * @see MPU6050_RA_USER_CTRL + * @see MPU6050_USERCTRL_SIG_COND_RESET_BIT + */ +void MPU6050_Base::resetSensors() { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_SIG_COND_RESET_BIT, true, wireObj); +} + +// PWR_MGMT_1 register + +/** Trigger a full device reset. + * A small delay of ~50ms may be desirable after triggering a reset. + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_DEVICE_RESET_BIT + */ +void MPU6050_Base::reset() { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_DEVICE_RESET_BIT, true, wireObj); +} +/** Get sleep mode status. + * Setting the SLEEP bit in the register puts the device into very low power + * sleep mode. In this mode, only the serial interface and internal registers + * remain active, allowing for a very low standby current. Clearing this bit + * puts the device back into normal mode. To save power, the individual standby + * selections for each of the gyros should be used if any gyro axis is not used + * by the application. + * @return Current sleep mode enabled status + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_SLEEP_BIT + */ +bool MPU6050_Base::getSleepEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set sleep mode status. + * @param enabled New sleep mode enabled status + * @see getSleepEnabled() + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_SLEEP_BIT + */ +void MPU6050_Base::setSleepEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled, wireObj); +} +/** Get wake cycle enabled status. + * When this bit is set to 1 and SLEEP is disabled, the MPU-60X0 will cycle + * between sleep mode and waking up to take a single sample of data from active + * sensors at a rate determined by LP_WAKE_CTRL (register 108). + * @return Current sleep mode enabled status + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_CYCLE_BIT + */ +bool MPU6050_Base::getWakeCycleEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CYCLE_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set wake cycle enabled status. + * @param enabled New sleep mode enabled status + * @see getWakeCycleEnabled() + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_CYCLE_BIT + */ +void MPU6050_Base::setWakeCycleEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CYCLE_BIT, enabled, wireObj); +} +/** Get temperature sensor enabled status. + * Control the usage of the internal temperature sensor. + * + * Note: this register stores the *disabled* value, but for consistency with the + * rest of the code, the function is named and used with standard true/false + * values to indicate whether the sensor is enabled or disabled, respectively. + * + * @return Current temperature sensor enabled status + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_TEMP_DIS_BIT + */ +bool MPU6050_Base::getTempSensorEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_TEMP_DIS_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0] == 0; // 1 is actually disabled here +} +/** Set temperature sensor enabled status. + * Note: this register stores the *disabled* value, but for consistency with the + * rest of the code, the function is named and used with standard true/false + * values to indicate whether the sensor is enabled or disabled, respectively. + * + * @param enabled New temperature sensor enabled status + * @see getTempSensorEnabled() + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_TEMP_DIS_BIT + */ +void MPU6050_Base::setTempSensorEnabled(bool enabled) { + // 1 is actually disabled here + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_TEMP_DIS_BIT, !enabled, wireObj); +} +/** Get clock source setting. + * @return Current clock source setting + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_CLKSEL_BIT + * @see MPU6050_PWR1_CLKSEL_LENGTH + */ +uint8_t MPU6050_Base::getClockSource() { + I2Cdev::readBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set clock source setting. + * An internal 8MHz oscillator, gyroscope based clock, or external sources can + * be selected as the MPU-60X0 clock source. When the internal 8 MHz oscillator + * or an external source is chosen as the clock source, the MPU-60X0 can operate + * in low power modes with the gyroscopes disabled. + * + * Upon power up, the MPU-60X0 clock source defaults to the internal oscillator. + * However, it is highly recommended that the device be configured to use one of + * the gyroscopes (or an external clock source) as the clock reference for + * improved stability. The clock source can be selected according to the following table: + * + *
+ * CLK_SEL | Clock Source
+ * --------+--------------------------------------
+ * 0       | Internal oscillator
+ * 1       | PLL with X Gyro reference
+ * 2       | PLL with Y Gyro reference
+ * 3       | PLL with Z Gyro reference
+ * 4       | PLL with external 32.768kHz reference
+ * 5       | PLL with external 19.2MHz reference
+ * 6       | Reserved
+ * 7       | Stops the clock and keeps the timing generator in reset
+ * 
+ * + * @param source New clock source setting + * @see getClockSource() + * @see MPU6050_RA_PWR_MGMT_1 + * @see MPU6050_PWR1_CLKSEL_BIT + * @see MPU6050_PWR1_CLKSEL_LENGTH + */ +void MPU6050_Base::setClockSource(uint8_t source) { + I2Cdev::writeBits(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source, wireObj); +} + +// PWR_MGMT_2 register + +/** Get wake frequency in Accel-Only Low Power Mode. + * The MPU-60X0 can be put into Accerlerometer Only Low Power Mode by setting + * PWRSEL to 1 in the Power Management 1 register (Register 107). In this mode, + * the device will power off all devices except for the primary I2C interface, + * waking only the accelerometer at fixed intervals to take a single + * measurement. The frequency of wake-ups can be configured with LP_WAKE_CTRL + * as shown below: + * + *
+ * LP_WAKE_CTRL | Wake-up Frequency
+ * -------------+------------------
+ * 0            | 1.25 Hz
+ * 1            | 2.5 Hz
+ * 2            | 20 Hz
+ * 3            | 40 Hz
+ * 
+ * + * For further information regarding the MPU-60X0's power modes, please refer to + * Register 107. + * + * @return Current wake frequency + * @see MPU6050_RA_PWR_MGMT_2 + */ +uint8_t MPU6050_Base::getWakeFrequency() { + I2Cdev::readBits(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_LP_WAKE_CTRL_BIT, MPU6050_PWR2_LP_WAKE_CTRL_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set wake frequency in Accel-Only Low Power Mode. + * @param frequency New wake frequency + * @see MPU6050_RA_PWR_MGMT_2 + */ +void MPU6050_Base::setWakeFrequency(uint8_t frequency) { + I2Cdev::writeBits(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_LP_WAKE_CTRL_BIT, MPU6050_PWR2_LP_WAKE_CTRL_LENGTH, frequency, wireObj); +} + +/** Get X-axis accelerometer standby enabled status. + * If enabled, the X-axis will not gather or report data (or use power). + * @return Current X-axis standby enabled status + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_XA_BIT + */ +bool MPU6050_Base::getStandbyXAccelEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_XA_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set X-axis accelerometer standby enabled status. + * @param New X-axis standby enabled status + * @see getStandbyXAccelEnabled() + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_XA_BIT + */ +void MPU6050_Base::setStandbyXAccelEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_XA_BIT, enabled, wireObj); +} +/** Get Y-axis accelerometer standby enabled status. + * If enabled, the Y-axis will not gather or report data (or use power). + * @return Current Y-axis standby enabled status + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_YA_BIT + */ +bool MPU6050_Base::getStandbyYAccelEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_YA_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Y-axis accelerometer standby enabled status. + * @param New Y-axis standby enabled status + * @see getStandbyYAccelEnabled() + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_YA_BIT + */ +void MPU6050_Base::setStandbyYAccelEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_YA_BIT, enabled, wireObj); +} +/** Get Z-axis accelerometer standby enabled status. + * If enabled, the Z-axis will not gather or report data (or use power). + * @return Current Z-axis standby enabled status + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_ZA_BIT + */ +bool MPU6050_Base::getStandbyZAccelEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_ZA_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Z-axis accelerometer standby enabled status. + * @param New Z-axis standby enabled status + * @see getStandbyZAccelEnabled() + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_ZA_BIT + */ +void MPU6050_Base::setStandbyZAccelEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_ZA_BIT, enabled, wireObj); +} +/** Get X-axis gyroscope standby enabled status. + * If enabled, the X-axis will not gather or report data (or use power). + * @return Current X-axis standby enabled status + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_XG_BIT + */ +bool MPU6050_Base::getStandbyXGyroEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_XG_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set X-axis gyroscope standby enabled status. + * @param New X-axis standby enabled status + * @see getStandbyXGyroEnabled() + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_XG_BIT + */ +void MPU6050_Base::setStandbyXGyroEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_XG_BIT, enabled, wireObj); +} +/** Get Y-axis gyroscope standby enabled status. + * If enabled, the Y-axis will not gather or report data (or use power). + * @return Current Y-axis standby enabled status + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_YG_BIT + */ +bool MPU6050_Base::getStandbyYGyroEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_YG_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Y-axis gyroscope standby enabled status. + * @param New Y-axis standby enabled status + * @see getStandbyYGyroEnabled() + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_YG_BIT + */ +void MPU6050_Base::setStandbyYGyroEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_YG_BIT, enabled, wireObj); +} +/** Get Z-axis gyroscope standby enabled status. + * If enabled, the Z-axis will not gather or report data (or use power). + * @return Current Z-axis standby enabled status + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_ZG_BIT + */ +bool MPU6050_Base::getStandbyZGyroEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_ZG_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Z-axis gyroscope standby enabled status. + * @param New Z-axis standby enabled status + * @see getStandbyZGyroEnabled() + * @see MPU6050_RA_PWR_MGMT_2 + * @see MPU6050_PWR2_STBY_ZG_BIT + */ +void MPU6050_Base::setStandbyZGyroEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_PWR_MGMT_2, MPU6050_PWR2_STBY_ZG_BIT, enabled, wireObj); +} + +// FIFO_COUNT* registers + +/** Get current FIFO buffer size. + * This value indicates the number of bytes stored in the FIFO buffer. This + * number is in turn the number of bytes that can be read from the FIFO buffer + * and it is directly proportional to the number of samples available given the + * set of sensor data bound to be stored in the FIFO (register 35 and 36). + * @return Current FIFO buffer size + */ +uint16_t MPU6050_Base::getFIFOCount() { + I2Cdev::readBytes(devAddr, MPU6050_RA_FIFO_COUNTH, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((uint16_t)buffer[0]) << 8) | buffer[1]; +} + +// FIFO_R_W register + +/** Get byte from FIFO buffer. + * This register is used to read and write data from the FIFO buffer. Data is + * written to the FIFO in order of register number (from lowest to highest). If + * all the FIFO enable flags (see below) are enabled and all External Sensor + * Data registers (Registers 73 to 96) are associated with a Slave device, the + * contents of registers 59 through 96 will be written in order at the Sample + * Rate. + * + * The contents of the sensor data registers (Registers 59 to 96) are written + * into the FIFO buffer when their corresponding FIFO enable flags are set to 1 + * in FIFO_EN (Register 35). An additional flag for the sensor data registers + * associated with I2C Slave 3 can be found in I2C_MST_CTRL (Register 36). + * + * If the FIFO buffer has overflowed, the status bit FIFO_OFLOW_INT is + * automatically set to 1. This bit is located in INT_STATUS (Register 58). + * When the FIFO buffer has overflowed, the oldest data will be lost and new + * data will be written to the FIFO. + * + * If the FIFO buffer is empty, reading this register will return the last byte + * that was previously read from the FIFO until new data is available. The user + * should check FIFO_COUNT to ensure that the FIFO buffer is not read when + * empty. + * + * @return Byte from FIFO buffer + */ +uint8_t MPU6050_Base::getFIFOByte() { + I2Cdev::readByte(devAddr, MPU6050_RA_FIFO_R_W, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::getFIFOBytes(uint8_t *data, uint8_t length) { + if(length > 0){ + I2Cdev::readBytes(devAddr, MPU6050_RA_FIFO_R_W, length, data, I2Cdev::readTimeout, wireObj); + } else { + *data = 0; + } +} + +/** Get timeout to get a packet from FIFO buffer. + * @return Current timeout to get a packet from FIFO buffer + * @see MPU6050_FIFO_DEFAULT_TIMEOUT + */ +uint32_t MPU6050_Base::getFIFOTimeout() { + return fifoTimeout; +} + +/** Set timeout to get a packet from FIFO buffer. + * @param New timeout to get a packet from FIFO buffer + * @see MPU6050_FIFO_DEFAULT_TIMEOUT + */ +void MPU6050_Base::setFIFOTimeout(uint32_t fifoTimeout) { + this->fifoTimeout = fifoTimeout; +} + +/** Get latest byte from FIFO buffer no matter how much time has passed. + * === GetCurrentFIFOPacket === + * ================================================================ + * Returns 1) when nothing special was done + * 2) when recovering from overflow + * 0) when no valid data is available + * ================================================================ */ + int8_t MPU6050_Base::GetCurrentFIFOPacket(uint8_t *data, uint8_t length) { // overflow proof + int16_t fifoC; + // This section of code is for when we allowed more than 1 packet to be acquired + uint32_t BreakTimer = micros(); + bool packetReceived = false; + do { + if ((fifoC = getFIFOCount()) > length) { + + if (fifoC > 200) { // if you waited to get the FIFO buffer to > 200 bytes it will take longer to get the last packet in the FIFO Buffer than it will take to reset the buffer and wait for the next to arrive + resetFIFO(); // Fixes any overflow corruption + fifoC = 0; + while (!(fifoC = getFIFOCount()) && ((micros() - BreakTimer) <= (getFIFOTimeout()))); // Get Next New Packet + } else { //We have more than 1 packet but less than 200 bytes of data in the FIFO Buffer + uint8_t Trash[I2CDEVLIB_WIRE_BUFFER_LENGTH]; + while ((fifoC = getFIFOCount()) > length) { // Test each time just in case the MPU is writing to the FIFO Buffer + fifoC = fifoC - length; // Save the last packet + uint16_t RemoveBytes; + while (fifoC) { // fifo count will reach zero so this is safe + RemoveBytes = (fifoC < I2CDEVLIB_WIRE_BUFFER_LENGTH) ? fifoC : I2CDEVLIB_WIRE_BUFFER_LENGTH; // Buffer Length is different than the packet length this will efficiently clear the buffer + getFIFOBytes(Trash, (uint8_t)RemoveBytes); + fifoC -= RemoveBytes; + } + } + } + } + if (!fifoC) return 0; // Called too early no data or we timed out after FIFO Reset + // We have 1 packet + packetReceived = fifoC == length; + if (!packetReceived && (micros() - BreakTimer) > (getFIFOTimeout())) return 0; + } while (!packetReceived); + getFIFOBytes(data, length); //Get 1 packet + return 1; +} + + +/** Write byte to FIFO buffer. + * @see getFIFOByte() + * @see MPU6050_RA_FIFO_R_W + */ +void MPU6050_Base::setFIFOByte(uint8_t data) { + I2Cdev::writeByte(devAddr, MPU6050_RA_FIFO_R_W, data, wireObj); +} + +// WHO_AM_I register + +/** Get Device ID. + * This register is used to verify the identity of the device (0b110100, 0x34). + * @return Device ID (6 bits only! should be 0x34) + * @see MPU6050_RA_WHO_AM_I + * @see MPU6050_WHO_AM_I_BIT + * @see MPU6050_WHO_AM_I_LENGTH + */ +uint8_t MPU6050_Base::getDeviceID() { + I2Cdev::readBits(devAddr, MPU6050_RA_WHO_AM_I, MPU6050_WHO_AM_I_BIT, MPU6050_WHO_AM_I_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +/** Set Device ID. + * Write a new ID into the WHO_AM_I register (no idea why this should ever be + * necessary though). + * @param id New device ID to set. + * @see getDeviceID() + * @see MPU6050_RA_WHO_AM_I + * @see MPU6050_WHO_AM_I_BIT + * @see MPU6050_WHO_AM_I_LENGTH + */ +void MPU6050_Base::setDeviceID(uint8_t id) { + I2Cdev::writeBits(devAddr, MPU6050_RA_WHO_AM_I, MPU6050_WHO_AM_I_BIT, MPU6050_WHO_AM_I_LENGTH, id, wireObj); +} + +// ======== UNDOCUMENTED/DMP REGISTERS/METHODS ======== + +// XG_OFFS_TC register + +uint8_t MPU6050_Base::getOTPBankValid() { + I2Cdev::readBit(devAddr, MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OTP_BNK_VLD_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setOTPBankValid(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OTP_BNK_VLD_BIT, enabled, wireObj); +} +int8_t MPU6050_Base::getXGyroOffsetTC() { + I2Cdev::readBits(devAddr, MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setXGyroOffsetTC(int8_t offset) { + I2Cdev::writeBits(devAddr, MPU6050_RA_XG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, offset, wireObj); +} + +// YG_OFFS_TC register + +int8_t MPU6050_Base::getYGyroOffsetTC() { + I2Cdev::readBits(devAddr, MPU6050_RA_YG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setYGyroOffsetTC(int8_t offset) { + I2Cdev::writeBits(devAddr, MPU6050_RA_YG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, offset, wireObj); +} + +// ZG_OFFS_TC register + +int8_t MPU6050_Base::getZGyroOffsetTC() { + I2Cdev::readBits(devAddr, MPU6050_RA_ZG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setZGyroOffsetTC(int8_t offset) { + I2Cdev::writeBits(devAddr, MPU6050_RA_ZG_OFFS_TC, MPU6050_TC_OFFSET_BIT, MPU6050_TC_OFFSET_LENGTH, offset, wireObj); +} + +// X_FINE_GAIN register + +int8_t MPU6050_Base::getXFineGain() { + I2Cdev::readByte(devAddr, MPU6050_RA_X_FINE_GAIN, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setXFineGain(int8_t gain) { + I2Cdev::writeByte(devAddr, MPU6050_RA_X_FINE_GAIN, gain, wireObj); +} + +// Y_FINE_GAIN register + +int8_t MPU6050_Base::getYFineGain() { + I2Cdev::readByte(devAddr, MPU6050_RA_Y_FINE_GAIN, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setYFineGain(int8_t gain) { + I2Cdev::writeByte(devAddr, MPU6050_RA_Y_FINE_GAIN, gain, wireObj); +} + +// Z_FINE_GAIN register + +int8_t MPU6050_Base::getZFineGain() { + I2Cdev::readByte(devAddr, MPU6050_RA_Z_FINE_GAIN, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setZFineGain(int8_t gain) { + I2Cdev::writeByte(devAddr, MPU6050_RA_Z_FINE_GAIN, gain, wireObj); +} + +// XA_OFFS_* registers + +int16_t MPU6050_Base::getXAccelOffset() { + uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77); // MPU6050,MPU9150 Vs MPU6500,MPU9250 + I2Cdev::readBytes(devAddr, SaveAddress, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +void MPU6050_Base::setXAccelOffset(int16_t offset) { + uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77); // MPU6050,MPU9150 Vs MPU6500,MPU9250 + I2Cdev::writeWord(devAddr, SaveAddress, offset, wireObj); +} + +// YA_OFFS_* register + +int16_t MPU6050_Base::getYAccelOffset() { + uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_YA_OFFS_H:0x7A); // MPU6050,MPU9150 Vs MPU6500,MPU9250 + I2Cdev::readBytes(devAddr, SaveAddress, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +void MPU6050_Base::setYAccelOffset(int16_t offset) { + uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_YA_OFFS_H:0x7A); // MPU6050,MPU9150 Vs MPU6500,MPU9250 + I2Cdev::writeWord(devAddr, SaveAddress, offset, wireObj); +} + +// ZA_OFFS_* register + +int16_t MPU6050_Base::getZAccelOffset() { + uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_ZA_OFFS_H:0x7D); // MPU6050,MPU9150 Vs MPU6500,MPU9250 + I2Cdev::readBytes(devAddr, SaveAddress, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +void MPU6050_Base::setZAccelOffset(int16_t offset) { + uint8_t SaveAddress = ((getDeviceID() < 0x38 )? MPU6050_RA_ZA_OFFS_H:0x7D); // MPU6050,MPU9150 Vs MPU6500,MPU9250 + I2Cdev::writeWord(devAddr, SaveAddress, offset, wireObj); +} + +// XG_OFFS_USR* registers + +int16_t MPU6050_Base::getXGyroOffset() { + I2Cdev::readBytes(devAddr, MPU6050_RA_XG_OFFS_USRH, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +void MPU6050_Base::setXGyroOffset(int16_t offset) { + I2Cdev::writeWord(devAddr, MPU6050_RA_XG_OFFS_USRH, offset, wireObj); +} + +// YG_OFFS_USR* register + +int16_t MPU6050_Base::getYGyroOffset() { + I2Cdev::readBytes(devAddr, MPU6050_RA_YG_OFFS_USRH, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +void MPU6050_Base::setYGyroOffset(int16_t offset) { + I2Cdev::writeWord(devAddr, MPU6050_RA_YG_OFFS_USRH, offset, wireObj); +} + +// ZG_OFFS_USR* register + +int16_t MPU6050_Base::getZGyroOffset() { + I2Cdev::readBytes(devAddr, MPU6050_RA_ZG_OFFS_USRH, 2, buffer, I2Cdev::readTimeout, wireObj); + return (((int16_t)buffer[0]) << 8) | buffer[1]; +} +void MPU6050_Base::setZGyroOffset(int16_t offset) { + I2Cdev::writeWord(devAddr, MPU6050_RA_ZG_OFFS_USRH, offset, wireObj); +} + +// INT_ENABLE register (DMP functions) + +bool MPU6050_Base::getIntPLLReadyEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_PLL_RDY_INT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setIntPLLReadyEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_PLL_RDY_INT_BIT, enabled, wireObj); +} +bool MPU6050_Base::getIntDMPEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_DMP_INT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setIntDMPEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_DMP_INT_BIT, enabled, wireObj); +} + +// DMP_INT_STATUS + +bool MPU6050_Base::getDMPInt5Status() { + I2Cdev::readBit(devAddr, MPU6050_RA_DMP_INT_STATUS, MPU6050_DMPINT_5_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +bool MPU6050_Base::getDMPInt4Status() { + I2Cdev::readBit(devAddr, MPU6050_RA_DMP_INT_STATUS, MPU6050_DMPINT_4_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +bool MPU6050_Base::getDMPInt3Status() { + I2Cdev::readBit(devAddr, MPU6050_RA_DMP_INT_STATUS, MPU6050_DMPINT_3_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +bool MPU6050_Base::getDMPInt2Status() { + I2Cdev::readBit(devAddr, MPU6050_RA_DMP_INT_STATUS, MPU6050_DMPINT_2_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +bool MPU6050_Base::getDMPInt1Status() { + I2Cdev::readBit(devAddr, MPU6050_RA_DMP_INT_STATUS, MPU6050_DMPINT_1_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +bool MPU6050_Base::getDMPInt0Status() { + I2Cdev::readBit(devAddr, MPU6050_RA_DMP_INT_STATUS, MPU6050_DMPINT_0_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} + +// INT_STATUS register (DMP functions) + +bool MPU6050_Base::getIntPLLReadyStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_PLL_RDY_INT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +bool MPU6050_Base::getIntDMPStatus() { + I2Cdev::readBit(devAddr, MPU6050_RA_INT_STATUS, MPU6050_INTERRUPT_DMP_INT_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} + +// USER_CTRL register (DMP functions) + +bool MPU6050_Base::getDMPEnabled() { + I2Cdev::readBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_DMP_EN_BIT, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setDMPEnabled(bool enabled) { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_DMP_EN_BIT, enabled, wireObj); +} +void MPU6050_Base::resetDMP() { + I2Cdev::writeBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_DMP_RESET_BIT, true, wireObj); +} + +// BANK_SEL register + +void MPU6050_Base::setMemoryBank(uint8_t bank, bool prefetchEnabled, bool userBank) { + bank &= 0x1F; + if (userBank) bank |= 0x20; + if (prefetchEnabled) bank |= 0x40; + I2Cdev::writeByte(devAddr, MPU6050_RA_BANK_SEL, bank, wireObj); +} + +// MEM_START_ADDR register + +void MPU6050_Base::setMemoryStartAddress(uint8_t address) { + I2Cdev::writeByte(devAddr, MPU6050_RA_MEM_START_ADDR, address, wireObj); +} + +// MEM_R_W register + +uint8_t MPU6050_Base::readMemoryByte() { + I2Cdev::readByte(devAddr, MPU6050_RA_MEM_R_W, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::writeMemoryByte(uint8_t data) { + I2Cdev::writeByte(devAddr, MPU6050_RA_MEM_R_W, data, wireObj); +} +void MPU6050_Base::readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address) { + setMemoryBank(bank); + setMemoryStartAddress(address); + uint8_t chunkSize; + for (uint16_t i = 0; i < dataSize;) { + // determine correct chunk size according to bank position and data size + chunkSize = MPU6050_DMP_MEMORY_CHUNK_SIZE; + + // make sure we don't go past the data size + if (i + chunkSize > dataSize) chunkSize = dataSize - i; + + // make sure this chunk doesn't go past the bank boundary (256 bytes) + if (chunkSize > 256 - address) chunkSize = 256 - address; + + // read the chunk of data as specified + I2Cdev::readBytes(devAddr, MPU6050_RA_MEM_R_W, chunkSize, data + i, I2Cdev::readTimeout, wireObj); + + // increase byte index by [chunkSize] + i += chunkSize; + + // uint8_t automatically wraps to 0 at 256 + address += chunkSize; + + // if we aren't done, update bank (if necessary) and address + if (i < dataSize) { + if (address == 0) bank++; + setMemoryBank(bank); + setMemoryStartAddress(address); + } + } +} +bool MPU6050_Base::writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address, bool verify, bool useProgMem) { + setMemoryBank(bank); + setMemoryStartAddress(address); + uint8_t chunkSize; + uint8_t *verifyBuffer=0; + uint8_t *progBuffer=0; + uint16_t i; + uint8_t j; + if (verify) verifyBuffer = (uint8_t *)malloc(MPU6050_DMP_MEMORY_CHUNK_SIZE); + if (useProgMem) progBuffer = (uint8_t *)malloc(MPU6050_DMP_MEMORY_CHUNK_SIZE); + for (i = 0; i < dataSize;) { + // determine correct chunk size according to bank position and data size + chunkSize = MPU6050_DMP_MEMORY_CHUNK_SIZE; + + // make sure we don't go past the data size + if (i + chunkSize > dataSize) chunkSize = dataSize - i; + + // make sure this chunk doesn't go past the bank boundary (256 bytes) + if (chunkSize > 256 - address) chunkSize = 256 - address; + + if (useProgMem) { + // write the chunk of data as specified + for (j = 0; j < chunkSize; j++) progBuffer[j] = pgm_read_byte(data + i + j); + } else { + // write the chunk of data as specified + progBuffer = (uint8_t *)data + i; + } + + I2Cdev::writeBytes(devAddr, MPU6050_RA_MEM_R_W, chunkSize, progBuffer, wireObj); + + // verify data if needed + if (verify && verifyBuffer) { + setMemoryBank(bank); + setMemoryStartAddress(address); + I2Cdev::readBytes(devAddr, MPU6050_RA_MEM_R_W, chunkSize, verifyBuffer, I2Cdev::readTimeout, wireObj); + if (memcmp(progBuffer, verifyBuffer, chunkSize) != 0) { + /*Serial.print("Block write verification error, bank "); + Serial.print(bank, DEC); + Serial.print(", address "); + Serial.print(address, DEC); + Serial.print("!\nExpected:"); + for (j = 0; j < chunkSize; j++) { + Serial.print(" 0x"); + if (progBuffer[j] < 16) Serial.print("0"); + Serial.print(progBuffer[j], HEX); + } + Serial.print("\nReceived:"); + for (uint8_t j = 0; j < chunkSize; j++) { + Serial.print(" 0x"); + if (verifyBuffer[i + j] < 16) Serial.print("0"); + Serial.print(verifyBuffer[i + j], HEX); + } + Serial.print("\n");*/ + free(verifyBuffer); + if (useProgMem) free(progBuffer); + return false; // uh oh. + } + } + + // increase byte index by [chunkSize] + i += chunkSize; + + // uint8_t automatically wraps to 0 at 256 + address += chunkSize; + + // if we aren't done, update bank (if necessary) and address + if (i < dataSize) { + if (address == 0) bank++; + setMemoryBank(bank); + setMemoryStartAddress(address); + } + } + if (verify) free(verifyBuffer); + if (useProgMem) free(progBuffer); + return true; +} +bool MPU6050_Base::writeProgMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank, uint8_t address, bool verify) { + return writeMemoryBlock(data, dataSize, bank, address, verify, true); +} +bool MPU6050_Base::writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, bool useProgMem) { + uint8_t *progBuffer = 0; + uint8_t success, special; + uint16_t i, j; + if (useProgMem) { + progBuffer = (uint8_t *)malloc(8); // assume 8-byte blocks, realloc later if necessary + } + + // config set data is a long string of blocks with the following structure: + // [bank] [offset] [length] [byte[0], byte[1], ..., byte[length]] + uint8_t bank, offset, length; + for (i = 0; i < dataSize;) { + if (useProgMem) { + bank = pgm_read_byte(data + i++); + offset = pgm_read_byte(data + i++); + length = pgm_read_byte(data + i++); + } else { + bank = data[i++]; + offset = data[i++]; + length = data[i++]; + } + + // write data or perform special action + if (length > 0) { + // regular block of data to write + /*Serial.print("Writing config block to bank "); + Serial.print(bank); + Serial.print(", offset "); + Serial.print(offset); + Serial.print(", length="); + Serial.println(length);*/ + if (useProgMem) { + if (sizeof(progBuffer) < length) progBuffer = (uint8_t *)realloc(progBuffer, length); + for (j = 0; j < length; j++) progBuffer[j] = pgm_read_byte(data + i + j); + } else { + progBuffer = (uint8_t *)data + i; + } + success = writeMemoryBlock(progBuffer, length, bank, offset, true); + i += length; + } else { + // special instruction + // NOTE: this kind of behavior (what and when to do certain things) + // is totally undocumented. This code is in here based on observed + // behavior only, and exactly why (or even whether) it has to be here + // is anybody's guess for now. + if (useProgMem) { + special = pgm_read_byte(data + i++); + } else { + special = data[i++]; + } + /*Serial.print("Special command code "); + Serial.print(special, HEX); + Serial.println(" found...");*/ + if (special == 0x01) { + // enable DMP-related interrupts + + //setIntZeroMotionEnabled(true); + //setIntFIFOBufferOverflowEnabled(true); + //setIntDMPEnabled(true); + I2Cdev::writeByte(devAddr, MPU6050_RA_INT_ENABLE, 0x32, wireObj); // single operation + + success = true; + } else { + // unknown special command + success = false; + } + } + + if (!success) { + if (useProgMem) free(progBuffer); + return false; // uh oh + } + } + if (useProgMem) free(progBuffer); + return true; +} +bool MPU6050_Base::writeProgDMPConfigurationSet(const uint8_t *data, uint16_t dataSize) { + return writeDMPConfigurationSet(data, dataSize, true); +} + +// DMP_CFG_1 register + +uint8_t MPU6050_Base::getDMPConfig1() { + I2Cdev::readByte(devAddr, MPU6050_RA_DMP_CFG_1, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setDMPConfig1(uint8_t config) { + I2Cdev::writeByte(devAddr, MPU6050_RA_DMP_CFG_1, config, wireObj); +} + +// DMP_CFG_2 register + +uint8_t MPU6050_Base::getDMPConfig2() { + I2Cdev::readByte(devAddr, MPU6050_RA_DMP_CFG_2, buffer, I2Cdev::readTimeout, wireObj); + return buffer[0]; +} +void MPU6050_Base::setDMPConfig2(uint8_t config) { + I2Cdev::writeByte(devAddr, MPU6050_RA_DMP_CFG_2, config, wireObj); +} + + +//*************************************************************************************** +//********************** Calibration Routines ********************** +//*************************************************************************************** +/** + @brief Fully calibrate Gyro from ZERO in about 6-7 Loops 600-700 readings +*/ +void MPU6050_Base::CalibrateGyro(uint8_t Loops ) { + double kP = 0.3; + double kI = 90; + float x; + x = (100 - map(Loops, 1, 5, 20, 0)) * .01; + kP *= x; + kI *= x; + + PID( 0x43, kP, kI, Loops); +} + +/** + @brief Fully calibrate Accel from ZERO in about 6-7 Loops 600-700 readings +*/ +void MPU6050_Base::CalibrateAccel(uint8_t Loops ) { + + float kP = 0.3; + float kI = 20; + float x; + x = (100 - map(Loops, 1, 5, 20, 0)) * .01; + kP *= x; + kI *= x; + PID( 0x3B, kP, kI, Loops); +} + +void MPU6050_Base::PID(uint8_t ReadAddress, float kP,float kI, uint8_t Loops){ + uint8_t SaveAddress = (ReadAddress == 0x3B)?((getDeviceID() < 0x38 )? 0x06:0x77):0x13; + + int16_t Data; + float Reading; + int16_t BitZero[3]; + uint8_t shift =(SaveAddress == 0x77)?3:2; + float Error, PTerm, ITerm[3]; + int16_t eSample; + uint32_t eSum; + uint16_t gravity = 8192; // prevent uninitialized compiler warning + if (ReadAddress == 0x3B) gravity = 16384 >> getFullScaleAccelRange(); + Serial.write('>'); + for (int i = 0; i < 3; i++) { + I2Cdev::readWords(devAddr, SaveAddress + (i * shift), 1, (uint16_t *)&Data, I2Cdev::readTimeout, wireObj); // reads 1 or more 16 bit integers (Word) + Reading = Data; + if(SaveAddress != 0x13){ + BitZero[i] = Data & 1; // Capture Bit Zero to properly handle Accelerometer calibration + ITerm[i] = ((float)Reading) * 8; + } else { + ITerm[i] = Reading * 4; + } + } + for (int L = 0; L < Loops; L++) { + eSample = 0; + for (int c = 0; c < 100; c++) {// 100 PI Calculations + eSum = 0; + for (int i = 0; i < 3; i++) { + I2Cdev::readWords(devAddr, ReadAddress + (i * 2), 1, (uint16_t *)&Data, I2Cdev::readTimeout, wireObj); // reads 1 or more 16 bit integers (Word) + Reading = Data; + if ((ReadAddress == 0x3B)&&(i == 2)) Reading -= gravity; //remove Gravity + Error = -Reading; + eSum += abs(Reading); + PTerm = kP * Error; + ITerm[i] += (Error * 0.001) * kI; // Integral term 1000 Calculations a second = 0.001 + if(SaveAddress != 0x13){ + Data = round((PTerm + ITerm[i] ) / 8); //Compute PID Output + Data = ((Data)&0xFFFE) |BitZero[i]; // Insert Bit0 Saved at beginning + } else Data = round((PTerm + ITerm[i] ) / 4); //Compute PID Output + I2Cdev::writeWords(devAddr, SaveAddress + (i * shift), 1, (uint16_t *)&Data, wireObj); + } + if((c == 99) && eSum > 1000){ // Error is still to great to continue + c = 0; + Serial.write('*'); + } + if((eSum * ((ReadAddress == 0x3B)?.05: 1)) < 5) eSample++; // Successfully found offsets prepare to advance + if((eSum < 100) && (c > 10) && (eSample >= 10)) break; // Advance to next Loop + delay(1); + } + Serial.write('.'); + kP *= .75; + kI *= .75; + for (int i = 0; i < 3; i++){ + if(SaveAddress != 0x13) { + Data = round((ITerm[i] ) / 8); //Compute PID Output + Data = ((Data)&0xFFFE) |BitZero[i]; // Insert Bit0 Saved at beginning + } else Data = round((ITerm[i]) / 4); + I2Cdev::writeWords(devAddr, SaveAddress + (i * shift), 1, (uint16_t *)&Data, wireObj); + } + } + resetFIFO(); + resetDMP(); +} + +int16_t * MPU6050_Base::GetActiveOffsets() { + uint8_t AOffsetRegister = (getDeviceID() < 0x38 )? MPU6050_RA_XA_OFFS_H:0x77; + if(AOffsetRegister == 0x06) I2Cdev::readWords(devAddr, AOffsetRegister, 3, (uint16_t *)offsets, I2Cdev::readTimeout, wireObj); + else { + I2Cdev::readWords(devAddr, AOffsetRegister, 1, (uint16_t *)offsets, I2Cdev::readTimeout, wireObj); + I2Cdev::readWords(devAddr, AOffsetRegister+3, 1, (uint16_t *)(offsets+1), I2Cdev::readTimeout, wireObj); + I2Cdev::readWords(devAddr, AOffsetRegister+6, 1, (uint16_t *)(offsets+2), I2Cdev::readTimeout, wireObj); + } + I2Cdev::readWords(devAddr, 0x13, 3, (uint16_t *)(offsets+3), I2Cdev::readTimeout, wireObj); + return offsets; +} + +void MPU6050_Base::PrintActiveOffsets() { + GetActiveOffsets(); + // A_OFFSET_H_READ_A_OFFS(Data); + Serial.print((float)offsets[0], 5); Serial.print(",\t"); + Serial.print((float)offsets[1], 5); Serial.print(",\t"); + Serial.print((float)offsets[2], 5); Serial.print(",\t"); + + // XG_OFFSET_H_READ_OFFS_USR(Data); + Serial.print((float)offsets[3], 5); Serial.print(",\t"); + Serial.print((float)offsets[4], 5); Serial.print(",\t"); + Serial.print((float)offsets[5], 5); Serial.print("\n\n"); +} \ No newline at end of file diff --git a/lib/MPU6050/src/MPU6050.h b/lib/MPU6050/src/MPU6050.h new file mode 100644 index 0000000..b8e6a3e --- /dev/null +++ b/lib/MPU6050/src/MPU6050.h @@ -0,0 +1,874 @@ +// I2Cdev library collection - MPU6050 I2C device class +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 10/3/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally +// ... - ongoing debug release + +// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE +// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF +// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#ifndef _MPU6050_H_ +#define _MPU6050_H_ + +#include "I2Cdev.h" +#include "helper_3dmath.h" + +// supporting link: http://forum.arduino.cc/index.php?&topic=143444.msg1079517#msg1079517 +// also: http://forum.arduino.cc/index.php?&topic=141571.msg1062899#msg1062899s + +#ifdef __AVR__ +#include +#elif defined(ESP32) + #include +#else +//#define PROGMEM /* empty */ +//#define pgm_read_byte(x) (*(x)) +//#define pgm_read_word(x) (*(x)) +//#define pgm_read_float(x) (*(x)) +//#define PSTR(STR) STR +#endif + + +#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board +#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC) +#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW + +#define MPU6050_RA_XG_OFFS_TC 0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD +#define MPU6050_RA_YG_OFFS_TC 0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD +#define MPU6050_RA_ZG_OFFS_TC 0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD +#define MPU6050_RA_X_FINE_GAIN 0x03 //[7:0] X_FINE_GAIN +#define MPU6050_RA_Y_FINE_GAIN 0x04 //[7:0] Y_FINE_GAIN +#define MPU6050_RA_Z_FINE_GAIN 0x05 //[7:0] Z_FINE_GAIN +#define MPU6050_RA_XA_OFFS_H 0x06 //[15:0] XA_OFFS +#define MPU6050_RA_XA_OFFS_L_TC 0x07 +#define MPU6050_RA_YA_OFFS_H 0x08 //[15:0] YA_OFFS +#define MPU6050_RA_YA_OFFS_L_TC 0x09 +#define MPU6050_RA_ZA_OFFS_H 0x0A //[15:0] ZA_OFFS +#define MPU6050_RA_ZA_OFFS_L_TC 0x0B +#define MPU6050_RA_SELF_TEST_X 0x0D //[7:5] XA_TEST[4-2], [4:0] XG_TEST[4-0] +#define MPU6050_RA_SELF_TEST_Y 0x0E //[7:5] YA_TEST[4-2], [4:0] YG_TEST[4-0] +#define MPU6050_RA_SELF_TEST_Z 0x0F //[7:5] ZA_TEST[4-2], [4:0] ZG_TEST[4-0] +#define MPU6050_RA_SELF_TEST_A 0x10 //[5:4] XA_TEST[1-0], [3:2] YA_TEST[1-0], [1:0] ZA_TEST[1-0] +#define MPU6050_RA_XG_OFFS_USRH 0x13 //[15:0] XG_OFFS_USR +#define MPU6050_RA_XG_OFFS_USRL 0x14 +#define MPU6050_RA_YG_OFFS_USRH 0x15 //[15:0] YG_OFFS_USR +#define MPU6050_RA_YG_OFFS_USRL 0x16 +#define MPU6050_RA_ZG_OFFS_USRH 0x17 //[15:0] ZG_OFFS_USR +#define MPU6050_RA_ZG_OFFS_USRL 0x18 +#define MPU6050_RA_SMPLRT_DIV 0x19 +#define MPU6050_RA_CONFIG 0x1A +#define MPU6050_RA_GYRO_CONFIG 0x1B +#define MPU6050_RA_ACCEL_CONFIG 0x1C +#define MPU6050_RA_FF_THR 0x1D +#define MPU6050_RA_FF_DUR 0x1E +#define MPU6050_RA_MOT_THR 0x1F +#define MPU6050_RA_MOT_DUR 0x20 +#define MPU6050_RA_ZRMOT_THR 0x21 +#define MPU6050_RA_ZRMOT_DUR 0x22 +#define MPU6050_RA_FIFO_EN 0x23 +#define MPU6050_RA_I2C_MST_CTRL 0x24 +#define MPU6050_RA_I2C_SLV0_ADDR 0x25 +#define MPU6050_RA_I2C_SLV0_REG 0x26 +#define MPU6050_RA_I2C_SLV0_CTRL 0x27 +#define MPU6050_RA_I2C_SLV1_ADDR 0x28 +#define MPU6050_RA_I2C_SLV1_REG 0x29 +#define MPU6050_RA_I2C_SLV1_CTRL 0x2A +#define MPU6050_RA_I2C_SLV2_ADDR 0x2B +#define MPU6050_RA_I2C_SLV2_REG 0x2C +#define MPU6050_RA_I2C_SLV2_CTRL 0x2D +#define MPU6050_RA_I2C_SLV3_ADDR 0x2E +#define MPU6050_RA_I2C_SLV3_REG 0x2F +#define MPU6050_RA_I2C_SLV3_CTRL 0x30 +#define MPU6050_RA_I2C_SLV4_ADDR 0x31 +#define MPU6050_RA_I2C_SLV4_REG 0x32 +#define MPU6050_RA_I2C_SLV4_DO 0x33 +#define MPU6050_RA_I2C_SLV4_CTRL 0x34 +#define MPU6050_RA_I2C_SLV4_DI 0x35 +#define MPU6050_RA_I2C_MST_STATUS 0x36 +#define MPU6050_RA_INT_PIN_CFG 0x37 +#define MPU6050_RA_INT_ENABLE 0x38 +#define MPU6050_RA_DMP_INT_STATUS 0x39 +#define MPU6050_RA_INT_STATUS 0x3A +#define MPU6050_RA_ACCEL_XOUT_H 0x3B +#define MPU6050_RA_ACCEL_XOUT_L 0x3C +#define MPU6050_RA_ACCEL_YOUT_H 0x3D +#define MPU6050_RA_ACCEL_YOUT_L 0x3E +#define MPU6050_RA_ACCEL_ZOUT_H 0x3F +#define MPU6050_RA_ACCEL_ZOUT_L 0x40 +#define MPU6050_RA_TEMP_OUT_H 0x41 +#define MPU6050_RA_TEMP_OUT_L 0x42 +#define MPU6050_RA_GYRO_XOUT_H 0x43 +#define MPU6050_RA_GYRO_XOUT_L 0x44 +#define MPU6050_RA_GYRO_YOUT_H 0x45 +#define MPU6050_RA_GYRO_YOUT_L 0x46 +#define MPU6050_RA_GYRO_ZOUT_H 0x47 +#define MPU6050_RA_GYRO_ZOUT_L 0x48 +#define MPU6050_RA_EXT_SENS_DATA_00 0x49 +#define MPU6050_RA_EXT_SENS_DATA_01 0x4A +#define MPU6050_RA_EXT_SENS_DATA_02 0x4B +#define MPU6050_RA_EXT_SENS_DATA_03 0x4C +#define MPU6050_RA_EXT_SENS_DATA_04 0x4D +#define MPU6050_RA_EXT_SENS_DATA_05 0x4E +#define MPU6050_RA_EXT_SENS_DATA_06 0x4F +#define MPU6050_RA_EXT_SENS_DATA_07 0x50 +#define MPU6050_RA_EXT_SENS_DATA_08 0x51 +#define MPU6050_RA_EXT_SENS_DATA_09 0x52 +#define MPU6050_RA_EXT_SENS_DATA_10 0x53 +#define MPU6050_RA_EXT_SENS_DATA_11 0x54 +#define MPU6050_RA_EXT_SENS_DATA_12 0x55 +#define MPU6050_RA_EXT_SENS_DATA_13 0x56 +#define MPU6050_RA_EXT_SENS_DATA_14 0x57 +#define MPU6050_RA_EXT_SENS_DATA_15 0x58 +#define MPU6050_RA_EXT_SENS_DATA_16 0x59 +#define MPU6050_RA_EXT_SENS_DATA_17 0x5A +#define MPU6050_RA_EXT_SENS_DATA_18 0x5B +#define MPU6050_RA_EXT_SENS_DATA_19 0x5C +#define MPU6050_RA_EXT_SENS_DATA_20 0x5D +#define MPU6050_RA_EXT_SENS_DATA_21 0x5E +#define MPU6050_RA_EXT_SENS_DATA_22 0x5F +#define MPU6050_RA_EXT_SENS_DATA_23 0x60 +#define MPU6050_RA_MOT_DETECT_STATUS 0x61 +#define MPU6050_RA_I2C_SLV0_DO 0x63 +#define MPU6050_RA_I2C_SLV1_DO 0x64 +#define MPU6050_RA_I2C_SLV2_DO 0x65 +#define MPU6050_RA_I2C_SLV3_DO 0x66 +#define MPU6050_RA_I2C_MST_DELAY_CTRL 0x67 +#define MPU6050_RA_SIGNAL_PATH_RESET 0x68 +#define MPU6050_RA_MOT_DETECT_CTRL 0x69 +#define MPU6050_RA_USER_CTRL 0x6A +#define MPU6050_RA_PWR_MGMT_1 0x6B +#define MPU6050_RA_PWR_MGMT_2 0x6C +#define MPU6050_RA_BANK_SEL 0x6D +#define MPU6050_RA_MEM_START_ADDR 0x6E +#define MPU6050_RA_MEM_R_W 0x6F +#define MPU6050_RA_DMP_CFG_1 0x70 +#define MPU6050_RA_DMP_CFG_2 0x71 +#define MPU6050_RA_FIFO_COUNTH 0x72 +#define MPU6050_RA_FIFO_COUNTL 0x73 +#define MPU6050_RA_FIFO_R_W 0x74 +#define MPU6050_RA_WHO_AM_I 0x75 + +#define MPU6050_SELF_TEST_XA_1_BIT 0x07 +#define MPU6050_SELF_TEST_XA_1_LENGTH 0x03 +#define MPU6050_SELF_TEST_XA_2_BIT 0x05 +#define MPU6050_SELF_TEST_XA_2_LENGTH 0x02 +#define MPU6050_SELF_TEST_YA_1_BIT 0x07 +#define MPU6050_SELF_TEST_YA_1_LENGTH 0x03 +#define MPU6050_SELF_TEST_YA_2_BIT 0x03 +#define MPU6050_SELF_TEST_YA_2_LENGTH 0x02 +#define MPU6050_SELF_TEST_ZA_1_BIT 0x07 +#define MPU6050_SELF_TEST_ZA_1_LENGTH 0x03 +#define MPU6050_SELF_TEST_ZA_2_BIT 0x01 +#define MPU6050_SELF_TEST_ZA_2_LENGTH 0x02 + +#define MPU6050_SELF_TEST_XG_1_BIT 0x04 +#define MPU6050_SELF_TEST_XG_1_LENGTH 0x05 +#define MPU6050_SELF_TEST_YG_1_BIT 0x04 +#define MPU6050_SELF_TEST_YG_1_LENGTH 0x05 +#define MPU6050_SELF_TEST_ZG_1_BIT 0x04 +#define MPU6050_SELF_TEST_ZG_1_LENGTH 0x05 + +#define MPU6050_TC_PWR_MODE_BIT 7 +#define MPU6050_TC_OFFSET_BIT 6 +#define MPU6050_TC_OFFSET_LENGTH 6 +#define MPU6050_TC_OTP_BNK_VLD_BIT 0 + +#define MPU6050_VDDIO_LEVEL_VLOGIC 0 +#define MPU6050_VDDIO_LEVEL_VDD 1 + +#define MPU6050_CFG_EXT_SYNC_SET_BIT 5 +#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3 +#define MPU6050_CFG_DLPF_CFG_BIT 2 +#define MPU6050_CFG_DLPF_CFG_LENGTH 3 + +#define MPU6050_EXT_SYNC_DISABLED 0x0 +#define MPU6050_EXT_SYNC_TEMP_OUT_L 0x1 +#define MPU6050_EXT_SYNC_GYRO_XOUT_L 0x2 +#define MPU6050_EXT_SYNC_GYRO_YOUT_L 0x3 +#define MPU6050_EXT_SYNC_GYRO_ZOUT_L 0x4 +#define MPU6050_EXT_SYNC_ACCEL_XOUT_L 0x5 +#define MPU6050_EXT_SYNC_ACCEL_YOUT_L 0x6 +#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L 0x7 + +#define MPU6050_DLPF_BW_256 0x00 +#define MPU6050_DLPF_BW_188 0x01 +#define MPU6050_DLPF_BW_98 0x02 +#define MPU6050_DLPF_BW_42 0x03 +#define MPU6050_DLPF_BW_20 0x04 +#define MPU6050_DLPF_BW_10 0x05 +#define MPU6050_DLPF_BW_5 0x06 + +#define MPU6050_GCONFIG_FS_SEL_BIT 4 +#define MPU6050_GCONFIG_FS_SEL_LENGTH 2 + +#define MPU6050_GYRO_FS_250 0x00 +#define MPU6050_GYRO_FS_500 0x01 +#define MPU6050_GYRO_FS_1000 0x02 +#define MPU6050_GYRO_FS_2000 0x03 + +#define MPU6050_ACONFIG_XA_ST_BIT 7 +#define MPU6050_ACONFIG_YA_ST_BIT 6 +#define MPU6050_ACONFIG_ZA_ST_BIT 5 +#define MPU6050_ACONFIG_AFS_SEL_BIT 4 +#define MPU6050_ACONFIG_AFS_SEL_LENGTH 2 +#define MPU6050_ACONFIG_ACCEL_HPF_BIT 2 +#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH 3 + +#define MPU6050_ACCEL_FS_2 0x00 +#define MPU6050_ACCEL_FS_4 0x01 +#define MPU6050_ACCEL_FS_8 0x02 +#define MPU6050_ACCEL_FS_16 0x03 + +#define MPU6050_DHPF_RESET 0x00 +#define MPU6050_DHPF_5 0x01 +#define MPU6050_DHPF_2P5 0x02 +#define MPU6050_DHPF_1P25 0x03 +#define MPU6050_DHPF_0P63 0x04 +#define MPU6050_DHPF_HOLD 0x07 + +#define MPU6050_TEMP_FIFO_EN_BIT 7 +#define MPU6050_XG_FIFO_EN_BIT 6 +#define MPU6050_YG_FIFO_EN_BIT 5 +#define MPU6050_ZG_FIFO_EN_BIT 4 +#define MPU6050_ACCEL_FIFO_EN_BIT 3 +#define MPU6050_SLV2_FIFO_EN_BIT 2 +#define MPU6050_SLV1_FIFO_EN_BIT 1 +#define MPU6050_SLV0_FIFO_EN_BIT 0 + +#define MPU6050_MULT_MST_EN_BIT 7 +#define MPU6050_WAIT_FOR_ES_BIT 6 +#define MPU6050_SLV_3_FIFO_EN_BIT 5 +#define MPU6050_I2C_MST_P_NSR_BIT 4 +#define MPU6050_I2C_MST_CLK_BIT 3 +#define MPU6050_I2C_MST_CLK_LENGTH 4 + +#define MPU6050_CLOCK_DIV_348 0x0 +#define MPU6050_CLOCK_DIV_333 0x1 +#define MPU6050_CLOCK_DIV_320 0x2 +#define MPU6050_CLOCK_DIV_308 0x3 +#define MPU6050_CLOCK_DIV_296 0x4 +#define MPU6050_CLOCK_DIV_286 0x5 +#define MPU6050_CLOCK_DIV_276 0x6 +#define MPU6050_CLOCK_DIV_267 0x7 +#define MPU6050_CLOCK_DIV_258 0x8 +#define MPU6050_CLOCK_DIV_500 0x9 +#define MPU6050_CLOCK_DIV_471 0xA +#define MPU6050_CLOCK_DIV_444 0xB +#define MPU6050_CLOCK_DIV_421 0xC +#define MPU6050_CLOCK_DIV_400 0xD +#define MPU6050_CLOCK_DIV_381 0xE +#define MPU6050_CLOCK_DIV_364 0xF + +#define MPU6050_I2C_SLV_RW_BIT 7 +#define MPU6050_I2C_SLV_ADDR_BIT 6 +#define MPU6050_I2C_SLV_ADDR_LENGTH 7 +#define MPU6050_I2C_SLV_EN_BIT 7 +#define MPU6050_I2C_SLV_BYTE_SW_BIT 6 +#define MPU6050_I2C_SLV_REG_DIS_BIT 5 +#define MPU6050_I2C_SLV_GRP_BIT 4 +#define MPU6050_I2C_SLV_LEN_BIT 3 +#define MPU6050_I2C_SLV_LEN_LENGTH 4 + +#define MPU6050_I2C_SLV4_RW_BIT 7 +#define MPU6050_I2C_SLV4_ADDR_BIT 6 +#define MPU6050_I2C_SLV4_ADDR_LENGTH 7 +#define MPU6050_I2C_SLV4_EN_BIT 7 +#define MPU6050_I2C_SLV4_INT_EN_BIT 6 +#define MPU6050_I2C_SLV4_REG_DIS_BIT 5 +#define MPU6050_I2C_SLV4_MST_DLY_BIT 4 +#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5 + +#define MPU6050_MST_PASS_THROUGH_BIT 7 +#define MPU6050_MST_I2C_SLV4_DONE_BIT 6 +#define MPU6050_MST_I2C_LOST_ARB_BIT 5 +#define MPU6050_MST_I2C_SLV4_NACK_BIT 4 +#define MPU6050_MST_I2C_SLV3_NACK_BIT 3 +#define MPU6050_MST_I2C_SLV2_NACK_BIT 2 +#define MPU6050_MST_I2C_SLV1_NACK_BIT 1 +#define MPU6050_MST_I2C_SLV0_NACK_BIT 0 + +#define MPU6050_INTCFG_INT_LEVEL_BIT 7 +#define MPU6050_INTCFG_INT_OPEN_BIT 6 +#define MPU6050_INTCFG_LATCH_INT_EN_BIT 5 +#define MPU6050_INTCFG_INT_RD_CLEAR_BIT 4 +#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT 3 +#define MPU6050_INTCFG_FSYNC_INT_EN_BIT 2 +#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT 1 +#define MPU6050_INTCFG_CLKOUT_EN_BIT 0 + +#define MPU6050_INTMODE_ACTIVEHIGH 0x00 +#define MPU6050_INTMODE_ACTIVELOW 0x01 + +#define MPU6050_INTDRV_PUSHPULL 0x00 +#define MPU6050_INTDRV_OPENDRAIN 0x01 + +#define MPU6050_INTLATCH_50USPULSE 0x00 +#define MPU6050_INTLATCH_WAITCLEAR 0x01 + +#define MPU6050_INTCLEAR_STATUSREAD 0x00 +#define MPU6050_INTCLEAR_ANYREAD 0x01 + +#define MPU6050_INTERRUPT_FF_BIT 7 +#define MPU6050_INTERRUPT_MOT_BIT 6 +#define MPU6050_INTERRUPT_ZMOT_BIT 5 +#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT 4 +#define MPU6050_INTERRUPT_I2C_MST_INT_BIT 3 +#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT 2 +#define MPU6050_INTERRUPT_DMP_INT_BIT 1 +#define MPU6050_INTERRUPT_DATA_RDY_BIT 0 + +// TODO: figure out what these actually do +// UMPL source code is not very obivous +#define MPU6050_DMPINT_5_BIT 5 +#define MPU6050_DMPINT_4_BIT 4 +#define MPU6050_DMPINT_3_BIT 3 +#define MPU6050_DMPINT_2_BIT 2 +#define MPU6050_DMPINT_1_BIT 1 +#define MPU6050_DMPINT_0_BIT 0 + +#define MPU6050_MOTION_MOT_XNEG_BIT 7 +#define MPU6050_MOTION_MOT_XPOS_BIT 6 +#define MPU6050_MOTION_MOT_YNEG_BIT 5 +#define MPU6050_MOTION_MOT_YPOS_BIT 4 +#define MPU6050_MOTION_MOT_ZNEG_BIT 3 +#define MPU6050_MOTION_MOT_ZPOS_BIT 2 +#define MPU6050_MOTION_MOT_ZRMOT_BIT 0 + +#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT 7 +#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT 4 +#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT 3 +#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT 2 +#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT 1 +#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT 0 + +#define MPU6050_PATHRESET_GYRO_RESET_BIT 2 +#define MPU6050_PATHRESET_ACCEL_RESET_BIT 1 +#define MPU6050_PATHRESET_TEMP_RESET_BIT 0 + +#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT 5 +#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH 2 +#define MPU6050_DETECT_FF_COUNT_BIT 3 +#define MPU6050_DETECT_FF_COUNT_LENGTH 2 +#define MPU6050_DETECT_MOT_COUNT_BIT 1 +#define MPU6050_DETECT_MOT_COUNT_LENGTH 2 + +#define MPU6050_DETECT_DECREMENT_RESET 0x0 +#define MPU6050_DETECT_DECREMENT_1 0x1 +#define MPU6050_DETECT_DECREMENT_2 0x2 +#define MPU6050_DETECT_DECREMENT_4 0x3 + +#define MPU6050_USERCTRL_DMP_EN_BIT 7 +#define MPU6050_USERCTRL_FIFO_EN_BIT 6 +#define MPU6050_USERCTRL_I2C_MST_EN_BIT 5 +#define MPU6050_USERCTRL_I2C_IF_DIS_BIT 4 +#define MPU6050_USERCTRL_DMP_RESET_BIT 3 +#define MPU6050_USERCTRL_FIFO_RESET_BIT 2 +#define MPU6050_USERCTRL_I2C_MST_RESET_BIT 1 +#define MPU6050_USERCTRL_SIG_COND_RESET_BIT 0 + +#define MPU6050_PWR1_DEVICE_RESET_BIT 7 +#define MPU6050_PWR1_SLEEP_BIT 6 +#define MPU6050_PWR1_CYCLE_BIT 5 +#define MPU6050_PWR1_TEMP_DIS_BIT 3 +#define MPU6050_PWR1_CLKSEL_BIT 2 +#define MPU6050_PWR1_CLKSEL_LENGTH 3 + +#define MPU6050_CLOCK_INTERNAL 0x00 +#define MPU6050_CLOCK_PLL_XGYRO 0x01 +#define MPU6050_CLOCK_PLL_YGYRO 0x02 +#define MPU6050_CLOCK_PLL_ZGYRO 0x03 +#define MPU6050_CLOCK_PLL_EXT32K 0x04 +#define MPU6050_CLOCK_PLL_EXT19M 0x05 +#define MPU6050_CLOCK_KEEP_RESET 0x07 + +#define MPU6050_PWR2_LP_WAKE_CTRL_BIT 7 +#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH 2 +#define MPU6050_PWR2_STBY_XA_BIT 5 +#define MPU6050_PWR2_STBY_YA_BIT 4 +#define MPU6050_PWR2_STBY_ZA_BIT 3 +#define MPU6050_PWR2_STBY_XG_BIT 2 +#define MPU6050_PWR2_STBY_YG_BIT 1 +#define MPU6050_PWR2_STBY_ZG_BIT 0 + +#define MPU6050_WAKE_FREQ_1P25 0x0 +#define MPU6050_WAKE_FREQ_2P5 0x1 +#define MPU6050_WAKE_FREQ_5 0x2 +#define MPU6050_WAKE_FREQ_10 0x3 + +#define MPU6050_BANKSEL_PRFTCH_EN_BIT 6 +#define MPU6050_BANKSEL_CFG_USER_BANK_BIT 5 +#define MPU6050_BANKSEL_MEM_SEL_BIT 4 +#define MPU6050_BANKSEL_MEM_SEL_LENGTH 5 + +#define MPU6050_WHO_AM_I_BIT 6 +#define MPU6050_WHO_AM_I_LENGTH 6 + +#define MPU6050_DMP_MEMORY_BANKS 8 +#define MPU6050_DMP_MEMORY_BANK_SIZE 256 +#define MPU6050_DMP_MEMORY_CHUNK_SIZE 16 + +#define MPU6050_FIFO_DEFAULT_TIMEOUT 11000 + +enum class ACCEL_FS { + A2G, + A4G, + A8G, + A16G +}; + +enum class GYRO_FS { + G250DPS, + G500DPS, + G1000DPS, + G2000DPS +}; + +class MPU6050_Base { + public: + MPU6050_Base(uint8_t address=MPU6050_DEFAULT_ADDRESS, void *wireObj=0); + + void initialize(); + void initialize(ACCEL_FS accelRange, GYRO_FS gyroRange); + + float get_acce_resolution(); + float get_gyro_resolution(); + + bool testConnection(); + + // AUX_VDDIO register + uint8_t getAuxVDDIOLevel(); + void setAuxVDDIOLevel(uint8_t level); + + // SMPLRT_DIV register + uint8_t getRate(); + void setRate(uint8_t rate); + + // CONFIG register + uint8_t getExternalFrameSync(); + void setExternalFrameSync(uint8_t sync); + uint8_t getDLPFMode(); + void setDLPFMode(uint8_t bandwidth); + + // GYRO_CONFIG register + uint8_t getFullScaleGyroRange(); + void setFullScaleGyroRange(uint8_t range); + + // SELF_TEST registers + uint8_t getAccelXSelfTestFactoryTrim(); + uint8_t getAccelYSelfTestFactoryTrim(); + uint8_t getAccelZSelfTestFactoryTrim(); + + uint8_t getGyroXSelfTestFactoryTrim(); + uint8_t getGyroYSelfTestFactoryTrim(); + uint8_t getGyroZSelfTestFactoryTrim(); + + // ACCEL_CONFIG register + bool getAccelXSelfTest(); + void setAccelXSelfTest(bool enabled); + bool getAccelYSelfTest(); + void setAccelYSelfTest(bool enabled); + bool getAccelZSelfTest(); + void setAccelZSelfTest(bool enabled); + uint8_t getFullScaleAccelRange(); + void setFullScaleAccelRange(uint8_t range); + uint8_t getDHPFMode(); + void setDHPFMode(uint8_t mode); + + // FF_THR register + uint8_t getFreefallDetectionThreshold(); + void setFreefallDetectionThreshold(uint8_t threshold); + + // FF_DUR register + uint8_t getFreefallDetectionDuration(); + void setFreefallDetectionDuration(uint8_t duration); + + // MOT_THR register + uint8_t getMotionDetectionThreshold(); + void setMotionDetectionThreshold(uint8_t threshold); + + // MOT_DUR register + uint8_t getMotionDetectionDuration(); + void setMotionDetectionDuration(uint8_t duration); + + // ZRMOT_THR register + uint8_t getZeroMotionDetectionThreshold(); + void setZeroMotionDetectionThreshold(uint8_t threshold); + + // ZRMOT_DUR register + uint8_t getZeroMotionDetectionDuration(); + void setZeroMotionDetectionDuration(uint8_t duration); + + // FIFO_EN register + bool getTempFIFOEnabled(); + void setTempFIFOEnabled(bool enabled); + bool getXGyroFIFOEnabled(); + void setXGyroFIFOEnabled(bool enabled); + bool getYGyroFIFOEnabled(); + void setYGyroFIFOEnabled(bool enabled); + bool getZGyroFIFOEnabled(); + void setZGyroFIFOEnabled(bool enabled); + bool getAccelFIFOEnabled(); + void setAccelFIFOEnabled(bool enabled); + bool getSlave2FIFOEnabled(); + void setSlave2FIFOEnabled(bool enabled); + bool getSlave1FIFOEnabled(); + void setSlave1FIFOEnabled(bool enabled); + bool getSlave0FIFOEnabled(); + void setSlave0FIFOEnabled(bool enabled); + + // I2C_MST_CTRL register + bool getMultiMasterEnabled(); + void setMultiMasterEnabled(bool enabled); + bool getWaitForExternalSensorEnabled(); + void setWaitForExternalSensorEnabled(bool enabled); + bool getSlave3FIFOEnabled(); + void setSlave3FIFOEnabled(bool enabled); + bool getSlaveReadWriteTransitionEnabled(); + void setSlaveReadWriteTransitionEnabled(bool enabled); + uint8_t getMasterClockSpeed(); + void setMasterClockSpeed(uint8_t speed); + + // I2C_SLV* registers (Slave 0-3) + uint8_t getSlaveAddress(uint8_t num); + void setSlaveAddress(uint8_t num, uint8_t address); + uint8_t getSlaveRegister(uint8_t num); + void setSlaveRegister(uint8_t num, uint8_t reg); + bool getSlaveEnabled(uint8_t num); + void setSlaveEnabled(uint8_t num, bool enabled); + bool getSlaveWordByteSwap(uint8_t num); + void setSlaveWordByteSwap(uint8_t num, bool enabled); + bool getSlaveWriteMode(uint8_t num); + void setSlaveWriteMode(uint8_t num, bool mode); + bool getSlaveWordGroupOffset(uint8_t num); + void setSlaveWordGroupOffset(uint8_t num, bool enabled); + uint8_t getSlaveDataLength(uint8_t num); + void setSlaveDataLength(uint8_t num, uint8_t length); + + // I2C_SLV* registers (Slave 4) + uint8_t getSlave4Address(); + void setSlave4Address(uint8_t address); + uint8_t getSlave4Register(); + void setSlave4Register(uint8_t reg); + void setSlave4OutputByte(uint8_t data); + bool getSlave4Enabled(); + void setSlave4Enabled(bool enabled); + bool getSlave4InterruptEnabled(); + void setSlave4InterruptEnabled(bool enabled); + bool getSlave4WriteMode(); + void setSlave4WriteMode(bool mode); + uint8_t getSlave4MasterDelay(); + void setSlave4MasterDelay(uint8_t delay); + uint8_t getSlate4InputByte(); + + // I2C_MST_STATUS register + bool getPassthroughStatus(); + bool getSlave4IsDone(); + bool getLostArbitration(); + bool getSlave4Nack(); + bool getSlave3Nack(); + bool getSlave2Nack(); + bool getSlave1Nack(); + bool getSlave0Nack(); + + // INT_PIN_CFG register + bool getInterruptMode(); + void setInterruptMode(bool mode); + bool getInterruptDrive(); + void setInterruptDrive(bool drive); + bool getInterruptLatch(); + void setInterruptLatch(bool latch); + bool getInterruptLatchClear(); + void setInterruptLatchClear(bool clear); + bool getFSyncInterruptLevel(); + void setFSyncInterruptLevel(bool level); + bool getFSyncInterruptEnabled(); + void setFSyncInterruptEnabled(bool enabled); + bool getI2CBypassEnabled(); + void setI2CBypassEnabled(bool enabled); + bool getClockOutputEnabled(); + void setClockOutputEnabled(bool enabled); + + // INT_ENABLE register + uint8_t getIntEnabled(); + void setIntEnabled(uint8_t enabled); + bool getIntFreefallEnabled(); + void setIntFreefallEnabled(bool enabled); + bool getIntMotionEnabled(); + void setIntMotionEnabled(bool enabled); + bool getIntZeroMotionEnabled(); + void setIntZeroMotionEnabled(bool enabled); + bool getIntFIFOBufferOverflowEnabled(); + void setIntFIFOBufferOverflowEnabled(bool enabled); + bool getIntI2CMasterEnabled(); + void setIntI2CMasterEnabled(bool enabled); + bool getIntDataReadyEnabled(); + void setIntDataReadyEnabled(bool enabled); + + // INT_STATUS register + uint8_t getIntStatus(); + bool getIntFreefallStatus(); + bool getIntMotionStatus(); + bool getIntZeroMotionStatus(); + bool getIntFIFOBufferOverflowStatus(); + bool getIntI2CMasterStatus(); + bool getIntDataReadyStatus(); + + // ACCEL_*OUT_* registers + void getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz); + void getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz); + void getAcceleration(int16_t* x, int16_t* y, int16_t* z); + int16_t getAccelerationX(); + int16_t getAccelerationY(); + int16_t getAccelerationZ(); + + // TEMP_OUT_* registers + int16_t getTemperature(); + + // GYRO_*OUT_* registers + void getRotation(int16_t* x, int16_t* y, int16_t* z); + int16_t getRotationX(); + int16_t getRotationY(); + int16_t getRotationZ(); + + // EXT_SENS_DATA_* registers + uint8_t getExternalSensorByte(int position); + uint16_t getExternalSensorWord(int position); + uint32_t getExternalSensorDWord(int position); + + // MOT_DETECT_STATUS register + uint8_t getMotionStatus(); + bool getXNegMotionDetected(); + bool getXPosMotionDetected(); + bool getYNegMotionDetected(); + bool getYPosMotionDetected(); + bool getZNegMotionDetected(); + bool getZPosMotionDetected(); + bool getZeroMotionDetected(); + + // I2C_SLV*_DO register + void setSlaveOutputByte(uint8_t num, uint8_t data); + + // I2C_MST_DELAY_CTRL register + bool getExternalShadowDelayEnabled(); + void setExternalShadowDelayEnabled(bool enabled); + bool getSlaveDelayEnabled(uint8_t num); + void setSlaveDelayEnabled(uint8_t num, bool enabled); + + // SIGNAL_PATH_RESET register + void resetGyroscopePath(); + void resetAccelerometerPath(); + void resetTemperaturePath(); + + // MOT_DETECT_CTRL register + uint8_t getAccelerometerPowerOnDelay(); + void setAccelerometerPowerOnDelay(uint8_t delay); + uint8_t getFreefallDetectionCounterDecrement(); + void setFreefallDetectionCounterDecrement(uint8_t decrement); + uint8_t getMotionDetectionCounterDecrement(); + void setMotionDetectionCounterDecrement(uint8_t decrement); + + // USER_CTRL register + bool getFIFOEnabled(); + void setFIFOEnabled(bool enabled); + bool getI2CMasterModeEnabled(); + void setI2CMasterModeEnabled(bool enabled); + void switchSPIEnabled(bool enabled); + void resetFIFO(); + void resetI2CMaster(); + void resetSensors(); + + // PWR_MGMT_1 register + void reset(); + bool getSleepEnabled(); + void setSleepEnabled(bool enabled); + bool getWakeCycleEnabled(); + void setWakeCycleEnabled(bool enabled); + bool getTempSensorEnabled(); + void setTempSensorEnabled(bool enabled); + uint8_t getClockSource(); + void setClockSource(uint8_t source); + + // PWR_MGMT_2 register + uint8_t getWakeFrequency(); + void setWakeFrequency(uint8_t frequency); + bool getStandbyXAccelEnabled(); + void setStandbyXAccelEnabled(bool enabled); + bool getStandbyYAccelEnabled(); + void setStandbyYAccelEnabled(bool enabled); + bool getStandbyZAccelEnabled(); + void setStandbyZAccelEnabled(bool enabled); + bool getStandbyXGyroEnabled(); + void setStandbyXGyroEnabled(bool enabled); + bool getStandbyYGyroEnabled(); + void setStandbyYGyroEnabled(bool enabled); + bool getStandbyZGyroEnabled(); + void setStandbyZGyroEnabled(bool enabled); + + // FIFO_COUNT_* registers + uint16_t getFIFOCount(); + + // FIFO_R_W register + uint8_t getFIFOByte(); + int8_t GetCurrentFIFOPacket(uint8_t *data, uint8_t length); + void setFIFOByte(uint8_t data); + void getFIFOBytes(uint8_t *data, uint8_t length); + void setFIFOTimeout(uint32_t fifoTimeout); + uint32_t getFIFOTimeout(); + + // WHO_AM_I register + uint8_t getDeviceID(); + void setDeviceID(uint8_t id); + + // ======== UNDOCUMENTED/DMP REGISTERS/METHODS ======== + + // XG_OFFS_TC register + uint8_t getOTPBankValid(); + void setOTPBankValid(bool enabled); + int8_t getXGyroOffsetTC(); + void setXGyroOffsetTC(int8_t offset); + + // YG_OFFS_TC register + int8_t getYGyroOffsetTC(); + void setYGyroOffsetTC(int8_t offset); + + // ZG_OFFS_TC register + int8_t getZGyroOffsetTC(); + void setZGyroOffsetTC(int8_t offset); + + // X_FINE_GAIN register + int8_t getXFineGain(); + void setXFineGain(int8_t gain); + + // Y_FINE_GAIN register + int8_t getYFineGain(); + void setYFineGain(int8_t gain); + + // Z_FINE_GAIN register + int8_t getZFineGain(); + void setZFineGain(int8_t gain); + + // XA_OFFS_* registers + int16_t getXAccelOffset(); + void setXAccelOffset(int16_t offset); + + // YA_OFFS_* register + int16_t getYAccelOffset(); + void setYAccelOffset(int16_t offset); + + // ZA_OFFS_* register + int16_t getZAccelOffset(); + void setZAccelOffset(int16_t offset); + + // XG_OFFS_USR* registers + int16_t getXGyroOffset(); + void setXGyroOffset(int16_t offset); + + // YG_OFFS_USR* register + int16_t getYGyroOffset(); + void setYGyroOffset(int16_t offset); + + // ZG_OFFS_USR* register + int16_t getZGyroOffset(); + void setZGyroOffset(int16_t offset); + + // INT_ENABLE register (DMP functions) + bool getIntPLLReadyEnabled(); + void setIntPLLReadyEnabled(bool enabled); + bool getIntDMPEnabled(); + void setIntDMPEnabled(bool enabled); + + // DMP_INT_STATUS + bool getDMPInt5Status(); + bool getDMPInt4Status(); + bool getDMPInt3Status(); + bool getDMPInt2Status(); + bool getDMPInt1Status(); + bool getDMPInt0Status(); + + // INT_STATUS register (DMP functions) + bool getIntPLLReadyStatus(); + bool getIntDMPStatus(); + + // USER_CTRL register (DMP functions) + bool getDMPEnabled(); + void setDMPEnabled(bool enabled); + void resetDMP(); + + // BANK_SEL register + void setMemoryBank(uint8_t bank, bool prefetchEnabled=false, bool userBank=false); + + // MEM_START_ADDR register + void setMemoryStartAddress(uint8_t address); + + // MEM_R_W register + uint8_t readMemoryByte(); + void writeMemoryByte(uint8_t data); + void readMemoryBlock(uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0); + bool writeMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0, bool verify=true, bool useProgMem=false); + bool writeProgMemoryBlock(const uint8_t *data, uint16_t dataSize, uint8_t bank=0, uint8_t address=0, bool verify=true); + + bool writeDMPConfigurationSet(const uint8_t *data, uint16_t dataSize, bool useProgMem=false); + bool writeProgDMPConfigurationSet(const uint8_t *data, uint16_t dataSize); + + // DMP_CFG_1 register + uint8_t getDMPConfig1(); + void setDMPConfig1(uint8_t config); + + // DMP_CFG_2 register + uint8_t getDMPConfig2(); + void setDMPConfig2(uint8_t config); + + // Calibration Routines + void CalibrateGyro(uint8_t Loops = 15); // Fine tune after setting offsets with less Loops. + void CalibrateAccel(uint8_t Loops = 15);// Fine tune after setting offsets with less Loops. + void PID(uint8_t ReadAddress, float kP,float kI, uint8_t Loops); // Does the math + void PrintActiveOffsets(); // See the results of the Calibration + int16_t * GetActiveOffsets(); + + protected: + uint8_t devAddr; + void *wireObj; + uint8_t buffer[14]; + uint32_t fifoTimeout = MPU6050_FIFO_DEFAULT_TIMEOUT; + + float accelerationResolution; + float gyroscopeResolution; + + private: + int16_t offsets[6]; +}; + +#ifndef I2CDEVLIB_MPU6050_TYPEDEF +#define I2CDEVLIB_MPU6050_TYPEDEF +typedef MPU6050_Base MPU6050; +#endif + +#endif /* _MPU6050_H_ */ \ No newline at end of file diff --git a/lib/MPU6050/src/MPU6050_6Axis_MotionApps20.cpp b/lib/MPU6050/src/MPU6050_6Axis_MotionApps20.cpp new file mode 100644 index 0000000..ed0f505 --- /dev/null +++ b/lib/MPU6050/src/MPU6050_6Axis_MotionApps20.cpp @@ -0,0 +1,632 @@ +// I2Cdev library collection - MPU6050 I2C device class, 6-axis MotionApps 2.0 implementation +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 5/20/2013 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally +// 2019/07/08 - merged all DMP Firmware configuration items into the dmpMemory array +// - Simplified dmpInitialize() to accomidate the dmpmemory array alterations + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2021 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +// MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board +#define MPU6050_INCLUDE_DMP_MOTIONAPPS20 + +#include "MPU6050_6Axis_MotionApps20.h" + +// Tom Carpenter's conditional PROGMEM code +// http://forum.arduino.cc/index.php?topic=129407.0 +#ifdef __AVR__ + #include +#elif defined(ESP32) + #include +#else + // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen + #ifndef __PGMSPACE_H_ + #define __PGMSPACE_H_ 1 + #include + + #define PROGMEM + #define PGM_P const char * + #define PSTR(str) (str) + #define F(x) x + + typedef void prog_void; + typedef char prog_char; + typedef unsigned char prog_uchar; + typedef int8_t prog_int8_t; + typedef uint8_t prog_uint8_t; + typedef int16_t prog_int16_t; + typedef uint16_t prog_uint16_t; + typedef int32_t prog_int32_t; + typedef uint32_t prog_uint32_t; + + #define strcpy_P(dest, src) strcpy((dest), (src)) + #define strcat_P(dest, src) strcat((dest), (src)) + #define strcmp_P(a, b) strcmp((a), (b)) + + #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) + #define pgm_read_word(addr) (*(const unsigned short *)(addr)) + #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) + #define pgm_read_float(addr) (*(const float *)(addr)) + + #define pgm_read_byte_near(addr) pgm_read_byte(addr) + #define pgm_read_word_near(addr) pgm_read_word(addr) + #define pgm_read_dword_near(addr) pgm_read_dword(addr) + #define pgm_read_float_near(addr) pgm_read_float(addr) + #define pgm_read_byte_far(addr) pgm_read_byte(addr) + #define pgm_read_word_far(addr) pgm_read_word(addr) + #define pgm_read_dword_far(addr) pgm_read_dword(addr) + #define pgm_read_float_far(addr) pgm_read_float(addr) + #endif +#endif + +/* Source is from the InvenSense MotionApps v2 demo code. Original source is + * unavailable, unless you happen to be amazing as decompiling binary by + * hand (in which case, please contact me, and I'm totally serious). + * + * Also, I'd like to offer many, many thanks to Noah Zerkin for all of the + * DMP reverse-engineering he did to help make this bit of wizardry + * possible. + */ + +// NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. +// Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) +// after moving string constants to flash memory storage using the F() +// compiler macro (Arduino IDE 1.0+ required). + +//#define DEBUG +/* Control whether debugging macros are active at compile time */ +#undef DB_ACTIVE +#ifdef DEBUG +#define DB_ACTIVE 1 +#else +#define DB_ACTIVE 0 +#endif /* DEBUG */ + +/* +** Usage: DB_PRINT((...)); +** Usage: DB_PRINTLN((...)); +** +** "..." is whatever extra arguments fmt requires (possibly nothing). +** +** The structure of the macros means that the code is always validated +** but is not called when DEBUG is undefined. +** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike. +*/ +#define DEBUG_PRINT(...)\ + do { if (DB_ACTIVE) Serial.print(__VA_ARGS__); } while (0) +#define DEBUG_PRINTF(...)\ + do { if (DB_ACTIVE) Serial.printf(__VA_ARGS__); } while (0) +#define DEBUG_PRINTLN(...)\ + do { if (DB_ACTIVE) Serial.println(__VA_ARGS__); } while (0) +#define DEBUG_PRINTLNF(x, y)\ + do { if (DB_ACTIVE) Serial.println(x, y); } while (0) + +#define MPU6050_DMP_CODE_SIZE 1929 // dmpMemory[] +#define MPU6050_DMP_CONFIG_SIZE 192 // dmpConfig[] +#define MPU6050_DMP_UPDATES_SIZE 47 // dmpUpdates[] + +/* ================================================================================================ * + | Default MotionApps v2.0 42-byte FIFO packet structure: | + | | + | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] | + | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | + | | + | [GYRO Z][ ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] | + | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | + * ================================================================================================ */ + +// this block of memory gets written to the MPU on start-up, and it seems +// to be volatile memory, so it has to be done each time (it only takes ~1 +// second though) + +// I Only Changed this by applying all the configuration data and capturing it before startup: +// *** this is a capture of the DMP Firmware after all the messy changes were made so we can just load it +static const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { + /* bank # 0 */ + 0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01, + 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCB, 0x47, 0xA2, 0x20, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82, + 0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC, + 0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4, + 0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10, + /* bank # 1 */ + 0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8, + 0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C, + 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x23, 0xA1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C, + 0x80, 0x00, 0xFF, 0xFF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0, + /* bank # 2 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x01, 0x00, 0x05, 0x8B, 0xC1, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* bank # 3 */ + 0xD8, 0xDC, 0xBA, 0xA2, 0xF1, 0xDE, 0xB2, 0xB8, 0xB4, 0xA8, 0x81, 0x91, 0xF7, 0x4A, 0x90, 0x7F, + 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2, + 0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF, + 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C, + 0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, + 0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01, + 0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80, + 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0x4C, 0xCD, 0x6C, 0xA9, 0x0C, + 0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80, + 0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E, + 0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9, + 0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24, + 0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xAF, 0xF0, + 0x00, 0x28, 0x50, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xD9, 0xFA, 0xA3, 0x86, + 0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1, + 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86, + /* bank # 4 */ + 0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA, + 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C, + 0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8, + 0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3, + 0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84, + 0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5, + 0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3, + 0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1, + 0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5, + 0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D, + 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, + 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D, + 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, + 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A, + 0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8, + 0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87, + /* bank # 5 */ + 0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8, + 0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68, + 0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D, + 0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94, + 0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA, + 0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56, + 0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, + 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA, + 0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0xA8, 0x8A, + 0x9A, 0xF5, 0x20, 0xAA, 0xDA, 0xDF, 0xD8, 0xA8, 0x40, 0xAA, 0xD0, 0xDA, 0xDE, 0xD8, 0xA8, 0x60, + 0xAA, 0xDA, 0xD0, 0xDF, 0xD8, 0xF1, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, + 0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, 0xB8, 0xB0, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04, + 0x28, 0x51, 0x79, 0x1D, 0x30, 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78, + 0x78, 0x9B, 0xF1, 0x1A, 0xB0, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79, + 0x8A, 0x24, 0x70, 0x59, 0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68, + 0x8A, 0x64, 0x48, 0x31, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, 0x58, 0x44, 0x68, + /* bank # 6 */ + 0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04, + 0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66, + 0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, + 0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60, + 0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76, + 0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, 0x6E, 0x8A, 0x56, + 0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, 0x9D, 0xB8, 0xAD, + 0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0x81, 0x91, + 0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, + 0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, 0xD9, 0x04, 0xAE, + 0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, 0x81, 0xAD, 0xD9, + 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, 0xAD, 0xAD, 0xAD, + 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, 0xF3, 0xAC, 0x2E, + 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, 0x30, 0x18, 0xA8, + 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, 0xF2, 0xB0, 0x89, + 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, 0xD8, 0xD8, 0x79, + /* bank # 7 */ + 0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, 0xD9, 0x28, 0xD8, + 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, 0x80, 0x25, 0xDA, + 0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, 0x3C, 0xF3, 0xAB, + 0x8B, 0xF8, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xFA, 0xB0, 0x87, 0x9C, 0xB9, 0xA3, + 0xDD, 0xF1, 0x20, 0x28, 0x30, 0x38, 0x9A, 0xF1, 0x28, 0x30, 0x38, 0x9D, 0xF1, 0xA3, 0xA3, 0xA3, + 0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, + 0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0x28, 0x30, 0x38, + 0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0x30, 0xDC, + 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xFE, 0xD8, 0xFF, + +}; + +#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR +#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x01 // The New instance of the Firmware has this as the default +#endif + +// I Simplified this: +uint8_t MPU6050_6Axis_MotionApps20::dmpInitialize() { + // reset device + DEBUG_PRINTLN(F("\n\nResetting MPU6050...")); + reset(); + delay(30); // wait after reset + + // enable sleep mode and wake cycle + /*Serial.println(F("Enabling sleep mode...")); + setSleepEnabled(true); + Serial.println(F("Enabling wake cycle...")); + setWakeCycleEnabled(true);*/ + + // disable sleep mode + setSleepEnabled(false); + + // get MPU hardware revision + setMemoryBank(0x10, true, true); + setMemoryStartAddress(0x06); + DEBUG_PRINTLN(F("Checking hardware revision...")); + DEBUG_PRINT(F("Revision @ user[16][6] = ")); + DEBUG_PRINTLN(readMemoryByte()); + DEBUG_PRINTLN(F("Resetting memory bank selection to 0...")); + setMemoryBank(0, false, false); + + // check OTP bank valid + DEBUG_PRINTLN(F("Reading OTP bank valid flag...")); + DEBUG_PRINT(F("OTP bank is ")); + DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!")); + + // setup weird slave stuff (?) + DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F...")); + setSlaveAddress(0, 0x7F); + DEBUG_PRINTLN(F("Disabling I2C Master mode...")); + setI2CMasterModeEnabled(false); + DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)...")); + setSlaveAddress(0, 0x68); + DEBUG_PRINTLN(F("Resetting I2C Master control...")); + resetI2CMaster(); + delay(20); + DEBUG_PRINTLN(F("Setting clock source to Z Gyro...")); + setClockSource(MPU6050_CLOCK_PLL_ZGYRO); + + DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled...")); + setIntEnabled(1<= dmpGetFIFOPacketSize(); +} + +// uint8_t MPU6050_6Axis_MotionApps20::dmpSetFIFORate(uint8_t fifoRate); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetFIFORate(); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetSampleStepSizeMS(); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetSampleFrequency(); +// int32_t MPU6050_6Axis_MotionApps20::dmpDecodeTemperature(int8_t tempReg); + +//uint8_t MPU6050_6Axis_MotionApps20::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); +//uint8_t MPU6050_6Axis_MotionApps20::dmpUnregisterFIFORateProcess(inv_obj_func func); +//uint8_t MPU6050_6Axis_MotionApps20::dmpRunFIFORateProcesses(); + +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendQuaternion(uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendPacketNumber(uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); + +uint8_t MPU6050_6Axis_MotionApps20::dmpGetAccel(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((int32_t)packet[28] << 24) | ((int32_t)packet[29] << 16) | ((int32_t)packet[30] << 8) | (int32_t)packet[31]); + data[1] = (((int32_t)packet[32] << 24) | ((int32_t)packet[33] << 16) | ((int32_t)packet[34] << 8) | (int32_t)packet[35]); + data[2] = (((int32_t)packet[36] << 24) | ((int32_t)packet[37] << 16) | ((int32_t)packet[38] << 8) | (int32_t)packet[39]); + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpGetAccel(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = ((int16_t)packet[28] << 8) | (int16_t)packet[29]; + data[1] = ((int16_t)packet[32] << 8) | (int16_t)packet[33]; + data[2] = ((int16_t)packet[36] << 8) | (int16_t)packet[37]; + return 0; +} + +uint8_t MPU6050_6Axis_MotionApps20::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + v -> x = ((int16_t)packet[28] << 8) | (int16_t)packet[29]; + v -> y = ((int16_t)packet[32] << 8) | (int16_t)packet[33]; + v -> z = ((int16_t)packet[36] << 8) | (int16_t)packet[37]; + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((int32_t)packet[0] << 24) | ((int32_t)packet[1] << 16) | ((int32_t)packet[2] << 8) | (int32_t)packet[3]); + data[1] = (((int32_t)packet[4] << 24) | ((int32_t)packet[5] << 16) | ((int32_t)packet[6] << 8) | (int32_t)packet[7]); + data[2] = (((int32_t)packet[8] << 24) | ((int32_t)packet[9] << 16) | ((int32_t)packet[10] << 8) | (int32_t)packet[11]); + data[3] = (((int32_t)packet[12] << 24) | ((int32_t)packet[13] << 16) | ((int32_t)packet[14] << 8) | (int32_t)packet[15]); + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((int16_t)packet[0] << 8) | (int16_t)packet[1]); + data[1] = (((int16_t)packet[4] << 8) | (int16_t)packet[5]); + data[2] = (((int16_t)packet[8] << 8) | (int16_t)packet[9]); + data[3] = (((int16_t)packet[12] << 8) | (int16_t)packet[13]); + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + int16_t qI[4]; + uint8_t status = dmpGetQuaternion(qI, packet); + if (status == 0) { + q -> w = (float)qI[0] / 16384.0f; + q -> x = (float)qI[1] / 16384.0f; + q -> y = (float)qI[2] / 16384.0f; + q -> z = (float)qI[3] / 16384.0f; + return 0; + } + return status; // int16 return value, indicates error if this line is reached +} +// uint8_t MPU6050_6Axis_MotionApps20::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); +uint8_t MPU6050_6Axis_MotionApps20::dmpGetGyro(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((int32_t)packet[16] << 24) | ((int32_t)packet[17] << 16) | ((int32_t)packet[18] << 8) | (int32_t)packet[19]); + data[1] = (((int32_t)packet[20] << 24) | ((int32_t)packet[21] << 16) | ((int32_t)packet[22] << 8) | (int32_t)packet[23]); + data[2] = (((int32_t)packet[24] << 24) | ((int32_t)packet[25] << 16) | ((int32_t)packet[26] << 8) | (int32_t)packet[27]); + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpGetGyro(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = ((int16_t)packet[16] << 8) | (int16_t)packet[17]; + data[1] = ((int16_t)packet[20] << 8) | (int16_t)packet[21]; + data[2] = ((int16_t)packet[24] << 8) | (int16_t)packet[25]; + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + v -> x = ((int16_t)packet[16] << 8) | (int16_t)packet[17]; + v -> y = ((int16_t)packet[20] << 8) | (int16_t)packet[21]; + v -> z = ((int16_t)packet[24] << 8) | (int16_t)packet[25]; + return 0; +} +// uint8_t MPU6050_6Axis_MotionApps20::dmpSetLinearAccelFilterCoefficient(float coef); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetLinearAccel(long *data, const uint8_t* packet); +uint8_t MPU6050_6Axis_MotionApps20::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { + // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) + v -> x = vRaw -> x - gravity -> x*8192; + v -> y = vRaw -> y - gravity -> y*8192; + v -> z = vRaw -> z - gravity -> z*8192; + return 0; +} +// uint8_t MPU6050_6Axis_MotionApps20::dmpConvertToWorldFrame(long *data, const uint8_t* packet); +uint8_t MPU6050_6Axis_MotionApps20::dmpConvertToWorldFrame(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { + // rotate measured 3D acceleration vector into original state + // frame of reference based on orientation quaternion + memcpy(v, vReal, sizeof(VectorInt16)); + v -> rotate(q); + return 0; +} +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetGyroSensor(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetControlData(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetTemperature(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetGravity(long *data, const uint8_t* packet); +uint8_t MPU6050_6Axis_MotionApps20::dmpGetGravity(int16_t *data, const uint8_t* packet) { + /* +1g corresponds to +8192, sensitivity is 2g. */ + int16_t qI[4]; + uint8_t status = dmpGetQuaternion(qI, packet); + data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384; + data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384; + data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1] - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (int32_t)(2 * 16384L); + return status; +} + +uint8_t MPU6050_6Axis_MotionApps20::dmpGetGravity(VectorFloat *v, Quaternion *q) { + v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); + v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); + v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; + return 0; + +} +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetQuantizedAccel(long *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetEIS(long *data, const uint8_t* packet); + +uint8_t MPU6050_6Axis_MotionApps20::dmpGetEuler(float *data, Quaternion *q) { + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi + data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta + data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi + return 0; +} + +#ifdef USE_OLD_DMPGETYAWPITCHROLL +uint8_t MPU6050_6Axis_MotionApps20::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { + // yaw: (about Z axis) + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); + // pitch: (nose up/down, about Y axis) + data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); + // roll: (tilt left/right, about X axis) + data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); + return 0; +} +#else +uint8_t MPU6050_6Axis_MotionApps20::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { + // yaw: (about Z axis) + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); + // pitch: (nose up/down, about Y axis) + data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); + // roll: (tilt left/right, about X axis) + data[2] = atan2(gravity -> y , gravity -> z); + if (gravity -> z < 0) { + if(data[1] > 0) { + data[1] = PI - data[1]; + } else { + data[1] = -PI - data[1]; + } + } + return 0; +} +#endif + +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetAccelFloat(float *data, const uint8_t* packet); +// uint8_t MPU6050_6Axis_MotionApps20::dmpGetQuaternionFloat(float *data, const uint8_t* packet); + +uint8_t MPU6050_6Axis_MotionApps20::dmpProcessFIFOPacket(const unsigned char *dmpData) { + (void)dmpData; // unused parameter + /*for (uint8_t k = 0; k < dmpPacketSize; k++) { + if (dmpData[k] < 0x10) Serial.print("0"); + Serial.print(dmpData[k], HEX); + Serial.print(" "); + } + Serial.print("\n");*/ + //Serial.println((uint16_t)dmpPacketBuffer); + return 0; +} +uint8_t MPU6050_6Axis_MotionApps20::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { + uint8_t status; + uint8_t buf[dmpPacketSize]; + for (uint8_t i = 0; i < numPackets; i++) { + // read packet from FIFO + getFIFOBytes(buf, dmpPacketSize); + + // process packet + if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; + + // increment external process count variable, if supplied + if (processed != 0) (*processed)++; + } + return 0; +} + +// uint8_t MPU6050_6Axis_MotionApps20::dmpSetFIFOProcessedCallback(void (*func) (void)); + +// uint8_t MPU6050_6Axis_MotionApps20::dmpInitFIFOParam(); +// uint8_t MPU6050_6Axis_MotionApps20::dmpCloseFIFO(); +// uint8_t MPU6050_6Axis_MotionApps20::dmpSetGyroDataSource(uint_fast8_t source); +// uint8_t MPU6050_6Axis_MotionApps20::dmpDecodeQuantizedAccel(); +// uint32_t MPU6050_6Axis_MotionApps20::dmpGetGyroSumOfSquare(); +// uint32_t MPU6050_6Axis_MotionApps20::dmpGetAccelSumOfSquare(); +// void MPU6050_6Axis_MotionApps20::dmpOverrideQuaternion(long *q); +uint16_t MPU6050_6Axis_MotionApps20::dmpGetFIFOPacketSize() { + return dmpPacketSize; +} + + + +uint8_t MPU6050_6Axis_MotionApps20::dmpGetCurrentFIFOPacket(uint8_t *data) { // overflow proof + return(GetCurrentFIFOPacket(data, dmpPacketSize)); +} \ No newline at end of file diff --git a/lib/MPU6050/src/MPU6050_6Axis_MotionApps20.h b/lib/MPU6050/src/MPU6050_6Axis_MotionApps20.h new file mode 100644 index 0000000..98e7c34 --- /dev/null +++ b/lib/MPU6050/src/MPU6050_6Axis_MotionApps20.h @@ -0,0 +1,154 @@ +// I2Cdev library collection - MPU6050 I2C device class +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 10/3/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally +// ... - ongoing debug release + +// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE +// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF +// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#ifndef _MPU6050_6AXIS_MOTIONAPPS20_H_ +#define _MPU6050_6AXIS_MOTIONAPPS20_H_ + +// take ownership of the "MPU6050" typedef +#define I2CDEVLIB_MPU6050_TYPEDEF + +#include "MPU6050.h" + +class MPU6050_6Axis_MotionApps20 : public MPU6050_Base { + public: + MPU6050_6Axis_MotionApps20(uint8_t address=MPU6050_DEFAULT_ADDRESS, void *wireObj=0) : MPU6050_Base(address, wireObj) { } + + uint8_t dmpInitialize(); + bool dmpPacketAvailable(); + + uint8_t dmpSetFIFORate(uint8_t fifoRate); + uint8_t dmpGetFIFORate(); + uint8_t dmpGetSampleStepSizeMS(); + uint8_t dmpGetSampleFrequency(); + int32_t dmpDecodeTemperature(int8_t tempReg); + + // Register callbacks after a packet of FIFO data is processed + //uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); + //uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func); + uint8_t dmpRunFIFORateProcesses(); + + // Setup FIFO for various output + uint8_t dmpSendQuaternion(uint_fast16_t accuracy); + uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendPacketNumber(uint_fast16_t accuracy); + uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); + + // Get Fixed Point data from FIFO + uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpSetLinearAccelFilterCoefficient(float coef); + uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity); + uint8_t dmpConvertToWorldFrame(int32_t *data, const uint8_t* packet=0); + uint8_t dmpConvertToWorldFrame(int16_t *data, const uint8_t* packet=0); + uint8_t dmpConvertToWorldFrame(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpConvertToWorldFrame(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q); + uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q); + uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0); + uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0); + + uint8_t dmpGetEuler(float *data, Quaternion *q); + uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity); + + // Get Floating Point data from FIFO + uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0); + + uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData); + uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL); + + uint8_t dmpSetFIFOProcessedCallback(void (*func) (void)); + + uint8_t dmpInitFIFOParam(); + uint8_t dmpCloseFIFO(); + uint8_t dmpSetGyroDataSource(uint8_t source); + uint8_t dmpDecodeQuantizedAccel(); + uint32_t dmpGetGyroSumOfSquare(); + uint32_t dmpGetAccelSumOfSquare(); + void dmpOverrideQuaternion(long *q); + uint16_t dmpGetFIFOPacketSize(); + uint8_t dmpGetCurrentFIFOPacket(uint8_t *data); // overflow proof + + private: + uint8_t *dmpPacketBuffer; + uint16_t dmpPacketSize; +}; + +typedef MPU6050_6Axis_MotionApps20 MPU6050; + + +#endif /* _MPU6050_6AXIS_MOTIONAPPS20_H_ */ \ No newline at end of file diff --git a/lib/MPU6050/src/MPU6050_6Axis_MotionApps612.cpp b/lib/MPU6050/src/MPU6050_6Axis_MotionApps612.cpp new file mode 100644 index 0000000..5958c25 --- /dev/null +++ b/lib/MPU6050/src/MPU6050_6Axis_MotionApps612.cpp @@ -0,0 +1,627 @@ +// I2Cdev library collection - MPU6050 I2C device class, 6-axis MotionApps 6.12 implementation +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 5/20/2013 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally +// 2019/07/10 - I incorporated DMP Firmware Version 6.12 Latest as of today with many features and bug fixes. +// - MPU6050 Registers have not changed just the DMP Image so that full backwards compatibility is present +// - Run-time calibration routine is enabled which calibrates after no motion state is detected +// - once no motion state is detected Calibration completes within 0.5 seconds +// - The Drawback is that the firmware image is larger. +// ... - ongoing debug release + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +// MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board +#define MPU6050_INCLUDE_DMP_MOTIONAPPS612 + +#include "MPU6050_6Axis_MotionApps612.h" + +// Tom Carpenter's conditional PROGMEM code +// http://forum.arduino.cc/index.php?topic=129407.0 +#ifdef __AVR__ + #include +#elif defined(ESP32) + #include +#else + // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen + #ifndef __PGMSPACE_H_ + #define __PGMSPACE_H_ 1 + #include + + #define PROGMEM + #define PGM_P const char * + #define PSTR(str) (str) + #define F(x) x + + typedef void prog_void; + typedef char prog_char; + typedef unsigned char prog_uchar; + typedef int8_t prog_int8_t; + typedef uint8_t prog_uint8_t; + typedef int16_t prog_int16_t; + typedef uint16_t prog_uint16_t; + typedef int32_t prog_int32_t; + typedef uint32_t prog_uint32_t; + + #define strcpy_P(dest, src) strcpy((dest), (src)) + #define strcat_P(dest, src) strcat((dest), (src)) + #define strcmp_P(a, b) strcmp((a), (b)) + + #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) + #define pgm_read_word(addr) (*(const unsigned short *)(addr)) + #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) + #define pgm_read_float(addr) (*(const float *)(addr)) + + #define pgm_read_byte_near(addr) pgm_read_byte(addr) + #define pgm_read_word_near(addr) pgm_read_word(addr) + #define pgm_read_dword_near(addr) pgm_read_dword(addr) + #define pgm_read_float_near(addr) pgm_read_float(addr) + #define pgm_read_byte_far(addr) pgm_read_byte(addr) + #define pgm_read_word_far(addr) pgm_read_word(addr) + #define pgm_read_dword_far(addr) pgm_read_dword(addr) + #define pgm_read_float_far(addr) pgm_read_float(addr) + #endif +#endif + +/* Source is from the InvenSense MotionApps v2 demo code. Original source is + * unavailable, unless you happen to be amazing as decompiling binary by + * hand (in which case, please contact me, and I'm totally serious). + * + * Also, I'd like to offer many, many thanks to Noah Zerkin for all of the + * DMP reverse-engineering he did to help make this bit of wizardry + * possible. + */ + +// NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. +// Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) +// after moving string constants to flash memory storage using the F() +// compiler macro (Arduino IDE 1.0+ required). + +//#define DEBUG +/* Control whether debugging macros are active at compile time */ +#undef DB_ACTIVE +#ifdef DEBUG +#define DB_ACTIVE 1 +#else +#define DB_ACTIVE 0 +#endif /* DEBUG */ + +/* +** Usage: DB_PRINT((...)); +** Usage: DB_PRINTLN((...)); +** +** "..." is whatever extra arguments fmt requires (possibly nothing). +** +** The structure of the macros means that the code is always validated +** but is not called when DEBUG is undefined. +** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike. +*/ +#define DEBUG_PRINT(...)\ + do { if (DB_ACTIVE) Serial.print(__VA_ARGS__); } while (0) +#define DEBUG_PRINTF(...)\ + do { if (DB_ACTIVE) Serial.printf(__VA_ARGS__); } while (0) +#define DEBUG_PRINTLN(...)\ + do { if (DB_ACTIVE) Serial.println(__VA_ARGS__); } while (0) +#define DEBUG_PRINTLNF(x, y)\ + do { if (DB_ACTIVE) Serial.println(x, y); } while (0) + +#define MPU6050_DMP_CODE_SIZE 3062 // dmpMemory[] + +/* ================================================================ * + | Default MotionApps v6.12 28-byte FIFO packet structure: | + | | + | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ] | + | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | + | | + | [GYRO X][GYRO Y][GYRO Z][ACC X ][ACC Y ][ACC Z ] | + | 16 17 18 19 20 21 22 23 24 25 26 27 | + * ================================================================ */ + +// this block of memory gets written to the MPU on start-up, and it seems +// to be volatile memory, so it has to be done each time (it only takes ~1 +// second though) + +// *** this is a capture of the DMP Firmware V6.1.2 after all the messy changes were made so we can just load it +const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { +/* bank # 0 */ +0x00, 0xF8, 0xF6, 0x2A, 0x3F, 0x68, 0xF5, 0x7A, 0x00, 0x06, 0xFF, 0xFE, 0x00, 0x03, 0x00, 0x00, +0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, +0x03, 0x0C, 0x30, 0xC3, 0x0A, 0x74, 0x56, 0x2D, 0x0D, 0x62, 0xDB, 0xC7, 0x16, 0xF4, 0xBA, 0x02, +0x38, 0x83, 0xF8, 0x83, 0x30, 0x00, 0xF8, 0x83, 0x25, 0x8E, 0xF8, 0x83, 0x30, 0x00, 0xF8, 0x83, +0xFF, 0xFF, 0xFF, 0xFF, 0x0C, 0xBD, 0xD8, 0x11, 0x24, 0x00, 0x04, 0x00, 0x1A, 0x82, 0x79, 0xA1, +0x00, 0x36, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x83, 0x6F, 0xA2, +0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00, +0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, +0x1F, 0xA4, 0xE8, 0xE4, 0xFF, 0xF5, 0xDC, 0xB9, 0x00, 0x5B, 0x79, 0xCF, 0x1F, 0x3F, 0x78, 0x76, +0x00, 0x86, 0x7C, 0x5A, 0x00, 0x86, 0x23, 0x47, 0xFA, 0xB9, 0x86, 0x31, 0x00, 0x74, 0x87, 0x8A, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x05, 0xFF, 0xFF, 0xE9, 0xA8, 0x00, 0x00, 0x21, 0x82, +0xFA, 0xB8, 0x4D, 0x46, 0xFF, 0xFA, 0xDF, 0x3D, 0xFF, 0xFF, 0xB2, 0xB3, 0x00, 0x00, 0x00, 0x00, +0x3F, 0xFF, 0xBA, 0x98, 0x00, 0x5D, 0xAC, 0x08, 0x00, 0x0A, 0x63, 0x78, 0x00, 0x01, 0x46, 0x21, +0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x42, 0xB5, 0x00, 0x06, 0x00, 0x64, 0x00, 0x64, 0x00, 0x06, +0x14, 0x06, 0x02, 0x9F, 0x0F, 0x47, 0x91, 0x32, 0xD9, 0x0E, 0x9F, 0xC9, 0x1D, 0xCF, 0x4C, 0x34, +0x3B, 0xB6, 0x7A, 0xE8, 0x00, 0x64, 0x00, 0x06, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, +/* bank # 1 */ +0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x07, 0x00, 0x00, 0xFF, 0xF1, 0x00, 0x00, 0xFA, 0x46, 0x00, 0x00, 0xA2, 0xB8, 0x00, 0x00, +0x10, 0x00, 0x00, 0x00, 0x04, 0xD6, 0x00, 0x00, 0x04, 0xCC, 0x00, 0x00, 0x04, 0xCC, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x05, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, +0x00, 0x00, 0x00, 0x32, 0xF8, 0x98, 0x00, 0x00, 0xFF, 0x65, 0x00, 0x00, 0x83, 0x0F, 0x00, 0x00, +0x00, 0x06, 0x00, 0x00, 0xFF, 0xF1, 0x00, 0x00, 0xFA, 0x46, 0x00, 0x00, 0xA2, 0xB8, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x02, 0x00, 0x00, +0x00, 0x01, 0xFB, 0x83, 0x00, 0x7C, 0x00, 0x00, 0xFB, 0x15, 0xFC, 0x00, 0x1F, 0xB4, 0xFF, 0x83, +0x00, 0x00, 0x00, 0x01, 0x00, 0x65, 0x00, 0x07, 0x00, 0x64, 0x03, 0xE8, 0x00, 0x64, 0x00, 0x28, +0x00, 0x00, 0xFF, 0xFD, 0x00, 0x00, 0x00, 0x00, 0x16, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x10, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, 0x00, 0x00, 0x10, 0x00, +/* bank # 2 */ +0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x01, 0x00, 0x05, 0xBA, 0xC6, 0x00, 0x47, 0x78, 0xA2, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, +0x00, 0x00, 0x23, 0xBB, 0x00, 0x2E, 0xA2, 0x5B, 0x00, 0x00, 0x05, 0x68, 0x00, 0x0B, 0xCF, 0x49, +0x00, 0x04, 0xFF, 0xFD, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x64, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x06, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x2E, 0xA2, 0x5B, 0x00, 0x00, 0x05, 0x68, 0x00, 0x0B, 0xCF, 0x49, 0x00, 0x00, 0x00, 0x00, +0x00, 0xF8, 0xF6, 0x2A, 0x3F, 0x68, 0xF5, 0x7A, 0x00, 0x04, 0xFF, 0xFD, 0x00, 0x02, 0x00, 0x00, +0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x0E, +0xFF, 0xFF, 0xFF, 0xCF, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xFF, 0xFF, 0xFF, 0x9C, +0x00, 0x00, 0x43, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, +0xFF, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* bank # 3 */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x24, 0x26, 0xD3, +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3C, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x9E, 0x65, 0x5D, +0x0C, 0x0A, 0x4E, 0x68, 0xCD, 0xCF, 0x77, 0x09, 0x50, 0x16, 0x67, 0x59, 0xC6, 0x19, 0xCE, 0x82, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x71, 0x1C, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xD7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, +0x00, 0x11, 0xDC, 0x47, 0x03, 0x00, 0x00, 0x00, 0xC7, 0x93, 0x8F, 0x9D, 0x1E, 0x1B, 0x1C, 0x19, +0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xDF, 0xA4, 0x38, 0x1F, 0x9E, 0x65, 0x5D, +0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x71, 0x1C, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x3F, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF4, 0xC9, 0xFF, 0xFF, 0xBC, 0xF0, 0x00, 0x01, 0x0C, 0x0F, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xF5, 0xB7, 0xBA, 0xB3, 0x67, 0x7D, 0xDF, 0x7E, 0x72, 0x90, 0x2E, 0x55, 0x4C, 0xF6, 0xE6, 0x88, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +/* bank # 4 */ +0xD8, 0xDC, 0xB4, 0xB8, 0xB0, 0xD8, 0xB9, 0xAB, 0xF3, 0xF8, 0xFA, 0xB3, 0xB7, 0xBB, 0x8E, 0x9E, +0xAE, 0xF1, 0x32, 0xF5, 0x1B, 0xF1, 0xB4, 0xB8, 0xB0, 0x80, 0x97, 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, +0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0x4C, 0xCD, 0x6C, 0xA9, 0x0C, 0xC9, 0x2C, 0x97, 0xF1, 0xA9, +0x89, 0x26, 0x46, 0x66, 0xB2, 0x89, 0x99, 0xA9, 0x2D, 0x55, 0x7D, 0xB0, 0xB0, 0x8A, 0xA8, 0x96, +0x36, 0x56, 0x76, 0xF1, 0xBA, 0xA3, 0xB4, 0xB2, 0x80, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB2, 0x83, +0x98, 0xBA, 0xA3, 0xF0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xB2, 0xB9, 0xB4, 0x98, 0x83, 0xF1, +0xA3, 0x29, 0x55, 0x7D, 0xBA, 0xB5, 0xB1, 0xA3, 0x83, 0x93, 0xF0, 0x00, 0x28, 0x50, 0xF5, 0xB2, +0xB6, 0xAA, 0x83, 0x93, 0x28, 0x54, 0x7C, 0xF1, 0xB9, 0xA3, 0x82, 0x93, 0x61, 0xBA, 0xA2, 0xDA, +0xDE, 0xDF, 0xDB, 0x81, 0x9A, 0xB9, 0xAE, 0xF5, 0x60, 0x68, 0x70, 0xF1, 0xDA, 0xBA, 0xA2, 0xDF, +0xD9, 0xBA, 0xA2, 0xFA, 0xB9, 0xA3, 0x82, 0x92, 0xDB, 0x31, 0xBA, 0xA2, 0xD9, 0xBA, 0xA2, 0xF8, +0xDF, 0x85, 0xA4, 0xD0, 0xC1, 0xBB, 0xAD, 0x83, 0xC2, 0xC5, 0xC7, 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, +0xBA, 0xA0, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xAA, 0xB3, 0x8D, 0xB4, 0x98, 0x0D, 0x35, +0x5D, 0xB2, 0xB6, 0xBA, 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, +0xB8, 0xAA, 0x87, 0x2C, 0x54, 0x7C, 0xBA, 0xA4, 0xB0, 0x8A, 0xB6, 0x91, 0x32, 0x56, 0x76, 0xB2, +0x84, 0x94, 0xA4, 0xC8, 0x08, 0xCD, 0xD8, 0xB8, 0xB4, 0xB0, 0xF1, 0x99, 0x82, 0xA8, 0x2D, 0x55, +0x7D, 0x98, 0xA8, 0x0E, 0x16, 0x1E, 0xA2, 0x2C, 0x54, 0x7C, 0x92, 0xA4, 0xF0, 0x2C, 0x50, 0x78, +/* bank # 5 */ +0xF1, 0x84, 0xA8, 0x98, 0xC4, 0xCD, 0xFC, 0xD8, 0x0D, 0xDB, 0xA8, 0xFC, 0x2D, 0xF3, 0xD9, 0xBA, +0xA6, 0xF8, 0xDA, 0xBA, 0xA6, 0xDE, 0xD8, 0xBA, 0xB2, 0xB6, 0x86, 0x96, 0xA6, 0xD0, 0xF3, 0xC8, +0x41, 0xDA, 0xA6, 0xC8, 0xF8, 0xD8, 0xB0, 0xB4, 0xB8, 0x82, 0xA8, 0x92, 0xF5, 0x2C, 0x54, 0x88, +0x98, 0xF1, 0x35, 0xD9, 0xF4, 0x18, 0xD8, 0xF1, 0xA2, 0xD0, 0xF8, 0xF9, 0xA8, 0x84, 0xD9, 0xC7, +0xDF, 0xF8, 0xF8, 0x83, 0xC5, 0xDA, 0xDF, 0x69, 0xDF, 0x83, 0xC1, 0xD8, 0xF4, 0x01, 0x14, 0xF1, +0xA8, 0x82, 0x4E, 0xA8, 0x84, 0xF3, 0x11, 0xD1, 0x82, 0xF5, 0xD9, 0x92, 0x28, 0x97, 0x88, 0xF1, +0x09, 0xF4, 0x1C, 0x1C, 0xD8, 0x84, 0xA8, 0xF3, 0xC0, 0xF9, 0xD1, 0xD9, 0x97, 0x82, 0xF1, 0x29, +0xF4, 0x0D, 0xD8, 0xF3, 0xF9, 0xF9, 0xD1, 0xD9, 0x82, 0xF4, 0xC2, 0x03, 0xD8, 0xDE, 0xDF, 0x1A, +0xD8, 0xF1, 0xA2, 0xFA, 0xF9, 0xA8, 0x84, 0x98, 0xD9, 0xC7, 0xDF, 0xF8, 0xF8, 0xF8, 0x83, 0xC7, +0xDA, 0xDF, 0x69, 0xDF, 0xF8, 0x83, 0xC3, 0xD8, 0xF4, 0x01, 0x14, 0xF1, 0x98, 0xA8, 0x82, 0x2E, +0xA8, 0x84, 0xF3, 0x11, 0xD1, 0x82, 0xF5, 0xD9, 0x92, 0x50, 0x97, 0x88, 0xF1, 0x09, 0xF4, 0x1C, +0xD8, 0x84, 0xA8, 0xF3, 0xC0, 0xF8, 0xF9, 0xD1, 0xD9, 0x97, 0x82, 0xF1, 0x49, 0xF4, 0x0D, 0xD8, +0xF3, 0xF9, 0xF9, 0xD1, 0xD9, 0x82, 0xF4, 0xC4, 0x03, 0xD8, 0xDE, 0xDF, 0xD8, 0xF1, 0xAD, 0x88, +0x98, 0xCC, 0xA8, 0x09, 0xF9, 0xD9, 0x82, 0x92, 0xA8, 0xF5, 0x7C, 0xF1, 0x88, 0x3A, 0xCF, 0x94, +0x4A, 0x6E, 0x98, 0xDB, 0x69, 0x31, 0xDA, 0xAD, 0xF2, 0xDE, 0xF9, 0xD8, 0x87, 0x95, 0xA8, 0xF2, +0x21, 0xD1, 0xDA, 0xA5, 0xF9, 0xF4, 0x17, 0xD9, 0xF1, 0xAE, 0x8E, 0xD0, 0xC0, 0xC3, 0xAE, 0x82, +/* bank # 6 */ +0xC6, 0x84, 0xC3, 0xA8, 0x85, 0x95, 0xC8, 0xA5, 0x88, 0xF2, 0xC0, 0xF1, 0xF4, 0x01, 0x0E, 0xF1, +0x8E, 0x9E, 0xA8, 0xC6, 0x3E, 0x56, 0xF5, 0x54, 0xF1, 0x88, 0x72, 0xF4, 0x01, 0x15, 0xF1, 0x98, +0x45, 0x85, 0x6E, 0xF5, 0x8E, 0x9E, 0x04, 0x88, 0xF1, 0x42, 0x98, 0x5A, 0x8E, 0x9E, 0x06, 0x88, +0x69, 0xF4, 0x01, 0x1C, 0xF1, 0x98, 0x1E, 0x11, 0x08, 0xD0, 0xF5, 0x04, 0xF1, 0x1E, 0x97, 0x02, +0x02, 0x98, 0x36, 0x25, 0xDB, 0xF9, 0xD9, 0x85, 0xA5, 0xF3, 0xC1, 0xDA, 0x85, 0xA5, 0xF3, 0xDF, +0xD8, 0x85, 0x95, 0xA8, 0xF3, 0x09, 0xDA, 0xA5, 0xFA, 0xD8, 0x82, 0x92, 0xA8, 0xF5, 0x78, 0xF1, +0x88, 0x1A, 0x84, 0x9F, 0x26, 0x88, 0x98, 0x21, 0xDA, 0xF4, 0x1D, 0xF3, 0xD8, 0x87, 0x9F, 0x39, +0xD1, 0xAF, 0xD9, 0xDF, 0xDF, 0xFB, 0xF9, 0xF4, 0x0C, 0xF3, 0xD8, 0xFA, 0xD0, 0xF8, 0xDA, 0xF9, +0xF9, 0xD0, 0xDF, 0xD9, 0xF9, 0xD8, 0xF4, 0x0B, 0xD8, 0xF3, 0x87, 0x9F, 0x39, 0xD1, 0xAF, 0xD9, +0xDF, 0xDF, 0xF4, 0x1D, 0xF3, 0xD8, 0xFA, 0xFC, 0xA8, 0x69, 0xF9, 0xF9, 0xAF, 0xD0, 0xDA, 0xDE, +0xFA, 0xD9, 0xF8, 0x8F, 0x9F, 0xA8, 0xF1, 0xCC, 0xF3, 0x98, 0xDB, 0x45, 0xD9, 0xAF, 0xDF, 0xD0, +0xF8, 0xD8, 0xF1, 0x8F, 0x9F, 0xA8, 0xCA, 0xF3, 0x88, 0x09, 0xDA, 0xAF, 0x8F, 0xCB, 0xF8, 0xD8, +0xF2, 0xAD, 0x97, 0x8D, 0x0C, 0xD9, 0xA5, 0xDF, 0xF9, 0xBA, 0xA6, 0xF3, 0xFA, 0xF4, 0x12, 0xF2, +0xD8, 0x95, 0x0D, 0xD1, 0xD9, 0xBA, 0xA6, 0xF3, 0xFA, 0xDA, 0xA5, 0xF2, 0xC1, 0xBA, 0xA6, 0xF3, +0xDF, 0xD8, 0xF1, 0xBA, 0xB2, 0xB6, 0x86, 0x96, 0xA6, 0xD0, 0xCA, 0xF3, 0x49, 0xDA, 0xA6, 0xCB, +0xF8, 0xD8, 0xB0, 0xB4, 0xB8, 0xD8, 0xAD, 0x84, 0xF2, 0xC0, 0xDF, 0xF1, 0x8F, 0xCB, 0xC3, 0xA8, +/* bank # 7 */ +0xB2, 0xB6, 0x86, 0x96, 0xC8, 0xC1, 0xCB, 0xC3, 0xF3, 0xB0, 0xB4, 0x88, 0x98, 0xA8, 0x21, 0xDB, +0x71, 0x8D, 0x9D, 0x71, 0x85, 0x95, 0x21, 0xD9, 0xAD, 0xF2, 0xFA, 0xD8, 0x85, 0x97, 0xA8, 0x28, +0xD9, 0xF4, 0x08, 0xD8, 0xF2, 0x8D, 0x29, 0xDA, 0xF4, 0x05, 0xD9, 0xF2, 0x85, 0xA4, 0xC2, 0xF2, +0xD8, 0xA8, 0x8D, 0x94, 0x01, 0xD1, 0xD9, 0xF4, 0x11, 0xF2, 0xD8, 0x87, 0x21, 0xD8, 0xF4, 0x0A, +0xD8, 0xF2, 0x84, 0x98, 0xA8, 0xC8, 0x01, 0xD1, 0xD9, 0xF4, 0x11, 0xD8, 0xF3, 0xA4, 0xC8, 0xBB, +0xAF, 0xD0, 0xF2, 0xDE, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xD8, 0xF1, 0xB8, 0xF6, +0xB5, 0xB9, 0xB0, 0x8A, 0x95, 0xA3, 0xDE, 0x3C, 0xA3, 0xD9, 0xF8, 0xD8, 0x5C, 0xA3, 0xD9, 0xF8, +0xD8, 0x7C, 0xA3, 0xD9, 0xF8, 0xD8, 0xF8, 0xF9, 0xD1, 0xA5, 0xD9, 0xDF, 0xDA, 0xFA, 0xD8, 0xB1, +0x85, 0x30, 0xF7, 0xD9, 0xDE, 0xD8, 0xF8, 0x30, 0xAD, 0xDA, 0xDE, 0xD8, 0xF2, 0xB4, 0x8C, 0x99, +0xA3, 0x2D, 0x55, 0x7D, 0xA0, 0x83, 0xDF, 0xDF, 0xDF, 0xB5, 0x91, 0xA0, 0xF6, 0x29, 0xD9, 0xFB, +0xD8, 0xA0, 0xFC, 0x29, 0xD9, 0xFA, 0xD8, 0xA0, 0xD0, 0x51, 0xD9, 0xF8, 0xD8, 0xFC, 0x51, 0xD9, +0xF9, 0xD8, 0x79, 0xD9, 0xFB, 0xD8, 0xA0, 0xD0, 0xFC, 0x79, 0xD9, 0xFA, 0xD8, 0xA1, 0xF9, 0xF9, +0xF9, 0xF9, 0xF9, 0xA0, 0xDA, 0xDF, 0xDF, 0xDF, 0xD8, 0xA1, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xAC, +0xDE, 0xF8, 0xAD, 0xDE, 0x83, 0x93, 0xAC, 0x2C, 0x54, 0x7C, 0xF1, 0xA8, 0xDF, 0xDF, 0xDF, 0xF6, +0x9D, 0x2C, 0xDA, 0xA0, 0xDF, 0xD9, 0xFA, 0xDB, 0x2D, 0xF8, 0xD8, 0xA8, 0x50, 0xDA, 0xA0, 0xD0, +0xDE, 0xD9, 0xD0, 0xF8, 0xF8, 0xF8, 0xDB, 0x55, 0xF8, 0xD8, 0xA8, 0x78, 0xDA, 0xA0, 0xD0, 0xDF, +/* bank # 8 */ +0xD9, 0xD0, 0xFA, 0xF8, 0xF8, 0xF8, 0xF8, 0xDB, 0x7D, 0xF8, 0xD8, 0x9C, 0xA8, 0x8C, 0xF5, 0x30, +0xDB, 0x38, 0xD9, 0xD0, 0xDE, 0xDF, 0xA0, 0xD0, 0xDE, 0xDF, 0xD8, 0xA8, 0x48, 0xDB, 0x58, 0xD9, +0xDF, 0xD0, 0xDE, 0xA0, 0xDF, 0xD0, 0xDE, 0xD8, 0xA8, 0x68, 0xDB, 0x70, 0xD9, 0xDF, 0xDF, 0xA0, +0xDF, 0xDF, 0xD8, 0xF1, 0xA8, 0x88, 0x90, 0x2C, 0x54, 0x7C, 0x98, 0xA8, 0xD0, 0x5C, 0x38, 0xD1, +0xDA, 0xF2, 0xAE, 0x8C, 0xDF, 0xF9, 0xD8, 0xB0, 0x87, 0xA8, 0xC1, 0xC1, 0xB1, 0x88, 0xA8, 0xC6, +0xF9, 0xF9, 0xDA, 0x36, 0xD8, 0xA8, 0xF9, 0xDA, 0x36, 0xD8, 0xA8, 0xF9, 0xDA, 0x36, 0xD8, 0xA8, +0xF9, 0xDA, 0x36, 0xD8, 0xA8, 0xF9, 0xDA, 0x36, 0xD8, 0xF7, 0x8D, 0x9D, 0xAD, 0xF8, 0x18, 0xDA, +0xF2, 0xAE, 0xDF, 0xD8, 0xF7, 0xAD, 0xFA, 0x30, 0xD9, 0xA4, 0xDE, 0xF9, 0xD8, 0xF2, 0xAE, 0xDE, +0xFA, 0xF9, 0x83, 0xA7, 0xD9, 0xC3, 0xC5, 0xC7, 0xF1, 0x88, 0x9B, 0xA7, 0x7A, 0xAD, 0xF7, 0xDE, +0xDF, 0xA4, 0xF8, 0x84, 0x94, 0x08, 0xA7, 0x97, 0xF3, 0x00, 0xAE, 0xF2, 0x98, 0x19, 0xA4, 0x88, +0xC6, 0xA3, 0x94, 0x88, 0xF6, 0x32, 0xDF, 0xF2, 0x83, 0x93, 0xDB, 0x09, 0xD9, 0xF2, 0xAA, 0xDF, +0xD8, 0xD8, 0xAE, 0xF8, 0xF9, 0xD1, 0xDA, 0xF3, 0xA4, 0xDE, 0xA7, 0xF1, 0x88, 0x9B, 0x7A, 0xD8, +0xF3, 0x84, 0x94, 0xAE, 0x19, 0xF9, 0xDA, 0xAA, 0xF1, 0xDF, 0xD8, 0xA8, 0x81, 0xC0, 0xC3, 0xC5, +0xC7, 0xA3, 0x92, 0x83, 0xF6, 0x28, 0xAD, 0xDE, 0xD9, 0xF8, 0xD8, 0xA3, 0x50, 0xAD, 0xD9, 0xF8, +0xD8, 0xA3, 0x78, 0xAD, 0xD9, 0xF8, 0xD8, 0xF8, 0xF9, 0xD1, 0xA1, 0xDA, 0xDE, 0xC3, 0xC5, 0xC7, +0xD8, 0xA1, 0x81, 0x94, 0xF8, 0x18, 0xF2, 0xB0, 0x89, 0xAC, 0xC3, 0xC5, 0xC7, 0xF1, 0xD8, 0xB8, +/* bank # 9 */ +0xB4, 0xB0, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, 0x28, 0x88, 0x9B, 0xF0, +0x0C, 0x20, 0x14, 0x40, 0xB0, 0xB4, 0xB8, 0xF0, 0xA8, 0x8A, 0x9A, 0x28, 0x50, 0x78, 0xB7, 0x9B, +0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xF1, 0xBB, 0xAB, +0x88, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0xB3, 0x8B, 0xB8, 0xA8, 0x04, 0x28, 0x50, 0x78, 0xF1, 0xB0, +0x88, 0xB4, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xBB, 0xAB, 0xB3, 0x8B, 0x02, 0x26, 0x46, 0x66, 0xB0, +0xB8, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79, 0x8A, 0x24, 0x70, 0x59, +0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68, 0x8A, 0x64, 0x48, 0x31, +0x8B, 0x30, 0x49, 0x60, 0x88, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04, 0x28, +0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66, 0xF0, +0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xA9, +0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60, 0x8C, +0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76, 0x7E, +0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, 0xB5, 0xB9, 0xA3, 0xDF, 0xDF, 0xDF, 0xAE, 0xD0, +0xDF, 0xAA, 0xD0, 0xDE, 0xF2, 0xAB, 0xF8, 0xF9, 0xD9, 0xB0, 0x87, 0xC4, 0xAA, 0xF1, 0xDF, 0xDF, +0xBB, 0xAF, 0xDF, 0xDF, 0xB9, 0xD8, 0xB1, 0xF1, 0xA3, 0x97, 0x8E, 0x60, 0xDF, 0xB0, 0x84, 0xF2, +0xC8, 0xF8, 0xF9, 0xD9, 0xDE, 0xD8, 0x93, 0x85, 0xF1, 0x4A, 0xB1, 0x83, 0xA3, 0x08, 0xB5, 0x83, +/* bank # 10 */ +0x9A, 0x08, 0x10, 0xB7, 0x9F, 0x10, 0xD8, 0xF1, 0xB0, 0xBA, 0xAE, 0xB0, 0x8A, 0xC2, 0xB2, 0xB6, +0x8E, 0x9E, 0xF1, 0xFB, 0xD9, 0xF4, 0x1D, 0xD8, 0xF9, 0xD9, 0x0C, 0xF1, 0xD8, 0xF8, 0xF8, 0xAD, +0x61, 0xD9, 0xAE, 0xFB, 0xD8, 0xF4, 0x0C, 0xF1, 0xD8, 0xF8, 0xF8, 0xAD, 0x19, 0xD9, 0xAE, 0xFB, +0xDF, 0xD8, 0xF4, 0x16, 0xF1, 0xD8, 0xF8, 0xAD, 0x8D, 0x61, 0xD9, 0xF4, 0xF4, 0xAC, 0xF5, 0x9C, +0x9C, 0x8D, 0xDF, 0x2B, 0xBA, 0xB6, 0xAE, 0xFA, 0xF8, 0xF4, 0x0B, 0xD8, 0xF1, 0xAE, 0xD0, 0xF8, +0xAD, 0x51, 0xDA, 0xAE, 0xFA, 0xF8, 0xF1, 0xD8, 0xB9, 0xB1, 0xB6, 0xA3, 0x83, 0x9C, 0x08, 0xB9, +0xB1, 0x83, 0x9A, 0xB5, 0xAA, 0xC0, 0xFD, 0x30, 0x83, 0xB7, 0x9F, 0x10, 0xB5, 0x8B, 0x93, 0xF2, +0x02, 0x02, 0xD1, 0xAB, 0xDA, 0xDE, 0xD8, 0xF1, 0xB0, 0x80, 0xBA, 0xAB, 0xC0, 0xC3, 0xB2, 0x84, +0xC1, 0xC3, 0xD8, 0xB1, 0xB9, 0xF3, 0x8B, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xB0, +0x87, 0x9C, 0xB9, 0xA3, 0xDD, 0xF1, 0xB3, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0xB0, 0x87, 0x20, 0x28, +0x30, 0x38, 0xB2, 0x8B, 0xB6, 0x9B, 0xF2, 0xA3, 0xC0, 0xC8, 0xC2, 0xC4, 0xCC, 0xC6, 0xA3, 0xA3, +0xA3, 0xF1, 0xB0, 0x87, 0xB5, 0x9A, 0xD8, 0xF3, 0x9B, 0xA3, 0xA3, 0xDC, 0xBA, 0xAC, 0xDF, 0xB9, //Reverted back as packet size changes causing isues... TODO:change 2742 from 0xD8 to 0x20 Including the DMP_FEATURE_TAP -- known issue in which if you do not enable DMP_FEATURE_TAP then the interrupts will be at 200Hz even if fifo rate +0xA3, 0xFE, 0xF2, 0xAB, 0xC4, 0xAA, 0xF1, 0xDF, 0xDF, 0xBB, 0xAF, 0xDF, 0xDF, 0xA3, 0xA3, 0xA3, +0xD8, 0xD8, 0xD8, 0xBB, 0xB3, 0xB7, 0xF1, 0xAA, 0xF9, 0xDA, 0xFF, 0xD9, 0x80, 0x9A, 0xAA, 0x28, +0xB4, 0x80, 0x98, 0xA7, 0x20, 0xB7, 0x97, 0x87, 0xA8, 0x66, 0x88, 0xF0, 0x79, 0x51, 0xF1, 0x90, +0x2C, 0x87, 0x0C, 0xA7, 0x81, 0x97, 0x62, 0x93, 0xF0, 0x71, 0x71, 0x60, 0x85, 0x94, 0x01, 0x29, +/* bank # 11 */ +0x51, 0x79, 0x90, 0xA5, 0xF1, 0x28, 0x4C, 0x6C, 0x87, 0x0C, 0x95, 0x18, 0x85, 0x78, 0xA3, 0x83, +0x90, 0x28, 0x4C, 0x6C, 0x88, 0x6C, 0xD8, 0xF3, 0xA2, 0x82, 0x00, 0xF2, 0x10, 0xA8, 0x92, 0x19, +0x80, 0xA2, 0xF2, 0xD9, 0x26, 0xD8, 0xF1, 0x88, 0xA8, 0x4D, 0xD9, 0x48, 0xD8, 0x96, 0xA8, 0x39, +0x80, 0xD9, 0x3C, 0xD8, 0x95, 0x80, 0xA8, 0x39, 0xA6, 0x86, 0x98, 0xD9, 0x2C, 0xDA, 0x87, 0xA7, +0x2C, 0xD8, 0xA8, 0x89, 0x95, 0x19, 0xA9, 0x80, 0xD9, 0x38, 0xD8, 0xA8, 0x89, 0x39, 0xA9, 0x80, +0xDA, 0x3C, 0xD8, 0xA8, 0x2E, 0xA8, 0x39, 0x90, 0xD9, 0x0C, 0xD8, 0xA8, 0x95, 0x31, 0x98, 0xD9, +0x0C, 0xD8, 0xA8, 0x09, 0xD9, 0xFF, 0xD8, 0x01, 0xDA, 0xFF, 0xD8, 0x95, 0x39, 0xA9, 0xDA, 0x26, +0xFF, 0xD8, 0x90, 0xA8, 0x0D, 0x89, 0x99, 0xA8, 0x10, 0x80, 0x98, 0x21, 0xDA, 0x2E, 0xD8, 0x89, +0x99, 0xA8, 0x31, 0x80, 0xDA, 0x2E, 0xD8, 0xA8, 0x86, 0x96, 0x31, 0x80, 0xDA, 0x2E, 0xD8, 0xA8, +0x87, 0x31, 0x80, 0xDA, 0x2E, 0xD8, 0xA8, 0x82, 0x92, 0xF3, 0x41, 0x80, 0xF1, 0xD9, 0x2E, 0xD8, +0xA8, 0x82, 0xF3, 0x19, 0x80, 0xF1, 0xD9, 0x2E, 0xD8, 0x82, 0xAC, 0xF3, 0xC0, 0xA2, 0x80, 0x22, +0xF1, 0xA6, 0x2E, 0xA7, 0x2E, 0xA9, 0x22, 0x98, 0xA8, 0x29, 0xDA, 0xAC, 0xDE, 0xFF, 0xD8, 0xA2, +0xF2, 0x2A, 0xF1, 0xA9, 0x2E, 0x82, 0x92, 0xA8, 0xF2, 0x31, 0x80, 0xA6, 0x96, 0xF1, 0xD9, 0x00, +0xAC, 0x8C, 0x9C, 0x0C, 0x30, 0xAC, 0xDE, 0xD0, 0xDE, 0xFF, 0xD8, 0x8C, 0x9C, 0xAC, 0xD0, 0x10, +0xAC, 0xDE, 0x80, 0x92, 0xA2, 0xF2, 0x4C, 0x82, 0xA8, 0xF1, 0xCA, 0xF2, 0x35, 0xF1, 0x96, 0x88, +0xA6, 0xD9, 0x00, 0xD8, 0xF1, 0xFF, +}; + +// this is the most basic initialization I can create. with the intent that we access the register bytes as few times as needed to get the job done. +// for detailed descriptins of all registers and there purpose google "MPU-6000/MPU-6050 Register Map and Descriptions" +uint8_t MPU6050::dmpInitialize(uint8_t rateDivisor, uint8_t mpuAddr) { // Lets get it over with fast Write everything once and set it up necely + uint8_t val; + uint16_t ival; + // Reset procedure per instructions in the "MPU-6000/MPU-6050 Register Map and Descriptions" page 41 + I2Cdev::writeBit(devAddr,0x6B, 7, (val = 1), wireObj); //PWR_MGMT_1: reset with 100ms delay + delay(100); + I2Cdev::writeBits(devAddr,0x6A, 2, 3, (val = 0b111), wireObj); // full SIGNAL_PATH_RESET: with another 100ms delay + delay(100); + I2Cdev::writeBytes(devAddr,0x6B, 1, &(val = 0x01), wireObj); // 1000 0001 PWR_MGMT_1:Clock Source Select PLL_X_gyro + I2Cdev::writeBytes(devAddr,0x38, 1, &(val = 0x00), wireObj); // 0000 0000 INT_ENABLE: no Interrupt + I2Cdev::writeBytes(devAddr,0x23, 1, &(val = 0x00), wireObj); // 0000 0000 MPU FIFO_EN: (all off) Using DMP's FIFO instead + I2Cdev::writeBytes(devAddr,0x1C, 1, &(val = 0x00), wireObj); // 0000 0000 ACCEL_CONFIG: 0 = Accel Full Scale Select: 2g + I2Cdev::writeBytes(devAddr,0x37, 1, &(val = 0x80), wireObj); // 1001 0000 INT_PIN_CFG: ACTL The logic level for int pin is active low. and interrupt status bits are cleared on any read + I2Cdev::writeBytes(devAddr,0x6B, 1, &(val = 0x01), wireObj); // 0000 0001 PWR_MGMT_1: Clock Source Select PLL_X_gyro + I2Cdev::writeBytes(devAddr,0x19, 1, &(val = rateDivisor), wireObj); // 0000 0100 SMPLRT_DIV: Divides the internal sample rate 400Hz ( Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV)) + I2Cdev::writeBytes(devAddr,0x1A, 1, &(val = 0x01), wireObj); // 0000 0001 CONFIG: Digital Low Pass Filter (DLPF) Configuration 188HZ //Im betting this will be the beat + if (!writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) return 1; // Loads the DMP image into the MPU6050 Memory // Should Never Fail + I2Cdev::writeWords(devAddr, 0x70, 1, &(ival = 0x0400), wireObj); // DMP Program Start Address + I2Cdev::writeBytes(devAddr,0x1B, 1, &(val = 0x18), wireObj); // 0001 1000 GYRO_CONFIG: 3 = +2000 Deg/sec + I2Cdev::writeBytes(devAddr,0x6A, 1, &(val = 0xC0), wireObj); // 1100 1100 USER_CTRL: Enable Fifo and Reset Fifo + I2Cdev::writeBytes(devAddr,0x38, 1, &(val = 0x02), wireObj); // 0000 0010 INT_ENABLE: RAW_DMP_INT_EN on + I2Cdev::writeBit(devAddr,0x6A, 2, 1, wireObj); // Reset FIFO one last time just for kicks. (MPUi2cWrite reads 0x6A first and only alters 1 bit and then saves the byte) + + setDMPEnabled(false); // disable DMP for compatibility with the MPU6050 library +/* + dmpPacketSize += 16;//DMP_FEATURE_6X_LP_QUAT + dmpPacketSize += 6;//DMP_FEATURE_SEND_RAW_ACCEL + dmpPacketSize += 6;//DMP_FEATURE_SEND_RAW_GYRO +*/ + dmpPacketSize = 28; + return 0; +} + +bool MPU6050::dmpPacketAvailable() { + return getFIFOCount() >= dmpGetFIFOPacketSize(); +} + +// uint8_t MPU6050::dmpSetFIFORate(uint8_t fifoRate); +// uint8_t MPU6050::dmpGetFIFORate(); +// uint8_t MPU6050::dmpGetSampleStepSizeMS(); +// uint8_t MPU6050::dmpGetSampleFrequency(); +// int32_t MPU6050::dmpDecodeTemperature(int8_t tempReg); + +//uint8_t MPU6050::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); +//uint8_t MPU6050::dmpUnregisterFIFORateProcess(inv_obj_func func); +//uint8_t MPU6050::dmpRunFIFORateProcesses(); + +// uint8_t MPU6050::dmpSendQuaternion(uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendPacketNumber(uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); + +uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((uint32_t)packet[16] << 8) | packet[17]); + data[1] = (((uint32_t)packet[18] << 8) | packet[19]); + data[2] = (((uint32_t)packet[20] << 8) | packet[21]); + return 0; +} +uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (packet[16] << 8) | packet[17]; + data[1] = (packet[18] << 8) | packet[19]; + data[2] = (packet[20] << 8) | packet[21]; + return 0; +} +uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + v -> x = (packet[16] << 8) | packet[17]; + v -> y = (packet[18] << 8) | packet[19]; + v -> z = (packet[20] << 8) | packet[21]; + return 0; +} +uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]); + data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]); + data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]); + data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]); + return 0; +} +uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = ((packet[0] << 8) | packet[1]); + data[1] = ((packet[4] << 8) | packet[5]); + data[2] = ((packet[8] << 8) | packet[9]); + data[3] = ((packet[12] << 8) | packet[13]); + return 0; +} +uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + int16_t qI[4]; + uint8_t status = dmpGetQuaternion(qI, packet); + if (status == 0) { + q -> w = (float)qI[0] / 16384.0f; + q -> x = (float)qI[1] / 16384.0f; + q -> y = (float)qI[2] / 16384.0f; + q -> z = (float)qI[3] / 16384.0f; + return 0; + } + return status; // int16 return value, indicates error if this line is reached +} +// uint8_t MPU6050::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); +uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((uint32_t)packet[22] << 8) | packet[23]); + data[1] = (((uint32_t)packet[24] << 8) | packet[25]); + data[2] = (((uint32_t)packet[26] << 8) | packet[27]); + return 0; +} +uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (packet[22] << 8) | packet[23]; + data[1] = (packet[24] << 8) | packet[25]; + data[2] = (packet[26] << 8) | packet[27]; + return 0; +} +uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + v -> x = (packet[22] << 8) | packet[23]; + v -> y = (packet[24] << 8) | packet[25]; + v -> z = (packet[26] << 8) | packet[27]; + return 0; +} +// uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef); +// uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet); +uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { + // get rid of the gravity component (+1g = +16384 in standard DMP FIFO packet, sensitivity is 2g) + v -> x = vRaw -> x - gravity -> x*16384; + v -> y = vRaw -> y - gravity -> y*16384; + v -> z = vRaw -> z - gravity -> z*16384; + return 0; +} +// uint8_t MPU6050::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); +uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { + // rotate measured 3D acceleration vector into original state + // frame of reference based on orientation quaternion + memcpy(v, vReal, sizeof(VectorInt16)); + v -> rotate(q); + return 0; +} +// uint8_t MPU6050::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetGyroSensor(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetControlData(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetTemperature(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetGravity(long *data, const uint8_t* packet); +uint8_t MPU6050::dmpGetGravity(int16_t *data, const uint8_t* packet) { + /* +1g corresponds to +16384, sensitivity is 2g. */ + int16_t qI[4]; + uint8_t status = dmpGetQuaternion(qI, packet); + data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384; + data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384; + data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1] + - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (int32_t)(2 * 16384L); + return status; +} + +uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) { + v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); + v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); + v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; + return 0; +} +// uint8_t MPU6050::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetQuantizedAccel(long *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); +// uint8_t MPU6050::dmpGetEIS(long *data, const uint8_t* packet); + +uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) { + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi + data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta + data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi + return 0; +} + +#ifdef USE_OLD_DMPGETYAWPITCHROLL +uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { + // yaw: (about Z axis) + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); + // pitch: (nose up/down, about Y axis) + data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); + // roll: (tilt left/right, about X axis) + data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); + return 0; +} +#else +uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { + // yaw: (about Z axis) + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); + // pitch: (nose up/down, about Y axis) + data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); + // roll: (tilt left/right, about X axis) + data[2] = atan2(gravity -> y , gravity -> z); + if (gravity -> z < 0) { + if(data[1] > 0) { + data[1] = PI - data[1]; + } else { + data[1] = -PI - data[1]; + } + } + return 0; +} +#endif + +// uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet); +// uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet); + +uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) { + (void)dmpData; // unused parameter + /*for (uint8_t k = 0; k < dmpPacketSize; k++) { + if (dmpData[k] < 0x10) Serial.print("0"); + Serial.print(dmpData[k], HEX); + Serial.print(" "); + } + Serial.print("\n");*/ + //Serial.println((uint16_t)dmpPacketBuffer); + return 0; +} +uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { + uint8_t status; + uint8_t buf[dmpPacketSize]; + for (uint8_t i = 0; i < numPackets; i++) { + // read packet from FIFO + getFIFOBytes(buf, dmpPacketSize); + + // process packet + if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; + + // increment external process count variable, if supplied + if (processed != 0) (*processed)++; + } + return 0; +} + +// uint8_t MPU6050::dmpSetFIFOProcessedCallback(void (*func) (void)); + +// uint8_t MPU6050::dmpInitFIFOParam(); +// uint8_t MPU6050::dmpCloseFIFO(); +// uint8_t MPU6050::dmpSetGyroDataSource(uint_fast8_t source); +// uint8_t MPU6050::dmpDecodeQuantizedAccel(); +// uint32_t MPU6050::dmpGetGyroSumOfSquare(); +// uint32_t MPU6050::dmpGetAccelSumOfSquare(); +// void MPU6050::dmpOverrideQuaternion(long *q); +uint16_t MPU6050::dmpGetFIFOPacketSize() { + return dmpPacketSize; +} + + + +uint8_t MPU6050::dmpGetCurrentFIFOPacket(uint8_t *data) { // overflow proof + return(GetCurrentFIFOPacket(data, dmpPacketSize)); +} diff --git a/lib/MPU6050/src/MPU6050_6Axis_MotionApps612.h b/lib/MPU6050/src/MPU6050_6Axis_MotionApps612.h new file mode 100644 index 0000000..a1b9526 --- /dev/null +++ b/lib/MPU6050/src/MPU6050_6Axis_MotionApps612.h @@ -0,0 +1,158 @@ +// I2Cdev library collection - MPU6050 I2C device class +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 10/3/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally +// ... - ongoing debug release + +// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE +// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF +// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#ifndef _MPU6050_6AXIS_MOTIONAPPS612_H_ +#define _MPU6050_6AXIS_MOTIONAPPS612_H_ + +// take ownership of the "MPU6050" typedef +#define I2CDEVLIB_MPU6050_TYPEDEF + +#include "MPU6050.h" + +// this divisor is pre configured into the above image and can't be modified at this time. +#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR +#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x01 // The New instance of the Firmware has this as the default +#endif + +class MPU6050_6Axis_MotionApps612 : public MPU6050_Base { + public: + MPU6050_6Axis_MotionApps612(uint8_t address=MPU6050_DEFAULT_ADDRESS, void *wireObj=0) : MPU6050_Base(address, wireObj) { } + + uint8_t dmpInitialize(uint8_t rateDivisor = MPU6050_DMP_FIFO_RATE_DIVISOR, uint8_t mpuAddr = 0x68); + bool dmpPacketAvailable(); + + uint8_t dmpSetFIFORate(uint8_t fifoRate); + uint8_t dmpGetFIFORate(); + uint8_t dmpGetSampleStepSizeMS(); + uint8_t dmpGetSampleFrequency(); + int32_t dmpDecodeTemperature(int8_t tempReg); + + // Register callbacks after a packet of FIFO data is processed + //uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); + //uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func); + uint8_t dmpRunFIFORateProcesses(); + + // Setup FIFO for various output + uint8_t dmpSendQuaternion(uint_fast16_t accuracy); + uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendPacketNumber(uint_fast16_t accuracy); + uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); + + // Get Fixed Point data from FIFO + uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpSetLinearAccelFilterCoefficient(float coef); + uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity); + uint8_t dmpGetLinearAccelInWorld(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccelInWorld(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q); + uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q); + uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0); + uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0); + + uint8_t dmpGetEuler(float *data, Quaternion *q); + uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity); + + // Get Floating Point data from FIFO + uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0); + + uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData); + uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL); + + uint8_t dmpSetFIFOProcessedCallback(void (*func) (void)); + + uint8_t dmpInitFIFOParam(); + uint8_t dmpCloseFIFO(); + uint8_t dmpSetGyroDataSource(uint8_t source); + uint8_t dmpDecodeQuantizedAccel(); + uint32_t dmpGetGyroSumOfSquare(); + uint32_t dmpGetAccelSumOfSquare(); + void dmpOverrideQuaternion(long *q); + uint16_t dmpGetFIFOPacketSize(); + uint8_t dmpGetCurrentFIFOPacket(uint8_t *data); // overflow proof + + private: + uint8_t *dmpPacketBuffer; + uint16_t dmpPacketSize; +}; + +typedef MPU6050_6Axis_MotionApps612 MPU6050; + +#endif /* _MPU6050_6AXIS_MOTIONAPPS612_H_ */ diff --git a/lib/MPU6050/src/MPU6050_9Axis_MotionApps41.cpp b/lib/MPU6050/src/MPU6050_9Axis_MotionApps41.cpp new file mode 100644 index 0000000..404d5a4 --- /dev/null +++ b/lib/MPU6050/src/MPU6050_9Axis_MotionApps41.cpp @@ -0,0 +1,902 @@ +// I2Cdev library collection - MPU6050 I2C device class, 9-axis MotionApps 4.1 implementation +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 6/18/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2021 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +// MotionApps 4.1 DMP implementation, built using the MPU-9150 "MotionFit" board +#define MPU6050_INCLUDE_DMP_MOTIONAPPS41 + +#include "MPU6050_9Axis_MotionApps41.h" + +// Tom Carpenter's conditional PROGMEM code +// http://forum.arduino.cc/index.php?topic=129407.0 +#ifdef __AVR__ + #include +#elif defined(ESP32) + #include +#else + // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen + #ifndef __PGMSPACE_H_ + #define __PGMSPACE_H_ 1 + #include + + #define PROGMEM + #define PGM_P const char * + #define PSTR(str) (str) + #define F(x) x + + typedef void prog_void; + typedef char prog_char; + //typedef unsigned char prog_uchar; + typedef int8_t prog_int8_t; + typedef uint8_t prog_uint8_t; + typedef int16_t prog_int16_t; + typedef uint16_t prog_uint16_t; + typedef int32_t prog_int32_t; + typedef uint32_t prog_uint32_t; + + #define strcpy_P(dest, src) strcpy((dest), (src)) + #define strcat_P(dest, src) strcat((dest), (src)) + #define strcmp_P(a, b) strcmp((a), (b)) + + #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) + #define pgm_read_word(addr) (*(const unsigned short *)(addr)) + #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) + #define pgm_read_float(addr) (*(const float *)(addr)) + + #define pgm_read_byte_near(addr) pgm_read_byte(addr) + #define pgm_read_word_near(addr) pgm_read_word(addr) + #define pgm_read_dword_near(addr) pgm_read_dword(addr) + #define pgm_read_float_near(addr) pgm_read_float(addr) + #define pgm_read_byte_far(addr) pgm_read_byte(addr) + #define pgm_read_word_far(addr) pgm_read_word(addr) + #define pgm_read_dword_far(addr) pgm_read_dword(addr) + #define pgm_read_float_far(addr) pgm_read_float(addr) + #endif +#endif + +// NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. +// Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) +// after moving string constants to flash memory storage using the F() +// compiler macro (Arduino IDE 1.0+ required). + +// #define DEBUG +/* Control whether debugging macros are active at compile time */ +#undef DB_ACTIVE +#ifdef DEBUG +#define DB_ACTIVE 1 +#else +#define DB_ACTIVE 0 +#endif /* DEBUG */ + +/* +** Usage: DB_PRINT((...)); +** Usage: DB_PRINTLN((...)); +** +** "..." is whatever extra arguments fmt requires (possibly nothing). +** +** The structure of the macros means that the code is always validated +** but is not called when DEBUG is undefined. +** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike. +*/ +#define DEBUG_PRINT(...)\ + do { if (DB_ACTIVE) Serial.print(__VA_ARGS__); } while (0) +#define DEBUG_PRINTF(...)\ + do { if (DB_ACTIVE) Serial.printf(__VA_ARGS__); } while (0) +#define DEBUG_PRINTLN(...)\ + do { if (DB_ACTIVE) Serial.println(__VA_ARGS__); } while (0) +#define DEBUG_PRINTLNF(x, y)\ + do { if (DB_ACTIVE) Serial.println(x, y); } while (0) + +#define MPU6050_DMP_CODE_SIZE 1962 // dmpMemory[] +#define MPU6050_DMP_CONFIG_SIZE 232 // dmpConfig[] +#define MPU6050_DMP_UPDATES_SIZE 140 // dmpUpdates[] + +/* ================================================================================================ * + | Default MotionApps v4.1 48-byte FIFO packet structure: | + | | + | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] | + | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | + | | + | [GYRO Z][ ][MAG X ][MAG Y ][MAG Z ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] | + | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | + * ================================================================================================ */ + +// this block of memory gets written to the MPU on start-up, and it seems +// to be volatile memory, so it has to be done each time (it only takes ~1 +// second though) +static const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { + // bank 0, 256 bytes + 0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01, + 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82, + 0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC, + 0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4, + 0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10, + + // bank 1, 256 bytes + 0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8, + 0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C, + 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C, + 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0, + + // bank 2, 256 bytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x78, 0xA2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + // bank 3, 256 bytes + 0xD8, 0xDC, 0xF4, 0xD8, 0xB9, 0xAB, 0xF3, 0xF8, 0xFA, 0xF1, 0xBA, 0xA2, 0xDE, 0xB2, 0xB8, 0xB4, + 0xA8, 0x81, 0x98, 0xF7, 0x4A, 0x90, 0x7F, 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, + 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2, 0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, + 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF, 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, + 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C, 0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, + 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, 0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, + 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01, 0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, + 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80, 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, + 0xF2, 0xAA, 0xC5, 0xCD, 0xC7, 0xA9, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, + 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80, 0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, + 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E, 0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, + 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9, 0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, + 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, + 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xF0, 0x00, 0x28, 0x50, 0xF5, 0xBA, 0xAD, 0x8F, 0x9F, 0x28, 0x54, + 0x7C, 0xB9, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xDB, 0xB2, 0xB6, 0x8E, 0x9D, + 0xAE, 0xF5, 0x60, 0x68, 0x70, 0xB1, 0xB5, 0xF1, 0xDA, 0xA6, 0xDF, 0xD9, 0xA6, 0xFA, 0xA3, 0x86, + + // bank 4, 256 bytes + 0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1, + 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86, + 0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA, + 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C, + 0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8, + 0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3, + 0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84, + 0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5, + 0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3, + 0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1, + 0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5, + 0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D, + 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, + 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D, + 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, + 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A, + + // bank 5, 256 bytes + 0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8, + 0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87, + 0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8, + 0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68, + 0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D, + 0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94, + 0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA, + 0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56, + 0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, + 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA, + 0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0x97, 0x86, + 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, 0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, + 0xB9, 0xA3, 0x8A, 0xC3, 0xC5, 0xC7, 0x9A, 0xA3, 0x28, 0x50, 0x78, 0xF1, 0xB5, 0x93, 0x01, 0xD9, + 0xDF, 0xDF, 0xDF, 0xD8, 0xB8, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04, 0x28, 0x51, 0x79, 0x1D, 0x30, + 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78, 0x78, 0x9B, 0xF1, 0x1A, 0xB0, + 0xF0, 0xB1, 0x83, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0xB0, 0x8B, 0x29, 0x51, 0x79, 0xB1, 0x83, 0x24, + + // bank 6, 256 bytes + 0x70, 0x59, 0xB0, 0x8B, 0x20, 0x58, 0x71, 0xB1, 0x83, 0x44, 0x69, 0x38, 0xB0, 0x8B, 0x39, 0x40, + 0x68, 0xB1, 0x83, 0x64, 0x48, 0x31, 0xB0, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, + 0x58, 0x44, 0x68, 0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, + 0x8C, 0xA8, 0x04, 0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, + 0x26, 0x46, 0x66, 0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, + 0x64, 0x48, 0x31, 0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, + 0x31, 0x48, 0x60, 0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, + 0xA8, 0x6E, 0x76, 0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, + 0x6E, 0x8A, 0x56, 0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, + 0x9D, 0xB8, 0xAD, 0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, + 0x7D, 0x81, 0x91, 0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, + 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, + 0xD9, 0x04, 0xAE, 0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, + 0x81, 0xAD, 0xD9, 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, + 0xAD, 0xAD, 0xAD, 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, + 0xF3, 0xAC, 0x2E, 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, + + // bank 7, 170 bytes (remainder) + 0x30, 0x18, 0xA8, 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, + 0xF2, 0xB0, 0x89, 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, + 0xD8, 0xD8, 0x79, 0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, + 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, + 0x80, 0x25, 0xDA, 0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, + 0x3C, 0xF3, 0xAB, 0x8B, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xB0, 0x87, 0x9C, 0xB9, + 0xA3, 0xDD, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x95, 0xF1, 0xA3, 0xA3, 0xA3, 0x9D, 0xF1, 0xA3, 0xA3, + 0xA3, 0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, + 0xA3, 0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0xA3, 0xA3, + 0xA3, 0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0xA3, + 0xDC, 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF +}; + +#ifndef MPU6050_DMP_FIFO_RATE_DIVISOR +#define MPU6050_DMP_FIFO_RATE_DIVISOR 0x03 +#endif + +static const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = { +// BANK OFFSET LENGTH [DATA] + 0x02, 0xEC, 0x04, 0x00, 0x47, 0x7D, 0x1A, // ? + 0x03, 0x82, 0x03, 0x4C, 0xCD, 0x6C, // FCFG_1 inv_set_gyro_calibration + 0x03, 0xB2, 0x03, 0x36, 0x56, 0x76, // FCFG_3 inv_set_gyro_calibration + 0x00, 0x68, 0x04, 0x02, 0xCA, 0xE3, 0x09, // D_0_104 inv_set_gyro_calibration + 0x01, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, // D_1_152 inv_set_accel_calibration + 0x03, 0x86, 0x03, 0x0C, 0xC9, 0x2C, // FCFG_2 inv_set_accel_calibration + 0x03, 0x90, 0x03, 0x26, 0x46, 0x66, // (continued)...FCFG_2 inv_set_accel_calibration + 0x00, 0x6C, 0x02, 0x40, 0x00, // D_0_108 inv_set_accel_calibration + + 0x02, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_00 inv_set_compass_calibration + 0x02, 0x44, 0x04, 0x40, 0x00, 0x00, 0x00, // CPASS_MTX_01 + 0x02, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_02 + 0x02, 0x4C, 0x04, 0x40, 0x00, 0x00, 0x00, // CPASS_MTX_10 + 0x02, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_11 + 0x02, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_12 + 0x02, 0x58, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_20 + 0x02, 0x5C, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_21 + 0x02, 0xBC, 0x04, 0xC0, 0x00, 0x00, 0x00, // CPASS_MTX_22 + + 0x01, 0xEC, 0x04, 0x00, 0x00, 0x40, 0x00, // D_1_236 inv_apply_endian_accel + 0x03, 0x86, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, // FCFG_2 inv_set_mpu_sensors + 0x04, 0x22, 0x03, 0x0D, 0x35, 0x5D, // CFG_MOTION_BIAS inv_turn_on_bias_from_no_motion + 0x00, 0xA3, 0x01, 0x00, // ? + 0x04, 0x29, 0x04, 0x87, 0x2D, 0x35, 0x3D, // FCFG_5 inv_set_bias_update + 0x07, 0x62, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // CFG_8 inv_send_quaternion + 0x07, 0x9F, 0x01, 0x30, // CFG_16 inv_set_footer + 0x07, 0x67, 0x01, 0x9A, // CFG_GYRO_SOURCE inv_send_gyro + 0x07, 0x68, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_9 inv_send_gyro -> inv_construct3_fifo + 0x07, 0x62, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // ? + 0x02, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, // ? + 0x07, 0x83, 0x06, 0xC2, 0xCA, 0xC4, 0xA3, 0xA3, 0xA3, // ? + // SPECIAL 0x01 = enable interrupts + 0x00, 0x00, 0x00, 0x01, // SET INT_ENABLE, SPECIAL INSTRUCTION + 0x07, 0xA7, 0x01, 0xFE, // ? + 0x07, 0x62, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // ? + 0x07, 0x67, 0x01, 0x9A, // ? + 0x07, 0x68, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_12 inv_send_accel -> inv_construct3_fifo + 0x07, 0x8D, 0x04, 0xF1, 0x28, 0x30, 0x38, // ??? CFG_12 inv_send_mag -> inv_construct3_fifo + 0x02, 0x16, 0x02, 0x00, MPU6050_DMP_FIFO_RATE_DIVISOR // D_0_22 inv_set_fifo_rate + + // This very last 0x03 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz, + // 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data. + // DMP output frequency is calculated easily using this equation: (200Hz / (1 + value)) + + // It is important to make sure the host processor can keep up with reading and processing + // the FIFO output at the desired rate. Handling FIFO overflow cleanly is also a good idea. +}; + +const unsigned char dmpUpdates[MPU6050_DMP_UPDATES_SIZE] PROGMEM = { + 0x01, 0xB2, 0x02, 0xFF, 0xF5, + 0x01, 0x90, 0x04, 0x0A, 0x0D, 0x97, 0xC0, + 0x00, 0xA3, 0x01, 0x00, + 0x04, 0x29, 0x04, 0x87, 0x2D, 0x35, 0x3D, + 0x01, 0x6A, 0x02, 0x06, 0x00, + 0x01, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x02, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x08, 0x02, 0x01, 0x20, + 0x01, 0x0A, 0x02, 0x00, 0x4E, + 0x01, 0x02, 0x02, 0xFE, 0xB3, + 0x02, 0x6C, 0x04, 0x00, 0x00, 0x00, 0x00, // READ + 0x02, 0x6C, 0x04, 0xFA, 0xFE, 0x00, 0x00, + 0x02, 0x60, 0x0C, 0xFF, 0xFF, 0xCB, 0x4D, 0x00, 0x01, 0x08, 0xC1, 0xFF, 0xFF, 0xBC, 0x2C, + 0x02, 0xF4, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xF8, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xFC, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x04, 0x00, 0x40, 0x00, 0x00 +}; + +uint8_t MPU6050_9Axis_MotionApps41::dmpInitialize() { + // reset device + DEBUG_PRINTLN(F("\n\nResetting MPU6050...")); + reset(); + delay(30); // wait after reset + + // disable sleep mode + DEBUG_PRINTLN(F("Disabling sleep mode...")); + setSleepEnabled(false); + + // get MPU product ID + //DEBUG_PRINTLN(F("Getting product ID...")); + //uint8_t productID = 0; //getProductID(); + //DEBUG_PRINT(F("Product ID = ")); + //DEBUG_PRINT(productID); + + // get MPU hardware revision + DEBUG_PRINTLN(F("Selecting user bank 16...")); + setMemoryBank(0x10, true, true); + DEBUG_PRINTLN(F("Selecting memory byte 6...")); + setMemoryStartAddress(0x06); + DEBUG_PRINTLN(F("Checking hardware revision...")); + uint8_t hwRevision = readMemoryByte(); + (void)hwRevision; // suppress unused variable compile warning + DEBUG_PRINT(F("Revision @ user[16][6] = ")); + DEBUG_PRINTLNF(hwRevision, HEX); + DEBUG_PRINTLN(F("Resetting memory bank selection to 0...")); + setMemoryBank(0, false, false); + + // check OTP bank valid + DEBUG_PRINTLN(F("Reading OTP bank valid flag...")); + uint8_t otpValid = getOTPBankValid(); + (void)otpValid; // suppress unused variable compile warning + DEBUG_PRINT(F("OTP bank is ")); + DEBUG_PRINTLN(otpValid ? F("valid!") : F("invalid!")); + + // get X/Y/Z gyro offsets + DEBUG_PRINTLN(F("Reading gyro offset values...")); + int8_t xgOffset = getXGyroOffset(); + int8_t ygOffset = getYGyroOffset(); + int8_t zgOffset = getZGyroOffset(); + DEBUG_PRINT(F("X gyro offset = ")); + DEBUG_PRINTLN(xgOffset); + DEBUG_PRINT(F("Y gyro offset = ")); + DEBUG_PRINTLN(ygOffset); + DEBUG_PRINT(F("Z gyro offset = ")); + DEBUG_PRINTLN(zgOffset); + + I2Cdev::readByte(devAddr, MPU6050_RA_USER_CTRL, buffer, I2Cdev::readTimeout, wireObj); // ? + + DEBUG_PRINTLN(F("Enabling interrupt latch, clear on any read, AUX bypass enabled")); + I2Cdev::writeByte(devAddr, MPU6050_RA_INT_PIN_CFG, 0x32, wireObj); + + // enable MPU AUX I2C bypass mode + //DEBUG_PRINTLN(F("Enabling AUX I2C bypass mode...")); + //setI2CBypassEnabled(true); + + DEBUG_PRINTLN(F("Setting magnetometer mode to power-down...")); + //mag -> setMode(0); + I2Cdev::writeByte(0x0E, 0x0A, 0x00, wireObj); + + DEBUG_PRINTLN(F("Setting magnetometer mode to fuse access...")); + //mag -> setMode(0x0F); + I2Cdev::writeByte(0x0E, 0x0A, 0x0F, wireObj); + + DEBUG_PRINTLN(F("Reading mag magnetometer factory calibration...")); + int8_t asax, asay, asaz; + //mag -> getAdjustment(&asax, &asay, &asaz); + I2Cdev::readBytes(0x0E, 0x10, 3, buffer, I2Cdev::readTimeout, wireObj); + asax = (int8_t)buffer[0]; + asay = (int8_t)buffer[1]; + asaz = (int8_t)buffer[2]; + (void)asax; // suppress unused variable compiler warning + (void)asay; // suppress unused variable compiler warning + (void)asaz; // suppress unused variable compiler warning + DEBUG_PRINT(F("Adjustment X/Y/Z = ")); + DEBUG_PRINT(asax); + DEBUG_PRINT(F(" / ")); + DEBUG_PRINT(asay); + DEBUG_PRINT(F(" / ")); + DEBUG_PRINTLN(asaz); + + DEBUG_PRINTLN(F("Setting magnetometer mode to power-down...")); + //mag -> setMode(0); + I2Cdev::writeByte(0x0E, 0x0A, 0x00, wireObj); + + // load DMP code into memory banks + DEBUG_PRINT(F("Writing DMP code to MPU memory banks (")); + DEBUG_PRINT(MPU6050_DMP_CODE_SIZE); + DEBUG_PRINTLN(F(" bytes)")); + if (writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) { + DEBUG_PRINTLN(F("Success! DMP code written and verified.")); + + DEBUG_PRINTLN(F("Configuring DMP and related settings...")); + + // write DMP configuration + DEBUG_PRINT(F("Writing DMP configuration to MPU memory banks (")); + DEBUG_PRINT(MPU6050_DMP_CONFIG_SIZE); + DEBUG_PRINTLN(F(" bytes in config def)")); + if (writeProgDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE)) { + DEBUG_PRINTLN(F("Success! DMP configuration written and verified.")); + + DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled...")); + setIntEnabled(1< setMode(1); + I2Cdev::writeByte(0x0E, 0x0A, 0x01, wireObj); + + // setup AK8975 (0x0E) as Slave 0 in read mode + DEBUG_PRINTLN(F("Setting up AK8975 read slave 0...")); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV0_ADDR, 0x8E, wireObj); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV0_REG, 0x01, wireObj); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV0_CTRL, 0xDA, wireObj); + + // setup AK8975 (0x0E) as Slave 2 in write mode + DEBUG_PRINTLN(F("Setting up AK8975 write slave 2...")); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_ADDR, 0x0E, wireObj); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_REG, 0x0A, wireObj); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_CTRL, 0x81, wireObj); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV2_DO, 0x01, wireObj); + + // setup I2C timing/delay control + DEBUG_PRINTLN(F("Setting up slave access delay...")); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_SLV4_CTRL, 0x18, wireObj); + I2Cdev::writeByte(0x68, MPU6050_RA_I2C_MST_DELAY_CTRL, 0x05, wireObj); + + // enable interrupts + DEBUG_PRINTLN(F("Enabling default interrupt behavior/no bypass...")); + I2Cdev::writeByte(0x68, MPU6050_RA_INT_PIN_CFG, 0x00, wireObj); + + // enable I2C master mode and reset DMP/FIFO + DEBUG_PRINTLN(F("Enabling I2C master mode...")); + I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0x20, wireObj); + DEBUG_PRINTLN(F("Resetting FIFO...")); + I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0x24, wireObj); + DEBUG_PRINTLN(F("Rewriting I2C master mode enabled because...I don't know")); + I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0x20, wireObj); + DEBUG_PRINTLN(F("Enabling and resetting DMP/FIFO...")); + I2Cdev::writeByte(0x68, MPU6050_RA_USER_CTRL, 0xE8, wireObj); + + DEBUG_PRINTLN(F("Writing final memory update 5/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 6/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 7/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 8/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 9/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 10/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 11/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + + DEBUG_PRINTLN(F("Reading final memory update 12/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + #ifdef DEBUG + DEBUG_PRINT(F("Read bytes: ")); + for (j = 0; j < 4; j++) { + DEBUG_PRINT(dmpUpdate[3 + j], HEX); + DEBUG_PRINT(" "); + } + DEBUG_PRINTLN(""); + #endif + + DEBUG_PRINTLN(F("Writing final memory update 13/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 14/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 15/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 16/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + DEBUG_PRINTLN(F("Writing final memory update 17/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + + DEBUG_PRINTLN(F("Waiting for FIRO count >= 46...")); + while ((fifoCount = getFIFOCount()) < 46); + DEBUG_PRINTLN(F("Reading FIFO...")); + getFIFOBytes(fifoBuffer, (fifoCount < 128) ? fifoCount : 128); // safeguard only 128 bytes + DEBUG_PRINTLN(F("Reading interrupt status...")); + getIntStatus(); + + DEBUG_PRINTLN(F("Writing final memory update 18/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + + DEBUG_PRINTLN(F("Waiting for FIRO count >= 48...")); + while ((fifoCount = getFIFOCount()) < 48); + DEBUG_PRINTLN(F("Reading FIFO...")); + getFIFOBytes(fifoBuffer, (fifoCount < 128) ? fifoCount : 128); // safeguard only 128 bytes + DEBUG_PRINTLN(F("Reading interrupt status...")); + getIntStatus(); + DEBUG_PRINTLN(F("Waiting for FIRO count >= 48...")); + while ((fifoCount = getFIFOCount()) < 48); + DEBUG_PRINTLN(F("Reading FIFO...")); + getFIFOBytes(fifoBuffer, (fifoCount < 128) ? fifoCount : 128); // safeguard only 128 bytes + DEBUG_PRINTLN(F("Reading interrupt status...")); + getIntStatus(); + + DEBUG_PRINTLN(F("Writing final memory update 19/19 (function unknown)...")); + for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); + writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); + + DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)...")); + setDMPEnabled(false); + + DEBUG_PRINTLN(F("Setting up internal 48-byte (default) DMP packet buffer...")); + dmpPacketSize = 48; + /*if ((dmpPacketBuffer = (uint8_t *)malloc(42)) == 0) { + return 3; // TODO: proper error code for no memory + }*/ + + DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time...")); + resetFIFO(); + getIntStatus(); + } else { + DEBUG_PRINTLN(F("ERROR! DMP configuration verification failed.")); + return 2; // configuration block loading failed + } + } else { + DEBUG_PRINTLN(F("ERROR! DMP code verification failed.")); + return 1; // main binary block loading failed + } + return 0; // success +} + +bool MPU6050_9Axis_MotionApps41::dmpPacketAvailable() { + return getFIFOCount() >= dmpGetFIFOPacketSize(); +} + +// uint8_t MPU6050_9Axis_MotionApps41::dmpSetFIFORate(uint8_t fifoRate); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetFIFORate(); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetSampleStepSizeMS(); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetSampleFrequency(); +// int32_t MPU6050_9Axis_MotionApps41::dmpDecodeTemperature(int8_t tempReg); + +//uint8_t MPU6050_9Axis_MotionApps41::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); +//uint8_t MPU6050_9Axis_MotionApps41::dmpUnregisterFIFORateProcess(inv_obj_func func); +//uint8_t MPU6050_9Axis_MotionApps41::dmpRunFIFORateProcesses(); + +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendQuaternion(uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendPacketNumber(uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); + +uint8_t MPU6050_9Axis_MotionApps41::dmpGetAccel(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((uint32_t)packet[34] << 24) | ((uint32_t)packet[35] << 16) | ((uint32_t)packet[36] << 8) | packet[37]); + data[1] = (((uint32_t)packet[38] << 24) | ((uint32_t)packet[39] << 16) | ((uint32_t)packet[40] << 8) | packet[41]); + data[2] = (((uint32_t)packet[42] << 24) | ((uint32_t)packet[43] << 16) | ((uint32_t)packet[44] << 8) | packet[45]); + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetAccel(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (packet[34] << 8) | packet[35]; + data[1] = (packet[38] << 8) | packet[39]; + data[2] = (packet[42] << 8) | packet[43]; + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + v -> x = (packet[34] << 8) | packet[35]; + v -> y = (packet[38] << 8) | packet[39]; + v -> z = (packet[42] << 8) | packet[43]; + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]); + data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]); + data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]); + data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]); + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = ((packet[0] << 8) | packet[1]); + data[1] = ((packet[4] << 8) | packet[5]); + data[2] = ((packet[8] << 8) | packet[9]); + data[3] = ((packet[12] << 8) | packet[13]); + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + int16_t qI[4]; + uint8_t status = dmpGetQuaternion(qI, packet); + if (status == 0) { + q -> w = (float)qI[0] / 16384.0f; + q -> x = (float)qI[1] / 16384.0f; + q -> y = (float)qI[2] / 16384.0f; + q -> z = (float)qI[3] / 16384.0f; + return 0; + } + return status; // int16 return value, indicates error if this line is reached +} +// uint8_t MPU6050_9Axis_MotionApps41::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); +uint8_t MPU6050_9Axis_MotionApps41::dmpGetGyro(int32_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (((uint32_t)packet[16] << 24) | ((uint32_t)packet[17] << 16) | ((uint32_t)packet[18] << 8) | packet[19]); + data[1] = (((uint32_t)packet[20] << 24) | ((uint32_t)packet[21] << 16) | ((uint32_t)packet[22] << 8) | packet[23]); + data[2] = (((uint32_t)packet[24] << 24) | ((uint32_t)packet[25] << 16) | ((uint32_t)packet[26] << 8) | packet[27]); + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetGyro(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (packet[16] << 8) | packet[17]; + data[1] = (packet[20] << 8) | packet[21]; + data[2] = (packet[24] << 8) | packet[25]; + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpGetMag(int16_t *data, const uint8_t* packet) { + // TODO: accommodate different arrangements of sent data (ONLY default supported now) + if (packet == 0) packet = dmpPacketBuffer; + data[0] = (packet[28] << 8) | packet[29]; + data[1] = (packet[30] << 8) | packet[31]; + data[2] = (packet[32] << 8) | packet[33]; + return 0; +} +// uint8_t MPU6050_9Axis_MotionApps41::dmpSetLinearAccelFilterCoefficient(float coef); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetLinearAccel(long *data, const uint8_t* packet); +uint8_t MPU6050_9Axis_MotionApps41::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { + // get rid of the gravity component (+1g = +4096 in standard DMP FIFO packet) + v -> x = vRaw -> x - gravity -> x*4096; + v -> y = vRaw -> y - gravity -> y*4096; + v -> z = vRaw -> z - gravity -> z*4096; + return 0; +} +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); +uint8_t MPU6050_9Axis_MotionApps41::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { + // rotate measured 3D acceleration vector into original state + // frame of reference based on orientation quaternion + memcpy(v, vReal, sizeof(VectorInt16)); + v -> rotate(q); + return 0; +} +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetGyroSensor(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetControlData(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetTemperature(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetGravity(long *data, const uint8_t* packet); +uint8_t MPU6050_9Axis_MotionApps41::dmpGetGravity(int16_t *data, const uint8_t* packet) { + /* +1g corresponds to +8192, sensitivity is 2g. */ + int16_t qI[4]; + uint8_t status = dmpGetQuaternion(qI, packet); + data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384; + data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384; + data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1] + - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (int32_t)(2 * 16384L); + return status; +} + +uint8_t MPU6050_9Axis_MotionApps41::dmpGetGravity(VectorFloat *v, Quaternion *q) { + v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); + v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); + v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; + return 0; +} +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetQuantizedAccel(long *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetEIS(long *data, const uint8_t* packet); + +uint8_t MPU6050_9Axis_MotionApps41::dmpGetEuler(float *data, Quaternion *q) { + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi + data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta + data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi + return 0; +} + +#ifdef USE_OLD_DMPGETYAWPITCHROLL +uint8_t MPU6050_9Axis_MotionApps41::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { + // yaw: (about Z axis) + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); + // pitch: (nose up/down, about Y axis) + data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); + // roll: (tilt left/right, about X axis) + data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); + return 0; +} +#else +uint8_t MPU6050_9Axis_MotionApps41::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { + // yaw: (about Z axis) + data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); + // pitch: (nose up/down, about Y axis) + data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); + // roll: (tilt left/right, about X axis) + data[2] = atan2(gravity -> y , gravity -> z); + if(gravity->z<0) { + if(data[1]>0) { + data[1] = PI - data[1]; + } else { + data[1] = -PI - data[1]; + } + } + return 0; +} +#endif + +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetAccelFloat(float *data, const uint8_t* packet); +// uint8_t MPU6050_9Axis_MotionApps41::dmpGetQuaternionFloat(float *data, const uint8_t* packet); + +uint8_t MPU6050_9Axis_MotionApps41::dmpProcessFIFOPacket(const unsigned char *dmpData) { + (void)dmpData; // suppress unused variable compiler warning + /*for (uint8_t k = 0; k < dmpPacketSize; k++) { + if (dmpData[k] < 0x10) Serial.print("0"); + Serial.print(dmpData[k], HEX); + Serial.print(" "); + } + Serial.print("\n");*/ + //Serial.println((uint16_t)dmpPacketBuffer); + return 0; +} +uint8_t MPU6050_9Axis_MotionApps41::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { + uint8_t status; + uint8_t buf[dmpPacketSize]; + for (uint8_t i = 0; i < numPackets; i++) { + // read packet from FIFO + getFIFOBytes(buf, dmpPacketSize); + + // process packet + if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; + + // increment external process count variable, if supplied + if (processed != 0) (*processed)++; + } + return 0; +} + +// uint8_t MPU6050_9Axis_MotionApps41::dmpSetFIFOProcessedCallback(void (*func) (void)); + +// uint8_t MPU6050_9Axis_MotionApps41::dmpInitFIFOParam(); +// uint8_t MPU6050_9Axis_MotionApps41::dmpCloseFIFO(); +// uint8_t MPU6050_9Axis_MotionApps41::dmpSetGyroDataSource(uint_fast8_t source); +// uint8_t MPU6050_9Axis_MotionApps41::dmpDecodeQuantizedAccel(); +// uint32_t MPU6050_9Axis_MotionApps41::dmpGetGyroSumOfSquare(); +// uint32_t MPU6050_9Axis_MotionApps41::dmpGetAccelSumOfSquare(); +// void MPU6050_9Axis_MotionApps41::dmpOverrideQuaternion(long *q); +uint16_t MPU6050_9Axis_MotionApps41::dmpGetFIFOPacketSize() { + return dmpPacketSize; +} \ No newline at end of file diff --git a/lib/MPU6050/src/MPU6050_9Axis_MotionApps41.h b/lib/MPU6050/src/MPU6050_9Axis_MotionApps41.h new file mode 100644 index 0000000..f9569e9 --- /dev/null +++ b/lib/MPU6050/src/MPU6050_9Axis_MotionApps41.h @@ -0,0 +1,153 @@ +// I2Cdev library collection - MPU6050 I2C device class +// Based on InvenSense MPU-6050 register map document rev. 2.0, 5/19/2011 (RM-MPU-6000A-00) +// 10/3/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2021/09/27 - split implementations out of header files, finally +// ... - ongoing debug release + +// NOTE: THIS IS ONLY A PARIAL RELEASE. THIS DEVICE CLASS IS CURRENTLY UNDERGOING ACTIVE +// DEVELOPMENT AND IS STILL MISSING SOME IMPORTANT FEATURES. PLEASE KEEP THIS IN MIND IF +// YOU DECIDE TO USE THIS PARTICULAR CODE FOR ANYTHING. + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#ifndef _MPU6050_6AXIS_MOTIONAPPS41_H_ +#define _MPU6050_6AXIS_MOTIONAPPS41_H_ + +// take ownership of the "MPU6050" typedef +#define I2CDEVLIB_MPU6050_TYPEDEF + +#include "MPU6050.h" + +class MPU6050_9Axis_MotionApps41 : public MPU6050_Base { + public: + MPU6050_9Axis_MotionApps41(uint8_t address=MPU6050_DEFAULT_ADDRESS, void *wireObj=0) : MPU6050_Base(address, wireObj) { } + + uint8_t dmpInitialize(); + bool dmpPacketAvailable(); + + uint8_t dmpSetFIFORate(uint8_t fifoRate); + uint8_t dmpGetFIFORate(); + uint8_t dmpGetSampleStepSizeMS(); + uint8_t dmpGetSampleFrequency(); + int32_t dmpDecodeTemperature(int8_t tempReg); + + // Register callbacks after a packet of FIFO data is processed + //uint8_t dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); + //uint8_t dmpUnregisterFIFORateProcess(inv_obj_func func); + uint8_t dmpRunFIFORateProcesses(); + + // Setup FIFO for various output + uint8_t dmpSendQuaternion(uint_fast16_t accuracy); + uint8_t dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendPacketNumber(uint_fast16_t accuracy); + uint8_t dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); + uint8_t dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); + + // Get Fixed Point data from FIFO + uint8_t dmpGetAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyro(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetMag(int16_t *data, const uint8_t* packet=0); + uint8_t dmpSetLinearAccelFilterCoefficient(float coef); + uint8_t dmpGetLinearAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity); + uint8_t dmpGetLinearAccelInWorld(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccelInWorld(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q); + uint8_t dmpGetGyroAndAccelSensor(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroAndAccelSensor(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroAndAccelSensor(VectorInt16 *g, VectorInt16 *a, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGyroSensor(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetControlData(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetTemperature(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetGravity(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetGravity(VectorFloat *v, Quaternion *q); + uint8_t dmpGetUnquantizedAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetUnquantizedAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetUnquantizedAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(int32_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(int16_t *data, const uint8_t* packet=0); + uint8_t dmpGetQuantizedAccel(VectorInt16 *v, const uint8_t* packet=0); + uint8_t dmpGetExternalSensorData(int32_t *data, uint16_t size, const uint8_t* packet=0); + uint8_t dmpGetEIS(int32_t *data, const uint8_t* packet=0); + + uint8_t dmpGetEuler(float *data, Quaternion *q); + uint8_t dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity); + + // Get Floating Point data from FIFO + uint8_t dmpGetAccelFloat(float *data, const uint8_t* packet=0); + uint8_t dmpGetQuaternionFloat(float *data, const uint8_t* packet=0); + + uint8_t dmpProcessFIFOPacket(const unsigned char *dmpData); + uint8_t dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed=NULL); + + uint8_t dmpSetFIFOProcessedCallback(void (*func) (void)); + + uint8_t dmpInitFIFOParam(); + uint8_t dmpCloseFIFO(); + uint8_t dmpSetGyroDataSource(uint8_t source); + uint8_t dmpDecodeQuantizedAccel(); + uint32_t dmpGetGyroSumOfSquare(); + uint32_t dmpGetAccelSumOfSquare(); + void dmpOverrideQuaternion(long *q); + uint16_t dmpGetFIFOPacketSize(); + + private: + uint8_t *dmpPacketBuffer; + uint16_t dmpPacketSize; +}; + +typedef MPU6050_9Axis_MotionApps41 MPU6050; + +#endif /* _MPU6050_6AXIS_MOTIONAPPS41_H_ */ \ No newline at end of file diff --git a/lib/MPU6050/src/helper_3dmath.h b/lib/MPU6050/src/helper_3dmath.h new file mode 100755 index 0000000..9f431a2 --- /dev/null +++ b/lib/MPU6050/src/helper_3dmath.h @@ -0,0 +1,216 @@ +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class, 3D math helper +// 6/5/2012 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2012-06-05 - add 3D math helper file to DMP6 example sketch + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2012 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +=============================================== +*/ + +#ifndef _HELPER_3DMATH_H_ +#define _HELPER_3DMATH_H_ + +class Quaternion { + public: + float w; + float x; + float y; + float z; + + Quaternion() { + w = 1.0f; + x = 0.0f; + y = 0.0f; + z = 0.0f; + } + + Quaternion(float nw, float nx, float ny, float nz) { + w = nw; + x = nx; + y = ny; + z = nz; + } + + Quaternion getProduct(Quaternion q) { + // Quaternion multiplication is defined by: + // (Q1 * Q2).w = (w1w2 - x1x2 - y1y2 - z1z2) + // (Q1 * Q2).x = (w1x2 + x1w2 + y1z2 - z1y2) + // (Q1 * Q2).y = (w1y2 - x1z2 + y1w2 + z1x2) + // (Q1 * Q2).z = (w1z2 + x1y2 - y1x2 + z1w2 + return Quaternion( + w*q.w - x*q.x - y*q.y - z*q.z, // new w + w*q.x + x*q.w + y*q.z - z*q.y, // new x + w*q.y - x*q.z + y*q.w + z*q.x, // new y + w*q.z + x*q.y - y*q.x + z*q.w); // new z + } + + Quaternion getConjugate() { + return Quaternion(w, -x, -y, -z); + } + + float getMagnitude() { + return sqrt(w*w + x*x + y*y + z*z); + } + + void normalize() { + const float im = 1.0f / getMagnitude(); + w *= im; + x *= im; + y *= im; + z *= im; + } + + Quaternion getNormalized() { + Quaternion r(w, x, y, z); + r.normalize(); + return r; + } +}; + +class VectorInt16 { + public: + int16_t x; + int16_t y; + int16_t z; + + VectorInt16() { + x = 0; + y = 0; + z = 0; + } + + VectorInt16(int16_t nx, int16_t ny, int16_t nz) { + x = nx; + y = ny; + z = nz; + } + + float getMagnitude() { + return sqrt(x*x + y*y + z*z); + } + + void normalize() { + const float im = 1.0f / getMagnitude(); + x *= im; + y *= im; + z *= im; + } + + VectorInt16 getNormalized() { + VectorInt16 r(x, y, z); + r.normalize(); + return r; + } + + void rotate(Quaternion *q) { + // http://www.cprogramming.com/tutorial/3d/quaternions.html + // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm + // http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation + // ^ or: http://webcache.googleusercontent.com/search?q=cache:xgJAp3bDNhQJ:content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation&hl=en&gl=us&strip=1 + + // P_out = q * P_in * conj(q) + // - P_out is the output vector + // - q is the orientation quaternion + // - P_in is the input vector (a*aReal) + // - conj(q) is the conjugate of the orientation quaternion (q=[w,x,y,z], q*=[w,-x,-y,-z]) + Quaternion p(0, x, y, z); + + // quaternion multiplication: q * p, stored back in p + p = q -> getProduct(p); + + // quaternion multiplication: p * conj(q), stored back in p + p = p.getProduct(q -> getConjugate()); + + // p quaternion is now [0, x', y', z'] + x = p.x; + y = p.y; + z = p.z; + } + + VectorInt16 getRotated(Quaternion *q) { + VectorInt16 r(x, y, z); + r.rotate(q); + return r; + } +}; + +class VectorFloat { + public: + float x; + float y; + float z; + + VectorFloat() { + x = 0; + y = 0; + z = 0; + } + + VectorFloat(float nx, float ny, float nz) { + x = nx; + y = ny; + z = nz; + } + + float getMagnitude() { + return sqrt(x*x + y*y + z*z); + } + + void normalize() { + const float m = 1.0f / getMagnitude(); + x *= m; + y *= m; + z *= m; + } + + VectorFloat getNormalized() { + VectorFloat r(x, y, z); + r.normalize(); + return r; + } + + void rotate(Quaternion *q) { + Quaternion p(0, x, y, z); + + // quaternion multiplication: q * p, stored back in p + p = q -> getProduct(p); + + // quaternion multiplication: p * conj(q), stored back in p + p = p.getProduct(q -> getConjugate()); + + // p quaternion is now [0, x', y', z'] + x = p.x; + y = p.y; + z = p.z; + } + + VectorFloat getRotated(Quaternion *q) { + VectorFloat r(x, y, z); + r.rotate(q); + return r; + } +}; + +#endif /* _HELPER_3DMATH_H_ */ \ No newline at end of file diff --git a/lib/OSC/API.md b/lib/OSC/API.md new file mode 100644 index 0000000..6941485 --- /dev/null +++ b/lib/OSC/API.md @@ -0,0 +1,395 @@ +# OSCMessage + +An OSCMessage is an address followed by any number of data. Messages can have mixed data types like an integer followed by a string followed by a float, etc. + +## Constructor + +OSCMessages can be constructed with or without an address. + +### `OSCMessage(const char *)` + +Set the address of the message in the constructor + +```C++ +OSCMessage msg("/address"); +``` + +### `OSCMessage()` + +An OSCMessage constructed without an address is not valid until it is given an address. + +## Add/Set Data + + +### `OSCMessage& add(int i)` + +Append an integer to the OSCMessage. + +```C++ +msg.add(1); +``` + + +### `OSCMessage& add(float f)` + +Append a float to the OSCMessage. + + + +### `OSCMessage& add(bool b)` + +Append a boolean to the OSCMessage. + + + +### `OSCMessage& add(const char * str)` + +Append a string to the OSCMessage. + +```C++ +msg.add("hello"); +``` + + +### `OSCMessage& add(uint8_t * blob, int length)` + +Append a [blob](https://en.wikipedia.org/wiki/Binary_large_object) to the OSCMessage. Pass in the length of the blob as the second argument. + + + +### `OSCMessage& set(int position, Type data)` + +Replace the data at the given position with the data. `Type` can be any of the supported data types. + +```C++ +//replace the data at the 0th position with a string +msg.set(0, "string"); +``` + + +### `OSCMessage& set(int position, uint8_t * data, int length)` + +Set the data at the given position to be a blob of the given length. + + +### `OSCMessage& add(double d)` + +Append a double precision floating point value to the OSCMessage. NOTE: double is not supported on most Arduino platforms. It will fall back to float, when double is not supported. + +## Get Data + + +### `int getInt(int position)` + +Returns the integer at the given position + +```C++ +//returns the integer at the third position +msg.getInt(2); +``` + +### `float getFloat(int position)` + +Returns the float at the given position + + + +### `bool getBoolean(int position)` + +Returns the boolean at the given position + + + +### `double getDouble(int position)` + +Returns the double at the given position. NOTE: double is not supported by most Arduino platforms. This will fail silently if double is not supported. + +### `int getString(int position, char * strBuffer)` + +Copy the string’s characters into the `strBuffer`, without any safety check. +Returns the number of copied characters. + +### `int getString(int position, char * strBuffer, int length)` + +Copy the string’s characters into the `strBuffer`, after checking that this doesn’t exceed the buffer’s `length`. +Returns the number of copied characters. NOTE that if the string length is greater than the available buffer length, then NO characters are copied. + +### `int getString(int position, char * strBuffer, int length, int offset, int size)` + +Copy `size` number of characters from the given `offset` into the `strBuffer`, after checking that this doesn’t exceed the buffer’s `length`. Returns `size`, even if the number of copied characters is lower. +```C++ +char str[8]; +//fill str with 8 characters from the 0th datum +msg.getString(0, str, 8, 0, 8); +``` + +### `int getBlob(int position, uint8_t * blobBuffer)` + +Directly copy the blob’s bytes into the `blob` buffer (without safety-check). +Returns the number of bytes from the blob. + + +### `int getBlob(int position, uint8_t * blobBuffer, int length)` + +Copy the blob's bytes into the given `blobBuffer`, if the blob's size doesn’t exceed the blobBuffer's `length`. +Returns the number of bytes copied from the blob. NOTE that if the blob length is greater than the available buffer length, then NO bytes are copied. + +### `int getBlob(int position, uint8_t * blobBuffer, int length, int offset, int size)` + +Copy `size` bytes from the blob, starting from `offset`, into the given `blobBuffer`, if the size doesn’t exceed the buffer’s `length` or the blob’s data length. +Returns the number of bytes copied from the blob. NOTE that if the requested size is greater than *either* the available buffer length *or* the (partial) blob length, then NO bytes are copied. + + +### `const uint8_t* getBlob(int position)` + +Get a pointer to blob data. + + +### `int getBlobLength(int position)` + +Returns the length of the blob in bytes. + + +### `char getType(int position)` + +Returns the type of the data at the given position. + +```C++ +OSCMessage msg("/address"); +msg.add(1); +msg.getType(0); //-> returns 'i' +``` + + +## Query Data + +### `bool isInt(int position)` + +Returns `true` when the data at the given position is an integer. + +### `bool isFloat(int position)` + +Returns `true` when the data at the given position is a float. + +### `bool isBoolean(int position)` + +Returns `true` when the data at the given position is a boolean. + +### `bool isString(int position)` + +Returns `true` when the data at the given position is a string. + +### `bool isBlob(int position)` + +Returns `true` when the data at the given position is a blob. + +### `bool isDouble(int position)` + +Returns `true` when the data at the given position is a double. + +### `int size()` + +Returns the number of data the OSCMessage has. + +### `int bytes()` + +Returns the size of the OSCMessage in bytes (if everything is 32-bit aligned). + + + +## Address + +### `OSCMessage& setAddress(const char * address)` + +Set the address of the OSCMessage. + +### `int getAddress(char * str, int offset=0)` + +Copy the address of the OSCMessage into the `str` buffer. Copy after the given address `offset` (defaults to 0). Returns the length of the resulting string. If the offset is past the end of the address an empty string / zero length are returned. + +### `int getAddress(char * str, int offset, int len)` + +Copy a maximum of len characters of the address of the OSCMessage into the `str` buffer, starting at at the given address `offset`. Returns the length of the resulting string. If the offset is past the end of the address an empty string / zero length are returned. + +### `int getAddressLength(int offset=0)` + +Returns the length of the OSCMessage's address, starting after the given address `offset` (defaults to 0). If the offset is +greater than the address length then it returns zero. + +### `const char* getAddress()` + +Get a pointer to the address as a C string. + +## Send Receive + +### `OSCMessage& send(Print &p)` + +Output the message to the given transport layer which extends Arduino's [Print class](http://playground.arduino.cc/Code/Printclass) like the `Serial` out. + +```C++ +msg.send(SLIPSerial); +``` + +### `OSCMessage& fill(uint8_t incomingByte)` + +Add the incoming byte to the OSCMessage where it will be decoded. + +### `OSCMessage& fill(uint8_t * bytes, int length)` + +Add and decode the array of `bytes` as an OSCMessage. + + + +## Matching / Routing + +### `bool fullMatch( const char * pattern, int offset = 0)` + +Returns true if the message's address is a full match to the given `pattern` after the `offset`. + +```C++ +OSCMessage msg("/a/0"); +msg.fullMatch("/0", 2); // ->returns true +``` + +### `int match( const char * pattern, int offset = 0)` + +Returns the number of matched characters of the message's address against the given `pattern` (optionally with an `offset`). Unlike `fullMatch`, `match` allows for partial matches + +```C++ +OSCMessage msg("/a/0"); +msg.match("/a"); // ->returns 2 +``` + +### `bool dispatch(const char * pattern, void (*callback)(OSCMessage &), int offset = 0)` + +Invoke the given `callback` if the address is a full match with the `pattern` (after the `offset`). The message is passed into the callback function. Returns true if the pattern was a match and the callback function was invoked. + +### `bool route(const char * pattern, void (*callback)(OSCMessage &, int), int offset = 0)` + +Invoke the given `callback` if the address if a match with the `pattern` (after the `offset`). The OSCMessage and the address offset is passed into the callback function. Returns true if the pattern was a match and the callback function was invoked. + +```C++ +//define a callback function for matching messages +void routeCallback(OSCMessage & message, int addressOffset){ + //do something with the message... + + //with the message below, the addressOffset will equal 2. +} + +OSCMessage msg("/a/0"); +msg.route("/a", routeCallback); +``` + + +## Address Patterns + +OSCMessages can be constructed with patterns and later routed or dispatched against addresses. + +```C++ +OSCMessage msg("/{a,b}/[0-9]"); +msg.route("/a/0", a0_callback); //matches the address +msg.route("/b/2", b2_callback); //matches the address +msg.route("/c/11", c11_callback); //not invoked +``` + +# OSCBundle + +A bundle is a group of OSCMessages with a timetag. + + +## Constructor + +### `OSCBundle()` + +Construct an empty OSCBundle. + +### `OSCBundle(osctime_t = zerotime)` + +Construct the bundle with a timetag. timetag defaults to 0 (immediate). + + + +## Add OSCMessage + +### `OSCMessage & add(char * address)` + +Create a new message with the given `address` in the bundle. Returns the newly created OSCMessage. + +```C++ +//create a new OSCMessage and add some data to it +bundle.add("/message").add("data"); +``` + + +## Get OSCMessage + +### `OSCMessage * getOSCMessage(int position)` + +Return the OSCMessage in the bundle at the given `position`. + +```C++ +OSCBundle bundle +bundle.add("/a"); +bundle.add("/b"); +bundle.getOSCMessage(0);//returns the OSCMessage with the address "/a". +``` + +### `OSCMessage * getOSCMessage(char * address)` + +Return the OSCMessage in the bundle which matches the given address. + +```C++ +OSCBundle bundle +bundle.add("/a"); +bundle.add("/b"); +bundle.getOSCMessage("/b");//returns the second OSCMessage in the bundle +``` + + +## Routing + +### `bool dispatch(const char * pattern, void (*callback)(OSCMessage&), int offset = 0)` + +Invoke the `callback` function with all messages in the bundle which match the given pattern after the offset. + +```C++ +bundle.add("/a/0"); +bundle.add("/b/0"); +bundle.dispatch("/0", dispatchZero, 2); +``` + +### `bool route(const char * pattern, void (*callback)(OSCMessage &, int), int offset = 0)` + +Invoke the `callback` with all the OSCMessages in the bundle which match the given `pattern`. `route` allows for partial matches. + + + +## Send/Receive + +### `OSCBundle& send(Print &p)` + +Output the bundle to the given transport layer which extends Arduino's [Print class](http://playground.arduino.cc/Code/Printclass) (such as `SLIPSerial` out). + +```C++ +bundle.send(SLIPSerial); +``` + +### `OSCBundle& fill(uint8_t incomingByte)` + +Add the incoming byte to the OSCBundle where it will be decoded. + +### `OSCBundle& fill(uint8_t * bytes, int length)` + +Add and decode the array of bytes as an OSCBundle. + + + +# Chaining + +Many methods return `this` which enables you to string together multiple commands. + +This technique allows multiple lines to be condensed into one: + +```C++ +bundle.add("/address").add("data").add(0).send(SLIPSerial).empty(); +``` diff --git a/lib/OSC/Applications/MaxMSP/examples/OSCEsplora.maxpat b/lib/OSC/Applications/MaxMSP/examples/OSCEsplora.maxpat new file mode 100644 index 0000000..01631f3 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/OSCEsplora.maxpat @@ -0,0 +1,306 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 130.0, 174.0, 983.0, 623.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-5", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 141.0, 266.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-3", + "linecount" : 6, + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 422.5, 125.0, 158.0, 101.0 ], + "text" : "/port : \"usbmodemOSCes41\",\n/rate/output : 0,\n/rate/input : 0,\n/mediansize/received : -1,\n/baud", + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-2", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 389.5, -32.5, 170.0, 33.0 ], + "style" : "", + "text" : "Look for your device in the menu list of serial USB" + } + + } +, { + "box" : { + "bgmode" : 0, + "border" : 0, + "clickthrough" : 0, + "enablehscroll" : 0, + "enablevscroll" : 0, + "id" : "obj-7", + "lockeddragscroll" : 0, + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "offset" : [ 3.0, 0.0 ], + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 81.5, 29.0, 340.5, 25.0 ], + "viewvisibility" : 1 + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-23", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 20.5, 68.0, 80.0, 22.0 ], + "style" : "", + "text" : "o.io.slipserial" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-11", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 471.0, 29.0, 150.0, 54.0 ], + "style" : "", + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-6", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 214.0, 285.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-4", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 23.0, 285.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-1", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 3, + "outlettype" : [ "", "", "FullPacket" ], + "patching_rect" : [ 23.0, 176.0, 119.0, 22.0 ], + "style" : "", + "text" : "o.route /raw /cooked" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 91.0, 109.0, 432.0, 109.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 91.0, 95.0, 433.0, 95.0, 433.0, 5.0, 91.0, 5.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-23", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-7", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/SerialCallResponse.maxpat b/lib/OSC/Applications/MaxMSP/examples/SerialCallResponse.maxpat new file mode 100644 index 0000000..a799bc8 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/SerialCallResponse.maxpat @@ -0,0 +1,974 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 140.0, 78.0, 1266.0, 737.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-6", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 725.5, 158.0, 170.0, 33.0 ], + "style" : "", + "text" : "Look for your device in the menu list of serial USB" + } + + } +, { + "box" : { + "bgmode" : 0, + "border" : 0, + "clickthrough" : 0, + "enablehscroll" : 0, + "enablevscroll" : 0, + "id" : "obj-9", + "lockeddragscroll" : 0, + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "offset" : [ 3.0, 0.0 ], + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 338.5, 162.0, 340.5, 25.0 ], + "viewvisibility" : 1 + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-8", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 240.5, 252.0, 150.0, 36.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-5", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 491.0, 252.0, 150.0, 36.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-7", + "maxclass" : "o.message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 521.0, 81.0, 150.0, 20.0 ], + "text" : "/analog/{2,3}/u", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 524.5, 16.0, 222.0, 38.0 ], + "style" : "", + "text" : "read analog pins 2 and 3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-78", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 504.5, 15.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-79", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 504.5, 46.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-55", + "maxclass" : "o.message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 266.0, 81.0, 150.0, 20.0 ], + "text" : "/analog/[0-3]/u", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-28", + "maxclass" : "o.message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 19.0, 81.0, 150.0, 20.0 ], + "text" : "/analog/*", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "id" : "obj-56", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 174.0, 455.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-64", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 172.0, 350.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[37]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[25]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 3.0, 493.0, 145.0, 22.0 ], + "style" : "", + "text" : "analog readings" + } + + } +, { + "box" : { + "id" : "obj-110", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 135.0, 454.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-109", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 102.0, 454.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-108", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 69.0, 454.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-107", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 36.0, 454.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-105", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 135.0, 350.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[19]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[4]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-104", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 102.0, 350.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[20]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[3]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-103", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 69.0, 350.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[21]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[2]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-102", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 36.0, 350.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[22]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[1]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-101", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 3.0, 350.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[23]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a" + } + + } +, { + "box" : { + "id" : "obj-84", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 3.0, 454.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 7, + "outlettype" : [ "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 8.0, 310.0, 221.0, 24.0 ], + "style" : "", + "text" : "o.route /0 /1 /2 /3 /4 /5" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 3.0, 252.0, 137.0, 24.0 ], + "style" : "", + "text" : "o.route /analog" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-15", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 269.5, 17.0, 187.0, 38.0 ], + "style" : "", + "text" : "read analog pins 0-3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 249.5, 17.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-22", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 249.5, 47.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 32.5, 18.0, 187.0, 22.0 ], + "style" : "", + "text" : "read all analog pins" + } + + } +, { + "box" : { + "id" : "obj-60", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 12.5, 18.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-61", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 12.5, 47.0, 95.0, 24.0 ], + "style" : "", + "text" : "qmetro 100" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-4", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 702.5, 243.0, 150.0, 54.0 ], + "style" : "", + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 220.5, 201.0, 137.0, 24.0 ], + "style" : "", + "text" : "o.io.slipserial" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-91", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 0, + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 34.0, 78.0, 738.0, 421.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-2", + "linecount" : 25, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 20.0, 768.0, 400.0 ], + "style" : "", + "text" : "/*\n Written by Yotam Mann and Adrian freed,\n The Center for New Music and Audio Technologies,\n University of California, Berkeley. Copyright (c) 2012, The Regents of\n the University of California (Regents).\n \n Permission to use, copy, modify, distribute, and distribute modified versions\n of this software and its documentation without fee and without a signed\n licensing agreement, is hereby granted, provided that the above copyright\n notice, this paragraph and the following two paragraphs appear in all copies,\n modifications, and distributions.\n \n IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,\n SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING\n OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS\n BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n \n REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED\n HEREUNDER IS PROVIDED \"AS IS\". REGENTS HAS NO OBLIGATION TO PROVIDE\n MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.\n \n For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu\n */" + } + + } + ], + "lines" : [ ] + } +, + "patching_rect" : [ 8.0, 570.0, 111.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p disclaimer" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-84", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-101", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-107", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-102", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-108", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-103", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-109", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-104", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-110", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-105", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-18", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-55", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-22", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-8", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-9", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 348.0, 229.0, 717.0, 229.0, 717.0, 131.0, 348.0, 131.0 ], + "source" : [ "obj-26", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-28", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-55", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-61", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-28", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-61", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-56", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-64", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-7", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-79", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-78", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-79", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-101", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-102", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-103", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-104", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-105", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-64", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-9", 0 ] + } + + } + ], + "parameters" : { + "obj-105" : [ "a[19]", "a", 0 ], + "obj-104" : [ "a[20]", "a", 0 ], + "obj-103" : [ "a[21]", "a", 0 ], + "obj-64" : [ "a[37]", "a", 0 ], + "obj-102" : [ "a[22]", "a", 0 ], + "obj-101" : [ "a[23]", "a", 0 ] + } +, + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.message.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/SerialEcho.maxpat b/lib/OSC/Applications/MaxMSP/examples/SerialEcho.maxpat new file mode 100644 index 0000000..7ef0315 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/SerialEcho.maxpat @@ -0,0 +1,304 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 6, + "minor" : 1, + "revision" : 6, + "architecture" : "x86" + } +, + "rect" : [ 608.0, 81.0, 1202.0, 749.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 0, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 0, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "boxanimatetime" : 200, + "imprint" : 0, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 218.0, 295.0, 95.0, 22.0 ], + "text" : "o.downcast" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-18", + "linecount" : 10, + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 28.5, 425.0, 267.0, 155.0 ], + "text" : "/ping : 100,\n/thing : [2., 3.04, 1242., 23., \"thing\"],\n/stuff : [1, 2, 3, 4, 5],\n/fsakjfskfsdkasfk : [234, 242, 234, 234, 4],\n/decision : 1,\n/notdecision : 0,\n/micros : 616229100,\n/sequencenumber : 20557,\n/digital/5 : false,\n/lsb : false", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-3", + "linecount" : 5, + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 404.5, 425.0, 158.0, 88.0 ], + "text" : "/port : \"usbmodem12341\",\n/rate/output : 32,\n/rate/input : 39,\n/mediansize/received : -1,\n/baud", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "frgb" : 0.0, + "id" : "obj-19", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 424.5, 269.5, 170.0, 33.0 ], + "text" : "Look for your device in the menu list of serial USB" + } + + } +, { + "box" : { + "id" : "obj-20", + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "offset" : [ 3.0, 0.0 ], + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 404.5, 340.0, 164.0, 24.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-23", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 343.5, 379.0, 80.0, 20.0 ], + "text" : "o.io.slipserial" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-2", + "linecount" : 6, + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 45.0, 90.166656, 964.0, 105.0 ], + "text" : "/ping : 100,\n/thing : [2., 3.04, 1242., 23., \"thing\"],\n/stuff : [1, 2, 3, 4, 5],\n/fsakjfskfsdkasfk : [234, 242, 234, 234, 4],\n/decision : true,\n/notdecision : false", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "frgb" : 0.0, + "id" : "obj-4", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 595.0, 415.0, 150.0, 54.0 ], + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-61", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 45.0, 38.166656, 162.0, 22.0 ], + "text" : "metro 22 @active 1" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-2", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-23", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-18", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 414.0, 406.0, 583.0, 406.0, 583.0, 316.0, 414.0, 316.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 414.0, 420.0, 414.0, 420.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-61", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", + "patcherrelativepath" : "../../../../../Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/ordering", + "patcherrelativepath" : "../../../../../Documents/Max/Packages/CNMAT-odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", + "patcherrelativepath" : "../../../../../Documents/Max/Packages/CNMAT-MMJSS/patchers/esplora", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.compose.mxo", + "type" : "iLaX" + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.downcast.mxo", + "type" : "iLaX" + } + ] + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/SerialOscuino.maxpat b/lib/OSC/Applications/MaxMSP/examples/SerialOscuino.maxpat new file mode 100644 index 0000000..81a211f --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/SerialOscuino.maxpat @@ -0,0 +1,6632 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 2, + "revision" : 1, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 260.0, 117.0, 1158.0, 548.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-5", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 35.5, 219.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.downcast" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-3", + "linecount" : 8, + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 408.5, 390.0, 150.0, 146.0 ], + "text" : "/port : \"usbmodem1\",\n/rate/output : 3,\n/rate/input : 3,\n/mediansize/received : -1,\n/baud", + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-2", + "linecount" : 23, + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 35.5, 382.0, 150.0, 383.0 ], + "text" : "/a/0 : 275,\n/a/1 : 352,\n/a/2 : 356,\n/a/3 : 296,\n/a/4 : 326,\n/a/5 : 285,\n/a/6 : 333,\n/a/7 : 403,\n/a/8 : 305,\n/a/9 : 312,\n/a/10 : 266,\n/a/11 : 485,\n/a/12 : 588,\n/a/13 : 479,\n/a/14 : 348,\n/a/15 : 327,\n/a/16 : 222,\n/a/17 : 262,\n/a/18 : 273,\n/a/19 : 265,\n/a/20 : 365,\n/a/21 : 301,\n/a/22 : 295", + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "bgmode" : 0, + "border" : 0, + "clickthrough" : 0, + "enablehscroll" : 0, + "enablevscroll" : 0, + "id" : "obj-16", + "lockeddragscroll" : 0, + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "offset" : [ 0.0, 0.0 ], + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 427.0, 224.0, 341.0, 30.0 ], + "viewvisibility" : 1 + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-9", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 453.5, 157.0, 288.0, 54.0 ], + "style" : "", + "text" : "Increase baud rate from 9600\nfor better performance:\nchange the rate in the sketch too" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 2, + "revision" : 1, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 618.0, 79.0, 788.0, 503.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "visible" : 1, + "boxes" : [ { + "box" : { + "id" : "obj-3", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 595.25, 423.0, 20.0, 20.0 ], + "presentation_rect" : [ 595.25, 422.0, 0.0, 0.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-4", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 558.833313, 417.0, 20.0, 20.0 ], + "presentation_rect" : [ 558.833313, 416.0, 0.0, 0.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-5", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 522.416626, 417.0, 20.0, 20.0 ], + "presentation_rect" : [ 522.416626, 416.0, 0.0, 0.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-9", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 477.333344, 424.0, 20.0, 20.0 ], + "presentation_rect" : [ 477.333344, 423.0, 0.0, 0.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-10", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 595.25, 313.0, 34.0, 95.0 ], + "presentation_rect" : [ 595.25, 312.0, 0.0, 0.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[75]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[6]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-12", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 558.833313, 313.0, 34.0, 95.0 ], + "presentation_rect" : [ 558.833313, 312.0, 0.0, 0.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[76]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[7]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-15", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 522.416626, 313.0, 34.0, 95.0 ], + "presentation_rect" : [ 522.416626, 312.0, 0.0, 0.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[77]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[8]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-22", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 486.0, 313.0, 34.0, 95.0 ], + "presentation_rect" : [ 486.0, 312.0, 0.0, 0.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[78]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[9]" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-8", + "linecount" : 12, + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 652.0, 213.0, 150.0, 181.0 ], + "text" : "/22 : 674,\n/23 : 722,\n/19 : 560,\n/18 : 553,\n/17 : 754,\n/16 : 590,\n/15 : 627,\n/0 : 639,\n/1 : 640,\n/25 : 0,\n/32 : 0,\n/33 : 0", + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-7", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 329.0, 104.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 99, 47, 42, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/c/*", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-18", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 33.0, 33.0, 90.0, 47.0 ], + "style" : "", + "text" : "Capacitance from touch pins\n" + } + + } +, { + "box" : { + "id" : "obj-13", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 329.0, 26.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-11", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 329.0, 68.0, 65.0, 22.0 ], + "style" : "", + "text" : "qmetro 30" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-6", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 329.0, 148.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 29.0, 148.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.route /c" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-60", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 29.0, 99.0, 170.0, 24.0 ], + "style" : "", + "text" : "r from_oscuino" + } + + } +, { + "box" : { + "id" : "obj-1", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 438.25, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-2", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 401.833313, 417.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-14", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 365.416656, 417.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-16", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 320.333344, 424.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-17", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 283.916656, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-19", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 438.25, 313.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[50]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[12]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-20", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 401.833313, 313.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[51]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[13]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-21", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 365.416656, 313.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[52]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[14]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-23", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 329.0, 313.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[53]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[15]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-24", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 283.916656, 320.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[54]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[16]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-25", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 247.5, 320.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[55]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[17]" + } + + } +, { + "box" : { + "id" : "obj-26", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 247.5, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-111", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 211.083328, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-110", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 174.666672, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-109", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 138.25, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-108", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 101.833336, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-107", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 65.416664, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-106", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 211.083328, 319.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[56]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[5]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-105", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 174.666672, 319.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[57]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[4]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-104", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 138.25, 319.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[58]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[3]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-103", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 101.833336, 319.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[59]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[2]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-102", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 65.416664, 319.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[60]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[1]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-101", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 29.0, 319.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[61]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a" + } + + } +, { + "box" : { + "id" : "obj-84", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 29.0, 423.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 17, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 29.0, 220.0, 573.0, 24.0 ], + "style" : "", + "text" : "o.route /0 /1 /3 /4 /16 /17 /18 /19 /22 /23 /25 /32 /33 /15 /29 /30" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-10", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-84", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-101", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-107", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-102", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-108", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-103", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-109", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-104", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-110", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-105", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-111", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-106", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-12", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-11", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-13", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-19", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-14", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-21", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-9", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-22", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-17", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-24", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-25", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-8", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-7", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-10", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-101", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-102", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-103", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-104", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-105", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-106", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-15", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-19", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-21", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-24", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-25", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 6 ] + } + + } + ] + } +, + "patching_rect" : [ 408.5, 110.0, 145.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p teensy 3 touch" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-4", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 427.0, 323.0, 150.0, 54.0 ], + "style" : "", + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-60", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 247.5, 355.0, 128.0, 24.0 ], + "style" : "", + "text" : "s from_oscuino" + } + + } +, { + "box" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-58", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 2, + "revision" : 1, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 572.0, 102.0, 834.0, 483.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "visible" : 1, + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-32", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 119.5, 296.0, 41.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 115, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/s", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-30", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 104.0, 234.0, 39.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 116, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/t", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-28", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 76.0, 179.0, 45.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 109, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/m", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-26", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 40.0, 122.0, 42.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 100, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/d", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-20", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 14.0, 68.0, 42.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 97, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/a", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-16", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 415.0, 122.0, 150.0, 34.0 ], + "text" : "/s : 1.83224", + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-15", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 166.5, 370.0, 65.0, 22.0 ], + "style" : "", + "text" : "o.pack /s/l" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 119.5, 266.0, 179.0, 22.0 ], + "style" : "", + "text" : "Power Supply Voltage" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 104.0, 212.0, 103.0, 22.0 ], + "style" : "", + "text" : "Temperature" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 415.0, 95.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.route /s" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-60", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 414.0, 64.0, 170.0, 24.0 ], + "style" : "", + "text" : "r from_oscuino" + } + + } +, { + "box" : { + "id" : "obj-8", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 166.5, 329.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-5", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 224.5, 320.0, 381.0, 38.0 ], + "style" : "", + "text" : "toggle the LED (don't do this on Teensy 3.0 with Wiznet Ethernet that uses pin 13)" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 76.0, 152.0, 246.0, 22.0 ], + "style" : "", + "text" : "Arduino time in microseconds" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-3", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 23.0, 46.0, 288.0, 22.0 ], + "style" : "", + "text" : "Returns the number of analog pins" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-2", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 14.0, 432.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-10", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 40.0, 96.0, 296.0, 22.0 ], + "style" : "", + "text" : "Returns the number of digital pins" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 19.0, 15.0, 792.0, 22.0 ], + "style" : "", + "text" : "QUERIES AND PARAMS" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-28", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-30", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-32", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-15", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } + ] + } +, + "patching_rect" : [ 222.0, 110.0, 179.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p queries-and-params" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-52", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 2, + "revision" : 1, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 56.0, 79.0, 1321.0, 589.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "id" : "obj-51", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1290.5, 337.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-52", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1274.088257, 501.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-53", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1247.676514, 501.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-3", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1209.5, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-5", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1183.088257, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-7", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1156.676514, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-9", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1130.264648, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-12", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1103.853027, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-33", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1077.441162, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-34", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1051.029419, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-37", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 1024.617676, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-38", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 998.205811, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-39", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 971.794189, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-41", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 945.382324, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-42", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 918.970581, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-43", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 892.558838, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-44", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 866.147095, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-47", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 839.735291, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-48", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 813.323486, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-49", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 786.911743, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-50", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 760.5, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-40", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 15.0, 383.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 100, 47, 42, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/d/*", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-15", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 326.5, 263.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 100, 47, 49, 91, 51, 56, 57, 93, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1 ], + "saved_bundle_length" : 40, + "text" : "/d/1[389] : 1", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-14", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 353.0, 306.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 100, 47, 49, 48, 47, 117, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/d/10/u", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-11", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 80.0, 263.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 100, 47, 49, 91, 48, 45, 57, 93, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1 ], + "saved_bundle_length" : 40, + "text" : "/d/1[0-9] : 1", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-2", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 197.0, 352.0, 76.0, 22.0 ], + "style" : "", + "text" : "o.pack /d/13" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-10", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 82.5, 395.0, 83.0, 20.0 ], + "style" : "", + "text" : "report all pins" + } + + } +, { + "box" : { + "id" : "obj-8", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 15.0, 320.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-4", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 15.0, 351.0, 72.0, 22.0 ], + "style" : "", + "text" : "qmetro 100" + } + + } +, { + "box" : { + "id" : "obj-35", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 730.5, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-36", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 704.088257, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-28", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 677.676453, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-30", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 651.264709, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-31", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 624.852966, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-32", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 598.441162, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-24", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 572.029419, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-25", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 545.617676, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-26", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 519.205872, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-27", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 492.794128, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-20", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 466.382324, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-21", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 439.970581, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-22", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 413.558838, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-23", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 387.147064, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-19", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 360.735291, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 334.323517, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-17", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 307.911774, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-16", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 281.5, 497.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "linecount" : 2, + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 39, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 298.756958, 411.0, 968.0, 40.0 ], + "style" : "", + "text" : "o.route /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 /12 /13 /14 /15 /16 /17 /18 /19 /20 /21 /22 /23 /24 /25 /26 /27 /28 /29 /30 /31 /32 /33 /34 /35 /36 /37" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 354.0, 383.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.route /d" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-60", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 354.0, 352.0, 170.0, 24.0 ], + "style" : "", + "text" : "r from_oscuino" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-1", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 241.0, 469.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-29", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 197.0, 313.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-6", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 281.5, 229.0, 313.0, 22.0 ], + "style" : "", + "text" : "Set digital pins 3, 8, and 9 to HIGH" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 229.0, 254.0, 22.0 ], + "style" : "", + "text" : "Set digital pin 0 to HIGH/LOW" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "linecount" : 12, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 11.0, 801.0, 195.0 ], + "style" : "", + "text" : "DIGITAL\nThe basic digital Arduino functions with the option of using the internal pullup available on most Arduinos. \n\n/d/(pin #)\n\t(no data) = digitalRead with pullup off\n\t/u = digitalRead with pullup on\n\t(value 0/1) = digitalWrite with that value\n\nexample:\n\"/d/1\" performs digitalRead with pullup off on pin 0. \n\"/d/[0-4] 0\" performs digitalWrite LOW on pins 0 through 4." + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-14", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-2", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-29", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-40", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-4", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-40", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 31 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-17", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-18", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-19", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-21", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 6 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-24", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-25", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-27", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-28", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 35 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-30", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-31", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-32", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-33", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 30 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-34", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 29 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-35", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 17 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-36", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 16 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-37", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 28 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-38", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 27 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-39", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 26 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-41", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 25 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-42", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 24 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-43", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 23 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-44", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 22 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-47", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 21 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-48", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 20 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-49", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 19 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 34 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-50", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 18 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-52", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 37 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-53", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 36 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 33 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-9", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 32 ] + } + + } + ] + } +, + "patching_rect" : [ 35.5, 110.0, 86.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p digital" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-47", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 2, + "revision" : 1, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 34.0, 79.0, 1372.0, 769.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "id" : "obj-125", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 682.533325, 563.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-126", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 682.533325, 446.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[46]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[33]" + } + + } +, { + "box" : { + "id" : "obj-127", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 646.333313, 562.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-128", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 646.266663, 445.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[47]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[34]" + } + + } +, { + "box" : { + "id" : "obj-129", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 609.133301, 563.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-130", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 610.0, 446.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[74]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[35]" + } + + } +, { + "box" : { + "id" : "obj-55", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 1009.0, 796.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-87", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 1009.0, 692.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[48]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[36]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-88", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 976.0, 692.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[62]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[37]" + } + + } +, { + "box" : { + "id" : "obj-89", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 976.0, 796.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-90", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 940.0, 795.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-91", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 907.0, 795.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-92", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 874.0, 795.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-93", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 841.0, 795.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-94", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 808.0, 795.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-95", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 940.0, 689.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[49]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[38]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-96", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 907.0, 691.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[63]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[39]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-97", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 874.0, 691.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[64]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[40]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-98", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 841.0, 691.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[65]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[41]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-99", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 808.0, 691.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[66]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[42]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-100", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 775.0, 691.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[67]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[43]" + } + + } +, { + "box" : { + "id" : "obj-112", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 775.0, 795.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-113", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 745.0, 794.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-114", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 709.0, 794.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-115", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 676.0, 794.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-116", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 643.0, 794.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-117", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 610.0, 794.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-118", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 742.0, 690.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[68]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[44]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-119", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 709.0, 690.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[69]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[45]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-120", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 676.0, 690.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[70]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[46]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-121", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 643.0, 690.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[71]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[47]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-122", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 610.0, 690.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[72]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[48]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-123", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 577.0, 690.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[73]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[49]" + } + + } +, { + "box" : { + "id" : "obj-124", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 577.0, 794.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-82", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 769.5, 275.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 97, 47, 92, 123, 50, 92, 44, 51, 92, 125, 47, 117, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 40, + "text" : "/a/\\{2\\,3\\}/u ", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-80", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 450.0, 273.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 97, 47, 91, 48, 45, 51, 93, 47, 117, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 36, + "text" : "/a/[0-3]/u", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-62", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 238.5, 273.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 47, 42, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/a/*", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-61", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 21.5, 275.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 97, 47, 49, 0, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1 ], + "saved_bundle_length" : 36, + "text" : "/a/1 : 1", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-63", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 789.5, 212.0, 222.0, 38.0 ], + "style" : "", + "text" : "read analog pins 2 and 3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-78", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 769.5, 212.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-79", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 769.5, 242.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "id" : "obj-76", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 570.0, 563.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-77", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 570.0, 446.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[45]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[32]" + } + + } +, { + "box" : { + "id" : "obj-74", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 533.799988, 562.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-75", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 533.733337, 445.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[44]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[31]" + } + + } +, { + "box" : { + "id" : "obj-72", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 496.600006, 563.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-73", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 497.466675, 446.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[43]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[30]" + } + + } +, { + "box" : { + "id" : "obj-70", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 461.399994, 561.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-71", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 461.200012, 444.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[42]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[24]" + } + + } +, { + "box" : { + "id" : "obj-56", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 537.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-57", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 503.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-58", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 471.0, 786.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-59", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 444.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-64", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 524.354858, 682.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[37]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[25]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-65", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 499.0, 682.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[38]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[26]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-66", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 471.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[39]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[27]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-67", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 444.0, 681.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[40]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[28]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-68", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 411.0, 681.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[41]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[29]" + } + + } +, { + "box" : { + "id" : "obj-69", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 411.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-27", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 425.200012, 559.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-29", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 389.0, 559.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-30", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 351.799988, 559.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-31", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 315.600006, 559.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-47", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 280.399994, 559.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-48", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 424.933319, 442.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[30]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[18]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-49", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 388.666656, 442.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[31]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[19]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-50", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 352.399994, 442.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[32]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[20]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-51", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 316.133331, 442.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[33]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[21]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-52", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 279.866669, 442.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[34]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[22]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-53", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 243.600006, 442.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[35]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[23]" + } + + } +, { + "box" : { + "id" : "obj-54", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 244.199997, 559.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-1", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 375.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-2", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 342.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-14", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 309.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-16", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 276.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-17", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 243.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-19", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 375.0, 678.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[24]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[12]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-20", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 342.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[25]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[13]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-21", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 309.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[26]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[14]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-23", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 276.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[27]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[15]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-24", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 243.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[28]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[16]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-25", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 210.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[29]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[17]" + } + + } +, { + "box" : { + "id" : "obj-26", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 210.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 545.0, 338.0, 447.0, 22.0 ], + "style" : "", + "text" : "analog readings come out of the SLIP_oscuino patcher" + } + + } +, { + "box" : { + "id" : "obj-32", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 207.0, 558.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-33", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 170.800003, 558.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-34", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 134.600006, 558.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-35", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 99.400002, 555.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-36", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 62.200001, 556.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-37", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 207.333328, 441.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[12]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[6]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-38", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 171.066666, 441.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[13]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[7]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-39", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 134.800003, 441.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[14]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[8]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-40", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 98.533333, 441.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[15]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[9]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-41", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 62.266666, 441.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[16]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[10]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-42", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 26.0, 441.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[17]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[11]" + } + + } +, { + "box" : { + "id" : "obj-43", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 26.0, 556.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-44", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 20, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 26.75, 384.0, 943.0, 24.0 ], + "style" : "", + "text" : "o.route /0/u /1/u /2/u /3/u /4/u /5/u /6/u /7/u /8/u /9/u /10/u /11/u /12/u /13/u /14/u /15/u /16/u /17/u /18/u" + } + + } +, { + "box" : { + "id" : "obj-111", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 180.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-110", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 144.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-109", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 111.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-108", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 78.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-107", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 45.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-106", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 177.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[18]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[5]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-105", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 144.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[19]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[4]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-104", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 111.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[20]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[3]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-103", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 78.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[21]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[2]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-102", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 45.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[22]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[1]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-101", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 12.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[23]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a" + } + + } +, { + "box" : { + "id" : "obj-84", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 12.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "linecount" : 2, + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 32, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 31.774193, 618.0, 1002.0, 40.0 ], + "style" : "", + "text" : "o.route /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 /12 /13 /14 /15 /16 /17 /18 /19 /20 /21 /22 /23 /24 /25 /26 /27 /28 /29 /30" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 26.75, 349.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.route /a" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-60", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 26.75, 317.0, 170.0, 24.0 ], + "style" : "", + "text" : "r from_oscuino" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 42.5, 210.0, 187.0, 22.0 ], + "style" : "", + "text" : "analog write on 1" + } + + } +, { + "box" : { + "id" : "obj-10", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 21.5, 210.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-11", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 21.5, 240.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-8", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 301.5, 327.0, 259.0, 22.0 ], + "style" : "", + "text" : "to SLIP_oscuino" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-4", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 480.5, 210.0, 187.0, 38.0 ], + "style" : "", + "text" : "read analog pins 0-3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-5", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 460.5, 210.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-6", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 460.5, 240.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-3", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 257.0, 319.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-15", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 258.5, 210.0, 187.0, 22.0 ], + "style" : "", + "text" : "read all analog pins" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 238.5, 210.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-22", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 238.5, 240.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "linecount" : 12, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 24.0, 6.0, 792.0, 195.0 ], + "style" : "", + "text" : "ANALOG\nThese are the basic analog Arduino functions with the option of using the internal pullup available on most Arduinos. All analog pins can be used as digital outputs also. \n\n/a/(pin #)\n\t(no data) = analogRead with pullup off\n\t/u = analogRead with pullup on\n\t(value 0/1) = digitalWrite with that value\n\nexample:\n\"/a/0/u\" performs analogRead with pullup on on pin 0. \n\"/a/8 1\" performs digitalWrite on pin 8 with HIGH." + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-11", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-10", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-112", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-100", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-84", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-101", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-107", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-102", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-108", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-103", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-109", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-104", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-110", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-105", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-111", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-106", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-61", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-113", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-118", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-114", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-119", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-115", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-120", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-116", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-121", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-117", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-122", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-124", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-123", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-125", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-126", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-127", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-128", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-129", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-130", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-18", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-19", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-14", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-21", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-62", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-22", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-17", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-24", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-25", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-32", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-37", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-33", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-38", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-34", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-39", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-35", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-40", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-36", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-41", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-43", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-42", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-126", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 18 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-128", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 17 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-130", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 16 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-37", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-38", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-39", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-40", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-41", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-42", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-48", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-49", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-50", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-51", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-52", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-53", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 6 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-71", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-73", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-75", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-77", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 19 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-44", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-27", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-48", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-29", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-49", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-5", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-30", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-50", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-31", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-51", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-47", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-52", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-54", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-53", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-80", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-61", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-62", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-56", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-64", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-57", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-65", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-58", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-66", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-59", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-67", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-69", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-68", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-70", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-71", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-72", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-73", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-74", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-75", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-76", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-77", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-79", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-78", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-82", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-79", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-80", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-100", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 23 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-101", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-102", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-103", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-104", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-105", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-106", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-118", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 22 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-119", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 21 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-120", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 20 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-121", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 19 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-122", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 18 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-123", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 17 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-19", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-21", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-24", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-25", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 6 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-64", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 16 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-65", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-66", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-67", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-68", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-87", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 30 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-88", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 29 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-95", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 28 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-96", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 27 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-97", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 26 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-98", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 25 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-99", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 24 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-82", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-55", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-87", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-89", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-88", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-90", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-95", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-91", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-96", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-92", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-97", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-93", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-98", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-94", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-99", 0 ] + } + + } + ] + } +, + "patching_rect" : [ 136.0, 110.0, 78.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p analog" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 247.5, 284.0, 137.0, 24.0 ], + "style" : "", + "text" : "o.io.slipserial" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-27", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 35.0, 860.0, 54.0 ], + "style" : "", + "text" : "Serial Oscuino sends and receives OSC packets over SLIPSerial \nto and from an Arduino or Teensy running the oscuinoSerial Sketch \n\n" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-91", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 0, + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 2, + "revision" : 1, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 25.0, 69.0, 738.0, 421.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-2", + "linecount" : 24, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 20.0, 697.0, 386.0 ], + "style" : "", + "text" : "/*\n Written by Yotam Mann, The Center for New Music and Audio Technologies,\n University of California, Berkeley. Copyright (c) 2012, The Regents of\n the University of California (Regents).\n \n Permission to use, copy, modify, distribute, and distribute modified versions\n of this software and its documentation without fee and without a signed\n licensing agreement, is hereby granted, provided that the above copyright\n notice, this paragraph and the following two paragraphs appear in all copies,\n modifications, and distributions.\n \n IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,\n SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING\n OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS\n BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n \n REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED\n HEREUNDER IS PROVIDED \"AS IS\". REGENTS HAS NO OBLIGATION TO PROVIDE\n MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.\n \n For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu\n */" + } + + } + ], + "lines" : [ ] + } +, + "patching_rect" : [ 749.5, 10.0, 111.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p disclaimer" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-16", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-60", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-47", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-5", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-52", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-58", 0 ] + } + + } + ], + "parameters" : { + "obj-47::obj-50" : [ "a[32]", "a", 0 ], + "obj-1::obj-23" : [ "a[53]", "a", 0 ], + "obj-47::obj-106" : [ "a[18]", "a", 0 ], + "obj-1::obj-15" : [ "a[77]", "a", 0 ], + "obj-47::obj-88" : [ "a[62]", "a", 0 ], + "obj-1::obj-104" : [ "a[58]", "a", 0 ], + "obj-47::obj-101" : [ "a[23]", "a", 0 ], + "obj-47::obj-51" : [ "a[33]", "a", 0 ], + "obj-47::obj-67" : [ "a[40]", "a", 0 ], + "obj-1::obj-25" : [ "a[55]", "a", 0 ], + "obj-47::obj-98" : [ "a[65]", "a", 0 ], + "obj-47::obj-39" : [ "a[14]", "a", 0 ], + "obj-47::obj-130" : [ "a[74]", "a", 0 ], + "obj-1::obj-24" : [ "a[54]", "a", 0 ], + "obj-1::obj-10" : [ "a[75]", "a", 0 ], + "obj-47::obj-64" : [ "a[37]", "a", 0 ], + "obj-47::obj-118" : [ "a[68]", "a", 0 ], + "obj-47::obj-19" : [ "a[24]", "a", 0 ], + "obj-47::obj-102" : [ "a[22]", "a", 0 ], + "obj-1::obj-103" : [ "a[59]", "a", 0 ], + "obj-47::obj-68" : [ "a[41]", "a", 0 ], + "obj-47::obj-53" : [ "a[35]", "a", 0 ], + "obj-47::obj-40" : [ "a[15]", "a", 0 ], + "obj-47::obj-99" : [ "a[66]", "a", 0 ], + "obj-47::obj-41" : [ "a[16]", "a", 0 ], + "obj-47::obj-49" : [ "a[31]", "a", 0 ], + "obj-47::obj-37" : [ "a[12]", "a", 0 ], + "obj-1::obj-22" : [ "a[78]", "a", 0 ], + "obj-47::obj-103" : [ "a[21]", "a", 0 ], + "obj-47::obj-75" : [ "a[44]", "a", 0 ], + "obj-47::obj-119" : [ "a[69]", "a", 0 ], + "obj-1::obj-102" : [ "a[60]", "a", 0 ], + "obj-47::obj-95" : [ "a[49]", "a", 0 ], + "obj-47::obj-120" : [ "a[70]", "a", 0 ], + "obj-1::obj-101" : [ "a[61]", "a", 0 ], + "obj-47::obj-121" : [ "a[71]", "a", 0 ], + "obj-47::obj-122" : [ "a[72]", "a", 0 ], + "obj-47::obj-123" : [ "a[73]", "a", 0 ], + "obj-47::obj-128" : [ "a[47]", "a", 0 ], + "obj-47::obj-71" : [ "a[42]", "a", 0 ], + "obj-47::obj-100" : [ "a[67]", "a", 0 ], + "obj-1::obj-106" : [ "a[56]", "a", 0 ], + "obj-47::obj-42" : [ "a[17]", "a", 0 ], + "obj-1::obj-12" : [ "a[76]", "a", 0 ], + "obj-47::obj-104" : [ "a[20]", "a", 0 ], + "obj-47::obj-77" : [ "a[45]", "a", 0 ], + "obj-47::obj-65" : [ "a[38]", "a", 0 ], + "obj-47::obj-20" : [ "a[25]", "a", 0 ], + "obj-47::obj-21" : [ "a[26]", "a", 0 ], + "obj-47::obj-96" : [ "a[63]", "a", 0 ], + "obj-47::obj-23" : [ "a[27]", "a", 0 ], + "obj-47::obj-24" : [ "a[28]", "a", 0 ], + "obj-47::obj-52" : [ "a[34]", "a", 0 ], + "obj-1::obj-20" : [ "a[51]", "a", 0 ], + "obj-47::obj-25" : [ "a[29]", "a", 0 ], + "obj-47::obj-73" : [ "a[43]", "a", 0 ], + "obj-47::obj-87" : [ "a[48]", "a", 0 ], + "obj-47::obj-105" : [ "a[19]", "a", 0 ], + "obj-1::obj-105" : [ "a[57]", "a", 0 ], + "obj-47::obj-48" : [ "a[30]", "a", 0 ], + "obj-1::obj-19" : [ "a[50]", "a", 0 ], + "obj-47::obj-66" : [ "a[39]", "a", 0 ], + "obj-47::obj-126" : [ "a[46]", "a", 0 ], + "obj-47::obj-38" : [ "a[13]", "a", 0 ], + "obj-47::obj-97" : [ "a[64]", "a", 0 ], + "obj-1::obj-21" : [ "a[52]", "a", 0 ] + } +, + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.compose.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.downcast.mxo", + "type" : "iLaX" + } + ], + "autosave" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/SerialReceive.maxpat b/lib/OSC/Applications/MaxMSP/examples/SerialReceive.maxpat new file mode 100644 index 0000000..3a9c242 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/SerialReceive.maxpat @@ -0,0 +1,428 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 378.0, 174.0, 792.0, 490.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-5", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 68.0, 374.0, 267.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-12", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 164.0, 202.0, 69.0, 22.0 ], + "style" : "", + "text" : "o.pack /led" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 164.0, 244.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.downcast" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-18", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 164.0, 314.0, 92.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-3", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 350.5, 374.0, 158.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-2", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 370.5, 218.5, 170.0, 33.0 ], + "style" : "", + "text" : "Look for your device in the menu list of serial USB" + } + + } +, { + "box" : { + "bgmode" : 0, + "border" : 0, + "clickthrough" : 0, + "enablehscroll" : 0, + "enablevscroll" : 0, + "id" : "obj-4", + "lockeddragscroll" : 0, + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "offset" : [ 3.0, 0.0 ], + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 350.5, 289.0, 340.5, 25.0 ], + "viewvisibility" : 1 + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-23", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 289.5, 328.0, 80.0, 22.0 ], + "style" : "", + "text" : "o.io.slipserial" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-11", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 541.0, 364.0, 150.0, 54.0 ], + "style" : "", + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-19", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 43.5, 42.0, 156.0, 33.0 ], + "style" : "", + "text" : "PWM control of brightness of LED" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-15", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 114.0, 151.0, 32.5, 22.0 ], + "style" : "", + "text" : "on" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-13", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 56.0, 151.0, 32.5, 22.0 ], + "style" : "", + "text" : "off" + } + + } +, { + "box" : { + "contdata" : 1, + "id" : "obj-9", + "maxclass" : "multislider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "" ], + "parameter_enable" : 0, + "patching_rect" : [ 220.5, 31.0, 20.0, 140.0 ], + "setminmax" : [ 0.0, 1.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-8", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 164.0, 151.0, 20.0, 20.0 ], + "style" : "" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-18", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-12", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-13", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 360.0, 369.0, 360.0, 369.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 360.0, 355.0, 702.0, 355.0, 702.0, 265.0, 360.0, 265.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-23", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-4", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-9", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.downcast.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/SerialReceivewithServo.maxpat b/lib/OSC/Applications/MaxMSP/examples/SerialReceivewithServo.maxpat new file mode 100644 index 0000000..4d8ecd0 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/SerialReceivewithServo.maxpat @@ -0,0 +1,297 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 125.0, 78.0, 1072.0, 480.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-12", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 27.5, 386.0, 158.0, 34.0 ], + "presentation_rect" : [ 534.5, 418.0, 0.0, 0.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "id" : "obj-6", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 137.5, 194.0, 82.0, 22.0 ], + "style" : "", + "text" : "o.pack /servo" + } + + } +, { + "box" : { + "contdata" : 1, + "id" : "obj-11", + "maxclass" : "multislider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "" ], + "parameter_enable" : 0, + "patching_rect" : [ 139.0, 27.0, 20.0, 140.0 ], + "setminmax" : [ 0.0, 180.0 ], + "settype" : 0, + "style" : "" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-3", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 198.5, 386.0, 158.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-1", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 218.5, 230.5, 170.0, 33.0 ], + "style" : "", + "text" : "Look for your device in the menu list of serial USB" + } + + } +, { + "box" : { + "bgmode" : 0, + "border" : 0, + "clickthrough" : 0, + "enablehscroll" : 0, + "enablevscroll" : 0, + "id" : "obj-20", + "lockeddragscroll" : 0, + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "offset" : [ 3.0, 0.0 ], + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 198.5, 301.0, 164.0, 24.0 ], + "viewvisibility" : 1 + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-23", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 137.5, 337.0, 80.0, 22.0 ], + "style" : "", + "text" : "o.io.slipserial" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-5", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 389.0, 376.0, 150.0, 54.0 ], + "style" : "", + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-19", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 335.0, 151.0, 156.0, 20.0 ], + "style" : "", + "text" : "Servo control (from 0-180)" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-23", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 208.0, 367.0, 377.0, 367.0, 377.0, 277.0, 208.0, 277.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 208.0, 381.0, 208.0, 381.0 ], + "source" : [ "obj-23", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/SerialSend.maxpat b/lib/OSC/Applications/MaxMSP/examples/SerialSend.maxpat new file mode 100644 index 0000000..3e43bf2 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/SerialSend.maxpat @@ -0,0 +1,227 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 6, + "minor" : 1, + "revision" : 9, + "architecture" : "x86" + } +, + "rect" : [ 196.0, 152.0, 1072.0, 480.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 0, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 0, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "boxanimatetime" : 200, + "imprint" : 0, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "boxes" : [ { + "box" : { + "fontsize" : 12.0, + "id" : "obj-8", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 572.0, 228.0, 207.0, 34.0 ], + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontsize" : 12.0, + "id" : "obj-6", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 95.0, 228.0, 394.0, 34.0 ], + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontsize" : 12.0, + "id" : "obj-9", + "maxclass" : "o.expr.codebox", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 95.0, 172.0, 251.0, 37.0 ], + "text" : " /bundle/time = gettimetag()", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "id" : "obj-7", + "maxclass" : "bpatcher", + "name" : "o.io.serial.display.maxpat", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 271.0, 58.0, 331.0, 28.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "frgb" : 0.0, + "id" : "obj-4", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 592.0, 119.0, 150.0, 54.0 ], + "text" : "stats on serial OSC communications" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 95.0, 119.0, 195.0, 22.0 ], + "text" : "o.io.slipserial f 9600" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 280.5, 141.0, 300.0, 141.0, 300.0, 96.0, 258.0, 96.0, 258.0, 54.0, 280.5, 54.0 ], + "source" : [ "obj-26", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-8", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 1 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-9", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-7", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-9", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.slipserial.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/ordering", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.io.serial.display.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/o.io/experimental/Protocols/serial", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/o.io/experimental/Protocols/serial", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.validate.mxo", + "type" : "iLaX" + } +, { + "name" : "o.print.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.encode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.slip.decode.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.expr.codebox.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } + ] + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/UDPCallResponse.maxpat b/lib/OSC/Applications/MaxMSP/examples/UDPCallResponse.maxpat new file mode 100644 index 0000000..13ac13b --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/UDPCallResponse.maxpat @@ -0,0 +1,947 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 140.0, 78.0, 982.0, 632.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-10", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 246.5, 265.0, 128.0, 24.0 ], + "style" : "", + "text" : "o.betweentimes" + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 699.5, 158.0, 157.0, 26.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 97, 110, 97, 108, 111, 103, 47, 123, 50, 44, 51, 125, 47, 117, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 40, + "text" : "/analog/{2,3}/u", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-8", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 448.5, 159.0, 150.0, 26.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 97, 110, 97, 108, 111, 103, 47, 91, 48, 45, 51, 93, 47, 117, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 40, + "text" : "/analog/[0-3]/u", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-6", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 246.5, 159.0, 150.0, 26.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 97, 110, 97, 108, 111, 103, 47, 42, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 36, + "text" : "/analog/*", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-4", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 246.5, 308.0, 265.0, 36.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-3", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 246.5, 55.0, 95.0, 24.0 ], + "style" : "", + "text" : "loadmess 1" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 726.5, 77.0, 222.0, 38.0 ], + "style" : "", + "text" : "read analog pins 2 and 3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-78", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 699.5, 95.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-79", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 699.5, 126.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "id" : "obj-56", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 179.333328, 500.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-64", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 179.333328, 396.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[37]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[25]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 11.0, 542.0, 137.0, 22.0 ], + "style" : "", + "text" : "analog readings" + } + + } +, { + "box" : { + "id" : "obj-110", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 145.666672, 500.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-109", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 112.0, 500.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-108", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 78.333336, 500.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-107", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 44.666668, 500.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-105", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 145.666672, 396.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[19]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[4]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-104", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 112.0, 396.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[20]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[3]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-103", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 78.333336, 396.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[21]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[2]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-102", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 44.666668, 396.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[22]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[1]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-101", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 11.0, 396.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[23]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a" + } + + } +, { + "box" : { + "id" : "obj-84", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 11.0, 500.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 7, + "outlettype" : [ "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 11.0, 323.0, 221.0, 24.0 ], + "style" : "", + "text" : "o.route /0 /1 /2 /3 /4 /5" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 11.0, 265.0, 137.0, 24.0 ], + "style" : "", + "text" : "o.route /analog" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-15", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 475.5, 86.0, 187.0, 38.0 ], + "style" : "", + "text" : "read analog pins 0-3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 448.5, 95.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-22", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 448.5, 125.0, 86.0, 24.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 261.5, 95.0, 187.0, 22.0 ], + "style" : "", + "text" : "read all analog pins" + } + + } +, { + "box" : { + "id" : "obj-60", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 246.5, 95.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-61", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 246.5, 124.0, 95.0, 24.0 ], + "style" : "", + "text" : "qmetro 100" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 246.5, 214.0, 288.0, 24.0 ], + "style" : "", + "text" : "o.io.udp 128.32.122.252 8888 9999" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-91", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 0, + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 34.0, 78.0, 738.0, 421.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-2", + "linecount" : 25, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 20.0, 768.0, 400.0 ], + "style" : "", + "text" : "/*\n Written by Yotam Mann and Adrian Freed,\n The Center for New Music and Audio Technologies,\n University of California, Berkeley. Copyright (c) 2012, The Regents of\n the University of California (Regents).\n \n Permission to use, copy, modify, distribute, and distribute modified versions\n of this software and its documentation without fee and without a signed\n licensing agreement, is hereby granted, provided that the above copyright\n notice, this paragraph and the following two paragraphs appear in all copies,\n modifications, and distributions.\n \n IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,\n SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING\n OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS\n BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n \n REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED\n HEREUNDER IS PROVIDED \"AS IS\". REGENTS HAS NO OBLIGATION TO PROVIDE\n MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.\n \n For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu\n */" + } + + } + ], + "lines" : [ ] + } +, + "patching_rect" : [ 666.5, 494.0, 111.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p disclaimer" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-10", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-84", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-101", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-107", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-102", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-108", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-103", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-109", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-104", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-110", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-105", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-18", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-8", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-22", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-10", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-60", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-3", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-61", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-61", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-56", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-64", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-79", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-78", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-9", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-79", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-101", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-102", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-103", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-104", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-105", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-64", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-9", 0 ] + } + + } + ], + "parameters" : { + "obj-105" : [ "a[19]", "a", 0 ], + "obj-104" : [ "a[20]", "a", 0 ], + "obj-103" : [ "a[21]", "a", 0 ], + "obj-64" : [ "a[37]", "a", 0 ], + "obj-102" : [ "a[22]", "a", 0 ], + "obj-101" : [ "a[23]", "a", 0 ] + } +, + "dependency_cache" : [ { + "name" : "o.io.udp.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/udp", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.betweentimes.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/time", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.was.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/dev", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "~/Documents/Max/Packages/odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.compose.mxo", + "type" : "iLaX" + } +, { + "name" : "o.timetag.mxo", + "type" : "iLaX" + } +, { + "name" : "o.prepend.mxo", + "type" : "iLaX" + } +, { + "name" : "o.intersection.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.var.mxo", + "type" : "iLaX" + } +, { + "name" : "o.collect.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.expr.codebox.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/UDPEcho.maxpat b/lib/OSC/Applications/MaxMSP/examples/UDPEcho.maxpat new file mode 100644 index 0000000..ca884ba --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/UDPEcho.maxpat @@ -0,0 +1,215 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 6, + "minor" : 1, + "revision" : 9, + "architecture" : "x86" + } +, + "rect" : [ 153.0, 100.0, 758.0, 531.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 0, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 0, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "boxanimatetime" : 200, + "imprint" : 0, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-8", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 20.5, 240.0, 128.0, 22.0 ], + "text" : "o.betweentimes" + } + + } +, { + "box" : { + "fontsize" : 14.0, + "id" : "obj-7", + "linecount" : 2, + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 20.5, 112.0, 510.0, 42.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 112, 105, 110, 103, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 100, 0, 0, 0, 76, 47, 116, 104, 105, 110, 103, 0, 0, 44, 100, 105, 105, 105, 105, 105, 105, 105, 105, 115, 0, 64, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 98, 105, 103, 103, 101, 114, 32, 112, 97, 99, 107, 101, 116, 0, 0, 0 ], + "saved_bundle_length" : 116, + "text" : "/ping : 100,\n/thing : [100., 100, 1, 2, 3, 4, 4, 4, 4, \"bigger packet\"]", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontsize" : 14.0, + "id" : "obj-5", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 20.5, 296.0, 517.0, 36.0 ], + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-61", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 20.5, 22.0, 153.0, 22.0 ], + "text" : "metro 2 @active 1" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 20.5, 191.0, 288.0, 22.0 ], + "text" : "o.io.udp 128.32.122.252 8888 9999" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-8", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-61", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-7", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.udp.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/o.io/experimental/Protocols/udp", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/o.io/experimental/Protocols/udp", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.betweentimes.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/time", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/patchers/time", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.was.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/dev", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/dev", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.righttoleft.maxpat", + "bootpath" : "/Users/adrian2013/Documents/Max/Packages/CNMAT-odot/patchers/ordering", + "patcherrelativepath" : "../../../../../../Documents/Max/Packages/CNMAT-odot/patchers/ordering", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.compose.mxo", + "type" : "iLaX" + } +, { + "name" : "o.timetag.mxo", + "type" : "iLaX" + } +, { + "name" : "o.prepend.mxo", + "type" : "iLaX" + } +, { + "name" : "o.intersection.mxo", + "type" : "iLaX" + } +, { + "name" : "o.union.mxo", + "type" : "iLaX" + } +, { + "name" : "o.var.mxo", + "type" : "iLaX" + } +, { + "name" : "o.collect.mxo", + "type" : "iLaX" + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.expr.codebox.mxo", + "type" : "iLaX" + } + ] + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/UDPOscuino.maxpat b/lib/OSC/Applications/MaxMSP/examples/UDPOscuino.maxpat new file mode 100644 index 0000000..e44809d --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/UDPOscuino.maxpat @@ -0,0 +1,4894 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 87.0, 78.0, 913.0, 425.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-3", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 506.0, 233.0, 95.0, 24.0 ], + "style" : "", + "text" : "o.downcast" + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 712.0, 168.0, 150.0, 26.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 116, 111, 110, 101, 47, 51, 0, 44, 100, 0, 0, 64, 123, -128, 0, 0, 0, 0, 0 ], + "saved_bundle_length" : 40, + "text" : "/tone/3 : 440.", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-5", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 712.0, 116.0, 150.0, 26.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 116, 111, 110, 101, 47, 51, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/tone/3", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 14.0, + "id" : "obj-2", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 506.0, 348.0, 265.0, 36.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-8", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 672.0, 233.0, 150.0, 22.0 ], + "style" : "", + "text" : "Ethernet" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-6", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 506.0, 279.0, 288.0, 24.0 ], + "style" : "", + "text" : "o.io.udp 128.32.122.252 8888 9999" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 624.0, 45.0, 640.0, 480.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-4", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 329.0, 106.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 99, 47, 51, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/c/3", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-18", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 33.0, 33.0, 90.0, 47.0 ], + "style" : "", + "text" : "Capacitance from touch pins\n" + } + + } +, { + "box" : { + "id" : "obj-13", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 312.0, 34.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-11", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 329.0, 68.0, 65.0, 20.0 ], + "style" : "", + "text" : "qmetro 30" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-6", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 311.0, 154.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 48.0, 169.0, 95.0, 22.0 ], + "style" : "", + "text" : "o.route /c" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-60", + "maxclass" : "inlet", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 48.0, 120.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-1", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 411.0, 430.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-2", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 378.0, 430.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-14", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 345.0, 430.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-16", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 312.0, 430.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-17", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 279.0, 430.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-19", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 411.0, 324.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[50]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[12]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-20", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 378.0, 326.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[51]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[13]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-21", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 345.0, 326.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[52]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[14]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-23", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 312.0, 326.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[53]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[15]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-24", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 279.0, 326.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[54]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[16]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-25", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 246.0, 326.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[55]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[17]" + } + + } +, { + "box" : { + "id" : "obj-26", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 246.0, 430.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-111", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 216.0, 429.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-110", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 180.0, 429.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-109", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 147.0, 429.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-108", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 114.0, 429.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-107", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 81.0, 429.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-106", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 213.0, 325.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[56]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[5]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-105", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 180.0, 325.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[57]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[4]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-104", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 147.0, 325.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[58]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[3]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-103", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 114.0, 325.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[59]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[2]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-102", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 81.0, 325.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[60]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[1]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-101", + "ignoreclick" : 1, + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 48.0, 325.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[61]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 2048.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a" + } + + } +, { + "box" : { + "id" : "obj-84", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 48.0, 429.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 13, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 48.0, 219.0, 456.0, 22.0 ], + "style" : "", + "text" : "o.route /0 /1 /16 /17 /18 /19 /22 /23 /25 /32 /33 /15" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-84", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-101", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-107", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-102", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-108", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-103", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-109", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-104", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-110", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-105", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-111", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-106", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-11", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-13", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-19", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-14", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-21", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-17", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-24", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-25", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-4", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-101", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-102", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-103", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-104", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-105", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-106", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-19", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-21", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-24", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-25", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 6 ] + } + + } + ] + } +, + "patching_rect" : [ 506.0, 149.0, 145.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p teensy 3 touch" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-58", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 550.0, 69.0, 834.0, 483.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-4", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 653.0, 419.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-32", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 149.5, 326.0, 41.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 115, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/s", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-30", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 134.0, 264.0, 39.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 116, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/t", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-28", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 106.0, 209.0, 45.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 109, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/m", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-26", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 70.0, 152.0, 42.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 100, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/d", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-20", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 44.0, 98.0, 42.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 115, 47, 97, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/s/a", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-15", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 196.5, 400.0, 65.0, 20.0 ], + "style" : "", + "text" : "o.pack /s/l" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 149.5, 296.0, 179.0, 22.0 ], + "style" : "", + "text" : "Power Supply Voltage" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 134.0, 242.0, 103.0, 22.0 ], + "style" : "", + "text" : "Temperature" + } + + } +, { + "box" : { + "id" : "obj-8", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 219.0, 333.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-25", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 254.5, 350.0, 381.0, 38.0 ], + "style" : "", + "text" : "toggle the LED (don't do this on Teensy 3.0 with Wiznet Ethernet that uses pin 13)" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-1", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 106.0, 182.0, 246.0, 22.0 ], + "style" : "", + "text" : "Arduino time in microseconds" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-3", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 53.0, 76.0, 288.0, 22.0 ], + "style" : "", + "text" : "Returns the number of analog pins" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-2", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 44.0, 462.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-10", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 70.0, 126.0, 296.0, 22.0 ], + "style" : "", + "text" : "Returns the number of digital pins" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 49.0, 45.0, 792.0, 22.0 ], + "style" : "", + "text" : "QUERIES AND PARAMS" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-5", + "maxclass" : "inlet", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 528.0, 324.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 528.0, 378.0, 95.0, 22.0 ], + "style" : "", + "text" : "o.route /s" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-28", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-30", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-32", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-5", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-15", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } + ] + } +, + "patching_rect" : [ 274.5, 149.0, 179.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p queries-and-params" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-52", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 493.0, 67.0, 947.0, 536.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-40", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 45.0, 445.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 100, 47, 42, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/d/*", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-15", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 356.5, 293.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 100, 47, 49, 91, 51, 56, 57, 93, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1 ], + "saved_bundle_length" : 40, + "text" : "/d/1[389] : 1", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-14", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 383.0, 336.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 100, 47, 49, 48, 47, 117, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/d/10/u", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-11", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 110.0, 293.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 100, 47, 49, 91, 48, 45, 57, 93, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1 ], + "saved_bundle_length" : 40, + "text" : "/d/1[0-9] : 1", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-2", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "FullPacket" ], + "patching_rect" : [ 220.0, 405.0, 76.0, 20.0 ], + "style" : "", + "text" : "o.pack /d/13" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-10", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 112.5, 425.0, 83.0, 20.0 ], + "style" : "", + "text" : "report all pins" + } + + } +, { + "box" : { + "id" : "obj-1", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 45.0, 382.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-4", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 45.0, 413.0, 72.0, 20.0 ], + "style" : "", + "text" : "qmetro 100" + } + + } +, { + "box" : { + "id" : "obj-35", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 833.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-36", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 808.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-28", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 778.0, 533.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-30", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 749.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-31", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 723.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-32", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 698.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-24", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 675.0, 533.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-25", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 646.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-26", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 620.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-27", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 595.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-20", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 573.0, 531.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-21", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 544.0, 530.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-22", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 518.0, 530.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-23", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 493.0, 530.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-19", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 469.0, 532.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 440.0, 531.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-17", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 414.0, 531.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-16", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 384.0, 531.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 18, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 384.0, 471.0, 557.0, 22.0 ], + "style" : "", + "text" : "o.route /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 /12 /13 /14 /15 /16" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 384.0, 413.0, 95.0, 22.0 ], + "style" : "", + "text" : "o.route /d" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-6", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 271.0, 499.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-7", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 220.0, 366.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 311.5, 259.0, 313.0, 22.0 ], + "style" : "", + "text" : "Set digital pins 3, 8, and 9 to HIGH" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 45.0, 259.0, 254.0, 22.0 ], + "style" : "", + "text" : "Set digital pin 0 to HIGH/LOW" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "linecount" : 12, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 110.0, 37.0, 801.0, 195.0 ], + "style" : "", + "text" : "DIGITAL\nThe basic digital Arduino functions with the option of using the internal pullup available on most Arduinos. \n\n/d/(pin #)\n\t(no data) = digitalRead with pullup off\n\t/u = digitalRead with pullup on\n\t(value 0/1) = digitalWrite with that value\n\nexample:\n\"/d/1\" performs digitalRead with pullup off on pin 0. \n\"/d/[0-4] 0\" performs digitalWrite LOW on pins 0 through 4." + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-60", + "maxclass" : "inlet", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 410.0, 365.0, 25.0, 25.0 ], + "style" : "" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-4", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-14", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-2", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-40", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-4", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-40", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-7", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-17", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-18", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-19", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-21", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 6 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-24", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-25", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-27", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-28", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-30", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-31", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-32", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-36", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 16 ] + } + + } + ] + } +, + "patching_rect" : [ 46.5, 150.0, 86.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p digital" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-47", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 168.0, 44.0, 1041.0, 838.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-82", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 784.5, 290.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 47, 97, 47, 92, 123, 50, 92, 44, 51, 92, 125, 47, 117, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 40, + "text" : "/a/\\{2\\,3\\}/u ", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-80", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 465.0, 288.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 97, 47, 91, 48, 45, 51, 93, 47, 117, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 36, + "text" : "/a/[0-3]/u", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-62", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 253.5, 288.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 47, 42, 0, 0, 0, 0, 44, 0, 0, 0 ], + "saved_bundle_length" : 32, + "text" : "/a/*", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-61", + "maxclass" : "o.compose", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 36.5, 290.0, 150.0, 24.0 ], + "saved_bundle_data" : [ 35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 47, 97, 47, 49, 0, 0, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1 ], + "saved_bundle_length" : 36, + "text" : "/a/1 : 1", + "textcolor" : [ 0.188, 0.188, 0.188, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-63", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 804.5, 227.0, 222.0, 38.0 ], + "style" : "", + "text" : "read analog pins 2 and 3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-78", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 784.5, 227.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-79", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 784.5, 257.0, 86.0, 22.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-9", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 57.5, 225.0, 187.0, 22.0 ], + "style" : "", + "text" : "analog write on 1" + } + + } +, { + "box" : { + "id" : "obj-10", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 36.5, 225.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-11", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 36.5, 255.0, 86.0, 22.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-3", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 316.5, 342.0, 259.0, 22.0 ], + "style" : "", + "text" : "to SLIP_oscuino" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-4", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 495.5, 225.0, 187.0, 38.0 ], + "style" : "", + "text" : "read analog pins 0-3 with pullup turned on" + } + + } +, { + "box" : { + "id" : "obj-5", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 475.5, 225.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-6", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 475.5, 255.0, 86.0, 22.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-7", + "maxclass" : "outlet", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 272.0, 334.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-15", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 273.5, 225.0, 187.0, 22.0 ], + "style" : "", + "text" : "read all analog pins" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "toggle", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 253.5, 225.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-22", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 253.5, 255.0, 86.0, 22.0 ], + "style" : "", + "text" : "qmetro 20" + } + + } +, { + "box" : { + "id" : "obj-76", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 584.0, 604.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-77", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 586.0, 488.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[45]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[32]" + } + + } +, { + "box" : { + "id" : "obj-74", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 543.0, 603.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-75", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 545.0, 487.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[44]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[31]" + } + + } +, { + "box" : { + "id" : "obj-72", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 496.0, 604.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-73", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 498.0, 488.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[43]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[30]" + } + + } +, { + "box" : { + "id" : "obj-70", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 448.0, 602.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-71", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 450.0, 486.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[42]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[24]" + } + + } +, { + "box" : { + "id" : "obj-56", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 537.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-57", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 503.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-58", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 471.0, 786.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-59", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 444.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-64", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 535.0, 677.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[37]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[25]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-65", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 499.0, 682.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[38]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[26]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-66", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 471.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[39]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[27]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-67", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 444.0, 681.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[40]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[28]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-68", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 411.0, 681.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[41]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[29]" + } + + } +, { + "box" : { + "id" : "obj-69", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 411.0, 785.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-27", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 404.0, 600.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-29", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 371.0, 600.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-30", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 338.0, 600.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-31", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 305.0, 600.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-47", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 272.0, 600.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-48", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 406.0, 484.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[30]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[18]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-49", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 373.0, 484.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[31]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[19]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-50", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 340.0, 484.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[32]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[20]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-51", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 307.0, 484.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[33]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[21]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-52", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 274.0, 484.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[34]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[22]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-53", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 241.0, 484.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[35]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[23]" + } + + } +, { + "box" : { + "id" : "obj-54", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 239.0, 600.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-1", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 375.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-2", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 342.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-14", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 309.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-16", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 276.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-17", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 243.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-19", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 375.0, 678.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[24]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[12]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-20", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 342.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[25]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[13]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-21", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 309.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[26]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[14]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-23", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 276.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[27]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[15]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-24", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 243.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[28]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[16]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-25", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 210.0, 680.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[29]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[17]" + } + + } +, { + "box" : { + "id" : "obj-26", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 210.0, 784.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-13", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 545.0, 338.0, 447.0, 22.0 ], + "style" : "", + "text" : "analog readings come out of the SLIP_oscuino patcher" + } + + } +, { + "box" : { + "id" : "obj-32", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 205.0, 599.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-33", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 172.0, 599.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-34", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 139.0, 599.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-35", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 108.0, 596.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-36", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 70.0, 597.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-37", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 207.0, 483.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[12]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[6]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-38", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 174.0, 483.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[13]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[7]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-39", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 141.0, 483.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[14]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[8]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-40", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 108.0, 483.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[15]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[9]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-41", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 75.0, 483.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[16]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[10]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-42", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 42.0, 483.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[17]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[11]" + } + + } +, { + "box" : { + "id" : "obj-43", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 41.0, 597.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-44", + "linecount" : 2, + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 17, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 40.0, 426.0, 599.0, 38.0 ], + "style" : "", + "text" : "o.route /0/u /1/u /2/u /3/u /4/u /5/u /6/u /7/u /8/u /9/u /10/u /11/u /12/u /13/u /14/u /15/u" + } + + } +, { + "box" : { + "id" : "obj-111", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 180.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-110", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 144.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-109", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 111.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-108", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 78.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "id" : "obj-107", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 45.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-106", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 177.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[18]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[5]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-105", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 144.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[19]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[4]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-104", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 111.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[20]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[3]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-103", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 78.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[21]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[2]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-102", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 45.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[22]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a[1]" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "id" : "obj-101", + "maxclass" : "live.slider", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "float" ], + "parameter_enable" : 1, + "patching_rect" : [ 12.0, 679.0, 34.0, 95.0 ], + "saved_attribute_attributes" : { + "valueof" : { + "parameter_longname" : "a[23]", + "parameter_shortname" : "a", + "parameter_type" : 0, + "parameter_mmax" : 1023.0, + "parameter_unitstyle" : 0 + } + + } +, + "varname" : "a" + } + + } +, { + "box" : { + "id" : "obj-84", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 12.0, 783.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-81", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 18, + "outlettype" : [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "FullPacket" ], + "patching_rect" : [ 17.0, 639.0, 557.0, 22.0 ], + "style" : "", + "text" : "o.route /0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 /12 /13 /14 /15 /16" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-45", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "", "FullPacket" ], + "patching_rect" : [ 40.0, 380.0, 95.0, 22.0 ], + "style" : "", + "text" : "o.route /a" + } + + } +, { + "box" : { + "comment" : "", + "id" : "obj-60", + "maxclass" : "inlet", + "numinlets" : 0, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 40.0, 338.0, 25.0, 25.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-46", + "linecount" : 12, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 24.0, 6.0, 792.0, 195.0 ], + "style" : "", + "text" : "ANALOG\nThese are the basic analog Arduino functions with the option of using the internal pullup available on most Arduinos. All analog pins can be used as digital outputs also. \n\n/a/(pin #)\n\t(no data) = analogRead with pullup off\n\t/u = analogRead with pullup on\n\t(value 0/1) = digitalWrite with that value\n\nexample:\n\"/a/0/u\" performs analogRead with pullup on on pin 0. \n\"/a/8 1\" performs digitalWrite on pin 8 with HIGH." + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-11", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-10", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-84", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-101", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-107", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-102", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-108", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-103", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-109", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-104", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-110", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-105", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-111", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-106", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-61", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-22", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-18", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-19", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-14", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-21", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-62", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-22", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-16", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-23", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-17", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-24", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-25", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-32", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-37", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-33", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-38", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-34", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-39", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-35", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-40", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-36", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-41", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-43", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-42", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-37", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-38", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-39", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-40", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-41", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-42", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-48", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-49", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-50", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-51", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-52", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-53", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 6 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-71", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-73", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-75", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-77", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-81", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-44", 16 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-44", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-45", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-27", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-48", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-29", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-49", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-5", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-30", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-50", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-31", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-51", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-47", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-52", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-54", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-53", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-80", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-45", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-60", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-61", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-62", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-56", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-64", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-57", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-65", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-58", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-66", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-59", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-67", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-69", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-68", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-70", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-71", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-72", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-73", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-74", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-75", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-76", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-77", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-79", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-78", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-82", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-79", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-80", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-101", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-102", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-103", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 2 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-104", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 3 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-105", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 4 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-106", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 5 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-19", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 11 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 10 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-21", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 9 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-23", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 8 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-24", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 7 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-25", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 6 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-64", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 16 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-65", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 15 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-66", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 14 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-67", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 13 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-68", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-81", 12 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-7", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-82", 0 ] + } + + } + ] + } +, + "patching_rect" : [ 165.0, 149.0, 78.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p analog" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-27", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 35.0, 844.0, 54.0 ], + "style" : "", + "text" : "oscuino sends and receives OSC bundles over Ethernet UDP to and from an Arduino or Teensy\nrunning the oscuinoSerial or oscuino Ethernet Sketch \n\n" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-91", + "maxclass" : "newobj", + "numinlets" : 0, + "numoutlets" : 0, + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 25.0, 69.0, 738.0, 421.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 14.0, + "default_fontface" : 0, + "default_fontname" : "Andale Mono", + "gridonopen" : 1, + "gridsize" : [ 5.0, 5.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-2", + "linecount" : 24, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 15.0, 20.0, 697.0, 386.0 ], + "style" : "", + "text" : "/*\n Written by Yotam Mann, The Center for New Music and Audio Technologies,\n University of California, Berkeley. Copyright (c) 2012, The Regents of\n the University of California (Regents).\n \n Permission to use, copy, modify, distribute, and distribute modified versions\n of this software and its documentation without fee and without a signed\n licensing agreement, is hereby granted, provided that the above copyright\n notice, this paragraph and the following two paragraphs appear in all copies,\n modifications, and distributions.\n \n IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,\n SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING\n OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS\n BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n \n REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED\n HEREUNDER IS PROVIDED \"AS IS\". REGENTS HAS NO OBLIGATION TO PROVIDE\n MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.\n \n For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu\n */" + } + + } + ], + "lines" : [ ] + } +, + "patching_rect" : [ 749.5, 10.0, 111.0, 24.0 ], + "saved_object_attributes" : { + "description" : "", + "digest" : "", + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "globalpatchername" : "", + "style" : "", + "tags" : "" + } +, + "style" : "", + "text" : "p disclaimer" + } + + } + ], + "lines" : [ { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-1", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-3", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 174.5, 202.0, 515.5, 202.0 ], + "source" : [ "obj-47", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 721.5, 155.0, 698.0, 155.0, 698.0, 218.0, 515.5, 218.0 ], + "source" : [ "obj-5", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 56.0, 202.0, 515.5, 202.0 ], + "source" : [ "obj-52", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 284.0, 202.0, 515.5, 202.0 ], + "source" : [ "obj-58", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-1", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 515.5, 314.0, 490.0, 314.0, 490.0, 182.0, 489.0, 182.0, 489.0, 119.0, 515.5, 119.0 ], + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-47", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 515.5, 323.0, 147.0, 323.0, 147.0, 121.0, 174.5, 121.0 ], + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-52", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 515.5, 323.0, 24.0, 323.0, 24.0, 120.0, 56.0, 120.0 ], + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-58", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 515.5, 323.0, 261.0, 323.0, 261.0, 182.0, 261.0, 182.0, 261.0, 121.0, 284.0, 121.0 ], + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "color" : [ 1.0, 0.8, 0.4, 1.0 ], + "destination" : [ "obj-3", 0 ], + "disabled" : 0, + "hidden" : 0, + "midpoints" : [ 721.5, 218.0, 515.5, 218.0 ], + "source" : [ "obj-9", 0 ] + } + + } + ], + "parameters" : { + "obj-1::obj-21" : [ "a[52]", "a", 0 ], + "obj-47::obj-49" : [ "a[31]", "a", 0 ], + "obj-1::obj-105" : [ "a[57]", "a", 0 ], + "obj-47::obj-71" : [ "a[42]", "a", 0 ], + "obj-47::obj-21" : [ "a[26]", "a", 0 ], + "obj-47::obj-39" : [ "a[14]", "a", 0 ], + "obj-47::obj-66" : [ "a[39]", "a", 0 ], + "obj-47::obj-77" : [ "a[45]", "a", 0 ], + "obj-1::obj-23" : [ "a[53]", "a", 0 ], + "obj-47::obj-19" : [ "a[24]", "a", 0 ], + "obj-1::obj-104" : [ "a[58]", "a", 0 ], + "obj-47::obj-23" : [ "a[27]", "a", 0 ], + "obj-47::obj-40" : [ "a[15]", "a", 0 ], + "obj-47::obj-67" : [ "a[40]", "a", 0 ], + "obj-47::obj-50" : [ "a[32]", "a", 0 ], + "obj-47::obj-37" : [ "a[12]", "a", 0 ], + "obj-1::obj-24" : [ "a[54]", "a", 0 ], + "obj-47::obj-73" : [ "a[43]", "a", 0 ], + "obj-1::obj-103" : [ "a[59]", "a", 0 ], + "obj-47::obj-51" : [ "a[33]", "a", 0 ], + "obj-47::obj-52" : [ "a[34]", "a", 0 ], + "obj-47::obj-24" : [ "a[28]", "a", 0 ], + "obj-47::obj-41" : [ "a[16]", "a", 0 ], + "obj-47::obj-68" : [ "a[41]", "a", 0 ], + "obj-47::obj-48" : [ "a[30]", "a", 0 ], + "obj-47::obj-106" : [ "a[18]", "a", 0 ], + "obj-1::obj-25" : [ "a[55]", "a", 0 ], + "obj-1::obj-19" : [ "a[50]", "a", 0 ], + "obj-47::obj-105" : [ "a[19]", "a", 0 ], + "obj-47::obj-104" : [ "a[20]", "a", 0 ], + "obj-47::obj-103" : [ "a[21]", "a", 0 ], + "obj-1::obj-102" : [ "a[60]", "a", 0 ], + "obj-47::obj-64" : [ "a[37]", "a", 0 ], + "obj-1::obj-101" : [ "a[61]", "a", 0 ], + "obj-47::obj-53" : [ "a[35]", "a", 0 ], + "obj-1::obj-20" : [ "a[51]", "a", 0 ], + "obj-47::obj-25" : [ "a[29]", "a", 0 ], + "obj-47::obj-75" : [ "a[44]", "a", 0 ], + "obj-47::obj-42" : [ "a[17]", "a", 0 ], + "obj-1::obj-106" : [ "a[56]", "a", 0 ], + "obj-47::obj-102" : [ "a[22]", "a", 0 ], + "obj-47::obj-20" : [ "a[25]", "a", 0 ], + "obj-47::obj-101" : [ "a[23]", "a", 0 ], + "obj-47::obj-38" : [ "a[13]", "a", 0 ], + "obj-47::obj-65" : [ "a[38]", "a", 0 ] + } +, + "dependency_cache" : [ { + "name" : "o.io.udp.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/udp", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.route.mxo", + "type" : "iLaX" + } +, { + "name" : "o.compose.mxo", + "type" : "iLaX" + } +, { + "name" : "o.pack.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } +, { + "name" : "o.downcast.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/UDPReceive.maxpat b/lib/OSC/Applications/MaxMSP/examples/UDPReceive.maxpat new file mode 100644 index 0000000..5598d31 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/UDPReceive.maxpat @@ -0,0 +1,319 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 334.0, 78.0, 1072.0, 480.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-5", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 183.5, 341.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-18", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 498.0, 91.0, 150.0, 33.0 ], + "style" : "", + "text" : "control Arduino square wave tone on pin 3" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-15", + "maxclass" : "o.message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 406.0, 168.0, 150.0, 22.0 ], + "text" : "/tone/3", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-12", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 134.0, 127.0, 34.0, 22.0 ], + "style" : "", + "text" : "mtof" + } + + } +, { + "box" : { + "id" : "obj-11", + "maxclass" : "kslider", + "numinlets" : 2, + "numoutlets" : 2, + "outlettype" : [ "int", "int" ], + "parameter_enable" : 0, + "patching_rect" : [ 132.0, 65.0, 336.0, 53.0 ], + "presentation_rect" : [ 0.0, 0.0, 336.0, 53.0 ], + "style" : "", + "varname" : "kslider" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-9", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 242.0, 140.0, 32.5, 22.0 ], + "style" : "", + "text" : "220" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-8", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 184.0, 137.0, 34.0, 22.0 ], + "style" : "", + "text" : "440." + } + + } +, { + "box" : { + "id" : "obj-4", + "maxclass" : "button", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 402.0, 137.0, 20.0, 20.0 ], + "style" : "" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-3", + "linecount" : 3, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 489.0, 279.0, 154.0, 47.0 ], + "style" : "", + "text" : "8888 is the port sent to on the Arduino node 128.32.122.252" + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-20", + "maxclass" : "o.message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 235.0, 234.0, 150.0, 22.0 ], + "text" : "/tone/3 130.813 \n", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-6", + "maxclass" : "o.message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 185.0, 191.0, 150.0, 22.0 ], + "text" : "/tone/3 \"$1\" ", + "textcolor" : [ 0.0, 0.0, 0.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 183.5, 290.0, 288.0, 24.0 ], + "style" : "", + "text" : "o.io.udp 128.32.122.252 8888 9999" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-12", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-11", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-12", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-15", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-5", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-15", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-4", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-20", 1 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-26", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-6", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-8", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-9", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.udp.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/udp", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.message.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/MaxMSP/examples/UDPSend.maxpat b/lib/OSC/Applications/MaxMSP/examples/UDPSend.maxpat new file mode 100644 index 0000000..93c1234 --- /dev/null +++ b/lib/OSC/Applications/MaxMSP/examples/UDPSend.maxpat @@ -0,0 +1,159 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 7, + "minor" : 0, + "revision" : 4, + "architecture" : "x86", + "modernui" : 1 + } +, + "rect" : [ 443.0, 218.0, 1072.0, 480.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "boxes" : [ { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-8", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 277.0, 243.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontface" : 0, + "fontsize" : 12.0, + "id" : "obj-6", + "maxclass" : "o.display", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 91.0, 243.0, 150.0, 34.0 ], + "textcolor" : [ 1.0, 1.0, 1.0, 1.0 ] + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-2", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 2, + "outlettype" : [ "FullPacket", "FullPacket" ], + "patching_rect" : [ 91.0, 149.0, 97.0, 22.0 ], + "style" : "", + "text" : "o.if exists(/units)" + } + + } +, { + "box" : { + "fontname" : "Arial", + "fontsize" : 12.0, + "id" : "obj-4", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 95.0, 62.0, 150.0, 33.0 ], + "style" : "", + "text" : "Set udp port, send and receive port respectively" + } + + } +, { + "box" : { + "fontname" : "Andale Mono", + "fontsize" : 14.0, + "id" : "obj-26", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 91.0, 107.0, 288.0, 24.0 ], + "style" : "", + "text" : "o.io.udp 128.32.122.26 8888 9999" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-6", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-2", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-8", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-2", 1 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "disabled" : 0, + "hidden" : 0, + "source" : [ "obj-26", 0 ] + } + + } + ], + "dependency_cache" : [ { + "name" : "o.io.udp.maxpat", + "bootpath" : "~/Documents/Max/Packages/o.io/experimental/Protocols/udp", + "type" : "JSON", + "implicit" : 1 + } +, { + "name" : "o.if.mxo", + "type" : "iLaX" + } +, { + "name" : "o.display.mxo", + "type" : "iLaX" + } + ], + "embedsnapshot" : 0 + } + +} diff --git a/lib/OSC/Applications/PD/SerialOscuino.pd b/lib/OSC/Applications/PD/SerialOscuino.pd new file mode 100644 index 0000000..1d94544 --- /dev/null +++ b/lib/OSC/Applications/PD/SerialOscuino.pd @@ -0,0 +1,312 @@ +#N canvas 33 23 1015 763 10; +#X msg 272 58 /a/*; +#X msg 612 30 /s/a; +#X msg 569 30 /s/d; +#X msg 675 30 /s/m; +#X obj 169 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 189 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 210 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 231 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X msg 439 45 /d/[1-3]; +#X obj 27 451 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 272 10 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 107 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 47 451 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 87 451 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 67 451 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 127 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 147 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 167 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 187 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 267 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 207 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 247 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 227 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 327 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 307 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 287 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 212 18 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X msg 212 37 /s/l \$1; +#X obj 252 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 273 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 294 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 314 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 335 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 356 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 377 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 398 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 419 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 440 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 460 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 481 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 333 117 o.io.slipserial; +#X obj 502 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 523 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 544 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 565 339 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 694 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 774 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 714 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 754 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 734 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 794 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 814 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 834 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 854 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 874 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 914 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 894 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X msg 786 80 /c/*; +#X obj 360 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 439 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 380 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 420 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 400 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 459 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 479 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 499 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 519 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 599 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 539 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 579 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 559 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 659 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 639 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X obj 619 452 vsl 15 128 0 1023 0 0 empty empty empty 0 -9 0 10 -262144 +-1 -1 0 1; +#X msg 333 64 /a/*/u; +#X text 340 48 Pull up; +#X text 567 10 How many pins?; +#X text 675 9 How many milliseconds ?; +#X text 215 -1 LED; +#X text 749 369 Touch Pins on Teensy 3; +#X text 341 211 System message responses; +#X text 356 370 Analog Values; +#X text 27 369 Analog Values with Pullups Enabled; +#N canvas 0 50 450 278 (subpatch) 0; +#X array AnalogArray 16 float 2 black black; +#X coords 0 1023 16 0 200 140 1; +#X restore 31 605 graph; +#X obj 272 35 metro 60; +#X obj 786 39 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 786 59 metro 60; +#X obj 200 214 print; +#X obj 253 115 print; +#X msg 459 107 devicename /dev/tty.usbmodem122611 \, baud 9600 \, pollintervall +4 \, verbose 1; +#X obj 333 96 mrpeach/packOSC; +#X obj 333 138 mrpeach/unpackOSC; +#X obj 333 159 mrpeach/routeOSC /a /d /s /c; +#X obj 169 297 mrpeach/routeOSC /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 +/12 /13 /14 /15 /16 /17 /18 /19 /20, f 70; +#X obj 694 387 mrpeach/routeOSC /0 /1 /16 /17 /18 /19 /22 /23 /25 /32 +/33 /15, f 40; +#X obj 359 387 mrpeach/routeOSC /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 +/12 /13 /14 /15 /16, f 54; +#X obj 27 387 mrpeach/routeOSC /0/u /1/u /2/u /3/u /4/u /5/u /6/u /7/u +/8/u /9/u /10/u /11/u /12/u /13/u /14/u /15/u, f 54; +#X obj 346 229 cyclone/prepend set; +#X obj 536 206 cyclone/prepend set; +#X text 291 8 Retrieve analog value each 60ms, f 15; +#X text 436 2 get digital pins 1 to 3 status, f 11; +#X text 741 25 get Teensy 3 Touch each 60ms; +#N canvas 0 94 450 300 fillArray 0; +#X obj 60 223 send AnalogArray; +#X obj 60 142 mrpeach/routeOSC /1 /2 /3 /4 /5 /6 /7 /8 /9 /10 /11 /12 +/13 /14 /15 /16, f 54; +#X obj 60 194 cyclone/funnel 16; +#X obj 60 120 inlet; +#X connect 1 0 2 0; +#X connect 1 1 2 1; +#X connect 1 2 2 2; +#X connect 1 3 2 3; +#X connect 1 4 2 4; +#X connect 1 5 2 5; +#X connect 1 6 2 6; +#X connect 1 7 2 7; +#X connect 1 8 2 8; +#X connect 1 9 2 9; +#X connect 1 10 2 10; +#X connect 1 11 2 11; +#X connect 1 12 2 12; +#X connect 1 13 2 13; +#X connect 1 14 2 14; +#X connect 1 15 2 15; +#X connect 2 0 0 0; +#X connect 3 0 1 0; +#X restore 348 423 pd fillArray; +#X msg 536 226; +#X msg 346 252; +#X text 211 279 Digital pins state; +#X obj 200 194 spigot; +#X obj 234 171 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 +1; +#X obj 668 651 cnv 15 400 80 empty empty empty 20 12 0 14 -258113 -66577 +0; +#X text 26 71 Oscuino Serial Adrian Freed 2013; +#X text 762 229 - comport; +#X text 763 213 - cyclone; +#X obj 530 148 import mrpeach; +#X text 763 197 - mrpeach osc slipenc and slipdec; +#X text 650 153 This patch depends on several third party externals +available in PD-extended (deprecated?) \, Purr \, or through deken +plugin (Help -> Find externals):; +#X connect 0 0 90 0; +#X connect 1 0 90 0; +#X connect 2 0 90 0; +#X connect 3 0 90 0; +#X connect 8 0 90 0; +#X connect 10 0 84 0; +#X connect 26 0 27 0; +#X connect 27 0 90 0; +#X connect 40 0 91 0; +#X connect 40 0 106 0; +#X connect 57 0 90 0; +#X connect 74 0 90 0; +#X connect 84 0 0 0; +#X connect 85 0 86 0; +#X connect 86 0 57 0; +#X connect 89 0 40 1; +#X connect 90 0 40 0; +#X connect 91 0 92 0; +#X connect 92 0 96 0; +#X connect 92 1 93 0; +#X connect 92 2 97 0; +#X connect 92 3 94 0; +#X connect 92 4 98 0; +#X connect 93 0 4 0; +#X connect 93 1 5 0; +#X connect 93 2 6 0; +#X connect 93 3 7 0; +#X connect 93 4 28 0; +#X connect 93 5 29 0; +#X connect 93 6 30 0; +#X connect 93 7 31 0; +#X connect 93 8 32 0; +#X connect 93 9 33 0; +#X connect 93 10 34 0; +#X connect 93 11 35 0; +#X connect 93 12 36 0; +#X connect 93 13 37 0; +#X connect 93 14 38 0; +#X connect 93 15 39 0; +#X connect 93 16 41 0; +#X connect 93 17 42 0; +#X connect 93 18 43 0; +#X connect 93 19 44 0; +#X connect 94 0 45 0; +#X connect 94 1 47 0; +#X connect 94 2 49 0; +#X connect 94 3 48 0; +#X connect 94 4 46 0; +#X connect 94 5 50 0; +#X connect 94 6 51 0; +#X connect 94 7 52 0; +#X connect 94 8 53 0; +#X connect 94 9 54 0; +#X connect 94 10 56 0; +#X connect 94 11 55 0; +#X connect 95 0 58 0; +#X connect 95 1 60 0; +#X connect 95 2 62 0; +#X connect 95 3 61 0; +#X connect 95 4 59 0; +#X connect 95 5 63 0; +#X connect 95 6 64 0; +#X connect 95 7 65 0; +#X connect 95 8 66 0; +#X connect 95 9 68 0; +#X connect 95 10 70 0; +#X connect 95 11 69 0; +#X connect 95 12 67 0; +#X connect 95 13 73 0; +#X connect 95 14 72 0; +#X connect 95 15 71 0; +#X connect 96 0 9 0; +#X connect 96 1 12 0; +#X connect 96 2 14 0; +#X connect 96 3 13 0; +#X connect 96 4 11 0; +#X connect 96 5 15 0; +#X connect 96 6 16 0; +#X connect 96 7 17 0; +#X connect 96 8 18 0; +#X connect 96 9 20 0; +#X connect 96 10 22 0; +#X connect 96 11 21 0; +#X connect 96 12 19 0; +#X connect 96 13 25 0; +#X connect 96 14 24 0; +#X connect 96 15 23 0; +#X connect 96 16 95 0; +#X connect 96 16 102 0; +#X connect 97 0 104 0; +#X connect 98 0 103 0; +#X connect 106 0 87 0; +#X connect 107 0 106 1; diff --git a/lib/OSC/Applications/PD/o.io.slipserial.pd b/lib/OSC/Applications/PD/o.io.slipserial.pd new file mode 100644 index 0000000..0d9fea0 --- /dev/null +++ b/lib/OSC/Applications/PD/o.io.slipserial.pd @@ -0,0 +1,22 @@ +#N canvas 618 358 756 268 10; +#X obj 95 179 mrpeach/slipdec 65536; +#X obj 95 47 mrpeach/slipenc 65536; +#X obj 359 20 loadbang; +#X obj 95 22 inlet; +#X obj 95 206 outlet; +#X msg 359 83 baud 115200; +#X obj 261 46 inlet; +#X msg 318 46 devicename /dev/tty.usbserial-A5002rKU \, pollintervall +1; +#X obj 95 135 comport; +#X obj 134 157 print errors; +#X connect 0 0 4 0; +#X connect 1 0 8 0; +#X connect 2 0 7 0; +#X connect 2 0 5 0; +#X connect 3 0 1 0; +#X connect 5 0 8 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 0 0; +#X connect 8 1 9 0; diff --git a/lib/OSC/Applications/Processing/SLIPSerialToUDP/GUI.pde b/lib/OSC/Applications/Processing/SLIPSerialToUDP/GUI.pde new file mode 100644 index 0000000..a1ef8ac --- /dev/null +++ b/lib/OSC/Applications/Processing/SLIPSerialToUDP/GUI.pde @@ -0,0 +1,148 @@ + +ControlP5 cp5; + +void setupGUI() { + //the ControlP5 object + cp5 = new ControlP5(this); + + //start button + cp5.addButton("START") + .setPosition(width/2 - 100, height-30) + .setSize(200, 20); + + //stop button + cp5.addButton("STOP") + .setPosition(width/2 - 100, height-30) + .setSize(200, 20) + .hide(); + + //setup the baud list + DropdownList baudRate = cp5.addDropdownList("BaudRate") + .setPosition(50, 130) + .setSize(200, 90) + .setItemHeight(20) + .setBarHeight(20) + .setId(4).close(); + ControllerStyle baudRateStyle = baudRate.getCaptionLabel().getStyle(); + baudRate.getCaptionLabel().set("SELECT THE BAUD RATE"); + baudRateStyle.marginTop = baudRateStyle.marginLeft = baudRateStyle.marginTop = 3; + //the baud options + for (int i=0; i serialBuffer = new ArrayList(); + +void setupSerial() { + serial = new Serial(this, Serial.list()[serialListNumber], baud); +} + +void stopSerial() { + serial.stop(); +} + +void serialEvent(Serial serial) { + //decode the message + while (serial.available () > 0) { + slipDecode(byte(serial.read())); + } +} + +void SerialSendToUDP() { + byte [] buffer = new byte[serialBuffer.size()]; + //copy the buffer over + for (int i = 0; i < serialBuffer.size(); i++) { + buffer[i] = serialBuffer.get(i); + } + //send it off + UDPSendBuffer(buffer); + //clear the buffer + serialBuffer.clear(); + //light up the indicator + drawIncomingSerial(); +} + +void serialSend(byte[] data) { + + //encode the message and send it + for (int i = 0; i < data.length; i++){ + slipEncode(data[i]); + } + //write the eot + serial.write(eot); + println(""); +} + +/************************************************************************************ + SLIP ENCODING + ************************************************************************************/ + +byte eot = byte(192); +byte slipesc = byte(219); +byte slipescend = byte(220); +byte slipescesc = byte(221); + +byte previousByte; + +void slipDecode(byte incoming) { + byte previous = previousByte; + previousByte = incoming; + //if the previous was the escape char + if (previous == slipesc) { + //if this one is the esc eot + if (incoming==slipescend) { + serialBuffer.add(eot); + } + else if (incoming==slipescesc) { + serialBuffer.add(slipesc); + } + } + else if (incoming==eot) { + //if it's the eot + //send off the packet + SerialSendToUDP(); + } + else if (incoming != slipesc) { + serialBuffer.add(incoming); + } +} + +void slipEncode(byte incoming) { + if(incoming == eot){ + serial.write(slipesc); + serial.write(slipescend); + } else if(incoming==slipesc) { + serial.write(slipesc); + serial.write(slipescesc); + } else { + serial.write(incoming); + } + print((char)incoming); + print(" "); + println(incoming); +} diff --git a/lib/OSC/Applications/Processing/SLIPSerialToUDP/UDP.pde b/lib/OSC/Applications/Processing/SLIPSerialToUDP/UDP.pde new file mode 100644 index 0000000..5520f34 --- /dev/null +++ b/lib/OSC/Applications/Processing/SLIPSerialToUDP/UDP.pde @@ -0,0 +1,27 @@ +//UDP communication +UDP udp; + +int inPort = 9000; +int outPort = 9001; +String ipAddress = "127.0.0.1"; + +void setupUDP() { + udp = new UDP( this, inPort ); + //udp.log( true ); // <-- printout the connection activity + udp.listen( true ); +} + +void stopUDP() { + udp.close(); +} + +void UDPSendBuffer(byte[] data) { + udp.send( data, ipAddress, outPort ); +} + +//called when UDP receives some data +void receive( byte[] data) { + drawIncomingUDP(); + //send it over to serial + serialSend(data); +} diff --git a/lib/OSC/Applications/Processing/SLIPSerialToUDPp3 b/lib/OSC/Applications/Processing/SLIPSerialToUDPp3 new file mode 100644 index 0000000..e5c3ad6 --- /dev/null +++ b/lib/OSC/Applications/Processing/SLIPSerialToUDPp3 @@ -0,0 +1,375 @@ +import processing.serial.*; +//download at http://ubaa.net/shared/processing/udp/ +import hypermedia.net.*; +//download at www.sojamo.de/libraries/controlp5 +import controlP5.*; + +/************************************************************************************ + GUI + ************************************************************************************/ + +ControlP5 cp5; + +DropdownList serialddl; +DropdownList baudddl; +Textlabel arduinoLabel; +Textlabel UDPLabel; +Textlabel incomingPacket; +Button startButton; +Button stopButton; +Textfield ipAddressField; +Textfield incomingPortField; +Textfield outgoingPortField; + +void setupGUI() { + //the ControlP5 object + cp5 = new ControlP5(this); + + //start button + startButton = cp5.addButton("START") + .setPosition(200, 200) + .setSize(200, 19) + ; + + //stop button + stopButton = cp5.addButton("STOP") + .setPosition(200, 200) + .setSize(200, 19) + ; + stopButton.hide(); + + //Serial Port selector + serialddl = cp5.addDropdownList("SerialPort") + .setPosition(50, 100) + .setSize(200, 200) + ; + serialddl.setItemHeight(20); + serialddl.setBarHeight(15); + serialddl.setCaptionLabel("SELECT ARDUINO SERIAL PORT"); + //serialddl.captionLabel().style().marginTop = 3; + //serialddl.captionLabel().style().marginLeft = 3; + //serialddl.valueLabel().style().marginTop = 3; + //set the serial options + String SerialList[] = Serial.list(); + for (int i=0;i serialBuffer = new ArrayList(); + +void setupSerial() { + serial = new Serial(this, Serial.list()[serialListNumber], baud); +} + +void stopSerial() { + serial.stop(); +} + +void serialEvent(Serial serial) { + //decode the message + //println (serial.read()); + while (serial.available () > 0) { + slipDecode(byte(serial.read())); + } +} + +void SerialSendToUDP() { + byte [] buffer = new byte[serialBuffer.size()]; + //copy the buffer over + for (int i = 0; i < serialBuffer.size(); i++) { + buffer[i] = serialBuffer.get(i); + } + //send it off + UDPSendBuffer(buffer); + //clear the buffer + serialBuffer.clear(); + //light up the indicator + drawIncomingSerial(); +} + +void serialSend(byte[] data) { + //encode the message and send it + for (int i = 0; i < data.length; i++){ + slipEncode(data[i]); + } + //write the eot + serial.write(eot); +} + +/************************************************************************************ + SLIP ENCODING + ************************************************************************************/ + +byte eot = byte(192); +byte slipesc = byte(219); +byte slipescend = byte(220); +byte slipescesc = byte(221); + +byte previousByte; + +void slipDecode(byte incoming) { + byte previous = previousByte; + previousByte = incoming; + //if the previous was the escape char + if (previous == slipesc) { + //if this one is the esc eot + if (incoming==slipescend) { + serialBuffer.add(eot); + } + else if (incoming==slipescesc) { + serialBuffer.add(slipesc); + } + } + else if (incoming==eot) { + //if it's the eot + //send off the packet + SerialSendToUDP(); + } + else { + serialBuffer.add(incoming); + } +} + +void slipEncode(byte incoming) { + if(incoming == eot){ + serial.write(slipesc); + serial.write(slipescend); + } else if(incoming==slipesc) { + serial.write(slipesc); + serial.write(slipescesc); + } else { + serial.write(incoming); + } +} + + +/************************************************************************************ + UDP + ************************************************************************************/ + +//UDP communication +UDP udp; + +int inPort = 9000; +int outPort = 10001; +String ipAddress = "192.168.0.12"; + +void setupUDP() { + udp = new UDP( this, inPort ); + udp.log( true ); // <-- printout the connection activity + udp.listen( true ); +} + +void stopUDP() { + udp.close(); +} + +void UDPSendBuffer(byte[] data) { + udp.send( data, ipAddress, outPort ); +} + +//called when UDP receives some data +void receive( byte[] data) { + drawIncomingUDP(); + //send it over to serial + serialSend(data); +} + +/************************************************************************************ + SETUP/DRAW + ************************************************************************************/ + +void setup() { + // configure the screen size and frame rate + size(550, 250, P3D); + frameRate(30); + setupGUI(); +} + +void draw() { + background(128); + if (applicationRunning) { + drawIncomingPackets(); + } +} + + +/************************************************************************************ + VISUALIZING INCOMING PACKETS + ************************************************************************************/ + +int lastSerialPacket = 0; +int lastUDPPacket = 0; + +void drawIncomingPackets() { + //the serial packet + fill(0); + rect(75, 50, 100, 100); + //the udp packet + rect(325, 50, 100, 100); + int now = millis(); + int lightDuration = 75; + if (now - lastSerialPacket < lightDuration) { + fill(255); + rect(85, 60, 80, 80); + } + if (now - lastUDPPacket < lightDuration) { + fill(255); + rect(335, 60, 80, 80); + } +} + +void drawIncomingSerial() { + lastSerialPacket = millis(); +} + +void drawIncomingUDP() { + lastUDPPacket = millis(); +} diff --git a/lib/OSC/Applications/Processing/UDPReceiveBundle/UDPReceiveBundle.pde b/lib/OSC/Applications/Processing/UDPReceiveBundle/UDPReceiveBundle.pde new file mode 100644 index 0000000..466ddbf --- /dev/null +++ b/lib/OSC/Applications/Processing/UDPReceiveBundle/UDPReceiveBundle.pde @@ -0,0 +1,74 @@ +/* +Receives and visualizes OSCBundles sent over UDP + +Use with /examples/UDPSendBundle + +or with /examples/SerialSendBundle in conjunction +with /Applications/Processing/SLIPSerialToUDP +*/ + +import oscP5.*; +import netP5.*; + +OscP5 oscP5; + +void setup() { + size(600,300); + frameRate(30); + //set this to the receiving port + oscP5 = new OscP5(this,9001); +} + + +void draw() { + background(0); + //draw the analog values + float analog0Height = map(analogValue0, 0, 1024, 0, 200); + float analog1Height = map(analogValue1, 0, 1024, 0, 200); + fill(255); + rect(50, 250, 50, -analog0Height); + rect(150, 250, 50, -analog1Height); + //and the labels + textSize(12); + text("/analog/0", 50, 270); + text("/analog/1", 150, 270); + //and the digital pin label + text("/digital/5", 250, 270); + textSize(25); + text(digitalValue5, 250, 250); + //now do the mouse part + //add the label + textSize(12); + text("/mouse/step", 350, 270); + //make a box where it should go + noFill(); + stroke(255); + rect(350, 50, 200, 200); + //and a square where the mouse is + fill(255); + float mouseXPos = map(mouseStepX, 0, 1024, 350, 530); + float mouseYPos = map(mouseStepY, 0, 1024, 50, 230); + rect(mouseXPos, mouseYPos, 20, 20); +} + +int analogValue0 = 50; +int analogValue1 = 50; +String digitalValue5 = "LOW"; + +int mouseStepX = 0; +int mouseStepY = 0; + +// incoming osc message are forwarded to the oscEvent method. +void oscEvent(OscMessage theOscMessage) { + //println(theOscMessage.addrPattern()); + if (theOscMessage.addrPattern().equals("/analog/0")){ + analogValue0 = theOscMessage.get(0).intValue(); + } else if(theOscMessage.addrPattern().equals("/analog/1")){ + analogValue1 = theOscMessage.get(0).intValue(); + } else if(theOscMessage.addrPattern().equals("/digital/5")){ + digitalValue5 = theOscMessage.get(0).stringValue(); + } else if(theOscMessage.addrPattern().equals("/mouse/step")){ + mouseStepX = theOscMessage.get(0).intValue(); + mouseStepY = theOscMessage.get(1).intValue(); + } +} diff --git a/lib/OSC/Applications/Processing/UDPReceiveMessage/UDPReceiveMessage.pde b/lib/OSC/Applications/Processing/UDPReceiveMessage/UDPReceiveMessage.pde new file mode 100644 index 0000000..9856bcd --- /dev/null +++ b/lib/OSC/Applications/Processing/UDPReceiveMessage/UDPReceiveMessage.pde @@ -0,0 +1,42 @@ +/* +Receives and visualizes OSCBundles sent over UDP + +Use with /examples/UDPSendMessage + +or with /examples/SerialSendMessage in conjunction +with /Applications/Processing/SLIPSerialToUDP +*/ + +import oscP5.*; +import netP5.*; + +OscP5 oscP5; + +void setup() { + size(150,300); + frameRate(30); + //set this to the receiving port + oscP5 = new OscP5(this,9001); +} + + +void draw() { + background(0); + //draw the analog values + float analog0Height = map(analogValue0, 0, 1024, 0, 200); + fill(255); + rect(50, 250, 50, -analog0Height); + //and the labels + textSize(12); + text("/analog/0", 50, 270); +} + +int analogValue0 = 50; + +// incoming osc message are forwarded to the oscEvent method. +void oscEvent(OscMessage theOscMessage) { + //println(theOscMessage.addrPattern()); + if (theOscMessage.addrPattern().equals("/analog/0")){ + analogValue0 = theOscMessage.get(0).intValue(); + } +} diff --git a/lib/OSC/Applications/Processing/serialSend/code/javaosc.jar b/lib/OSC/Applications/Processing/serialSend/code/javaosc.jar new file mode 100755 index 0000000000000000000000000000000000000000..8a683ef919ac8cee480a74d91f0ce3421bf0e13c GIT binary patch literal 10927 zcmai41ymi$(#9?c?(R+q?w8;MceuE_y9Wz|;0}S{8iKnA2=49#cX#)nylggav%Bx_ zb7tXVa%gn|Y8-u5hfS^x9!#|;Jy3QSrUBtR!FBf{{|3kD|lhv;*# z-6zrdMS@a|CsC893;pT(Q&d_&MqET#5kxO7aw^^5CnZToKY}1hM>E(zRH48)&a$*_ z-!Ft}M=K^ZD5eA!3{Ej{CgoO_9HM|Gsi5eXLL;yveHQ8{Esf3^iw_5DuYi$!>HsGp zsSx6b&V3qv9?R-h=UVq?XTbi`nLoPxpC72FyMc`r!_V&iT>{|`2{TJeTN?)>!~YWf zeGpK77qxLP_*4AHKxB2mqw+l&y?O=)M*L6WvWh~2PS%E&M)U@jdJYaLN+Zg6O6c?P z@CoEn8t{?qN`7(q;{MU-1^g}Q5P8rr!<2v*G>ARe(9t-FQl@#lH%kmxJL**>qY~w@ z6n!RqEeuC3Hl?X7IMj0LQ_M)0bMAw@w|nk~2}yhp*G@>yU`@xXbec%RM|xne*4@}h z{DRT*XxvF_%g_vpq4hm|5r!W9>;%o|yfEoVV@0-Jsb8@ZVA8Qz_E7iE^x}LRlD$Jt zt!qd^@R3|IT(4p)u#D!;^@4!BF~`6$ZxRDF;$&&*{y{0@c$8; zkUcp;V%EkSEA!)WmRaa& z4*vqI;Z4FSYnYwW3sZ8^~{ayr%WrD&}6w_CEN>47OAM6WT&@j zrTx;4`eOrSfzI*g$SF3oI`)V<0#NdRc&6?)FrNq=^xLnX^h_Nee+&SVOt%5Q0Jx*h zrcM(XKqrIRK*^^C-9lC6h!WRo#=@kz$YrwoRAvjK#>^Riqv-NtG)M>&e z{H;7lOd4s?QR5vX%PDb=${`QOFL#XuJAy&Hf#my?<*|lFR@F|_TRLvMHhLe?6M_d< zA$Y7{8~ssR=OkI-9N=E1ezeF_>8T#65T}ziNLJQ5;vCB5qfF&z9WLK*sDu}0I+r`O=GDcF)9h z;-H0V?Y#}p%5lY40uUr`Yx|8$t{{Pr=Y@;igpqd`txe{KlY73pF`4g5Lghu7z64JUz1r@wV(wx5pKH zz}*3YGuCa-tEF^FdSLvsrj`_pazaGeq)1&C0PU|{C} zFffvT>Akd(gM*&QPu~feRT$Gnet2M)6U&Mf5|F_JWmDymWCI)~emj&|LVS?pjRbk#sl8|I{MEx<%KPEk3tkuOCCxYF^QA;s ztju%Mj<*t|os&)%^SVskO-YsrdA0BLFl*H2^cDlLT$p>;Epl5UC#`?h94mMztzGvm4Zjnt3wO5p!cS?r7U|?YotTKstmR* zzY${DJ`<9JkZ7G_gt}{~FvLexJ}yzN-I!z#n)bWm3JQGqnfvYS^(wKc!O)|6UZm1sDM8$}j{7IEIrN=S}Xh3GXF_{vTz27)J zC#dgVi#dSGt7q(j(8o?o<>nq$rOFQ|k?oYAN6^}$eB92k*y5*p=FY0g|4JhUH|I#M zjm*))HPj0!hpnHuc_qkSjhv0UBl+1WZt8NKKY-T0P*w<;1VImzp)^|$hXKGf#3~j> zVFv#u*m+i-j;o~PE0gJ-gl!_8(-{3j**g`em6(jN3h9~K;YTS@`bN=*Y6O`?Tl!8n z&AC~2`}MgGQ@!b2WCq>yHCPe7EmB5i6miy{2Wa;fb=Zi9kJN`Kr29V7lnu`-N-h*0 z55^6SZK`w8lvpX#YG#aujA2zPJJ%_%Zhb1L2z!9llyhw~e9>S#N&}S!)e~|y4&YFG z%isZp@&G>7i!v7=huF*~0!?0?5J^9pYWo^LBL{vf>aCkZMr5jEE@?n6#)#~5VD`u= znQP!A&jJC@Lm>av%UIJ(T|%e6!+HJ3H5K6>v53vr3`J8DAq{xbV%@A0E^gt>1fN*0yNV}sy5ti@(PbddUDRGq9 z7RCu(!Rg)se(r02d_t9rw?|^&U|`4)|GxW>(=)Iza{OcW5w$1*A%NcbRZX;Je)8*w z4{F2n^#bl=(&z$juzUqjKq|Xj-QPBPxnP?lWaW`z0X+Oj7%5C_8DFdiuQ&Q#yi6WE zyc#{hINMWUAcYB%C|S{^3w8U_ON&6_c?1MT1Yh7S1io@buW*Mq%G15sL&!E|Dt!f= z1uS7Py;SlaHycJ+!x3sNo?|>xA4i1;K7KB^+2yU?1v$QB+!OX3vCnEcL^MQ(wqIi} zHpf~R{t_OS;~YR5N6IS?Dxh0K4W7kdODyQYWbS6hzYnk?iSPxW6-XG-sfw}0KBPal z+rCB;9PQw0w-+jzb;cVAKcZOt9Kf>W$!04|+JO;Zk19nFt{<-K)+?oy0y7QA$hLts zO95dT%W^nuO(iy-@{Z|hyz4^=zb`NJE{nIDe;=?!j90*=Q!Hvc&15YM0OZ+k_n>Y9 z|LZKg)f!lle3}Ko(<~7FizAb>vHxQZoFWHgTKSQ?9wp)EsvsavmTNfHb&2>_0X!cg zb$ySUVgVtN@xwPLX+0r9Bkk{ymL#tzJ7)yVr5s~Y<`WjZO`JDYclQaJ!JYA^bMcx@ zq?6jM*7P#AbrE(k*=a4A*GSiOLOy29;GAk4yeGYoaqSmn;oYX#ifl>F#}S{#*^cmK z42-}DZM>HxwPHht|Kx*xf`@bYZC?A98wHKZjSWCR7_MN7^e(b*$tRWT^JUY=P9In@ zI1P9;oqVxcRgo59;UsQ+xLJC0YDQKMwquAFpUH7uX-*nh&0d)CD-e{-62YYjen=bc zn2?%3Zpw~6_vT`AG2>>JW`I;w`IHnyQR`^jau(5z*`tvWvu(PIu?O>JU0$LU7Ypq< z_Im#+MBL-sPW;4rNt!%8gQ)3G?Z&$}GgxaI*9Ae*dLNwW?!}xkYP`*k5&k+2{E8Nk z_)qa<@+qDW|Bq=9xBlZ}0L>_%383>Ji2K90HN6Y0HGU@`03{GB4QL}3U_D}$$!RtH zC_ca%>k+Ke9KrxfkfVqrTB?Zf3UPI(gaMU-%<@NTz8p4w9%}T=c?u{Okj=!^hG)8B zt)4ha*sxi6NaXN+&u>CdV33T)bwRX*L3&cHweWz54t>EZ%8rwu?le?4Sqko$5nnSH z7Upk^Fa3eb30NaT6b+F_3at=AMcb6p@py4&MmW=yLaH@IJZ;PVZH$TI`vepH>nGI~ zhM?Jr2`%dlsiukTl_K!bX>u-#b*qa%q}CFw`gqdEz0 zqX0_jzBNU7pKd|Ncm0JaOwS!3VyxHd%ruJqg#FD;rZSmG1$VTHfp=0boak##O(xMr zIws5$LchKUL=cT83am{WD=bW0K?KMoZ%W|zy+B*ZO;06D^VJAs4!x6ohkmvUEwrNZ zEi;{n1BZ*dHLhg>7-pd+Ix9XyDmPqLw1g228&~QfpB_OCp@M$4QtzwOpj_%7>+94Y zU+Pl>Pp6$~Rsi?%gY!#QDswAttI3;c15+HI56Y!MxxV1=G;+eKm%;>^RRm4^H4|Rs;;Hyc%bJ;qFz?L(S~B;&;pW5vUH?Iaech26o~ zsGaUsXfHyfM8#Rt4gnY^%A%8An~gapA=i-u7{)8h6;~_o$ z^3xh6AbxJ&QJGCmjS=1PRUfkXdf+7L>oDq~Kzcq1@82BUjTS2j{F8IreEPcnZKw9# z!O1%P;p03NtZYW*(7otEG@t6XwRPc>rBXgM@7&@!^zfr4F*1?Rt6k(}IJJ~%k2>#o z#r0r^NM1nR$#*)yndKi0{VNs@u{V?kAm~1tPvQh2pj;z>CU7tGkJIa@l!yRpBUCD#sJyHhOtC zdv>wcF0y?~*?3mqz69mu!v>mr9ZrI`?qL9!Y%(Emt_90;eH%byY$wz~#;tq|B?~Z; z>14qeIu`7d#3+$Vi_`arcx#i}y~@^h0s_v#eG>&2qNkV0puSdBIirT}pgtSnvAtHg zB)DYg+H7@=z%#xbHS0w>9d@tQm-rl=E#L}d!7;YljBy%A;u;V`Yh(v(e0F*#Fz@1v zd8qE0;eTeaUTfCfRb!f*V~5YFk!nH^LtNA_l^$Ky=zpCy^1}2H6N8O_B5?&L(N%&9 zSMpWR#keBws@si*P&8)bl&J0v5cLZgc|hb@FS5#6D{|f;@?xuB9d>yI+69Ci+S=Hg zb@-F#DxZBE&}`$HLp?w)gr^jX|5Nsc>wl?zPq(-^ z8VT6j>$!n!B=ns1glw#xjqDwNo`9;9XC3fNFdmDl3O=lbWpT!p7Enu%Ceh|O1q=BR ztm^i#Q-9E>idIDDsG6D-Spbbvj&kW*)9Dt|)u5U}Qo!VlzsKw}#0_c5XoEvKB0B1Z zNAi4!iL3Yg#5dasPuh#N?P`{I6+xpg8&C3_K+-rjMT5od68`*W(_gjG++&_0z`BokA;Z{+u{uiZ-yfn`mSKp)>!>Z zm~U{qj+_|k9-&#Z*FMLSt9ln-UI{FT;w+w#_}KJZRfC!7b&T&oa2dxya23UeD$^xM zLikm_Ev{D^8}F@@pOT)>g|&^?QkuudSPDK%LnY1$&7|blX3fW{N_?T~ZOEQ*Fhq;{ z0lZO@*JiwG<*mF9{>R==ITIb5tfzrs5!$l!Dj`M#<@V~$h#K=52Vs^r89h{RTGfKe z1yd8KX56ks2pVre9%r9xxl(uH5xtfgV_S7h>YR@`>;8z zv8`Zp@odyI0AveO0UIs$;)>UcnD~s>Dsu@tRpAI$TPadNxrHV9j!I6>7KaaHi?0YP zQ_+}p73Iq1+Z+4(4pknTLTC4sNm=`Teq}T(eljBrq;RT` zxnIPWV2VCSTQeB_W{*-}`sH+c?=?MNTuQ2>Nd?;Kb{TiVi49AnQI>kS#p^LADSjPm zQZ^?KZVnDNdzx35Yr`$?9C8FqR?^?<8h_E|Y_*O!PiytMfrUSYrb-7^Rs+K_ox;^O z>A&r==J<8(aV(rFRDv&0#eHnPx2ag&DwWy~>9kHKtKWpyl%GNfB&XBz4?w(xCUI*U z-CI(tVMF52bRn(<$dcS3a%p8-w1x{7 z`V{YBI%DD<5mCJ&^|3%uL!CZ%ceK&J)MFxEID?lgZaaAUinv(MCJo)TqR-T4O*Z7z z(1!8r4(6oI{kq*sP|_BTbJy)$((}T_8>Kmz)X5lveqi7k68D$)#J~rBN|A#%93!G# zkZL3k(An6V1omP6tB1uT%V}W&NLpq4qcgs)_Jn=3~p(h%5bVxjk%n8HQAqAA03&gH{pt9NFHaR6e^uE{OC)=!-S#v0sPPGT8B6FH>Srx2;aX+FI*l7qU@nfP*6R759Y|Nad$e zC8z#oo47>V0^fq#Qb~7;&H>(nzsQK?#+L;dN~k~Hx3wI$>*}{Og3uD=kC{&}Ko-k- z>9~kV__ESyguh)LIHOSK0FTJIrx{`uEll{1;yQ;4&7taCS;~@1d_VglXHJmM#Wj|T zTRG5%^Z}21p&3mE>RK7S)gyA-1QnV+fEY{nOUqq(L-lcU+X+S?9H^EBD#)E^zd^9J5!8q2rIR@G!;f`m%)ML^!tlD#u7}W(yU5!`ZhRg25hr%S&jl_> zaCo*kASHPC5baiwaw*4Kx0?-j7A=);jn4r?yWsib^G8IXw#?m9^vG6=t$j2|1=eaR z;(=3$z9I?oQ|+{^kJ*cy)ja{*{&kY>T4aN*Fat>1lob$pcXVro_a^F#X`Yp-s#yU> z>!)PO*K2Z7yHj`g%X~j$^N(yokEd)5;d3xB8sz^!$bOHkAe%o!?QcQWQ+ZoRQw8IZ z$Jnjy2$k4y6xE*}-b{~@aX>#`ycq%<4x&siT_LomuOE^U@le`ifjlEg$pFi0qBd@v z&D^$##LT}kNIZYSeExF3z$>3OjVbO?vnBj8HVeoM8a^X_@aj1_2%yH?^%TTwV zJD+n~6d-fG+-k;m!}xiHgb&oOv_ed{v5ulmxW3M$&D;E~%k7$&f#@V=udN~ZI17bn zc^!tYdPSVCdijMi_r53^Z*O1M^a>8fQ2Es=4R6a?49y_(eQdBS%YA6@5c560=xqbi z5EIK#U5Y`^DX)jmHkRiV>KMcA5k`*A`7-xd$@S5>ga;(nU1jp>JjAS5Oru9%gw5(J zr7QZTu0FWA_lFfLqzoYqnk(oG1+MZP7)177j;ocy6c{QPt}M>qhD|V75mJU_ccT0- zwi7DC4jk3fUd2`^s=0%}E?yo{NF_Pp05D>BU@NnYWUvgC)?VnzTn=uT`D_h@kS|rM zDhwH_b4p1naD3K)mYV&@J_>7|GEEzL#vGWb6h4@65voU}56h0FHn?*kB`K@VWrI)c zGMiTEsL_&Re=YFRo!hK10~UQ=R<1s;I zG3DDVtMUbly*YK0gfA^R#~cjDxn{;Xi_C`=U$lir7{-WS;8fMmSc9sYdaF-(sHTcq z+Z||9N?-T|c-pp4f>YvYguJ1knIBq_?$DpX&B%?1wbsZUX3u~_#{)`FANuWRed2Yz z^FwjaR|@XWba;_POJL#%pEoGPT%Ipo6l39jik1F8Qtee#Xee5{J#!I8Iuna^_Tj{U zYc!PtgJF5<{FlrQ9@>%pc{IBHL*g%ITy4swo<;P9`4SzHxZ2PiR`iNts?K~!4Tp~X zVlyy(pwdrZIAu^<=}hZyN6lUqE#nqjV2dWl-(s*nEEasuAUYhkWq@XdKRKa?H^bhT zN3s=ayS0^SbGLilMjLL=6I2d2Y zj@<7AI*8crV7w=fuvy2L1zb#x`6-~}H7#U?+#5nw0w1L26t_RZ~Q1o!D~!!xsE%*vuBamPjG zpaA$|YsAPF^axW;Sz`kEufFGk=vAiqJTR}?uqx9s?&_kNB_2l6L!q}XC=ndKrIMf< z5%U3?CVhN*w2vk7&rA^mQ>I)Q3#eEgSJ~Xt*XAx%l}Cs3ZV$GW%XkxKhiM2VR<{oc zara}QQvAoOioF<>->99%MukPO8Y9FM6zY_ryyaziWs&Vf$e;#22^yw0KIz&9^~(&kd$zd)g=X1=dRwiXb*N6jnQqzZ$om{PkI$7z+DyFzIkCtJi{TXis0*9F4gQyd*-hvDb13ex zO?jWw@2cra1ReC||`&;45^ zbG7<+BZ@{jX!V2yN+j?16-wT>0>`yFI#I{%f?&l!6j=}yk*b6%H2myz%heF%^dy+v znTt$kzZ4nZ%w^1S=FBbS ze;*>Rh?t)uPk@-OmHsV6-tHNO-nbSb4XIp|KB!Y*-*BA%S(ReCGiH{4sQQbvCcpB# zELL!=5qTAp$iwMURK$aNutNwg20e~_hiR4w^JP*Add$*$)CF~#L#z`g5|a6(wt2^3 z%s7S;D0jYS=4qA_b6%OCMl07YN!KsFZrP?4vMqt5gLd(YrdTo;Ls@FBY2=3)&RnQK zd}LoTeCul^iIPU{x^*n-x{H(XxHLE*@1eG;7kjMGW^Ws7(${g68GmTIoNaxV^`me= zAyJe6K@b9uk2SlUX%{=e97OI}&d=aZRJC>DsotIlYzUOhJO{m4_>cMBRwg;$#9m!Ia zz2c79tRrg4oo%G@M31-%^~qZVCw41InVR_Z&{I$d^NmnL(j%fAjZ%d!yqs6R9qk8u zT6vJ35=#cqU|`Ju&(Z!zE#tMBgRP#Uf$7g9{dQ>2q-Rjz zI#BX3)HDo$s`0UCsrM6xXcc&p2M;jC+MF7nvWIElB5pXiZ?W1__edlBT(?sb9-0nP zQxC4MH=p(uZLTXqSgaT%L_6thnP_@-!MTAqrYza|syiRi$#`Au)Pm*f2x6M;_==bE z(WgL~ml@z39;O|Bl^se_Hz>{07>YF3OqIKNAOY1$bNZ+e@ofv77UYlKpT15Q2+wx6 zZ#Y`a$9363A7<;}UZB4dh2t@jL#;#4xL-3^D7DlJhG_e^5y?`Y5MDG5Xp`#NjH$Ei z?>0OEN@nW=U*c$}i|;9}j4CPimY&q7XzEPHl)N9X)h>{*?>CYtq+A(BFm}|yM_|@s zRXj-QQsna$2sdqgd*fW?cfU}FV}{>f;W+oiCZPT z!Kt@sU$6B8e*q25iCX&DLMzH}!+Efh8Vn4-b!|RIK82_2T8uOR55bpI-Ej5mg6FAP zh&2Edz>mO&HYDrW;B$|MYUs>x1^ChzHKK}}L&`RZo!l&^+Djex#>lOsK+3|oPjtif zO;))1v(q^?+`;pFd9Ze&gJ^U^wZn2 z{*(G|%&uQ={sZlIa>g&TvZn&o-#YVz_E)OL?|8q{C4S-AJbBK4!utz(;&-^;OUJ+9 z%3=N)?!ODkzoY$L0{w-?3HL8(e-=c4$NIgF_Y3PQ{J&%Utm^%a_IvH(7aGpfG54Q_ z?Jt##UvPh4o!|4 +#include "OSCBoards.h" + +#ifndef analogInputToDigitalPin +int analogInputToDigitalPin(int i) +{ + switch(i) + { +#ifdef A0 + case 0: return A0; +#endif +#ifdef A1 + case 1: return A1; +#endif +#ifdef A2 + case 2: return A2; +#endif +#ifdef A3 + case 3: return A3; +#endif +#ifdef A4 + case 4: return A4; +#endif +#ifdef A5 + case 5: return A5; +#endif +#ifdef A6 + case 6: return A6; +#endif +#ifdef A7 + case 7: return A7; +#endif +#ifdef A8 + case 8: return A8; +#endif +#ifdef A9 + case 9: return A9; +#endif +#ifdef A10 + case 10: return A10; +#endif +#ifdef A11 + case 11: return A11; +#endif +#ifdef A12 + case 12: return A12; +#endif +#ifdef A13 + case 13: return A13; +#endif +#ifdef A14 + case 14: return A14; +#endif +#ifdef A15 + case 15: return A15; +#endif +#ifdef A16 + case 16: return A16; +#endif + } + return -1; +} +#endif + + +#ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK64FX512V__) || defined(__MK66FX1M0__) +float getSupplyVoltage() +{ + analogReference(DEFAULT); + analogReadResolution(12); + analogReadAveraging(32); + PMC_REGSC |= PMC_REGSC_BGBE; // 39=bandgap ref (PMC_REGSC |= PMC_REGSC_BGBE); + delay(1); + +#if defined(__MKL26Z64__) + // Teensy 3 LC + int val = analogRead(39); + return val>0? (1.0f*4095/val):0.0f; +#elif defined(__MK64FX512V__) || defined(__MK66FX1M0__) + int val = analogRead(71); + return val>0? (1.195f*4095/val):0.0f; +#else + int val = analogRead(39); + return val>0? (1.195f*4095/val):0.0f; +#endif +} + +#else +// power supply measurement on some Arduinos +float getSupplyVoltage(){ + // powersupply + int result; + // Read 1.1V reference against AVcc +#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); +#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) + ADMUX = _BV(MUX5) | _BV(MUX0); +#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) + ADMUX = _BV(MUX3) | _BV(MUX2); +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega1280__) + ADMUX = 0x40| _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) ; + ADCSRB = 0; +#else + ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); +#endif + delayMicroseconds(300); // wait for Vref to settle + ADCSRA |= _BV(ADSC); // Convert + while (bit_is_set(ADCSRA,ADSC)); + result = ADCL; + result |= ADCH<<8; + + float supplyvoltage = 1.1264f *1023 / result; + return supplyvoltage; +} +#endif + +#endif + +#ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR + +#if defined(__MK20DX128__) || defined(__MK20DX256__)|| defined(__MKL26Z64__) || defined(__MK66FX1M0__) || defined(__MK64FX512V__) +float getTemperature() +{ +#if defined(__MK64FX512V__) || defined(__MK66FX1M0__) + const int temppin = 70 ; +#else + const int temppin = 38; +#endif + // untested on all teensy 3.x + analogReference(INTERNAL); + analogReadResolution(12); + analogReadAveraging(32); + delay(2); + + float val = 25.0 + 0.17083 * (2454.19 - analogRead(temppin)); + + analogReference(DEFAULT); + + return val; +} +#else +// temperature +float getTemperature(){ + int result; + +#if defined(__AVR_ATmega32U4__) + ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); + ADCSRB = _BV(MUX5); +#else + ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); +#endif + delayMicroseconds(200); // wait for Vref to settle + ADCSRA |= _BV(ADSC); // Convert + while (bit_is_set(ADCSRA,ADSC)); + result = ADCL; + result |= ADCH<<8; + + analogReference(DEFAULT); + + return result/1023.0f; +} +#endif + +#endif diff --git a/lib/OSC/OSCBoards.h b/lib/OSC/OSCBoards.h new file mode 100644 index 0000000..29a31f7 --- /dev/null +++ b/lib/OSC/OSCBoards.h @@ -0,0 +1,56 @@ +// +// OSCBoards.h +// +// +// Created by AdrianFreed on 5/26/13. +// +// + +#ifndef _OSCBoards_h +#define _OSCBoards_h + + +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK66FX1M0__) +// Teensy 3.0 3.1 3.1LC 3.2 3.6 +#define BOARD_HAS_CAPACITANCE_SENSING +#endif + +#if defined(__AVR_ATmega32U4__) || defined(__MKL26Z64__) || defined(__MK20DX128__)|| defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__AVR_ATmega328_) || defined(__AVR_ATmega128__) + +#define BOARD_HAS_DIE_TEMPERATURE_SENSOR +#endif + +#if defined(__AVR_ATmega32U4__) || defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega328_) || defined(__AVR_ATmega128__) + + +#define BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT +#endif + + +#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega328_) || defined(__AVR_ATmega128__) +#define BOARD_HAS_ANALOG_PULLUP +#endif + +// missing specs for PIC32 + +#if (defined(__PIC32MX__) || defined(__PIC32MZ__)) +#define NUM_ANALOG_INPUTS NUM_ANALOG_PINS +#define NUM_DIGITAL_INPUTS NUM_DIGITAL_PINS +#define LED_BUILTIN PIN_LED1 + +#endif + + +#ifndef analogInputToDigitalPin +int analogInputToDigitalPin(int i); +#endif + +#ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR +float getTemperature(); +#endif + +#ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT +float getSupplyVoltage(); +#endif + +#endif diff --git a/lib/OSC/OSCBundle.cpp b/lib/OSC/OSCBundle.cpp new file mode 100644 index 0000000..3957c11 --- /dev/null +++ b/lib/OSC/OSCBundle.cpp @@ -0,0 +1,357 @@ +/* + Written by Yotam Mann, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2012, The Regents of + the University of California (Regents). + + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu + */ + +#include "OSCBundle.h" +#include + + /*============================================================================= + CONSTRUCTORS / DESTRUCTOR +=============================================================================*/ + +OSCBundle::OSCBundle(osctime_t _timetag){ + setTimetag(_timetag); + numMessages = 0; + error = OSC_OK; + messages = NULL; + incomingBuffer = NULL; + incomingBufferSize = 0; + decodeState = STANDBY; +} + +OSCBundle::~OSCBundle(){ + for (int i = 0; i < numMessages; i++){ + OSCMessage * msg = getOSCMessage(i); + delete msg; + } + free(messages); + free(incomingBuffer); +} + +//clears all of the OSCMessages inside +OSCBundle& OSCBundle::empty(){ + error = OSC_OK; + for (int i = 0; i < numMessages; i++){ + OSCMessage * msg = getOSCMessage(i); + delete msg; + } + free(messages); + messages = NULL; + clearIncomingBuffer(); + numMessages = 0; + return *this; +} + +/*============================================================================= + SETTERS + =============================================================================*/ + +OSCMessage & OSCBundle::add(const char * _address){ + OSCMessage * msg = new OSCMessage(_address); + if (!msg->hasError()){ + //realloc the array to fit the message + OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1)); + if (messageMem != NULL){ + messages = messageMem; + messages[numMessages] = msg; + numMessages++; + } else { + error = ALLOCFAILED; + } + } + return *msg; +} + +OSCMessage & OSCBundle::add(){ + OSCMessage * msg = new OSCMessage(); + //realloc the array to fit the message + OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1)); + if (messageMem != NULL){ + messages = messageMem; + messages[numMessages] = msg; + numMessages++; + } else { + error = ALLOCFAILED; + } + return *msg; +} + +OSCMessage & OSCBundle::add(OSCMessage & _msg){ + OSCMessage * msg = new OSCMessage(&_msg); + if (!msg->hasError()){ + //realloc the array to fit the message + OSCMessage ** messageMem = (OSCMessage **) realloc(messages, sizeof(OSCMessage *) * (numMessages + 1)); + if (messageMem != NULL){ + messages = messageMem; + messages[numMessages] = msg; + numMessages++; + } else { + error = ALLOCFAILED; + } + } + return *msg; +} + +/*============================================================================= + GETTERS + =============================================================================*/ + +//returns the first fullMatch. +OSCMessage * OSCBundle::getOSCMessage( char * addr){ + for (int i = 0; i < numMessages; i++){ + OSCMessage * msg = getOSCMessage(i); + if (msg->fullMatch(addr)){ + return msg; + } + } + return NULL; +} + +//the position is the same as the order they were declared in +OSCMessage * OSCBundle::getOSCMessage(int pos){ + if (pos < numMessages){ + return messages[pos]; + } + return NULL; +} + +/*============================================================================= + PATTERN MATCHING + =============================================================================*/ + + +bool OSCBundle::dispatch(const char * pattern, void (*callback)(OSCMessage&), int initial_offset){ + bool called = false; + for (int i = 0; i < numMessages; i++){ + OSCMessage msg = getOSCMessage(i); + called = msg.dispatch(pattern, callback, initial_offset) || called ; + } + return called; +} + + +bool OSCBundle::route(const char * pattern, void (*callback)(OSCMessage&, int), int initial_offset){ + bool called = false; + for (int i = 0; i < numMessages; i++){ + OSCMessage msg = getOSCMessage(i); + called = msg.route(pattern, callback, initial_offset) || called; + } + return called; +} + +/*============================================================================= + SIZE + =============================================================================*/ + + +int OSCBundle::size(){ + return numMessages; +} + +/*============================================================================= + ERROR HANDLING + =============================================================================*/ + +bool OSCBundle::hasError(){ + bool retError = error != OSC_OK; + //test each of the data + for (int i = 0; i < numMessages; i++){ + OSCMessage * msg = getOSCMessage(i); + retError |= msg->hasError(); + } + return retError; +} + +OSCErrorCode OSCBundle::getError(){ + return error; +} + + +/*============================================================================= + SENDING + =============================================================================*/ + +OSCBundle& OSCBundle::send(Print &p){ + //don't send a bundle with errors + if (hasError()){ + return *this; + } + //write the bundle header + static uint8_t header[] = {'#', 'b', 'u', 'n', 'd', 'l', 'e', 0}; + p.write(header, 8); + //write the timetag +{ + osctime_t time = timetag; + uint32_t d = BigEndian(time.seconds); + uint8_t * ptr = (uint8_t *) &d; + p.write(ptr, 4); + d = BigEndian(time.fractionofseconds); + ptr = (uint8_t *) &d; + p.write(ptr, 4); +} + + //send the messages + for (int i = 0; i < numMessages; i++){ + OSCMessage * msg = getOSCMessage(i); + int msgSize = msg->bytes(); + //turn the message size into a pointer + uint32_t s32 = BigEndian((uint32_t) msgSize); + uint8_t * sptr = (uint8_t *) &s32; + //write the message size + p.write(sptr, 4); + msg->send(p); + } + return *this; +} + +/*============================================================================= + FILLING + =============================================================================*/ + +OSCBundle& OSCBundle::fill(uint8_t incomingByte){ + decode(incomingByte); + return *this; +} + +OSCBundle& OSCBundle::fill(const uint8_t * incomingBytes, int length){ + while (length--){ + decode(*incomingBytes++); + } + return *this; +} + +/*============================================================================= + DECODING + =============================================================================*/ + +void OSCBundle::decodeTimetag(){ + //parse the incoming buffer as a uint64 + setTimetag(incomingBuffer); + //make sure the endianness is right + //xxx time tag timetag = BigEndian(timetag); + decodeState = MESSAGE_SIZE; + clearIncomingBuffer(); +} + +void OSCBundle::decodeHeader(){ + const char * header = "#bundle"; + if (strcmp(header, (char *) incomingBuffer)!=0){ + //otherwise go back to the top and wait for a new bundle header + decodeState = STANDBY; + error = INVALID_OSC; + } else { + decodeState = TIMETAG; + } + clearIncomingBuffer(); +} + +void OSCBundle::decodeMessage(uint8_t incomingByte){ + //get the current message + if (numMessages > 0){ + OSCMessage * lastMessage = messages[numMessages - 1]; + //put the bytes in there + lastMessage->fill(incomingByte); + //if it's all done + if (incomingBufferSize == incomingMessageSize){ + //move onto the next message + decodeState = MESSAGE_SIZE; + clearIncomingBuffer(); + } else if (incomingBufferSize > incomingMessageSize){ + error = INVALID_OSC; + } + } +} + +//does not validate the incoming OSC for correctness +void OSCBundle::decode(uint8_t incomingByte){ + addToIncomingBuffer(incomingByte); + switch (decodeState){ + case STANDBY: + if (incomingByte == '#'){ + decodeState = HEADER; + } else if (incomingByte == '/'){ + add();//add a simple message to the bundle + decodeMessage(incomingByte); + decodeState = MESSAGE; + } + break; + case HEADER: + if (incomingBufferSize == 8){ + decodeHeader(); + decodeState = TIMETAG; + } + break; + case TIMETAG: + if (incomingBufferSize == 8){ + decodeTimetag(); + decodeState = MESSAGE_SIZE; + } + break; + case MESSAGE_SIZE: + if (incomingBufferSize == 4){ + //make sure the message size is valid + int32_t msgSize; + memcpy(&msgSize, incomingBuffer, 4); + msgSize = BigEndian(msgSize); + if (msgSize % 4 != 0 || msgSize == 0){ + error = INVALID_OSC; + } else { + //add a message to the buffer + decodeState = MESSAGE; + incomingMessageSize = msgSize; + clearIncomingBuffer(); + //add a new empty message + add(); + } + } + break; + case MESSAGE: + decodeMessage(incomingByte); + break; + } +} + + +/*============================================================================= + INCOMING BUFFER MANAGEMENT + =============================================================================*/ + +void OSCBundle::addToIncomingBuffer(uint8_t incomingByte){ + //realloc some space for the new byte and stick it on the end + incomingBuffer = (uint8_t *) realloc ( incomingBuffer, incomingBufferSize + 1); + if (incomingBuffer != NULL){ + incomingBuffer[incomingBufferSize++] = incomingByte; + } else { + error = ALLOCFAILED; + } +} + +void OSCBundle::clearIncomingBuffer(){ + incomingBufferSize = 0; + free(incomingBuffer); + incomingBuffer = NULL; +} + + + diff --git a/lib/OSC/OSCBundle.h b/lib/OSC/OSCBundle.h new file mode 100644 index 0000000..4285749 --- /dev/null +++ b/lib/OSC/OSCBundle.h @@ -0,0 +1,175 @@ +/* + Written by Yotam Mann, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2012, 2013, The Regents of + the University of California (Regents). + + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + + */ + +#ifndef OSCBUNDLE_h +#define OSCBUNDLE_h + +#include "OSCMessage.h" + +extern osctime_t zerotime; +class OSCBundle +{ + +private: + +/*============================================================================= + PRIVATE VARIABLES +=============================================================================*/ + + //the array of messages contained in the bundle + OSCMessage ** messages; + + //the number of messages in the array + int numMessages; + + osctime_t timetag; + + //error codes + OSCErrorCode error; + +/*============================================================================= + DECODING INCOMING BYTES + =============================================================================*/ + + //the decoding states for incoming bytes + enum DecodeState { + STANDBY, + HEADER, + TIMETAG, + MESSAGE_SIZE, + MESSAGE, + } decodeState; + + //stores incoming bytes until they can be decoded + uint8_t * incomingBuffer; + int incomingBufferSize; + + //the size of the incoming message + int incomingMessageSize; + + //adds a byte to the buffer + void addToIncomingBuffer(uint8_t); + //clears the incoming buffer + void clearIncomingBuffer(); + + //decoding functions + void decode(uint8_t); + void decodeTimetag(); + void decodeHeader(); + void decodeMessage(uint8_t); + + //just a placeholder while filling + OSCMessage & add(); + + +public: + +/*============================================================================= + CONSTRUCTORS / DESTRUCTOR +=============================================================================*/ + + //default timetag of + OSCBundle(osctime_t = zerotime); + + //DESTRUCTOR + ~OSCBundle(); + + //clears all of the OSCMessages inside + OSCBundle& empty(); + +/*============================================================================= + SETTERS +=============================================================================*/ + + //start a new OSC Message in the bundle + OSCMessage & add(const char * address); + //add with nothing in it produces an invalid osc message + //copies an existing message into the bundle + OSCMessage & add(OSCMessage & msg); + + template + OSCBundle& setTimetag(T t){ + timetag = (osctime_t) t; + return *this; + } + //sets the timetag from a buffer + OSCBundle& setTimetag(uint8_t * buff){ + memcpy(&timetag, buff, 8); + return *this; + } + +/*============================================================================= + GETTERS + =============================================================================*/ + + //gets the message the matches the address string + //will do regex matching + OSCMessage * getOSCMessage(char * addr); + + //get message by position + OSCMessage * getOSCMessage(int position); + +/*============================================================================= + MATCHING +=============================================================================*/ + + //if the bundle contains a message that matches the pattern, + //call the function callback on that message + bool dispatch(const char * pattern, void (*callback)(OSCMessage&), int = 0); + + //like dispatch, but allows for partial matches + //the address match offset is sent as an argument to the callback + bool route(const char * pattern, void (*callback)(OSCMessage&, int), int = 0); + +/*============================================================================= + SIZE +=============================================================================*/ + //returns the number of messages in the bundle; + int size(); + +/*============================================================================= + ERROR + =============================================================================*/ + + bool hasError(); + + OSCErrorCode getError(); + +/*============================================================================= + SENDING + =============================================================================*/ + + OSCBundle& send(Print &p); + +/*============================================================================= + FILLING + =============================================================================*/ + + OSCBundle& fill(uint8_t incomingByte); + + OSCBundle& fill(const uint8_t * incomingBytes, int length); +}; + +#endif diff --git a/lib/OSC/OSCData.cpp b/lib/OSC/OSCData.cpp new file mode 100644 index 0000000..f72cb9a --- /dev/null +++ b/lib/OSC/OSCData.cpp @@ -0,0 +1,335 @@ + +#include "OSCData.h" + + +osctime_t zerotime = {0,0}; +/*============================================================================= + CONSTRUCTORS + + overloaded methods for each of the types which will + set the type flag, the size (in bytes), and the data +=============================================================================*/ + + +OSCData::OSCData(const char * s){ + error = OSC_OK; + type = 's'; + bytes = (strlen(s) + 1); + //own the data + char * mem = (char *) malloc(bytes); + if (mem == NULL){ + error = ALLOCFAILED; + } else { + strcpy(mem, s); + data.s = mem; + } +} + + + + +OSCData::OSCData(int32_t i){ + error = OSC_OK; + type = 'i'; + bytes = 4; + data.i = i; +} +#ifndef ESPxx +OSCData::OSCData(int i){ + error = OSC_OK; + type = 'i'; + bytes = 4; + data.i = i; +} +#endif +OSCData::OSCData(unsigned int i){ + error = OSC_OK; + type = 'i'; + bytes = 4; + data.i = i; +} +#if defined(__SAM3X8E__) +OSCData::OSCData(int16_t i){ + error = OSC_OK; + type = 'i'; + bytes = 4; + data.i = i; +} +#endif + +OSCData::OSCData(float f){ + error = OSC_OK; + type = 'f'; + bytes = 4; + data.f = f; +} + +OSCData::OSCData(osctime_t t){ + error = OSC_OK; + type = 't'; + bytes = 8; + data.time = t; +} +OSCData::OSCData(boolean b){ + error = OSC_OK; + type = b?'T':'F'; + bytes = 0; +} + + +OSCData::OSCData(double d){ + error = OSC_OK; + bytes = sizeof(double); + //if it's not 8 bytes it's not a true double + if (bytes == 8){ + type = 'd'; + data.d = d; + } else { + type = 'f'; + data.f = d; + } +} + +OSCData::OSCData(uint8_t * b, int len){ + error = OSC_OK; + type = 'b'; + bytes = len + 4; + //add the size to the front of the blob + uint32_t len32 = (uint32_t) len; + //make sure the length is endian-safe + len32 = BigEndian(len32); + uint8_t * lenPtr = (uint8_t *) (& len32); + //own the data + if(bytes>0) + { + + uint8_t * mem = (uint8_t * ) malloc(bytes); + if (mem == NULL){ + error = ALLOCFAILED; + } else { + //copy over the blob length + memcpy(mem, lenPtr, 4); + //copy over the blob data + memcpy(mem + 4, b, len); + data.b = mem; + } + } + else + data.b = 0; +} + +OSCData::OSCData (OSCData * datum){ + error = OSC_OK; + type = datum->type; + bytes = datum->bytes; + if ( (type == 'i') || (type == 'f') || (type == 'd') || (type == 't') + || (type == 'h') || (type == 'c') || (type == 'r') || (type == 'm') + ) + { + data = datum->data; + } else if ((type == 's') || (type == 'b')){ + //allocate a new piece of memory + uint8_t * mem = (uint8_t * ) malloc(bytes); + if (mem == NULL){ + error = ALLOCFAILED; + } else { + //copy over the blob length + memcpy(mem, datum->data.b, bytes); + data.b = mem; + } + } +} + +//DESTRUCTOR +OSCData::~OSCData(){ + //if there are no bytes, there is nothing to free + if (bytes>0){ + //if the data is of type 's' or 'b', need to free that memory + if (type == 's'){ + free(data.s); + }else if( type == 'b'){ + free(data.b); + } + } +} + +//sets just the type as a message placeholder +//no data +OSCData::OSCData(char t){ + error = (t == 'T' || t == 'F') ? OSC_OK : INVALID_OSC; + type = t; + bytes = 0; +} + +/*============================================================================= + GETTERS + + perform a safety check to make sure the data type matches the request + otherwise returns NULL +=============================================================================*/ + +int32_t OSCData::getInt(){ + if (type == 'i'){ + return data.i; + } else { + #ifndef ESPxx + return (int32_t)NULL; + #else + return -1; + #endif + } +} +osctime_t OSCData::getTime(){ + if (type == 't'){ + return data.time; + } else { + + return zerotime; + } +} +float OSCData::getFloat(){ + if (type == 'f'){ + return data.f; + } else { + #ifndef ESPxx + return (float)NULL; + #else + return -1; + #endif + } +} + +double OSCData::getDouble(){ + if (type == 'd'){ + return data.d; + } else { + #ifndef ESPxx + return (double)NULL; + #else + return -1; + #endif + } +} +bool OSCData::getBoolean(){ + if (type == 'T'){ + return true; + } else if (type=='F'){ + return false; + } + else + #ifndef ESPxx + return NULL; + #else + return -1; + #endif +} + + +// no-safety-check straightforward way to fill the passed buffer +// with the received string +int OSCData::getString(char * strBuffer){ + if (type == 's'){ + strncpy(strBuffer, data.s, bytes); + return bytes; + } else { + #ifndef ESPxx + return (int)NULL; + #else + return -1; + #endif + } +} + +// it's possible to pass strBuffer's size as argument (length) +// in order to check that it won't be overflown +int OSCData::getString(char * strBuffer, int length){ + if (type == 's' && bytes <= length){ + strncpy(strBuffer, data.s, bytes); + return bytes; + } else { + #ifndef ESPxx + return (int)NULL; + #else + return -1; + #endif + } +} + +// Here we can get only a part of the string +int OSCData::getString(char * strBuffer, int length, int offset, int size) +{ + int maxLen = bytes - offset; + if (type == 's' && maxLen >= 0 && size <= maxLen && size <= length){ + strncpy(strBuffer, data.s + offset, size); + return size; + } else { + #ifndef ESPxx + return (int)NULL; + #else + return -1; + #endif + } +} + +// no-safety-check straightforward way to fill the passed buffer +// with the contents of the received blob +int OSCData::getBlob(uint8_t * blobBuffer){ + // read the blob length + int blobLength = getBlobLength(); + + if (type == 'b'){ + memcpy(blobBuffer, data.b + 4, blobLength); + return blobLength; + } else { + #ifndef ESPxx + return (int)NULL; + #else + return -1; + #endif + } +} + +// it's possible to pass blobBuffer's size as argument (length) +// in order to check that it won't be overflown +int OSCData::getBlob(uint8_t * blobBuffer, int length){ + //jump over the first 4 bytes which encode the length + int blobLength = bytes-4; + if (type == 'b' && blobLength <= length){ + memcpy(blobBuffer, data.b + 4, blobLength); + return blobLength; + } else { + #ifndef ESPxx + return (int)NULL; + #else + return -1; + #endif + } +} + +// Here we can get only a part of the blob +int OSCData::getBlob(uint8_t * blobBuffer, int length, int offset, int size){ + //jump over the first 4 bytes which encode the length + int blobLength = bytes-4-offset; + if (type == 'b' && blobLength >= 0 && size <= blobLength && size <= length){ + memcpy(blobBuffer, data.b + 4 + offset, size); + return size; + } else { + #ifndef ESPxx + return (int)NULL; + #else + return -1; + #endif + } +} + +const uint8_t* OSCData::getBlob() { + return type == 'b' ? data.b + 4 : NULL; +} + +int OSCData::getBlobLength(){ + if (type == 'b'){ + //jump over the first 4 bytes which encode the length + return bytes-4; + } + return -1; +} diff --git a/lib/OSC/OSCData.h b/lib/OSC/OSCData.h new file mode 100644 index 0000000..e3f16b0 --- /dev/null +++ b/lib/OSC/OSCData.h @@ -0,0 +1,156 @@ +/* + Written by Yotam Mann, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2013, The Regents of + the University of California (Regents). + + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu + */ + +#ifndef OSCDATA_h +#define OSCDATA_h + +#include "Arduino.h" + +#include +#include +#include +#include + +#include "OSCTiming.h" + +#if (defined(TEENSYDUINO) && defined(USB_SERIAL)) || (!defined(TEENSYDUINO) && defined(__AVR_ATmega32U4__)) || defined(__SAM3X8E__) || (defined(_USB) && defined(_USE_USB_FOR_SERIAL_)) || defined(BOARD_maple_mini) + +#define BOARD_HAS_USB_SERIAL +#if defined(__SAM3X8E__) +#define thisBoardsSerialUSB SerialUSB +#else +#define thisBoardsSerialUSB Serial +#endif +#endif + +#if defined(ESP8266) || defined(ESP32) +#define ESPxx +#endif + +//ERRORS///////////////////////////////////////////////// +typedef enum { OSC_OK = 0, + BUFFER_FULL, INVALID_OSC, ALLOCFAILED, INDEX_OUT_OF_BOUNDS +} OSCErrorCode; + +class OSCData +{ + +private: + + //friends + friend class OSCMessage; + + //should only be used while decoding + //leaves an invalid OSCMessage with a type, but no data + OSCData(char t); + +public: + + //an error flag + OSCErrorCode error; + + //the size (in bytes) of the data + int bytes; + + //the type of the data + int type; + + //the data + union { + char * s; //string + int32_t i; //int + float f; //float + double d; //double + uint64_t l; //long + uint8_t * b; //blob + osctime_t time; + } data; + + //overload the constructor to account for all the types and sizes + OSCData(const char * s); +#if defined(__SAM3X8E__) + OSCData (int16_t); +#endif + OSCData (int32_t); +#ifndef ESPxx + OSCData (int); +#endif + OSCData (unsigned int); + OSCData (float); + OSCData (double); + OSCData (uint8_t *, int); + //accepts another OSCData objects and clones it + OSCData (OSCData *); + OSCData (boolean); + OSCData (osctime_t); + + //destructor + ~OSCData(); + + //GETTERS + int32_t getInt(); + float getFloat(); + double getDouble(); + int getString(char *); + int getString(char *, int); + int getString(char *, int, int, int); + int getBlob(uint8_t *); + int getBlob(uint8_t *, int); + int getBlob(uint8_t *, int, int, int); + const uint8_t* getBlob(); + int getBlobLength(); + bool getBoolean(); + osctime_t getTime(); + + //constructor from byte array with type and length + OSCData(char, uint8_t *, int); + //fill the passed in buffer with the data + //uint8_t * asByteArray(); + +}; + +/* + based on http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c + + if the system is little endian, it will flip the bits + if the system is big endian, it'll do nothing + */ +template +static inline T BigEndian(const T& x) +{ + const int one = 1; + const char sig = *(char*)&one; + if (sig == 0) return x; // for big endian machine just return the input + T ret; + int size = sizeof(T); + char* src = (char*)&x + sizeof(T) - 1; + char* dst = (char*)&ret; + while (size-- > 0){ + *dst++ = *src--; + } + return ret; +} + +#endif diff --git a/lib/OSC/OSCMatch.c b/lib/OSC/OSCMatch.c new file mode 100644 index 0000000..ce4c727 --- /dev/null +++ b/lib/OSC/OSCMatch.c @@ -0,0 +1,307 @@ +#define OSC_MATCH_ENABLE_2STARS 1 +#define OSC_MATCH_ENABLE_NSTARS 1 +/* + Written by John MacCallum, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2009, The Regents of + the University of California (Regents). + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ +#include +#include "OSCMatch.h" + +static int osc_match_star(const char *pattern, const char *address); +static int osc_match_star_r(const char *pattern, const char *address); +static int osc_match_single_char(const char *pattern, const char *address); +static int osc_match_bracket(const char *pattern, const char *address); +static int osc_match_curly_brace(const char *pattern, const char *address); + +int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset) +{ + if(!strcmp(pattern, address)){ + *pattern_offset = strlen(pattern); + *address_offset = strlen(address); + return OSC_MATCH_ADDRESS_COMPLETE | OSC_MATCH_PATTERN_COMPLETE; + } + + const char *pattern_start; + const char *address_start; + + pattern_start = pattern; + address_start = address; + + *pattern_offset = 0; + *address_offset = 0; + + while(*address != '\0' && *pattern != '\0'){ + if(*pattern == '*'){ + if(!osc_match_star(pattern, address)){ + return 0; + } + while(*pattern != '/' && *pattern != '\0'){ + pattern++; + } + while(*address != '/' && *address != '\0'){ + address++; + } + }else if(*address == '*'){ + while(*pattern != '/' && *pattern != '\0'){ + pattern++; + } + while(*address != '/' && *address != '\0'){ + address++; + } + }else{ + int n = 0; + if(!(n = osc_match_single_char(pattern, address))){ + return 0; + } + if(*pattern == '['){ + while(*pattern != ']'){ + pattern++; + } + pattern++; + address++; + }else if(*pattern == '{'){ + while(*pattern != '}'){ + pattern++; + } + pattern++; + address += n; + }else{ + pattern++; + address++; + } + } + } + + *pattern_offset = pattern - pattern_start; + *address_offset = address - address_start; + + int r = 0; + + if(*address == '\0') { + r |= OSC_MATCH_ADDRESS_COMPLETE; + } + + if(*pattern == '\0') { + r |= OSC_MATCH_PATTERN_COMPLETE; + } + + return r; +} + +static int osc_match_star(const char *pattern, const char *address) +{ + const char *address_start = address; + const char *pattern_start = pattern; + int num_stars = 0; + if(*address == '\0') { return 0; } + while(*address != '/' && *address != '\0'){ + address++; + } + while(*pattern != '/' && *pattern != '\0'){ + if(*pattern == '*'){ + num_stars++; + } + pattern++; + } + pattern--; + address--; + switch(num_stars){ + case 1: + { + const char *pp = pattern, *aa = address; + while(*pp != '*'){ + if(!(osc_match_single_char(pp, aa))){ + return 0; + } + if(*pp == ']' || *pp == '}'){ + while(*pp != '[' && *pp != '{'){ + pp--; + } + } + pp--; + aa--; + } + } + break; + case 2: +#if (OSC_MATCH_ENABLE_2STARS == 1) + { + const char *pp = pattern, *aa = address; + while(*pp != '*'){ + if(!(osc_match_single_char(pp, aa))){ + return 0; + } + if(*pp == ']' || *pp == '}'){ + while(*pp != '[' && *pp != '{'){ + pp--; + } + } + pp--; + aa--; + } + aa++; // we want to start one character forward to allow the star to match nothing + const char *star2 = pp; + const char *test = aa; + int i = 0; + while(test > address_start){ + pp = star2 - 1; + aa = test - 1; + i++; + while(*pp != '*'){ + if(!osc_match_single_char(pp, aa)){ + break; + } + if(*pp == ']' || *pp == '}'){ + while(*pp != '[' && *pp != '{'){ + pp--; + } + } + pp--; + aa--; + } + if(pp == pattern_start){ + return 1; + } + test--; + } + return 0; + } + break; +#else + return 0; +#endif + default: +#if (OSC_MATCH_ENABLE_NSTARS == 1) + return osc_match_star_r(pattern_start, address_start); + break; +#else + return 0; +#endif + } + return 1; +} + +#if (OSC_MATCH_ENABLE_NSTARS == 1) +static int osc_match_star_r(const char *pattern, const char *address) +{ + if(*address == '/' || *address == '\0'){ + if(*pattern == '/' || *pattern == '\0' || (*pattern == '*' && ((*(pattern + 1) == '/') || *(pattern + 1) == '\0'))){ + return 1; + }else{ + return 0; + } + } + if(*pattern == '*'){ + if(osc_match_star_r(pattern + 1, address)){ + return 1; + }else{ + return osc_match_star_r(pattern, address + 1); + } + }else{ + if(!osc_match_single_char(pattern, address)){ + return 0; + } + if(*pattern == '[' || *pattern == '{'){ + while(*pattern != ']' && *pattern != '}'){ + pattern++; + } + } + return osc_match_star_r(pattern + 1, address + 1); + } +} +#endif + +static int osc_match_single_char(const char *pattern, const char *address) +{ + switch(*pattern){ + case '[': + return osc_match_bracket(pattern, address); + case ']': + while(*pattern != '['){ + pattern--; + } + return osc_match_bracket(pattern, address); + case '{': + return osc_match_curly_brace(pattern, address); + case '}': + while(*pattern != '{'){ + pattern--; + } + return osc_match_curly_brace(pattern, address); + case '?': + return 1; + default: + if(*pattern == *address){ + return 1; + }else{ + return 0; + } + } + return 0; +} + +static int osc_match_bracket(const char *pattern, const char *address) +{ + pattern++; + int val = 1; + if(*pattern == '!'){ + pattern++; + val = 0; + } + int matched = !val; + while(*pattern != ']' && *pattern != '\0'){ + // the character we're on now is the beginning of a range + if(*(pattern + 1) == '-'){ + if(*address >= *pattern && *address <= *(pattern + 2)){ + matched = val; + break; + }else{ + pattern += 3; + } + }else{ + // just test the character + if(*pattern == *address){ + matched = val; + break; + } + pattern++; + } + } + return matched; +} + +static int osc_match_curly_brace(const char *pattern, const char *address) +{ + pattern++; + const char *ptr = pattern; + while(*ptr != '}' && *ptr != '\0' && *ptr != '/'){ + while(*ptr != '}' && *ptr != '\0' && *ptr != '/' && *ptr != ','){ + ptr++; + } + int n = ptr - pattern; + if(!strncmp(pattern, address, n)){ + return n; + }else{ + ptr++; + pattern = ptr; + } + } + return 0; +} \ No newline at end of file diff --git a/lib/OSC/OSCMatch.h b/lib/OSC/OSCMatch.h new file mode 100644 index 0000000..a73d26f --- /dev/null +++ b/lib/OSC/OSCMatch.h @@ -0,0 +1,78 @@ +/* + Written by John MacCallum, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2009, The Regents of + the University of California (Regents). + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef __OSC_MATCH_H__ +#define __OSC_MATCH_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Switch this off to disable matching against a pattern with 2 stars + */ + //#define OSC_MATCH_ENABLE_2STARS 1 + /** + * Switch this off to disable matching against a pattern with more than 2 stars which will + * be done recursively. + */ + //#define OSC_MATCH_ENABLE_NSTARS 1 + + /** + * Return code for osc_match() that indicates that the entire address was successfully matched + */ +#define OSC_MATCH_ADDRESS_COMPLETE 1 + + /** + * Return code for osc_match() that indicates that the entire pattern was successfully matched + */ +#define OSC_MATCH_PATTERN_COMPLETE 2 + /* + typedef struct _osc_callback { + const char* address; // Address + struct _osc_callback *child; // RAM + struct _osc_callback *sibling; // RAM + struct _osc_callback *parent; // RAM + int callback; // ROM + } osc_callback; + */ + + /** + * Match a pattern against an address. In the case of a partial match, pattern_offset + * and address_offset will contain the number of bytes into their respective strings + * where the match failed. + * + * @param pattern The pattern to match + * @param address The address to match + * @param pattern_offset The number of bytes into the pattern that were matched successfully + * @param address_offset The number of bytes into the address that were matched successfully + * @return 0 if the match failed altogether, or an or'd combination of OSC_MATCH_ADDRESS_COMPLETE and + * OSC_MATCH_PATTERN_COMPLETE. + */ + int osc_match(const char *pattern, const char *address, int *pattern_offset, int *address_offset); + +#ifdef __cplusplus +} +#endif + +#endif // __OSC_MATCH_H__ + diff --git a/lib/OSC/OSCMessage.cpp b/lib/OSC/OSCMessage.cpp new file mode 100644 index 0000000..9a18fe8 --- /dev/null +++ b/lib/OSC/OSCMessage.cpp @@ -0,0 +1,791 @@ +/* + Written by Yotam Mann, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2012, The Regents of + the University of California (Regents). + + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu + */ + +#include "OSCMessage.h" +#include "OSCMatch.h" +#include "OSCTiming.h" + +extern osctime_t zerotime; +/*============================================================================= + CONSTRUCTORS / DESTRUCTOR +=============================================================================*/ + +//constructor with address +OSCMessage::OSCMessage(const char * _address){ + setupMessage(); + setAddress(_address); +} + +//constructor with nothing +//just a placeholder since the message is invalid +OSCMessage::OSCMessage(){ + setupMessage(); + error = INVALID_OSC; +} + +//variable length constructor +//for example OSCMessage msg("/address", "isf", 1, "two", 3.0); +/* +OSCMessage::OSCMessage(const char * _address, char * types, ... ){ + setupMessage(_address); +} + */ + +//sets up a new message +void OSCMessage::setupMessage(){ + address = NULL; + //setup the attributes + dataCount = 0; + error = OSC_OK; + //setup the space for data + data = NULL; + //setup for filling the message + incomingBuffer = NULL; + incomingBufferSize = 0; + incomingBufferFree = 0; + clearIncomingBuffer(); + //set the decode state + decodeState = STANDBY; +} + +//DESTRUCTOR +OSCMessage::~OSCMessage(){ + //free everything that needs to be freed + //free the address + free(address); + //free the data + empty(); + //free the filling buffer + free(incomingBuffer); +} + +OSCMessage& OSCMessage::empty(){ + error = OSC_OK; + //free each of the data in the array + for (int i = 0; i < dataCount; i++){ + const auto datum = getOSCData(i); + //explicitly destruct the data + //datum->~OSCData(); + delete datum; + } + //and free the array + free(data); + data = NULL; + dataCount = 0; + decodeState = STANDBY; + clearIncomingBuffer(); + return *this; +} + +//COPY +OSCMessage::OSCMessage(OSCMessage * msg){ + //start with a message with the same address + setupMessage(); + setAddress(msg->address); + //add each of the data to the other message + for (int i = 0; i < msg->dataCount; i++){ + add(msg->data[i]); + } +} + +/*============================================================================= + GETTING DATA +=============================================================================*/ + +OSCData * OSCMessage::getOSCData(int position){ + if (position < dataCount){ + const auto datum = data[position]; + return datum; + } else { + error = INDEX_OUT_OF_BOUNDS; + return nullptr; + } +} + +int32_t OSCMessage::getInt(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getInt(); + } else { + return 0; + } +} +osctime_t OSCMessage::getTime(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getTime(); + } else { + return zerotime; + } +} +float OSCMessage::getFloat(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getFloat(); + } else { + return 0.0f; + } +} + +double OSCMessage::getDouble(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getDouble(); + } else { + + return 0.0; + } +} + +bool OSCMessage::getBoolean(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getBoolean(); + } else { + return false; + } +} + + +int OSCMessage::getString(int position, char * buffer){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getString(buffer, datum->bytes); + } else { + return -1; + } +} + +int OSCMessage::getString(int position, char * buffer, int bufferSize){ + const auto datum = getOSCData(position); + if (!hasError()){ + //the number of bytes to copy is the smaller between the buffer size and the datum's byte length + int copyBytes = bufferSize < datum->bytes? bufferSize : datum->bytes; + return datum->getString(buffer, copyBytes); + } else { + return -1; + } +} + +int OSCMessage::getString(int position, char * buffer, int bufferSize, int offset, int size){ + const auto datum = getOSCData(position); + if (!hasError()){ + //the number of bytes to copy is the smaller between the buffer size and the datum's byte length + int copyBytes = bufferSize < datum->bytes? bufferSize : datum->bytes; + return datum->getString(buffer, copyBytes, offset, size); + } else { + return -1; + } +} + + +int OSCMessage::getBlob(int position, uint8_t * buffer){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getBlob(buffer); + } else { + return -1; + } +} + +int OSCMessage::getBlob(int position, uint8_t * buffer, int bufferSize){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getBlob(buffer, bufferSize); + } else { + return -1; + } +} + +int OSCMessage::getBlob(int position, uint8_t * buffer, int bufferSize, int offset, int size){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getBlob(buffer, bufferSize, offset, size); + } else { + return -1; + } +} + +const uint8_t* OSCMessage::getBlob(int position) { + const auto datum = getOSCData(position); + if(!hasError()) { + return datum->getBlob(); + } else { + return nullptr; + } +} + +uint32_t OSCMessage::getBlobLength(int position) +{ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->getBlobLength(); + } else { + return 0; + } + +} + +char OSCMessage::getType(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->type; + } else { + return '\0'; + } +} + +int OSCMessage::getDataLength(int position){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->bytes; + } else { + return 0; + } +} + +/*============================================================================= + TESTING DATA +=============================================================================*/ + +bool OSCMessage::testType(int position, char type){ + const auto datum = getOSCData(position); + if (!hasError()){ + return datum->type == type; + } else { + return false; + } +} + +bool OSCMessage::isInt(int position){ + return testType(position, 'i'); +} + +bool OSCMessage::isTime(int position){ + return testType(position, 't'); +} + + +bool OSCMessage::isFloat(int position){ + return testType(position, 'f'); +} + +bool OSCMessage::isBlob(int position){ + return testType(position, 'b'); +} + +bool OSCMessage::isChar(int position){ + return testType(position, 'c'); +} + +bool OSCMessage::isString(int position){ + return testType(position, 's'); +} + +bool OSCMessage::isDouble(int position){ + return testType(position, 'd'); +} +bool OSCMessage::isBoolean(int position){ + return testType(position, 'T') || testType(position, 'F'); +} + + +/*============================================================================= + PATTERN MATCHING +=============================================================================*/ + +int OSCMessage::match(const char * pattern, int addr_offset){ + int pattern_offset; + int address_offset; + int ret = osc_match(address + addr_offset, pattern, &pattern_offset, &address_offset); + char * next = (char *) (address + addr_offset + pattern_offset); + if (ret==3){ + return pattern_offset; + } else if (pattern_offset > 0 && *next == '/'){ + return pattern_offset; + } else { + return 0; + } +} + +bool OSCMessage::fullMatch( const char * pattern, int addr_offset){ + int pattern_offset; + int address_offset; + int ret = osc_match(address + addr_offset, pattern, &pattern_offset, &address_offset ); + return (ret==3); +} + +bool OSCMessage::dispatch(const char * pattern, void (*callback)(OSCMessage &), int addr_offset){ + if (fullMatch(pattern, addr_offset)){ + callback(*this); + return true; + } else { + return false; + } +} + +bool OSCMessage::route(const char * pattern, void (*callback)(OSCMessage &, int), int initial_offset){ + int match_offset = match(pattern, initial_offset); + if (match_offset>0){ + callback(*this, match_offset + initial_offset); + return true; + } else { + return false; + } +} + +/*============================================================================= + ADDRESS + =============================================================================*/ + +int OSCMessage::getAddress(char * buffer, int offset){ + int result = strlen(address); + if (result > offset) + strcpy(buffer, address+offset); + else + *buffer = 0; + return result - offset; // could be negative! +} + +int OSCMessage::getAddress(char * buffer, int offset, int len){ + int result = strlen(address); + + if (result > offset) + { + strncpy(buffer, address+offset, len); // N.B. NOT guaranteed to null-terminate! So... + buffer[len-1] = 0; // ...prevent strlen() blowing up + } + else + *buffer = 0; + return strlen(buffer); +} + +const char* OSCMessage::getAddress(){ + return address; +} + +int OSCMessage::getAddressLength(int offset) +{ + int result = (int) strlen(address) - offset; + if (result < 0) // offset past end! + result = 0; // do the best we can + return result; +} + +OSCMessage& OSCMessage::setAddress(const char * _address){ + //free the previous address + free(address); // are we sure address was allocated? + //copy the address + char * addressMemory = (char *) malloc( (strlen(_address) + 1) * sizeof(char) ); + if (addressMemory == NULL){ + error = ALLOCFAILED; + address = NULL; + } else { + strcpy(addressMemory, _address); + address = addressMemory; + } + return *this; +} + +/*============================================================================= + SIZE +=============================================================================*/ + +#ifdef SLOWpadcalculation +int OSCMessage::padSize(int _bytes){ + int space = (_bytes + 3) / 4; + space *= 4; + return space - _bytes; +} +#else +static inline int padSize(int bytes) { return (4- (bytes&03))&3; } +#endif +//returns the number of OSCData in the OSCMessage +int OSCMessage::size(){ + return dataCount; +} + +int OSCMessage::bytes(){ + int messageSize = 0; + //send the address + int addrLen = strlen(address) + 1; + messageSize += addrLen; + //padding amount + int addrPad = padSize(addrLen); + messageSize += addrPad; + //add the comma separator + messageSize += 1; + //add the types + messageSize += dataCount; + //pad the types + int typePad = padSize(dataCount + 1); //for the comma + if (typePad == 0){ + typePad = 4; // to make sure the type string is null terminated + } + messageSize+=typePad; + //then the data + for (int i = 0; i < dataCount; i++){ + const auto datum = getOSCData(i); + messageSize+=datum->bytes; + messageSize += padSize(datum->bytes); + } + return messageSize; +} + +/*============================================================================= + ERROR HANDLING +=============================================================================*/ + +bool OSCMessage::hasError(){ + if(error != OSC_OK) return true; + //test each of the data + for (int i = 0; i < dataCount; i++){ + if(getOSCData(i)->error) return true; + } + return false; +} + +OSCErrorCode OSCMessage::getError(){ + return error; +} + +/*============================================================================= + SENDING + =============================================================================*/ + +OSCMessage& OSCMessage::send(Print &p){ + //don't send a message with errors + if (hasError()){ + return *this; + } + uint8_t nullChar = '\0'; + //send the address + int addrLen = strlen(address) + 1; + //padding amount + int addrPad = padSize(addrLen); + //write it to the stream + p.write((uint8_t *) address, addrLen); + //add the padding + while(addrPad--){ + p.write(nullChar); + } + //add the comma separator + p.write((uint8_t) ','); + //add the types +#ifdef PAULSSUGGESTION + // Paul suggested buffering on the stack + // to improve performance. The problem is this could exhaust the stack + // for long complex messages + { + uint8_t typstr[dataCount]; + + for (int i = 0; i < dataCount; i++){ + typstr[i] = getType(i); + } + p.write(typstr,dataCount); + } +#else + for (int i = 0; i < dataCount; i++){ + p.write((uint8_t) getType(i)); + } +#endif + //pad the types + int typePad = padSize(dataCount + 1); // 1 is for the comma + if (typePad == 0){ + typePad = 4; // This is because the type string has to be null terminated + } + while(typePad--){ + p.write(nullChar); + } + //write the data + for (int i = 0; i < dataCount; i++){ + const auto datum = getOSCData(i); + if ((datum->type == 's') || (datum->type == 'b')){ + p.write(datum->data.b, datum->bytes); + int dataPad = padSize(datum->bytes); + while(dataPad--){ + p.write(nullChar); + } + } else if (datum->type == 'd'){ + double d = BigEndian(datum->data.d); + uint8_t * ptr = (uint8_t *) &d; + p.write(ptr, 8); + } else if (datum->type == 't'){ + osctime_t time = datum->data.time; + uint32_t d = BigEndian(time.seconds); + uint8_t * ptr = (uint8_t *) &d; + p.write(ptr, 4); + d = BigEndian(time.fractionofseconds); + ptr = (uint8_t *) &d; + p.write(ptr, 4); + + } else if (datum->type == 'T' || datum->type == 'F') + { } + else { // float or int + uint32_t i = BigEndian(datum->data.i); + uint8_t * ptr = (uint8_t *) &i; + p.write(ptr, datum->bytes); + } + } + return *this; +} + +/*============================================================================= + FILLING + =============================================================================*/ + +OSCMessage& OSCMessage::fill(uint8_t incomingByte){ + decode(incomingByte); + return *this; +} + +OSCMessage& OSCMessage::fill(uint8_t * incomingBytes, int length){ + while (length--){ + decode(*incomingBytes++); + } + return *this; +} + +/*============================================================================= + DECODING + =============================================================================*/ + +void OSCMessage::decodeAddress(){ + setAddress((char *) incomingBuffer); + //change the error from invalid message + error = OSC_OK; + clearIncomingBuffer(); +} + +void OSCMessage::decodeType(uint8_t incomingByte){ + char type = incomingByte; + add(type); +} + +void OSCMessage::decodeData(uint8_t incomingByte){ + //get the first OSCData to re-set + for (int i = 0; i < dataCount; i++){ + const auto datum = getOSCData(i); + if (datum->error == INVALID_OSC){ + //set the contents of datum with the data received + switch (datum->type){ + case 'i': + if (incomingBufferSize == 4){ + //parse the buffer as an int + union { + int32_t i; + uint8_t b[4]; + } u; + memcpy(u.b, incomingBuffer, 4); + int32_t dataVal = BigEndian(u.i); + set(i, dataVal); + clearIncomingBuffer(); + } + break; + case 'f': + if (incomingBufferSize == 4){ + //parse the buffer as a float + union { + float f; + uint8_t b[4]; + } u; + memcpy(u.b, incomingBuffer, 4); + float dataVal = BigEndian(u.f); + set(i, dataVal); + clearIncomingBuffer(); + } + break; + case 'd': + if (incomingBufferSize == 8){ + //parse the buffer as a double + union { + double d; + uint8_t b[8]; + } u; + memcpy(u.b, incomingBuffer, 8); + double dataVal = BigEndian(u.d); + set(i, dataVal); + clearIncomingBuffer(); + } + break; + case 't': + if (incomingBufferSize == 8){ + //parse the buffer as a timetag + union { + osctime_t t; + uint8_t b[8]; + } u; + memcpy(u.b, incomingBuffer, 8); + + u.t.seconds = BigEndian(u.t.seconds); + u.t.fractionofseconds = BigEndian(u.t.fractionofseconds); + set(i, u.t); + clearIncomingBuffer(); + } + break; + + case 's': + if (incomingByte == 0){ + char * str = (char *) incomingBuffer; + set(i, str); + clearIncomingBuffer(); + decodeState = DATA_PADDING; + } + break; + case 'b': + if (incomingBufferSize > 4){ + //compute the expected blob size + union { + uint32_t i; + uint8_t b[4]; + } u; + memcpy(u.b, incomingBuffer, 4); + uint32_t blobLength = BigEndian(u.i); + if (incomingBufferSize == (int)(blobLength + 4)){ + set(i, incomingBuffer + 4, blobLength); + clearIncomingBuffer(); + decodeState = DATA_PADDING; + } + + } + break; + } + //break out of the for loop once we've selected the first invalid message + break; + } + } +} + +//does not validate the incoming OSC for correctness +void OSCMessage::decode(uint8_t incomingByte){ + addToIncomingBuffer(incomingByte); + switch (decodeState){ + case STANDBY: + if (incomingByte == '/'){ + decodeState = ADDRESS; + } + break; + case ADDRESS: + if (incomingByte == 0){ + //end of the address + //decode the address + decodeAddress(); + //next state + decodeState = ADDRESS_PADDING; + } + break; + case ADDRESS_PADDING: + //it does not count the padding + if (incomingByte==','){ + //next state + decodeState = TYPES; + clearIncomingBuffer(); + } + break; + case TYPES: + if (incomingByte != 0){ + //next state + decodeType(incomingByte); + } else { + decodeState = TYPES_PADDING; + } + //FALL THROUGH to test if it should go to the data state + case TYPES_PADDING: { + //compute the padding size for the types + //to determine the start of the data section + int typePad = padSize(dataCount + 1); // 1 is the comma + if (typePad == 0){ + typePad = 4; // to make sure it will be null terminated + } + if (incomingBufferSize == (typePad + dataCount)){ + clearIncomingBuffer(); + decodeState = DATA; + } + } + break; + case DATA: + decodeData(incomingByte); + break; + case DATA_PADDING:{ + //get the last valid data + for (int i = dataCount - 1; i >= 0; i--){ + const auto datum = getOSCData(i); + if (datum->error == OSC_OK){ + //compute the padding size for the data + int dataPad = padSize(datum->bytes); + // if there is no padding required, switch back to DATA, and don't clear the incomingBuffer because it holds next data + if (dataPad == 0){ + decodeState = DATA; + } + else if (incomingBufferSize == dataPad){ + clearIncomingBuffer(); + decodeState = DATA; + } + break; + } + } + } + break; + case DONE: + break; // TODO: is this correct? - was missing from original code, it did this by default + } +} + + +/*============================================================================= + INCOMING BUFFER MANAGEMENT + =============================================================================*/ +#define OSCPREALLOCATEIZE 16 +void OSCMessage::addToIncomingBuffer(uint8_t incomingByte){ + //realloc some space for the new byte and stick it on the end + if(incomingBufferFree>0) + { + incomingBuffer[incomingBufferSize++] = incomingByte; + incomingBufferFree--; + } + else + { + + incomingBuffer = (uint8_t *) realloc ( incomingBuffer, incomingBufferSize + 1 + OSCPREALLOCATEIZE); + if (incomingBuffer != NULL){ + incomingBuffer[incomingBufferSize++] = incomingByte; + incomingBufferFree = OSCPREALLOCATEIZE; + } else { + error = ALLOCFAILED; + } + } +} + +void OSCMessage::clearIncomingBuffer(){ + incomingBuffer = (uint8_t *) realloc ( incomingBuffer, OSCPREALLOCATEIZE); + if (incomingBuffer != NULL){ + incomingBufferFree = OSCPREALLOCATEIZE; + } else { + error = ALLOCFAILED; + incomingBuffer = NULL; + + } + incomingBufferSize = 0; +} diff --git a/lib/OSC/OSCMessage.h b/lib/OSC/OSCMessage.h new file mode 100644 index 0000000..3d9d448 --- /dev/null +++ b/lib/OSC/OSCMessage.h @@ -0,0 +1,350 @@ +/* + Written by Yotam Mann, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2012, The Regents of + the University of California (Regents). + + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu + */ + +#ifndef OSCMESSAGE_h +#define OSCMESSAGE_h + +#include "OSCData.h" +#include + + +class OSCMessage +{ + +private: + + //friends + friend class OSCBundle; + + +/*============================================================================= + PRIVATE VARIABLES +=============================================================================*/ + + //the address + char * address; + + //the data + OSCData ** data; + + //the number of OSCData in the data array + int dataCount; + + //error codes for potential runtime problems + OSCErrorCode error; + +/*============================================================================= + DECODING INCOMING BYTES + =============================================================================*/ + + //the decoding states for incoming bytes + enum DecodeState { + STANDBY, + ADDRESS, + ADDRESS_PADDING, + TYPES, + TYPES_PADDING, + DATA, + DATA_PADDING, + DONE, + } decodeState; + + //stores incoming bytes until they can be decoded + uint8_t * incomingBuffer; + int incomingBufferSize; // how many bytes are stored + int incomingBufferFree; // how many bytes are allocated but unused + + //adds a byte to the buffer + void addToIncomingBuffer(uint8_t); + //clears the incoming buffer + void clearIncomingBuffer(); + + //decoding function + void decode(uint8_t); + void decodeAddress(); + void decodeType(uint8_t); + void decodeData(uint8_t); + +/*============================================================================= + HELPER FUNCTIONS +=============================================================================*/ + + void setupMessage(); + + //compares the OSCData's type char to a test char + bool testType(int position, char type); + + //returns the number of bytes to pad to make it 4-bit aligned + // int padSize(int bytes); + +public: + + //returns the OSCData at that position + OSCData * getOSCData(int); + +/*============================================================================= + CONSTRUCTORS / DESTRUCTOR +=============================================================================*/ + + //new constructor needs an address + OSCMessage (const char * _address); + //no address + //placeholder since it's invalid OSC + OSCMessage(); + + //can optionally accept all of the data after the address + //OSCMessage(const char * _address, char * types, ... ); + //created from another OSCMessage + OSCMessage (OSCMessage *); + + //DESTRUCTOR + ~OSCMessage(); + + //empties all of the data + OSCMessage& empty(); + +/*============================================================================= + SETTING DATA +=============================================================================*/ + + //returns the OSCMessage so that multiple 'add's can be strung together + template + OSCMessage& add(T datum){ + //make a piece of data + OSCData * d = new OSCData(datum); + //check if it has any errors + if (d->error == ALLOCFAILED){ + error = ALLOCFAILED; + } else { + //resize the data array + OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1)); + if (dataMem == NULL){ + error = ALLOCFAILED; + } else { + data = dataMem; + //add data to the end of the array + data[dataCount] = d; + //increment the data size + dataCount++; + } + } + return *this; + } + + //blob specific add + OSCMessage& add(uint8_t * blob, int length){ + //make a piece of data + OSCData * d = new OSCData(blob, length); + //check if it has any errors + if (d->error == ALLOCFAILED){ + error = ALLOCFAILED; + } else { + //resize the data array + OSCData ** dataMem = (OSCData **) realloc(data, sizeof(OSCData *) * (dataCount + 1)); + if (dataMem == NULL){ + error = ALLOCFAILED; + } else { + data = dataMem; + //add data to the end of the array + data[dataCount] = d; + //increment the data size + dataCount++; + } + } + return *this; + } + + //sets the data at a position + template + OSCMessage& set(int position, T datum){ + if (position < dataCount){ + //replace the OSCData with a new one + OSCData * oldDatum = getOSCData(position); + //destroy the old one + delete oldDatum; + //make a new one + OSCData * newDatum = new OSCData(datum); + //test if there was an error + if (newDatum->error == ALLOCFAILED){ + error = ALLOCFAILED; + } else { + //otherwise, put it in the data array + data[position] = newDatum; + } + } else if (position == (dataCount)){ + //add the data to the end + add(datum); + } else { + //else out of bounds error + error = INDEX_OUT_OF_BOUNDS; + } + return *this; + } + + //blob specific setter + OSCMessage& set(int position, uint8_t * blob, int length){ + if (position < dataCount){ + //replace the OSCData with a new one + OSCData * oldDatum = getOSCData(position); + //destroy the old one + delete oldDatum; + //make a new one + OSCData * newDatum = new OSCData(blob, length); + //test if there was an error + if (newDatum->error == ALLOCFAILED){ + error = ALLOCFAILED; + } else { + //otherwise, put it in the data array + data[position] = newDatum; + } + } else if (position == (dataCount)){ + //add the data to the end + add(blob, length); + } else { + //else out of bounds error + error = INDEX_OUT_OF_BOUNDS; + } + return *this; + } + + OSCMessage& setAddress(const char *); + +/*============================================================================= + GETTING DATA + + getters take a position as an argument +=============================================================================*/ + + int32_t getInt(int); + osctime_t getTime(int); + + float getFloat(int); + double getDouble(int); + bool getBoolean(int); + + //return the copied string's length + int getString(int, char *); + //check that it won't overflow the passed buffer's size with a third argument + int getString(int, char *, int); + //offset and size can be defined in order to only query a part of the string + int getString(int, char *, int, int, int); + + //returns the number of unsigned int8's copied into the buffer + int getBlob(int, uint8_t *); + //check that it won't overflow the passed buffer's size with a third argument + int getBlob(int, uint8_t *, int); + //offset and size can be defined in order to only query a part of the blob's content + int getBlob(int, uint8_t *, int, int, int); + //get pointer to blob + const uint8_t* getBlob(int); + + + // returns the length of blob + uint32_t getBlobLength(int position); + + //returns the number of bytes of the data at that position + int getDataLength(int); + + //returns the type at the position + char getType(int); + + //put the address in the buffer + int getAddress(char * buffer, int offset = 0); + int getAddress(char * buffer, int offset, int len); + + const char* getAddress(); + + // Find out address length so we can create a buffer + int getAddressLength(int offset = 0); + + +/*============================================================================= + TESTING DATA + + testers take a position as an argument +=============================================================================*/ + + bool isInt(int); + bool isFloat(int); + bool isBlob(int); + bool isChar(int); + bool isString(int); + bool isDouble(int); + bool isBoolean(int); + bool isTime(int); + +/*============================================================================= + PATTERN MATCHING +=============================================================================*/ + + //match the pattern against the address + //returns true only for a complete match + bool fullMatch( const char * pattern, int = 0); + + //returns the number of characters matched in the address + int match( const char * pattern, int = 0); + + //calls the function with the message as the arg if it was a full match + bool dispatch(const char * pattern, void (*callback)(OSCMessage &), int = 0); + + //like dispatch, but allows for partial matches + //the address match offset is sent as an argument to the callback + //also room for an option address offset to allow for multiple nested routes + bool route(const char * pattern, void (*callback)(OSCMessage &, int), int = 0); + + + +/*============================================================================= + SIZE +=============================================================================*/ + + //the number of data that the message contains + int size(); + + //computes the number of bytes the OSCMessage occupies if everything is 32-bit aligned + int bytes(); + +/*============================================================================= + TRANSMISSION + =============================================================================*/ + + //send the message + OSCMessage& send(Print &p); + + //fill the message from a byte stream + OSCMessage& fill(uint8_t); + OSCMessage& fill(uint8_t *, int); + +/*============================================================================= + ERROR +=============================================================================*/ + + bool hasError(); + + OSCErrorCode getError(); + +}; + +#endif diff --git a/lib/OSC/OSCTiming.cpp b/lib/OSC/OSCTiming.cpp new file mode 100644 index 0000000..1f85073 --- /dev/null +++ b/lib/OSC/OSCTiming.cpp @@ -0,0 +1,178 @@ +/* + Written by Adrian Freed, The Center for New Music and Audio Technologies, + University of California, Berkeley. Copyright (c) 2013, The Regents of + the University of California (Regents). + + Permission to use, copy, modify, distribute, and distribute modified versions + of this software and its documentation without fee and without a signed + licensing agreement, is hereby granted, provided that the above copyright + notice, this paragraph and the following two paragraphs appear in all copies, + modifications, and distributions. + + IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING + OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED + HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE + MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + For bug reports and feature requests please email me at yotam@cnmat.berkeley.edu + */ + + +#include "OSCTiming.h" + +#if defined(TEENSYDUINO) && defined(__arm__) +extern volatile uint32_t systick_millis_count; +static uint32_t savedcount, savedcurrent; + +static void latchOscTime() +{ + + uint32_t istatus; + uint32_t count, current; + + __disable_irq(); + current = SYST_CVR; + count = systick_millis_count; + istatus = SCB_ICSR; // bit 26 indicates if systick exception pending + __enable_irq(); + //systick_current = current; + //systick_count = count; + //systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0; + if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++; + current = ((F_CPU / 1000) - 1) - current; + savedcount=count; savedcurrent=current; +} +static osctime_t computeOscTime() +{ //4,294,967,296 + + + osctime_t t; + + + t.seconds = (( uint64_t)(savedcount/1000)) ; + + + t.fractionofseconds = ( (uint64_t)(4294967295) * ( (savedcount * 1000 + (uint64_t)savedcurrent / (F_CPU / 1000000UL)) % 1000000) ) /1000000; + return t; +} + +osctime_t oscTime() +{ + latchOscTime(); + return computeOscTime(); +} + +#elif defined(CORE_TEENSY) +extern volatile uint32_t timer0_millis_count; +static uint32_t savedcount, savedmicros; + +static void latchOscTime() +{ + noInterrupts(); + savedcount = timer0_millis_count; + savedmicros = micros(); + interrupts(); +} + +static osctime_t computeOscTime() +{ //4,294,967,296 + osctime_t t; + savedmicros %= 1000000; + t.fractionofseconds= (67108864ULL * savedmicros) / 15625 ; // 2^32/1000000 + t.seconds = savedcount/1000; + return t; +#ifdef ddfgsdfgsdfgsdfg + return ((savedcount/1000)<<32) + ( (4294967295ULL) * ( (savedcount * 1000ULL + savedmicros) % 1000000ULL) ) /1000000ULL + + ; +#endif + + +} +osctime_t oscTime() +{ + latchOscTime(); + return computeOscTime(); + +} +#elif defined(AVR) || defined(__AVR_ATmega32U4__) || defined(__SAM3X8E__) || defined(_SAMD21_) || defined(__ARM__) +static uint32_t savedcount, savedmicros; + + +static void latchOscTime() +{ + noInterrupts(); + //cli(); + savedcount = millis(); + savedmicros = micros(); + interrupts(); + //sei(); +} + +osctime_t computeOscTime() +{ //4,294,967,296 + osctime_t t; + savedmicros %= 1000000UL; + // t.fractionofseconds = (67108864ULL * (uint64_t)savedmicros) / 15625ULL ; // 2^32/1000000 + t.fractionofseconds= (67108864UL * savedmicros)/ 15625ULL ; // 2^32/1000000 + t.seconds = savedcount/1000; + return t; + + + +} +osctime_t oscTime() +{ + latchOscTime(); + return computeOscTime(); +} + +#else + + + +static void latchOscTime() +{ +} + +osctime_t oscTime() +{ + osctime_t t; + t.fractionofseconds = 1; + return t; + +} +#endif + +int adcRead(int pin, osctime_t *t) +{ + latchOscTime(); + + int v =analogRead(pin); + *t = oscTime(); + return v; +} +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK66FX1M0__) +int capacitanceRead(int pin, osctime_t *t) +{ + latchOscTime(); + int v = touchRead(pin); + + *t = oscTime(); + return v; +} +#endif +int inputRead(int pin, osctime_t *t) +{ + + int v =digitalRead(pin); + *t = oscTime(); + + return v; +} diff --git a/lib/OSC/OSCTiming.h b/lib/OSC/OSCTiming.h new file mode 100644 index 0000000..4fc9f32 --- /dev/null +++ b/lib/OSC/OSCTiming.h @@ -0,0 +1,30 @@ +// +// OSCTiming.h +// +// +// Created by AdrianFreed on 11/10/13. +// +// + +#ifndef ____OSCTiming__ +#define ____OSCTiming__ + + +#include "Arduino.h" +#include +#include +#include +typedef struct +{ + uint32_t seconds; + uint32_t fractionofseconds; +} osctime_t; + +osctime_t oscTime(); +int adcRead(int pin, osctime_t *t); +int capacitanceRead(int pin, osctime_t *t); + +int inputRead(int pin, uint64_t *t); + + +#endif /* defined(____OSCTiming__) */ diff --git a/lib/OSC/README.md b/lib/OSC/README.md new file mode 100644 index 0000000..bd035f0 --- /dev/null +++ b/lib/OSC/README.md @@ -0,0 +1,235 @@ +# OSC for Arduino + +This is an Arduino and Teensy library implementation of the [OSC](http://opensoundcontrol.org) (Open Sound Control) encoding.It was developed primarily by Yotam Mann and Adrian Freed at CNMAT where OSC was invented. It benefits from contributions from John MacCallum, Matt Wright, Jeff Lubow and Andy Schmeder and many beta testers. + +Features: + +* Supports the four basic OSC data types (32-bit integers, 32-bit floats, strings, and blobs - arbitrary length byte sequences) +* Supports the optional 64-bit timetag data type and Booleans +* Address pattern matching +* Dynamic memory allocation +* Sends and receives OSC packets over transport layers that implements the Arduino Stream Class such as Serial and Ethernet UDP + +# Installation + +We recommend Arduino 1.8.5 and a compatible Teensyduino overlay if you use the Teensy. Install using the library manager. + +Additional information about installing libraries on [Arduino's website](https://www.arduino.cc/en/Guide/Libraries). + +# Examples + +The `Applications` folder contains examples for Max/MSP and PD and Processing that work with the example sketches. This will be expanded to include other applications like TouchOSC and Processing. For the Max/MSP examples you will need to download the CNMAT max externals package that includes the "o." objects available [here](http://cnmat.berkeley.edu/downloads). + +# API + +OSC for Arduino supports creating, sending and receiving OSCMessages individually and wrapped into OSCBundles. + +The full API is available [here](./API.md). + +### Sending Data + +Create a new `OSCMessage` with an address in the constructor: + +```C++ +OSCMessage msg("/address"); +``` + +add some data to it: + +```C++ +msg.add(1); +msg.add(2.0); +msg.add("three"); +``` + +`add` will infer the type of the data and encode it correctly. The API also supports chaining, so multiple calls to `add` can be strung together: + +```C++ +msg.add(1).add(2.0f).add("three"); +``` + +Then send it over any transport layer that extends Arduino's [Print class](http://playground.arduino.cc/Code/Printclass) like the `Serial` out. + +```C++ +msg.send(Serial); +``` + +### Receiving Data + +In a typical Serial stream, there is no way to know where one message ends and another begins. That's why we recommend using `SLIPSerial` (which also comes in the OSC for Arduino Package). Read more about the lightweight [SLIP encoding](https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol). + +To receive an OSCMessage, wait for the end of SLIP Stream, and fill an empty OSCMessage with the available bytes: + +```C++ +//make an empty message to fill with the incoming data +OSCMessage msg; +//wait for the end of the packet to be received +while(!SLIPSerial.endofPacket()){ + int size = SLIPSerial.available(); + if (size > 0){ + //fill the msg with all of the available bytes + while(size--){ + msg.fill(SLIPSerial.read()); + } + } +} +``` + +Now you can query and use the data you received: + +```C++ +//returns true if the data in the first position is an integer +if (msg.isInt(0)){ + //get that integer + int data = msg.getInt(0); +} +``` + +### Routing / Dispatching + +OSCMessages can be routed to a specific function by matching their address exactly or with an OSC pattern. + +`dispatch` will do a full match on the OSCMessage's address or patterned address. + +```C++ +OSCMessage msg("/a/1"); +msg.dispatch("/a/1", dispatchAddress); +``` + +And the function definition of `dispatchAddress` could be as follows: + +```C++ +//called whenever an OSCMessage's address matches "/a/1" +void dispatchAddress(OSCMessage &msg){ + //do something with the OSCMessage... + if (msg.isFloat(0)){ + float val = msg.getFloat(0); + } +} +``` + +`route` does the same thing as `dispatch` but allows for partial address matching as long as they are aligned to a `/` character. + +```C++ +OSCMessage msg("/b/2"); +msg.route("/b", routeAddress); +``` + +```C++ +//called whenever an OSCMessage's address matches "/b" +void routeAddress(OSCMessage &msg, int addressOffset){ + //do something with the OSCMessage... + if (msg.isBoolean(0)){ + bool val = msg.getBoolean(0); + } +} +``` + +### OSCBundles + +An OSCBundle is a group of OSCMessage that can be sent and received together. + +```C++ +OSCBundle bundle; +//add a new OSCMessage to the bundle with the address "/a" +OSCMessage msgA = bundle.add("/a"); +//add some data to that message +msgA.add("some data"); +//append another OSCMessage, this time chaining 'add' calls +bundle.add("/b").add("some more data").add("even more data"); +``` + +Now send the OSCBundle over SLIPSerial + +```C++ +//start a new SLIP Packet +SLIPSerial.beginPacket(); +//send the data +bundle.send(SLIPSerial); +//end the packet +SLIPSerial.endPacket(); +``` + +### SLIP Serial + +The OSC for Arduino library includes extensions of the USB serial and Hardware serial functions of the Arduino core that sends and receives data using the SLIP encoding. This makes Max/MSP and PD integration very simple using CNMAT's o.io.slipserial. The SLIPSerial library implements the same methods as the Serial object with additional `beginPacket` and `endPacket` methods to mark the boundaries of each packet in a serial stream. + +When sending data, begin each packet with `SLIPSerial.beginPacket()`, then write any data to the SLIPSerial and signify the end of the packet using `SLIPSerial.endPacket()`. + +On the receiving side, in addition to the normal `read` and `available` methods of the Serial object, SLIPSerial includes `SLIPSerial.endofPacket()` which returns true when the EOT (End Of Transmission) character is received, marking the end of the data packet. + +# Oscuino + +As well as many small examples illustrating the API, there is a larger application called "oscuino" that illustrates how to use OSC to simplify situations Firmata and Maxuino are typically used in. + +# Support + +### IDEs + +Arduino 1.8.5 + +Best Supported Board: +ARM boards such M0, Zero, Teensy 3.0 and 3.1 and LC have the performance and memory that afford rich OSC implementations. +Our primary test platform for new development is the Teensy 3.x series which currently offers the best performance +of any of the Arduinos and variants. We greatly appreciate Paul Stoffregen's ongoing work +with "best practice" engineering of high performance micro-controllers. + +### Unsupported boards + +Arduino Yun and related openwrt/arduino hybrids (e.g. Draguino): + +Marco Brianza is exploring these interesting approaches to running this OSC library on the Atmel 32u4 in the Yun: + https://github.com/cylinderlight/udp2serial + https://github.com/cylinderlight/udp2serialSPI + +The Yun still lacks the Linux-side support to reliably move data between the 32u4 and the router's cpu. We recommend that you add a Teensy to the USB port of an OpenWrt router to get good performance and reliability with our library. + +# Testing + +OSC for Arduino comes with a small suite of tests to validate its functionality and test compatibility when new platforms come out. The tests are broken into a number of individual `.ino` files located in the `test` folder. + +The tests require [ArduinoUnit](https://github.com/mmurdoch/arduinounit) to be installed in the `libraries` folder. The results of the test are printed to the Serial console. + +Tested on: + +* Esplora +* Leonardo +* Teensy 3.x +* Mega 2560 + +# Performance + +Currently best performance is achieved with Arduinos with built-in USB Serial, i.e. Teensy 3.0, Teensy 2.0 and 2.0++ and Leanardo variants (12Mbps max). + +This is because the Wiznet 5100 used in the Ethernet Arduino and shields uses really slow SPI (0.3Mbps). This will change as people retool to use the much faster Wiznet 5200 which has been measured with the Due at 6Mbps. + +References: +* http://forum.pjrc.com/threads/17951-WIZ820io-Ethernet-and-2nd-power-supply-with-teensy-3-0 +* http://arduino.cc/forum/index.php?topic=139147.0 + +The serial examples use a 9600 baud rate which is reliable on most of the FTDI based Arduinos. The slow rate is required for Arduino's without clock chips such as the TinyLili. Once you have established that things work at 9600 baud you will find it very beneficial to increase the rate. e.g. `Serial.begin(345600); // !! 115200, 230400, 345600, 460800 X` + +# Future development ideas + +* WIFI examples +* STM32 support +* Intel Galileo support +* HiFive Support +* Photon Support +* support for special OSC types in CNMAT's "o." especially subbundles +* examples for recent OSC support in node.js and Node Red +* nested bundles +* performance tuning +* Photon spark core examples +* Better Time Tags that avoid the overflow limitation of Arduino timer code +* Time Tag synchronization +* Bluetooth LE +* TCP/IP Examples +* examples for more applications (i.e. TouchOSC, Processing with SLIP) +* deadline scheduling of OSC 64-bit timetags +* ADK support + +We welcome and appreciate your contributions and feedback. + +# New in this release +ESPxx, M0, PIC32 \ No newline at end of file diff --git a/lib/OSC/SLIPEncodedSerial.h b/lib/OSC/SLIPEncodedSerial.h new file mode 100644 index 0000000..a75c549 --- /dev/null +++ b/lib/OSC/SLIPEncodedSerial.h @@ -0,0 +1,292 @@ +/* +Extends the Serial class to encode SLIP over serial +*/ +#include "Arduino.h" + +#ifndef SLIPEncodedSerial_h +#define SLIPEncodedSerial_h + +#include +#ifdef ARDUINO_API_VERSION +#include +#else +#include +#endif + + + +#if (defined(TEENSYDUINO) && (defined(USB_SERIAL) || defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL) || defined(USB_SERIAL_HID) || defined(USB_MIDI_SERIAL) || defined(USB_MIDI_AUDIO_DUAL_SERIAL) || defined(USB_MIDI4_SERIAL) || defined(USB_MIDI16_SERIAL) || defined(USB_MIDI_AUDIO_SERIAL) || defined(USB_MIDI16_AUDIO_SERIAL))) || (!defined(TEENSYDUINO) && defined(__AVR_ATmega32U4__)) || defined(__SAM3X8E__) || (defined(_USB) && defined(_USE_USB_FOR_SERIAL_)) || defined(_SAMD21_) || defined(__PIC32MX__) || defined(__PIC32MZ__) || defined(ARDUINO_USB_CDC_ON_BOOT) || defined(ARDUINO_ARCH_RP2040) +#define BOARD_HAS_USB_SERIAL + + +//import the serial USB object +#if defined(TEENSYDUINO) && defined (__arm__) +#if !defined(USB_HOST_TEENSY36_) +#include +#endif +#elif defined(TEENSYDUINO) && defined (__AVR__) +#include +#elif defined(__SAM3X8E__) || defined(_SAMD21_) +#include +#elif (defined(__PIC32MX__) || defined(__PIC32MZ__) || defined(ARDUINO_USB_CDC_ON_BOOT)) +#include +#elif defined(__AVR_ATmega32U4__) +#include "USBAPI.h" +#include +#elif defined(ARDUINO_ARCH_RP2040) +#include +#else +#error Unknown USB port +#endif + +#endif + +template +class _SLIPSerial: public Stream{ + +private: + // state machine for SLIP escape characters + enum erstate {CHAR, FIRSTEOT, SECONDEOT, SLIPESC } rstate; + + //the serial port used + T * serial; + +public: + _SLIPSerial(T &s) + { + serial = &s; + rstate = CHAR; + } + + static const uint8_t eot = 0300; + static const uint8_t slipesc = 0333; + static const uint8_t slipescend = 0334; + static const uint8_t slipescesc = 0335; + /* + SERIAL METHODS + */ + bool endofPacket() + { + if(rstate == SECONDEOT) + { + rstate = CHAR; + return true; + } + if (rstate==FIRSTEOT) + { + if(serial->available()) + { + uint8_t c =serial->peek(); + if(c==eot) + { + serial->read(); // throw it on the floor + } + } + rstate = CHAR; + return true; + } + return false; + } + int available(){ + back: + uint8_t cnt = serial->available(); + + if(cnt==0) + return 0; + if(rstate==CHAR) + { + uint8_t c =serial->peek(); + if(c==slipesc) + { + rstate = SLIPESC; + serial->read(); // throw it on the floor + goto back; + } + else if( c==eot) + { + rstate = FIRSTEOT; + serial->read(); // throw it on the floor + goto back; + } + return 1; // we may have more but this is the only sure bet + } + else if(rstate==SLIPESC) + return 1; + else if(rstate==FIRSTEOT) + { + if(serial->peek()==eot) + { + rstate = SECONDEOT; + serial->read(); // throw it on the floor + return 0; + } + rstate = CHAR; + }else if (rstate==SECONDEOT) { + rstate = CHAR; + } + + return 0; + + } + + //reads a byte from the buffer + int read(){ + back: + uint8_t c = serial->read(); + if(rstate==CHAR) + { + if(c==slipesc) + { + rstate=SLIPESC; + goto back; + } + else if(c==eot){ + + return -1; // xxx this is an error + } + return c; + } + else + if(rstate==SLIPESC) + { + rstate=CHAR; + if(c==slipescend) + return eot; + else if(c==slipescesc) + return slipesc; + else { + // insert some error code here + return -1; + } + + } + else + return -1; + } + size_t readBytes( uint8_t *buffer, size_t size) + { + size_t count = 0; + while(!endofPacket() && available() && (size>0)) + { + int c = read(); + if(c>=0) + { + *buffer++ = c; + ++count; + --size; + + } + else + break; + } + return count; + } + // as close as we can get to correct behavior + int peek(){ + uint8_t c = serial->peek(); + if(rstate==SLIPESC) + { + if(c==slipescend) + return eot; + else if(c==slipescesc) + return slipesc; + } + return c; + } + + //encode SLIP + size_t write(uint8_t b){ + if(b == eot){ + serial->write(slipesc); + return serial->write(slipescend); + } else if(b==slipesc) { + serial->write(slipesc); + return serial->write(slipescesc); + } else { + return serial->write(b); + } + } + size_t write(const uint8_t *buffer, size_t size) + { + size_t result=0; + while(size--) + { + result = write(*buffer++); + } + return result; + } + + + void begin(unsigned long baudrate){ + serial->begin(baudrate); + } + // for bluetooth + void begin(char *name){ + serial->begin(name); + } + //SLIP specific method which begins a transmitted packet + void beginPacket() { serial->write(eot); } + + //signify the end of the packet with an EOT + void endPacket(){ + serial->write(eot); + } + + void flush(){ + serial->flush(); + } + +}; + +using SLIPEncodedSerial = _SLIPSerial ; +// template <> void _SLIPSerial::endPacket(){ +// serial->write(eot); + +// } + +#ifdef BOARD_HAS_USB_SERIAL + +#if defined(_SAMD21_) +// Required for Serial on Zero based boards +#if defined(ARDUINO_SAMD_ZERO) +// Adafruit breaks with tradition here +#define thisBoardsSerialUSB Serial +typedef decltype(Serial) actualUSBtype; +#else +#define thisBoardsSerialUSB SerialUSB +typedef decltype(SerialUSB) actualUSBtype; +#endif +#elif defined(__SAM3X8E__) +// Required for Serial on Zero based boards +#define thisBoardsSerialUSB SerialUSB +typedef decltype(SerialUSB) actualUSBtype; + +// defined(__SAM3X8E__) +#elif defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_USB_CDC_ON_BOOT) || defined(CORE_TEENSY) || defined(__AVR_ATmega32U4__) || (defined(__PIC32MX__) || defined(__PIC32MZ__)) +#define thisBoardsSerialUSB Serial +typedef decltype(Serial) actualUSBtype; +#endif +using SLIPEncodedUSBSerial = _SLIPSerial; +#if defined(CORE_TEENSY) +template <> void _SLIPSerial::endPacket(){ + serial->write(eot); + serial->send_now(); +} +#endif + +#endif + +// Bluetooth Example + +// #if BOARD_HAS_BLUETOOTH_SERIAL +// #include "BluetoothSerial.h" +// BluetoothSerial bluetoothserialinstance; +// SLIPEncodedBluetoothSerial SLIPSerial(bluetoothserialinstance); + +#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32S2) +#include "BluetoothSerial.h" +using SLIPEncodedBluetoothSerial = _SLIPSerial; +#define BOARD_HAS_BLUETOOTH_SERIAL + +#endif +#endif \ No newline at end of file diff --git a/lib/OSC/examples/ESP8266ReceiveBundle/ESP8266ReceiveBundle.ino b/lib/OSC/examples/ESP8266ReceiveBundle/ESP8266ReceiveBundle.ino new file mode 100644 index 0000000..7558258 --- /dev/null +++ b/lib/OSC/examples/ESP8266ReceiveBundle/ESP8266ReceiveBundle.ino @@ -0,0 +1,103 @@ +/*--------------------------------------------------------------------------------------------- + + Open Sound Control (OSC) library for the ESP8266/ESP32 + + Example for receiving open sound control (OSC) bundles on the ESP8266/ESP32 + Send integers '0' or '1' to the address "/led" to turn on/off the built-in LED of the esp8266. + + This example code is in the public domain. + +--------------------------------------------------------------------------------------------- */ +#ifdef ESP8266 +#include +#else +#include +#endif +#include +#include +#include +#include + +char ssid[] = "*****************"; // your network SSID (name) +char pass[] = "*******"; // your network password + +// A UDP instance to let us send and receive packets over UDP +WiFiUDP Udp; +const IPAddress outIp(10,40,10,105); // remote IP (not needed for receive) +const unsigned int outPort = 9999; // remote port (not needed for receive) +const unsigned int localPort = 8888; // local port to listen for UDP packets (here's where we send the packets) + + +OSCErrorCode error; +unsigned int ledState = LOW; // LOW means led is *on* + +#ifndef BUILTIN_LED +#ifdef LED_BUILTIN +#define BUILTIN_LED LED_BUILTIN +#else +#define BUILTIN_LED 13 +#endif +#endif + +void setup() { + pinMode(BUILTIN_LED, OUTPUT); + digitalWrite(BUILTIN_LED, ledState); // turn *on* led + + Serial.begin(115200); + + // Connect to WiFi network + Serial.println(); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + WiFi.begin(ssid, pass); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.println("Starting UDP"); + Udp.begin(localPort); + Serial.print("Local port: "); +#ifdef ESP32 + Serial.println(localPort); +#else + Serial.println(Udp.localPort()); +#endif + +} + + +void led(OSCMessage &msg) { + ledState = msg.getInt(0); + digitalWrite(BUILTIN_LED, ledState); + Serial.print("/led: "); + Serial.println(ledState); +} + +void loop() { + OSCBundle bundle; + int size = Udp.parsePacket(); + + if (size > 0) { + while (size--) { + bundle.fill(Udp.read()); + } + if (!bundle.hasError()) { + bundle.dispatch("/led", led); + } else { + error = bundle.getError(); + Serial.print("error: "); + Serial.println(error); + } + } +} + + + diff --git a/lib/OSC/examples/ESP8266ReceiveMessage/ESP8266ReceiveMessage.ino b/lib/OSC/examples/ESP8266ReceiveMessage/ESP8266ReceiveMessage.ino new file mode 100644 index 0000000..69faa10 --- /dev/null +++ b/lib/OSC/examples/ESP8266ReceiveMessage/ESP8266ReceiveMessage.ino @@ -0,0 +1,100 @@ +/*--------------------------------------------------------------------------------------------- + + Open Sound Control (OSC) library for the ESP8266/ESP32 + + Example for receiving open sound control (OSC) messages on the ESP8266/ESP32 + Send integers '0' or '1' to the address "/led" to turn on/off the built-in LED of the esp8266. + + This example code is in the public domain. + +--------------------------------------------------------------------------------------------- */ +#ifdef ESP8266 +#include +#else +#include +#endif +#include +#include +#include +#include + +char ssid[] = "*****************"; // your network SSID (name) +char pass[] = "*******"; // your network password + +// A UDP instance to let us send and receive packets over UDP +WiFiUDP Udp; +const IPAddress outIp(10,40,10,105); // remote IP (not needed for receive) +const unsigned int outPort = 9999; // remote port (not needed for receive) +const unsigned int localPort = 8888; // local port to listen for UDP packets (here's where we send the packets) + + +OSCErrorCode error; +unsigned int ledState = LOW; // LOW means led is *on* + +#ifndef BUILTIN_LED +#ifdef LED_BUILTIN +#define BUILTIN_LED LED_BUILTIN +#else +#define BUILTIN_LED 13 +#endif +#endif + +void setup() { + pinMode(BUILTIN_LED, OUTPUT); + digitalWrite(BUILTIN_LED, ledState); // turn *on* led + + Serial.begin(115200); + + // Connect to WiFi network + Serial.println(); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + WiFi.begin(ssid, pass); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.println("Starting UDP"); + Udp.begin(localPort); + Serial.print("Local port: "); +#ifdef ESP32 + Serial.println(localPort); +#else + Serial.println(Udp.localPort()); +#endif + +} + + +void led(OSCMessage &msg) { + ledState = msg.getInt(0); + digitalWrite(BUILTIN_LED, ledState); + Serial.print("/led: "); + Serial.println(ledState); +} + +void loop() { + OSCMessage msg; + int size = Udp.parsePacket(); + + if (size > 0) { + while (size--) { + msg.fill(Udp.read()); + } + if (!msg.hasError()) { + msg.dispatch("/led", led); + } else { + error = msg.getError(); + Serial.print("error: "); + Serial.println(error); + } + } +} diff --git a/lib/OSC/examples/ESP8266sendMessage/ESP8266sendMessage.ino b/lib/OSC/examples/ESP8266sendMessage/ESP8266sendMessage.ino new file mode 100644 index 0000000..3aa61ff --- /dev/null +++ b/lib/OSC/examples/ESP8266sendMessage/ESP8266sendMessage.ino @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------------------------- + + Open Sound Control (OSC) library for the ESP8266/ESP32 + + Example for sending messages from the ESP8266/ESP32 to a remote computer + The example is sending "hello, osc." to the address "/test". + + This example code is in the public domain. + +--------------------------------------------------------------------------------------------- */ +#if defined(ESP8266) +#include +#else +#include +#endif +#include +#include + +char ssid[] = "*****************"; // your network SSID (name) +char pass[] = "*******"; // your network password + +WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP +const IPAddress outIp(10,40,10,105); // remote IP of your computer +const unsigned int outPort = 9999; // remote port to receive OSC +const unsigned int localPort = 8888; // local port to listen for OSC packets (actually not used for sending) + +void setup() { + Serial.begin(115200); + + // Connect to WiFi network + Serial.println(); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + WiFi.begin(ssid, pass); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.println("Starting UDP"); + Udp.begin(localPort); + Serial.print("Local port: "); +#ifdef ESP32 + Serial.println(localPort); +#else + Serial.println(Udp.localPort()); +#endif + +} + +void loop() { + OSCMessage msg("/test"); + msg.add("hello, osc."); + Udp.beginPacket(outIp, outPort); + msg.send(Udp); + Udp.endPacket(); + msg.empty(); + delay(500); +} diff --git a/lib/OSC/examples/OSCEsplora/OSCEsplora.ino b/lib/OSC/examples/OSCEsplora/OSCEsplora.ino new file mode 100644 index 0000000..3325d97 --- /dev/null +++ b/lib/OSC/examples/OSCEsplora/OSCEsplora.ino @@ -0,0 +1,287 @@ + +/* + Bidirectional Esplora OSC communications using SLIP + + Adrian Freed, Jeff Lubow 2013 + + Includes some examples of common "best practices" for OSC name space and parameter + mapping design. + + +*/ + +#include +#include +//Teensy and Leonardo variants have special USB serial +#include + +#if !defined(__AVR_ATmega32U4__) +#error select Arduino Esplora in board menu +#endif + +// temperature +float getTemperature(){ + int result; + + ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0); + ADCSRB = _BV(MUX5); + delayMicroseconds(200); // wait for Vref to settle + ADCSRA |= _BV(ADSC); // Convert + while (bit_is_set(ADCSRA,ADSC)); + result = ADCL; + result |= ADCH<<8; + + analogReference(DEFAULT); + return result/1023.0f; +} + +float getSupplyVoltage(){ + // powersupply + int result; + // Read 1.1V reference against AVcc + ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); + delayMicroseconds(300); // wait for Vref to settle + ADCSRA |= _BV(ADSC); // Convert + while (bit_is_set(ADCSRA,ADSC)); + result = ADCL; + result |= ADCH<<8; + + float supplyvoltage = 1.1264f *1023 / result; + return supplyvoltage; +} + +// Esplora has a dinky green led at the top left and a big RGB led at the bottom right +void routeLed(OSCMessage &msg, int addrOffset ){ + if(msg.match("/red", addrOffset)) { + if (msg.isInt(0)) Esplora.writeRed( (byte)msg.getInt(0)); + } + else + if(msg.match("/green", addrOffset)) { + if (msg.isInt(0)) Esplora.writeGreen( (byte)msg.getInt(0)); + } + else + if(msg.match("/blue", addrOffset)) { + if (msg.isInt(0)) Esplora.writeBlue( (byte)msg.getInt(0)); + } + else + if(msg.match("/rgb", addrOffset)) { + + if (msg.isInt(0)&&msg.isInt(1)&&msg.isInt(2)) + { + Esplora.writeRGB((byte)msg.getInt(0),(byte)msg.getInt(1),(byte)msg.getInt(2)); + } + } + else + { + if (msg.isInt(0)) + { + digitalWrite(13, msg.getInt(0)>0?HIGH:LOW); + } + } +} + +// Esplora has a dinky green led at the top left and a big RGB led at the bottom right +void routeOut(OSCMessage &msg, int addrOffset ){ + if(msg.match("/B", addrOffset) || msg.match("/b", addrOffset)) { + if (msg.isInt(0)) { + pinMode(11,OUTPUT); + digitalWrite(11, msg.getInt(0)>0?HIGH:LOW); + } + else + pinMode(11,INPUT); // add pull up logic some day + } + else + if(msg.match("/A", addrOffset) ||msg.match("/a", addrOffset)) { + if (msg.isInt(0)) { + pinMode(3,OUTPUT); + digitalWrite(3, msg.getInt(0)>0?HIGH:LOW); + } + else + pinMode(3,INPUT); // add pull up logic some day + } +} + +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone + * (no value) = notome + * float or int = frequency + * optional length of time as an integer in milliseconds afterwards + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + + unsigned int frequency = 0; + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); // this doesn't work due to problems with double to float conversion? + } + else + Esplora.noTone(); + if(frequency>0) + { + if(msg.isInt(1)) + Esplora.tone(frequency, msg.getInt(1)); + else + Esplora.tone( frequency); + } +} +const char *released = "released"; +const char *pressed = "pressed"; + +const byte MUX_ADDR_PINS[] = { + A0, A1, A2, A3 }; +const byte MUX_COM_PIN = A4; + +unsigned int myReadChannel(byte channel) { + digitalWrite(MUX_ADDR_PINS[0], (channel & 1) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[1], (channel & 2) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[2], (channel & 4) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[3], (channel & 8) ? HIGH : LOW); + + return analogRead(MUX_COM_PIN); +} + + +SLIPEncodedUSBSerial SLIPSerial(Serial); +void setup() { + SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform +} + +int32_t counter = 0; +int32_t serialnumber = 2; //hard coded; beware +int32_t num_components = 3; //currently break the bundle up into 3 components + +void loop(){ + OSCBundle bndl; + int32_t manifest_count = 1; + + if(!SLIPSerial.available()) + { + + // The RAW OSC address space and parameter mappngs try to capture + // the data at lowest level without calibration or scaling + // The names are chosen to match what is on the silkscreen of the board where it is found + #define RAW + #ifdef RAW + SLIPSerial.beginPacket(); + bndl.add("/mic").add((int32_t)Esplora.readMicrophone()); + bndl.add("/temp/sensor/celsius").add((int32_t)Esplora.readTemperature(DEGREES_C)); + bndl.add("/temp/sensor/fahrenheit").add((int32_t)Esplora.readTemperature(DEGREES_F)); + bndl.add("/linear/potentiometer").add((int32_t)Esplora.readSlider()); + bndl.add("/light/sensor").add((int32_t)Esplora.readLightSensor()); + bndl.add("/switch/1").add((int32_t)Esplora.readButton(SWITCH_1)); + bndl.add("/switch/2").add((int32_t)Esplora.readButton(SWITCH_2)); + bndl.add("/switch/3").add((int32_t)Esplora.readButton(SWITCH_3)); + bndl.add("/switch/4").add((int32_t)Esplora.readButton(SWITCH_4)); + bndl.add("/joystick/X").add((int32_t)Esplora.readJoystickX()); + bndl.add("/joystick/Y").add((int32_t)Esplora.readJoystickY()); + bndl.add("/joystick/switch").add((int32_t)Esplora.readJoystickSwitch()); + bndl.add("/joystick/switch/1").add((int32_t)Esplora.readButton(JOYSTICK_DOWN)); + bndl.add("/joystick/switch/2").add((int32_t)Esplora.readButton(JOYSTICK_LEFT)); + bndl.add("/joystick/switch/3").add((int32_t)Esplora.readButton(JOYSTICK_UP)); + bndl.add("/joystick/switch/4").add((int32_t)Esplora.readButton(JOYSTICK_RIGHT)); + bndl.add("/accelerometer/x").add(Esplora.readAccelerometer(X_AXIS)); + bndl.add("/accelerometer/y").add(Esplora.readAccelerometer(Y_AXIS)); + bndl.add("/accelerometer/z").add(Esplora.readAccelerometer(Z_AXIS)); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); + #endif //RAW + + + // The COOKED OSC address space and parameter mappings + // encode data for ease of use and legibility at the host. Unit intervals replace integers + // The names are chosen to clarify usage rather than adherence to the silkscreen + // also values are acquired as close together as reasonably possible to increase + // their usability in sensor fusion contexts, i.e. in this case with the accelerometer + + + SLIPSerial.beginPacket(); // mark the beginning of the OSC Packet + + //bundle 1 + bndl.add("/acceleration/x").add(Esplora.readAccelerometer(X_AXIS)/512.0f); + bndl.add("/acceleration/y").add(Esplora.readAccelerometer(Y_AXIS)/512.0f); + bndl.add("/acceleration/z").add(Esplora.readAccelerometer(Z_AXIS)/512.0f); + bndl.add("/photoresistor").add(Esplora.readLightSensor()/1023.0f); + bndl.add("/joystick/horizontal").add(-1.0 * (int32_t)Esplora.readJoystickX()/512.0f); + bndl.add("/joystick/vertical").add(-1.0 * (int32_t)Esplora.readJoystickY()/512.0f); + bndl.add("/joystick/button").add(Esplora.readJoystickSwitch()>0? released:pressed); + bndl.add("/joystick/backward").add((int32_t)Esplora.readButton(JOYSTICK_DOWN)?released:pressed); + bndl.add("/joystick/left").add((int32_t)Esplora.readButton(JOYSTICK_LEFT)?released:pressed); + bndl.add("/joystick/forward").add((int32_t)Esplora.readButton(JOYSTICK_UP)?released:pressed); + bndl.add("/joystick/right").add((int32_t)Esplora.readButton(JOYSTICK_RIGHT)?released:pressed); + bndl.add("/serialnumber").add(serialnumber); + //bndl.add("/manifest").add(manifest_count++).add(num_components).add(counter); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); //bundle ending early due to current memory limitations + + //bundle 2 + bndl.add("/diamond/backward").add((int32_t)Esplora.readButton(SWITCH_1)?released:pressed); + bndl.add("/diamond/left").add((int32_t)Esplora.readButton(SWITCH_2)?released:pressed); + bndl.add("/diamond/forward").add((int32_t)Esplora.readButton(SWITCH_3)?released:pressed); + bndl.add("/diamond/right").add((int32_t)Esplora.readButton(SWITCH_4)?released:pressed); + bndl.add("/microphone/loudness").add(Esplora.readMicrophone()/1023.0f); + bndl.add("/temperature/fahrenheit").add((float)Esplora.readTemperature(DEGREES_F)); + bndl.add("/temperature/celsius").add((float)Esplora.readTemperature(DEGREES_C)); + bndl.add("/slider/horizontal").add(1.0f - ((float)Esplora.readSlider()/1023.0f)); + bndl.add("/serialnumber").add(serialnumber); + //bndl.add("/manifest").add(manifest_count++).add(num_components).add(counter); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); //bundle ending early due to current memory limitations + + //bundle 3 + bndl.add("/connector/white/left").add(myReadChannel(CH_MIC +1)/1023.0); + bndl.add("/connector/white/right").add(myReadChannel(CH_MIC +2)/1023.0); + bndl.add("/led/red").add((int32_t)Esplora.readRed()); + bndl.add("/led/green").add((int32_t)Esplora.readGreen()); + bndl.add("/led/blue").add((int32_t)Esplora.readBlue()); + bndl.add("/led/rgb").add((int32_t)Esplora.readRed()).add((int32_t)Esplora.readGreen()).add((int32_t)Esplora.readBlue()); + bndl.add("/connector/orange/right").add((digitalRead(3)==HIGH)?1:0); + bndl.add("/connector/orange/left").add((digitalRead(11)==HIGH)?1:0); + bndl.add("/vendor").add("Arduino"); + bndl.add("/productname").add("Esplora"); + bndl.add("/serialnumber").add(serialnumber); + //bndl.add("/manifest").add(manifest_count++).add(num_components).add(counter); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); + + counter += 1; + // bndl.add("/32u4/supplyVoltage").add(getSupplyVoltage()); + // bndl.add("/32u4/temperature").add(getTemperature()); + + } + else + { + OSCBundle bundleIN; + int size; + + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + { + if(!bundleIN.hasError()) + { + bundleIN.route("/led", routeLed); + bundleIN.route("/L", routeLed); // this is how it is marked on the silkscreen + bundleIN.route("/out", routeOut); // for the TinkerIt output connectors + bundleIN.route("/tone", routeTone); + bundleIN.route("/squarewave", routeTone); + bundleIN.route("/notone", routeTone); + } + } + } +} diff --git a/lib/OSC/examples/PatternMatching/PatternMatching.ino b/lib/OSC/examples/PatternMatching/PatternMatching.ino new file mode 100644 index 0000000..e68ec8c --- /dev/null +++ b/lib/OSC/examples/PatternMatching/PatternMatching.ino @@ -0,0 +1,91 @@ +/* + The library has four methods for doing pattern matching on address. + 'match' and 'fullMatch' are specific to OSCMessages while route and dispatch work on both messages and bundles. + + OSCMessage: + match - matches the message's address pattern against an address. returns the number of characters matched from the address passed in. + fullMatch - returns true if the pattern was a complete match against the address + + OSCMessage && OSCBundle: + route - calls a function with the matched OSCMessage(s) and the number of matched characters in the address as the parameters + dispatch - calls a function with each OSCMessage which was fully matched by the pattern + +/////////////////////////////////////////////////////////////////////////////////////////////////// +OSC Regular expression pattern matching rules from http://opensoundcontrol.org/spec-1_0 + + 1. '?' in the OSC Address Pattern matches any single character + 2. '*' in the OSC Address Pattern matches any sequence of zero or more characters + 3. A string of characters in square brackets (e.g., "[string]") in the OSC Address Pattern matches any character in the string. + Inside square brackets, the minus sign (-) and exclamation point (!) have special meanings: + two characters separated by a minus sign indicates the range of characters between the given two in ASCII collating sequence. + An exclamation point at the beginning of a bracketed string negates the sense of the list, meaning that the list matches any character not in the list. + 4. A comma-separated list of strings enclosed in curly braces (e.g., "{foo,bar}") in the OSC Address Pattern matches any of the strings in the list. + 5. Any other character in an OSC Address Pattern can match only the same character. + /////////////////////////////////////////////////////////////////////////////////////////////////// + */ + +#include + +void setup() { + Serial.begin(38400); +} + +void loop(){ + //a heavily patterned message address + OSCMessage msg0("/{input,output}/[0-2]/[!ab]/*"); + //match will traverse as far as it can in the pattern + //it returns the number of characters matched from the pattern + int patternOffset = msg0.match("/input/1"); + if (patternOffset>0){ + //string multiple 'match' methods together using the pattern offset parameter to continue matching where it left off + //use 'fullMatch' to test if the entire pattern was matched. + if(msg0.fullMatch("/c/anything", patternOffset)){ + Serial.println("Match: '/input/1/c/anything' against the pattern '/{input,output}/[0-2]/[abc]/*'"); + } + } + //write over the other message address + OSCMessage msg1("/partialMatch"); + //match will return 0 if it did not reach the end or a '/' + if(!msg1.match("/partial")){ + Serial.println("No Match: '/partial' against the pattern '/partialMatch'"); + } + OSCMessage msg2("/output/[0-2]"); + //'route' is uses 'match' to allow for partial matches + //it invokes the callback with the matched message and the pattern offset as parameters to the callback + msg2.route("/output", routeOutput); + //'dispatch' uses 'fullMatch' so it does not allow for partial matches + //invokes the callback with only one argument which is the matched message + msg2.dispatch("/output/1", routeOutputOne); + delay(1000); +} + +//called after matching '/output' +//the matched message and the number of matched characters as the parameters +void routeOutput(OSCMessage &msg, int patternOffset){ + Serial.println("Match: '/output'"); + //string multiple 'route' methods together using the pattern offset parameter. + msg.route("/0", routeZero, patternOffset); +} + +//called after matching '/0' +void routeZero(OSCMessage &msg, int addressOffset){ + Serial.println("Match: '/output/0'"); +} + +//called after matching '/output/1' +void routeOutputOne(OSCMessage &msg){ + Serial.println("Match: '/output/1'"); +} + + +// +// TROUBLESHOOTING: +// Because of a bug in the Arduino IDE, it sometimes thinks that the '*' in combination with '/' is the opening or closing of a multiline comment +// This can be fixed by escaping the '/' with '\' or using the octal value of '*' which is '\052' +// for example: +// "/*" == "/\052" == "\/*" +// + + + + diff --git a/lib/OSC/examples/SerialCallResponse/SerialCallResponse.ino b/lib/OSC/examples/SerialCallResponse/SerialCallResponse.ino new file mode 100644 index 0000000..2569835 --- /dev/null +++ b/lib/OSC/examples/SerialCallResponse/SerialCallResponse.ino @@ -0,0 +1,108 @@ +/* + Serial Call Response + Send responses to calls for information from a remote host +*/ + +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + +OSCBundle bundleOUT; + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /analog/(pin) + * /u = analogRead with pullup + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + int pinMatched; + pinMatched = msg.match("/0", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(0), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/0").add((int32_t)analogRead(0)); + } + pinMatched = msg.match("/1", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(1), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/1").add((int32_t)analogRead(1)); + } + pinMatched = msg.match("/2", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(2), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/2").add((int32_t)analogRead(2)); + } + pinMatched = msg.match("/3", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(3), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/3").add((int32_t)analogRead(3)); + } + pinMatched = msg.match("/4", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(4), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/4").add((int32_t)analogRead(4)); + } + pinMatched = msg.match("/5", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(5), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/5").add((int32_t)analogRead(5)); + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ +void setup() { + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + + int size; + + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + if(!bundleIN.hasError()) + { + bundleIN.route("/analog", routeAnalog); + //send the outgoing response message + SLIPSerial.beginPacket(); + bundleOUT.send(SLIPSerial); + SLIPSerial.endPacket(); + bundleOUT.empty(); // empty the bundle ready to use for new messages + } +} + + + + + + + + diff --git a/lib/OSC/examples/SerialEcho/SerialEcho.ino b/lib/OSC/examples/SerialEcho/SerialEcho.ino new file mode 100644 index 0000000..079a28a --- /dev/null +++ b/lib/OSC/examples/SerialEcho/SerialEcho.ino @@ -0,0 +1,48 @@ +/* + +Serial USB ports are bidirectional. + +This example can be extended to build routers and forwarders of OSC packets +*/ + +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + +void setup() { + //begin SLIPSerial just like Serial + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} + +void loop(){ + OSCBundle bndl; + int size; + //receive a bundle + + while(!SLIPSerial.endofPacket()) + if( (size =SLIPSerial.available()) > 0) + { + while(size--) + bndl.fill(SLIPSerial.read()); + } + + if(!bndl.hasError()) + { + static int32_t sequencenumber=0; + // we can sneak an addition onto the end of the bundle + bndl.add("/micros").add((int32_t)micros()); // (int32_t) is the type of OSC Integers + bndl.add("/sequencenumber").add(sequencenumber++); + bndl.add("/digital/5").add(digitalRead(5)==HIGH); + bndl.add("/lsb").add((sequencenumber &1)==1); + SLIPSerial.beginPacket(); // mark the beginning of the OSC Packet + bndl.send(SLIPSerial); + SLIPSerial.endPacket(); + } +} + diff --git a/lib/OSC/examples/SerialOscuinoAdaFruitPlayGroundExpresswithBundles/SerialOscuinoAdaFruitPlayGroundExpresswithBundles.ino b/lib/OSC/examples/SerialOscuinoAdaFruitPlayGroundExpresswithBundles/SerialOscuinoAdaFruitPlayGroundExpresswithBundles.ino new file mode 100644 index 0000000..2b1a8af --- /dev/null +++ b/lib/OSC/examples/SerialOscuinoAdaFruitPlayGroundExpresswithBundles/SerialOscuinoAdaFruitPlayGroundExpresswithBundles.ino @@ -0,0 +1,332 @@ + +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + +//outgoing messages + +OSCBundle bundleOUT; + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} + +/** + * ROUTES + * + * these are where the routing functions go + * + */ + +/** + * DIGITAL + * + * called when address matched "/d" + * expected format: + * /d/(pin) + * /u = digitalRead with pullup + * (no value) = digitalRead without pullup + * (value) = digital write on that pin + * + */ + +void routeDigital(OSCMessage &msg, int addrOffset ){ + //match input or output + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(pin, OUTPUT); + digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); + } + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } + + //otherwise it's an digital read + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + pinMode(pin, INPUT_PULLUP); + //setup the output address which should be /d/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } //else without a pullup + else { + //set the pinmode + pinMode(pin, INPUT); + //setup the output address which should be /d/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } + } + } +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /a/(pin) + * /u = analogRead with pullup + * (no value) = analogRead without pullup + * (digital value) = digital write on that pin + * (float value) = analogWrite on that pin + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(analogInputToDigitalPin(pin), OUTPUT); + digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); + } + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } +#ifdef BOARD_HAS_ANALOG_PULLUP + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + + pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); + + //setup the output address which should be /a/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } //else without a pullup +#endif + + else { + //otherwise it's an analog read + //set the pinmode + + pinMode(analogInputToDigitalPin(pin), INPUT); + //setup the output address which should be /a/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } + } + } +} + +#ifdef BOARD_HAS_TONE +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} +#endif + + +#ifdef BOARD_HAS_CAPACITANCE_SENSING +#if defined(__MKL26Z64__) +// teensy 3.0LC +#define NTPINS 11 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,3,4 }; +#elif defined(__MK66FX1M0__) +// teensy 3.6 +#define NTPINS 12 +const int cpins[NTPINS] = {0,1,14,15,16,17,18,19,22,23,29,30 }; +#else +//Teensy 3.1 3.2 +#define NTPINS 12 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,25,32, 33 }; +#endif + +void routeTouch(OSCMessage &msg, int addrOffset ) +{ + for(int i=0;i 0)? HIGH: LOW); + bundleOUT.add("/s/l").add(i); + } + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ + + +void setup() { + SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform +#if ARDUINO >= 100 + while(!Serial) + ; // Leonardo bug +#endif + +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + { + bundleIN.route("/s", routeSystem); + bundleIN.route("/a", routeAnalog); + bundleIN.route("/d", routeDigital); +#ifdef BOARD_HAS_TONE + bundleIN.route("/tone", routeTone); +#endif +#ifdef BOARD_HAS_CAPACITANCE_SENSING + bundleIN.route("/c", routeTouch); +#endif + } + bundleIN.empty(); + + +//send the outgoing message + SLIPSerial.beginPacket(); + bundleOUT.send(SLIPSerial); + SLIPSerial.endPacket(); + bundleOUT.empty(); + +} + + + + + + + diff --git a/lib/OSC/examples/SerialOscuinoForFubarino/SerialOscuinoForFubarino.ino b/lib/OSC/examples/SerialOscuinoForFubarino/SerialOscuinoForFubarino.ino new file mode 100644 index 0000000..0900c49 --- /dev/null +++ b/lib/OSC/examples/SerialOscuinoForFubarino/SerialOscuinoForFubarino.ino @@ -0,0 +1,292 @@ +#include +#include + +// Fubarino MINI + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif +OSCBundle bundleOUT; + +//converts the pin to an osc address + char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + s[i--]= '\0'; + do +{ + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; +} + while(pin && i); +s[i] = '/'; +return &s[i]; +} + +/** + * ROUTES + * + * these are where the routing functions go + * + */ +/** + * DIGITAL + * + * called when address matched "/d" + * expected format: + * /d/(pin) + * /u = digitalRead with pullup + * (no value) = digitalRead without pullup + * (value) = digital write on that pin + * + */ + +void routeDigital(OSCMessage &msg, int addrOffset ){ + //match input or output + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + switch(pin) + { + // fubarino MINI + // these are used for clocks and USB and Program switch and shouldn't be written to + // unless you know what you are doing + case 3: case 14: case 15: case 23: case 16: case 31:case 32: goto out; + } + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(pin, OUTPUT); + digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); + } //otherwise it's an digital read + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + pinMode(pin, INPUT_PULLUP); + //setup the output address which should be /d/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the digital read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add(digitalRead(pin)); + SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } //else without a pullup + else { + //set the pinmode + pinMode(pin, INPUT); + //setup the output address which should be /d/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the digital read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add(digitalRead(pin)); + SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } + } + out: ; + } +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /a/(pin) + * /u = analogRead with pullup + * (no value) = analogRead without pullup + * (digital value) = digital write on that pin + * (float value) = analogWrite on that pin + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(analogInputToDigitalPin(pin), OUTPUT); + digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); + } //otherwise it's an analog read + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } +#ifdef BOARD_HAS_ANALOG_PULLUP + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + + pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); + + //setup the output address which should be /a/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the analog read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add((int32_t)analogRead(pin)); + SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } //else without a pullup +#endif + else { + //set the pinmode + // This fails on Arduino 1.04 on Leanardo, I added this to fix it: #define analogInputToDigitalPin(p) (p+18) + + pinMode(analogInputToDigitalPin(pin), INPUT); + //setup the output address which should be /a/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the analog read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add((int32_t)analogRead(pin)); + SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } + } + } +} + +#ifdef BOARD_HAS_TONE + +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} +#endif + + + +/** + * SYSTEM MESSAGES + * + * expected format: + * /s + * /m = microseconds + * /d = number of digital pins + * /a = number of analog pins + * /l integer = set the led + * /t = temperature + * /s = power supply voltage + */ +// +void routeSystem(OSCMessage &msg, int addrOffset ){ + + #ifdef BOARD_HAS_DIE_TEMPERATURE_SENSOR + if (msg.fullMatch("/t", addrOffset)){ + { OSCMessage msgOut("/s/t"); msgOut.add(getTemperature()); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + #endif + #ifdef BOARD_HAS_DIE_POWER_SUPPLY_MEASUREMENT + if (msg.fullMatch("/s", addrOffset)){ + { OSCMessage msgOut("/s/s"); msgOut.add(getSupplyVoltage()); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + #endif + if (msg.fullMatch("/m", addrOffset)){ + { OSCMessage msgOut("/s/m"); msgOut.add((int32_t)micros()); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + if (msg.fullMatch("/d", addrOffset)){ + { OSCMessage msgOut("/s/d"); msgOut.add(NUM_DIGITAL_PINS); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + if (msg.fullMatch("/a", addrOffset)){ + { OSCMessage msgOut("/s/a"); msgOut.add(NUM_ANALOG_INPUTS); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + if (msg.fullMatch("/l", addrOffset)){ + + if (msg.isInt(0)){ + pinMode(LED_BUILTIN, OUTPUT); + int i = msg.getInt(0); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, (i > 0)? HIGH: LOW); + { OSCMessage msgOut("/s/l"); msgOut.add(i); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ + +void setup() { + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + { + bundleIN.route("/s", routeSystem); + bundleIN.route("/a", routeAnalog); + bundleIN.route("/d", routeDigital); +#ifdef BOARD_HAS_TONE + bundleIN.route("/tone", routeTone); +#endif +#ifdef BOARD_HAS_CAPACITANCE_SENSING + bundleIN.route("/c", routeTouch); +#endif + } + +} + diff --git a/lib/OSC/examples/SerialOscuinoGemmaM0/SerialOscuinoGemmaM0.ino b/lib/OSC/examples/SerialOscuinoGemmaM0/SerialOscuinoGemmaM0.ino new file mode 100644 index 0000000..68d9dbe --- /dev/null +++ b/lib/OSC/examples/SerialOscuinoGemmaM0/SerialOscuinoGemmaM0.ino @@ -0,0 +1,311 @@ + +#include +#include +#include "Adafruit_FreeTouch.h" +#include + +Adafruit_FreeTouch qt_0 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE); +Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A1, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE); +Adafruit_FreeTouch qt_2 = Adafruit_FreeTouch(A2, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE); + Adafruit_FreeTouch *p[3] = { &qt_0, &qt_1, &qt_2 }; + +#undef NUM_DIGITAL_PINS +#define NUM_DIGITAL_PINS 3 +#undef NUM_ANALOG_PINS +#define NUM_ANALOG_PINS 3 + +SLIPEncodedUSBSerial SLIPSerial( Serial ); + + + +//outgoing messages + +OSCBundle bundleOUT; + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} + +/** + * ROUTES + * + * these are where the routing functions go + * + */ + +/** + * DIGITAL + * + * called when address matched "/d" + * expected format: + * /d/(pin) + * /u = digitalRead with pullup + * (no value) = digitalRead without pullup + * (value) = digital write on that pin + * + */ + +void routeDigital(OSCMessage &msg, int addrOffset ){ + //match input or output + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(pin, OUTPUT); + digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); + } + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } + + //otherwise it's an digital read + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + pinMode(pin, INPUT_PULLUP); + //setup the output address which should be /d/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } //else without a pullup + else { + //set the pinmode + pinMode(pin, INPUT); + //setup the output address which should be /d/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } + } + } +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /a/(pin) + * /u = analogRead with pullup + * (no value) = analogRead without pullup + * (digital value) = digital write on that pin + * (float value) = analogWrite on that pin + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(analogInputToDigitalPin(pin), OUTPUT); + digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); + } + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } +#ifdef BOARD_HAS_ANALOG_PULLUP + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + + pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); + + //setup the output address which should be /a/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } //else without a pullup +#endif + + else { + //otherwise it's an analog read + //set the pinmode + + pinMode(analogInputToDigitalPin(pin), INPUT); + //setup the output address which should be /a/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } + } + } +} + +#if 1 +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} +#endif + + + + +void routeTouch(OSCMessage &msg, int addrOffset ) +{ + for(int i=0;i<3;++i) + { + const char *name = numToOSCAddress(i); + int pinMatched = msg.match(name, addrOffset); + if(pinMatched && p[i]) + { + + char outputAddress[9]; + strcpy(outputAddress, "/c"); + strcat(outputAddress, name); + bundleOUT.add(outputAddress).add(p[i]->measure()); + } + } +} + +/** + * SYSTEM MESSAGES + * + * expected format: + * /s + * /m = microseconds + * /d = number of digital pins + * /a = number of analog pins + * /l integer = set the led + * /t = temperature + * /s = power supply voltage + */ +// +void routeSystem(OSCMessage &msg, int addrOffset ){ + + if (msg.fullMatch("/m", addrOffset)){ + bundleOUT.add("/s/m").add((int32_t)micros()); + } + if (msg.fullMatch("/d", addrOffset)){ + bundleOUT.add("/s/d").add(NUM_DIGITAL_PINS); + } + if (msg.fullMatch("/a", addrOffset)){ + bundleOUT.add("/s/a").add(NUM_ANALOG_INPUTS); + } + if (msg.fullMatch("/l", addrOffset)){ + if (msg.isInt(0)){ + pinMode(LED_BUILTIN, OUTPUT); + int i = msg.getInt(0); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, (i > 0)? HIGH: LOW); + bundleOUT.add("/s/l").add(i); + } + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ + + +void setup() { + SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform + for(int i=0; i<3; ++i) + if(!p[i]->begin()) + p[i] =0; +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + { + bundleIN.route("/s", routeSystem); + bundleIN.route("/a", routeAnalog); + bundleIN.route("/d", routeDigital); + bundleIN.route("/tone", routeTone); + bundleIN.route("/c", routeTouch); + } + bundleIN.empty(); + + +//send the outgoing message + SLIPSerial.beginPacket(); + bundleOUT.send(SLIPSerial); + SLIPSerial.endPacket(); + bundleOUT.empty(); + +} + + + + + + + diff --git a/lib/OSC/examples/SerialOscuinowithBundles/SerialOscuinowithBundles.ino b/lib/OSC/examples/SerialOscuinowithBundles/SerialOscuinowithBundles.ino new file mode 100644 index 0000000..5828ed5 --- /dev/null +++ b/lib/OSC/examples/SerialOscuinowithBundles/SerialOscuinowithBundles.ino @@ -0,0 +1,323 @@ + +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +//outgoing messages + +OSCBundle bundleOUT; + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} + +/** + * ROUTES + * + * these are where the routing functions go + * + */ + +/** + * DIGITAL + * + * called when address matched "/d" + * expected format: + * /d/(pin) + * /u = digitalRead with pullup + * (no value) = digitalRead without pullup + * (value) = digital write on that pin + * + */ + +void routeDigital(OSCMessage &msg, int addrOffset ){ + //match input or output + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(pin, OUTPUT); + digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); + } + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } + + //otherwise it's an digital read + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + pinMode(pin, INPUT_PULLUP); + //setup the output address which should be /d/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } //else without a pullup + else { + //set the pinmode + pinMode(pin, INPUT); + //setup the output address which should be /d/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } + } + } +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /a/(pin) + * /u = analogRead with pullup + * (no value) = analogRead without pullup + * (digital value) = digital write on that pin + * (float value) = analogWrite on that pin + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(analogInputToDigitalPin(pin), OUTPUT); + digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); + } + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } +#ifdef BOARD_HAS_ANALOG_PULLUP + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + + pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); + + //setup the output address which should be /a/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } //else without a pullup +#endif + + else { + //otherwise it's an analog read + //set the pinmode + + pinMode(analogInputToDigitalPin(pin), INPUT); + //setup the output address which should be /a/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } + } + } +} + +#ifdef BOARD_HAS_TONE +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} +#endif + + +#ifdef BOARD_HAS_CAPACITANCE_SENSING +#if defined(__MKL26Z64__) +#define NTPINS 11 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,3,4 }; +#else +#define NTPINS 12 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,25,32, 33 }; +#endif + +void routeTouch(OSCMessage &msg, int addrOffset ) +{ + for(int i=0;i 0)? HIGH: LOW); + bundleOUT.add("/s/l").add(i); + } + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ + + +void setup() { + SLIPSerial.begin(115200); // set this as high as you can reliably run on your platform +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + { + bundleIN.route("/s", routeSystem); + bundleIN.route("/a", routeAnalog); + bundleIN.route("/d", routeDigital); +#ifdef BOARD_HAS_TONE + bundleIN.route("/tone", routeTone); +#endif +#ifdef BOARD_HAS_CAPACITANCE_SENSING + bundleIN.route("/c", routeTouch); +#endif + } + bundleIN.empty(); + + +//send the outgoing message + SLIPSerial.beginPacket(); + bundleOUT.send(SLIPSerial); + SLIPSerial.endPacket(); + bundleOUT.empty(); + +} + + + + + + + diff --git a/lib/OSC/examples/SerialOscuinowithMessages/SerialOscuinowithMessages.ino b/lib/OSC/examples/SerialOscuinowithMessages/SerialOscuinowithMessages.ino new file mode 100644 index 0000000..894f0fb --- /dev/null +++ b/lib/OSC/examples/SerialOscuinowithMessages/SerialOscuinowithMessages.ino @@ -0,0 +1,338 @@ + +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} +/** + * ROUTES + * + * these are where the routing functions go + * + */ + +/** + * DIGITAL + * + * called when address matched "/d" + * expected format: + * /d/(pin) + * /u = digitalRead with pullup + * (no value) = digitalRead without pullup + * (value) = digital write on that pin + * + */ + +void routeDigital(OSCMessage &msg, int addrOffset ){ + //match input or output + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(pin, OUTPUT); + digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); + } //otherwise it's an analog read + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } + + + //otherwise it's an digital read + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + pinMode(pin, INPUT_PULLUP); + //setup the output address which should be /d/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the digital read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add(digitalRead(pin)); + SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } //else without a pullup + else { + //set the pinmode + pinMode(pin, INPUT); + //setup the output address which should be /d/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the digital read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add(digitalRead(pin)); + SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } + } + } +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /a/(pin) + * /u = analogRead with pullup + * (no value) = analogRead without pullup + * (digital value) = digital write on that pin + * (float value) = analogWrite on that pin + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(analogInputToDigitalPin(pin), OUTPUT); + digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); + } //otherwise it's an analog read + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } +#ifdef BOARD_HAS_ANALOG_PULLUP + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + + pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); + + //setup the output address which should be /a/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the analog read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add((int32_t)analogRead(pin)); + SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } //else without a pullup +#endif + else { + //set the pinmode + // This fails on Arduino 1.04 on Leanardo, I added this to fix it: #define analogInputToDigitalPin(p) (p+18) + + pinMode(analogInputToDigitalPin(pin), INPUT); + //setup the output address which should be /a/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the analog read and send the results + { + OSCMessage msgOut(outputAddress); msgOut.add((int32_t)analogRead(pin)); + SLIPSerial.beginPacket(); msgOut.send(SLIPSerial); SLIPSerial.endPacket(); + } + } + } + } +} +#ifdef BOARD_HAS_TONE +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} +#endif + + +#ifdef BOARD_HAS_CAPACITANCE_SENSING +#if defined(__MKL26Z64__) +// teensy 3.0LC +#define NTPINS 11 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,3,4 }; +#elif defined(__MK66FX1M0__) +// teensy 3.6 +#define NTPINS 12 +const int cpins[NTPINS] = {0,1,14,15,16,17,18,19,22,23,29,30 }; +#else +//Teensy 3.1 3.2 +#define NTPINS 12 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,25,32, 33 }; +#endif + +void routeTouch(OSCMessage &msg, int addrOffset ) +{ + for(int i=0;i 0)? HIGH: LOW); + { OSCMessage msgOut("/s/l"); msgOut.add(i); SLIPSerial.beginPacket();msgOut.send(SLIPSerial); SLIPSerial.endPacket(); } + } + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ +void setup() { + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} + + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + while(!SLIPSerial.endofPacket()) + if ((size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + { + bundleIN.route("/s", routeSystem); + bundleIN.route("/a", routeAnalog); + bundleIN.route("/d", routeDigital); +#ifdef BOARD_HAS_TONE + bundleIN.route("/tone", routeTone); +#endif +#ifdef BOARD_HAS_CAPACITANCE_SENSING + bundleIN.route("/c", routeTouch); +#endif + } +} + + + + + + + + + + + + + + + diff --git a/lib/OSC/examples/SerialReceive/SerialReceive.ino b/lib/OSC/examples/SerialReceive/SerialReceive.ino new file mode 100644 index 0000000..4d96445 --- /dev/null +++ b/lib/OSC/examples/SerialReceive/SerialReceive.ino @@ -0,0 +1,66 @@ +/* +* Set the LED according to incoming OSC control +*/ +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +void LEDcontrol(OSCMessage &msg) +{ + if (msg.isInt(0)) + { + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, (msg.getInt(0) > 0)? HIGH: LOW); + } + else if(msg.isString(0)) + { + int length=msg.getDataLength(0); + if(length<5) + { + char str[length]; + msg.getString(0,str,length); + if((strcmp("on", str)==0)|| (strcmp("On",str)==0)) + { + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + } + else if((strcmp("Of", str)==0)|| (strcmp("off",str)==0)) + { + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); + } + } + } + +} + + +void setup() { + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} +//reads and dispatches the incoming message +void loop(){ + OSCBundle bundleIN; + int size; + + while(!SLIPSerial.endofPacket()) + if( (size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + bundleIN.dispatch("/led", LEDcontrol); + +} + + diff --git a/lib/OSC/examples/SerialReceiveInfiniteLoop/SerialReceiveInfiniteLoop.ino b/lib/OSC/examples/SerialReceiveInfiniteLoop/SerialReceiveInfiniteLoop.ino new file mode 100644 index 0000000..bef9323 --- /dev/null +++ b/lib/OSC/examples/SerialReceiveInfiniteLoop/SerialReceiveInfiniteLoop.ino @@ -0,0 +1,77 @@ +/* +* Blink the LED according to incoming OSC on/off rates in quasi-asynchronous way +*/ +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +constexpr unsigned long blinkInterval = 2500; +unsigned long blinkNow; + +unsigned long blinkRateOn = 50; +unsigned long blinkRateOff = 50; + +void LEDcontrol(OSCMessage& msg) +{ + if (msg.isInt(0)) { + blinkRateOn = msg.getInt(0); + } + + if (msg.isInt(1)) { + blinkRateOff = msg.getInt(1); + } +} + +void setup() +{ + Serial.begin(9600); + + const unsigned long startNow = millis() + 5000; + while(!Serial && millis() < startNow); + + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform + + blinkNow = millis() + blinkInterval; +} + +//reads and dispatches the incoming message +void loop() +{ + OSCBundle bundleIN; + int size; + + if (SLIPSerial.available()) + while (!SLIPSerial.endofPacket()) + while (SLIPSerial.available()) + bundleIN.fill(SLIPSerial.read()); + + if (!bundleIN.hasError()) + bundleIN.dispatch("/led", LEDcontrol); + + if (millis() >= blinkNow) { + pinMode(LED_BUILTIN, OUTPUT); + + Serial.print("Blinking at "); + Serial.print(blinkRateOn); + Serial.print("/"); + Serial.print(blinkRateOff); + Serial.println(); + + for (auto i = 0; i <= 5; i ++) { + digitalWrite(LED_BUILTIN, HIGH); + delay(blinkRateOn); + digitalWrite(LED_BUILTIN, LOW); + delay(blinkRateOff); + } + // blinkNow = millis() + blinkInterval; + blinkNow = millis() + blinkInterval - 5 * (blinkRateOn + blinkRateOff); + } +} diff --git a/lib/OSC/examples/SerialReceivewithServo/SerialReceivewithServo.ino b/lib/OSC/examples/SerialReceivewithServo/SerialReceivewithServo.ino new file mode 100644 index 0000000..c9849a2 --- /dev/null +++ b/lib/OSC/examples/SerialReceivewithServo/SerialReceivewithServo.ino @@ -0,0 +1,67 @@ +/* +* Control a servo according to incoming OSC control +* +*/ +#include +#include +#include + +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +Servo myservo; + +void servoControl(OSCMessage &msg) +{ + if (msg.isInt(0)) + { + myservo.write(msg.getInt(0)); + } +#ifdef TEMPoraray + else if (msg.isFloat(0)) + { + //test if that pin is a PWM + if (digitalPinHasPWM(LED_BUILTIN)) + { + pinMode(LED_BUILTIN, OUTPUT); + analogWrite(LED_BUILTIN, (int)(msg.getFloat(0)*127.0f)); + } + else + SoftPWMSet(LED_BUILTIN, (int)(msg.getFloat(0)*127.0f)); + } +#endif + +} + +void setup() { + SLIPSerial.begin(9600); + + myservo.attach(13); + myservo.write(90); + + +} +//reads and dispatches the incoming message +void loop(){ + OSCBundle bundleIN; + int size; + + while(!SLIPSerial.endofPacket()) + if( (size =SLIPSerial.available()) > 0) + { + while(size--) + bundleIN.fill(SLIPSerial.read()); + } + + if(!bundleIN.hasError()) + bundleIN.dispatch("/servo", servoControl); + +} + + diff --git a/lib/OSC/examples/SerialSendBundle/SerialSendBundle.ino b/lib/OSC/examples/SerialSendBundle/SerialSendBundle.ino new file mode 100644 index 0000000..5241697 --- /dev/null +++ b/lib/OSC/examples/SerialSendBundle/SerialSendBundle.ino @@ -0,0 +1,47 @@ + +/* + Make an OSC bundle and send it over SLIP serial + + OSCBundles allow OSCMessages to be grouped together to preserve the order and completeness of related messages. + They also allow for timetags to be carried to represent the presentation time of the messages. +*/ +#include +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +void setup() { + //begin SLIPSerial just like Serial + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform + + +} + +void loop(){ + //declare the bundle + OSCBundle bndl; + //BOSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together + bndl.add("/analog/0").add((int32_t)analogRead(0)); + bndl.add("/analog/1").add((int32_t)analogRead(1)); + bndl.add("/digital/5").add((digitalRead(5)==HIGH)?"HIGH":"LOW"); + + + SLIPSerial.beginPacket(); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + bndl.add("/mouse/step").add((int32_t)analogRead(0)).add((int32_t)analogRead(1)); + bndl.add("/units").add("pixels"); + SLIPSerial.beginPacket(); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + delay(100); +} diff --git a/lib/OSC/examples/SerialSendBundleWithTimeTag/SerialSendBundleWithTimeTag.ino b/lib/OSC/examples/SerialSendBundleWithTimeTag/SerialSendBundleWithTimeTag.ino new file mode 100644 index 0000000..3a62218 --- /dev/null +++ b/lib/OSC/examples/SerialSendBundleWithTimeTag/SerialSendBundleWithTimeTag.ino @@ -0,0 +1,47 @@ + +/* + Make an OSC bundle and send it over SLIP serial + + OSCBundles allow OSCMessages to be grouped together to preserve the order and completeness of related messages. + They also allow for timetags to be carried to represent the presentation time of the messages. +*/ +#include +#include +#include +#include + +#ifdef BOARD_HAS_USB_SERIAL +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +void setup() { + //begin SLIPSerial just like Serial + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform + +} + +void loop(){ + //declare the bundle + OSCBundle bndl; + osctime_t timetag; + + //OSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together + bndl.add("/analog/0").add((int32_t)adcRead(0, &timetag)); + bndl.add("/analog/0/time").add(timetag); + + bndl.add("/analog/1").add((int32_t)adcRead(1, &timetag)); + bndl.add("/analog/1/time").add(timetag); + + bndl.add("/digital/5").add((digitalRead(5)==HIGH)?"HIGH":"LOW"); + + SLIPSerial.beginPacket(); + bndl.setTimetag(oscTime()); + bndl.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + delay(100); +} diff --git a/lib/OSC/examples/SerialSendMessage/SerialSendMessage.ino b/lib/OSC/examples/SerialSendMessage/SerialSendMessage.ino new file mode 100644 index 0000000..4618804 --- /dev/null +++ b/lib/OSC/examples/SerialSendMessage/SerialSendMessage.ino @@ -0,0 +1,33 @@ +#include +#include +/* +Make an OSC message and send it over serial + */ + +#ifdef BOARD_HAS_USB_SERIAL +#include +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else +#include + SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + + +void setup() { + //begin SLIPSerial just like Serial + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} + + +void loop(){ + //the message wants an OSC address as first argument + OSCMessage msg("/analog/0"); + msg.add((int32_t)analogRead(0)); + + SLIPSerial.beginPacket(); + msg.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + msg.empty(); // free space occupied by message + + delay(20); +} diff --git a/lib/OSC/examples/SerialSendMessageInfiniteLoop/SerialSendMessageInfiniteLoop.ino b/lib/OSC/examples/SerialSendMessageInfiniteLoop/SerialSendMessageInfiniteLoop.ino new file mode 100644 index 0000000..0ac18e0 --- /dev/null +++ b/lib/OSC/examples/SerialSendMessageInfiniteLoop/SerialSendMessageInfiniteLoop.ino @@ -0,0 +1,44 @@ +/* +* Make an OSC message for controlling a remote LED blinking rates. +*/ + +#include +#include + +#ifdef BOARD_HAS_USB_SERIAL +#include +SLIPEncodedUSBSerial SLIPSerial(thisBoardsSerialUSB); +#else +#include +SLIPEncodedSerial SLIPSerial(Serial1); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + +constexpr auto blinkRatesSize = 8; +int blinkRates[blinkRatesSize] = { 25, 50, 100, 125, 150, 175, 200, 225 }; + +void setup() +{ + //begin SLIPSerial just like Serial + SLIPSerial.begin(9600); // set this as high as you can reliably run on your platform +} + +void loop() +{ + //the message wants an OSC address as first argument + OSCMessage msg("/led"); + + auto i = rand() % (blinkRatesSize - 1); + auto blinkRateOn = blinkRates[i]; + + auto j = rand() % (blinkRatesSize - 1); + auto blinkRateOff = blinkRates[j]; + + msg.add(blinkRateOn).add(blinkRateOff); + + SLIPSerial.beginPacket(); + msg.send(SLIPSerial); // send the bytes to the SLIP stream + SLIPSerial.endPacket(); // mark the end of the OSC Packet + msg.empty(); // free space occupied by message + + delay(20); +} diff --git a/lib/OSC/examples/UDPCallResponse/UDPCallResponse.ino b/lib/OSC/examples/UDPCallResponse/UDPCallResponse.ino new file mode 100644 index 0000000..bc7f7b5 --- /dev/null +++ b/lib/OSC/examples/UDPCallResponse/UDPCallResponse.ino @@ -0,0 +1,164 @@ +/* +UDP Call Response + +Send responses to calls for information from a remote host +*/ + +#include +#include +#include +#include +#include + +//UDP communication +EthernetUDP Udp; + +//the Arduino's IP +IPAddress ip(128, 32, 122, 252); + +//port numbers +const unsigned int inPort = 8888; +const unsigned int outPort = 9999; + + +//everything on the network needs a unique MAC +#if defined(__MK20DX128__) +// Teensy 3 has MAC burned in +static byte mac[6]; +void read(uint8_t word, uint8_t *mac, uint8_t offset) { + FTFL_FCCOB0 = 0x41; // Selects the READONCE command + FTFL_FCCOB1 = word; // read the given word of read once area + + // launch command and wait until complete + FTFL_FSTAT = FTFL_FSTAT_CCIF; + while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); + + *(mac+offset) = FTFL_FCCOB5; // collect only the top three bytes, + *(mac+offset+1) = FTFL_FCCOB6; // in the right orientation (big endian). + *(mac+offset+2) = FTFL_FCCOB7; // Skip FTFL_FCCOB4 as it's always 0. +} +void read_mac() { + read(0xe,mac,0); + read(0xf,mac,3); +} +#else +void read_mac() {} + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields +#endif + +//outgoing messages + +OSCBundle bundleOUT; + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /analog/(pin) + * /u = analogRead with pullup + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + int pinMatched; + pinMatched = msg.match("/0", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(0), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/0").add((int32_t)analogRead(0)); + } + pinMatched = msg.match("/1", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(1), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/1").add((int32_t)analogRead(1)); + } + pinMatched = msg.match("/2", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(2), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/2").add((int32_t)analogRead(2)); + } + pinMatched = msg.match("/3", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(3), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/3").add((int32_t)analogRead(3)); + } + pinMatched = msg.match("/4", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(4), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/4").add((int32_t)analogRead(4)); + } + pinMatched = msg.match("/5", addrOffset); + if(pinMatched){ + if (msg.fullMatch("/u", pinMatched+addrOffset)) pinMode(analogInputToDigitalPin(5), INPUT_PULLUP); //set the pullup + //do the analog read and send the results + bundleOUT.add("/analog/5").add((int32_t)analogRead(5)); + } +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ +void setup() { + //setup ethernet part + read_mac(); + Ethernet.begin(mac,ip); + Udp.begin(inPort); + +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + + if( (size = Udp.parsePacket())>0) + { +// unsigned int outPort = Udp.remotePort(); + + while(size--) + bundleIN.fill(Udp.read()); + + if(!bundleIN.hasError()) + bundleIN.route("/analog", routeAnalog); + + // send the response bundle back to where the request came from + Udp.beginPacket(Udp.remoteIP(), outPort); + bundleOUT.send(Udp); + Udp.endPacket(); + bundleOUT.empty(); // empty the bundle ready to use for new messages + } +} + + + + + + + + diff --git a/lib/OSC/examples/UDPEcho/UDPEcho.ino b/lib/OSC/examples/UDPEcho/UDPEcho.ino new file mode 100644 index 0000000..3cfb0ee --- /dev/null +++ b/lib/OSC/examples/UDPEcho/UDPEcho.ino @@ -0,0 +1,84 @@ +/* + +Leverage the UDP source IP and port calls to +return OSC information back + +This example can be extended to build routers and forwarders of OSC packets + + */ +#include +#include +#include +#include + +EthernetUDP Udp; + +//the Arduino's IP +IPAddress ip(128, 32, 122, 252); + +//port numbers +const unsigned int inPort = 8888; +const unsigned int outPort = 9999; + +//everything on the network needs a unique MAC +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) +// Teensy 3.x has MAC burned in +static byte mac[6]; +void read(uint8_t word, uint8_t *mac, uint8_t offset) { +   FTFL_FCCOB0 = 0x41;             // Selects the READONCE command +   FTFL_FCCOB1 = word;             // read the given word of read once area + +   // launch command and wait until complete +   FTFL_FSTAT = FTFL_FSTAT_CCIF; +   while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); + +   *(mac+offset) =   FTFL_FCCOB5;       // collect only the top three bytes, +   *(mac+offset+1) = FTFL_FCCOB6;       // in the right orientation (big endian). +   *(mac+offset+2) = FTFL_FCCOB7;       // Skip FTFL_FCCOB4 as it's always 0. +} +void read_mac() { +   read(0xe,mac,0); +   read(0xf,mac,3); +} +#else +void read_mac() {} + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields +#endif + +void setup() { + Ethernet.begin(mac,ip); + Udp.begin(inPort); +} + +void loop(){ + OSCBundle bndl; + int size; + + //receive a bundle + if( (size = Udp.parsePacket())>0) + { +// unsigned int outPort = Udp.remotePort(); + + while(size--) + bndl.fill(Udp.read()); + + if(!bndl.hasError()) + { + //and echo it back + if(bndl.size() > 0) + { + static int32_t sequencenumber=0; + + // we can sneak an addition onto the end of the bundle + bndl.add("/micros").add((int32_t)micros()); // (int32_t) is the type of OSC Integers + bndl.add("/sequencenumber").add(sequencenumber++); + + Udp.beginPacket(Udp.remoteIP(), outPort); + bndl.send(Udp); + Udp.endPacket(); + } + } + } +} + diff --git a/lib/OSC/examples/UDPOscuino/UDPOscuino.ino b/lib/OSC/examples/UDPOscuino/UDPOscuino.ino new file mode 100644 index 0000000..9fdafea --- /dev/null +++ b/lib/OSC/examples/UDPOscuino/UDPOscuino.ino @@ -0,0 +1,378 @@ + +// UDP OSCuino +// system, analog and digital pin control and monitoring for Arduino +// Yotam Mann and Adrian Freed + + +#include +#include +#include +#include +#include + +EthernetUDP Udp; + +//the Arduino's IP +IPAddress ip(128, 32, 122, 252); + +//port numbers +const unsigned int inPort = 8888; +const unsigned int outPort = 9999; + +//everything on the network needs a unique MAC +#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || defined(__MK66FX1M0__) +// Teensy 3 has MAC burned in +static byte mac[6]; +void read(uint8_t word, uint8_t *mac, uint8_t offset) { + FTFL_FCCOB0 = 0x41; // Selects the READONCE command + FTFL_FCCOB1 = word; // read the given word of read once area + + // launch command and wait until complete + FTFL_FSTAT = FTFL_FSTAT_CCIF; + while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)); + + *(mac+offset) = FTFL_FCCOB5; // collect only the top three bytes, + *(mac+offset+1) = FTFL_FCCOB6; // in the right orientation (big endian). + *(mac+offset+2) = FTFL_FCCOB7; // Skip FTFL_FCCOB4 as it's always 0. +} +void read_mac() { + read(0xe,mac,0); + read(0xf,mac,3); +} +#else +void read_mac() {} + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields +#endif + + +//outgoing messages + +OSCBundle bundleOUT; + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} + +/** + * ROUTES + * + * these are where the routing functions go + * + */ + +/** + * DIGITAL + * + * called when address matched "/d" + * expected format: + * /d/(pin) + * /u = digitalRead with pullup + * (no value) = digitalRead without pullup + * (value) = digital write on that pin + * + */ + +void routeDigital(OSCMessage &msg, int addrOffset ){ + //match input or output + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(pin, OUTPUT); + digitalWrite(pin, (msg.getInt(0)>0) ? HIGH:LOW); + } //otherwise it's an analog read + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } + + + //otherwise it's an digital read + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + pinMode(pin, INPUT_PULLUP); + //setup the output address which should be /d/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } //else without a pullup + else { + //set the pinmode + pinMode(pin, INPUT); + //setup the output address which should be /d/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/d"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the digital read and send the results + bundleOUT.add(outputAddress).add(digitalRead(pin)); + } + } + } +} + +/** + * ANALOG + * + * called when the address matches "/a" + * + * format: + * /a/(pin) + * /u = analogRead with pullup + * (no value) = analogRead without pullup + * (digital value) = digital write on that pin + * (float value) = analogWrite on that pin + * + **/ + +void routeAnalog(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_ANALOG_INPUTS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + //if it has an int, then it's a digital write + if (msg.isInt(0)){ + pinMode(analogInputToDigitalPin(pin), OUTPUT); + digitalWrite(analogInputToDigitalPin(pin), (msg.getInt(0) > 0)? HIGH: LOW); + } //otherwise it's an analog read + else if(msg.isFloat(0)){ + analogWrite(pin, (int)(msg.getFloat(0)*255.0f)); + } +#ifdef BOARD_HAS_ANALOG_PULLUP + //with a pullup? + else if (msg.fullMatch("/u", pinMatched+addrOffset)){ + //set the pullup + + pinMode(analogInputToDigitalPin(pin), INPUT_PULLUP); + + //setup the output address which should be /a/(pin)/u + char outputAddress[9]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + strcat(outputAddress,"/u"); + strcat(outputAddress,"/u"); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } //else without a pullup +#endif + else { + //set the pinmode + + pinMode(analogInputToDigitalPin(pin), INPUT); + //setup the output address which should be /a/(pin) + char outputAddress[6]; + strcpy(outputAddress, "/a"); + strcat(outputAddress, numToOSCAddress(pin)); + //do the analog read and send the results + bundleOUT.add(outputAddress).add((int32_t)analogRead(pin)); + } + } + } +} + +#ifdef BOARD_HAS_TONE + +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} + +#endif + +#ifdef BOARD_HAS_CAPACITANCE_SENSING + +#if defined(__MKL26Z64__) +// teensy 3.0LC +#define NTPINS 11 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,3,4 }; +#elif defined(__MK66FX1M0__) +// teensy 3.6 +#define NTPINS 12 +const int cpins[NTPINS] = {0,1,14,15,16,17,18,19,22,23,29,30 }; +#else +//Teensy 3.1 3.2 +#define NTPINS 12 +const int cpins[NTPINS] = {22,23,19,18,17,16,15,0,1,25,32, 33 }; +#endif + +void routeTouch(OSCMessage &msg, int addrOffset ) +{ + for(int i=0;i 0)? HIGH: LOW); + bundleOUT.add("/s/l").add(i); + } + } +#endif +} + +/** + * MAIN METHODS + * + * setup and loop, bundle receiving/sending, initial routing + */ +void setup() { + //setup ethernet port + read_mac(); + Ethernet.begin(mac,ip); + Udp.begin(inPort); + +} + +//reads and routes the incoming messages +void loop(){ + OSCBundle bundleIN; + int size; + + if( (size = Udp.parsePacket())>0) + { +// unsigned int outPort = Udp.remotePort(); + + while(size--) + bundleIN.fill(Udp.read()); + + if(!bundleIN.hasError()) + { + bundleIN.route("/s", routeSystem); + bundleIN.route("/a", routeAnalog); + bundleIN.route("/d", routeDigital); +#ifdef BOARD_HAS_TONE + bundleIN.route("/tone", routeTone); +#endif + +#ifdef TOUCHSUPPORT + bundleIN.route("/c", routeTouch); +#endif + + } + // send the response bundle back to where the request came from + Udp.beginPacket(Udp.remoteIP(),outPort); + bundleOUT.send(Udp); + Udp.endPacket(); + bundleOUT.empty(); // empty the bundle ready to use for new messages + } +} + + + + + + + + diff --git a/lib/OSC/examples/UDPReceive/UDPReceive.ino b/lib/OSC/examples/UDPReceive/UDPReceive.ino new file mode 100644 index 0000000..060db8b --- /dev/null +++ b/lib/OSC/examples/UDPReceive/UDPReceive.ino @@ -0,0 +1,106 @@ + +#include +#include +#include + +#include +#include + +/* +* UDPReceiveOSC +* Set a tone according to incoming OSC control +* Adrian Freed +*/ + +//UDP communication + + +EthernetUDP Udp; +byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields + +//the Arduino's IP +IPAddress ip(128, 32, 122, 252); + +//port numbers +const unsigned int inPort = 8888; + +//converts the pin to an osc address +char * numToOSCAddress( int pin){ + static char s[10]; + int i = 9; + + s[i--]= '\0'; + do + { + s[i] = "0123456789"[pin % 10]; + --i; + pin /= 10; + } + while(pin && i); + s[i] = '/'; + return &s[i]; +} + +/** + * TONE + * + * square wave output "/tone" + * + * format: + * /tone/pin + * + * (digital value) (float value) = frequency in Hz + * (no value) disable tone + * + **/ + +void routeTone(OSCMessage &msg, int addrOffset ){ + //iterate through all the analog pins + for(byte pin = 0; pin < NUM_DIGITAL_PINS; pin++){ + //match against the pin number strings + int pinMatched = msg.match(numToOSCAddress(pin), addrOffset); + if(pinMatched){ + unsigned int frequency = 0; + //if it has an int, then it's an integers frequency in Hz + if (msg.isInt(0)){ + frequency = msg.getInt(0); + } //otherwise it's a floating point frequency in Hz + else if(msg.isFloat(0)){ + frequency = msg.getFloat(0); + } + else + noTone(pin); + if(frequency>0) + { + if(msg.isInt(1)) + tone(pin, frequency, msg.getInt(1)); + else + tone(pin, frequency); + } + } + } +} + +void setup() { + //setup ethernet part + Ethernet.begin(mac,ip); + Udp.begin(inPort); + +} +//reads and dispatches the incoming message +void loop(){ + OSCBundle bundleIN; + int size; + + if( (size = Udp.parsePacket())>0) + { + while(size--) + bundleIN.fill(Udp.read()); + + if(!bundleIN.hasError()) + bundleIN.route("/tone", routeTone); + } +} + + diff --git a/lib/OSC/examples/UDPSendBundle/UDPSendBundle.ino b/lib/OSC/examples/UDPSendBundle/UDPSendBundle.ino new file mode 100644 index 0000000..fec9de9 --- /dev/null +++ b/lib/OSC/examples/UDPSendBundle/UDPSendBundle.ino @@ -0,0 +1,55 @@ + +/* +Make an OSC bundle and send it over UDP + +OSCBundles allow OSCMessages to be grouped together +to preserve the order and completeness of related messages. +They also allow for timetags to be carried to represent the presentation time +of the messages. + */ +#include +#include +#include +#include + +EthernetUDP Udp; + +//the Arduino's IP +IPAddress ip(128, 32, 122, 252); +//destination IP +IPAddress outIp(128, 32, 122, 125); +const unsigned int outPort = 9999; + + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields +void setup() { + Ethernet.begin(mac,ip); + Udp.begin(8888); +} + + + +void loop(){ + //declare the bundle + OSCBundle bndl; + + //BOSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together + bndl.add("/analog/0").add((int32_t)analogRead(0)); + bndl.add("/analog/1").add((int32_t)analogRead(1)); + bndl.add("/digital/5").add((digitalRead(5)==HIGH)?"HIGH":"LOW"); + + Udp.beginPacket(outIp, outPort); + bndl.send(Udp); // send the bytes to the SLIP stream + Udp.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + bndl.add("/mouse/step").add((int32_t)analogRead(0)).add((int32_t)analogRead(1)); + bndl.add("/units").add("pixels"); + + Udp.beginPacket(outIp, outPort); + bndl.send(Udp); // send the bytes to the SLIP stream + Udp.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + delay(1000); +} diff --git a/lib/OSC/examples/UDPSendBundlewithTimeTag/UDPSendBundlewithTimeTag.ino b/lib/OSC/examples/UDPSendBundlewithTimeTag/UDPSendBundlewithTimeTag.ino new file mode 100644 index 0000000..c12b19e --- /dev/null +++ b/lib/OSC/examples/UDPSendBundlewithTimeTag/UDPSendBundlewithTimeTag.ino @@ -0,0 +1,62 @@ + +/* +Make an OSC bundle and send it over UDP + +OSCBundles allow OSCMessages to be grouped together +to preserve the order and completeness of related messages. +They also allow for timetags to be carried to represent the presentation time +of the messages. + */ +#include +#include +#include +#include +#include + + +EthernetUDP Udp; + +//the Arduino's IP +IPAddress ip(128, 32, 122, 26); +//destination IP +IPAddress outIp(128, 32, 122, 25); +const unsigned int outPort = 9999; + + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields +void setup() { + Ethernet.begin(mac,ip); + Udp.begin(8888); +} + + + +void loop(){ + //declare the bundle + OSCBundle bndl; + osctime_t timetag; + + //OSCBundle's add' returns the OSCMessage so the message's 'add' can be composed together + bndl.add("/analog/0").add((int32_t)adcRead(0, &timetag)); + bndl.add("/analog/0/time").add(timetag); + + bndl.add("/analog/1").add((int32_t)adcRead(1, &timetag)); + bndl.add("/analog/1/time").add(timetag); + + Udp.beginPacket(outIp, outPort); + bndl.setTimetag(oscTime()); + bndl.send(Udp); // send the bytes to the SLIP stream + Udp.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + bndl.add("/mouse/step").add((int32_t)analogRead(0)).add((int32_t)analogRead(1)); + bndl.add("/units").add("pixels"); + + Udp.beginPacket(outIp, outPort); + bndl.setTimetag(oscTime()); + bndl.send(Udp); // send the bytes to the SLIP stream + Udp.endPacket(); // mark the end of the OSC Packet + bndl.empty(); // empty the bundle to free room for a new one + + delay(100); +} diff --git a/lib/OSC/examples/UDPSendMessage/UDPSendMessage.ino b/lib/OSC/examples/UDPSendMessage/UDPSendMessage.ino new file mode 100644 index 0000000..011dba1 --- /dev/null +++ b/lib/OSC/examples/UDPSendMessage/UDPSendMessage.ino @@ -0,0 +1,41 @@ +#include + +/* + Make an OSC message and send it over UDP + + Adrian Freed + */ +#include +#include +#include +#include + +EthernetUDP Udp; + +//the Arduino's IP +IPAddress ip(128, 32, 122, 252); +//destination IP +IPAddress outIp(128, 32, 122, 125); +const unsigned int outPort = 9999; + + byte mac[] = { + 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields +void setup() { + Ethernet.begin(mac,ip); + Udp.begin(8888); + +} + + +void loop(){ + //the message wants an OSC address as first argument + OSCMessage msg("/analog/0"); + msg.add((int32_t)analogRead(0)); + + Udp.beginPacket(outIp, outPort); + msg.send(Udp); // send the bytes to the SLIP stream + Udp.endPacket(); // mark the end of the OSC Packet + msg.empty(); // free space occupied by message + + delay(20); +} diff --git a/lib/OSC/keywords.txt b/lib/OSC/keywords.txt new file mode 100644 index 0000000..7ad684b --- /dev/null +++ b/lib/OSC/keywords.txt @@ -0,0 +1,91 @@ +getOSCMessage KEYWORD2 +fill KEYWORD2 +send KEYWORD2 +dispatch KEYWORD2 +route KEYWORD2 +setTimetag KEYWORD2 +getTimetag KEYWORD2 +hasError KEYWORD2 +add KEYWORD2 +set KEYWORD2 +match KEYWORD2 +fullMatch KEYWORD2 +getInt KEYWORD2 +getFloat KEYWORD2 +getBoolean KEYWORD2 +getTime KEYWORD2 +getDouble KEYWORD2 +getBlob KEYWORD2 +getString KEYWORD2 +getAddress KEYWORD2 +getDataLength KEYWORD2 +getBlobLength KEYWORD2 +getType KEYWORD2 +isInt KEYWORD2 +isFloat KEYWORD2 +isBlob KEYWORD2 +isString KEYWORD2 +isBoolean KEYWORD2 +isDouble KEYWORD2 +isTime KEYWORD2 +size KEYWORD2 +bytes KEYWORD2 +empty KEYWORD2 +OSCBundle KEYWORD1 +OSCMessage KEYWORD1 +OSCMatch KEYWORD1 +OSCData KEYWORD1 +endTransmission KEYWORD1 +endofTransmission KEYWORD1 +SLIPEncodedSerial KEYWORD3 +SLIPEncodedUSBSerial KEYWORD3 +SLIPEncodedSPISerial KEYWORD3 +oscTime KEYWORD1 +adcRead KEYWORD1 +capacitanceRead KEYWORD1 +inputRead KEYWORD1 +####################################### +# Syntax Coloring Map SPI +####################################### +####################################### +# Class +####################################### +StreamSPI0 KEYWORD3 + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SPI KEYWORD1 +StreamSPI KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +end KEYWORD2 +transfer KEYWORD2 +setBitOrder KEYWORD2 +setDataMode KEYWORD2 +setClockDivider KEYWORD2 + + +####################################### +# Constants (LITERAL1) +####################################### +SPI_CLOCK_DIV4 LITERAL1 +SPI_CLOCK_DIV16 LITERAL1 +SPI_CLOCK_DIV64 LITERAL1 +SPI_CLOCK_DIV128 LITERAL1 +SPI_CLOCK_DIV2 LITERAL1 +SPI_CLOCK_DIV8 LITERAL1 +SPI_CLOCK_DIV32 LITERAL1 +SPI_CLOCK_DIV64 LITERAL1 +SPI_MODE0 LITERAL1 +SPI_MODE1 LITERAL1 +SPI_MODE2 LITERAL1 +SPI_MODE3 LITERAL1 + + + + diff --git a/lib/OSC/library.json b/lib/OSC/library.json new file mode 100644 index 0000000..d5662fd --- /dev/null +++ b/lib/OSC/library.json @@ -0,0 +1,25 @@ +{ + "name": "OSC", + "version": "1.0.0", + "keywords": "sound, encoding, OSC", + "description": "Open Sound Control (OSC) is an open, transport-independent, message-based encidubg developed for communication among computers, sound synthesizers, and other multimedia devices.", + "authors": [ + { + "name": "Adrian Freed", + "email": "adrian@adrianfreed.com", + "url": "http://www.adrianfreed.com" + }, + { + "name": "Yotam Mann", + "url": "http://yotammann.info" + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/CNMAT/OSC.git" + }, + "frameworks": "arduino", + "platforms": "*" + ] +} diff --git a/lib/OSC/library.properties b/lib/OSC/library.properties new file mode 100644 index 0000000..1c3a54e --- /dev/null +++ b/lib/OSC/library.properties @@ -0,0 +1,9 @@ +name=OSC +version=1.3.7 +author=Adrian Freed , Yotam Mann +maintainer=Adrian Freed +sentence=Open Sound Control (OSC) +paragraph=Open Sound Control (OSC) is an open, transport-independent, message-based encoding developed for communication among computers, sound synthesizers, and other multimedia devices. +category=Device Control +url=https://github.com/CNMAT/OSC +architectures=* diff --git a/lib/OSC/test/OSCBundle_test/OSCBundle_test.ino b/lib/OSC/test/OSCBundle_test/OSCBundle_test.ino new file mode 100644 index 0000000..81438c5 --- /dev/null +++ b/lib/OSC/test/OSCBundle_test/OSCBundle_test.ino @@ -0,0 +1,123 @@ +#include +#include +#include "TestPrint.h" + +#define HAS_DOUBLE sizeof(double) == 8 + +test(bundle_address){ + OSCBundle bundle; + bundle.add("/address").add(1); + assertEqual(bundle.size(), 1); + OSCMessage msg = bundle.getOSCMessage("/address"); + assertTrue(msg.isInt(0)); + assertEqual(msg.getInt(0), 1); +} + +test(bundle_message_position){ + OSCBundle bundle; + bundle.add("/one").add(1); + bundle.add("/two").add(2); + assertEqual(bundle.size(), 2); + OSCMessage msg0 = bundle.getOSCMessage(0); + assertTrue(msg0.isInt(0)); + assertEqual(msg0.getInt(0), 1); + OSCMessage msg1 = bundle.getOSCMessage(1); + assertTrue(msg1.isInt(0)); + assertEqual(msg1.getInt(0), 2); +} + +test(bundle_add_message){ + OSCMessage msg("/msg"); + OSCBundle bundle; + bundle.add(msg).add(1); + assertEqual(bundle.size(), 1); + OSCMessage test_msg = bundle.getOSCMessage(0); + assertTrue(test_msg.isInt(0)); + assertEqual(test_msg.getInt(0), 1); +} + +void routeA(OSCMessage & msg, int offset){ + assertTrue(msg.isInt(0)); + assertEqual(msg.getInt(0), 1); +} + +void routeB(OSCMessage & msg, int offset){ + assertTrue(msg.isInt(0)); + assertEqual(msg.getInt(0), 2); +} + +test(bundle_route){ + OSCMessage msg("/msg"); + OSCBundle bundle; + bundle.add("/a").add(1); + bundle.add("/b/1").add(2); + assertEqual(bundle.size(), 2); + assertTrue(bundle.route("/a", routeA)); + assertTrue(bundle.route("/b", routeB)); +} + +void dispatchA(OSCMessage & msg){ + assertTrue(msg.isInt(0)); + assertEqual(msg.getInt(0), 1); +} + +void dispatchB(OSCMessage & msg){ + assertTrue(msg.isInt(0)); + assertEqual(msg.getInt(0), 2); +} + +test(bundle_dispatch){ + OSCMessage msg("/msg"); + OSCBundle bundle; + bundle.add("/a").add(1); + bundle.add("/b").add(2); + assertEqual(bundle.size(), 2); + assertTrue(bundle.route("/a", routeA)); + assertTrue(bundle.route("/b", routeB)); +} + +test(bundle_encode){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 47, 98, 0, 0, 44, 105, 0, 0, 0, 0, 0, 2}; + OSCBundle bundle; + bundle.add("/a").add(1); + bundle.add("/b").add(2); + bundle.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } +} + +test(bundle_decode){ + uint8_t testBuffer[] = {35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 47, 98, 0, 0, 44, 105, 0, 0, 0, 0, 0, 2}; + OSCBundle bundle; + bundle.fill(testBuffer, sizeof(testBuffer)); + assertEqual(bundle.size(), 2); + OSCMessage msgA = bundle.getOSCMessage("/a"); + assertTrue(msgA.isInt(0)); + assertEqual(msgA.getInt(0), 1); + OSCMessage msgB = bundle.getOSCMessage("/b"); + assertTrue(msgB.isInt(0)); + assertEqual(msgB.getInt(0), 2); +} + +test(bundle_decode_invalid){ + uint8_t testBuffer[] = {35, 98, 117, 110, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 47, 97, 0, 0, 44, 105, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 47, 98, 0, 0, 44, 105, 0, 0, 0, 0, 2}; + OSCBundle bundle; + bundle.fill(testBuffer, sizeof(testBuffer)); + assertTrue(bundle.hasError()); +} + + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only +} + +void loop() +{ + Test::run(); +} diff --git a/lib/OSC/test/OSCBundle_test/TestPrint.h b/lib/OSC/test/OSCBundle_test/TestPrint.h new file mode 100644 index 0000000..8caf749 --- /dev/null +++ b/lib/OSC/test/OSCBundle_test/TestPrint.h @@ -0,0 +1,36 @@ + +/** + * A print class for testing the encoder + */ +class TestPrint : public Print { + + private: + //a small test buffer + uint8_t buffer[64]; + + //pointer to the current write spot + int bufferPointer; + + public: + + TestPrint(){ + bufferPointer = 0; + } + + size_t write(uint8_t character) { + buffer[bufferPointer++] = character; + return character; + } + + int size(){ + return bufferPointer; + } + + uint8_t at(int index){ + return buffer[index]; + } + + void clear(){ + bufferPointer = 0; + } +}; diff --git a/lib/OSC/test/OSCData_test/OSCData_test.ino b/lib/OSC/test/OSCData_test/OSCData_test.ino new file mode 100644 index 0000000..b07ae53 --- /dev/null +++ b/lib/OSC/test/OSCData_test/OSCData_test.ino @@ -0,0 +1,96 @@ +#include +#include + +#define HAS_DOUBLE sizeof(double) == 8 + +test(data_int){ + int i = 1; + OSCData datum(i); + assertEqual(datum.getInt(), i); + assertEqual(datum.type, 'i'); +} + +test(data_float){ + float f = 1.1; + OSCData datum(f); + assertEqual(datum.getFloat(), f); + assertEqual(datum.type, 'f'); +} + +test(data_string){ + const char * testStr = "data"; + int testStrLen = strlen(testStr) + 1; + OSCData datum(testStr); + char str[testStrLen]; + datum.getString(str, testStrLen); + assertEqual(strcmp(str, testStr), 0); + assertEqual(datum.type, 's'); +} + +test(data_string_partial_copy){ + const char * testStr = "data"; + int testStrLen = strlen(testStr) + 1; + OSCData datum(testStr); + char str[testStrLen]; + assertEqual(datum.getString(str, 2), 2); + assertEqual(strncmp(str, testStr, 2), 0); +} + +test(data_bool){ + bool f = false; + OSCData datum(f); + assertFalse(datum.getBoolean()); +} + +test(has_double){ + assertEqual(sizeof(double), 8U); +} + +test(data_double){ + if (HAS_DOUBLE){ + double d = 1.1; + OSCData datum = OSCData(d); + assertEqual(datum.getDouble(), d); + assertEqual(datum.type, 'd'); + } +} + +test(data_blob){ + uint8_t b[] = {0, 1, 2, 3}; + OSCData datum(b, 4); + uint8_t blob[4]; + datum.getBlob(blob, 4); + for (int i = 0; i < 4; i++){ + assertEqual(blob[i], b[i]); + } + assertEqual(datum.type, 'b'); +} + +test(data_blob_partial_copy){ + uint8_t b[] = {0, 1, 2, 3}; + OSCData datum(b, 4); + uint8_t blob[4]; + assertEqual(datum.getBlob(blob, 2), 2); + for (int i = 0; i < 2; i++){ + assertEqual(blob[i], b[i]); + } +} + +test(data_copy){ + OSCData datum = OSCData(1); + OSCData cpy(datum); + assertEqual(cpy.getInt(), 1); + assertEqual(cpy.type, 'i'); +} + + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only +} + +void loop() +{ + Test::run(); +} diff --git a/lib/OSC/test/OSCMessage_encode_decode_test/OSCMessage_encode_decode_test.ino b/lib/OSC/test/OSCMessage_encode_decode_test/OSCMessage_encode_decode_test.ino new file mode 100644 index 0000000..649deea --- /dev/null +++ b/lib/OSC/test/OSCMessage_encode_decode_test/OSCMessage_encode_decode_test.ino @@ -0,0 +1,182 @@ +#include +#include +#include "TestPrint.h" + +#define HAS_DOUBLE sizeof(double) == 8 + +test(message_encode_int){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {47, 102, 111, 111, 0, 0, 0, 0, 44, 105, 105, 105, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 255, 255, 255, 236}; + OSCMessage msg("/foo"); + msg.add(1); + msg.add(2); + msg.add(-20); + msg.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (unsigned int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } +} + +test(message_encode_string){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {47, 116, 101, 115, 116, 0, 0, 0, 44, 115, 115, 0, 104, 105, 0, 0, 104, 111, 119, 100, 121, 0, 0, 0}; + OSCMessage msg("/test"); + msg.add("hi"); + msg.add("howdy"); + msg.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (unsigned int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } +} + +test(message_encode_float){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {47, 97, 100, 100, 114, 101, 115, 115, 0, 0, 0, 0, 44, 102, 102, 0, 63, 128, 0, 0, 192, 6, 102, 102}; + OSCMessage msg("/address"); + msg.add(1.0f); + msg.add(-2.1f); + msg.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (unsigned int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } +} + +test(message_encode_double){ + if (HAS_DOUBLE){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {47, 97, 0, 0, 44, 100, 100, 0, 64, 89, 0, 0, 0, 0, 0, 0, 63, 80, 98, 77, 210, 241, 169, 252}; + OSCMessage msg("/a"); + double d0 = 100; + double d1 = 0.001; + msg.add(d0); + msg.add(d1); + msg.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (unsigned int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } + } +} + +test(message_encode_blob){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {47, 98, 0, 0, 44, 98, 0, 0, 0, 0, 0, 5, 1, 2, 3, 4, 5, 0, 0, 0}; + OSCMessage msg("/b"); + uint8_t blob[] = {1, 2, 3, 4, 5}; + msg.add(blob, 5); + msg.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (unsigned int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } +} + +test(message_encode_mixed){ + TestPrint printer; + //this is the desired output + uint8_t testBuffer[] = {47, 109, 105, 120, 101, 100, 0, 0, 44, 115, 105, 102, 0, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 1, 63, 128, 0, 0}; + OSCMessage msg("/mixed"); + msg.add("one"); + msg.add(1); + msg.add(1.0f); + msg.send(printer); + assertEqual(printer.size(), sizeof(testBuffer)); + for (unsigned int i = 0; i < sizeof(testBuffer); i++){ + assertEqual(testBuffer[i], printer.at(i)); + } +} + +test(message_decode_int){ + uint8_t testBuffer[] = {47, 105, 110, 116, 115, 0, 0, 0, 44, 105, 105, 105, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 200, 255, 255, 255, 231}; + OSCMessage msg; + msg.fill(testBuffer, sizeof(testBuffer)); + assertEqual(msg.size(), 3); + assertTrue(msg.isInt(0)); + assertTrue(msg.isInt(1)); + assertTrue(msg.isInt(2)); + assertEqual(msg.getInt(0), 1); + assertEqual(msg.getInt(1), 200); + assertEqual(msg.getInt(2), -25); +} + +test(message_decode_float){ + uint8_t testBuffer[] = {47, 102, 108, 111, 97, 116, 115, 0, 44, 102, 102, 0, 191, 128, 0, 0, 67, 72, 2, 143}; + OSCMessage msg; + msg.fill(testBuffer, sizeof(testBuffer)); + assertEqual(msg.size(), 2); + assertFalse(msg.isInt(0)); + assertTrue(msg.isFloat(0)); + assertTrue(msg.isFloat(1)); + assertEqual(msg.getFloat(0), -1.0f); + assertEqual(msg.getFloat(1), 200.01f); +} + +test(message_decode_double){ + if (HAS_DOUBLE){ + uint8_t testBuffer[] = {47, 100, 0, 0, 44, 100, 0, 0, 64, 36, 5, 30, 184, 81, 235, 133}; + OSCMessage msg; + msg.fill(testBuffer, sizeof(testBuffer)); + double d = 10.01; + assertEqual(msg.size(), 1); + assertTrue(msg.isDouble(0)); + assertEqual(msg.getDouble(0), d); + } +} + +test(message_decode_string){ + uint8_t testBuffer[] = {47, 115, 116, 114, 105, 110, 103, 115, 0, 0, 0, 0, 44, 115, 115, 0, 104, 101, 121, 0, 104, 105, 0, 0}; + OSCMessage msg; + msg.fill(testBuffer, sizeof(testBuffer)); + assertEqual(msg.size(), 2); + assertTrue(msg.isString(0)); + assertTrue(msg.isString(1)); + char str[4]; + msg.getString(0, str, 5); + assertEqual(strcmp(str, "hey"), 0); + msg.getString(1, str, 3); + assertEqual(strcmp(str, "hi"), 0); +} + +test(message_decode_blob){ + uint8_t testBuffer[] = {47, 98, 0, 0, 44, 98, 0, 0, 0, 0, 0, 4, 0, 1, 2, 3}; + OSCMessage msg; + msg.fill(testBuffer, sizeof(testBuffer)); + assertEqual(msg.size(), 1); + assertTrue(msg.isBlob(0)); + uint8_t blob[4]; + msg.getBlob(0, blob, 4); + for (int i = 0; i < 4; i++){ + assertEqual(i, blob[i]); + } +} + +test(message_decode_mixed){ + uint8_t testBuffer[] = {47, 109, 105, 120, 101, 100, 0, 0, 44, 115, 105, 102, 0, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 1, 63, 128, 0, 0}; + OSCMessage msg; + msg.fill(testBuffer, sizeof(testBuffer)); + assertEqual(msg.size(), 3); + assertTrue(msg.isString(0)); + assertTrue(msg.isInt(1)); + assertTrue(msg.isFloat(2)); + assertEqual(msg.getInt(1), 1); + assertEqual(msg.getFloat(2), 1.0f); +} + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only +} + +void loop() +{ + Test::run(); +} diff --git a/lib/OSC/test/OSCMessage_encode_decode_test/TestPrint.h b/lib/OSC/test/OSCMessage_encode_decode_test/TestPrint.h new file mode 100644 index 0000000..2644f2d --- /dev/null +++ b/lib/OSC/test/OSCMessage_encode_decode_test/TestPrint.h @@ -0,0 +1,36 @@ + +/** + * A print class for testing the encoder + */ +class TestPrint : public Print { + + private: + //a small test buffer + uint8_t buffer[64]; + + //pointer to the current write spot + unsigned int bufferPointer; + + public: + + TestPrint(){ + bufferPointer = 0; + } + + size_t write(uint8_t character) { + buffer[bufferPointer++] = character; + return character; + } + + unsigned int size(){ + return bufferPointer; + } + + uint8_t at(int index){ + return buffer[index]; + } + + void clear(){ + bufferPointer = 0; + } +}; diff --git a/lib/OSC/test/OSCMessage_match_test/OSCMessage_match_test.ino b/lib/OSC/test/OSCMessage_match_test/OSCMessage_match_test.ino new file mode 100644 index 0000000..41aeddc --- /dev/null +++ b/lib/OSC/test/OSCMessage_match_test/OSCMessage_match_test.ino @@ -0,0 +1,86 @@ +#include +#include + + +test(message_address_match){ + OSCMessage msg("/a/0"); + assertEqual(msg.match("/a"), 2); + assertEqual(msg.match("/a/0"), 4); +} + +test(message_address_match_offset){ + OSCMessage msg("/a/0"); + assertEqual(msg.match("/0", 2), 2); + assertEqual(msg.match("/1", 2), 0); +} + +test(message_address_match_range){ + OSCMessage msg("/[a-z]/0"); + assertEqual(msg.match("/a"), 6); + assertEqual(msg.match("/b/0"), 8); +} + +test(message_address_match_or){ + OSCMessage msg("/{a,b}/0"); + assertEqual(msg.match("/a/0"), 8); + assertEqual(msg.match("/b/0"), 8); + assertEqual(msg.match("/c/0"), 0); +} + +test(message_address_match_char){ + OSCMessage msg("/a/?"); + assertEqual(msg.match("/a/0"), 4); + assertEqual(msg.match("/a/1"), 4); + assertEqual(msg.match("/a/10"), 0); +} + +test(message_address_match_star){ + OSCMessage msg("/a/*"); + assertEqual(msg.match("/a/0"), 4); + assertEqual(msg.match("/a/10"), 4); + assertEqual(msg.match("/a/100"), 4); +} + +test(message_address_fullMatch){ + OSCMessage msg("/a/0"); + assertTrue(msg.fullMatch("/a/0")); + assertFalse(msg.fullMatch("/a/1")); + assertTrue(msg.fullMatch("/0", 2)); +} + +void dispatchMsg(OSCMessage &m){ + assertTrue(m.isInt(0)); + assertEqual(m.getInt(0), 1); +} + +test(message_address_dispatch){ + OSCMessage msg("/a/[0-9]"); + msg.add(1); + assertTrue(msg.dispatch("/a/0", dispatchMsg)); + assertTrue(msg.dispatch("/1", dispatchMsg, 2)); +} + + +void routeMsg(OSCMessage &m, int offset){ + assertTrue(m.isInt(0)); + assertEqual(m.getInt(0), 2); + assertEqual(offset, 2); +} + +test(message_address_route){ + OSCMessage msg("/?/[0-9]"); + msg.add(2); + assertTrue(msg.route("/a", routeMsg)); + assertTrue(msg.route("/b", routeMsg)); +} + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only +} + +void loop() +{ + Test::run(); +} diff --git a/lib/OSC/test/OSCMessage_test/OSCMessage_test.ino b/lib/OSC/test/OSCMessage_test/OSCMessage_test.ino new file mode 100644 index 0000000..072ecac --- /dev/null +++ b/lib/OSC/test/OSCMessage_test/OSCMessage_test.ino @@ -0,0 +1,104 @@ +#include +#include + +#define HAS_DOUBLE sizeof(double) == 8 + + +test(message_address){ + OSCMessage msg("/hihi"); + char addr[6]; + msg.getAddress(addr); + assertEqual(strcmp(addr, "/hihi"), 0); +} + +test(message_address_offset){ + OSCMessage msg("/foo/bar"); + char addr[5]; + msg.getAddress(addr, 4); + assertEqual(strcmp(addr, "/bar"), 0); +} + +test(message_copy){ + OSCMessage msg("/hihi"); + msg.add(1); + OSCMessage cpy(&msg); + assertEqual(cpy.size(), 1); + assertTrue(cpy.isInt(0)); + assertEqual(cpy.getInt(0), 1); +} + +test(message_int){ + OSCMessage msg("/foo"); + msg.add(1); + assertTrue(msg.isInt(0)); + assertEqual(msg.getInt(0), 1); + assertEqual(msg.getDataLength(0), 4); +} + +test(message_float){ + OSCMessage msg("/foo"); + msg.add(1.0f); + assertTrue(msg.isFloat(0)); + assertEqual(msg.getFloat(0), 1.0f); + assertEqual(msg.getDataLength(0), 4); +} + +test(message_string){ + OSCMessage msg("/foo"); + msg.add("oh hi"); + assertTrue(msg.isString(0)); + char str[6]; + msg.getString(0, str, 6); + assertEqual(strcmp(str, "oh hi"), 0); + assertEqual(msg.getDataLength(0), 6); +} + +test(message_blob){ + OSCMessage msg("/foo"); + uint8_t b[] = {0, 1, 2, 3, 4}; + msg.add(b, 5); + assertTrue(msg.isBlob(0)); + uint8_t blob[5]; + msg.getBlob(0, blob, 5); + for (int i = 0; i < 5; i++){ + assertEqual(blob[i], b[i]); + } + //9 because it includes the 4 byte length + assertEqual(msg.getDataLength(0), 9); +} + +test(message_boolean){ + OSCMessage msg("/foo"); + msg.add(true); + assertTrue(msg.isBoolean(0)); + assertEqual(msg.getBoolean(0), true); + assertEqual(msg.getDataLength(0), 0); +} + +test(mixed_message_type){ + OSCMessage msg("/foo"); + msg.add(true); + msg.add(1.0f); + msg.add(2); + msg.add("test"); + assertEqual(msg.size(), 4); + assertEqual(msg.getType(0), 'T'); + assertTrue(msg.isBoolean(0)); + assertFalse(msg.isBoolean(1)); + assertTrue(msg.isFloat(1)); + assertTrue(msg.isInt(2)); + assertTrue(msg.isString(3)); + assertEqual(msg.getInt(2), 2); + assertEqual(msg.getInt(3), (int)NULL); +} + +void setup() +{ + Serial.begin(9600); + while(!Serial); // for the Arduino Leonardo/Micro only +} + +void loop() +{ + Test::run(); +} diff --git a/monitor.sh b/monitor.sh new file mode 100755 index 0000000..1185d93 --- /dev/null +++ b/monitor.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +source venv/bin/activate + +pio device monitor -b 115200 diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..d009352 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,33 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env] +platform = espressif32 +board = esp32-s2-saola-1 +framework = arduino + +[env:main] +build_src_filter = + + +lib_deps = + adafruit/Adafruit NeoPixel@^1.12.3 + +[env:sprejemnik] +board = esp32dev +build_src_filter = + + + +[env:kalibracija] +build_src_filter = + + + +[env:detect] +build_src_filter = + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c837717 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +platformio == 6.1.15 diff --git a/src/debug.cfg b/src/debug.cfg new file mode 100644 index 0000000..aa99b3e --- /dev/null +++ b/src/debug.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Example OpenOCD configuration file for ESP32-WROVER-KIT board. +# +# For example, OpenOCD can be started for ESP32 debugging on +# +# openocd -f board/esp32-wrover-kit-3.3v.cfg +# + +# Source the JTAG interface configuration file +source [find interface/ftdi/esp32_devkitj_v1.cfg] +set ESP32_FLASH_VOLTAGE 3.3 +# Source the ESP32 configuration file +source [find target/esp32.cfg] diff --git a/src/debug.svd b/src/debug.svd new file mode 100644 index 0000000..783023f --- /dev/null +++ b/src/debug.svd @@ -0,0 +1,46087 @@ + + + ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD. + ESPRESSIF + ESP32 + ESP32 + 8 + 32-bit MCU & 2.4 GHz Wi-Fi & Bluetooth/Bluetooth LE + + Copyright 2022 Espressif Systems (Shanghai) PTE LTD + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Xtensa LX6 + r0p0 + little + false + true + 3 + false + + 32 + 32 + 0x00000000 + 0xFFFFFFFF + + + AES + AES (Advanced Encryption Standard) Accelerator + AES + 0x3FF01000 + + 0x0 + 0x40 + registers + + + + START + 0x0 + 0x20 + + + START + Write 1 to start the AES operation. + 0 + 1 + write-only + + + + + IDLE + 0x4 + 0x20 + + + IDLE + AES Idle register. Reads ’zero’ while the AES Accelerator is busy processing; reads ’one’ otherwise. + 0 + 1 + read-only + + + + + MODE + 0x8 + 0x20 + + + MODE + Selects the AES accelerator mode of operation. See Table 22-1 for details. + 0 + 8 + read-write + + + + + 8 + 0x4 + KEY_%s + 0x10 + 0x20 + + + KEY + AES key material register. + 0 + 8 + read-write + + + + + 4 + 0x4 + TEXT_%s + 0x30 + 0x20 + + + TEXT + Plaintext and ciphertext register. + 0 + 8 + read-write + + + + + ENDIAN + 0x40 + 0x20 + + + ENDIAN + Endianness selection register. See Table 22-2 for details. + 0 + 2 + read-write + + + + + + + APB_CTRL + Advanced Peripheral Bus Controller + APB_CTRL + 0x3FF66000 + + 0x0 + 0x44 + registers + + + + SYSCLK_CONF + 0x0 + 0x20 + 0x00002000 + + + PRE_DIV_CNT + 0 + 10 + read-write + + + CLK_320M_EN + 10 + 1 + read-write + + + CLK_EN + 11 + 1 + read-write + + + RST_TICK_CNT + 12 + 1 + read-write + + + QUICK_CLK_CHNG + 13 + 1 + read-write + + + + + XTAL_TICK_CONF + 0x4 + 0x20 + 0x00000027 + + + XTAL_TICK_NUM + 0 + 8 + read-write + + + + + PLL_TICK_CONF + 0x8 + 0x20 + 0x0000004F + + + PLL_TICK_NUM + 0 + 8 + read-write + + + + + CK8M_TICK_CONF + 0xC + 0x20 + 0x0000000B + + + CK8M_TICK_NUM + 0 + 8 + read-write + + + + + APB_SARADC_CTRL + 0x10 + 0x20 + 0x007F8240 + + + SARADC_START_FORCE + 0 + 1 + read-write + + + SARADC_START + 1 + 1 + read-write + + + SARADC_SAR2_MUX + 1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL + 2 + 1 + read-write + + + SARADC_WORK_MODE + 0: single mode 1: double mode 2: alternate mode + 3 + 2 + read-write + + + SARADC_SAR_SEL + 0: SAR1 1: SAR2 only work for single SAR mode + 5 + 1 + read-write + + + SARADC_SAR_CLK_GATED + 6 + 1 + read-write + + + SARADC_SAR_CLK_DIV + SAR clock divider + 7 + 8 + read-write + + + SARADC_SAR1_PATT_LEN + 0 ~ 15 means length 1 ~ 16 + 15 + 4 + read-write + + + SARADC_SAR2_PATT_LEN + 0 ~ 15 means length 1 ~ 16 + 19 + 4 + read-write + + + SARADC_SAR1_PATT_P_CLEAR + clear the pointer of pattern table for DIG ADC1 CTRL + 23 + 1 + read-write + + + SARADC_SAR2_PATT_P_CLEAR + clear the pointer of pattern table for DIG ADC2 CTRL + 24 + 1 + read-write + + + SARADC_DATA_SAR_SEL + 1: sar_sel will be coded by the MSB of the 16-bit output data in this case the resolution should not be larger than 11 bits. + 25 + 1 + read-write + + + SARADC_DATA_TO_I2S + 1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix + 26 + 1 + read-write + + + + + APB_SARADC_CTRL2 + 0x14 + 0x20 + 0x000001FE + + + SARADC_MEAS_NUM_LIMIT + 0 + 1 + read-write + + + SARADC_MAX_MEAS_NUM + max conversion number + 1 + 8 + read-write + + + SARADC_SAR1_INV + 1: data to DIG ADC1 CTRL is inverted otherwise not + 9 + 1 + read-write + + + SARADC_SAR2_INV + 1: data to DIG ADC2 CTRL is inverted otherwise not + 10 + 1 + read-write + + + + + APB_SARADC_FSM + 0x18 + 0x20 + 0x0208FF08 + + + SARADC_RSTB_WAIT + 0 + 8 + read-write + + + SARADC_STANDBY_WAIT + 8 + 8 + read-write + + + SARADC_START_WAIT + 16 + 8 + read-write + + + SARADC_SAMPLE_CYCLE + sample cycles + 24 + 8 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB1 + 0x1C + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB1 + item 0 ~ 3 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB2 + 0x20 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB2 + Item 4 ~ 7 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB3 + 0x24 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB3 + Item 8 ~ 11 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR1_PATT_TAB4 + 0x28 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR1_PATT_TAB4 + Item 12 ~ 15 for pattern table 1 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB1 + 0x2C + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB1 + item 0 ~ 3 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB2 + 0x30 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB2 + Item 4 ~ 7 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB3 + 0x34 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB3 + Item 8 ~ 11 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APB_SARADC_SAR2_PATT_TAB4 + 0x38 + 0x20 + 0x0F0F0F0F + + + SARADC_SAR2_PATT_TAB4 + Item 12 ~ 15 for pattern table 2 (each item one byte) + 0 + 32 + read-write + + + + + APLL_TICK_CONF + 0x3C + 0x20 + 0x00000063 + + + APLL_TICK_NUM + 0 + 8 + read-write + + + + + DATE + 0x7C + 0x20 + 0x16042000 + + + DATE + 0 + 32 + read-write + + + + + + + BB + Peripheral BB + BB + 0x3FF5D000 + + 0x0 + 0x4 + registers + + + + BBPD_CTRL + Baseband control register + 0x54 + 0x20 + + + DC_EST_FORCE_PD + 0 + 1 + read-write + + + DC_EST_FORCE_PU + 1 + 1 + read-write + + + FFT_FORCE_PD + 2 + 1 + read-write + + + FFT_FORCE_PU + 3 + 1 + read-write + + + + + + + DPORT + Peripheral DPORT + DPORT + 0x3FF00000 + + 0x0 + 0x5C0 + registers + + + WIFI_MAC + 0 + + + WIFI_NMI + 1 + + + WIFI_BB + 2 + + + BT_MAC + 3 + + + BT_BB + 4 + + + BT_BB_NMI + 5 + + + RWBT + 6 + + + RWBLE + 7 + + + RWBT_NMI + 8 + + + RWBLE_NMI + 9 + + + + PRO_BOOT_REMAP_CTRL + 0x0 + 0x20 + + + PRO_BOOT_REMAP + 0 + 1 + read-write + + + + + APP_BOOT_REMAP_CTRL + 0x4 + 0x20 + + + APP_BOOT_REMAP + 0 + 1 + read-write + + + + + ACCESS_CHECK + 0x8 + 0x20 + + + PRO + 0 + 1 + read-only + + + APP + 8 + 1 + read-only + + + + + PRO_DPORT_APB_MASK0 + 0xC + 0x20 + + + PRODPORT_APB_MASK0 + 0 + 32 + read-write + + + + + PRO_DPORT_APB_MASK1 + 0x10 + 0x20 + + + PRODPORT_APB_MASK1 + 0 + 32 + read-write + + + + + APP_DPORT_APB_MASK0 + 0x14 + 0x20 + + + APPDPORT_APB_MASK0 + 0 + 32 + read-write + + + + + APP_DPORT_APB_MASK1 + 0x18 + 0x20 + + + APPDPORT_APB_MASK1 + 0 + 32 + read-write + + + + + PERI_CLK_EN + 0x1C + 0x20 + + + PERI_CLK_EN + 0 + 32 + read-write + + + + + PERI_RST_EN + 0x20 + 0x20 + + + PERI_RST_EN + 0 + 32 + read-write + + + + + WIFI_BB_CFG + 0x24 + 0x20 + + + WIFI_BB_CFG + 0 + 32 + read-write + + + + + WIFI_BB_CFG_2 + 0x28 + 0x20 + + + WIFI_BB_CFG_2 + 0 + 32 + read-write + + + + + APPCPU_CTRL_A + 0x2C + 0x20 + 0x00000001 + + + APPCPU_RESETTING + 0 + 1 + read-write + + + + + APPCPU_CTRL_B + 0x30 + 0x20 + + + APPCPU_CLKGATE_EN + 0 + 1 + read-write + + + + + APPCPU_CTRL_C + 0x34 + 0x20 + + + APPCPU_RUNSTALL + 0 + 1 + read-write + + + + + APPCPU_CTRL_D + 0x38 + 0x20 + + + APPCPU_BOOT_ADDR + 0 + 32 + read-write + + + + + CPU_PER_CONF + 0x3C + 0x20 + + + CPUPERIOD_SEL + 0 + 2 + read-write + + + LOWSPEED_CLK_SEL + 2 + 1 + read-write + + + FAST_CLK_RTC_SEL + 3 + 1 + read-write + + + + + PRO_CACHE_CTRL + 0x40 + 0x20 + 0x00000010 + + + PRO_CACHE_MODE + 2 + 1 + read-write + + + PRO_CACHE_ENABLE + 3 + 1 + read-write + + + PRO_CACHE_FLUSH_ENA + 4 + 1 + read-write + + + PRO_CACHE_FLUSH_DONE + 5 + 1 + read-only + + + PRO_CACHE_LOCK_0_EN + 6 + 1 + read-write + + + PRO_CACHE_LOCK_1_EN + 7 + 1 + read-write + + + PRO_CACHE_LOCK_2_EN + 8 + 1 + read-write + + + PRO_CACHE_LOCK_3_EN + 9 + 1 + read-write + + + PRO_SINGLE_IRAM_ENA + 10 + 1 + read-write + + + PRO_DRAM_SPLIT + 11 + 1 + read-write + + + PRO_AHB_SPI_REQ + 12 + 1 + read-only + + + PRO_SLAVE_REQ + 13 + 1 + read-only + + + AHB_SPI_REQ + 14 + 1 + read-only + + + SLAVE_REQ + 15 + 1 + read-only + + + PRO_DRAM_HL + 16 + 1 + read-write + + + + + PRO_CACHE_CTRL1 + 0x44 + 0x20 + 0x000008FF + + + PRO_CACHE_MASK_IRAM0 + 0 + 1 + read-write + + + PRO_CACHE_MASK_IRAM1 + 1 + 1 + read-write + + + PRO_CACHE_MASK_IROM0 + 2 + 1 + read-write + + + PRO_CACHE_MASK_DRAM1 + 3 + 1 + read-write + + + PRO_CACHE_MASK_DROM0 + 4 + 1 + read-write + + + PRO_CACHE_MASK_OPSDRAM + 5 + 1 + read-write + + + PRO_CMMU_SRAM_PAGE_MODE + 6 + 3 + read-write + + + PRO_CMMU_FLASH_PAGE_MODE + 9 + 2 + read-write + + + PRO_CMMU_FORCE_ON + 11 + 1 + read-write + + + PRO_CMMU_PD + 12 + 1 + read-write + + + PRO_CACHE_MMU_IA_CLR + 13 + 1 + read-write + + + + + PRO_CACHE_LOCK_0_ADDR + 0x48 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + PRO_CACHE_LOCK_1_ADDR + 0x4C + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + PRO_CACHE_LOCK_2_ADDR + 0x50 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + PRO_CACHE_LOCK_3_ADDR + 0x54 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_CTRL + 0x58 + 0x20 + 0x00000010 + + + APP_CACHE_MODE + 2 + 1 + read-write + + + APP_CACHE_ENABLE + 3 + 1 + read-write + + + APP_CACHE_FLUSH_ENA + 4 + 1 + read-write + + + APP_CACHE_FLUSH_DONE + 5 + 1 + read-only + + + APP_CACHE_LOCK_0_EN + 6 + 1 + read-write + + + APP_CACHE_LOCK_1_EN + 7 + 1 + read-write + + + APP_CACHE_LOCK_2_EN + 8 + 1 + read-write + + + APP_CACHE_LOCK_3_EN + 9 + 1 + read-write + + + APP_SINGLE_IRAM_ENA + 10 + 1 + read-write + + + APP_DRAM_SPLIT + 11 + 1 + read-write + + + APP_AHB_SPI_REQ + 12 + 1 + read-only + + + APP_SLAVE_REQ + 13 + 1 + read-only + + + APP_DRAM_HL + 14 + 1 + read-write + + + + + APP_CACHE_CTRL1 + 0x5C + 0x20 + 0x000008FF + + + APP_CACHE_MASK_IRAM0 + 0 + 1 + read-write + + + APP_CACHE_MASK_IRAM1 + 1 + 1 + read-write + + + APP_CACHE_MASK_IROM0 + 2 + 1 + read-write + + + APP_CACHE_MASK_DRAM1 + 3 + 1 + read-write + + + APP_CACHE_MASK_DROM0 + 4 + 1 + read-write + + + APP_CACHE_MASK_OPSDRAM + 5 + 1 + read-write + + + APP_CMMU_SRAM_PAGE_MODE + 6 + 3 + read-write + + + APP_CMMU_FLASH_PAGE_MODE + 9 + 2 + read-write + + + APP_CMMU_FORCE_ON + 11 + 1 + read-write + + + APP_CMMU_PD + 12 + 1 + read-write + + + APP_CACHE_MMU_IA_CLR + 13 + 1 + read-write + + + + + APP_CACHE_LOCK_0_ADDR + 0x60 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_LOCK_1_ADDR + 0x64 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_LOCK_2_ADDR + 0x68 + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + APP_CACHE_LOCK_3_ADDR + 0x6C + 0x20 + + + PRE + 0 + 14 + read-write + + + MIN + 14 + 4 + read-write + + + MAX + 18 + 4 + read-write + + + + + TRACEMEM_MUX_MODE + 0x70 + 0x20 + + + TRACEMEM_MUX_MODE + 0 + 2 + read-write + + + + + PRO_TRACEMEM_ENA + 0x74 + 0x20 + + + PRO_TRACEMEM_ENA + 0 + 1 + read-write + + + + + APP_TRACEMEM_ENA + 0x78 + 0x20 + + + APP_TRACEMEM_ENA + 0 + 1 + read-write + + + + + CACHE_MUX_MODE + 0x7C + 0x20 + + + CACHE_MUX_MODE + 0 + 2 + read-write + + + + + IMMU_PAGE_MODE + 0x80 + 0x20 + + + INTERNAL_SRAM_IMMU_ENA + 0 + 1 + read-write + + + IMMU_PAGE_MODE + 1 + 2 + read-write + + + + + DMMU_PAGE_MODE + 0x84 + 0x20 + + + INTERNAL_SRAM_DMMU_ENA + 0 + 1 + read-write + + + DMMU_PAGE_MODE + 1 + 2 + read-write + + + + + ROM_MPU_ENA + 0x88 + 0x20 + + + SHARE_ROM_MPU_ENA + 0 + 1 + read-write + + + PRO_ROM_MPU_ENA + 1 + 1 + read-write + + + APP_ROM_MPU_ENA + 2 + 1 + read-write + + + + + MEM_PD_MASK + 0x8C + 0x20 + 0x00000001 + + + LSLP_MEM_PD_MASK + 0 + 1 + read-write + + + + + ROM_PD_CTRL + 0x90 + 0x20 + + + PRO_ROM_PD + 0 + 1 + read-write + + + APP_ROM_PD + 1 + 1 + read-write + + + SHARE_ROM_PD + 2 + 6 + read-write + + + + + ROM_FO_CTRL + 0x94 + 0x20 + 0x00000003 + + + PRO_ROM_FO + 0 + 1 + read-write + + + APP_ROM_FO + 1 + 1 + read-write + + + SHARE_ROM_FO + 2 + 6 + read-write + + + + + SRAM_PD_CTRL_0 + 0x98 + 0x20 + + + SRAM_PD_0 + 0 + 32 + read-write + + + + + SRAM_PD_CTRL_1 + 0x9C + 0x20 + + + SRAM_PD_1 + 0 + 1 + read-write + + + + + SRAM_FO_CTRL_0 + 0xA0 + 0x20 + 0xFFFFFFFF + + + SRAM_FO_0 + 0 + 32 + read-write + + + + + SRAM_FO_CTRL_1 + 0xA4 + 0x20 + 0x00000001 + + + SRAM_FO_1 + 0 + 1 + read-write + + + + + IRAM_DRAM_AHB_SEL + 0xA8 + 0x20 + + + MASK_PRO_IRAM + 0 + 1 + read-write + + + MASK_APP_IRAM + 1 + 1 + read-write + + + MASK_PRO_DRAM + 2 + 1 + read-write + + + MASK_APP_DRAM + 3 + 1 + read-write + + + MASK_AHB + 4 + 1 + read-write + + + MAC_DUMP_MODE + 5 + 2 + read-write + + + + + TAG_FO_CTRL + 0xAC + 0x20 + 0x00000101 + + + PRO_CACHE_TAG_FORCE_ON + 0 + 1 + read-write + + + PRO_CACHE_TAG_PD + 1 + 1 + read-write + + + APP_CACHE_TAG_FORCE_ON + 8 + 1 + read-write + + + APP_CACHE_TAG_PD + 9 + 1 + read-write + + + + + AHB_LITE_MASK + 0xB0 + 0x20 + + + PRO + 0 + 1 + read-write + + + APP + 4 + 1 + read-write + + + SDIO + 8 + 1 + read-write + + + PRODPORT + 9 + 1 + read-write + + + APPDPORT + 10 + 1 + read-write + + + AHB_LITE_SDHOST_PID + 11 + 3 + read-write + + + + + AHB_MPU_TABLE_0 + 0xB4 + 0x20 + 0xFFFFFFFF + + + AHB_ACCESS_GRANT_0 + 0 + 32 + read-write + + + + + AHB_MPU_TABLE_1 + 0xB8 + 0x20 + 0x000001FF + + + AHB_ACCESS_GRANT_1 + 0 + 9 + read-write + + + + + HOST_INF_SEL + 0xBC + 0x20 + + + PERI_IO_SWAP + 0 + 8 + read-write + + + LINK_DEVICE_SEL + 8 + 8 + read-write + + + + + PERIP_CLK_EN + 0xC0 + 0x20 + 0xF9C1E06F + + + TIMERS_CLK_EN + 0 + 1 + read-write + + + SPI01_CLK_EN + 1 + 1 + read-write + + + UART_CLK_EN + 2 + 1 + read-write + + + WDG_CLK_EN + 3 + 1 + read-write + + + I2S0_CLK_EN + 4 + 1 + read-write + + + UART1_CLK_EN + 5 + 1 + read-write + + + SPI2_CLK_EN + 6 + 1 + read-write + + + I2C0_EXT0_CLK_EN + 7 + 1 + read-write + + + UHCI0_CLK_EN + 8 + 1 + read-write + + + RMT_CLK_EN + 9 + 1 + read-write + + + PCNT_CLK_EN + 10 + 1 + read-write + + + LEDC_CLK_EN + 11 + 1 + read-write + + + UHCI1_CLK_EN + 12 + 1 + read-write + + + TIMERGROUP_CLK_EN + 13 + 1 + read-write + + + EFUSE_CLK_EN + 14 + 1 + read-write + + + TIMERGROUP1_CLK_EN + 15 + 1 + read-write + + + SPI3_CLK_EN + 16 + 1 + read-write + + + PWM0_CLK_EN + 17 + 1 + read-write + + + I2C_EXT1_CLK_EN + 18 + 1 + read-write + + + TWAI_CLK_EN + 19 + 1 + read-write + + + PWM1_CLK_EN + 20 + 1 + read-write + + + I2S1_CLK_EN + 21 + 1 + read-write + + + SPI_DMA_CLK_EN + 22 + 1 + read-write + + + UART2_CLK_EN + 23 + 1 + read-write + + + UART_MEM_CLK_EN + 24 + 1 + read-write + + + PWM2_CLK_EN + 25 + 1 + read-write + + + PWM3_CLK_EN + 26 + 1 + read-write + + + + + PERIP_RST_EN + 0xC4 + 0x20 + + + TIMERS_RST + 0 + 1 + read-write + + + SPI01_RST + 1 + 1 + read-write + + + UART_RST + 2 + 1 + read-write + + + WDG_RST + 3 + 1 + read-write + + + I2S0_RST + 4 + 1 + read-write + + + UART1_RST + 5 + 1 + read-write + + + SPI2_RST + 6 + 1 + read-write + + + I2C0_EXT0_RST + 7 + 1 + read-write + + + UHCI0_RST + 8 + 1 + read-write + + + RMT_RST + 9 + 1 + read-write + + + PCNT_RST + 10 + 1 + read-write + + + LEDC_RST + 11 + 1 + read-write + + + UHCI1_RST + 12 + 1 + read-write + + + TIMERGROUP_RST + 13 + 1 + read-write + + + EFUSE_RST + 14 + 1 + read-write + + + TIMERGROUP1_RST + 15 + 1 + read-write + + + SPI3_RST + 16 + 1 + read-write + + + PWM0_RST + 17 + 1 + read-write + + + I2C_EXT1_RST + 18 + 1 + read-write + + + TWAI_RST + 19 + 1 + read-write + + + PWM1_RST + 20 + 1 + read-write + + + I2S1_RST + 21 + 1 + read-write + + + SPI_DMA_RST + 22 + 1 + read-write + + + UART2_RST + 23 + 1 + read-write + + + UART_MEM_RST + 24 + 1 + read-write + + + PWM2_RST + 25 + 1 + read-write + + + PWM3_RST + 26 + 1 + read-write + + + + + SLAVE_SPI_CONFIG + 0xC8 + 0x20 + + + SLAVE_SPI_MASK_PRO + 0 + 1 + read-write + + + SLAVE_SPI_MASK_APP + 4 + 1 + read-write + + + SPI_ENCRYPT_ENABLE + 8 + 1 + read-write + + + SPI_DECRYPT_ENABLE + 12 + 1 + read-write + + + + + WIFI_CLK_EN + 0xCC + 0x20 + 0xFFFCE030 + + + WIFI_CLK_EN + 0 + 32 + read-write + + + WIFI_CLK_WIFI_EN + 0 + 3 + read-write + + + WIFI_CLK_WIFI_BT_COMMON + 0 + 6 + read-write + + + WIFI_CLK_BT_EN + 11 + 3 + read-write + + + + + CORE_RST_EN + 0xD0 + 0x20 + + + CORE_RST + 0 + 8 + read-write + + + BB_RST + 0 + 1 + read-write + + + FE_RST + 1 + 1 + read-write + + + MAC_RST + 2 + 1 + read-write + + + BT_RST + 3 + 1 + read-write + + + BTMAC_RST + 4 + 1 + read-write + + + SDIO_RST + 5 + 1 + read-write + + + SDIO_HOST_RST + 6 + 1 + read-write + + + EMAC_RST + 7 + 1 + read-write + + + MACPWR_RST + 8 + 1 + read-write + + + RW_BTMAC_RST + 9 + 1 + read-write + + + RW_BTLP_RST + 10 + 1 + read-write + + + + + BT_LPCK_DIV_INT + 0xD4 + 0x20 + 0x000000FF + + + BT_LPCK_DIV_NUM + 0 + 12 + read-write + + + BTEXTWAKEUP_REQ + 12 + 1 + read-write + + + + + BT_LPCK_DIV_FRAC + 0xD8 + 0x20 + 0x02001001 + + + BT_LPCK_DIV_B + 0 + 12 + read-write + + + BT_LPCK_DIV_A + 12 + 12 + read-write + + + LPCLK_SEL_RTC_SLOW + 24 + 1 + read-write + + + LPCLK_SEL_8M + 25 + 1 + read-write + + + LPCLK_SEL_XTAL + 26 + 1 + read-write + + + LPCLK_SEL_XTAL32K + 27 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_0 + 0xDC + 0x20 + + + CPU_INTR_FROM_CPU_0 + 0 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_1 + 0xE0 + 0x20 + + + CPU_INTR_FROM_CPU_1 + 0 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_2 + 0xE4 + 0x20 + + + CPU_INTR_FROM_CPU_2 + 0 + 1 + read-write + + + + + CPU_INTR_FROM_CPU_3 + 0xE8 + 0x20 + + + CPU_INTR_FROM_CPU_3 + 0 + 1 + read-write + + + + + PRO_INTR_STATUS_0 + 0xEC + 0x20 + + + PRO_INTR_STATUS_0 + 0 + 32 + read-only + + + + + PRO_INTR_STATUS_1 + 0xF0 + 0x20 + + + PRO_INTR_STATUS_1 + 0 + 32 + read-only + + + + + PRO_INTR_STATUS_2 + 0xF4 + 0x20 + + + PRO_INTR_STATUS_2 + 0 + 32 + read-only + + + + + APP_INTR_STATUS_0 + 0xF8 + 0x20 + + + APP_INTR_STATUS_0 + 0 + 32 + read-only + + + + + APP_INTR_STATUS_1 + 0xFC + 0x20 + + + APP_INTR_STATUS_1 + 0 + 32 + read-only + + + + + APP_INTR_STATUS_2 + 0x100 + 0x20 + + + APP_INTR_STATUS_2 + 0 + 32 + read-only + + + + + PRO_MAC_INTR_MAP + 0x104 + 0x20 + 0x00000010 + + + PRO_MAC_INTR_MAP + 0 + 5 + read-write + + + + + PRO_MAC_NMI_MAP + 0x108 + 0x20 + 0x00000010 + + + PRO_MAC_NMI_MAP + 0 + 5 + read-write + + + + + PRO_BB_INT_MAP + 0x10C + 0x20 + 0x00000010 + + + PRO_BB_INT_MAP + 0 + 5 + read-write + + + + + PRO_BT_MAC_INT_MAP + 0x110 + 0x20 + 0x00000010 + + + PRO_BT_MAC_INT_MAP + 0 + 5 + read-write + + + + + PRO_BT_BB_INT_MAP + 0x114 + 0x20 + 0x00000010 + + + PRO_BT_BB_INT_MAP + 0 + 5 + read-write + + + + + PRO_BT_BB_NMI_MAP + 0x118 + 0x20 + 0x00000010 + + + PRO_BT_BB_NMI_MAP + 0 + 5 + read-write + + + + + PRO_RWBT_IRQ_MAP + 0x11C + 0x20 + 0x00000010 + + + PRO_RWBT_IRQ_MAP + 0 + 5 + read-write + + + + + PRO_RWBLE_IRQ_MAP + 0x120 + 0x20 + 0x00000010 + + + PRO_RWBLE_IRQ_MAP + 0 + 5 + read-write + + + + + PRO_RWBT_NMI_MAP + 0x124 + 0x20 + 0x00000010 + + + PRO_RWBT_NMI_MAP + 0 + 5 + read-write + + + + + PRO_RWBLE_NMI_MAP + 0x128 + 0x20 + 0x00000010 + + + PRO_RWBLE_NMI_MAP + 0 + 5 + read-write + + + + + PRO_SLC0_INTR_MAP + 0x12C + 0x20 + 0x00000010 + + + PRO_SLC0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_SLC1_INTR_MAP + 0x130 + 0x20 + 0x00000010 + + + PRO_SLC1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UHCI0_INTR_MAP + 0x134 + 0x20 + 0x00000010 + + + PRO_UHCI0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UHCI1_INTR_MAP + 0x138 + 0x20 + 0x00000010 + + + PRO_UHCI1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_TG_T0_LEVEL_INT_MAP + 0x13C + 0x20 + 0x00000010 + + + PRO_TG_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_T1_LEVEL_INT_MAP + 0x140 + 0x20 + 0x00000010 + + + PRO_TG_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_WDT_LEVEL_INT_MAP + 0x144 + 0x20 + 0x00000010 + + + PRO_TG_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_LACT_LEVEL_INT_MAP + 0x148 + 0x20 + 0x00000010 + + + PRO_TG_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T0_LEVEL_INT_MAP + 0x14C + 0x20 + 0x00000010 + + + PRO_TG1_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T1_LEVEL_INT_MAP + 0x150 + 0x20 + 0x00000010 + + + PRO_TG1_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_WDT_LEVEL_INT_MAP + 0x154 + 0x20 + 0x00000010 + + + PRO_TG1_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_LACT_LEVEL_INT_MAP + 0x158 + 0x20 + 0x00000010 + + + PRO_TG1_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + PRO_GPIO_INTERRUPT_MAP + 0x15C + 0x20 + 0x00000010 + + + PRO_GPIO_INTERRUPT_PRO_MAP + 0 + 5 + read-write + + + + + PRO_GPIO_INTERRUPT_NMI_MAP + 0x160 + 0x20 + 0x00000010 + + + PRO_GPIO_INTERRUPT_PRO_NMI_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_0_MAP + 0x164 + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_0_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_1_MAP + 0x168 + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_1_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_2_MAP + 0x16C + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_2_MAP + 0 + 5 + read-write + + + + + PRO_CPU_INTR_FROM_CPU_3_MAP + 0x170 + 0x20 + 0x00000010 + + + PRO_CPU_INTR_FROM_CPU_3_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_0_MAP + 0x174 + 0x20 + 0x00000010 + + + PRO_SPI_INTR_0_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_1_MAP + 0x178 + 0x20 + 0x00000010 + + + PRO_SPI_INTR_1_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_2_MAP + 0x17C + 0x20 + 0x00000010 + + + PRO_SPI_INTR_2_MAP + 0 + 5 + read-write + + + + + PRO_SPI_INTR_3_MAP + 0x180 + 0x20 + 0x00000010 + + + PRO_SPI_INTR_3_MAP + 0 + 5 + read-write + + + + + PRO_I2S0_INT_MAP + 0x184 + 0x20 + 0x00000010 + + + PRO_I2S0_INT_MAP + 0 + 5 + read-write + + + + + PRO_I2S1_INT_MAP + 0x188 + 0x20 + 0x00000010 + + + PRO_I2S1_INT_MAP + 0 + 5 + read-write + + + + + PRO_UART_INTR_MAP + 0x18C + 0x20 + 0x00000010 + + + PRO_UART_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UART1_INTR_MAP + 0x190 + 0x20 + 0x00000010 + + + PRO_UART1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_UART2_INTR_MAP + 0x194 + 0x20 + 0x00000010 + + + PRO_UART2_INTR_MAP + 0 + 5 + read-write + + + + + PRO_SDIO_HOST_INTERRUPT_MAP + 0x198 + 0x20 + 0x00000010 + + + PRO_SDIO_HOST_INTERRUPT_MAP + 0 + 5 + read-write + + + + + PRO_EMAC_INT_MAP + 0x19C + 0x20 + 0x00000010 + + + PRO_EMAC_INT_MAP + 0 + 5 + read-write + + + + + PRO_PWM0_INTR_MAP + 0x1A0 + 0x20 + 0x00000010 + + + PRO_PWM0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PWM1_INTR_MAP + 0x1A4 + 0x20 + 0x00000010 + + + PRO_PWM1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PWM2_INTR_MAP + 0x1A8 + 0x20 + 0x00000010 + + + PRO_PWM2_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PWM3_INTR_MAP + 0x1AC + 0x20 + 0x00000010 + + + PRO_PWM3_INTR_MAP + 0 + 5 + read-write + + + + + PRO_LEDC_INT_MAP + 0x1B0 + 0x20 + 0x00000010 + + + PRO_LEDC_INT_MAP + 0 + 5 + read-write + + + + + PRO_EFUSE_INT_MAP + 0x1B4 + 0x20 + 0x00000010 + + + PRO_EFUSE_INT_MAP + 0 + 5 + read-write + + + + + PRO_CAN_INT_MAP + 0x1B8 + 0x20 + 0x00000010 + + + PRO_CAN_INT_MAP + 0 + 5 + read-write + + + + + PRO_RTC_CORE_INTR_MAP + 0x1BC + 0x20 + 0x00000010 + + + PRO_RTC_CORE_INTR_MAP + 0 + 5 + read-write + + + + + PRO_RMT_INTR_MAP + 0x1C0 + 0x20 + 0x00000010 + + + PRO_RMT_INTR_MAP + 0 + 5 + read-write + + + + + PRO_PCNT_INTR_MAP + 0x1C4 + 0x20 + 0x00000010 + + + PRO_PCNT_INTR_MAP + 0 + 5 + read-write + + + + + PRO_I2C_EXT0_INTR_MAP + 0x1C8 + 0x20 + 0x00000010 + + + PRO_I2C_EXT0_INTR_MAP + 0 + 5 + read-write + + + + + PRO_I2C_EXT1_INTR_MAP + 0x1CC + 0x20 + 0x00000010 + + + PRO_I2C_EXT1_INTR_MAP + 0 + 5 + read-write + + + + + PRO_RSA_INTR_MAP + 0x1D0 + 0x20 + 0x00000010 + + + PRO_RSA_INTR_MAP + 0 + 5 + read-write + + + + + PRO_SPI1_DMA_INT_MAP + 0x1D4 + 0x20 + 0x00000010 + + + PRO_SPI1_DMA_INT_MAP + 0 + 5 + read-write + + + + + PRO_SPI2_DMA_INT_MAP + 0x1D8 + 0x20 + 0x00000010 + + + PRO_SPI2_DMA_INT_MAP + 0 + 5 + read-write + + + + + PRO_SPI3_DMA_INT_MAP + 0x1DC + 0x20 + 0x00000010 + + + PRO_SPI3_DMA_INT_MAP + 0 + 5 + read-write + + + + + PRO_WDG_INT_MAP + 0x1E0 + 0x20 + 0x00000010 + + + PRO_WDG_INT_MAP + 0 + 5 + read-write + + + + + PRO_TIMER_INT1_MAP + 0x1E4 + 0x20 + 0x00000010 + + + PRO_TIMER_INT1_MAP + 0 + 5 + read-write + + + + + PRO_TIMER_INT2_MAP + 0x1E8 + 0x20 + 0x00000010 + + + PRO_TIMER_INT2_MAP + 0 + 5 + read-write + + + + + PRO_TG_T0_EDGE_INT_MAP + 0x1EC + 0x20 + 0x00000010 + + + PRO_TG_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_T1_EDGE_INT_MAP + 0x1F0 + 0x20 + 0x00000010 + + + PRO_TG_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_WDT_EDGE_INT_MAP + 0x1F4 + 0x20 + 0x00000010 + + + PRO_TG_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG_LACT_EDGE_INT_MAP + 0x1F8 + 0x20 + 0x00000010 + + + PRO_TG_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T0_EDGE_INT_MAP + 0x1FC + 0x20 + 0x00000010 + + + PRO_TG1_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_T1_EDGE_INT_MAP + 0x200 + 0x20 + 0x00000010 + + + PRO_TG1_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_WDT_EDGE_INT_MAP + 0x204 + 0x20 + 0x00000010 + + + PRO_TG1_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_TG1_LACT_EDGE_INT_MAP + 0x208 + 0x20 + 0x00000010 + + + PRO_TG1_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + PRO_MMU_IA_INT_MAP + 0x20C + 0x20 + 0x00000010 + + + PRO_MMU_IA_INT_MAP + 0 + 5 + read-write + + + + + PRO_MPU_IA_INT_MAP + 0x210 + 0x20 + 0x00000010 + + + PRO_MPU_IA_INT_MAP + 0 + 5 + read-write + + + + + PRO_CACHE_IA_INT_MAP + 0x214 + 0x20 + 0x00000010 + + + PRO_CACHE_IA_INT_MAP + 0 + 5 + read-write + + + + + APP_MAC_INTR_MAP + 0x218 + 0x20 + 0x00000010 + + + APP_MAC_INTR_MAP + 0 + 5 + read-write + + + + + APP_MAC_NMI_MAP + 0x21C + 0x20 + 0x00000010 + + + APP_MAC_NMI_MAP + 0 + 5 + read-write + + + + + APP_BB_INT_MAP + 0x220 + 0x20 + 0x00000010 + + + APP_BB_INT_MAP + 0 + 5 + read-write + + + + + APP_BT_MAC_INT_MAP + 0x224 + 0x20 + 0x00000010 + + + APP_BT_MAC_INT_MAP + 0 + 5 + read-write + + + + + APP_BT_BB_INT_MAP + 0x228 + 0x20 + 0x00000010 + + + APP_BT_BB_INT_MAP + 0 + 5 + read-write + + + + + APP_BT_BB_NMI_MAP + 0x22C + 0x20 + 0x00000010 + + + APP_BT_BB_NMI_MAP + 0 + 5 + read-write + + + + + APP_RWBT_IRQ_MAP + 0x230 + 0x20 + 0x00000010 + + + APP_RWBT_IRQ_MAP + 0 + 5 + read-write + + + + + APP_RWBLE_IRQ_MAP + 0x234 + 0x20 + 0x00000010 + + + APP_RWBLE_IRQ_MAP + 0 + 5 + read-write + + + + + APP_RWBT_NMI_MAP + 0x238 + 0x20 + 0x00000010 + + + APP_RWBT_NMI_MAP + 0 + 5 + read-write + + + + + APP_RWBLE_NMI_MAP + 0x23C + 0x20 + 0x00000010 + + + APP_RWBLE_NMI_MAP + 0 + 5 + read-write + + + + + APP_SLC0_INTR_MAP + 0x240 + 0x20 + 0x00000010 + + + APP_SLC0_INTR_MAP + 0 + 5 + read-write + + + + + APP_SLC1_INTR_MAP + 0x244 + 0x20 + 0x00000010 + + + APP_SLC1_INTR_MAP + 0 + 5 + read-write + + + + + APP_UHCI0_INTR_MAP + 0x248 + 0x20 + 0x00000010 + + + APP_UHCI0_INTR_MAP + 0 + 5 + read-write + + + + + APP_UHCI1_INTR_MAP + 0x24C + 0x20 + 0x00000010 + + + APP_UHCI1_INTR_MAP + 0 + 5 + read-write + + + + + APP_TG_T0_LEVEL_INT_MAP + 0x250 + 0x20 + 0x00000010 + + + APP_TG_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_T1_LEVEL_INT_MAP + 0x254 + 0x20 + 0x00000010 + + + APP_TG_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_WDT_LEVEL_INT_MAP + 0x258 + 0x20 + 0x00000010 + + + APP_TG_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_LACT_LEVEL_INT_MAP + 0x25C + 0x20 + 0x00000010 + + + APP_TG_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T0_LEVEL_INT_MAP + 0x260 + 0x20 + 0x00000010 + + + APP_TG1_T0_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T1_LEVEL_INT_MAP + 0x264 + 0x20 + 0x00000010 + + + APP_TG1_T1_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_WDT_LEVEL_INT_MAP + 0x268 + 0x20 + 0x00000010 + + + APP_TG1_WDT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_LACT_LEVEL_INT_MAP + 0x26C + 0x20 + 0x00000010 + + + APP_TG1_LACT_LEVEL_INT_MAP + 0 + 5 + read-write + + + + + APP_GPIO_INTERRUPT_MAP + 0x270 + 0x20 + 0x00000010 + + + APP_GPIO_INTERRUPT_APP_MAP + 0 + 5 + read-write + + + + + APP_GPIO_INTERRUPT_NMI_MAP + 0x274 + 0x20 + 0x00000010 + + + APP_GPIO_INTERRUPT_APP_NMI_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_0_MAP + 0x278 + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_0_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_1_MAP + 0x27C + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_1_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_2_MAP + 0x280 + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_2_MAP + 0 + 5 + read-write + + + + + APP_CPU_INTR_FROM_CPU_3_MAP + 0x284 + 0x20 + 0x00000010 + + + APP_CPU_INTR_FROM_CPU_3_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_0_MAP + 0x288 + 0x20 + 0x00000010 + + + APP_SPI_INTR_0_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_1_MAP + 0x28C + 0x20 + 0x00000010 + + + APP_SPI_INTR_1_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_2_MAP + 0x290 + 0x20 + 0x00000010 + + + APP_SPI_INTR_2_MAP + 0 + 5 + read-write + + + + + APP_SPI_INTR_3_MAP + 0x294 + 0x20 + 0x00000010 + + + APP_SPI_INTR_3_MAP + 0 + 5 + read-write + + + + + APP_I2S0_INT_MAP + 0x298 + 0x20 + 0x00000010 + + + APP_I2S0_INT_MAP + 0 + 5 + read-write + + + + + APP_I2S1_INT_MAP + 0x29C + 0x20 + 0x00000010 + + + APP_I2S1_INT_MAP + 0 + 5 + read-write + + + + + APP_UART_INTR_MAP + 0x2A0 + 0x20 + 0x00000010 + + + APP_UART_INTR_MAP + 0 + 5 + read-write + + + + + APP_UART1_INTR_MAP + 0x2A4 + 0x20 + 0x00000010 + + + APP_UART1_INTR_MAP + 0 + 5 + read-write + + + + + APP_UART2_INTR_MAP + 0x2A8 + 0x20 + 0x00000010 + + + APP_UART2_INTR_MAP + 0 + 5 + read-write + + + + + APP_SDIO_HOST_INTERRUPT_MAP + 0x2AC + 0x20 + 0x00000010 + + + APP_SDIO_HOST_INTERRUPT_MAP + 0 + 5 + read-write + + + + + APP_EMAC_INT_MAP + 0x2B0 + 0x20 + 0x00000010 + + + APP_EMAC_INT_MAP + 0 + 5 + read-write + + + + + APP_PWM0_INTR_MAP + 0x2B4 + 0x20 + 0x00000010 + + + APP_PWM0_INTR_MAP + 0 + 5 + read-write + + + + + APP_PWM1_INTR_MAP + 0x2B8 + 0x20 + 0x00000010 + + + APP_PWM1_INTR_MAP + 0 + 5 + read-write + + + + + APP_PWM2_INTR_MAP + 0x2BC + 0x20 + 0x00000010 + + + APP_PWM2_INTR_MAP + 0 + 5 + read-write + + + + + APP_PWM3_INTR_MAP + 0x2C0 + 0x20 + 0x00000010 + + + APP_PWM3_INTR_MAP + 0 + 5 + read-write + + + + + APP_LEDC_INT_MAP + 0x2C4 + 0x20 + 0x00000010 + + + APP_LEDC_INT_MAP + 0 + 5 + read-write + + + + + APP_EFUSE_INT_MAP + 0x2C8 + 0x20 + 0x00000010 + + + APP_EFUSE_INT_MAP + 0 + 5 + read-write + + + + + APP_CAN_INT_MAP + 0x2CC + 0x20 + 0x00000010 + + + APP_CAN_INT_MAP + 0 + 5 + read-write + + + + + APP_RTC_CORE_INTR_MAP + 0x2D0 + 0x20 + 0x00000010 + + + APP_RTC_CORE_INTR_MAP + 0 + 5 + read-write + + + + + APP_RMT_INTR_MAP + 0x2D4 + 0x20 + 0x00000010 + + + APP_RMT_INTR_MAP + 0 + 5 + read-write + + + + + APP_PCNT_INTR_MAP + 0x2D8 + 0x20 + 0x00000010 + + + APP_PCNT_INTR_MAP + 0 + 5 + read-write + + + + + APP_I2C_EXT0_INTR_MAP + 0x2DC + 0x20 + 0x00000010 + + + APP_I2C_EXT0_INTR_MAP + 0 + 5 + read-write + + + + + APP_I2C_EXT1_INTR_MAP + 0x2E0 + 0x20 + 0x00000010 + + + APP_I2C_EXT1_INTR_MAP + 0 + 5 + read-write + + + + + APP_RSA_INTR_MAP + 0x2E4 + 0x20 + 0x00000010 + + + APP_RSA_INTR_MAP + 0 + 5 + read-write + + + + + APP_SPI1_DMA_INT_MAP + 0x2E8 + 0x20 + 0x00000010 + + + APP_SPI1_DMA_INT_MAP + 0 + 5 + read-write + + + + + APP_SPI2_DMA_INT_MAP + 0x2EC + 0x20 + 0x00000010 + + + APP_SPI2_DMA_INT_MAP + 0 + 5 + read-write + + + + + APP_SPI3_DMA_INT_MAP + 0x2F0 + 0x20 + 0x00000010 + + + APP_SPI3_DMA_INT_MAP + 0 + 5 + read-write + + + + + APP_WDG_INT_MAP + 0x2F4 + 0x20 + 0x00000010 + + + APP_WDG_INT_MAP + 0 + 5 + read-write + + + + + APP_TIMER_INT1_MAP + 0x2F8 + 0x20 + 0x00000010 + + + APP_TIMER_INT1_MAP + 0 + 5 + read-write + + + + + APP_TIMER_INT2_MAP + 0x2FC + 0x20 + 0x00000010 + + + APP_TIMER_INT2_MAP + 0 + 5 + read-write + + + + + APP_TG_T0_EDGE_INT_MAP + 0x300 + 0x20 + 0x00000010 + + + APP_TG_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_T1_EDGE_INT_MAP + 0x304 + 0x20 + 0x00000010 + + + APP_TG_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_WDT_EDGE_INT_MAP + 0x308 + 0x20 + 0x00000010 + + + APP_TG_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG_LACT_EDGE_INT_MAP + 0x30C + 0x20 + 0x00000010 + + + APP_TG_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T0_EDGE_INT_MAP + 0x310 + 0x20 + 0x00000010 + + + APP_TG1_T0_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_T1_EDGE_INT_MAP + 0x314 + 0x20 + 0x00000010 + + + APP_TG1_T1_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_WDT_EDGE_INT_MAP + 0x318 + 0x20 + 0x00000010 + + + APP_TG1_WDT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_TG1_LACT_EDGE_INT_MAP + 0x31C + 0x20 + 0x00000010 + + + APP_TG1_LACT_EDGE_INT_MAP + 0 + 5 + read-write + + + + + APP_MMU_IA_INT_MAP + 0x320 + 0x20 + 0x00000010 + + + APP_MMU_IA_INT_MAP + 0 + 5 + read-write + + + + + APP_MPU_IA_INT_MAP + 0x324 + 0x20 + 0x00000010 + + + APP_MPU_IA_INT_MAP + 0 + 5 + read-write + + + + + APP_CACHE_IA_INT_MAP + 0x328 + 0x20 + 0x00000010 + + + APP_CACHE_IA_INT_MAP + 0 + 5 + read-write + + + + + AHBLITE_MPU_TABLE_UART + 0x32C + 0x20 + + + UART_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI1 + 0x330 + 0x20 + + + SPI1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI0 + 0x334 + 0x20 + + + SPI0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_GPIO + 0x338 + 0x20 + + + GPIO_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_FE2 + 0x33C + 0x20 + + + FE2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_FE + 0x340 + 0x20 + + + FE_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_TIMER + 0x344 + 0x20 + + + TIMER_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_RTC + 0x348 + 0x20 + + + RTC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_IO_MUX + 0x34C + 0x20 + + + IOMUX_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_WDG + 0x350 + 0x20 + + + WDG_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_HINF + 0x354 + 0x20 + + + HINF_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UHCI1 + 0x358 + 0x20 + + + UHCI1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_MISC + 0x35C + 0x20 + + + MISC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2C + 0x360 + 0x20 + + + I2C_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2S0 + 0x364 + 0x20 + + + I2S0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UART1 + 0x368 + 0x20 + + + UART1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BT + 0x36C + 0x20 + + + BT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BT_BUFFER + 0x370 + 0x20 + + + BTBUFFER_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2C_EXT0 + 0x374 + 0x20 + + + I2CEXT0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UHCI0 + 0x378 + 0x20 + + + UHCI0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SLCHOST + 0x37C + 0x20 + + + SLCHOST_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_RMT + 0x380 + 0x20 + + + RMT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PCNT + 0x384 + 0x20 + + + PCNT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SLC + 0x388 + 0x20 + + + SLC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_LEDC + 0x38C + 0x20 + + + LEDC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_EFUSE + 0x390 + 0x20 + + + EFUSE_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI_ENCRYPT + 0x394 + 0x20 + + + SPI_ENCRYPY_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BB + 0x398 + 0x20 + + + BB_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM0 + 0x39C + 0x20 + + + PWM0_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_TIMERGROUP + 0x3A0 + 0x20 + + + TIMERGROUP_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_TIMERGROUP1 + 0x3A4 + 0x20 + + + TIMERGROUP1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI2 + 0x3A8 + 0x20 + + + SPI2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SPI3 + 0x3AC + 0x20 + + + SPI3_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_APB_CTRL + 0x3B0 + 0x20 + + + APBCTRL_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2C_EXT1 + 0x3B4 + 0x20 + + + I2CEXT1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_SDIO_HOST + 0x3B8 + 0x20 + + + SDIOHOST_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_EMAC + 0x3BC + 0x20 + + + EMAC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_CAN + 0x3C0 + 0x20 + + + CAN_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM1 + 0x3C4 + 0x20 + + + PWM1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_I2S1 + 0x3C8 + 0x20 + + + I2S1_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_UART2 + 0x3CC + 0x20 + + + UART2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM2 + 0x3D0 + 0x20 + + + PWM2_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWM3 + 0x3D4 + 0x20 + + + PWM3_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_RWBT + 0x3D8 + 0x20 + + + RWBT_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_BTMAC + 0x3DC + 0x20 + + + BTMAC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_WIFIMAC + 0x3E0 + 0x20 + + + WIFIMAC_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + AHBLITE_MPU_TABLE_PWR + 0x3E4 + 0x20 + + + PWR_ACCESS_GRANT_CONFIG + 0 + 6 + read-write + + + + + MEM_ACCESS_DBUG0 + 0x3E8 + 0x20 + + + PRO_ROM_MPU_AD + 0 + 1 + read-only + + + PRO_ROM_IA + 1 + 1 + read-only + + + APP_ROM_MPU_AD + 2 + 1 + read-only + + + APP_ROM_IA + 3 + 1 + read-only + + + SHARE_ROM_MPU_AD + 4 + 2 + read-only + + + SHARE_ROM_IA + 6 + 4 + read-only + + + INTERNAL_SRAM_MMU_AD + 10 + 4 + read-only + + + INTERNAL_SRAM_IA + 14 + 12 + read-only + + + INTERNAL_SRAM_MMU_MULTI_HIT + 26 + 4 + read-only + + + + + MEM_ACCESS_DBUG1 + 0x3EC + 0x20 + + + INTERNAL_SRAM_MMU_MISS + 0 + 4 + read-only + + + ARB_IA + 4 + 2 + read-only + + + PIDGEN_IA + 6 + 2 + read-only + + + AHB_ACCESS_DENY + 8 + 1 + read-only + + + AHBLITE_ACCESS_DENY + 9 + 1 + read-only + + + AHBLITE_IA + 10 + 1 + read-only + + + + + PRO_DCACHE_DBUG0 + 0x3F0 + 0x20 + + + PRO_SLAVE_WDATA + 0 + 1 + read-write + + + PRO_CACHE_MMU_IA + 0 + 1 + read-only + + + PRO_CACHE_IA + 1 + 6 + read-only + + + PRO_CACHE_STATE + 7 + 12 + read-only + + + PRO_WR_BAK_TO_READ + 19 + 1 + read-only + + + PRO_TX_END + 20 + 1 + read-only + + + PRO_SLAVE_WR + 21 + 1 + read-only + + + PRO_SLAVE_WDATA_V + 22 + 1 + read-only + + + PRO_RX_END + 23 + 1 + read-only + + + + + PRO_DCACHE_DBUG1 + 0x3F4 + 0x20 + + + PRO_CTAG_RAM_RDATA + 0 + 32 + read-only + + + + + PRO_DCACHE_DBUG2 + 0x3F8 + 0x20 + + + PRO_CACHE_VADDR + 0 + 27 + read-only + + + + + PRO_DCACHE_DBUG3 + 0x3FC + 0x20 + + + PRO_MMU_RDATA + 0 + 9 + read-only + + + PRO_CPU_DISABLED_CACHE_IA + 9 + 6 + read-only + + + PRO_CPU_DISABLED_CACHE_IA_OPPOSITE + 9 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_DRAM1 + 10 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_IROM0 + 11 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_IRAM1 + 12 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_IRAM0 + 13 + 1 + read-write + + + PRO_CPU_DISABLED_CACHE_IA_DROM0 + 14 + 1 + read-write + + + PRO_CACHE_IRAM0_PID_ERROR + 15 + 1 + read-only + + + + + PRO_DCACHE_DBUG4 + 0x400 + 0x20 + + + PRO_DRAM1ADDR0_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG5 + 0x404 + 0x20 + + + PRO_DROM0ADDR0_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG6 + 0x408 + 0x20 + + + PRO_IRAM0ADDR_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG7 + 0x40C + 0x20 + + + PRO_IRAM1ADDR_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG8 + 0x410 + 0x20 + + + PRO_IROM0ADDR_IA + 0 + 20 + read-only + + + + + PRO_DCACHE_DBUG9 + 0x414 + 0x20 + + + PRO_OPSDRAMADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG0 + 0x418 + 0x20 + + + APP_SLAVE_WDATA + 0 + 1 + read-write + + + APP_CACHE_MMU_IA + 0 + 1 + read-only + + + APP_CACHE_IA + 1 + 6 + read-only + + + APP_CACHE_STATE + 7 + 12 + read-only + + + APP_WR_BAK_TO_READ + 19 + 1 + read-only + + + APP_TX_END + 20 + 1 + read-only + + + APP_SLAVE_WR + 21 + 1 + read-only + + + APP_SLAVE_WDATA_V + 22 + 1 + read-only + + + APP_RX_END + 23 + 1 + read-only + + + + + APP_DCACHE_DBUG1 + 0x41C + 0x20 + + + APP_CTAG_RAM_RDATA + 0 + 32 + read-only + + + + + APP_DCACHE_DBUG2 + 0x420 + 0x20 + + + APP_CACHE_VADDR + 0 + 27 + read-only + + + + + APP_DCACHE_DBUG3 + 0x424 + 0x20 + + + APP_MMU_RDATA + 0 + 9 + read-only + + + APP_CPU_DISABLED_CACHE_IA + 9 + 6 + read-only + + + APP_CPU_DISABLED_CACHE_IA_OPPOSITE + 9 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_DRAM1 + 10 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_IROM0 + 11 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_IRAM1 + 12 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_IRAM0 + 13 + 1 + read-write + + + APP_CPU_DISABLED_CACHE_IA_DROM0 + 14 + 1 + read-write + + + APP_CACHE_IRAM0_PID_ERROR + 15 + 1 + read-only + + + + + APP_DCACHE_DBUG4 + 0x428 + 0x20 + + + APP_DRAM1ADDR0_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG5 + 0x42C + 0x20 + + + APP_DROM0ADDR0_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG6 + 0x430 + 0x20 + + + APP_IRAM0ADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG7 + 0x434 + 0x20 + + + APP_IRAM1ADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG8 + 0x438 + 0x20 + + + APP_IROM0ADDR_IA + 0 + 20 + read-only + + + + + APP_DCACHE_DBUG9 + 0x43C + 0x20 + + + APP_OPSDRAMADDR_IA + 0 + 20 + read-only + + + + + PRO_CPU_RECORD_CTRL + 0x440 + 0x20 + 0x00000100 + + + PRO_CPU_RECORD_ENABLE + 0 + 1 + read-write + + + PRO_CPU_RECORD_DISABLE + 4 + 1 + read-write + + + PRO_CPU_PDEBUG_ENABLE + 8 + 1 + read-write + + + + + PRO_CPU_RECORD_STATUS + 0x444 + 0x20 + + + PRO_CPU_RECORDING + 0 + 1 + read-only + + + + + PRO_CPU_RECORD_PID + 0x448 + 0x20 + + + RECORD_PRO_PID + 0 + 3 + read-only + + + + + PRO_CPU_RECORD_PDEBUGINST + 0x44C + 0x20 + + + RECORD_PRO_PDEBUGINST + 0 + 32 + read-only + + + RECORD_PDEBUGINST_SZ + 0 + 8 + read-write + + + RECORD_PDEBUGINST_ISRC + 12 + 3 + read-write + + + RECORD_PDEBUGINST_LOOP_REP + 20 + 1 + read-write + + + RECORD_PDEBUGINST_LOOP + 21 + 1 + read-write + + + RECORD_PDEBUGINST_CINTL + 24 + 4 + read-write + + + + + PRO_CPU_RECORD_PDEBUGSTATUS + 0x450 + 0x20 + + + RECORD_PRO_PDEBUGSTATUS + 0 + 8 + read-only + + + RECORD_PDEBUGSTATUS_BBCAUSE + 0 + 6 + read-write + + + RECORD_PDEBUGSTATUS_INSNTYPE + 0 + 6 + read-write + + + + + PRO_CPU_RECORD_PDEBUGDATA + 0x454 + 0x20 + + + RECORD_PRO_PDEBUGDATA + 0 + 32 + read-only + + + RECORD_PDEBUGDATA_DEP_OTHER + 0 + 1 + read-write + + + RECORD_PDEBUGDATA_EXCVEC + 0 + 5 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_SR + 0 + 8 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_RER + 0 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BUFF + 1 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_WER + 1 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BUFFCONFL + 2 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_ER + 2 + 12 + read-write + + + RECORD_PDEBUGDATA_STALL_DCM + 3 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_LSU + 4 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_ICM + 6 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_IRAMBUSY + 7 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_LSU + 8 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_IPIF + 8 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_RSR + 8 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_TIE + 9 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_WSR + 9 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_RUN + 10 + 1 + read-write + + + RECORD_PDEBUGDATA_INSNTYPE_XSR + 10 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_STR + 11 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP + 12 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BPIFETCH + 12 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_L32R + 13 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_LSPROC + 14 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_BPLOAD + 15 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_MEMW + 16 + 1 + read-write + + + RECORD_PDEBUGDATA_EXCCAUSE + 16 + 6 + read-write + + + RECORD_PDEBUGDATA_STALL_BANKCONFL + 16 + 1 + read-write + + + RECORD_PDEBUGDATA_DEP_HALT + 17 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_ITERMUL + 18 + 1 + read-write + + + RECORD_PDEBUGDATA_STALL_ITERDIV + 19 + 1 + read-write + + + + + PRO_CPU_RECORD_PDEBUGPC + 0x458 + 0x20 + + + RECORD_PRO_PDEBUGPC + 0 + 32 + read-only + + + + + PRO_CPU_RECORD_PDEBUGLS0STAT + 0x45C + 0x20 + + + RECORD_PRO_PDEBUGLS0STAT + 0 + 32 + read-only + + + RECORD_PDEBUGLS0STAT_TYPE + 0 + 4 + read-write + + + RECORD_PDEBUGLS0STAT_SZ + 4 + 4 + read-write + + + RECORD_PDEBUGLS0STAT_DTLBM + 8 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_DCM + 9 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_DCH + 10 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_UC + 12 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_WB + 13 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_COH + 16 + 1 + read-write + + + RECORD_PDEBUGLS0STAT_STCOH + 17 + 2 + read-write + + + RECORD_PDEBUGLS0STAT_TGT + 20 + 4 + read-write + + + + + PRO_CPU_RECORD_PDEBUGLS0ADDR + 0x460 + 0x20 + + + RECORD_PRO_PDEBUGLS0ADDR + 0 + 32 + read-only + + + + + PRO_CPU_RECORD_PDEBUGLS0DATA + 0x464 + 0x20 + + + RECORD_PRO_PDEBUGLS0DATA + 0 + 32 + read-only + + + + + APP_CPU_RECORD_CTRL + 0x468 + 0x20 + 0x00000100 + + + APP_CPU_RECORD_ENABLE + 0 + 1 + read-write + + + APP_CPU_RECORD_DISABLE + 4 + 1 + read-write + + + APP_CPU_PDEBUG_ENABLE + 8 + 1 + read-write + + + + + APP_CPU_RECORD_STATUS + 0x46C + 0x20 + + + APP_CPU_RECORDING + 0 + 1 + read-only + + + + + APP_CPU_RECORD_PID + 0x470 + 0x20 + + + RECORD_APP_PID + 0 + 3 + read-only + + + + + APP_CPU_RECORD_PDEBUGINST + 0x474 + 0x20 + + + RECORD_APP_PDEBUGINST + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGSTATUS + 0x478 + 0x20 + + + RECORD_APP_PDEBUGSTATUS + 0 + 8 + read-only + + + + + APP_CPU_RECORD_PDEBUGDATA + 0x47C + 0x20 + + + RECORD_APP_PDEBUGDATA + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGPC + 0x480 + 0x20 + + + RECORD_APP_PDEBUGPC + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGLS0STAT + 0x484 + 0x20 + + + RECORD_APP_PDEBUGLS0STAT + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGLS0ADDR + 0x488 + 0x20 + + + RECORD_APP_PDEBUGLS0ADDR + 0 + 32 + read-only + + + + + APP_CPU_RECORD_PDEBUGLS0DATA + 0x48C + 0x20 + + + RECORD_APP_PDEBUGLS0DATA + 0 + 32 + read-only + + + + + RSA_PD_CTRL + 0x490 + 0x20 + + + RSA_PD + 0 + 1 + read-write + + + + + ROM_MPU_TABLE0 + 0x494 + 0x20 + 0x00000001 + + + ROM_MPU_TABLE0 + 0 + 2 + read-write + + + + + ROM_MPU_TABLE1 + 0x498 + 0x20 + 0x00000001 + + + ROM_MPU_TABLE1 + 0 + 2 + read-write + + + + + ROM_MPU_TABLE2 + 0x49C + 0x20 + 0x00000001 + + + ROM_MPU_TABLE2 + 0 + 2 + read-write + + + + + ROM_MPU_TABLE3 + 0x4A0 + 0x20 + 0x00000001 + + + ROM_MPU_TABLE3 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE0 + 0x4A4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE0 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE1 + 0x4A8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE1 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE2 + 0x4AC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE2 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE3 + 0x4B0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE3 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE4 + 0x4B4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE4 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE5 + 0x4B8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE5 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE6 + 0x4BC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE6 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE7 + 0x4C0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE7 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE8 + 0x4C4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE8 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE9 + 0x4C8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE9 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE10 + 0x4CC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE10 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE11 + 0x4D0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE11 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE12 + 0x4D4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE12 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE13 + 0x4D8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE13 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE14 + 0x4DC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE14 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE15 + 0x4E0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE15 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE16 + 0x4E4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE16 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE17 + 0x4E8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE17 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE18 + 0x4EC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE18 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE19 + 0x4F0 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE19 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE20 + 0x4F4 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE20 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE21 + 0x4F8 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE21 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE22 + 0x4FC + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE22 + 0 + 2 + read-write + + + + + SHROM_MPU_TABLE23 + 0x500 + 0x20 + 0x00000001 + + + SHROM_MPU_TABLE23 + 0 + 2 + read-write + + + + + IMMU_TABLE0 + 0x504 + 0x20 + + + IMMU_TABLE0 + 0 + 7 + read-write + + + + + IMMU_TABLE1 + 0x508 + 0x20 + 0x00000001 + + + IMMU_TABLE1 + 0 + 7 + read-write + + + + + IMMU_TABLE2 + 0x50C + 0x20 + 0x00000002 + + + IMMU_TABLE2 + 0 + 7 + read-write + + + + + IMMU_TABLE3 + 0x510 + 0x20 + 0x00000003 + + + IMMU_TABLE3 + 0 + 7 + read-write + + + + + IMMU_TABLE4 + 0x514 + 0x20 + 0x00000004 + + + IMMU_TABLE4 + 0 + 7 + read-write + + + + + IMMU_TABLE5 + 0x518 + 0x20 + 0x00000005 + + + IMMU_TABLE5 + 0 + 7 + read-write + + + + + IMMU_TABLE6 + 0x51C + 0x20 + 0x00000006 + + + IMMU_TABLE6 + 0 + 7 + read-write + + + + + IMMU_TABLE7 + 0x520 + 0x20 + 0x00000007 + + + IMMU_TABLE7 + 0 + 7 + read-write + + + + + IMMU_TABLE8 + 0x524 + 0x20 + 0x00000008 + + + IMMU_TABLE8 + 0 + 7 + read-write + + + + + IMMU_TABLE9 + 0x528 + 0x20 + 0x00000009 + + + IMMU_TABLE9 + 0 + 7 + read-write + + + + + IMMU_TABLE10 + 0x52C + 0x20 + 0x0000000A + + + IMMU_TABLE10 + 0 + 7 + read-write + + + + + IMMU_TABLE11 + 0x530 + 0x20 + 0x0000000B + + + IMMU_TABLE11 + 0 + 7 + read-write + + + + + IMMU_TABLE12 + 0x534 + 0x20 + 0x0000000C + + + IMMU_TABLE12 + 0 + 7 + read-write + + + + + IMMU_TABLE13 + 0x538 + 0x20 + 0x0000000D + + + IMMU_TABLE13 + 0 + 7 + read-write + + + + + IMMU_TABLE14 + 0x53C + 0x20 + 0x0000000E + + + IMMU_TABLE14 + 0 + 7 + read-write + + + + + IMMU_TABLE15 + 0x540 + 0x20 + 0x0000000F + + + IMMU_TABLE15 + 0 + 7 + read-write + + + + + DMMU_TABLE0 + 0x544 + 0x20 + + + DMMU_TABLE0 + 0 + 7 + read-write + + + + + DMMU_TABLE1 + 0x548 + 0x20 + 0x00000001 + + + DMMU_TABLE1 + 0 + 7 + read-write + + + + + DMMU_TABLE2 + 0x54C + 0x20 + 0x00000002 + + + DMMU_TABLE2 + 0 + 7 + read-write + + + + + DMMU_TABLE3 + 0x550 + 0x20 + 0x00000003 + + + DMMU_TABLE3 + 0 + 7 + read-write + + + + + DMMU_TABLE4 + 0x554 + 0x20 + 0x00000004 + + + DMMU_TABLE4 + 0 + 7 + read-write + + + + + DMMU_TABLE5 + 0x558 + 0x20 + 0x00000005 + + + DMMU_TABLE5 + 0 + 7 + read-write + + + + + DMMU_TABLE6 + 0x55C + 0x20 + 0x00000006 + + + DMMU_TABLE6 + 0 + 7 + read-write + + + + + DMMU_TABLE7 + 0x560 + 0x20 + 0x00000007 + + + DMMU_TABLE7 + 0 + 7 + read-write + + + + + DMMU_TABLE8 + 0x564 + 0x20 + 0x00000008 + + + DMMU_TABLE8 + 0 + 7 + read-write + + + + + DMMU_TABLE9 + 0x568 + 0x20 + 0x00000009 + + + DMMU_TABLE9 + 0 + 7 + read-write + + + + + DMMU_TABLE10 + 0x56C + 0x20 + 0x0000000A + + + DMMU_TABLE10 + 0 + 7 + read-write + + + + + DMMU_TABLE11 + 0x570 + 0x20 + 0x0000000B + + + DMMU_TABLE11 + 0 + 7 + read-write + + + + + DMMU_TABLE12 + 0x574 + 0x20 + 0x0000000C + + + DMMU_TABLE12 + 0 + 7 + read-write + + + + + DMMU_TABLE13 + 0x578 + 0x20 + 0x0000000D + + + DMMU_TABLE13 + 0 + 7 + read-write + + + + + DMMU_TABLE14 + 0x57C + 0x20 + 0x0000000E + + + DMMU_TABLE14 + 0 + 7 + read-write + + + + + DMMU_TABLE15 + 0x580 + 0x20 + 0x0000000F + + + DMMU_TABLE15 + 0 + 7 + read-write + + + + + PRO_INTRUSION_CTRL + 0x584 + 0x20 + 0x00000001 + + + PRO_INTRUSION_RECORD_RESET_N + 0 + 1 + read-write + + + + + PRO_INTRUSION_STATUS + 0x588 + 0x20 + + + PRO_INTRUSION_RECORD + 0 + 4 + read-only + + + + + APP_INTRUSION_CTRL + 0x58C + 0x20 + 0x00000001 + + + APP_INTRUSION_RECORD_RESET_N + 0 + 1 + read-write + + + + + APP_INTRUSION_STATUS + 0x590 + 0x20 + + + APP_INTRUSION_RECORD + 0 + 4 + read-only + + + + + FRONT_END_MEM_PD + 0x594 + 0x20 + 0x00000005 + + + AGC_MEM_FORCE_PU + 0 + 1 + read-write + + + AGC_MEM_FORCE_PD + 1 + 1 + read-write + + + PBUS_MEM_FORCE_PU + 2 + 1 + read-write + + + PBUS_MEM_FORCE_PD + 3 + 1 + read-write + + + + + MMU_IA_INT_EN + 0x598 + 0x20 + + + MMU_IA_INT_EN + 0 + 24 + read-write + + + + + MPU_IA_INT_EN + 0x59C + 0x20 + + + MPU_IA_INT_EN + 0 + 17 + read-write + + + + + CACHE_IA_INT_EN + 0x5A0 + 0x20 + + + CACHE_IA_INT_EN + Interrupt enable bits for various invalid cache access reasons + 0 + 28 + read-write + + + CACHE_IA_INT_APP_DROM0 + APP CPU invalid access to DROM0 when cache is disabled + 0 + 1 + read-write + + + CACHE_IA_INT_APP_IRAM0 + APP CPU invalid access to IRAM0 when cache is disabled + 1 + 1 + read-write + + + CACHE_IA_INT_APP_IRAM1 + APP CPU invalid access to IRAM1 when cache is disabled + 2 + 1 + read-write + + + CACHE_IA_INT_APP_IROM0 + APP CPU invalid access to IROM0 when cache is disabled + 3 + 1 + read-write + + + CACHE_IA_INT_APP_DRAM1 + APP CPU invalid access to DRAM1 when cache is disabled + 4 + 1 + read-write + + + CACHE_IA_INT_APP_OPPOSITE + APP CPU invalid access to APP CPU cache when cache disabled + 5 + 1 + read-write + + + CACHE_IA_INT_PRO_DROM0 + PRO CPU invalid access to DROM0 when cache is disabled + 14 + 1 + read-write + + + CACHE_IA_INT_PRO_IRAM0 + PRO CPU invalid access to IRAM0 when cache is disabled + 15 + 1 + read-write + + + CACHE_IA_INT_PRO_IRAM1 + PRO CPU invalid access to IRAM1 when cache is disabled + 16 + 1 + read-write + + + CACHE_IA_INT_PRO_IROM0 + PRO CPU invalid access to IROM0 when cache is disabled + 17 + 1 + read-write + + + CACHE_IA_INT_PRO_DRAM1 + PRO CPU invalid access to DRAM1 when cache is disabled + 18 + 1 + read-write + + + CACHE_IA_INT_PRO_OPPOSITE + PRO CPU invalid access to APP CPU cache when cache disabled + 19 + 1 + read-write + + + + + SECURE_BOOT_CTRL + 0x5A4 + 0x20 + + + SW_BOOTLOADER_SEL + 0 + 1 + read-write + + + + + SPI_DMA_CHAN_SEL + 0x5A8 + 0x20 + + + SPI1_DMA_CHAN_SEL + 0 + 2 + read-write + + + SPI2_DMA_CHAN_SEL + 2 + 2 + read-write + + + SPI3_DMA_CHAN_SEL + 4 + 2 + read-write + + + + + PRO_VECBASE_CTRL + 0x5AC + 0x20 + + + PRO_OUT_VECBASE_SEL + 0 + 2 + read-write + + + + + PRO_VECBASE_SET + 0x5B0 + 0x20 + + + PRO_OUT_VECBASE + 0 + 22 + read-write + + + + + APP_VECBASE_CTRL + 0x5B4 + 0x20 + + + APP_OUT_VECBASE_SEL + 0 + 2 + read-write + + + + + APP_VECBASE_SET + 0x5B8 + 0x20 + + + APP_OUT_VECBASE + 0 + 22 + read-write + + + + + DATE + 0xFFC + 0x20 + 0x01605190 + + + DATE + 0 + 28 + read-write + + + + + + + EFUSE + eFuse Controller + EFUSE + 0x3FF5A000 + + 0x0 + 0x124 + registers + + + EFUSE + 44 + + + + BLK0_RDATA0 + 0x0 + 0x20 + + + RD_EFUSE_WR_DIS + read for efuse_wr_disable + 0 + 16 + read-only + + + RD_EFUSE_RD_DIS + read for efuse_rd_disable + 16 + 4 + read-only + + + RD_FLASH_CRYPT_CNT + read for flash_crypt_cnt + 20 + 7 + read-only + + + + + BLK0_RDATA1 + 0x4 + 0x20 + + + RD_WIFI_MAC_CRC_LOW + read for low 32bit WIFI_MAC_Address + 0 + 32 + read-only + + + + + BLK0_RDATA2 + 0x8 + 0x20 + + + RD_WIFI_MAC_CRC_HIGH + read for high 24bit WIFI_MAC_Address + 0 + 24 + read-only + + + + + BLK0_RDATA3 + 0xC + 0x20 + + + RD_CHIP_VER_DIS_APP_CPU + 0 + 1 + read-only + + + RD_CHIP_VER_DIS_BT + 1 + 1 + read-only + + + RD_CHIP_VER_PKG_4BIT + most significant bit of chip package + 2 + 1 + read-only + + + RD_CHIP_VER_DIS_CACHE + 3 + 1 + read-only + + + RD_SPI_PAD_CONFIG_HD + read for SPI_pad_config_hd + 4 + 5 + read-only + + + RD_CHIP_VER_PKG + least significant bits of chip package + 9 + 3 + read-write + + + RD_CHIP_CPU_FREQ_LOW + If set alongside EFUSE_RD_CHIP_CPU_FREQ_RATED, the ESP32's max CPU frequency is rated for 160MHz. 240MHz otherwise + 12 + 1 + read-write + + + RD_CHIP_CPU_FREQ_RATED + If set, the ESP32's maximum CPU frequency has been rated + 13 + 1 + read-write + + + RD_BLK3_PART_RESERVE + If set, this bit indicates that BLOCK3[143:96] is reserved for internal use + 14 + 1 + read-write + + + RD_CHIP_VER_REV1 + bit is set to 1 for rev1 silicon + 15 + 1 + read-write + + + + + BLK0_RDATA4 + 0x10 + 0x20 + + + RD_CK8M_FREQ + 0 + 8 + read-only + + + RD_ADC_VREF + True ADC reference voltage + 8 + 5 + read-write + + + RD_SDIO_DREFH + 8 + 2 + read-only + + + RD_SDIO_DREFM + 10 + 2 + read-only + + + RD_SDIO_DREFL + 12 + 2 + read-only + + + RD_XPD_SDIO + read for XPD_SDIO_REG + 14 + 1 + read-only + + + RD_SDIO_TIEH + read for SDIO_TIEH + 15 + 1 + read-only + + + RD_SDIO_FORCE + read for sdio_force + 16 + 1 + read-only + + + + + BLK0_RDATA5 + 0x14 + 0x20 + + + RD_SPI_PAD_CONFIG_CLK + read for SPI_pad_config_clk + 0 + 5 + read-only + + + RD_SPI_PAD_CONFIG_Q + read for SPI_pad_config_q + 5 + 5 + read-only + + + RD_SPI_PAD_CONFIG_D + read for SPI_pad_config_d + 10 + 5 + read-only + + + RD_SPI_PAD_CONFIG_CS0 + read for SPI_pad_config_cs0 + 15 + 5 + read-only + + + RD_CHIP_VER_REV2 + 20 + 1 + read-only + + + RD_VOL_LEVEL_HP_INV + This field stores the voltage level for CPU to run at 240 MHz, or for flash/PSRAM to run at 80 MHz.0x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: level 4. (RO) + 22 + 2 + read-only + + + RD_WAFER_VERSION_MINOR + 24 + 2 + read-only + + + RD_FLASH_CRYPT_CONFIG + read for flash_crypt_config + 28 + 4 + read-only + + + + + BLK0_RDATA6 + 0x18 + 0x20 + + + RD_CODING_SCHEME + read for coding_scheme + 0 + 2 + read-only + + + RD_CONSOLE_DEBUG_DISABLE + read for console_debug_disable + 2 + 1 + read-only + + + RD_DISABLE_SDIO_HOST + 3 + 1 + read-only + + + RD_ABS_DONE_0 + read for abstract_done_0 + 4 + 1 + read-only + + + RD_ABS_DONE_1 + read for abstract_done_1 + 5 + 1 + read-only + + + RD_DISABLE_JTAG + read for JTAG_disable + 6 + 1 + read-only + + + RD_DISABLE_DL_ENCRYPT + read for download_dis_encrypt + 7 + 1 + read-only + + + RD_DISABLE_DL_DECRYPT + read for download_dis_decrypt + 8 + 1 + read-only + + + RD_DISABLE_DL_CACHE + read for download_dis_cache + 9 + 1 + read-only + + + RD_KEY_STATUS + read for key_status + 10 + 1 + read-only + + + + + BLK0_WDATA0 + 0x1C + 0x20 + + + WR_DIS + program for efuse_wr_disable + 0 + 16 + read-write + + + RD_DIS + program for efuse_rd_disable + 16 + 4 + read-write + + + FLASH_CRYPT_CNT + program for flash_crypt_cnt + 20 + 7 + read-write + + + + + BLK0_WDATA1 + 0x20 + 0x20 + + + WIFI_MAC_CRC_LOW + program for low 32bit WIFI_MAC_Address + 0 + 32 + read-write + + + + + BLK0_WDATA2 + 0x24 + 0x20 + + + WIFI_MAC_CRC_HIGH + program for high 24bit WIFI_MAC_Address + 0 + 24 + read-write + + + + + BLK0_WDATA3 + 0x28 + 0x20 + + + CHIP_VER_DIS_APP_CPU + 0 + 1 + read-write + + + CHIP_VER_DIS_BT + 1 + 1 + read-write + + + CHIP_VER_PKG_4BIT + most significant bit of chip package + 2 + 1 + read-only + + + CHIP_VER_DIS_CACHE + 3 + 1 + read-write + + + SPI_PAD_CONFIG_HD + program for SPI_pad_config_hd + 4 + 5 + read-write + + + CHIP_VER_PKG + least significant bits of chip package + 9 + 3 + read-write + + + CHIP_CPU_FREQ_LOW + If set alongside EFUSE_CHIP_CPU_FREQ_RATED, the ESP32's max CPU frequency is rated for 160MHz. 240MHz otherwise + 12 + 1 + read-write + + + CHIP_CPU_FREQ_RATED + If set, the ESP32's maximum CPU frequency has been rated + 13 + 1 + read-write + + + BLK3_PART_RESERVE + If set, this bit indicates that BLOCK3[143:96] is reserved for internal use + 14 + 1 + read-write + + + CHIP_VER_REV1 + 15 + 1 + read-write + + + + + BLK0_WDATA4 + 0x2C + 0x20 + + + CK8M_FREQ + 0 + 8 + read-write + + + ADC_VREF + True ADC reference voltage + 8 + 5 + read-write + + + SDIO_DREFH + 8 + 2 + read-write + + + SDIO_DREFM + 10 + 2 + read-write + + + SDIO_DREFL + 12 + 2 + read-write + + + XPD_SDIO + program for XPD_SDIO_REG + 14 + 1 + read-write + + + SDIO_TIEH + program for SDIO_TIEH + 15 + 1 + read-write + + + SDIO_FORCE + program for sdio_force + 16 + 1 + read-write + + + + + BLK0_WDATA5 + 0x30 + 0x20 + + + SPI_PAD_CONFIG_CLK + program for SPI_pad_config_clk + 0 + 5 + read-write + + + SPI_PAD_CONFIG_Q + program for SPI_pad_config_q + 5 + 5 + read-write + + + SPI_PAD_CONFIG_D + program for SPI_pad_config_d + 10 + 5 + read-write + + + SPI_PAD_CONFIG_CS0 + program for SPI_pad_config_cs0 + 15 + 5 + read-write + + + INST_CONFIG + 20 + 8 + read-write + + + VOL_LEVEL_HP_INV + This field stores the voltage level for CPU to run at 240 MHz, or for flash/PSRAM to run at 80 MHz.0x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: level 4. (R/W) + 22 + 2 + read-write + + + DIG_VOL_L6 + 24 + 4 + read-write + + + FLASH_CRYPT_CONFIG + program for flash_crypt_config + 28 + 4 + read-write + + + + + BLK0_WDATA6 + 0x34 + 0x20 + + + CODING_SCHEME + program for coding_scheme + 0 + 2 + read-write + + + CONSOLE_DEBUG_DISABLE + program for console_debug_disable + 2 + 1 + read-write + + + DISABLE_SDIO_HOST + 3 + 1 + read-write + + + ABS_DONE_0 + program for abstract_done_0 + 4 + 1 + read-write + + + ABS_DONE_1 + program for abstract_done_1 + 5 + 1 + read-write + + + DISABLE_JTAG + program for JTAG_disable + 6 + 1 + read-write + + + DISABLE_DL_ENCRYPT + program for download_dis_encrypt + 7 + 1 + read-write + + + DISABLE_DL_DECRYPT + program for download_dis_decrypt + 8 + 1 + read-write + + + DISABLE_DL_CACHE + program for download_dis_cache + 9 + 1 + read-write + + + KEY_STATUS + program for key_status + 10 + 1 + read-write + + + + + BLK1_RDATA0 + 0x38 + 0x20 + + + BLK1_DOUT0 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA1 + 0x3C + 0x20 + + + BLK1_DOUT1 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA2 + 0x40 + 0x20 + + + BLK1_DOUT2 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA3 + 0x44 + 0x20 + + + BLK1_DOUT3 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA4 + 0x48 + 0x20 + + + BLK1_DOUT4 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA5 + 0x4C + 0x20 + + + BLK1_DOUT5 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA6 + 0x50 + 0x20 + + + BLK1_DOUT6 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK1_RDATA7 + 0x54 + 0x20 + + + BLK1_DOUT7 + read for BLOCK1 + 0 + 32 + read-only + + + + + BLK2_RDATA0 + 0x58 + 0x20 + + + BLK2_DOUT0 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA1 + 0x5C + 0x20 + + + BLK2_DOUT1 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA2 + 0x60 + 0x20 + + + BLK2_DOUT2 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA3 + 0x64 + 0x20 + + + BLK2_DOUT3 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA4 + 0x68 + 0x20 + + + BLK2_DOUT4 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA5 + 0x6C + 0x20 + + + BLK2_DOUT5 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA6 + 0x70 + 0x20 + + + BLK2_DOUT6 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK2_RDATA7 + 0x74 + 0x20 + + + BLK2_DOUT7 + read for BLOCK2 + 0 + 32 + read-only + + + + + BLK3_RDATA0 + 0x78 + 0x20 + + + BLK3_DOUT0 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA1 + 0x7C + 0x20 + + + BLK3_DOUT1 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA2 + 0x80 + 0x20 + + + BLK3_DOUT2 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA3 + 0x84 + 0x20 + + + BLK3_DOUT3 + read for BLOCK3 + 0 + 32 + read-only + + + RD_ADC1_TP_LOW + ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 0 + 7 + read-write + + + RD_ADC1_TP_HIGH + ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 7 + 9 + read-write + + + RD_ADC2_TP_LOW + ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 16 + 7 + read-write + + + RD_ADC2_TP_HIGH + ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 23 + 9 + read-write + + + + + BLK3_RDATA4 + 0x88 + 0x20 + + + BLK3_DOUT4 + read for BLOCK3 + 0 + 32 + read-only + + + RD_CAL_RESERVED + Reserved for future calibration use. Indicated by EFUSE_RD_BLK3_PART_RESERVE + 0 + 16 + read-write + + + + + BLK3_RDATA5 + 0x8C + 0x20 + + + BLK3_DOUT5 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA6 + 0x90 + 0x20 + + + BLK3_DOUT6 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK3_RDATA7 + 0x94 + 0x20 + + + BLK3_DOUT7 + read for BLOCK3 + 0 + 32 + read-only + + + + + BLK1_WDATA0 + 0x98 + 0x20 + + + BLK1_DIN0 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA1 + 0x9C + 0x20 + + + BLK1_DIN1 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA2 + 0xA0 + 0x20 + + + BLK1_DIN2 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA3 + 0xA4 + 0x20 + + + BLK1_DIN3 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA4 + 0xA8 + 0x20 + + + BLK1_DIN4 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA5 + 0xAC + 0x20 + + + BLK1_DIN5 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA6 + 0xB0 + 0x20 + + + BLK1_DIN6 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK1_WDATA7 + 0xB4 + 0x20 + + + BLK1_DIN7 + program for BLOCK1 + 0 + 32 + read-write + + + + + BLK2_WDATA0 + 0xB8 + 0x20 + + + BLK2_DIN0 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA1 + 0xBC + 0x20 + + + BLK2_DIN1 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA2 + 0xC0 + 0x20 + + + BLK2_DIN2 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA3 + 0xC4 + 0x20 + + + BLK2_DIN3 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA4 + 0xC8 + 0x20 + + + BLK2_DIN4 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA5 + 0xCC + 0x20 + + + BLK2_DIN5 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA6 + 0xD0 + 0x20 + + + BLK2_DIN6 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK2_WDATA7 + 0xD4 + 0x20 + + + BLK2_DIN7 + program for BLOCK2 + 0 + 32 + read-write + + + + + BLK3_WDATA0 + 0xD8 + 0x20 + + + BLK3_DIN0 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA1 + 0xDC + 0x20 + + + BLK3_DIN1 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA2 + 0xE0 + 0x20 + + + BLK3_DIN2 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA3 + 0xE4 + 0x20 + + + BLK3_DIN3 + program for BLOCK3 + 0 + 32 + read-write + + + ADC1_TP_LOW + ADC1 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 0 + 7 + read-write + + + ADC1_TP_HIGH + ADC1 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 7 + 9 + read-write + + + ADC2_TP_LOW + ADC2 Two Point calibration low point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 16 + 7 + read-write + + + ADC2_TP_HIGH + ADC2 Two Point calibration high point. Only valid if EFUSE_RD_BLK3_PART_RESERVE + 23 + 9 + read-write + + + + + BLK3_WDATA4 + 0xE8 + 0x20 + + + BLK3_DIN4 + program for BLOCK3 + 0 + 32 + read-write + + + CAL_RESERVED + Reserved for future calibration use. Indicated by EFUSE_BLK3_PART_RESERVE + 0 + 16 + read-write + + + + + BLK3_WDATA5 + 0xEC + 0x20 + + + BLK3_DIN5 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA6 + 0xF0 + 0x20 + + + BLK3_DIN6 + program for BLOCK3 + 0 + 32 + read-write + + + + + BLK3_WDATA7 + 0xF4 + 0x20 + + + BLK3_DIN7 + program for BLOCK3 + 0 + 32 + read-write + + + + + CLK + 0xF8 + 0x20 + 0x00004052 + + + SEL0 + efuse timing configure + 0 + 8 + read-write + + + SEL1 + efuse timing configure + 8 + 8 + read-write + + + EN + 16 + 1 + read-write + + + + + CONF + 0xFC + 0x20 + 0x00010000 + + + OP_CODE + efuse operation code + 0 + 16 + read-write + + + FORCE_NO_WR_RD_DIS + 16 + 1 + read-write + + + + + STATUS + 0x100 + 0x20 + + + DEBUG + 0 + 32 + read-only + + + + + CMD + 0x104 + 0x20 + + + READ_CMD + command for read + 0 + 1 + read-write + + + PGM_CMD + command for program + 1 + 1 + read-write + + + + + INT_RAW + 0x108 + 0x20 + + + READ_DONE_INT_RAW + read done interrupt raw status + 0 + 1 + read-only + + + PGM_DONE_INT_RAW + program done interrupt raw status + 1 + 1 + read-only + + + + + INT_ST + 0x10C + 0x20 + + + READ_DONE_INT_ST + read done interrupt status + 0 + 1 + read-only + + + PGM_DONE_INT_ST + program done interrupt status + 1 + 1 + read-only + + + + + INT_ENA + 0x110 + 0x20 + + + READ_DONE_INT_ENA + read done interrupt enable + 0 + 1 + read-write + + + PGM_DONE_INT_ENA + program done interrupt enable + 1 + 1 + read-write + + + + + INT_CLR + 0x114 + 0x20 + + + READ_DONE_INT_CLR + read done interrupt clear + 0 + 1 + write-only + + + PGM_DONE_INT_CLR + program done interrupt clear + 1 + 1 + write-only + + + + + DAC_CONF + 0x118 + 0x20 + 0x00000028 + + + DAC_CLK_DIV + efuse timing configure + 0 + 8 + read-write + + + DAC_CLK_PAD_SEL + 8 + 1 + read-write + + + + + DEC_STATUS + 0x11C + 0x20 + + + DEC_WARNINGS + the decode result of 3/4 coding scheme has warning + 0 + 12 + read-only + + + + + DATE + 0x1FC + 0x20 + 0x16042600 + + + DATE + 0 + 32 + read-write + + + + + + + FLASH_ENCRYPTION + Flash Encryption Peripheral + FLASH_ENCRYPTION + 0x3FF46000 + + 0x0 + 0x2C + registers + + + + 8 + 0x4 + BUFFER_%s + 0x0 + 0x20 + + + BUFFER + Data buffers for encryption. + 0 + 8 + write-only + + + + + START + 0x20 + 0x20 + + + FLASH_START + Set this bit to start encryption operation on data buffer. + 0 + 8 + write-only + + + + + ADDRESS + 0x24 + 0x20 + + + ADDRESS + The physical address on the off-chip flash must be 8-word boundary aligned. + 0 + 8 + write-only + + + + + DONE + 0x28 + 0x20 + + + FLASH_DONE + Set this bit when encryption operation is complete. + 0 + 1 + read-only + + + + + + + FRC_TIMER + Peripheral FRC_TIMER + FRC + 0x3FF47000 + + 0x0 + 0x14 + registers + + + + TIMER_LOAD + 0x0 + 0x20 + + + VALUE + 0 + 8 + read-write + + + + + TIMER_COUNT + 0x4 + 0x20 + + + TIMER_COUNT + 0 + 8 + read-write + + + + + TIMER_CTRL + 0x8 + 0x20 + + + TIMER_PRESCALER + 1 + 8 + read-write + + + + + TIMER_INT + 0xC + 0x20 + + + CLR + 0 + 1 + read-write + + + + + TIMER_ALARM + 0x10 + 0x20 + + + TIMER_ALARM + 0 + 8 + read-write + + + + + + + GPIO + General Purpose Input/Output + GPIO + 0x3FF44000 + + 0x0 + 0x5CC + registers + + + GPIO + 22 + + + GPIO_NMI + 23 + + + + BT_SELECT + 0x0 + 0x20 + + + BT_SEL + NA + 0 + 32 + read-write + + + + + OUT + 0x4 + 0x20 + + + DATA + GPIO0~31 output value + 0 + 32 + read-write + + + + + OUT_W1TS + 0x8 + 0x20 + + + OUT_DATA_W1TS + GPIO0~31 output value write 1 to set + 0 + 32 + read-write + + + + + OUT_W1TC + 0xC + 0x20 + + + OUT_DATA_W1TC + GPIO0~31 output value write 1 to clear + 0 + 32 + read-write + + + + + OUT1 + 0x10 + 0x20 + + + DATA + GPIO32~39 output value + 0 + 8 + read-write + + + + + OUT1_W1TS + 0x14 + 0x20 + + + OUT1_DATA_W1TS + GPIO32~39 output value write 1 to set + 0 + 8 + read-write + + + + + OUT1_W1TC + 0x18 + 0x20 + + + OUT1_DATA_W1TC + GPIO32~39 output value write 1 to clear + 0 + 8 + read-write + + + + + SDIO_SELECT + 0x1C + 0x20 + + + SDIO_SEL + SDIO PADS on/off control from outside + 0 + 8 + read-write + + + + + ENABLE + 0x20 + 0x20 + + + DATA + GPIO0~31 output enable + 0 + 32 + read-write + + + + + ENABLE_W1TS + 0x24 + 0x20 + + + ENABLE_DATA_W1TS + GPIO0~31 output enable write 1 to set + 0 + 32 + read-write + + + + + ENABLE_W1TC + 0x28 + 0x20 + + + ENABLE_DATA_W1TC + GPIO0~31 output enable write 1 to clear + 0 + 32 + read-write + + + + + ENABLE1 + 0x2C + 0x20 + + + DATA + GPIO32~39 output enable + 0 + 8 + read-write + + + + + ENABLE1_W1TS + 0x30 + 0x20 + + + ENABLE1_DATA_W1TS + GPIO32~39 output enable write 1 to set + 0 + 8 + read-write + + + + + ENABLE1_W1TC + 0x34 + 0x20 + + + ENABLE1_DATA_W1TC + GPIO32~39 output enable write 1 to clear + 0 + 8 + read-write + + + + + STRAP + 0x38 + 0x20 + + + STRAPPING + {10'b0, MTDI, GPIO0, GPIO2, GPIO4, MTDO, GPIO5} + 0 + 16 + read-only + + + + + IN + 0x3C + 0x20 + + + DATA_NEXT + GPIO0~31 input value + 0 + 32 + read-write + + + + + IN1 + 0x40 + 0x20 + + + DATA_NEXT + GPIO32~39 input value + 0 + 8 + read-write + + + + + STATUS + 0x44 + 0x20 + + + INT + GPIO0~31 interrupt status + 0 + 32 + read-write + + + + + STATUS_W1TS + 0x48 + 0x20 + + + STATUS_INT_W1TS + GPIO0~31 interrupt status write 1 to set + 0 + 32 + read-write + + + + + STATUS_W1TC + 0x4C + 0x20 + + + STATUS_INT_W1TC + GPIO0~31 interrupt status write 1 to clear + 0 + 32 + read-write + + + + + STATUS1 + 0x50 + 0x20 + + + INT + GPIO32~39 interrupt status + 0 + 8 + read-write + + + + + STATUS1_W1TS + 0x54 + 0x20 + + + STATUS1_INT_W1TS + GPIO32~39 interrupt status write 1 to set + 0 + 8 + read-write + + + + + STATUS1_W1TC + 0x58 + 0x20 + + + STATUS1_INT_W1TC + GPIO32~39 interrupt status write 1 to clear + 0 + 8 + read-write + + + + + ACPU_INT + 0x60 + 0x20 + + + APPCPU_INT + GPIO0~31 APP CPU interrupt status + 0 + 32 + read-only + + + + + ACPU_NMI_INT + 0x64 + 0x20 + + + APPCPU_NMI_INT + GPIO0~31 APP CPU non-maskable interrupt status + 0 + 32 + read-only + + + + + PCPU_INT + 0x68 + 0x20 + + + PROCPU_INT + GPIO0~31 PRO CPU interrupt status + 0 + 32 + read-only + + + + + PCPU_NMI_INT + 0x6C + 0x20 + + + PROCPU_NMI_INT + GPIO0~31 PRO CPU non-maskable interrupt status + 0 + 32 + read-only + + + + + CPUSDIO_INT + 0x70 + 0x20 + + + SDIO_INT + SDIO's extent GPIO0~31 interrupt + 0 + 32 + read-only + + + + + ACPU_INT1 + 0x74 + 0x20 + + + APPCPU_INT_H + GPIO32~39 APP CPU interrupt status + 0 + 8 + read-only + + + + + ACPU_NMI_INT1 + 0x78 + 0x20 + + + APPCPU_NMI_INT_H + GPIO32~39 APP CPU non-maskable interrupt status + 0 + 8 + read-only + + + + + PCPU_INT1 + 0x7C + 0x20 + + + PROCPU_INT_H + GPIO32~39 PRO CPU interrupt status + 0 + 8 + read-only + + + + + PCPU_NMI_INT1 + 0x80 + 0x20 + + + PROCPU_NMI_INT_H + GPIO32~39 PRO CPU non-maskable interrupt status + 0 + 8 + read-only + + + + + CPUSDIO_INT1 + 0x84 + 0x20 + + + SDIO_INT_H + SDIO's extent GPIO32~39 interrupt + 0 + 8 + read-only + + + PIN_PAD_DRIVER + 2 + 1 + read-write + + + PIN_INT_TYPE + 7 + 3 + read-write + + + PIN_WAKEUP_ENABLE + 10 + 1 + read-write + + + PIN_CONFIG + 11 + 2 + read-write + + + PIN_INT_ENA + 13 + 5 + read-write + + + + + 40 + 0x4 + 0-39 + PIN%s + 0x88 + 0x20 + + + PAD_DRIVER + if set to 0: normal output if set to 1: open drain + 2 + 1 + read-write + + + INT_TYPE + if set to 0: GPIO interrupt disable if set to 1: rising edge trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger + 7 + 3 + read-write + + + WAKEUP_ENABLE + GPIO wake up enable only available in light sleep + 10 + 1 + read-write + + + CONFIG + NA + 11 + 2 + read-write + + + INT_ENA + bit0: APP CPU interrupt enable bit1: APP CPU non-maskable interrupt enable bit3: PRO CPU interrupt enable bit4: PRO CPU non-maskable interrupt enable bit5: SDIO's extent interrupt enable + 13 + 5 + read-write + + + + + cali_conf + 0x128 + 0x20 + + + CALI_RTC_MAX + 0 + 10 + read-write + + + CALI_START + 31 + 1 + read-write + + + + + cali_data + 0x12C + 0x20 + + + CALI_VALUE_SYNC2 + 0 + 20 + read-only + + + CALI_RDY_REAL + 30 + 1 + read-only + + + CALI_RDY_SYNC2 + 31 + 1 + read-only + + + + + 256 + 0x4 + 0-255 + FUNC%s_IN_SEL_CFG + 0x130 + 0x20 + + + IN_SEL + select one of the 256 inputs + 0 + 6 + read-write + + + IN_INV_SEL + revert the value of the input if you want to revert please set the value to 1 + 6 + 1 + read-write + + + SEL + if the slow signal bypass the io matrix or not if you want setting the value to 1 + 7 + 1 + read-write + + + + + 40 + 0x4 + 0-39 + FUNC%s_OUT_SEL_CFG + 0x530 + 0x20 + + + OUT_SEL + select one of the 256 output to 40 GPIO + 0 + 9 + read-write + + + INV_SEL + invert the output value if you want to revert the output value setting the value to 1 + 9 + 1 + read-write + + + OEN_SEL + weather using the logical oen signal or not using the value setting by the register + 10 + 1 + read-write + + + OEN_INV_SEL + invert the output enable value if you want to revert the output enable value setting the value to 1 + 11 + 1 + read-write + + + + + + + GPIO_SD + Sigma-Delta Modulation + GPIO_SIGMADELTA + 0x3FF44F00 + + 0x0 + 0x2C + registers + + + + SIGMADELTA0 + 0x0 + 0x20 + 0x0000FF00 + + + SD0_IN + 0 + 8 + read-write + + + SD0_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA1 + 0x4 + 0x20 + 0x0000FF00 + + + SD1_IN + 0 + 8 + read-write + + + SD1_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA2 + 0x8 + 0x20 + 0x0000FF00 + + + SD2_IN + 0 + 8 + read-write + + + SD2_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA3 + 0xC + 0x20 + 0x0000FF00 + + + SD3_IN + 0 + 8 + read-write + + + SD3_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA4 + 0x10 + 0x20 + 0x0000FF00 + + + SD4_IN + 0 + 8 + read-write + + + SD4_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA5 + 0x14 + 0x20 + 0x0000FF00 + + + SD5_IN + 0 + 8 + read-write + + + SD5_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA6 + 0x18 + 0x20 + 0x0000FF00 + + + SD6_IN + 0 + 8 + read-write + + + SD6_PRESCALE + 8 + 8 + read-write + + + + + SIGMADELTA7 + 0x1C + 0x20 + 0x0000FF00 + + + SD7_IN + 0 + 8 + read-write + + + SD7_PRESCALE + 8 + 8 + read-write + + + + + CG + 0x20 + 0x20 + + + SD_CLK_EN + 31 + 1 + read-write + + + + + MISC + 0x24 + 0x20 + + + SPI_SWAP + 31 + 1 + read-write + + + + + VERSION + 0x28 + 0x20 + 0x01506190 + + + SD_DATE + 0 + 28 + read-write + + + + + + + HINF + Peripheral HINF + HINF + 0x3FF4B000 + + 0x0 + 0x34 + registers + + + + CFG_DATA0 + 0x0 + 0x20 + 0x22226666 + + + USER_ID_FN1 + 0 + 16 + read-write + + + DEVICE_ID_FN1 + 16 + 16 + read-write + + + + + CFG_DATA1 + 0x4 + 0x20 + 0x01110011 + + + SDIO_ENABLE + 0 + 1 + read-write + + + SDIO_IOREADY1 + 1 + 1 + read-write + + + HIGHSPEED_ENABLE + 2 + 1 + read-write + + + HIGHSPEED_MODE + 3 + 1 + read-only + + + SDIO_CD_ENABLE + 4 + 1 + read-write + + + SDIO_IOREADY2 + 5 + 1 + read-write + + + SDIO_INT_MASK + 6 + 1 + read-write + + + IOENABLE2 + 7 + 1 + read-only + + + CD_DISABLE + 8 + 1 + read-only + + + FUNC1_EPS + 9 + 1 + read-only + + + EMP + 10 + 1 + read-only + + + IOENABLE1 + 11 + 1 + read-only + + + SDIO20_CONF0 + 12 + 4 + read-write + + + SDIO_VER + 16 + 12 + read-write + + + FUNC2_EPS + 28 + 1 + read-only + + + SDIO20_CONF1 + 29 + 3 + read-write + + + + + CFG_DATA7 + 0x1C + 0x20 + 0x00020000 + + + PIN_STATE + 0 + 8 + read-write + + + CHIP_STATE + 8 + 8 + read-write + + + SDIO_RST + 16 + 1 + read-write + + + SDIO_IOREADY0 + 17 + 1 + read-write + + + + + CIS_CONF0 + 0x20 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W0 + 0 + 32 + read-write + + + + + CIS_CONF1 + 0x24 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W1 + 0 + 32 + read-write + + + + + CIS_CONF2 + 0x28 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W2 + 0 + 32 + read-write + + + + + CIS_CONF3 + 0x2C + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W3 + 0 + 32 + read-write + + + + + CIS_CONF4 + 0x30 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W4 + 0 + 32 + read-write + + + + + CIS_CONF5 + 0x34 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W5 + 0 + 32 + read-write + + + + + CIS_CONF6 + 0x38 + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W6 + 0 + 32 + read-write + + + + + CIS_CONF7 + 0x3C + 0x20 + 0xFFFFFFFF + + + CIS_CONF_W7 + 0 + 32 + read-write + + + + + CFG_DATA16 + 0x40 + 0x20 + 0x33336666 + + + USER_ID_FN2 + 0 + 16 + read-write + + + DEVICE_ID_FN2 + 16 + 16 + read-write + + + + + DATE + 0xFC + 0x20 + 0x15030200 + + + SDIO_DATE + 0 + 32 + read-write + + + + + + + I2C0 + I2C (Inter-Integrated Circuit) Controller + I2C + 0x3FF53000 + + 0x0 + 0x9C + registers + + + I2C_EXT0 + 49 + + + + SCL_LOW_PERIOD + 0x0 + 0x20 + + + SCL_LOW_PERIOD + This register is used to configure the low level width of SCL clock. + 0 + 14 + read-write + + + + + CTR + 0x4 + 0x20 + 0x00000003 + + + SDA_FORCE_OUT + 1: normally ouput sda data 0: exchange the function of sda_o and sda_oe (sda_o is the original internal output sda signal sda_oe is the enable bit for the internal output sda signal) + 0 + 1 + read-write + + + SCL_FORCE_OUT + 1: normally ouput scl clock 0: exchange the function of scl_o and scl_oe (scl_o is the original internal output scl signal scl_oe is the enable bit for the internal output scl signal) + 1 + 1 + read-write + + + SAMPLE_SCL_LEVEL + Set this bit to sample data in SCL low level. clear this bit to sample data in SCL high level. + 2 + 1 + read-write + + + MS_MODE + Set this bit to configure the module as i2c master clear this bit to configure the module as i2c slave. + 4 + 1 + read-write + + + TRANS_START + Set this bit to start sending data in txfifo. + 5 + 1 + read-write + + + TX_LSB_FIRST + This bit is used to control the sending mode for data need to be send. 1: receive data from most significant bit 0: receive data from least significant bit + 6 + 1 + read-write + + + RX_LSB_FIRST + This bit is used to control the storage mode for received datas. 1: receive data from most significant bit 0: receive data from least significant bit + 7 + 1 + read-write + + + CLK_EN + This is the clock gating control bit for reading or writing registers. + 8 + 1 + read-write + + + + + SR + 0x8 + 0x20 + + + ACK_REC + This register stores the value of ACK bit. + 0 + 1 + read-only + + + SLAVE_RW + when in slave mode 1: master read slave 0: master write slave. + 1 + 1 + read-only + + + TIME_OUT + when I2C takes more than time_out_reg clocks to receive a data then this register changes to high level. + 2 + 1 + read-only + + + ARB_LOST + when I2C lost control of SDA line this register changes to high level. + 3 + 1 + read-only + + + BUS_BUSY + 1:I2C bus is busy transferring data. 0:I2C bus is in idle state. + 4 + 1 + read-only + + + SLAVE_ADDRESSED + when configured as i2c slave and the address send by master is equal to slave's address then this bit will be high level. + 5 + 1 + read-only + + + BYTE_TRANS + This register changes to high level when one byte is transferred. + 6 + 1 + read-only + + + RXFIFO_CNT + This register represent the amount of data need to send. + 8 + 6 + read-only + + + TXFIFO_CNT + This register stores the amount of received data in ram. + 18 + 6 + read-only + + + SCL_MAIN_STATE_LAST + This register stores the value of state machine for i2c module. 3'h0: SCL_MAIN_IDLE 3'h1: SCL_ADDRESS_SHIFT 3'h2: SCL_ACK_ADDRESS 3'h3: SCL_RX_DATA 3'h4 SCL_TX_DATA 3'h5:SCL_SEND_ACK 3'h6:SCL_WAIT_ACK + 24 + 3 + read-only + + + SCL_STATE_LAST + This register stores the value of state machine to produce SCL. 3'h0: SCL_IDLE 3'h1:SCL_START 3'h2:SCL_LOW_EDGE 3'h3: SCL_LOW 3'h4:SCL_HIGH_EDGE 3'h5:SCL_HIGH 3'h6:SCL_STOP + 28 + 3 + read-only + + + + + TO + 0xC + 0x20 + + + TIME_OUT + This register is used to configure the max clock number of receiving a data. + 0 + 20 + read-write + + + + + SLAVE_ADDR + 0x10 + 0x20 + + + SLAVE_ADDR + when configured as i2c slave this register is used to configure slave's address. + 0 + 15 + read-write + + + ADDR_10BIT_EN + This register is used to enable slave 10bit address mode. + 31 + 1 + read-write + + + + + RXFIFO_ST + 0x14 + 0x20 + + + RXFIFO_START_ADDR + This is the offset address of the last receiving data as described in nonfifo_rx_thres_register. + 0 + 5 + read-only + + + RXFIFO_END_ADDR + This is the offset address of the first receiving data as described in nonfifo_rx_thres_register. + 5 + 5 + read-only + + + TXFIFO_START_ADDR + This is the offset address of the first sending data as described in nonfifo_tx_thres register. + 10 + 5 + read-only + + + TXFIFO_END_ADDR + This is the offset address of the last sending data as described in nonfifo_tx_thres register. + 15 + 5 + read-only + + + + + FIFO_CONF + 0x18 + 0x20 + 0x0155408B + + + RXFIFO_FULL_THRHD + 0 + 5 + read-write + + + TXFIFO_EMPTY_THRHD + Config txfifo empty threhd value when using apb fifo access + 5 + 5 + read-write + + + NONFIFO_EN + Set this bit to enble apb nonfifo access. + 10 + 1 + read-write + + + FIFO_ADDR_CFG_EN + When this bit is set to 1 then the byte after address represent the offset address of I2C Slave's ram. + 11 + 1 + read-write + + + RX_FIFO_RST + Set this bit to reset rx fifo when using apb fifo access. + 12 + 1 + read-write + + + TX_FIFO_RST + Set this bit to reset tx fifo when using apb fifo access. + 13 + 1 + read-write + + + NONFIFO_RX_THRES + when I2C receives more than nonfifo_rx_thres data it will produce rx_send_full_int_raw interrupt and update the current offset address of the receiving data. + 14 + 6 + read-write + + + NONFIFO_TX_THRES + when I2C sends more than nonfifo_tx_thres data it will produce tx_send_empty_int_raw interrupt and update the current offset address of the sending data. + 20 + 6 + read-write + + + + + DATA + 0x1C + 0x20 + + + FIFO_RDATA + The register represent the byte data read from rxfifo when use apb fifo access + 0 + 8 + read-only + + + + + INT_RAW + 0x20 + 0x20 + + + RXFIFO_FULL_INT_RAW + The raw interrupt status bit for rxfifo full when use apb fifo access. + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_RAW + The raw interrupt status bit for txfifo empty when use apb fifo access. + 1 + 1 + read-only + + + RXFIFO_OVF_INT_RAW + The raw interrupt status bit for receiving data overflow when use apb fifo access. + 2 + 1 + read-only + + + END_DETECT_INT_RAW + The raw interrupt status bit for end_detect_int interrupt. when I2C deals with the END command it will produce end_detect_int interrupt. + 3 + 1 + read-only + + + SLAVE_TRAN_COMP_INT_RAW + The raw interrupt status bit for slave_tran_comp_int interrupt. when I2C Slave detectsthe STOP bit it will produce slave_tran_comp_int interrupt. + 4 + 1 + read-only + + + ARBITRATION_LOST_INT_RAW + The raw interrupt status bit for arbitration_lost_int interrupt.when I2C lost the usage right of I2C BUS it will produce arbitration_lost_int interrupt. + 5 + 1 + read-only + + + MASTER_TRAN_COMP_INT_RAW + The raw interrupt status bit for master_tra_comp_int interrupt. when I2C Master sends or receives a byte it will produce master_tran_comp_int interrupt. + 6 + 1 + read-only + + + TRANS_COMPLETE_INT_RAW + The raw interrupt status bit for trans_complete_int interrupt. when I2C Master finished STOP command it will produce trans_complete_int interrupt. + 7 + 1 + read-only + + + TIME_OUT_INT_RAW + The raw interrupt status bit for time_out_int interrupt. when I2C takes a lot of time to receive a data it will produce time_out_int interrupt. + 8 + 1 + read-only + + + TRANS_START_INT_RAW + The raw interrupt status bit for trans_start_int interrupt. when I2C sends the START bit it will produce trans_start_int interrupt. + 9 + 1 + read-only + + + ACK_ERR_INT_RAW + The raw interrupt status bit for ack_err_int interrupt. when I2C receives a wrong ACK bit it will produce ack_err_int interrupt.. + 10 + 1 + read-only + + + RX_REC_FULL_INT_RAW + The raw interrupt status bit for rx_rec_full_int interrupt. when I2C receives more data than nonfifo_rx_thres it will produce rx_rec_full_int interrupt. + 11 + 1 + read-only + + + TX_SEND_EMPTY_INT_RAW + The raw interrupt status bit for tx_send_empty_int interrupt.when I2C sends more data than nonfifo_tx_thres it will produce tx_send_empty_int interrupt.. + 12 + 1 + read-only + + + + + INT_CLR + 0x24 + 0x20 + + + RXFIFO_FULL_INT_CLR + Set this bit to clear the rxfifo_full_int interrupt. + 0 + 1 + write-only + + + TXFIFO_EMPTY_INT_CLR + Set this bit to clear the txfifo_empty_int interrupt. + 1 + 1 + write-only + + + RXFIFO_OVF_INT_CLR + Set this bit to clear the rxfifo_ovf_int interrupt. + 2 + 1 + write-only + + + END_DETECT_INT_CLR + Set this bit to clear the end_detect_int interrupt. + 3 + 1 + write-only + + + SLAVE_TRAN_COMP_INT_CLR + Set this bit to clear the slave_tran_comp_int interrupt. + 4 + 1 + write-only + + + ARBITRATION_LOST_INT_CLR + Set this bit to clear the arbitration_lost_int interrupt. + 5 + 1 + write-only + + + MASTER_TRAN_COMP_INT_CLR + Set this bit to clear the master_tran_comp interrupt. + 6 + 1 + write-only + + + TRANS_COMPLETE_INT_CLR + Set this bit to clear the trans_complete_int interrupt. + 7 + 1 + write-only + + + TIME_OUT_INT_CLR + Set this bit to clear the time_out_int interrupt. + 8 + 1 + write-only + + + TRANS_START_INT_CLR + Set this bit to clear the trans_start_int interrupt. + 9 + 1 + write-only + + + ACK_ERR_INT_CLR + Set this bit to clear the ack_err_int interrupt. + 10 + 1 + write-only + + + RX_REC_FULL_INT_CLR + Set this bit to clear the rx_rec_full_int interrupt. + 11 + 1 + write-only + + + TX_SEND_EMPTY_INT_CLR + Set this bit to clear the tx_send_empty_int interrupt. + 12 + 1 + write-only + + + + + INT_ENA + 0x28 + 0x20 + + + RXFIFO_FULL_INT_ENA + The enable bit for rxfifo_full_int interrupt. + 0 + 1 + read-write + + + TXFIFO_EMPTY_INT_ENA + The enable bit for txfifo_empty_int interrupt. + 1 + 1 + read-write + + + RXFIFO_OVF_INT_ENA + The enable bit for rxfifo_ovf_int interrupt. + 2 + 1 + read-write + + + END_DETECT_INT_ENA + The enable bit for end_detect_int interrupt. + 3 + 1 + read-write + + + SLAVE_TRAN_COMP_INT_ENA + The enable bit for slave_tran_comp_int interrupt. + 4 + 1 + read-write + + + ARBITRATION_LOST_INT_ENA + The enable bit for arbitration_lost_int interrupt. + 5 + 1 + read-write + + + MASTER_TRAN_COMP_INT_ENA + The enable bit for master_tran_comp_int interrupt. + 6 + 1 + read-write + + + TRANS_COMPLETE_INT_ENA + The enable bit for trans_complete_int interrupt. + 7 + 1 + read-write + + + TIME_OUT_INT_ENA + The enable bit for time_out_int interrupt. + 8 + 1 + read-write + + + TRANS_START_INT_ENA + The enable bit for trans_start_int interrupt. + 9 + 1 + read-write + + + ACK_ERR_INT_ENA + The enable bit for ack_err_int interrupt. + 10 + 1 + read-write + + + RX_REC_FULL_INT_ENA + The enable bit for rx_rec_full_int interrupt. + 11 + 1 + read-write + + + TX_SEND_EMPTY_INT_ENA + The enable bit for tx_send_empty_int interrupt. + 12 + 1 + read-write + + + + + INT_STATUS + 0x2C + 0x20 + + + RXFIFO_FULL_INT_ST + The masked interrupt status for rxfifo_full_int interrupt. + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_ST + The masked interrupt status for txfifo_empty_int interrupt. + 1 + 1 + read-only + + + RXFIFO_OVF_INT_ST + The masked interrupt status for rxfifo_ovf_int interrupt. + 2 + 1 + read-only + + + END_DETECT_INT_ST + The masked interrupt status for end_detect_int interrupt. + 3 + 1 + read-only + + + SLAVE_TRAN_COMP_INT_ST + The masked interrupt status for slave_tran_comp_int interrupt. + 4 + 1 + read-only + + + ARBITRATION_LOST_INT_ST + The masked interrupt status for arbitration_lost_int interrupt. + 5 + 1 + read-only + + + MASTER_TRAN_COMP_INT_ST + The masked interrupt status for master_tran_comp_int interrupt. + 6 + 1 + read-only + + + TRANS_COMPLETE_INT_ST + The masked interrupt status for trans_complete_int interrupt. + 7 + 1 + read-only + + + TIME_OUT_INT_ST + The masked interrupt status for time_out_int interrupt. + 8 + 1 + read-only + + + TRANS_START_INT_ST + The masked interrupt status for trans_start_int interrupt. + 9 + 1 + read-only + + + ACK_ERR_INT_ST + The masked interrupt status for ack_err_int interrupt. + 10 + 1 + read-only + + + RX_REC_FULL_INT_ST + The masked interrupt status for rx_rec_full_int interrupt. + 11 + 1 + read-only + + + TX_SEND_EMPTY_INT_ST + The masked interrupt status for tx_send_empty_int interrupt. + 12 + 1 + read-only + + + + + SDA_HOLD + 0x30 + 0x20 + + + TIME + This register is used to configure the clock num I2C used to hold the data after the negedge of SCL. + 0 + 10 + read-write + + + + + SDA_SAMPLE + 0x34 + 0x20 + + + TIME + This register is used to configure the clock num I2C used to sample data on SDA after the posedge of SCL + 0 + 10 + read-write + + + + + SCL_HIGH_PERIOD + 0x38 + 0x20 + + + SCL_HIGH_PERIOD + This register is used to configure the clock num during SCL is low level. + 0 + 14 + read-write + + + + + SCL_START_HOLD + 0x40 + 0x20 + 0x00000008 + + + TIME + This register is used to configure the clock num between the negedge of SDA and negedge of SCL for start mark. + 0 + 10 + read-write + + + + + SCL_RSTART_SETUP + 0x44 + 0x20 + 0x00000008 + + + TIME + This register is used to configure the clock num between the posedge of SCL and the negedge of SDA for restart mark. + 0 + 10 + read-write + + + + + SCL_STOP_HOLD + 0x48 + 0x20 + + + TIME + This register is used to configure the clock num after the STOP bit's posedge. + 0 + 14 + read-write + + + + + SCL_STOP_SETUP + 0x4C + 0x20 + + + TIME + This register is used to configure the clock num between the posedge of SCL and the posedge of SDA. + 0 + 10 + read-write + + + + + SCL_FILTER_CFG + 0x50 + 0x20 + 0x00000008 + + + SCL_FILTER_THRES + When input SCL's pulse width is smaller than this register value I2C ignores this pulse. + 0 + 3 + read-write + + + SCL_FILTER_EN + This is the filter enable bit for SCL. + 3 + 1 + read-write + + + + + SDA_FILTER_CFG + 0x54 + 0x20 + 0x00000008 + + + SDA_FILTER_THRES + When input SCL's pulse width is smaller than this register value I2C ignores this pulse. + 0 + 3 + read-write + + + SDA_FILTER_EN + This is the filter enable bit for SDA. + 3 + 1 + read-write + + + + + 16 + 0x4 + 0-15 + COMD%s + 0x58 + 0x20 + + + COMMAND + This is the content of command0. It consists of three part. op_code is the command 0: RSTART 1: WRITE 2: READ 3: STOP . 4:END. Byte_num represent the number of data need to be send or data need to be received. ack_check_en ack_exp and ack value are used to control the ack bit. + 0 + 14 + read-write + + + COMMAND_DONE + When command0 is done in I2C Master mode this bit changes to high level. + 31 + 1 + read-write + + + + + DATE + 0xF8 + 0x20 + 0x16042000 + + + DATE + 0 + 32 + read-write + + + + + FIFO_START_ADDR + 0x100 + 0x20 + + + + + I2C1 + I2C (Inter-Integrated Circuit) Controller + 0x3FF67000 + + I2C_EXT1 + 50 + + + + I2S0 + I2S (Inter-IC Sound) Controller + I2S + 0x3FF4F000 + + 0x0 + 0xB4 + registers + + + I2S0 + 32 + + + + CONF + 0x8 + 0x20 + 0x00030300 + + + TX_RESET + 0 + 1 + read-write + + + RX_RESET + 1 + 1 + read-write + + + TX_FIFO_RESET + 2 + 1 + read-write + + + RX_FIFO_RESET + 3 + 1 + read-write + + + TX_START + 4 + 1 + read-write + + + RX_START + 5 + 1 + read-write + + + TX_SLAVE_MOD + 6 + 1 + read-write + + + RX_SLAVE_MOD + 7 + 1 + read-write + + + TX_RIGHT_FIRST + 8 + 1 + read-write + + + RX_RIGHT_FIRST + 9 + 1 + read-write + + + TX_MSB_SHIFT + 10 + 1 + read-write + + + RX_MSB_SHIFT + 11 + 1 + read-write + + + TX_SHORT_SYNC + 12 + 1 + read-write + + + RX_SHORT_SYNC + 13 + 1 + read-write + + + TX_MONO + 14 + 1 + read-write + + + RX_MONO + 15 + 1 + read-write + + + TX_MSB_RIGHT + 16 + 1 + read-write + + + RX_MSB_RIGHT + 17 + 1 + read-write + + + SIG_LOOPBACK + 18 + 1 + read-write + + + + + INT_RAW + 0xC + 0x20 + + + RX_TAKE_DATA_INT_RAW + 0 + 1 + read-only + + + TX_PUT_DATA_INT_RAW + 1 + 1 + read-only + + + RX_WFULL_INT_RAW + 2 + 1 + read-only + + + RX_REMPTY_INT_RAW + 3 + 1 + read-only + + + TX_WFULL_INT_RAW + 4 + 1 + read-only + + + TX_REMPTY_INT_RAW + 5 + 1 + read-only + + + RX_HUNG_INT_RAW + 6 + 1 + read-only + + + TX_HUNG_INT_RAW + 7 + 1 + read-only + + + IN_DONE_INT_RAW + 8 + 1 + read-only + + + IN_SUC_EOF_INT_RAW + 9 + 1 + read-only + + + IN_ERR_EOF_INT_RAW + 10 + 1 + read-only + + + OUT_DONE_INT_RAW + 11 + 1 + read-only + + + OUT_EOF_INT_RAW + 12 + 1 + read-only + + + IN_DSCR_ERR_INT_RAW + 13 + 1 + read-only + + + OUT_DSCR_ERR_INT_RAW + 14 + 1 + read-only + + + IN_DSCR_EMPTY_INT_RAW + 15 + 1 + read-only + + + OUT_TOTAL_EOF_INT_RAW + 16 + 1 + read-only + + + + + INT_ST + 0x10 + 0x20 + + + RX_TAKE_DATA_INT_ST + 0 + 1 + read-only + + + TX_PUT_DATA_INT_ST + 1 + 1 + read-only + + + RX_WFULL_INT_ST + 2 + 1 + read-only + + + RX_REMPTY_INT_ST + 3 + 1 + read-only + + + TX_WFULL_INT_ST + 4 + 1 + read-only + + + TX_REMPTY_INT_ST + 5 + 1 + read-only + + + RX_HUNG_INT_ST + 6 + 1 + read-only + + + TX_HUNG_INT_ST + 7 + 1 + read-only + + + IN_DONE_INT_ST + 8 + 1 + read-only + + + IN_SUC_EOF_INT_ST + 9 + 1 + read-only + + + IN_ERR_EOF_INT_ST + 10 + 1 + read-only + + + OUT_DONE_INT_ST + 11 + 1 + read-only + + + OUT_EOF_INT_ST + 12 + 1 + read-only + + + IN_DSCR_ERR_INT_ST + 13 + 1 + read-only + + + OUT_DSCR_ERR_INT_ST + 14 + 1 + read-only + + + IN_DSCR_EMPTY_INT_ST + 15 + 1 + read-only + + + OUT_TOTAL_EOF_INT_ST + 16 + 1 + read-only + + + + + INT_ENA + 0x14 + 0x20 + + + RX_TAKE_DATA_INT_ENA + 0 + 1 + read-write + + + TX_PUT_DATA_INT_ENA + 1 + 1 + read-write + + + RX_WFULL_INT_ENA + 2 + 1 + read-write + + + RX_REMPTY_INT_ENA + 3 + 1 + read-write + + + TX_WFULL_INT_ENA + 4 + 1 + read-write + + + TX_REMPTY_INT_ENA + 5 + 1 + read-write + + + RX_HUNG_INT_ENA + 6 + 1 + read-write + + + TX_HUNG_INT_ENA + 7 + 1 + read-write + + + IN_DONE_INT_ENA + 8 + 1 + read-write + + + IN_SUC_EOF_INT_ENA + 9 + 1 + read-write + + + IN_ERR_EOF_INT_ENA + 10 + 1 + read-write + + + OUT_DONE_INT_ENA + 11 + 1 + read-write + + + OUT_EOF_INT_ENA + 12 + 1 + read-write + + + IN_DSCR_ERR_INT_ENA + 13 + 1 + read-write + + + OUT_DSCR_ERR_INT_ENA + 14 + 1 + read-write + + + IN_DSCR_EMPTY_INT_ENA + 15 + 1 + read-write + + + OUT_TOTAL_EOF_INT_ENA + 16 + 1 + read-write + + + + + INT_CLR + 0x18 + 0x20 + + + TAKE_DATA_INT_CLR + 0 + 1 + write-only + + + PUT_DATA_INT_CLR + 1 + 1 + write-only + + + RX_WFULL_INT_CLR + 2 + 1 + write-only + + + RX_REMPTY_INT_CLR + 3 + 1 + write-only + + + TX_WFULL_INT_CLR + 4 + 1 + write-only + + + TX_REMPTY_INT_CLR + 5 + 1 + write-only + + + RX_HUNG_INT_CLR + 6 + 1 + write-only + + + TX_HUNG_INT_CLR + 7 + 1 + write-only + + + IN_DONE_INT_CLR + 8 + 1 + write-only + + + IN_SUC_EOF_INT_CLR + 9 + 1 + write-only + + + IN_ERR_EOF_INT_CLR + 10 + 1 + write-only + + + OUT_DONE_INT_CLR + 11 + 1 + write-only + + + OUT_EOF_INT_CLR + 12 + 1 + write-only + + + IN_DSCR_ERR_INT_CLR + 13 + 1 + write-only + + + OUT_DSCR_ERR_INT_CLR + 14 + 1 + write-only + + + IN_DSCR_EMPTY_INT_CLR + 15 + 1 + write-only + + + OUT_TOTAL_EOF_INT_CLR + 16 + 1 + write-only + + + + + TIMING + 0x1C + 0x20 + + + TX_BCK_IN_DELAY + 0 + 2 + read-write + + + TX_WS_IN_DELAY + 2 + 2 + read-write + + + RX_BCK_IN_DELAY + 4 + 2 + read-write + + + RX_WS_IN_DELAY + 6 + 2 + read-write + + + RX_SD_IN_DELAY + 8 + 2 + read-write + + + TX_BCK_OUT_DELAY + 10 + 2 + read-write + + + TX_WS_OUT_DELAY + 12 + 2 + read-write + + + TX_SD_OUT_DELAY + 14 + 2 + read-write + + + RX_WS_OUT_DELAY + 16 + 2 + read-write + + + RX_BCK_OUT_DELAY + 18 + 2 + read-write + + + TX_DSYNC_SW + 20 + 1 + read-write + + + RX_DSYNC_SW + 21 + 1 + read-write + + + DATA_ENABLE_DELAY + 22 + 2 + read-write + + + TX_BCK_IN_INV + 24 + 1 + read-write + + + + + FIFO_CONF + 0x20 + 0x20 + 0x00001820 + + + RX_DATA_NUM + 0 + 6 + read-write + + + TX_DATA_NUM + 6 + 6 + read-write + + + DSCR_EN + 12 + 1 + read-write + + + TX_FIFO_MOD + 13 + 3 + read-write + + + RX_FIFO_MOD + 16 + 3 + read-write + + + TX_FIFO_MOD_FORCE_EN + 19 + 1 + read-write + + + RX_FIFO_MOD_FORCE_EN + 20 + 1 + read-write + + + + + RXEOF_NUM + 0x24 + 0x20 + 0x00000040 + + + RX_EOF_NUM + 0 + 32 + read-write + + + + + CONF_SIGLE_DATA + 0x28 + 0x20 + + + SIGLE_DATA + 0 + 32 + read-write + + + + + CONF_CHAN + 0x2C + 0x20 + + + TX_CHAN_MOD + 0 + 3 + read-write + + + RX_CHAN_MOD + 3 + 2 + read-write + + + + + OUT_LINK + 0x30 + 0x20 + + + OUTLINK_ADDR + 0 + 20 + read-write + + + OUTLINK_STOP + 28 + 1 + read-write + + + OUTLINK_START + 29 + 1 + read-write + + + OUTLINK_RESTART + 30 + 1 + read-write + + + OUTLINK_PARK + 31 + 1 + read-only + + + + + IN_LINK + 0x34 + 0x20 + + + INLINK_ADDR + 0 + 20 + read-write + + + INLINK_STOP + 28 + 1 + read-write + + + INLINK_START + 29 + 1 + read-write + + + INLINK_RESTART + 30 + 1 + read-write + + + INLINK_PARK + 31 + 1 + read-only + + + + + OUT_EOF_DES_ADDR + 0x38 + 0x20 + + + OUT_EOF_DES_ADDR + 0 + 32 + read-only + + + + + IN_EOF_DES_ADDR + 0x3C + 0x20 + + + IN_SUC_EOF_DES_ADDR + 0 + 32 + read-only + + + + + OUT_EOF_BFR_DES_ADDR + 0x40 + 0x20 + + + OUT_EOF_BFR_DES_ADDR + 0 + 32 + read-only + + + + + AHB_TEST + 0x44 + 0x20 + + + AHB_TESTMODE + 0 + 3 + read-write + + + AHB_TESTADDR + 4 + 2 + read-write + + + + + INLINK_DSCR + 0x48 + 0x20 + + + INLINK_DSCR + 0 + 32 + read-only + + + + + INLINK_DSCR_BF0 + 0x4C + 0x20 + + + INLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + INLINK_DSCR_BF1 + 0x50 + 0x20 + + + INLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + OUTLINK_DSCR + 0x54 + 0x20 + + + OUTLINK_DSCR + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF0 + 0x58 + 0x20 + + + OUTLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF1 + 0x5C + 0x20 + + + OUTLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + LC_CONF + 0x60 + 0x20 + 0x00000100 + + + IN_RST + 0 + 1 + read-write + + + OUT_RST + 1 + 1 + read-write + + + AHBM_FIFO_RST + 2 + 1 + read-write + + + AHBM_RST + 3 + 1 + read-write + + + OUT_LOOP_TEST + 4 + 1 + read-write + + + IN_LOOP_TEST + 5 + 1 + read-write + + + OUT_AUTO_WRBACK + 6 + 1 + read-write + + + OUT_NO_RESTART_CLR + 7 + 1 + read-write + + + OUT_EOF_MODE + 8 + 1 + read-write + + + OUTDSCR_BURST_EN + 9 + 1 + read-write + + + INDSCR_BURST_EN + 10 + 1 + read-write + + + OUT_DATA_BURST_EN + 11 + 1 + read-write + + + CHECK_OWNER + 12 + 1 + read-write + + + MEM_TRANS_EN + 13 + 1 + read-write + + + + + OUTFIFO_PUSH + 0x64 + 0x20 + + + OUTFIFO_WDATA + 0 + 9 + read-write + + + OUTFIFO_PUSH + 16 + 1 + read-write + + + + + INFIFO_POP + 0x68 + 0x20 + + + INFIFO_RDATA + 0 + 12 + read-only + + + INFIFO_POP + 16 + 1 + read-write + + + + + LC_STATE0 + 0x6C + 0x20 + + + LC_STATE0 + 0 + 32 + read-only + + + + + LC_STATE1 + 0x70 + 0x20 + + + LC_STATE1 + 0 + 32 + read-only + + + + + LC_HUNG_CONF + 0x74 + 0x20 + 0x00000810 + + + LC_FIFO_TIMEOUT + 0 + 8 + read-write + + + LC_FIFO_TIMEOUT_SHIFT + 8 + 3 + read-write + + + LC_FIFO_TIMEOUT_ENA + 11 + 1 + read-write + + + + + CVSD_CONF0 + 0x80 + 0x20 + 0x80007FFF + + + CVSD_Y_MAX + 0 + 16 + read-write + + + CVSD_Y_MIN + 16 + 16 + read-write + + + + + CVSD_CONF1 + 0x84 + 0x20 + 0x000A0500 + + + CVSD_SIGMA_MAX + 0 + 16 + read-write + + + CVSD_SIGMA_MIN + 16 + 16 + read-write + + + + + CVSD_CONF2 + 0x88 + 0x20 + 0x000502A4 + + + CVSD_K + 0 + 3 + read-write + + + CVSD_J + 3 + 3 + read-write + + + CVSD_BETA + 6 + 10 + read-write + + + CVSD_H + 16 + 3 + read-write + + + + + PLC_CONF0 + 0x8C + 0x20 + 0x08A80339 + + + GOOD_PACK_MAX + 0 + 6 + read-write + + + N_ERR_SEG + 6 + 3 + read-write + + + SHIFT_RATE + 9 + 3 + read-write + + + MAX_SLIDE_SAMPLE + 12 + 8 + read-write + + + PACK_LEN_8K + 20 + 5 + read-write + + + N_MIN_ERR + 25 + 3 + read-write + + + + + PLC_CONF1 + 0x90 + 0x20 + 0xA0178A05 + + + BAD_CEF_ATTEN_PARA + 0 + 8 + read-write + + + BAD_CEF_ATTEN_PARA_SHIFT + 8 + 4 + read-write + + + BAD_OLA_WIN2_PARA_SHIFT + 12 + 4 + read-write + + + BAD_OLA_WIN2_PARA + 16 + 8 + read-write + + + SLIDE_WIN_LEN + 24 + 8 + read-write + + + + + PLC_CONF2 + 0x94 + 0x20 + 0x00000028 + + + CVSD_SEG_MOD + 0 + 2 + read-write + + + MIN_PERIOD + 2 + 5 + read-write + + + + + ESCO_CONF0 + 0x98 + 0x20 + + + ESCO_EN + 0 + 1 + read-write + + + ESCO_CHAN_MOD + 1 + 1 + read-write + + + ESCO_CVSD_DEC_PACK_ERR + 2 + 1 + read-write + + + ESCO_CVSD_PACK_LEN_8K + 3 + 5 + read-write + + + ESCO_CVSD_INF_EN + 8 + 1 + read-write + + + CVSD_DEC_START + 9 + 1 + read-write + + + CVSD_DEC_RESET + 10 + 1 + read-write + + + PLC_EN + 11 + 1 + read-write + + + PLC2DMA_EN + 12 + 1 + read-write + + + + + SCO_CONF0 + 0x9C + 0x20 + + + SCO_WITH_I2S_EN + 0 + 1 + read-write + + + SCO_NO_I2S_EN + 1 + 1 + read-write + + + CVSD_ENC_START + 2 + 1 + read-write + + + CVSD_ENC_RESET + 3 + 1 + read-write + + + + + CONF1 + 0xA0 + 0x20 + 0x00000089 + + + TX_PCM_CONF + 0 + 3 + read-write + + + TX_PCM_BYPASS + 3 + 1 + read-write + + + RX_PCM_CONF + 4 + 3 + read-write + + + RX_PCM_BYPASS + 7 + 1 + read-write + + + TX_STOP_EN + 8 + 1 + read-write + + + TX_ZEROS_RM_EN + 9 + 1 + read-write + + + + + PD_CONF + 0xA4 + 0x20 + 0x0000000A + + + FIFO_FORCE_PD + 0 + 1 + read-write + + + FIFO_FORCE_PU + 1 + 1 + read-write + + + PLC_MEM_FORCE_PD + 2 + 1 + read-write + + + PLC_MEM_FORCE_PU + 3 + 1 + read-write + + + + + CONF2 + 0xA8 + 0x20 + + + CAMERA_EN + 0 + 1 + read-write + + + LCD_TX_WRX2_EN + 1 + 1 + read-write + + + LCD_TX_SDX2_EN + 2 + 1 + read-write + + + DATA_ENABLE_TEST_EN + 3 + 1 + read-write + + + DATA_ENABLE + 4 + 1 + read-write + + + LCD_EN + 5 + 1 + read-write + + + EXT_ADC_START_EN + 6 + 1 + read-write + + + INTER_VALID_EN + 7 + 1 + read-write + + + + + CLKM_CONF + 0xAC + 0x20 + 0x00000004 + + + CLKM_DIV_NUM + 0 + 8 + read-write + + + CLKM_DIV_B + 8 + 6 + read-write + + + CLKM_DIV_A + 14 + 6 + read-write + + + CLK_EN + 20 + 1 + read-write + + + CLKA_ENA + 21 + 1 + read-write + + + + + SAMPLE_RATE_CONF + 0xB0 + 0x20 + 0x00410186 + + + TX_BCK_DIV_NUM + 0 + 6 + read-write + + + RX_BCK_DIV_NUM + 6 + 6 + read-write + + + TX_BITS_MOD + 12 + 6 + read-write + + + RX_BITS_MOD + 18 + 6 + read-write + + + + + PDM_CONF + 0xB4 + 0x20 + 0x01550020 + + + TX_PDM_EN + 0 + 1 + read-write + + + RX_PDM_EN + 1 + 1 + read-write + + + PCM2PDM_CONV_EN + 2 + 1 + read-write + + + PDM2PCM_CONV_EN + 3 + 1 + read-write + + + TX_PDM_SINC_OSR2 + 4 + 4 + read-write + + + TX_PDM_PRESCALE + 8 + 8 + read-write + + + TX_PDM_HP_IN_SHIFT + 16 + 2 + read-write + + + TX_PDM_LP_IN_SHIFT + 18 + 2 + read-write + + + TX_PDM_SINC_IN_SHIFT + 20 + 2 + read-write + + + TX_PDM_SIGMADELTA_IN_SHIFT + 22 + 2 + read-write + + + RX_PDM_SINC_DSR_16_EN + 24 + 1 + read-write + + + TX_PDM_HP_BYPASS + 25 + 1 + read-write + + + + + PDM_FREQ_CONF + 0xB8 + 0x20 + 0x000F01E0 + + + TX_PDM_FS + 0 + 10 + read-write + + + TX_PDM_FP + 10 + 10 + read-write + + + + + STATE + 0xBC + 0x20 + 0x00000007 + + + TX_IDLE + 0 + 1 + read-only + + + TX_FIFO_RESET_BACK + 1 + 1 + read-only + + + RX_FIFO_RESET_BACK + 2 + 1 + read-only + + + + + DATE + 0xFC + 0x20 + 0x01604201 + + + I2SDATE + 0 + 32 + read-write + + + + + + + I2S1 + I2S (Inter-IC Sound) Controller + 0x3FF6D000 + + I2S1 + 33 + + + + IO_MUX + Input/Output Multiplexer + IO_MUX + 0x3FF49000 + + 0x0 + 0x94 + registers + + + + PIN_CTRL + 0x0 + 0x20 + + + CLK1 + If you want to output clock for I2S0 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0x0; CLK_OUT2, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[11:8] = 0x0. If you want to output clock for I2S1 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0xF; CLK_OUT2, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[11:8] = 0x0. + 0 + 4 + read-write + + + CLK2 + If you want to output clock for I2S0 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0x0; CLK_OUT2, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[11:8] = 0x0. If you want to output clock for I2S1 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0xF; CLK_OUT2, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[11:8] = 0x0. + 4 + 4 + read-write + + + CLK3 + If you want to output clock for I2S0 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0x0; CLK_OUT2, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0x0 and PIN_CTRL[11:8] = 0x0. If you want to output clock for I2S1 to: CLK_OUT1, then set PIN_CTRL[3:0] = 0xF; CLK_OUT2, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[7:4] = 0x0; CLK_OUT3, then set PIN_CTRL[3:0] = 0xF and PIN_CTRL[11:8] = 0x0. + 8 + 4 + read-write + + + + + GPIO36 + 0x4 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO37 + 0x8 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO38 + 0xC + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO39 + 0x10 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO34 + 0x14 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO35 + 0x18 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO32 + 0x1C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO33 + 0x20 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO25 + 0x24 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO26 + 0x28 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO27 + 0x2C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO14 + 0x30 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO12 + 0x34 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO13 + 0x38 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO15 + 0x3C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO2 + 0x40 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO0 + 0x44 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO4 + 0x48 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO16 + 0x4C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO17 + 0x50 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO9 + 0x54 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO10 + 0x58 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO11 + 0x5C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO6 + 0x60 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO7 + 0x64 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO8 + 0x68 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO5 + 0x6C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO18 + 0x70 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO19 + 0x74 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO20 + 0x78 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO21 + 0x7C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO22 + 0x80 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO3 + 0x84 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO1 + 0x88 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO23 + 0x8C + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + GPIO24 + 0x90 + 0x20 + + + MCU_OE + Output enable of the pad in sleep mode. 1: enable output; 0: disable output. + 0 + 1 + read-write + + + SLP_SEL + Sleep mode selection of this pad. Set to 1 to put the pad in sleep mode. + 1 + 1 + read-write + + + MCU_WPD + Pull-down enable of the pad during sleep mode. 1: internal pull-down enabled; 0: internal pull-down disabled. + 2 + 1 + read-write + + + MCU_WPU + Pull-up enable of the pad during sleep mode. 1: internal pull-up enabled; 0: internal pull-up disabled. + 3 + 1 + read-write + + + MCU_IE + Input enable of the pad during sleep mode. 1: input enabled; 0: input disabled. + 4 + 1 + read-write + + + MCU_DRV + Select the drive strength of the pad during sleep mode. A higher value corresponds with a higher strength. + 5 + 2 + read-write + + + FUN_WPD + Pull-down enable of the pad. 1: internal pull-down enabled, 0: internal pull-down disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull-down circuitry, therefore, their FUN_WPD is always 0. + 7 + 1 + read-write + + + FUN_WPU + Pull-up enable of the pad. 1: internal pull-up enabled; 0: internal pull-up disabled. GPIO pins 34-39 are input-only. These pins do not feature an output driver or internal pull- up/pull- down circuitry, therefore, their FUN_WPU is always 0. + 8 + 1 + read-write + + + FUN_IE + Input enable of the pad. 1: input enabled; 0: input disabled. + 9 + 1 + read-write + + + FUN_DRV + Select the drive strength of the pad. A higher value corresponds with a higher strength. For GPIO34-39, FUN_DRV is always 0. For detailed drive strength, please see note 8 in Table ”Notes on ESP32 Pin Lists”, in ESP32 Datasheet. + 10 + 2 + read-write + + + MCU_SEL + Select the IO_MUX function for this signal. 0 selects Function 0, 1 selects Function 1, etc. + 12 + 3 + read-write + + + + + + + LEDC + LED Control PWM (Pulse Width Modulation) + LEDC + 0x3FF59000 + + 0x0 + 0x198 + registers + + + LEDC + 43 + + + TIMER1 + 56 + + + TIMER2 + 57 + + + + 8 + 0x14 + 0-7 + HSCH%s_CONF0 + 0x0 + 0x20 + + + TIMER_SEL + There are four high speed timers the two bits are used to select one of them for high speed channel0. 2'b00: seletc hstimer0. 2'b01: select hstimer1. 2'b10: select hstimer2. 2'b11: select hstimer3. + 0 + 2 + read-write + + + SIG_OUT_EN + This is the output enable control bit for high speed channel0 + 2 + 1 + read-write + + + IDLE_LV + This bit is used to control the output value when high speed channel0 is off. + 3 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_HPOINT + 0x4 + 0x20 + + + HPOINT + The output value changes to high when htimerx(x=[0 3]) selected by high speed channel0 has reached reg_hpoint_hsch0[19:0] + 0 + 20 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_DUTY + 0x8 + 0x20 + + + DUTY + This register represents the current duty of the output signal for high speed channel0. + 0 + 25 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_CONF1 + 0xC + 0x20 + 0x40000000 + + + DUTY_SCALE + This register controls the increase or decrease step scale for high speed channel0. + 0 + 10 + read-write + + + DUTY_CYCLE + This register is used to increase or decrease the duty every reg_duty_cycle_hsch0 cycles for high speed channel0. + 10 + 10 + read-write + + + DUTY_NUM + This register is used to control the num of increased or decreased times for high speed channel0. + 20 + 10 + read-write + + + DUTY_INC + This register is used to increase the duty of output signal or decrease the duty of output signal for high speed channel0. + 30 + 1 + read-write + + + DUTY_START + When reg_duty_num_hsch0 reg_duty_cycle_hsch0 and reg_duty_scale_hsch0 has been configured. these register won't take effect until set reg_duty_start_hsch0. this bit is automatically cleared by hardware. + 31 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + HSCH%s_DUTY_R + 0x10 + 0x20 + + + DUTY_R + This register represents the current duty cycle of the output signal for high-speed channel %s + 0 + 25 + read-only + + + + + 8 + 0x14 + 0-7 + LSCH%s_CONF0 + 0xA0 + 0x20 + + + TIMER_SEL + There are four low speed timers the two bits are used to select one of them for low speed channel0. 2'b00: seletc lstimer0. 2'b01: select lstimer1. 2'b10: select lstimer2. 2'b11: select lstimer3. + 0 + 2 + read-write + + + SIG_OUT_EN + This is the output enable control bit for low speed channel0. + 2 + 1 + read-write + + + IDLE_LV + This bit is used to control the output value when low speed channel0 is off. + 3 + 1 + read-write + + + PARA_UP + This bit is used to update register LEDC_LSCH0_HPOINT and LEDC_LSCH0_DUTY for low speed channel0. + 4 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_HPOINT + 0xA4 + 0x20 + + + HPOINT + The output value changes to high when lstimerx(x=[0 3]) selected by low speed channel0 has reached reg_hpoint_lsch0[19:0] + 0 + 20 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_DUTY + 0xA8 + 0x20 + read-write + + + DUTY + This register represents the current duty of the output signal for low speed channel0. + 0 + 25 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_CONF1 + 0xAC + 0x20 + 0x40000000 + + + DUTY_SCALE + This register controls the increase or decrease step scale for low speed channel0. + 0 + 10 + read-write + + + DUTY_CYCLE + This register is used to increase or decrease the duty every reg_duty_cycle_lsch0 cycles for low speed channel0. + 10 + 10 + read-write + + + DUTY_NUM + This register is used to control the num of increased or decreased times for low speed channel6. + 20 + 10 + read-write + + + DUTY_INC + This register is used to increase the duty of output signal or decrease the duty of output signal for low speed channel6. + 30 + 1 + read-write + + + DUTY_START + When reg_duty_num_hsch1 reg_duty_cycle_hsch1 and reg_duty_scale_hsch1 has been configured. these register won't take effect until set reg_duty_start_hsch1. this bit is automatically cleared by hardware. + 31 + 1 + read-write + + + + + 8 + 0x14 + 0-7 + LSCH%s_DUTY_R + 0xB0 + 0x20 + + + DUTY_R + This register represents the current duty cycle of the output signal for low-speed channel %s + 0 + 25 + read-only + + + + + 4 + 0x8 + 0-3 + HSTIMER%s_CONF + 0x140 + 0x20 + 0x01000000 + + + DUTY_RES + This register controls the range of the counter in high speed timer0. the counter range is [0 2**reg_hstimer0_lim] the max bit width for counter is 20. + 0 + 5 + read-write + + + DIV_NUM + This register is used to configure parameter for divider in high speed timer0 the least significant eight bits represent the decimal part. + 5 + 18 + read-write + + + PAUSE + This bit is used to pause the counter in high speed timer0 + 23 + 1 + read-write + + + RST + This bit is used to reset high speed timer0 the counter will be 0 after reset. + 24 + 1 + read-write + + + TICK_SEL + This bit is used to choose apb_clk or ref_tick for high speed timer0. 1'b1:apb_clk 0:ref_tick + 25 + 1 + read-write + + + LIM + 31 + 5 + read-write + + + + + 4 + 0x8 + 0-3 + HSTIMER%s_VALUE + 0x144 + 0x20 + + + CNT + software can read this register to get the current counter value in high speed timer0 + 0 + 20 + read-only + + + + + 4 + 0x8 + 0-3 + LSTIMER%s_CONF + 0x160 + 0x20 + 0x01000000 + + + DUTY_RES + This register controls the range of the counter in low speed timer0. the counter range is [0 2**reg_lstimer0_lim] the max bit width for counter is 20. + 0 + 5 + read-write + + + DIV_NUM + This register is used to configure parameter for divider in low speed timer0 the least significant eight bits represent the decimal part. + 5 + 18 + read-write + + + PAUSE + This bit is used to pause the counter in low speed timer0. + 23 + 1 + read-write + + + RST + This bit is used to reset low speed timer0 the counter will be 0 after reset. + 24 + 1 + read-write + + + TICK_SEL + This bit is used to choose slow_clk or ref_tick for low speed timer0. 1'b1:slow_clk 0:ref_tick + 25 + 1 + read-write + + + PARA_UP + Set this bit to update reg_div_num_lstime0 and reg_lstimer0_lim. + 26 + 1 + read-write + + + LIM + 31 + 5 + read-write + + + + + 4 + 0x8 + 0-3 + LSTIMER%s_VALUE + 0x164 + 0x20 + + + CNT + software can read this register to get the current counter value in low speed timer0. + 0 + 20 + read-only + + + + + INT_RAW + 0x180 + 0x20 + + + HSTIMER0_OVF_INT_RAW + The interrupt raw bit for high speed channel0 counter overflow. + 0 + 1 + read-only + + + HSTIMER1_OVF_INT_RAW + The interrupt raw bit for high speed channel1 counter overflow. + 1 + 1 + read-only + + + HSTIMER2_OVF_INT_RAW + The interrupt raw bit for high speed channel2 counter overflow. + 2 + 1 + read-only + + + HSTIMER3_OVF_INT_RAW + The interrupt raw bit for high speed channel3 counter overflow. + 3 + 1 + read-only + + + LSTIMER0_OVF_INT_RAW + The interrupt raw bit for low speed channel0 counter overflow. + 4 + 1 + read-only + + + LSTIMER1_OVF_INT_RAW + The interrupt raw bit for low speed channel1 counter overflow. + 5 + 1 + read-only + + + LSTIMER2_OVF_INT_RAW + The interrupt raw bit for low speed channel2 counter overflow. + 6 + 1 + read-only + + + LSTIMER3_OVF_INT_RAW + The interrupt raw bit for low speed channel3 counter overflow. + 7 + 1 + read-only + + + DUTY_CHNG_END_HSCH0_INT_RAW + The interrupt raw bit for high speed channel 0 duty change done. + 8 + 1 + read-only + + + DUTY_CHNG_END_HSCH1_INT_RAW + The interrupt raw bit for high speed channel 1 duty change done. + 9 + 1 + read-only + + + DUTY_CHNG_END_HSCH2_INT_RAW + The interrupt raw bit for high speed channel 2 duty change done. + 10 + 1 + read-only + + + DUTY_CHNG_END_HSCH3_INT_RAW + The interrupt raw bit for high speed channel 3 duty change done. + 11 + 1 + read-only + + + DUTY_CHNG_END_HSCH4_INT_RAW + The interrupt raw bit for high speed channel 4 duty change done. + 12 + 1 + read-only + + + DUTY_CHNG_END_HSCH5_INT_RAW + The interrupt raw bit for high speed channel 5 duty change done. + 13 + 1 + read-only + + + DUTY_CHNG_END_HSCH6_INT_RAW + The interrupt raw bit for high speed channel 6 duty change done. + 14 + 1 + read-only + + + DUTY_CHNG_END_HSCH7_INT_RAW + The interrupt raw bit for high speed channel 7 duty change done. + 15 + 1 + read-only + + + DUTY_CHNG_END_LSCH0_INT_RAW + The interrupt raw bit for low speed channel 0 duty change done. + 16 + 1 + read-only + + + DUTY_CHNG_END_LSCH1_INT_RAW + The interrupt raw bit for low speed channel 1 duty change done. + 17 + 1 + read-only + + + DUTY_CHNG_END_LSCH2_INT_RAW + The interrupt raw bit for low speed channel 2 duty change done. + 18 + 1 + read-only + + + DUTY_CHNG_END_LSCH3_INT_RAW + The interrupt raw bit for low speed channel 3 duty change done. + 19 + 1 + read-only + + + DUTY_CHNG_END_LSCH4_INT_RAW + The interrupt raw bit for low speed channel 4 duty change done. + 20 + 1 + read-only + + + DUTY_CHNG_END_LSCH5_INT_RAW + The interrupt raw bit for low speed channel 5 duty change done. + 21 + 1 + read-only + + + DUTY_CHNG_END_LSCH6_INT_RAW + The interrupt raw bit for low speed channel 6 duty change done. + 22 + 1 + read-only + + + DUTY_CHNG_END_LSCH7_INT_RAW + The interrupt raw bit for low speed channel 7 duty change done. + 23 + 1 + read-only + + + + + INT_ST + 0x184 + 0x20 + + + HSTIMER0_OVF_INT_ST + The interrupt status bit for high speed channel0 counter overflow event. + 0 + 1 + read-only + + + HSTIMER1_OVF_INT_ST + The interrupt status bit for high speed channel1 counter overflow event. + 1 + 1 + read-only + + + HSTIMER2_OVF_INT_ST + The interrupt status bit for high speed channel2 counter overflow event. + 2 + 1 + read-only + + + HSTIMER3_OVF_INT_ST + The interrupt status bit for high speed channel3 counter overflow event. + 3 + 1 + read-only + + + LSTIMER0_OVF_INT_ST + The interrupt status bit for low speed channel0 counter overflow event. + 4 + 1 + read-only + + + LSTIMER1_OVF_INT_ST + The interrupt status bit for low speed channel1 counter overflow event. + 5 + 1 + read-only + + + LSTIMER2_OVF_INT_ST + The interrupt status bit for low speed channel2 counter overflow event. + 6 + 1 + read-only + + + LSTIMER3_OVF_INT_ST + The interrupt status bit for low speed channel3 counter overflow event. + 7 + 1 + read-only + + + DUTY_CHNG_END_HSCH0_INT_ST + The interrupt status bit for high speed channel 0 duty change done event. + 8 + 1 + read-only + + + DUTY_CHNG_END_HSCH1_INT_ST + The interrupt status bit for high speed channel 1 duty change done event. + 9 + 1 + read-only + + + DUTY_CHNG_END_HSCH2_INT_ST + The interrupt status bit for high speed channel 2 duty change done event. + 10 + 1 + read-only + + + DUTY_CHNG_END_HSCH3_INT_ST + The interrupt status bit for high speed channel 3 duty change done event. + 11 + 1 + read-only + + + DUTY_CHNG_END_HSCH4_INT_ST + The interrupt status bit for high speed channel 4 duty change done event. + 12 + 1 + read-only + + + DUTY_CHNG_END_HSCH5_INT_ST + The interrupt status bit for high speed channel 5 duty change done event. + 13 + 1 + read-only + + + DUTY_CHNG_END_HSCH6_INT_ST + The interrupt status bit for high speed channel 6 duty change done event. + 14 + 1 + read-only + + + DUTY_CHNG_END_HSCH7_INT_ST + The interrupt status bit for high speed channel 7 duty change done event. + 15 + 1 + read-only + + + DUTY_CHNG_END_LSCH0_INT_ST + The interrupt status bit for low speed channel 0 duty change done event. + 16 + 1 + read-only + + + DUTY_CHNG_END_LSCH1_INT_ST + The interrupt status bit for low speed channel 1 duty change done event. + 17 + 1 + read-only + + + DUTY_CHNG_END_LSCH2_INT_ST + The interrupt status bit for low speed channel 2 duty change done event. + 18 + 1 + read-only + + + DUTY_CHNG_END_LSCH3_INT_ST + The interrupt status bit for low speed channel 3 duty change done event. + 19 + 1 + read-only + + + DUTY_CHNG_END_LSCH4_INT_ST + The interrupt status bit for low speed channel 4 duty change done event. + 20 + 1 + read-only + + + DUTY_CHNG_END_LSCH5_INT_ST + The interrupt status bit for low speed channel 5 duty change done event. + 21 + 1 + read-only + + + DUTY_CHNG_END_LSCH6_INT_ST + The interrupt status bit for low speed channel 6 duty change done event. + 22 + 1 + read-only + + + DUTY_CHNG_END_LSCH7_INT_ST + The interrupt status bit for low speed channel 7 duty change done event + 23 + 1 + read-only + + + + + INT_ENA + 0x188 + 0x20 + + + HSTIMER0_OVF_INT_ENA + The interrupt enable bit for high speed channel0 counter overflow interrupt. + 0 + 1 + read-write + + + HSTIMER1_OVF_INT_ENA + The interrupt enable bit for high speed channel1 counter overflow interrupt. + 1 + 1 + read-write + + + HSTIMER2_OVF_INT_ENA + The interrupt enable bit for high speed channel2 counter overflow interrupt. + 2 + 1 + read-write + + + HSTIMER3_OVF_INT_ENA + The interrupt enable bit for high speed channel3 counter overflow interrupt. + 3 + 1 + read-write + + + LSTIMER0_OVF_INT_ENA + The interrupt enable bit for low speed channel0 counter overflow interrupt. + 4 + 1 + read-write + + + LSTIMER1_OVF_INT_ENA + The interrupt enable bit for low speed channel1 counter overflow interrupt. + 5 + 1 + read-write + + + LSTIMER2_OVF_INT_ENA + The interrupt enable bit for low speed channel2 counter overflow interrupt. + 6 + 1 + read-write + + + LSTIMER3_OVF_INT_ENA + The interrupt enable bit for low speed channel3 counter overflow interrupt. + 7 + 1 + read-write + + + DUTY_CHNG_END_HSCH0_INT_ENA + The interrupt enable bit for high speed channel 0 duty change done interrupt. + 8 + 1 + read-write + + + DUTY_CHNG_END_HSCH1_INT_ENA + The interrupt enable bit for high speed channel 1 duty change done interrupt. + 9 + 1 + read-write + + + DUTY_CHNG_END_HSCH2_INT_ENA + The interrupt enable bit for high speed channel 2 duty change done interrupt. + 10 + 1 + read-write + + + DUTY_CHNG_END_HSCH3_INT_ENA + The interrupt enable bit for high speed channel 3 duty change done interrupt. + 11 + 1 + read-write + + + DUTY_CHNG_END_HSCH4_INT_ENA + The interrupt enable bit for high speed channel 4 duty change done interrupt. + 12 + 1 + read-write + + + DUTY_CHNG_END_HSCH5_INT_ENA + The interrupt enable bit for high speed channel 5 duty change done interrupt. + 13 + 1 + read-write + + + DUTY_CHNG_END_HSCH6_INT_ENA + The interrupt enable bit for high speed channel 6 duty change done interrupt. + 14 + 1 + read-write + + + DUTY_CHNG_END_HSCH7_INT_ENA + The interrupt enable bit for high speed channel 7 duty change done interrupt. + 15 + 1 + read-write + + + DUTY_CHNG_END_LSCH0_INT_ENA + The interrupt enable bit for low speed channel 0 duty change done interrupt. + 16 + 1 + read-write + + + DUTY_CHNG_END_LSCH1_INT_ENA + The interrupt enable bit for low speed channel 1 duty change done interrupt. + 17 + 1 + read-write + + + DUTY_CHNG_END_LSCH2_INT_ENA + The interrupt enable bit for low speed channel 2 duty change done interrupt. + 18 + 1 + read-write + + + DUTY_CHNG_END_LSCH3_INT_ENA + The interrupt enable bit for low speed channel 3 duty change done interrupt. + 19 + 1 + read-write + + + DUTY_CHNG_END_LSCH4_INT_ENA + The interrupt enable bit for low speed channel 4 duty change done interrupt. + 20 + 1 + read-write + + + DUTY_CHNG_END_LSCH5_INT_ENA + The interrupt enable bit for low speed channel 5 duty change done interrupt. + 21 + 1 + read-write + + + DUTY_CHNG_END_LSCH6_INT_ENA + The interrupt enable bit for low speed channel 6 duty change done interrupt. + 22 + 1 + read-write + + + DUTY_CHNG_END_LSCH7_INT_ENA + The interrupt enable bit for low speed channel 7 duty change done interrupt. + 23 + 1 + read-write + + + + + INT_CLR + 0x18C + 0x20 + + + HSTIMER0_OVF_INT_CLR + Set this bit to clear high speed channel0 counter overflow interrupt. + 0 + 1 + write-only + + + HSTIMER1_OVF_INT_CLR + Set this bit to clear high speed channel1 counter overflow interrupt. + 1 + 1 + write-only + + + HSTIMER2_OVF_INT_CLR + Set this bit to clear high speed channel2 counter overflow interrupt. + 2 + 1 + write-only + + + HSTIMER3_OVF_INT_CLR + Set this bit to clear high speed channel3 counter overflow interrupt. + 3 + 1 + write-only + + + LSTIMER0_OVF_INT_CLR + Set this bit to clear low speed channel0 counter overflow interrupt. + 4 + 1 + write-only + + + LSTIMER1_OVF_INT_CLR + Set this bit to clear low speed channel1 counter overflow interrupt. + 5 + 1 + write-only + + + LSTIMER2_OVF_INT_CLR + Set this bit to clear low speed channel2 counter overflow interrupt. + 6 + 1 + write-only + + + LSTIMER3_OVF_INT_CLR + Set this bit to clear low speed channel3 counter overflow interrupt. + 7 + 1 + write-only + + + DUTY_CHNG_END_HSCH0_INT_CLR + Set this bit to clear high speed channel 0 duty change done interrupt. + 8 + 1 + write-only + + + DUTY_CHNG_END_HSCH1_INT_CLR + Set this bit to clear high speed channel 1 duty change done interrupt. + 9 + 1 + write-only + + + DUTY_CHNG_END_HSCH2_INT_CLR + Set this bit to clear high speed channel 2 duty change done interrupt. + 10 + 1 + write-only + + + DUTY_CHNG_END_HSCH3_INT_CLR + Set this bit to clear high speed channel 3 duty change done interrupt. + 11 + 1 + write-only + + + DUTY_CHNG_END_HSCH4_INT_CLR + Set this bit to clear high speed channel 4 duty change done interrupt. + 12 + 1 + write-only + + + DUTY_CHNG_END_HSCH5_INT_CLR + Set this bit to clear high speed channel 5 duty change done interrupt. + 13 + 1 + write-only + + + DUTY_CHNG_END_HSCH6_INT_CLR + Set this bit to clear high speed channel 6 duty change done interrupt. + 14 + 1 + write-only + + + DUTY_CHNG_END_HSCH7_INT_CLR + Set this bit to clear high speed channel 7 duty change done interrupt. + 15 + 1 + write-only + + + DUTY_CHNG_END_LSCH0_INT_CLR + Set this bit to clear low speed channel 0 duty change done interrupt. + 16 + 1 + write-only + + + DUTY_CHNG_END_LSCH1_INT_CLR + Set this bit to clear low speed channel 1 duty change done interrupt. + 17 + 1 + write-only + + + DUTY_CHNG_END_LSCH2_INT_CLR + Set this bit to clear low speed channel 2 duty change done interrupt. + 18 + 1 + write-only + + + DUTY_CHNG_END_LSCH3_INT_CLR + Set this bit to clear low speed channel 3 duty change done interrupt. + 19 + 1 + write-only + + + DUTY_CHNG_END_LSCH4_INT_CLR + Set this bit to clear low speed channel 4 duty change done interrupt. + 20 + 1 + write-only + + + DUTY_CHNG_END_LSCH5_INT_CLR + Set this bit to clear low speed channel 5 duty change done interrupt. + 21 + 1 + write-only + + + DUTY_CHNG_END_LSCH6_INT_CLR + Set this bit to clear low speed channel 6 duty change done interrupt. + 22 + 1 + write-only + + + DUTY_CHNG_END_LSCH7_INT_CLR + Set this bit to clear low speed channel 7 duty change done interrupt. + 23 + 1 + write-only + + + + + CONF + 0x190 + 0x20 + + + APB_CLK_SEL + This bit is used to set the frequency of slow_clk. 1'b1:80mhz 1'b0:8mhz + 0 + 1 + read-write + + + + + DATE + 0x1FC + 0x20 + 0x16031700 + + + DATE + This register represents the version . + 0 + 32 + read-write + + + + + + + PWM0 + Motor Control Pulse-Width Modulation + MCPWM + 0x3FF5E000 + + 0x0 + 0x128 + registers + + + PWM0 + 39 + + + + CLK_CFG + 0x0 + 0x20 + + + CLK_PRESCALE + 0 + 8 + read-write + + + + + TIMER0_CFG0 + 0x4 + 0x20 + 0x0000FF00 + + + TIMER0_PRESCALE + 0 + 8 + read-write + + + TIMER0_PERIOD + 8 + 16 + read-write + + + TIMER0_PERIOD_UPMETHOD + 24 + 2 + read-write + + + + + TIMER0_CFG1 + 0x8 + 0x20 + + + TIMER0_START + 0 + 3 + read-write + + + TIMER0_MOD + 3 + 2 + read-write + + + + + TIMER0_SYNC + 0xC + 0x20 + + + TIMER0_SYNCI_EN + 0 + 1 + read-write + + + SW + 1 + 1 + read-write + + + TIMER0_SYNCO_SEL + 2 + 2 + read-write + + + TIMER0_PHASE + 4 + 16 + read-write + + + TIMER0_PHASE_DIRECTION + 20 + 1 + read-write + + + + + TIMER0_STATUS + 0x10 + 0x20 + + + TIMER0_VALUE + 0 + 16 + read-only + + + TIMER0_DIRECTION + 16 + 1 + read-only + + + + + TIMER1_CFG0 + 0x14 + 0x20 + 0x0000FF00 + + + TIMER1_PRESCALE + 0 + 8 + read-write + + + TIMER1_PERIOD + 8 + 16 + read-write + + + TIMER1_PERIOD_UPMETHOD + 24 + 2 + read-write + + + + + TIMER1_CFG1 + 0x18 + 0x20 + + + TIMER1_START + 0 + 3 + read-write + + + TIMER1_MOD + 3 + 2 + read-write + + + + + TIMER1_SYNC + 0x1C + 0x20 + + + TIMER1_SYNCI_EN + 0 + 1 + read-write + + + SW + 1 + 1 + read-write + + + TIMER1_SYNCO_SEL + 2 + 2 + read-write + + + TIMER1_PHASE + 4 + 16 + read-write + + + TIMER1_PHASE_DIRECTION + 20 + 1 + read-write + + + + + TIMER1_STATUS + 0x20 + 0x20 + + + TIMER1_VALUE + 0 + 16 + read-only + + + TIMER1_DIRECTION + 16 + 1 + read-only + + + + + TIMER2_CFG0 + 0x24 + 0x20 + 0x0000FF00 + + + TIMER2_PRESCALE + 0 + 8 + read-write + + + TIMER2_PERIOD + 8 + 16 + read-write + + + TIMER2_PERIOD_UPMETHOD + 24 + 2 + read-write + + + + + TIMER2_CFG1 + 0x28 + 0x20 + + + TIMER2_START + 0 + 3 + read-write + + + TIMER2_MOD + 3 + 2 + read-write + + + + + TIMER2_SYNC + 0x2C + 0x20 + + + TIMER2_SYNCI_EN + 0 + 1 + read-write + + + SW + 1 + 1 + read-write + + + TIMER2_SYNCO_SEL + 2 + 2 + read-write + + + TIMER2_PHASE + 4 + 16 + read-write + + + TIMER2_PHASE_DIRECTION + 20 + 1 + read-write + + + + + TIMER2_STATUS + 0x30 + 0x20 + + + TIMER2_VALUE + 0 + 16 + read-only + + + TIMER2_DIRECTION + 16 + 1 + read-only + + + + + TIMER_SYNCI_CFG + 0x34 + 0x20 + + + TIMER0_SYNCISEL + 0 + 3 + read-write + + + TIMER1_SYNCISEL + 3 + 3 + read-write + + + TIMER2_SYNCISEL + 6 + 3 + read-write + + + EXTERNAL_SYNCI0_INVERT + 9 + 1 + read-write + + + EXTERNAL_SYNCI1_INVERT + 10 + 1 + read-write + + + EXTERNAL_SYNCI2_INVERT + 11 + 1 + read-write + + + + + OPERATOR_TIMERSEL + 0x38 + 0x20 + + + OPERATOR0_TIMERSEL + 0 + 2 + read-write + + + OPERATOR1_TIMERSEL + 2 + 2 + read-write + + + OPERATOR2_TIMERSEL + 4 + 2 + read-write + + + + + GEN0_STMP_CFG + 0x3C + 0x20 + + + GEN0_A_UPMETHOD + 0 + 4 + read-write + + + GEN0_B_UPMETHOD + 4 + 4 + read-write + + + GEN0_A_SHDW_FULL + 8 + 1 + read-write + + + GEN0_B_SHDW_FULL + 9 + 1 + read-write + + + + + GEN0_TSTMP_A + 0x40 + 0x20 + + + GEN0_A + 0 + 16 + read-write + + + + + GEN0_TSTMP_B + 0x44 + 0x20 + + + GEN0_B + 0 + 16 + read-write + + + + + GEN0_CFG0 + 0x48 + 0x20 + + + GEN0_CFG_UPMETHOD + 0 + 4 + read-write + + + GEN0_T0_SEL + 4 + 3 + read-write + + + GEN0_T1_SEL + 7 + 3 + read-write + + + + + GEN0_FORCE + 0x4C + 0x20 + 0x00000020 + + + GEN0_CNTUFORCE_UPMETHOD + 0 + 6 + read-write + + + GEN0_A_CNTUFORCE_MODE + 6 + 2 + read-write + + + GEN0_B_CNTUFORCE_MODE + 8 + 2 + read-write + + + GEN0_A_NCIFORCE + 10 + 1 + read-write + + + GEN0_A_NCIFORCE_MODE + 11 + 2 + read-write + + + GEN0_B_NCIFORCE + 13 + 1 + read-write + + + GEN0_B_NCIFORCE_MODE + 14 + 2 + read-write + + + + + GEN0_A + 0x50 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + GEN0_B + 0x54 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + DT0_CFG + 0x58 + 0x20 + 0x00018000 + + + DT0_FED_UPMETHOD + 0 + 4 + read-write + + + DT0_RED_UPMETHOD + 4 + 4 + read-write + + + DT0_DEB_MODE + 8 + 1 + read-write + + + DT0_A_OUTSWAP + 9 + 1 + read-write + + + DT0_B_OUTSWAP + 10 + 1 + read-write + + + DT0_RED_INSEL + 11 + 1 + read-write + + + DT0_FED_INSEL + 12 + 1 + read-write + + + DT0_RED_OUTINVERT + 13 + 1 + read-write + + + DT0_FED_OUTINVERT + 14 + 1 + read-write + + + DT0_A_OUTBYPASS + 15 + 1 + read-write + + + DT0_B_OUTBYPASS + 16 + 1 + read-write + + + DT0_CLK_SEL + 17 + 1 + read-write + + + + + DT0_FED_CFG + 0x5C + 0x20 + + + DT0_FED + 0 + 16 + read-write + + + + + DT0_RED_CFG + 0x60 + 0x20 + + + DT0_RED + 0 + 16 + read-write + + + + + CARRIER0_CFG + 0x64 + 0x20 + + + CARRIER0_EN + 0 + 1 + read-write + + + CARRIER0_PRESCALE + 1 + 4 + read-write + + + CARRIER0_DUTY + 5 + 3 + read-write + + + CARRIER0_OSHTWTH + 8 + 4 + read-write + + + CARRIER0_OUT_INVERT + 12 + 1 + read-write + + + CARRIER0_IN_INVERT + 13 + 1 + read-write + + + + + FH0_CFG0 + 0x68 + 0x20 + + + FH0_SW_CBC + 0 + 1 + read-write + + + FH0_F2_CBC + 1 + 1 + read-write + + + FH0_F1_CBC + 2 + 1 + read-write + + + FH0_F0_CBC + 3 + 1 + read-write + + + FH0_SW_OST + 4 + 1 + read-write + + + FH0_F2_OST + 5 + 1 + read-write + + + FH0_F1_OST + 6 + 1 + read-write + + + FH0_F0_OST + 7 + 1 + read-write + + + FH0_A_CBC_D + 8 + 2 + read-write + + + FH0_A_CBC_U + 10 + 2 + read-write + + + FH0_A_OST_D + 12 + 2 + read-write + + + FH0_A_OST_U + 14 + 2 + read-write + + + FH0_B_CBC_D + 16 + 2 + read-write + + + FH0_B_CBC_U + 18 + 2 + read-write + + + FH0_B_OST_D + 20 + 2 + read-write + + + FH0_B_OST_U + 22 + 2 + read-write + + + + + FH0_CFG1 + 0x6C + 0x20 + + + FH0_CLR_OST + 0 + 1 + read-write + + + FH0_CBCPULSE + 1 + 2 + read-write + + + FH0_FORCE_CBC + 3 + 1 + read-write + + + FH0_FORCE_OST + 4 + 1 + read-write + + + + + FH0_STATUS + 0x70 + 0x20 + + + FH0_CBC_ON + 0 + 1 + read-only + + + FH0_OST_ON + 1 + 1 + read-only + + + + + GEN1_STMP_CFG + 0x74 + 0x20 + + + GEN1_A_UPMETHOD + 0 + 4 + read-write + + + GEN1_B_UPMETHOD + 4 + 4 + read-write + + + GEN1_A_SHDW_FULL + 8 + 1 + read-write + + + GEN1_B_SHDW_FULL + 9 + 1 + read-write + + + + + GEN1_TSTMP_A + 0x78 + 0x20 + + + GEN1_A + 0 + 16 + read-write + + + + + GEN1_TSTMP_B + 0x7C + 0x20 + + + GEN1_B + 0 + 16 + read-write + + + + + GEN1_CFG0 + 0x80 + 0x20 + + + GEN1_CFG_UPMETHOD + 0 + 4 + read-write + + + GEN1_T0_SEL + 4 + 3 + read-write + + + GEN1_T1_SEL + 7 + 3 + read-write + + + + + GEN1_FORCE + 0x84 + 0x20 + 0x00000020 + + + GEN1_CNTUFORCE_UPMETHOD + 0 + 6 + read-write + + + GEN1_A_CNTUFORCE_MODE + 6 + 2 + read-write + + + GEN1_B_CNTUFORCE_MODE + 8 + 2 + read-write + + + GEN1_A_NCIFORCE + 10 + 1 + read-write + + + GEN1_A_NCIFORCE_MODE + 11 + 2 + read-write + + + GEN1_B_NCIFORCE + 13 + 1 + read-write + + + GEN1_B_NCIFORCE_MODE + 14 + 2 + read-write + + + + + GEN1_A + 0x88 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + GEN1_B + 0x8C + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + DT1_CFG + 0x90 + 0x20 + 0x00018000 + + + DT1_FED_UPMETHOD + 0 + 4 + read-write + + + DT1_RED_UPMETHOD + 4 + 4 + read-write + + + DT1_DEB_MODE + 8 + 1 + read-write + + + DT1_A_OUTSWAP + 9 + 1 + read-write + + + DT1_B_OUTSWAP + 10 + 1 + read-write + + + DT1_RED_INSEL + 11 + 1 + read-write + + + DT1_FED_INSEL + 12 + 1 + read-write + + + DT1_RED_OUTINVERT + 13 + 1 + read-write + + + DT1_FED_OUTINVERT + 14 + 1 + read-write + + + DT1_A_OUTBYPASS + 15 + 1 + read-write + + + DT1_B_OUTBYPASS + 16 + 1 + read-write + + + DT1_CLK_SEL + 17 + 1 + read-write + + + + + DT1_FED_CFG + 0x94 + 0x20 + + + DT1_FED + 0 + 16 + read-write + + + + + DT1_RED_CFG + 0x98 + 0x20 + + + DT1_RED + 0 + 16 + read-write + + + + + CARRIER1_CFG + 0x9C + 0x20 + + + CARRIER1_EN + 0 + 1 + read-write + + + CARRIER1_PRESCALE + 1 + 4 + read-write + + + CARRIER1_DUTY + 5 + 3 + read-write + + + CARRIER1_OSHTWTH + 8 + 4 + read-write + + + CARRIER1_OUT_INVERT + 12 + 1 + read-write + + + CARRIER1_IN_INVERT + 13 + 1 + read-write + + + + + FH1_CFG0 + 0xA0 + 0x20 + + + FH1_SW_CBC + 0 + 1 + read-write + + + FH1_F2_CBC + 1 + 1 + read-write + + + FH1_F1_CBC + 2 + 1 + read-write + + + FH1_F0_CBC + 3 + 1 + read-write + + + FH1_SW_OST + 4 + 1 + read-write + + + FH1_F2_OST + 5 + 1 + read-write + + + FH1_F1_OST + 6 + 1 + read-write + + + FH1_F0_OST + 7 + 1 + read-write + + + FH1_A_CBC_D + 8 + 2 + read-write + + + FH1_A_CBC_U + 10 + 2 + read-write + + + FH1_A_OST_D + 12 + 2 + read-write + + + FH1_A_OST_U + 14 + 2 + read-write + + + FH1_B_CBC_D + 16 + 2 + read-write + + + FH1_B_CBC_U + 18 + 2 + read-write + + + FH1_B_OST_D + 20 + 2 + read-write + + + FH1_B_OST_U + 22 + 2 + read-write + + + + + FH1_CFG1 + 0xA4 + 0x20 + + + FH1_CLR_OST + 0 + 1 + read-write + + + FH1_CBCPULSE + 1 + 2 + read-write + + + FH1_FORCE_CBC + 3 + 1 + read-write + + + FH1_FORCE_OST + 4 + 1 + read-write + + + + + FH1_STATUS + 0xA8 + 0x20 + + + FH1_CBC_ON + 0 + 1 + read-only + + + FH1_OST_ON + 1 + 1 + read-only + + + + + GEN2_STMP_CFG + 0xAC + 0x20 + + + GEN2_A_UPMETHOD + 0 + 4 + read-write + + + GEN2_B_UPMETHOD + 4 + 4 + read-write + + + GEN2_A_SHDW_FULL + 8 + 1 + read-write + + + GEN2_B_SHDW_FULL + 9 + 1 + read-write + + + + + GEN2_TSTMP_A + 0xB0 + 0x20 + + + GEN2_A + 0 + 16 + read-write + + + + + GEN2_TSTMP_B + 0xB4 + 0x20 + + + GEN2_B + 0 + 16 + read-write + + + + + GEN2_CFG0 + 0xB8 + 0x20 + + + GEN2_CFG_UPMETHOD + 0 + 4 + read-write + + + GEN2_T0_SEL + 4 + 3 + read-write + + + GEN2_T1_SEL + 7 + 3 + read-write + + + + + GEN2_FORCE + 0xBC + 0x20 + 0x00000020 + + + GEN2_CNTUFORCE_UPMETHOD + 0 + 6 + read-write + + + GEN2_A_CNTUFORCE_MODE + 6 + 2 + read-write + + + GEN2_B_CNTUFORCE_MODE + 8 + 2 + read-write + + + GEN2_A_NCIFORCE + 10 + 1 + read-write + + + GEN2_A_NCIFORCE_MODE + 11 + 2 + read-write + + + GEN2_B_NCIFORCE + 13 + 1 + read-write + + + GEN2_B_NCIFORCE_MODE + 14 + 2 + read-write + + + + + GEN2_A + 0xC0 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + GEN2_B + 0xC4 + 0x20 + + + UTEZ + 0 + 2 + read-write + + + UTEP + 2 + 2 + read-write + + + UTEA + 4 + 2 + read-write + + + UTEB + 6 + 2 + read-write + + + UT0 + 8 + 2 + read-write + + + UT1 + 10 + 2 + read-write + + + DTEZ + 12 + 2 + read-write + + + DTEP + 14 + 2 + read-write + + + DTEA + 16 + 2 + read-write + + + DTEB + 18 + 2 + read-write + + + DT0 + 20 + 2 + read-write + + + DT1 + 22 + 2 + read-write + + + + + DT2_CFG + 0xC8 + 0x20 + 0x00018000 + + + DT2_FED_UPMETHOD + 0 + 4 + read-write + + + DT2_RED_UPMETHOD + 4 + 4 + read-write + + + DT2_DEB_MODE + 8 + 1 + read-write + + + DT2_A_OUTSWAP + 9 + 1 + read-write + + + DT2_B_OUTSWAP + 10 + 1 + read-write + + + DT2_RED_INSEL + 11 + 1 + read-write + + + DT2_FED_INSEL + 12 + 1 + read-write + + + DT2_RED_OUTINVERT + 13 + 1 + read-write + + + DT2_FED_OUTINVERT + 14 + 1 + read-write + + + DT2_A_OUTBYPASS + 15 + 1 + read-write + + + DT2_B_OUTBYPASS + 16 + 1 + read-write + + + DT2_CLK_SEL + 17 + 1 + read-write + + + + + DT2_FED_CFG + 0xCC + 0x20 + + + DT2_FED + 0 + 16 + read-write + + + + + DT2_RED_CFG + 0xD0 + 0x20 + + + DT2_RED + 0 + 16 + read-write + + + + + CARRIER2_CFG + 0xD4 + 0x20 + + + CARRIER2_EN + 0 + 1 + read-write + + + CARRIER2_PRESCALE + 1 + 4 + read-write + + + CARRIER2_DUTY + 5 + 3 + read-write + + + CARRIER2_OSHTWTH + 8 + 4 + read-write + + + CARRIER2_OUT_INVERT + 12 + 1 + read-write + + + CARRIER2_IN_INVERT + 13 + 1 + read-write + + + + + FH2_CFG0 + 0xD8 + 0x20 + + + FH2_SW_CBC + 0 + 1 + read-write + + + FH2_F2_CBC + 1 + 1 + read-write + + + FH2_F1_CBC + 2 + 1 + read-write + + + FH2_F0_CBC + 3 + 1 + read-write + + + FH2_SW_OST + 4 + 1 + read-write + + + FH2_F2_OST + 5 + 1 + read-write + + + FH2_F1_OST + 6 + 1 + read-write + + + FH2_F0_OST + 7 + 1 + read-write + + + FH2_A_CBC_D + 8 + 2 + read-write + + + FH2_A_CBC_U + 10 + 2 + read-write + + + FH2_A_OST_D + 12 + 2 + read-write + + + FH2_A_OST_U + 14 + 2 + read-write + + + FH2_B_CBC_D + 16 + 2 + read-write + + + FH2_B_CBC_U + 18 + 2 + read-write + + + FH2_B_OST_D + 20 + 2 + read-write + + + FH2_B_OST_U + 22 + 2 + read-write + + + + + FH2_CFG1 + 0xDC + 0x20 + + + FH2_CLR_OST + 0 + 1 + read-write + + + FH2_CBCPULSE + 1 + 2 + read-write + + + FH2_FORCE_CBC + 3 + 1 + read-write + + + FH2_FORCE_OST + 4 + 1 + read-write + + + + + FH2_STATUS + 0xE0 + 0x20 + + + FH2_CBC_ON + 0 + 1 + read-only + + + FH2_OST_ON + 1 + 1 + read-only + + + + + FAULT_DETECT + 0xE4 + 0x20 + + + F0_EN + 0 + 1 + read-write + + + F1_EN + 1 + 1 + read-write + + + F2_EN + 2 + 1 + read-write + + + F0_POLE + 3 + 1 + read-write + + + F1_POLE + 4 + 1 + read-write + + + F2_POLE + 5 + 1 + read-write + + + EVENT_F0 + 6 + 1 + read-only + + + EVENT_F1 + 7 + 1 + read-only + + + EVENT_F2 + 8 + 1 + read-only + + + + + CAP_TIMER_CFG + 0xE8 + 0x20 + + + CAP_TIMER_EN + 0 + 1 + read-write + + + CAP_SYNCI_EN + 1 + 1 + read-write + + + CAP_SYNCI_SEL + 2 + 3 + read-write + + + CAP_SYNC_SW + 5 + 1 + write-only + + + + + CAP_TIMER_PHASE + 0xEC + 0x20 + + + CAP_TIMER_PHASE + 0 + 32 + read-write + + + + + CAP_CH0_CFG + 0xF0 + 0x20 + + + CAP0_EN + 0 + 1 + read-write + + + CAP0_MODE + 1 + 2 + read-write + + + CAP0_PRESCALE + 3 + 8 + read-write + + + CAP0_IN_INVERT + 11 + 1 + read-write + + + CAP0_SW + 12 + 1 + write-only + + + + + CAP_CH1_CFG + 0xF4 + 0x20 + + + CAP1_EN + 0 + 1 + read-write + + + CAP1_MODE + 1 + 2 + read-write + + + CAP1_PRESCALE + 3 + 8 + read-write + + + CAP1_IN_INVERT + 11 + 1 + read-write + + + CAP1_SW + 12 + 1 + write-only + + + + + CAP_CH2_CFG + 0xF8 + 0x20 + + + CAP2_EN + 0 + 1 + read-write + + + CAP2_MODE + 1 + 2 + read-write + + + CAP2_PRESCALE + 3 + 8 + read-write + + + CAP2_IN_INVERT + 11 + 1 + read-write + + + CAP2_SW + 12 + 1 + write-only + + + + + CAP_CH0 + 0xFC + 0x20 + + + CAP0_VALUE + 0 + 32 + read-only + + + + + CAP_CH1 + 0x100 + 0x20 + + + CAP1_VALUE + 0 + 32 + read-only + + + + + CAP_CH2 + 0x104 + 0x20 + + + CAP2_VALUE + 0 + 32 + read-only + + + + + CAP_STATUS + 0x108 + 0x20 + + + CAP0_EDGE + 0 + 1 + read-only + + + CAP1_EDGE + 1 + 1 + read-only + + + CAP2_EDGE + 2 + 1 + read-only + + + + + UPDATE_CFG + 0x10C + 0x20 + 0x00000055 + + + GLOBAL_UP_EN + 0 + 1 + read-write + + + GLOBAL_FORCE_UP + 1 + 1 + read-write + + + OP0_UP_EN + 2 + 1 + read-write + + + OP0_FORCE_UP + 3 + 1 + read-write + + + OP1_UP_EN + 4 + 1 + read-write + + + OP1_FORCE_UP + 5 + 1 + read-write + + + OP2_UP_EN + 6 + 1 + read-write + + + OP2_FORCE_UP + 7 + 1 + read-write + + + + + INT_ENA + 0x110 + 0x20 + + + TIMER0_STOP_INT_ENA + 0 + 1 + read-write + + + TIMER1_STOP_INT_ENA + 1 + 1 + read-write + + + TIMER2_STOP_INT_ENA + 2 + 1 + read-write + + + TIMER0_TEZ_INT_ENA + 3 + 1 + read-write + + + TIMER1_TEZ_INT_ENA + 4 + 1 + read-write + + + TIMER2_TEZ_INT_ENA + 5 + 1 + read-write + + + TIMER0_TEP_INT_ENA + 6 + 1 + read-write + + + TIMER1_TEP_INT_ENA + 7 + 1 + read-write + + + TIMER2_TEP_INT_ENA + 8 + 1 + read-write + + + FAULT0_INT_ENA + 9 + 1 + read-write + + + FAULT1_INT_ENA + 10 + 1 + read-write + + + FAULT2_INT_ENA + 11 + 1 + read-write + + + FAULT0_CLR_INT_ENA + 12 + 1 + read-write + + + FAULT1_CLR_INT_ENA + 13 + 1 + read-write + + + FAULT2_CLR_INT_ENA + 14 + 1 + read-write + + + OP0_TEA_INT_ENA + 15 + 1 + read-write + + + OP1_TEA_INT_ENA + 16 + 1 + read-write + + + OP2_TEA_INT_ENA + 17 + 1 + read-write + + + OP0_TEB_INT_ENA + 18 + 1 + read-write + + + OP1_TEB_INT_ENA + 19 + 1 + read-write + + + OP2_TEB_INT_ENA + 20 + 1 + read-write + + + FH0_CBC_INT_ENA + 21 + 1 + read-write + + + FH1_CBC_INT_ENA + 22 + 1 + read-write + + + FH2_CBC_INT_ENA + 23 + 1 + read-write + + + FH0_OST_INT_ENA + 24 + 1 + read-write + + + FH1_OST_INT_ENA + 25 + 1 + read-write + + + FH2_OST_INT_ENA + 26 + 1 + read-write + + + CAP0_INT_ENA + 27 + 1 + read-write + + + CAP1_INT_ENA + 28 + 1 + read-write + + + CAP2_INT_ENA + 29 + 1 + read-write + + + + + INT_RAW + 0x114 + 0x20 + + + TIMER0_STOP_INT_RAW + 0 + 1 + read-only + + + TIMER1_STOP_INT_RAW + 1 + 1 + read-only + + + TIMER2_STOP_INT_RAW + 2 + 1 + read-only + + + TIMER0_TEZ_INT_RAW + 3 + 1 + read-only + + + TIMER1_TEZ_INT_RAW + 4 + 1 + read-only + + + TIMER2_TEZ_INT_RAW + 5 + 1 + read-only + + + TIMER0_TEP_INT_RAW + 6 + 1 + read-only + + + TIMER1_TEP_INT_RAW + 7 + 1 + read-only + + + TIMER2_TEP_INT_RAW + 8 + 1 + read-only + + + FAULT0_INT_RAW + 9 + 1 + read-only + + + FAULT1_INT_RAW + 10 + 1 + read-only + + + FAULT2_INT_RAW + 11 + 1 + read-only + + + FAULT0_CLR_INT_RAW + 12 + 1 + read-only + + + FAULT1_CLR_INT_RAW + 13 + 1 + read-only + + + FAULT2_CLR_INT_RAW + 14 + 1 + read-only + + + OP0_TEA_INT_RAW + 15 + 1 + read-only + + + OP1_TEA_INT_RAW + 16 + 1 + read-only + + + OP2_TEA_INT_RAW + 17 + 1 + read-only + + + OP0_TEB_INT_RAW + 18 + 1 + read-only + + + OP1_TEB_INT_RAW + 19 + 1 + read-only + + + OP2_TEB_INT_RAW + 20 + 1 + read-only + + + FH0_CBC_INT_RAW + 21 + 1 + read-only + + + FH1_CBC_INT_RAW + 22 + 1 + read-only + + + FH2_CBC_INT_RAW + 23 + 1 + read-only + + + FH0_OST_INT_RAW + 24 + 1 + read-only + + + FH1_OST_INT_RAW + 25 + 1 + read-only + + + FH2_OST_INT_RAW + 26 + 1 + read-only + + + CAP0_INT_RAW + 27 + 1 + read-only + + + CAP1_INT_RAW + 28 + 1 + read-only + + + CAP2_INT_RAW + 29 + 1 + read-only + + + + + INT_ST + 0x118 + 0x20 + + + TIMER0_STOP_INT_ST + 0 + 1 + read-only + + + TIMER1_STOP_INT_ST + 1 + 1 + read-only + + + TIMER2_STOP_INT_ST + 2 + 1 + read-only + + + TIMER0_TEZ_INT_ST + 3 + 1 + read-only + + + TIMER1_TEZ_INT_ST + 4 + 1 + read-only + + + TIMER2_TEZ_INT_ST + 5 + 1 + read-only + + + TIMER0_TEP_INT_ST + 6 + 1 + read-only + + + TIMER1_TEP_INT_ST + 7 + 1 + read-only + + + TIMER2_TEP_INT_ST + 8 + 1 + read-only + + + FAULT0_INT_ST + 9 + 1 + read-only + + + FAULT1_INT_ST + 10 + 1 + read-only + + + FAULT2_INT_ST + 11 + 1 + read-only + + + FAULT0_CLR_INT_ST + 12 + 1 + read-only + + + FAULT1_CLR_INT_ST + 13 + 1 + read-only + + + FAULT2_CLR_INT_ST + 14 + 1 + read-only + + + OP0_TEA_INT_ST + 15 + 1 + read-only + + + OP1_TEA_INT_ST + 16 + 1 + read-only + + + OP2_TEA_INT_ST + 17 + 1 + read-only + + + OP0_TEB_INT_ST + 18 + 1 + read-only + + + OP1_TEB_INT_ST + 19 + 1 + read-only + + + OP2_TEB_INT_ST + 20 + 1 + read-only + + + FH0_CBC_INT_ST + 21 + 1 + read-only + + + FH1_CBC_INT_ST + 22 + 1 + read-only + + + FH2_CBC_INT_ST + 23 + 1 + read-only + + + FH0_OST_INT_ST + 24 + 1 + read-only + + + FH1_OST_INT_ST + 25 + 1 + read-only + + + FH2_OST_INT_ST + 26 + 1 + read-only + + + CAP0_INT_ST + 27 + 1 + read-only + + + CAP1_INT_ST + 28 + 1 + read-only + + + CAP2_INT_ST + 29 + 1 + read-only + + + + + INT_CLR + 0x11C + 0x20 + + + TIMER0_STOP_INT_CLR + 0 + 1 + write-only + + + TIMER1_STOP_INT_CLR + 1 + 1 + write-only + + + TIMER2_STOP_INT_CLR + 2 + 1 + write-only + + + TIMER0_TEZ_INT_CLR + 3 + 1 + write-only + + + TIMER1_TEZ_INT_CLR + 4 + 1 + write-only + + + TIMER2_TEZ_INT_CLR + 5 + 1 + write-only + + + TIMER0_TEP_INT_CLR + 6 + 1 + write-only + + + TIMER1_TEP_INT_CLR + 7 + 1 + write-only + + + TIMER2_TEP_INT_CLR + 8 + 1 + write-only + + + FAULT0_INT_CLR + 9 + 1 + write-only + + + FAULT1_INT_CLR + 10 + 1 + write-only + + + FAULT2_INT_CLR + 11 + 1 + write-only + + + FAULT0_CLR_INT_CLR + 12 + 1 + write-only + + + FAULT1_CLR_INT_CLR + 13 + 1 + write-only + + + FAULT2_CLR_INT_CLR + 14 + 1 + write-only + + + OP0_TEA_INT_CLR + 15 + 1 + write-only + + + OP1_TEA_INT_CLR + 16 + 1 + write-only + + + OP2_TEA_INT_CLR + 17 + 1 + write-only + + + OP0_TEB_INT_CLR + 18 + 1 + write-only + + + OP1_TEB_INT_CLR + 19 + 1 + write-only + + + OP2_TEB_INT_CLR + 20 + 1 + write-only + + + FH0_CBC_INT_CLR + 21 + 1 + write-only + + + FH1_CBC_INT_CLR + 22 + 1 + write-only + + + FH2_CBC_INT_CLR + 23 + 1 + write-only + + + FH0_OST_INT_CLR + 24 + 1 + write-only + + + FH1_OST_INT_CLR + 25 + 1 + write-only + + + FH2_OST_INT_CLR + 26 + 1 + write-only + + + CAP0_INT_CLR + 27 + 1 + write-only + + + CAP1_INT_CLR + 28 + 1 + write-only + + + CAP2_INT_CLR + 29 + 1 + write-only + + + + + CLK + 0x120 + 0x20 + + + EN + 0 + 1 + read-write + + + + + VERSION + 0x124 + 0x20 + 0x02107230 + + + DATE + 0 + 28 + read-write + + + + + + + PWM1 + Motor Control Pulse-Width Modulation + 0x3FF6C000 + + PWM1 + 40 + + + + NRX + Peripheral NRX + NRX + 0x3FF5CC00 + + 0x0 + 0x4 + registers + + + + NRXPD_CTRL + WiFi RX control register + 0xD4 + 0x20 + + + DEMAP_FORCE_PD + 0 + 1 + read-write + + + DEMAP_FORCE_PU + 1 + 1 + read-write + + + VIT_FORCE_PD + 2 + 1 + read-write + + + VIT_FORCE_PU + 3 + 1 + read-write + + + RX_ROT_FORCE_PD + 4 + 1 + read-write + + + RX_ROT_FORCE_PU + 5 + 1 + read-write + + + CHAN_EST_FORCE_PD + 6 + 1 + read-write + + + CHAN_EST_FORCE_PU + 7 + 1 + read-write + + + + + + + PCNT + Pulse Count Controller + PCNT + 0x3FF57000 + + 0x0 + 0xB8 + registers + + + PCNT + 48 + + + + U0_CONF0 + 0x0 + 0x20 + 0x00003C10 + + + FILTER_THRES_U0 + This register is used to filter pluse whose width is smaller than this value for unit0. + 0 + 10 + read-write + + + FILTER_EN_U0 + This is the enable bit for filtering input signals for unit0. + 10 + 1 + read-write + + + THR_ZERO_EN_U0 + This is the enable bit for comparing unit0's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U0 + This is the enable bit for comparing unit0's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U0 + This is the enable bit for comparing unit0's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U0 + This is the enable bit for comparing unit0's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U0 + This is the enable bit for comparing unit0's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U0 + This register is used to control the mode of channel0's input negedge signal for unit0. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U0 + This register is used to control the mode of channel0's input posedge signal for unit0. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U0 + This register is used to control the mode of channel0's high control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U0 + This register is used to control the mode of channel0's low control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U0 + This register is used to control the mode of channel1's input negedge signal for unit0. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U0 + This register is used to control the mode of channel1's input posedge signal for unit0. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U0 + This register is used to control the mode of channel1's high control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U0 + This register is used to control the mode of channel1's low control signal for unit0. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U0_CONF1 + 0x4 + 0x20 + + + CNT_THRES0_U0 + This register is used to configure thres0 value for unit0. + 0 + 16 + read-write + + + CNT_THRES1_U0 + This register is used to configure thres1 value for unit0. + 16 + 16 + read-write + + + + + U0_CONF2 + 0x8 + 0x20 + + + CNT_H_LIM_U0 + This register is used to configure thr_h_lim value for unit0. + 0 + 16 + read-write + + + CNT_L_LIM_U0 + This register is used to confiugre thr_l_lim value for unit0. + 16 + 16 + read-write + + + + + U1_CONF0 + 0xC + 0x20 + 0x00003C10 + + + FILTER_THRES_U1 + This register is used to filter pluse whose width is smaller than this value for unit1. + 0 + 10 + read-write + + + FILTER_EN_U1 + This is the enable bit for filtering input signals for unit1. + 10 + 1 + read-write + + + THR_ZERO_EN_U1 + This is the enable bit for comparing unit1's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U1 + This is the enable bit for comparing unit1's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U1 + This is the enable bit for comparing unit1's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U1 + This is the enable bit for comparing unit1's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U1 + This is the enable bit for comparing unit1's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U1 + This register is used to control the mode of channel0's input negedge signal for unit1. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U1 + This register is used to control the mode of channel0's input posedge signal for unit1. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U1 + This register is used to control the mode of channel0's high control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U1 + This register is used to control the mode of channel0's low control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U1 + This register is used to control the mode of channel1's input negedge signal for unit1. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U1 + This register is used to control the mode of channel1's input posedge signal for unit1. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U1 + This register is used to control the mode of channel1's high control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U1 + This register is used to control the mode of channel1's low control signal for unit1. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U1_CONF1 + 0x10 + 0x20 + + + CNT_THRES0_U1 + This register is used to configure thres0 value for unit1. + 0 + 16 + read-write + + + CNT_THRES1_U1 + This register is used to configure thres1 value for unit1. + 16 + 16 + read-write + + + + + U1_CONF2 + 0x14 + 0x20 + + + CNT_H_LIM_U1 + This register is used to configure thr_h_lim value for unit1. + 0 + 16 + read-write + + + CNT_L_LIM_U1 + This register is used to confiugre thr_l_lim value for unit1. + 16 + 16 + read-write + + + + + U2_CONF0 + 0x18 + 0x20 + 0x00003C10 + + + FILTER_THRES_U2 + This register is used to filter pluse whose width is smaller than this value for unit2. + 0 + 10 + read-write + + + FILTER_EN_U2 + This is the enable bit for filtering input signals for unit2. + 10 + 1 + read-write + + + THR_ZERO_EN_U2 + This is the enable bit for comparing unit2's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U2 + This is the enable bit for comparing unit2's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U2 + This is the enable bit for comparing unit2's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U2 + This is the enable bit for comparing unit2's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U2 + This is the enable bit for comparing unit2's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U2 + This register is used to control the mode of channel0's input negedge signal for unit2. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U2 + This register is used to control the mode of channel0's input posedge signal for unit2. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U2 + This register is used to control the mode of channel0's high control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U2 + This register is used to control the mode of channel0's low control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U2 + This register is used to control the mode of channel1's input negedge signal for unit2. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U2 + This register is used to control the mode of channel1's input posedge signal for unit2. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U2 + This register is used to control the mode of channel1's high control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U2 + This register is used to control the mode of channel1's low control signal for unit2. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U2_CONF1 + 0x1C + 0x20 + + + CNT_THRES0_U2 + This register is used to configure thres0 value for unit2. + 0 + 16 + read-write + + + CNT_THRES1_U2 + This register is used to configure thres1 value for unit2. + 16 + 16 + read-write + + + + + U2_CONF2 + 0x20 + 0x20 + + + CNT_H_LIM_U2 + This register is used to configure thr_h_lim value for unit2. + 0 + 16 + read-write + + + CNT_L_LIM_U2 + This register is used to confiugre thr_l_lim value for unit2. + 16 + 16 + read-write + + + + + U3_CONF0 + 0x24 + 0x20 + 0x00003C10 + + + FILTER_THRES_U3 + This register is used to filter pluse whose width is smaller than this value for unit3. + 0 + 10 + read-write + + + FILTER_EN_U3 + This is the enable bit for filtering input signals for unit3. + 10 + 1 + read-write + + + THR_ZERO_EN_U3 + This is the enable bit for comparing unit3's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U3 + This is the enable bit for comparing unit3's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U3 + This is the enable bit for comparing unit3's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U3 + This is the enable bit for comparing unit3's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U3 + This is the enable bit for comparing unit3's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U3 + This register is used to control the mode of channel0's input negedge signal for unit3. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U3 + This register is used to control the mode of channel0's input posedge signal for unit3. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U3 + This register is used to control the mode of channel0's high control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U3 + This register is used to control the mode of channel0's low control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U3 + This register is used to control the mode of channel1's input negedge signal for unit3. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U3 + This register is used to control the mode of channel1's input posedge signal for unit3. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U3 + This register is used to control the mode of channel1's high control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U3 + This register is used to control the mode of channel1's low control signal for unit3. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U3_CONF1 + 0x28 + 0x20 + + + CNT_THRES0_U3 + This register is used to configure thres0 value for unit3. + 0 + 16 + read-write + + + CNT_THRES1_U3 + This register is used to configure thres1 value for unit3. + 16 + 16 + read-write + + + + + U3_CONF2 + 0x2C + 0x20 + + + CNT_H_LIM_U3 + This register is used to configure thr_h_lim value for unit3. + 0 + 16 + read-write + + + CNT_L_LIM_U3 + This register is used to confiugre thr_l_lim value for unit3. + 16 + 16 + read-write + + + + + U4_CONF0 + 0x30 + 0x20 + 0x00003C10 + + + FILTER_THRES_U4 + This register is used to filter pluse whose width is smaller than this value for unit4. + 0 + 10 + read-write + + + FILTER_EN_U4 + This is the enable bit for filtering input signals for unit4. + 10 + 1 + read-write + + + THR_ZERO_EN_U4 + This is the enable bit for comparing unit4's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U4 + This is the enable bit for comparing unit4's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U4 + This is the enable bit for comparing unit4's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U4 + This is the enable bit for comparing unit4's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U4 + This is the enable bit for comparing unit4's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U4 + This register is used to control the mode of channel0's input negedge signal for unit4. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U4 + This register is used to control the mode of channel0's input posedge signal for unit4. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U4 + This register is used to control the mode of channel0's high control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U4 + This register is used to control the mode of channel0's low control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U4 + This register is used to control the mode of channel1's input negedge signal for unit4. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U4 + This register is used to control the mode of channel1's input posedge signal for unit4. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U4 + This register is used to control the mode of channel1's high control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U4 + This register is used to control the mode of channel1's low control signal for unit4. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U4_CONF1 + 0x34 + 0x20 + + + CNT_THRES0_U4 + This register is used to configure thres0 value for unit4. + 0 + 16 + read-write + + + CNT_THRES1_U4 + This register is used to configure thres1 value for unit4. + 16 + 16 + read-write + + + + + U4_CONF2 + 0x38 + 0x20 + + + CNT_H_LIM_U4 + This register is used to configure thr_h_lim value for unit4. + 0 + 16 + read-write + + + CNT_L_LIM_U4 + This register is used to confiugre thr_l_lim value for unit4. + 16 + 16 + read-write + + + + + U5_CONF0 + 0x3C + 0x20 + 0x00003C10 + + + FILTER_THRES_U5 + This register is used to filter pluse whose width is smaller than this value for unit5. + 0 + 10 + read-write + + + FILTER_EN_U5 + This is the enable bit for filtering input signals for unit5. + 10 + 1 + read-write + + + THR_ZERO_EN_U5 + This is the enable bit for comparing unit5's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U5 + This is the enable bit for comparing unit5's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U5 + This is the enable bit for comparing unit5's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U5 + This is the enable bit for comparing unit5's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U5 + This is the enable bit for comparing unit5's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U5 + This register is used to control the mode of channel0's input negedge signal for unit5. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U5 + This register is used to control the mode of channel0's input posedge signal for unit5. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U5 + This register is used to control the mode of channel0's high control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U5 + This register is used to control the mode of channel0's low control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U5 + This register is used to control the mode of channel1's input negedge signal for unit5. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U5 + This register is used to control the mode of channel1's input posedge signal for unit5. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U5 + This register is used to control the mode of channel1's high control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U5 + This register is used to control the mode of channel1's low control signal for unit5. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U5_CONF1 + 0x40 + 0x20 + + + CNT_THRES0_U5 + This register is used to configure thres0 value for unit5. + 0 + 16 + read-write + + + CNT_THRES1_U5 + This register is used to configure thres1 value for unit5. + 16 + 16 + read-write + + + + + U5_CONF2 + 0x44 + 0x20 + + + CNT_H_LIM_U5 + This register is used to configure thr_h_lim value for unit5. + 0 + 16 + read-write + + + CNT_L_LIM_U5 + This register is used to confiugre thr_l_lim value for unit5. + 16 + 16 + read-write + + + + + U6_CONF0 + 0x48 + 0x20 + 0x00003C10 + + + FILTER_THRES_U6 + This register is used to filter pluse whose width is smaller than this value for unit6. + 0 + 10 + read-write + + + FILTER_EN_U6 + This is the enable bit for filtering input signals for unit6. + 10 + 1 + read-write + + + THR_ZERO_EN_U6 + This is the enable bit for comparing unit6's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U6 + This is the enable bit for comparing unit6's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U6 + This is the enable bit for comparing unit6's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U6 + This is the enable bit for comparing unit6's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U6 + This is the enable bit for comparing unit6's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U6 + This register is used to control the mode of channel0's input negedge signal for unit6. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U6 + This register is used to control the mode of channel0's input posedge signal for unit6. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U6 + This register is used to control the mode of channel0's high control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U6 + This register is used to control the mode of channel0's low control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U6 + This register is used to control the mode of channel1's input negedge signal for unit6. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U6 + This register is used to control the mode of channel1's input posedge signal for unit6. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U6 + This register is used to control the mode of channel1's high control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U6 + This register is used to control the mode of channel1's low control signal for unit6. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U6_CONF1 + 0x4C + 0x20 + + + CNT_THRES0_U6 + This register is used to configure thres0 value for unit6. + 0 + 16 + read-write + + + CNT_THRES1_U6 + This register is used to configure thres1 value for unit6. + 16 + 16 + read-write + + + + + U6_CONF2 + 0x50 + 0x20 + + + CNT_H_LIM_U6 + This register is used to configure thr_h_lim value for unit6. + 0 + 16 + read-write + + + CNT_L_LIM_U6 + This register is used to confiugre thr_l_lim value for unit6. + 16 + 16 + read-write + + + + + U7_CONF0 + 0x54 + 0x20 + 0x00003C10 + + + FILTER_THRES_U7 + This register is used to filter pluse whose width is smaller than this value for unit7. + 0 + 10 + read-write + + + FILTER_EN_U7 + This is the enable bit for filtering input signals for unit7. + 10 + 1 + read-write + + + THR_ZERO_EN_U7 + This is the enable bit for comparing unit7's count with 0 value. + 11 + 1 + read-write + + + THR_H_LIM_EN_U7 + This is the enable bit for comparing unit7's count with thr_h_lim value. + 12 + 1 + read-write + + + THR_L_LIM_EN_U7 + This is the enable bit for comparing unit7's count with thr_l_lim value. + 13 + 1 + read-write + + + THR_THRES0_EN_U7 + This is the enable bit for comparing unit7's count with thres0 value. + 14 + 1 + read-write + + + THR_THRES1_EN_U7 + This is the enable bit for comparing unit7's count with thres1 value . + 15 + 1 + read-write + + + CH0_NEG_MODE_U7 + This register is used to control the mode of channel0's input negedge signal for unit7. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 16 + 2 + read-write + + + CH0_POS_MODE_U7 + This register is used to control the mode of channel0's input posedge signal for unit7. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 18 + 2 + read-write + + + CH0_HCTRL_MODE_U7 + This register is used to control the mode of channel0's high control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 20 + 2 + read-write + + + CH0_LCTRL_MODE_U7 + This register is used to control the mode of channel0's low control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 22 + 2 + read-write + + + CH1_NEG_MODE_U7 + This register is used to control the mode of channel1's input negedge signal for unit7. 2'd1: increase at the negedge of input signal 2'd2:decrease at the negedge of input signal others:forbidden + 24 + 2 + read-write + + + CH1_POS_MODE_U7 + This register is used to control the mode of channel1's input posedge signal for unit7. 2'd1: increase at the posedge of input signal 2'd2:decrease at the posedge of input signal others:forbidden + 26 + 2 + read-write + + + CH1_HCTRL_MODE_U7 + This register is used to control the mode of channel1's high control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 28 + 2 + read-write + + + CH1_LCTRL_MODE_U7 + This register is used to control the mode of channel1's low control signal for unit7. 2'd0:increase when control signal is low 2'd1: decrease when control signal is high others:forbidden + 30 + 2 + read-write + + + + + U7_CONF1 + 0x58 + 0x20 + + + CNT_THRES0_U7 + This register is used to configure thres0 value for unit7. + 0 + 16 + read-write + + + CNT_THRES1_U7 + This register is used to configure thres1 value for unit7. + 16 + 16 + read-write + + + + + U7_CONF2 + 0x5C + 0x20 + + + CNT_H_LIM_U7 + This register is used to configure thr_h_lim value for unit7. + 0 + 16 + read-write + + + CNT_L_LIM_U7 + This register is used to confiugre thr_l_lim value for unit7. + 16 + 16 + read-write + + + + + U0_CNT + 0x60 + 0x20 + + + PLUS_CNT_U0 + This register stores the current pulse count value for unit0. + 0 + 16 + read-only + + + + + U1_CNT + 0x64 + 0x20 + + + PLUS_CNT_U1 + This register stores the current pulse count value for unit1. + 0 + 16 + read-only + + + + + U2_CNT + 0x68 + 0x20 + + + PLUS_CNT_U2 + This register stores the current pulse count value for unit2. + 0 + 16 + read-only + + + + + U3_CNT + 0x6C + 0x20 + + + PLUS_CNT_U3 + This register stores the current pulse count value for unit3. + 0 + 16 + read-only + + + + + U4_CNT + 0x70 + 0x20 + + + PLUS_CNT_U4 + This register stores the current pulse count value for unit4. + 0 + 16 + read-only + + + + + U5_CNT + 0x74 + 0x20 + + + PLUS_CNT_U5 + This register stores the current pulse count value for unit5. + 0 + 16 + read-only + + + + + U6_CNT + 0x78 + 0x20 + + + PLUS_CNT_U6 + This register stores the current pulse count value for unit6. + 0 + 16 + read-only + + + + + U7_CNT + 0x7C + 0x20 + + + PLUS_CNT_U7 + This register stores the current pulse count value for unit7. + 0 + 16 + read-only + + + + + INT_RAW + 0x80 + 0x20 + + + CNT_THR_EVENT_U0_INT_RAW + This is the interrupt raw bit for channel0 event. + 0 + 1 + read-only + + + CNT_THR_EVENT_U1_INT_RAW + This is the interrupt raw bit for channel1 event. + 1 + 1 + read-only + + + CNT_THR_EVENT_U2_INT_RAW + This is the interrupt raw bit for channel2 event. + 2 + 1 + read-only + + + CNT_THR_EVENT_U3_INT_RAW + This is the interrupt raw bit for channel3 event. + 3 + 1 + read-only + + + CNT_THR_EVENT_U4_INT_RAW + This is the interrupt raw bit for channel4 event. + 4 + 1 + read-only + + + CNT_THR_EVENT_U5_INT_RAW + This is the interrupt raw bit for channel5 event. + 5 + 1 + read-only + + + CNT_THR_EVENT_U6_INT_RAW + This is the interrupt raw bit for channel6 event. + 6 + 1 + read-only + + + CNT_THR_EVENT_U7_INT_RAW + This is the interrupt raw bit for channel7 event. + 7 + 1 + read-only + + + + + INT_ST + 0x84 + 0x20 + + + CNT_THR_EVENT_U0_INT_ST + This is the interrupt status bit for channel0 event. + 0 + 1 + read-only + + + CNT_THR_EVENT_U1_INT_ST + This is the interrupt status bit for channel1 event. + 1 + 1 + read-only + + + CNT_THR_EVENT_U2_INT_ST + This is the interrupt status bit for channel2 event. + 2 + 1 + read-only + + + CNT_THR_EVENT_U3_INT_ST + This is the interrupt status bit for channel3 event. + 3 + 1 + read-only + + + CNT_THR_EVENT_U4_INT_ST + This is the interrupt status bit for channel4 event. + 4 + 1 + read-only + + + CNT_THR_EVENT_U5_INT_ST + This is the interrupt status bit for channel5 event. + 5 + 1 + read-only + + + CNT_THR_EVENT_U6_INT_ST + This is the interrupt status bit for channel6 event. + 6 + 1 + read-only + + + CNT_THR_EVENT_U7_INT_ST + This is the interrupt status bit for channel7 event. + 7 + 1 + read-only + + + + + INT_ENA + 0x88 + 0x20 + + + CNT_THR_EVENT_U0_INT_ENA + This is the interrupt enable bit for channel0 event. + 0 + 1 + read-write + + + CNT_THR_EVENT_U1_INT_ENA + This is the interrupt enable bit for channel1 event. + 1 + 1 + read-write + + + CNT_THR_EVENT_U2_INT_ENA + This is the interrupt enable bit for channel2 event. + 2 + 1 + read-write + + + CNT_THR_EVENT_U3_INT_ENA + This is the interrupt enable bit for channel3 event. + 3 + 1 + read-write + + + CNT_THR_EVENT_U4_INT_ENA + This is the interrupt enable bit for channel4 event. + 4 + 1 + read-write + + + CNT_THR_EVENT_U5_INT_ENA + This is the interrupt enable bit for channel5 event. + 5 + 1 + read-write + + + CNT_THR_EVENT_U6_INT_ENA + This is the interrupt enable bit for channel6 event. + 6 + 1 + read-write + + + CNT_THR_EVENT_U7_INT_ENA + This is the interrupt enable bit for channel7 event. + 7 + 1 + read-write + + + + + INT_CLR + 0x8C + 0x20 + + + CNT_THR_EVENT_U0_INT_CLR + Set this bit to clear channel0 event interrupt. + 0 + 1 + write-only + + + CNT_THR_EVENT_U1_INT_CLR + Set this bit to clear channel1 event interrupt. + 1 + 1 + write-only + + + CNT_THR_EVENT_U2_INT_CLR + Set this bit to clear channel2 event interrupt. + 2 + 1 + write-only + + + CNT_THR_EVENT_U3_INT_CLR + Set this bit to clear channel3 event interrupt. + 3 + 1 + write-only + + + CNT_THR_EVENT_U4_INT_CLR + Set this bit to clear channel4 event interrupt. + 4 + 1 + write-only + + + CNT_THR_EVENT_U5_INT_CLR + Set this bit to clear channel5 event interrupt. + 5 + 1 + write-only + + + CNT_THR_EVENT_U6_INT_CLR + Set this bit to clear channel6 event interrupt. + 6 + 1 + write-only + + + CNT_THR_EVENT_U7_INT_CLR + Set this bit to clear channel7 event interrupt. + 7 + 1 + write-only + + + + + U0_STATUS + 0x90 + 0x20 + + + CORE_STATUS_U0 + 0 + 32 + read-only + + + STATUS_CNT_MODE + 0 + 2 + read-write + + + STATUS_THRES1 + 2 + 1 + read-write + + + STATUS_THRES0 + 3 + 1 + read-write + + + STATUS_L_LIM + 4 + 1 + read-write + + + STATUS_H_LIM + 5 + 1 + read-write + + + STATUS_ZERO + 6 + 1 + read-write + + + + + U1_STATUS + 0x94 + 0x20 + + + CORE_STATUS_U1 + 0 + 32 + read-only + + + + + U2_STATUS + 0x98 + 0x20 + + + CORE_STATUS_U2 + 0 + 32 + read-only + + + + + U3_STATUS + 0x9C + 0x20 + + + CORE_STATUS_U3 + 0 + 32 + read-only + + + + + U4_STATUS + 0xA0 + 0x20 + + + CORE_STATUS_U4 + 0 + 32 + read-only + + + + + U5_STATUS + 0xA4 + 0x20 + + + CORE_STATUS_U5 + 0 + 32 + read-only + + + + + U6_STATUS + 0xA8 + 0x20 + + + CORE_STATUS_U6 + 0 + 32 + read-only + + + + + U7_STATUS + 0xAC + 0x20 + + + CORE_STATUS_U7 + 0 + 32 + read-only + + + + + CTRL + 0xB0 + 0x20 + 0x00005555 + + + PLUS_CNT_RST_U0 + Set this bit to clear unit0's counter. + 0 + 1 + read-write + + + CNT_PAUSE_U0 + Set this bit to pause unit0's counter. + 1 + 1 + read-write + + + PLUS_CNT_RST_U1 + Set this bit to clear unit1's counter. + 2 + 1 + read-write + + + CNT_PAUSE_U1 + Set this bit to pause unit1's counter. + 3 + 1 + read-write + + + PLUS_CNT_RST_U2 + Set this bit to clear unit2's counter. + 4 + 1 + read-write + + + CNT_PAUSE_U2 + Set this bit to pause unit2's counter. + 5 + 1 + read-write + + + PLUS_CNT_RST_U3 + Set this bit to clear unit3's counter. + 6 + 1 + read-write + + + CNT_PAUSE_U3 + Set this bit to pause unit3's counter. + 7 + 1 + read-write + + + PLUS_CNT_RST_U4 + Set this bit to clear unit4's counter. + 8 + 1 + read-write + + + CNT_PAUSE_U4 + Set this bit to pause unit4's counter. + 9 + 1 + read-write + + + PLUS_CNT_RST_U5 + Set this bit to clear unit5's counter. + 10 + 1 + read-write + + + CNT_PAUSE_U5 + Set this bit to pause unit5's counter. + 11 + 1 + read-write + + + PLUS_CNT_RST_U6 + Set this bit to clear unit6's counter. + 12 + 1 + read-write + + + CNT_PAUSE_U6 + Set this bit to pause unit6's counter. + 13 + 1 + read-write + + + PLUS_CNT_RST_U7 + Set this bit to clear unit7's counter. + 14 + 1 + read-write + + + CNT_PAUSE_U7 + Set this bit to pause unit7's counter. + 15 + 1 + read-write + + + CLK_EN + 16 + 1 + read-write + + + + + DATE + 0xFC + 0x20 + 0x14122600 + + + DATE + 0 + 32 + read-write + + + + + + + RMT + Remote Control Peripheral + RMT + 0x3FF56000 + + 0x0 + 0xF8 + registers + + + RMT + 47 + + + + CH0DATA + 0x0 + 0x20 + + + CH1DATA + 0x4 + 0x20 + + + CH2DATA + 0x8 + 0x20 + + + CH3DATA + 0xC + 0x20 + + + CH4DATA + 0x10 + 0x20 + + + CH5DATA + 0x14 + 0x20 + + + CH6DATA + 0x18 + 0x20 + + + CH7DATA + 0x1C + 0x20 + + + 8 + 0x8 + 0-7 + CH%sCONF0 + 0x20 + 0x20 + 0x31100002 + + + DIV_CNT + This register is used to configure the frequency divider's factor in channel0. + 0 + 8 + read-write + + + IDLE_THRES + In receive mode when no edge is detected on the input signal for longer than reg_idle_thres_ch0 then the receive process is done. + 8 + 16 + read-write + + + MEM_SIZE + This register is used to configure the the amount of memory blocks allocated to channel0. + 24 + 4 + read-write + + + CARRIER_EN + This is the carrier modulation enable control bit for channel0. + 28 + 1 + read-write + + + CARRIER_OUT_LV + This bit is used to configure the way carrier wave is modulated for channel0.1'b1:transmit on low output level 1'b0:transmit on high output level. + 29 + 1 + read-write + + + MEM_PD + This bit is used to reduce power consumed by mem. 1:mem is in low power state. + 30 + 1 + read-write + + + CLK_EN + This bit is used to control clock.when software config RMT internal registers it controls the register clock. + 31 + 1 + read-write + + + + + 8 + 0x8 + 0-7 + CH%sCONF1 + 0x24 + 0x20 + 0x00000F20 + + + TX_START + Set this bit to start sending data for channel0. + 0 + 1 + read-write + + + RX_EN + Set this bit to enbale receving data for channel0. + 1 + 1 + read-write + + + MEM_WR_RST + Set this bit to reset write ram address for channel0 by receiver access. + 2 + 1 + read-write + + + MEM_RD_RST + Set this bit to reset read ram address for channel0 by transmitter access. + 3 + 1 + read-write + + + APB_MEM_RST + Set this bit to reset W/R ram address for channel0 by apb fifo access + 4 + 1 + read-write + + + MEM_OWNER + This is the mark of channel0's ram usage right.1'b1:receiver uses the ram 0:transmitter uses the ram + 5 + 1 + read-write + + + TX_CONTI_MODE + Set this bit to continue sending from the first data to the last data in channel0 again and again. + 6 + 1 + read-write + + + RX_FILTER_EN + This is the receive filter enable bit for channel0. + 7 + 1 + read-write + + + RX_FILTER_THRES + in receive mode channel0 ignore input pulse when the pulse width is smaller then this value. + 8 + 8 + read-write + + + REF_CNT_RST + This bit is used to reset divider in channel0. + 16 + 1 + read-write + + + REF_ALWAYS_ON + This bit is used to select base clock. 1'b1:clk_apb 1'b0:clk_ref + 17 + 1 + read-write + + + IDLE_OUT_LV + This bit configures the output signal's level for channel0 in IDLE state. + 18 + 1 + read-write + + + IDLE_OUT_EN + This is the output enable control bit for channel0 in IDLE state. + 19 + 1 + read-write + + + + + CH0STATUS + 0x60 + 0x20 + + + STATUS + The status for channel0 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel0. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel0. + 12 + 10 + read-only + + + STATE + The channel0 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel0 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel0 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel0. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel0 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel0 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH1STATUS + 0x64 + 0x20 + + + STATUS + The status for channel1 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel1. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel1. + 12 + 10 + read-only + + + STATE + The channel1 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel1 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel1 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel1. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel1 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel1 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH2STATUS + 0x68 + 0x20 + + + STATUS + The status for channel2 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel2. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel2. + 12 + 10 + read-only + + + STATE + The channel2 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel2 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel2 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel2. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel2 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel2 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH3STATUS + 0x6C + 0x20 + + + STATUS + The status for channel3 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel3. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel3. + 12 + 10 + read-only + + + STATE + The channel3 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel3 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel3 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel3. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel3 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel3 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH4STATUS + 0x70 + 0x20 + + + STATUS + The status for channel4 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel4. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel4. + 12 + 10 + read-only + + + STATE + The channel4 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel4 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel4 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel4. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel4 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel4 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH5STATUS + 0x74 + 0x20 + + + STATUS + The status for channel5 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel5. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel5. + 12 + 10 + read-only + + + STATE + The channel5 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel5 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel5 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel5. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel5 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel5 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH6STATUS + 0x78 + 0x20 + + + STATUS + The status for channel6 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel6. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel6. + 12 + 10 + read-only + + + STATE + The channel6 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel6 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel6 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel6. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel6 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel6 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH7STATUS + 0x7C + 0x20 + + + STATUS + The status for channel7 + 0 + 32 + read-only + + + MEM_WADDR_EX + The current memory read address of channel7. + 0 + 10 + read-only + + + MEM_RADDR_EX + The current memory write address of channel7. + 12 + 10 + read-only + + + STATE + The channel7 state machine status register.3'h0 : idle, 3'h1 : send, 3'h2 : read memory, 3'h3 : receive, 3'h4 : wait. + 24 + 3 + read-only + + + MEM_OWNER_ERR + When channel7 is configured for receive mode, this bit will turn to high level if rmt_mem_owner register is not set to 1. + 27 + 1 + read-only + + + MEM_FULL + The memory full status bit for channel7 turns to high level when mem_waddr_ex is greater than or equal to the configuration range. + 28 + 1 + read-only + + + MEM_EMPTY + The memory empty status bit for channel7. in acyclic mode, this bit turns to high level when mem_raddr_ex is greater than or equal to the configured range. + 29 + 1 + read-only + + + APB_MEM_WR_ERR + The apb write memory status bit for channel7 turns to high level when the apb write address exceeds the configuration range. + 30 + 1 + read-only + + + APB_MEM_RD_ERR + The apb read memory status bit for channel7 turns to high level when the apb read address exceeds the configuration range. + 31 + 1 + read-only + + + + + CH0ADDR + 0x80 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel0 by apb fifo access + 0 + 32 + read-only + + + + + CH1ADDR + 0x84 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel1 by apb fifo access + 0 + 32 + read-only + + + + + CH2ADDR + 0x88 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel2 by apb fifo access + 0 + 32 + read-only + + + + + CH3ADDR + 0x8C + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel3 by apb fifo access + 0 + 32 + read-only + + + + + CH4ADDR + 0x90 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel4 by apb fifo access + 0 + 32 + read-only + + + + + CH5ADDR + 0x94 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel5 by apb fifo access + 0 + 32 + read-only + + + + + CH6ADDR + 0x98 + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel6 by apb fifo access + 0 + 32 + read-only + + + + + CH7ADDR + 0x9C + 0x20 + + + APB_MEM_ADDR + The ram relative address in channel7 by apb fifo access + 0 + 32 + read-only + + + + + INT_RAW + 0xA0 + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_RAW + The interrupt raw bit for channel %s turns to high level when the transmit process is done. + 0 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_RAW + The interrupt raw bit for channel %s turns to high level when the receive process is done. + 1 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_RAW + The interrupt raw bit for channel %s turns to high level when channle %s detects some errors. + 2 + 1 + read-only + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_RAW + The interrupt raw bit for channel %s turns to high level when transmitter in channle%s have send datas more than reg_rmt_tx_lim_ch%s after detecting this interrupt software can updata the old datas with new datas. + 24 + 1 + read-only + + + + + INT_ST + 0xA4 + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_ST + The interrupt state bit for channel %s's mt_ch%s_tx_end_int_raw when mt_ch%s_tx_end_int_ena is set to %s. + 0 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_ST + The interrupt state bit for channel %s's rmt_ch%s_rx_end_int_raw when rmt_ch%s_rx_end_int_ena is set to %s. + 1 + 1 + read-only + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_ST + The interrupt state bit for channel %s's rmt_ch%s_err_int_raw when rmt_ch%s_err_int_ena is set to %s. + 2 + 1 + read-only + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_ST + The interrupt state bit for channel %s's rmt_ch%s_tx_thr_event_int_raw when mt_ch%s_tx_thr_event_int_ena is set to 1. + 24 + 1 + read-only + + + + + INT_ENA + 0xA8 + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_ENA + Set this bit to enable rmt_ch%s_tx_end_int_st. + 0 + 1 + read-write + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_ENA + Set this bit to enable rmt_ch%s_rx_end_int_st. + 1 + 1 + read-write + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_ENA + Set this bit to enable rmt_ch%s_err_int_st. + 2 + 1 + read-write + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_ENA + Set this bit to enable rmt_ch%s_tx_thr_event_int_st. + 24 + 1 + read-write + + + + + INT_CLR + 0xAC + 0x20 + + + 8 + 0x3 + 0-7 + CH%s_TX_END_INT_CLR + Set this bit to clear the rmt_ch%s_rx_end_int_raw.. + 0 + 1 + write-only + + + 8 + 0x3 + 0-7 + CH%s_RX_END_INT_CLR + Set this bit to clear the rmt_ch%s_tx_end_int_raw. + 1 + 1 + write-only + + + 8 + 0x3 + 0-7 + CH%s_ERR_INT_CLR + Set this bit to clear the rmt_ch%s_err_int_raw. + 2 + 1 + write-only + + + 8 + 0x1 + 0-7 + CH%s_TX_THR_EVENT_INT_CLR + Set this bit to clear the rmt_ch%s_tx_thr_event_int_raw interrupt. + 24 + 1 + write-only + + + + + CH0CARRIER_DUTY + 0xB0 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel0. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel0. + 16 + 16 + read-write + + + + + CH1CARRIER_DUTY + 0xB4 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel1. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel1. + 16 + 16 + read-write + + + + + CH2CARRIER_DUTY + 0xB8 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel2. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel2. + 16 + 16 + read-write + + + + + CH3CARRIER_DUTY + 0xBC + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel3. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel3. + 16 + 16 + read-write + + + + + CH4CARRIER_DUTY + 0xC0 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel4. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel4. + 16 + 16 + read-write + + + + + CH5CARRIER_DUTY + 0xC4 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel5. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel5. + 16 + 16 + read-write + + + + + CH6CARRIER_DUTY + 0xC8 + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel6. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel6. + 16 + 16 + read-write + + + + + CH7CARRIER_DUTY + 0xCC + 0x20 + 0x00400040 + + + CARRIER_LOW + This register is used to configure carrier wave's low level value for channel7. + 0 + 16 + read-write + + + CARRIER_HIGH + This register is used to configure carrier wave's high level value for channel7. + 16 + 16 + read-write + + + + + 8 + 0x4 + 0-7 + CH%s_TX_LIM + 0xD0 + 0x20 + 0x00000080 + + + TX_LIM + When channel0 sends more than reg_rmt_tx_lim_ch0 datas then channel0 produce the relative interrupt. + 0 + 9 + read-write + + + + + APB_CONF + 0xF0 + 0x20 + + + APB_FIFO_MASK + Set this bit to disable apb fifo access + 0 + 1 + read-write + + + MEM_TX_WRAP_EN + when datas need to be send is more than channel's mem can store then set this bit to enable reusage of mem this bit is used together with reg_rmt_tx_lim_chn. + 1 + 1 + read-write + + + + + DATE + 0xFC + 0x20 + 0x16022600 + + + DATE + This is the version register. + 0 + 32 + read-write + + + + + + + RNG + Hardware random number generator + RNG + 0x60035000 + + 0x0 + 0x4 + registers + + + + DATA + Random number data + 0x144 + 0x20 + + + + + RSA + RSA (Rivest Shamir Adleman) Accelerator + RSA + 0x3FF02000 + + 0x0 + 0x1C + registers + + + RSA + 51 + + + + M_PRIME + 0x0 + 0x20 + + + M_PRIME + This register contains M’. + 0 + 8 + read-write + + + + + MODEXP_MODE + 0x4 + 0x20 + + + MODEXP_MODE + This register contains the mode of modular exponentiation. + 0 + 2 + read-write + + + + + MODEXP_START + 0x8 + 0x20 + + + MODEXP_START + Write 1 to start modular exponentiation. + 0 + 1 + write-only + + + + + MULT_MODE + 0xC + 0x20 + + + MULT_MODE + This register contains the mode of modular multiplication and multiplication. + 0 + 1 + read-write + + + + + MULT_START + 0x10 + 0x20 + + + MULT_START + Write 1 to start modular multiplication or multiplication. + 0 + 1 + write-only + + + + + INTERRUPT + 0x14 + 0x20 + + + INTERRUPT + RSA interrupt status register. Will read 1 once an operation has completed. + 0 + 1 + read-write + + + + + CLEAN + 0x18 + 0x20 + + + CLEAN + This bit will read 1 once the memory initialization is completed. + 0 + 1 + read-only + + + + + + + RTC_CNTL + Real-Time Clock Control + RTC_CNTL + 0x3FF48000 + + 0x0 + 0xDC + registers + + + RTC_CORE + 46 + + + + OPTIONS0 + 0x0 + 0x20 + 0x1C492000 + + + SW_STALL_APPCPU_C0 + {reg_sw_stall_appcpu_c1[5:0] reg_sw_stall_appcpu_c0[1:0]} == 0x86 will stall APP CPU + 0 + 2 + read-write + + + SW_STALL_PROCPU_C0 + {reg_sw_stall_procpu_c1[5:0] reg_sw_stall_procpu_c0[1:0]} == 0x86 will stall PRO CPU + 2 + 2 + read-write + + + SW_APPCPU_RST + APP CPU SW reset + 4 + 1 + write-only + + + SW_PROCPU_RST + PRO CPU SW reset + 5 + 1 + write-only + + + BB_I2C_FORCE_PD + BB_I2C force power down + 6 + 1 + read-write + + + BB_I2C_FORCE_PU + BB_I2C force power up + 7 + 1 + read-write + + + BBPLL_I2C_FORCE_PD + BB_PLL _I2C force power down + 8 + 1 + read-write + + + BBPLL_I2C_FORCE_PU + BB_PLL_I2C force power up + 9 + 1 + read-write + + + BBPLL_FORCE_PD + BB_PLL force power down + 10 + 1 + read-write + + + BBPLL_FORCE_PU + BB_PLL force power up + 11 + 1 + read-write + + + XTL_FORCE_PD + crystall force power down + 12 + 1 + read-write + + + XTL_FORCE_PU + crystall force power up + 13 + 1 + read-write + + + BIAS_SLEEP_FOLW_8M + BIAS_SLEEP follow CK8M + 14 + 1 + read-write + + + BIAS_FORCE_SLEEP + BIAS_SLEEP force sleep + 15 + 1 + read-write + + + BIAS_FORCE_NOSLEEP + BIAS_SLEEP force no sleep + 16 + 1 + read-write + + + BIAS_I2C_FOLW_8M + BIAS_I2C follow CK8M + 17 + 1 + read-write + + + BIAS_I2C_FORCE_PD + BIAS_I2C force power down + 18 + 1 + read-write + + + BIAS_I2C_FORCE_PU + BIAS_I2C force power up + 19 + 1 + read-write + + + BIAS_CORE_FOLW_8M + BIAS_CORE follow CK8M + 20 + 1 + read-write + + + BIAS_CORE_FORCE_PD + BIAS_CORE force power down + 21 + 1 + read-write + + + BIAS_CORE_FORCE_PU + BIAS_CORE force power up + 22 + 1 + read-write + + + XTL_FORCE_ISO + 23 + 1 + read-write + + + PLL_FORCE_ISO + 24 + 1 + read-write + + + ANALOG_FORCE_ISO + 25 + 1 + read-write + + + XTL_FORCE_NOISO + 26 + 1 + read-write + + + PLL_FORCE_NOISO + 27 + 1 + read-write + + + ANALOG_FORCE_NOISO + 28 + 1 + read-write + + + DG_WRAP_FORCE_RST + digital wrap force reset in deep sleep + 29 + 1 + read-write + + + DG_WRAP_FORCE_NORST + digital core force no reset in deep sleep + 30 + 1 + read-write + + + SW_SYS_RST + SW system reset + 31 + 1 + write-only + + + + + SLP_TIMER0 + 0x4 + 0x20 + + + SLP_VAL_LO + RTC sleep timer low 32 bits + 0 + 32 + read-write + + + + + SLP_TIMER1 + 0x8 + 0x20 + + + SLP_VAL_HI + RTC sleep timer high 16 bits + 0 + 16 + read-write + + + MAIN_TIMER_ALARM_EN + timer alarm enable bit + 16 + 1 + read-write + + + + + TIME_UPDATE + 0xC + 0x20 + + + TIME_VALID + To indicate the register is updated + 30 + 1 + read-only + + + TIME_UPDATE + Set 1: to update register with RTC timer + 31 + 1 + write-only + + + + + TIME0 + 0x10 + 0x20 + + + TIME_LO + RTC timer low 32 bits + 0 + 32 + read-only + + + + + TIME1 + 0x14 + 0x20 + + + TIME_HI + RTC timer high 16 bits + 0 + 16 + read-only + + + + + STATE0 + 0x18 + 0x20 + 0x00300000 + + + TOUCH_WAKEUP_FORCE_EN + touch controller force wake up + 20 + 1 + read-write + + + ULP_CP_WAKEUP_FORCE_EN + ULP-coprocessor force wake up + 21 + 1 + read-write + + + APB2RTC_BRIDGE_SEL + 1: APB to RTC using bridge 0: APB to RTC using sync + 22 + 1 + read-write + + + TOUCH_SLP_TIMER_EN + touch timer enable bit + 23 + 1 + read-write + + + ULP_CP_SLP_TIMER_EN + ULP-coprocessor timer enable bit + 24 + 1 + read-write + + + SDIO_ACTIVE_IND + SDIO active indication + 28 + 1 + read-only + + + SLP_WAKEUP + sleep wakeup bit + 29 + 1 + read-write + + + SLP_REJECT + sleep reject bit + 30 + 1 + read-write + + + SLEEP_EN + sleep enable bit + 31 + 1 + read-write + + + + + TIMER1 + 0x1C + 0x20 + 0x28140403 + + + CPU_STALL_EN + CPU stall enable bit + 0 + 1 + read-write + + + CPU_STALL_WAIT + CPU stall wait cycles in fast_clk_rtc + 1 + 5 + read-write + + + CK8M_WAIT + CK8M wait cycles in slow_clk_rtc + 6 + 8 + read-write + + + XTL_BUF_WAIT + XTAL wait cycles in slow_clk_rtc + 14 + 10 + read-write + + + PLL_BUF_WAIT + PLL wait cycles in slow_clk_rtc + 24 + 8 + read-write + + + + + TIMER2 + 0x20 + 0x20 + 0x01080000 + + + ULPCP_TOUCH_START_WAIT + wait cycles in slow_clk_rtc before ULP-coprocessor / touch controller start to work + 15 + 9 + read-write + + + MIN_TIME_CK8M_OFF + minimal cycles in slow_clk_rtc for CK8M in power down state + 24 + 8 + read-write + + + + + TIMER3 + 0x24 + 0x20 + 0x14160A08 + + + WIFI_WAIT_TIMER + 0 + 9 + read-write + + + WIFI_POWERUP_TIMER + 9 + 7 + read-write + + + ROM_RAM_WAIT_TIMER + 16 + 9 + read-write + + + ROM_RAM_POWERUP_TIMER + 25 + 7 + read-write + + + + + TIMER4 + 0x28 + 0x20 + 0x10200A08 + + + WAIT_TIMER + 0 + 9 + read-write + + + POWERUP_TIMER + 9 + 7 + read-write + + + DG_WRAP_WAIT_TIMER + 16 + 9 + read-write + + + DG_WRAP_POWERUP_TIMER + 25 + 7 + read-write + + + + + TIMER5 + 0x2C + 0x20 + 0x12148001 + + + ULP_CP_SUBTIMER_PREDIV + 0 + 8 + read-write + + + MIN_SLP_VAL + minimal sleep cycles in slow_clk_rtc + 8 + 8 + read-write + + + RTCMEM_WAIT_TIMER + 16 + 9 + read-write + + + RTCMEM_POWERUP_TIMER + 25 + 7 + read-write + + + + + ANA_CONF + 0x30 + 0x20 + 0x00800000 + + + PLLA_FORCE_PD + PLLA force power down + 23 + 1 + read-write + + + PLLA_FORCE_PU + PLLA force power up + 24 + 1 + read-write + + + BBPLL_CAL_SLP_START + start BBPLL calibration during sleep + 25 + 1 + read-write + + + PVTMON_PU + 1: PVTMON power up otherwise power down + 26 + 1 + read-write + + + TXRF_I2C_PU + 1: TXRF_I2C power up otherwise power down + 27 + 1 + read-write + + + RFRX_PBUS_PU + 1: RFRX_PBUS power up otherwise power down + 28 + 1 + read-write + + + CKGEN_I2C_PU + 1: CKGEN_I2C power up otherwise power down + 30 + 1 + read-write + + + PLL_I2C_PU + 1: PLL_I2C power up otherwise power down + 31 + 1 + read-write + + + + + RESET_STATE + 0x34 + 0x20 + 0x00003000 + + + RESET_CAUSE_PROCPU + reset cause of PRO CPU + 0 + 6 + read-only + + + RESET_CAUSE_APPCPU + reset cause of APP CPU + 6 + 6 + read-only + + + APPCPU_STAT_VECTOR_SEL + APP CPU state vector sel + 12 + 1 + read-write + + + PROCPU_STAT_VECTOR_SEL + PRO CPU state vector sel + 13 + 1 + read-write + + + + + WAKEUP_STATE + 0x38 + 0x20 + 0x00006000 + + + WAKEUP_CAUSE + wakeup cause + 0 + 11 + read-only + + + WAKEUP_ENA + wakeup enable bitmap + 11 + 11 + read-write + + + GPIO_WAKEUP_FILTER + enable filter for gpio wakeup event + 22 + 1 + read-write + + + + + INT_ENA + 0x3C + 0x20 + + + SLP_WAKEUP_INT_ENA + enable sleep wakeup interrupt + 0 + 1 + read-write + + + SLP_REJECT_INT_ENA + enable sleep reject interrupt + 1 + 1 + read-write + + + SDIO_IDLE_INT_ENA + enable SDIO idle interrupt + 2 + 1 + read-write + + + WDT_INT_ENA + enable RTC WDT interrupt + 3 + 1 + read-write + + + TIME_VALID_INT_ENA + enable RTC time valid interrupt + 4 + 1 + read-write + + + ULP_CP_INT_ENA + enable ULP-coprocessor interrupt + 5 + 1 + read-write + + + TOUCH_INT_ENA + enable touch interrupt + 6 + 1 + read-write + + + BROWN_OUT_INT_ENA + enable brown out interrupt + 7 + 1 + read-write + + + MAIN_TIMER_INT_ENA + enable RTC main timer interrupt + 8 + 1 + read-write + + + + + INT_RAW + 0x40 + 0x20 + + + SLP_WAKEUP_INT_RAW + sleep wakeup interrupt raw + 0 + 1 + read-only + + + SLP_REJECT_INT_RAW + sleep reject interrupt raw + 1 + 1 + read-only + + + SDIO_IDLE_INT_RAW + SDIO idle interrupt raw + 2 + 1 + read-only + + + WDT_INT_RAW + RTC WDT interrupt raw + 3 + 1 + read-only + + + TIME_VALID_INT_RAW + RTC time valid interrupt raw + 4 + 1 + read-only + + + ULP_CP_INT_RAW + ULP-coprocessor interrupt raw + 5 + 1 + read-only + + + TOUCH_INT_RAW + touch interrupt raw + 6 + 1 + read-only + + + BROWN_OUT_INT_RAW + brown out interrupt raw + 7 + 1 + read-only + + + MAIN_TIMER_INT_RAW + RTC main timer interrupt raw + 8 + 1 + read-only + + + + + INT_ST + 0x44 + 0x20 + + + SLP_WAKEUP_INT_ST + sleep wakeup interrupt state + 0 + 1 + read-only + + + SLP_REJECT_INT_ST + sleep reject interrupt state + 1 + 1 + read-only + + + SDIO_IDLE_INT_ST + SDIO idle interrupt state + 2 + 1 + read-only + + + WDT_INT_ST + RTC WDT interrupt state + 3 + 1 + read-only + + + TIME_VALID_INT_ST + RTC time valid interrupt state + 4 + 1 + read-only + + + SAR_INT_ST + ULP-coprocessor interrupt state + 5 + 1 + read-only + + + TOUCH_INT_ST + touch interrupt state + 6 + 1 + read-only + + + BROWN_OUT_INT_ST + brown out interrupt state + 7 + 1 + read-only + + + MAIN_TIMER_INT_ST + RTC main timer interrupt state + 8 + 1 + read-only + + + + + INT_CLR + 0x48 + 0x20 + + + SLP_WAKEUP_INT_CLR + Clear sleep wakeup interrupt state + 0 + 1 + write-only + + + SLP_REJECT_INT_CLR + Clear sleep reject interrupt state + 1 + 1 + write-only + + + SDIO_IDLE_INT_CLR + Clear SDIO idle interrupt state + 2 + 1 + write-only + + + WDT_INT_CLR + Clear RTC WDT interrupt state + 3 + 1 + write-only + + + TIME_VALID_INT_CLR + Clear RTC time valid interrupt state + 4 + 1 + write-only + + + SAR_INT_CLR + Clear ULP-coprocessor interrupt state + 5 + 1 + write-only + + + TOUCH_INT_CLR + Clear touch interrupt state + 6 + 1 + write-only + + + BROWN_OUT_INT_CLR + Clear brown out interrupt state + 7 + 1 + write-only + + + MAIN_TIMER_INT_CLR + Clear RTC main timer interrupt state + 8 + 1 + write-only + + + + + STORE0 + 0x4C + 0x20 + + + SCRATCH0 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE1 + 0x50 + 0x20 + + + SCRATCH1 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE2 + 0x54 + 0x20 + + + SCRATCH2 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE3 + 0x58 + 0x20 + + + SCRATCH3 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + EXT_XTL_CONF + 0x5C + 0x20 + + + XTL_EXT_CTR_LV + 0: power down XTAL at high level 1: power down XTAL at low level + 30 + 1 + read-write + + + XTL_EXT_CTR_EN + enable control XTAL by external pads + 31 + 1 + read-write + + + + + EXT_WAKEUP_CONF + 0x60 + 0x20 + + + EXT_WAKEUP0_LV + 0: external wakeup at low level 1: external wakeup at high level + 30 + 1 + read-write + + + EXT_WAKEUP1_LV + 0: external wakeup at low level 1: external wakeup at high level + 31 + 1 + read-write + + + + + SLP_REJECT_CONF + 0x64 + 0x20 + + + GPIO_REJECT_EN + enable GPIO reject + 24 + 1 + read-write + + + SDIO_REJECT_EN + enable SDIO reject + 25 + 1 + read-write + + + LIGHT_SLP_REJECT_EN + enable reject for light sleep + 26 + 1 + read-write + + + DEEP_SLP_REJECT_EN + enable reject for deep sleep + 27 + 1 + read-write + + + REJECT_CAUSE + sleep reject cause + 28 + 4 + read-only + + + + + CPU_PERIOD_CONF + 0x68 + 0x20 + + + CPUSEL_CONF + CPU sel option + 29 + 1 + read-write + + + CPUPERIOD_SEL + CPU period sel + 30 + 2 + read-write + + + + + SDIO_ACT_CONF + 0x6C + 0x20 + + + SDIO_ACT_DNUM + 22 + 10 + read-write + + + + + CLK_CONF + 0x70 + 0x20 + 0x00002210 + + + CK8M_DIV + CK8M_D256_OUT divider. 00: div128 01: div256 10: div512 11: div1024. + 4 + 2 + read-write + + CK8M_DIV + read-write + + DIV128 + DIV128 + 0 + + + DIV256 + DIV256 + 1 + + + DIV512 + DIV512 + 2 + + + DIV1024 + DIV1024 + 3 + + + + + ENB_CK8M + disable CK8M and CK8M_D256_OUT + 6 + 1 + read-write + + + ENB_CK8M_DIV + 1: CK8M_D256_OUT is actually CK8M 0: CK8M_D256_OUT is CK8M divided by 256 + 7 + 1 + read-write + + ENB_CK8M_DIV + read-write + + CK8M_DIV_256 + CK8M_DIV_256 + 0 + + + CK8M + CK8M + 1 + + + + + DIG_XTAL32K_EN + enable CK_XTAL_32K for digital core (no relationship with RTC core) + 8 + 1 + read-write + + + DIG_CLK8M_D256_EN + enable CK8M_D256_OUT for digital core (no relationship with RTC core) + 9 + 1 + read-write + + + DIG_CLK8M_EN + enable CK8M for digital core (no relationship with RTC core) + 10 + 1 + read-write + + + CK8M_DFREQ_FORCE + 11 + 1 + read-write + + + CK8M_DIV_SEL + divider = reg_ck8m_div_sel + 1 + 12 + 3 + read-write + + + XTAL_FORCE_NOGATING + XTAL force no gating during sleep + 15 + 1 + read-write + + + CK8M_FORCE_NOGATING + CK8M force no gating during sleep + 16 + 1 + read-write + + + CK8M_DFREQ + CK8M_DFREQ + 17 + 8 + read-write + + + CK8M_FORCE_PD + CK8M force power down + 25 + 1 + read-write + + + CK8M_FORCE_PU + CK8M force power up + 26 + 1 + read-write + + + SOC_CLK_SEL + SOC clock sel. 0: XTAL 1: PLL 2: CK8M 3: APLL + 27 + 2 + read-write + + SOC_CLK_SEL + read-write + + XTAL + XTAL + 0 + + + PLL + PLL + 1 + + + CK8M + CK8M + 2 + + + APLL + APLL + 3 + + + + + FAST_CLK_RTC_SEL + fast_clk_rtc sel. 0: XTAL div 4 1: CK8M + 29 + 1 + read-write + + FAST_CLK_RTC_SEL + read-write + + XTAL_DIV_4 + XTAL_DIV_4 + 0 + + + CK8M + CK8M + 1 + + + + + ANA_CLK_RTC_SEL + slow_clk_rtc sel. 0: SLOW_CK 1: CK_XTAL_32K 2: CK8M_D256_OUT + 30 + 2 + read-write + + ANA_CLK_RTC_SEL + read-write + + SLOW_CK + SLOW_CK + 0 + + + CK_XTAL_32K + CK_XTAL_32K + 1 + + + CK8M_D256_OUT + CK8M_D256_OUT + 2 + + + + + + + SDIO_CONF + 0x74 + 0x20 + 0x02A00000 + + + SDIO_PD_EN + power down SDIO_REG in sleep. Only active when reg_sdio_force = 0 + 21 + 1 + read-write + + + SDIO_FORCE + 1: use SW option to control SDIO_REG 0: use state machine + 22 + 1 + read-write + + + SDIO_TIEH + SW option for SDIO_TIEH. Only active when reg_sdio_force = 1 + 23 + 1 + read-write + + + REG1P8_READY + read only register for REG1P8_READY + 24 + 1 + read-only + + + DREFL_SDIO + SW option for DREFL_SDIO. Only active when reg_sdio_force = 1 + 25 + 2 + read-write + + + DREFM_SDIO + SW option for DREFM_SDIO. Only active when reg_sdio_force = 1 + 27 + 2 + read-write + + + DREFH_SDIO + SW option for DREFH_SDIO. Only active when reg_sdio_force = 1 + 29 + 2 + read-write + + + XPD_SDIO + SW option for XPD_SDIO_REG. Only active when reg_sdio_force = 1 + 31 + 1 + read-write + + + + + BIAS_CONF + 0x78 + 0x20 + + + DBG_ATTEN + DBG_ATTEN + 24 + 2 + read-write + + + ENB_SCK_XTAL + ENB_SCK_XTAL + 26 + 1 + read-write + + + INC_HEARTBEAT_REFRESH + INC_HEARTBEAT_REFRESH + 27 + 1 + read-write + + + DEC_HEARTBEAT_PERIOD + DEC_HEARTBEAT_PERIOD + 28 + 1 + read-write + + + INC_HEARTBEAT_PERIOD + INC_HEARTBEAT_PERIOD + 29 + 1 + read-write + + + DEC_HEARTBEAT_WIDTH + DEC_HEARTBEAT_WIDTH + 30 + 1 + read-write + + + RST_BIAS_I2C + RST_BIAS_I2C + 31 + 1 + read-write + + + + + REG + 0x7C + 0x20 + 0x29002400 + + + SCK_DCAP_FORCE + N/A + 7 + 1 + read-write + + + DIG_DBIAS_SLP + DIG_REG_DBIAS during sleep + 8 + 3 + read-write + + + DIG_DBIAS_WAK + DIG_REG_DBIAS during wakeup + 11 + 3 + read-write + + + SCK_DCAP + SCK_DCAP + 14 + 8 + read-write + + + DBIAS_SLP + RTC_DBIAS during sleep + 22 + 3 + read-write + + + DBIAS_WAK + RTC_DBIAS during wakeup + 25 + 3 + read-write + + + DBOOST_FORCE_PD + RTC_DBOOST force power down + 28 + 1 + read-write + + + DBOOST_FORCE_PU + RTC_DBOOST force power up + 29 + 1 + read-write + + + FORCE_PD + RTC_REG force power down (for RTC_REG power down means decrease the voltage to 0.8v or lower ) + 30 + 1 + read-write + + + FORCE_PU + RTC_REG force power up + 31 + 1 + read-write + + + + + PWC + 0x80 + 0x20 + 0x00012925 + + + FASTMEM_FORCE_NOISO + Fast RTC memory force no ISO + 0 + 1 + read-write + + + FASTMEM_FORCE_ISO + Fast RTC memory force ISO + 1 + 1 + read-write + + + SLOWMEM_FORCE_NOISO + RTC memory force no ISO + 2 + 1 + read-write + + + SLOWMEM_FORCE_ISO + RTC memory force ISO + 3 + 1 + read-write + + + FORCE_ISO + rtc_peri force ISO + 4 + 1 + read-write + + + FORCE_NOISO + rtc_peri force no ISO + 5 + 1 + read-write + + + FASTMEM_FOLW_CPU + 1: Fast RTC memory PD following CPU 0: fast RTC memory PD following RTC state machine + 6 + 1 + read-write + + + FASTMEM_FORCE_LPD + Fast RTC memory force PD + 7 + 1 + read-write + + + FASTMEM_FORCE_LPU + Fast RTC memory force no PD + 8 + 1 + read-write + + + SLOWMEM_FOLW_CPU + 1: RTC memory PD following CPU 0: RTC memory PD following RTC state machine + 9 + 1 + read-write + + + SLOWMEM_FORCE_LPD + RTC memory force PD + 10 + 1 + read-write + + + SLOWMEM_FORCE_LPU + RTC memory force no PD + 11 + 1 + read-write + + + FASTMEM_FORCE_PD + Fast RTC memory force power down + 12 + 1 + read-write + + + FASTMEM_FORCE_PU + Fast RTC memory force power up + 13 + 1 + read-write + + + FASTMEM_PD_EN + enable power down fast RTC memory in sleep + 14 + 1 + read-write + + + SLOWMEM_FORCE_PD + RTC memory force power down + 15 + 1 + read-write + + + SLOWMEM_FORCE_PU + RTC memory force power up + 16 + 1 + read-write + + + SLOWMEM_PD_EN + enable power down RTC memory in sleep + 17 + 1 + read-write + + + FORCE_PD + rtc_peri force power down + 18 + 1 + read-write + + + FORCE_PU + rtc_peri force power up + 19 + 1 + read-write + + + PD_EN + enable power down rtc_peri in sleep + 20 + 1 + read-write + + + + + DIG_PWC + 0x84 + 0x20 + 0x00155550 + + + LSLP_MEM_FORCE_PD + memories in digital core force PD in sleep + 3 + 1 + read-write + + + LSLP_MEM_FORCE_PU + memories in digital core force no PD in sleep + 4 + 1 + read-write + + + ROM0_FORCE_PD + ROM force power down + 5 + 1 + read-write + + + ROM0_FORCE_PU + ROM force power up + 6 + 1 + read-write + + + INTER_RAM0_FORCE_PD + internal SRAM 0 force power down + 7 + 1 + read-write + + + INTER_RAM0_FORCE_PU + internal SRAM 0 force power up + 8 + 1 + read-write + + + INTER_RAM1_FORCE_PD + internal SRAM 1 force power down + 9 + 1 + read-write + + + INTER_RAM1_FORCE_PU + internal SRAM 1 force power up + 10 + 1 + read-write + + + INTER_RAM2_FORCE_PD + internal SRAM 2 force power down + 11 + 1 + read-write + + + INTER_RAM2_FORCE_PU + internal SRAM 2 force power up + 12 + 1 + read-write + + + INTER_RAM3_FORCE_PD + internal SRAM 3 force power down + 13 + 1 + read-write + + + INTER_RAM3_FORCE_PU + internal SRAM 3 force power up + 14 + 1 + read-write + + + INTER_RAM4_FORCE_PD + internal SRAM 4 force power down + 15 + 1 + read-write + + + INTER_RAM4_FORCE_PU + internal SRAM 4 force power up + 16 + 1 + read-write + + + WIFI_FORCE_PD + wifi force power down + 17 + 1 + read-write + + + WIFI_FORCE_PU + wifi force power up + 18 + 1 + read-write + + + DG_WRAP_FORCE_PD + digital core force power down + 19 + 1 + read-write + + + DG_WRAP_FORCE_PU + digital core force power up + 20 + 1 + read-write + + + ROM0_PD_EN + enable power down ROM in sleep + 24 + 1 + read-write + + + INTER_RAM0_PD_EN + enable power down internal SRAM 0 in sleep + 25 + 1 + read-write + + + INTER_RAM1_PD_EN + enable power down internal SRAM 1 in sleep + 26 + 1 + read-write + + + INTER_RAM2_PD_EN + enable power down internal SRAM 2 in sleep + 27 + 1 + read-write + + + INTER_RAM3_PD_EN + enable power down internal SRAM 3 in sleep + 28 + 1 + read-write + + + INTER_RAM4_PD_EN + enable power down internal SRAM 4 in sleep + 29 + 1 + read-write + + + WIFI_PD_EN + enable power down wifi in sleep + 30 + 1 + read-write + + + DG_WRAP_PD_EN + enable power down digital core in sleep + 31 + 1 + read-write + + + + + DIG_ISO + 0x88 + 0x20 + 0xAAAA5000 + + + FORCE_OFF + 7 + 1 + read-write + + + FORCE_ON + 8 + 1 + read-write + + + DG_PAD_AUTOHOLD + read only register to indicate digital pad auto-hold status + 9 + 1 + read-only + + + CLR_DG_PAD_AUTOHOLD + wtite only register to clear digital pad auto-hold + 10 + 1 + write-only + + + DG_PAD_AUTOHOLD_EN + digital pad enable auto-hold + 11 + 1 + read-write + + + DG_PAD_FORCE_NOISO + digital pad force no ISO + 12 + 1 + read-write + + + DG_PAD_FORCE_ISO + digital pad force ISO + 13 + 1 + read-write + + + DG_PAD_FORCE_UNHOLD + digital pad force un-hold + 14 + 1 + read-write + + + DG_PAD_FORCE_HOLD + digital pad force hold + 15 + 1 + read-write + + + ROM0_FORCE_ISO + ROM force ISO + 16 + 1 + read-write + + + ROM0_FORCE_NOISO + ROM force no ISO + 17 + 1 + read-write + + + INTER_RAM0_FORCE_ISO + internal SRAM 0 force ISO + 18 + 1 + read-write + + + INTER_RAM0_FORCE_NOISO + internal SRAM 0 force no ISO + 19 + 1 + read-write + + + INTER_RAM1_FORCE_ISO + internal SRAM 1 force ISO + 20 + 1 + read-write + + + INTER_RAM1_FORCE_NOISO + internal SRAM 1 force no ISO + 21 + 1 + read-write + + + INTER_RAM2_FORCE_ISO + internal SRAM 2 force ISO + 22 + 1 + read-write + + + INTER_RAM2_FORCE_NOISO + internal SRAM 2 force no ISO + 23 + 1 + read-write + + + INTER_RAM3_FORCE_ISO + internal SRAM 3 force ISO + 24 + 1 + read-write + + + INTER_RAM3_FORCE_NOISO + internal SRAM 3 force no ISO + 25 + 1 + read-write + + + INTER_RAM4_FORCE_ISO + internal SRAM 4 force ISO + 26 + 1 + read-write + + + INTER_RAM4_FORCE_NOISO + internal SRAM 4 force no ISO + 27 + 1 + read-write + + + WIFI_FORCE_ISO + wifi force ISO + 28 + 1 + read-write + + + WIFI_FORCE_NOISO + wifi force no ISO + 29 + 1 + read-write + + + DG_WRAP_FORCE_ISO + digital core force ISO + 30 + 1 + read-write + + + DG_WRAP_FORCE_NOISO + digital core force no ISO + 31 + 1 + read-write + + + + + WDTCONFIG0 + 0x8C + 0x20 + 0x00004C80 + + + WDT_PAUSE_IN_SLP + pause WDT in sleep + 7 + 1 + read-write + + + WDT_APPCPU_RESET_EN + enable WDT reset APP CPU + 8 + 1 + read-write + + + WDT_PROCPU_RESET_EN + enable WDT reset PRO CPU + 9 + 1 + read-write + + + WDT_FLASHBOOT_MOD_EN + enable WDT in flash boot + 10 + 1 + read-write + + + WDT_SYS_RESET_LENGTH + system reset counter length + 11 + 3 + read-write + + + WDT_CPU_RESET_LENGTH + CPU reset counter length + 14 + 3 + read-write + + + WDT_LEVEL_INT_EN + N/A + 17 + 1 + read-write + + + WDT_EDGE_INT_EN + N/A + 18 + 1 + read-write + + + WDT_STG3 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 19 + 3 + read-write + + + WDT_STG2 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 22 + 3 + read-write + + + WDT_STG1 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 25 + 3 + read-write + + + WDT_STG0 + 1: interrupt stage en 2: CPU reset stage en 3: system reset stage en 4: RTC reset stage en + 28 + 3 + read-write + + + WDT_EN + enable RTC WDT + 31 + 1 + read-write + + + + + WDTCONFIG1 + 0x90 + 0x20 + 0x0001F400 + + + WDT_STG0_HOLD + 0 + 32 + read-write + + + + + WDTCONFIG2 + 0x94 + 0x20 + 0x00013880 + + + WDT_STG1_HOLD + 0 + 32 + read-write + + + + + WDTCONFIG3 + 0x98 + 0x20 + 0x00000FFF + + + WDT_STG2_HOLD + 0 + 32 + read-write + + + + + WDTCONFIG4 + 0x9C + 0x20 + 0x00000FFF + + + WDT_STG3_HOLD + 0 + 32 + read-write + + + + + WDTFEED + 0xA0 + 0x20 + + + WDT_FEED + 31 + 1 + write-only + + + + + WDTWPROTECT + 0xA4 + 0x20 + 0x50D83AA1 + + + WDT_WKEY + 0 + 32 + read-write + + + + + TEST_MUX + 0xA8 + 0x20 + + + ENT_RTC + ENT_RTC + 29 + 1 + read-write + + + DTEST_RTC + DTEST_RTC + 30 + 2 + read-write + + + + + SW_CPU_STALL + 0xAC + 0x20 + + + SW_STALL_APPCPU_C1 + {reg_sw_stall_appcpu_c1[5:0] reg_sw_stall_appcpu_c0[1:0]} == 0x86 will stall APP CPU + 20 + 6 + read-write + + + SW_STALL_PROCPU_C1 + {reg_sw_stall_procpu_c1[5:0] reg_sw_stall_procpu_c0[1:0]} == 0x86 will stall PRO CPU + 26 + 6 + read-write + + + + + STORE4 + 0xB0 + 0x20 + + + SCRATCH4 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE5 + 0xB4 + 0x20 + + + SCRATCH5 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE6 + 0xB8 + 0x20 + + + SCRATCH6 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + STORE7 + 0xBC + 0x20 + + + SCRATCH7 + 32-bit general purpose retention register + 0 + 32 + read-write + + + + + LOW_POWER_ST + 0xC0 + 0x20 + + + LOW_POWER_DIAG0 + 0 + 32 + read-only + + + RDY_FOR_WAKEUP + 1 if RTC controller is ready to execute WAKE instruction, 0 otherwise + 19 + 1 + read-only + + + + + DIAG1 + 0xC4 + 0x20 + + + LOW_POWER_DIAG1 + 0 + 32 + read-only + + + + + HOLD_FORCE + 0xC8 + 0x20 + + + ADC1_HOLD_FORCE + 0 + 1 + read-write + + + ADC2_HOLD_FORCE + 1 + 1 + read-write + + + PDAC1_HOLD_FORCE + 2 + 1 + read-write + + + PDAC2_HOLD_FORCE + 3 + 1 + read-write + + + SENSE1_HOLD_FORCE + 4 + 1 + read-write + + + SENSE2_HOLD_FORCE + 5 + 1 + read-write + + + SENSE3_HOLD_FORCE + 6 + 1 + read-write + + + SENSE4_HOLD_FORCE + 7 + 1 + read-write + + + TOUCH_PAD0_HOLD_FORCE + 8 + 1 + read-write + + + TOUCH_PAD1_HOLD_FORCE + 9 + 1 + read-write + + + TOUCH_PAD2_HOLD_FORCE + 10 + 1 + read-write + + + TOUCH_PAD3_HOLD_FORCE + 11 + 1 + read-write + + + TOUCH_PAD4_HOLD_FORCE + 12 + 1 + read-write + + + TOUCH_PAD5_HOLD_FORCE + 13 + 1 + read-write + + + TOUCH_PAD6_HOLD_FORCE + 14 + 1 + read-write + + + TOUCH_PAD7_HOLD_FORCE + 15 + 1 + read-write + + + X32P_HOLD_FORCE + 16 + 1 + read-write + + + X32N_HOLD_FORCE + 17 + 1 + read-write + + + + + EXT_WAKEUP1 + 0xCC + 0x20 + + + SEL + Bitmap to select RTC pads for ext wakeup1 + 0 + 18 + read-write + + + STATUS_CLR + clear ext wakeup1 status + 18 + 1 + write-only + + + + + EXT_WAKEUP1_STATUS + 0xD0 + 0x20 + + + EXT_WAKEUP1_STATUS + ext wakeup1 status + 0 + 18 + read-only + + + + + BROWN_OUT + 0xD4 + 0x20 + 0x13FF0000 + + + RTC_MEM_PID_CONF + 0 + 8 + read-write + + + RTC_MEM_CRC_START + 8 + 1 + read-write + + + RTC_MEM_CRC_ADDR + 9 + 11 + read-write + + + CLOSE_FLASH_ENA + enable close flash when brown out happens + 14 + 1 + read-write + + + PD_RF_ENA + enable power down RF when brown out happens + 15 + 1 + read-write + + + RST_WAIT + brown out reset wait cycles + 16 + 10 + read-write + + + RTC_MEM_CRC_LEN + 20 + 11 + read-write + + + RST_ENA + enable brown out reset + 26 + 1 + read-write + + + DBROWN_OUT_THRES + brown out threshold + 27 + 3 + read-write + + + ENA + enable brown out + 30 + 1 + read-write + + + DET + brown out detect + 31 + 1 + read-only + + + RTC_MEM_CRC_FINISH + 31 + 1 + read-write + + + + + DATE + 0x13C + 0x20 + 0x01604280 + + + CNTL_DATE + 0 + 28 + read-write + + + + + + + RTCIO + Peripheral RTCIO + RTC_GPIO + 0x3FF48400 + + 0x0 + 0xCC + registers + + + + OUT + 0x0 + 0x20 + + + DATA + GPIO0~17 output value + 14 + 18 + read-write + + + + + OUT_W1TS + 0x4 + 0x20 + + + OUT_DATA_W1TS + GPIO0~17 output value write 1 to set + 14 + 18 + write-only + + + + + OUT_W1TC + 0x8 + 0x20 + + + OUT_DATA_W1TC + GPIO0~17 output value write 1 to clear + 14 + 18 + write-only + + + + + ENABLE + 0xC + 0x20 + + + ENABLE + GPIO0~17 output enable + 14 + 18 + read-write + + + + + ENABLE_W1TS + 0x10 + 0x20 + + + ENABLE_W1TS + GPIO0~17 output enable write 1 to set + 14 + 18 + write-only + + + + + ENABLE_W1TC + 0x14 + 0x20 + + + ENABLE_W1TC + GPIO0~17 output enable write 1 to clear + 14 + 18 + write-only + + + + + STATUS + 0x18 + 0x20 + + + INT + GPIO0~17 interrupt status + 14 + 18 + read-write + + + + + STATUS_W1TS + 0x1C + 0x20 + + + STATUS_INT_W1TS + GPIO0~17 interrupt status write 1 to set + 14 + 18 + write-only + + + + + STATUS_W1TC + 0x20 + 0x20 + + + STATUS_INT_W1TC + GPIO0~17 interrupt status write 1 to clear + 14 + 18 + write-only + + + + + IN + 0x24 + 0x20 + + + NEXT + GPIO0~17 input value + 14 + 18 + read-only + + + + + 18 + 0x4 + 0-17 + PIN%s + 0x28 + 0x20 + + + PAD_DRIVER + if set to 0: normal output if set to 1: open drain + 2 + 1 + read-write + + + INT_TYPE + if set to 0: GPIO interrupt disable if set to 1: rising edge trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger + 7 + 3 + read-write + + + WAKEUP_ENABLE + GPIO wake up enable only available in light sleep + 10 + 1 + read-write + + + + + RTC_DEBUG_SEL + 0x70 + 0x20 + + + DEBUG_SEL0 + 0 + 5 + read-write + + + DEBUG_SEL1 + 5 + 5 + read-write + + + DEBUG_SEL2 + 10 + 5 + read-write + + + DEBUG_SEL3 + 15 + 5 + read-write + + + DEBUG_SEL4 + 20 + 5 + read-write + + + DEBUG_12M_NO_GATING + 25 + 1 + read-write + + + + + DIG_PAD_HOLD + 0x74 + 0x20 + + + DIG_PAD_HOLD + select the digital pad hold value. + 0 + 32 + read-write + + + + + HALL_SENS + 0x78 + 0x20 + + + HALL_PHASE + Reverse phase of hall sensor + 30 + 1 + read-write + + + XPD_HALL + Power on hall sensor and connect to VP and VN + 31 + 1 + read-write + + + + + SENSOR_PADS + 0x7C + 0x20 + + + SENSE4_FUN_IE + the input enable of the pad + 4 + 1 + read-write + + + SENSE4_SLP_IE + the input enable of the pad in sleep status + 5 + 1 + read-write + + + SENSE4_SLP_SEL + the sleep status selection signal of the pad + 6 + 1 + read-write + + + SENSE4_FUN_SEL + the functional selection signal of the pad + 7 + 2 + read-write + + + SENSE3_FUN_IE + the input enable of the pad + 9 + 1 + read-write + + + SENSE3_SLP_IE + the input enable of the pad in sleep status + 10 + 1 + read-write + + + SENSE3_SLP_SEL + the sleep status selection signal of the pad + 11 + 1 + read-write + + + SENSE3_FUN_SEL + the functional selection signal of the pad + 12 + 2 + read-write + + + SENSE2_FUN_IE + the input enable of the pad + 14 + 1 + read-write + + + SENSE2_SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SENSE2_SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + SENSE2_FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + SENSE1_FUN_IE + the input enable of the pad + 19 + 1 + read-write + + + SENSE1_SLP_IE + the input enable of the pad in sleep status + 20 + 1 + read-write + + + SENSE1_SLP_SEL + the sleep status selection signal of the pad + 21 + 1 + read-write + + + SENSE1_FUN_SEL + the functional selection signal of the pad + 22 + 2 + read-write + + + SENSE4_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 24 + 1 + read-write + + + SENSE3_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 25 + 1 + read-write + + + SENSE2_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 26 + 1 + read-write + + + SENSE1_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 27 + 1 + read-write + + + SENSE4_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 28 + 1 + read-write + + + SENSE3_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + SENSE2_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 30 + 1 + read-write + + + SENSE1_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + ADC_PAD + 0x80 + 0x20 + + + ADC2_FUN_IE + the input enable of the pad + 18 + 1 + read-write + + + ADC2_SLP_IE + the input enable of the pad in sleep status + 19 + 1 + read-write + + + ADC2_SLP_SEL + the sleep status selection signal of the pad + 20 + 1 + read-write + + + ADC2_FUN_SEL + the functional selection signal of the pad + 21 + 2 + read-write + + + ADC1_FUN_IE + the input enable of the pad + 23 + 1 + read-write + + + ADC1_SLP_IE + the input enable of the pad in sleep status + 24 + 1 + read-write + + + ADC1_SLP_SEL + the sleep status selection signal of the pad + 25 + 1 + read-write + + + ADC1_FUN_SEL + the functional selection signal of the pad + 26 + 2 + read-write + + + ADC2_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 28 + 1 + read-write + + + ADC1_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 29 + 1 + read-write + + + ADC2_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 30 + 1 + read-write + + + ADC1_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + PAD_DAC1 + 0x84 + 0x20 + 0x80000000 + + + PDAC1_DAC_XPD_FORCE + Power on DAC1. Usually we need to tristate PDAC1 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 10 + 1 + read-write + + + PDAC1_FUN_IE + the input enable of the pad + 11 + 1 + read-write + + + PDAC1_SLP_OE + the output enable of the pad in sleep status + 12 + 1 + read-write + + + PDAC1_SLP_IE + the input enable of the pad in sleep status + 13 + 1 + read-write + + + PDAC1_SLP_SEL + the sleep status selection signal of the pad + 14 + 1 + read-write + + + PDAC1_FUN_SEL + the functional selection signal of the pad + 15 + 2 + read-write + + + PDAC1_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 17 + 1 + read-write + + + PDAC1_XPD_DAC + Power on DAC1. Usually we need to tristate PDAC1 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 18 + 1 + read-write + + + PDAC1_DAC + PAD DAC1 control code. + 19 + 8 + read-write + + + PDAC1_RUE + the pull up enable of the pad + 27 + 1 + read-write + + + PDAC1_RDE + the pull down enable of the pad + 28 + 1 + read-write + + + PDAC1_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + PDAC1_DRV + the driver strength of the pad + 30 + 2 + read-write + + + + + PAD_DAC2 + 0x88 + 0x20 + 0x80000000 + + + PDAC2_DAC_XPD_FORCE + Power on DAC2. Usually we need to tristate PDAC2 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 10 + 1 + read-write + + + PDAC2_FUN_IE + the input enable of the pad + 11 + 1 + read-write + + + PDAC2_SLP_OE + the output enable of the pad in sleep status + 12 + 1 + read-write + + + PDAC2_SLP_IE + the input enable of the pad in sleep status + 13 + 1 + read-write + + + PDAC2_SLP_SEL + the sleep status selection signal of the pad + 14 + 1 + read-write + + + PDAC2_FUN_SEL + the functional selection signal of the pad + 15 + 2 + read-write + + + PDAC2_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 17 + 1 + read-write + + + PDAC2_XPD_DAC + Power on DAC2. Usually we need to tristate PDAC1 if we power on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0 + 18 + 1 + read-write + + + PDAC2_DAC + PAD DAC2 control code. + 19 + 8 + read-write + + + PDAC2_RUE + the pull up enable of the pad + 27 + 1 + read-write + + + PDAC2_RDE + the pull down enable of the pad + 28 + 1 + read-write + + + PDAC2_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + PDAC2_DRV + the driver strength of the pad + 30 + 2 + read-write + + + + + XTAL_32K_PAD + 0x8C + 0x20 + 0x84100010 + + + DBIAS_XTAL_32K + 32K XTAL self-bias reference control. + 1 + 2 + read-write + + + DRES_XTAL_32K + 32K XTAL resistor bias control. + 3 + 2 + read-write + + + X32P_FUN_IE + the input enable of the pad + 5 + 1 + read-write + + + X32P_SLP_OE + the output enable of the pad in sleep status + 6 + 1 + read-write + + + X32P_SLP_IE + the input enable of the pad in sleep status + 7 + 1 + read-write + + + X32P_SLP_SEL + the sleep status selection signal of the pad + 8 + 1 + read-write + + + X32P_FUN_SEL + the functional selection signal of the pad + 9 + 2 + read-write + + + X32N_FUN_IE + the input enable of the pad + 11 + 1 + read-write + + + X32N_SLP_OE + the output enable of the pad in sleep status + 12 + 1 + read-write + + + X32N_SLP_IE + the input enable of the pad in sleep status + 13 + 1 + read-write + + + X32N_SLP_SEL + the sleep status selection signal of the pad + 14 + 1 + read-write + + + X32N_FUN_SEL + the functional selection signal of the pad + 15 + 2 + read-write + + + X32P_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 17 + 1 + read-write + + + X32N_MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 18 + 1 + read-write + + + XPD_XTAL_32K + Power up 32kHz crystal oscillator + 19 + 1 + read-write + + + DAC_XTAL_32K + 32K XTAL bias current DAC. + 20 + 2 + read-write + + + X32P_RUE + the pull up enable of the pad + 22 + 1 + read-write + + + X32P_RDE + the pull down enable of the pad + 23 + 1 + read-write + + + X32P_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 24 + 1 + read-write + + + X32P_DRV + the driver strength of the pad + 25 + 2 + read-write + + + X32N_RUE + the pull up enable of the pad + 27 + 1 + read-write + + + X32N_RDE + the pull down enable of the pad + 28 + 1 + read-write + + + X32N_HOLD + hold the current value of the output when setting the hold to Ò1Ó + 29 + 1 + read-write + + + X32N_DRV + the driver strength of the pad + 30 + 2 + read-write + + + + + TOUCH_CFG + 0x90 + 0x20 + 0x66000000 + + + TOUCH_DCUR + touch sensor bias current. Should have option to tie with BIAS_SLEEP(When BIAS_SLEEP this setting is available + 23 + 2 + read-write + + + TOUCH_DRANGE + touch sensor saw wave voltage range. + 25 + 2 + read-write + + + TOUCH_DREFL + touch sensor saw wave bottom voltage. + 27 + 2 + read-write + + + TOUCH_DREFH + touch sensor saw wave top voltage. + 29 + 2 + read-write + + + TOUCH_XPD_BIAS + touch sensor bias power on. + 31 + 1 + read-write + + + + + TOUCH_PAD0 + 0x94 + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale GPIO4 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD1 + 0x98 + 0x20 + 0x4A000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO0 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + 31 + 1 + read-write + + + + + TOUCH_PAD2 + 0x9C + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO2 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD3 + 0xA0 + 0x20 + 0x4A000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDO + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD4 + 0xA4 + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTCK + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD5 + 0xA8 + 0x20 + 0x52000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDI + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD6 + 0xAC + 0x20 + 0x4A000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.MTMS + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD7 + 0xB0 + 0x20 + 0x42000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO27 + 12 + 1 + read-write + + + FUN_IE + the input enable of the pad + 13 + 1 + read-write + + + SLP_OE + the output enable of the pad in sleep status + 14 + 1 + read-write + + + SLP_IE + the input enable of the pad in sleep status + 15 + 1 + read-write + + + SLP_SEL + the sleep status selection signal of the pad + 16 + 1 + read-write + + + FUN_SEL + the functional selection signal of the pad + 17 + 2 + read-write + + + MUX_SEL + Ò1Ó select the digital function Ó0Óslection the rtc function + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + RUE + the pull up enable of the pad + 27 + 1 + read-write + + + RDE + the pull down enable of the pad + 28 + 1 + read-write + + + DRV + the driver strength of the pad + 29 + 2 + read-write + + + HOLD + hold the current value of the output when setting the hold to Ò1Ó + 31 + 1 + read-write + + + + + TOUCH_PAD8 + 0xB4 + 0x20 + 0x02000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + + + TOUCH_PAD9 + 0xB8 + 0x20 + 0x02000000 + + + TO_GPIO + connect the rtc pad input to digital pad input Ó0Ó is availbale + 19 + 1 + read-write + + + XPD + touch sensor power on. + 20 + 1 + read-write + + + TIE_OPT + default touch sensor tie option. 0: tie low 1: tie high. + 21 + 1 + read-write + + + START + start touch sensor. + 22 + 1 + read-write + + + DAC + touch sensor slope control. 3-bit for each touch panel default 100. + 23 + 3 + read-write + + + + + EXT_WAKEUP0 + 0xBC + 0x20 + + + SEL + select the wakeup source Ó0Ó select GPIO0 Ó1Ó select GPIO2 ...Ò17Ó select GPIO17 + 27 + 5 + read-write + + + + + XTL_EXT_CTR + 0xC0 + 0x20 + + + SEL + select the external xtl power source Ó0Ó select GPIO0 Ó1Ó select GPIO2 ...Ò17Ó select GPIO17 + 27 + 5 + read-write + + + + + SAR_I2C_IO + 0xC4 + 0x20 + + + SAR_DEBUG_BIT_SEL + 23 + 5 + read-write + + + SAR_I2C_SCL_SEL + Ò0Ó using TOUCH_PAD[0] as i2c clk Ò1Ó using TOUCH_PAD[2] as i2c clk + 28 + 2 + read-write + + + SAR_I2C_SDA_SEL + Ò0Ó using TOUCH_PAD[1] as i2c sda Ò1Ó using TOUCH_PAD[3] as i2c sda + 30 + 2 + read-write + + + + + DATE + 0xC8 + 0x20 + 0x01603160 + + + IO_DATE + date + 0 + 28 + read-write + + + + + + + RTC_I2C + Peripheral RTC_I2C + RTC_I2C + 0x3FF48C00 + + 0x0 + 0x3C + registers + + + + SCL_LOW_PERIOD + 0x0 + 0x20 + + + SCL_LOW_PERIOD + number of cycles that scl == 0 + 0 + 25 + read-write + + + + + CTRL + 0x4 + 0x20 + + + SDA_FORCE_OUT + SDA is push-pull (1) or open-drain (0) + 0 + 1 + read-write + + + SCL_FORCE_OUT + SCL is push-pull (1) or open-drain (0) + 1 + 1 + read-write + + + MS_MODE + Master (1) or slave (0) + 4 + 1 + read-write + + + TRANS_START + Force to generate start condition + 5 + 1 + read-write + + + TX_LSB_FIRST + Send LSB first + 6 + 1 + read-write + + + RX_LSB_FIRST + Receive LSB first + 7 + 1 + read-write + + + + + DEBUG_STATUS + 0x8 + 0x20 + + + ACK_VAL + The value of an acknowledge signal on the bus + 0 + 1 + read-write + + + SLAVE_RW + When working as a slave, the value of R/W bit received + 1 + 1 + read-write + + + TIMED_OUT + Transfer has timed out + 2 + 1 + read-write + + + ARB_LOST + When working as a master, lost control of I2C bus + 3 + 1 + read-write + + + BUS_BUSY + operation is in progress + 4 + 1 + read-write + + + SLAVE_ADDR_MATCH + When working as a slave, whether address was matched + 5 + 1 + read-write + + + BYTE_TRANS + 8 bit transmit done + 6 + 1 + read-write + + + MAIN_STATE + state of the main state machine + 25 + 3 + read-write + + + SCL_STATE + state of SCL state machine + 28 + 3 + read-write + + + + + TIMEOUT + 0xC + 0x20 + + + TIMEOUT + Maximum number of FAST_CLK cycles that the transmission can take + 0 + 20 + read-write + + + + + SLAVE_ADDR + 0x10 + 0x20 + + + SLAVE_ADDR + local slave address + 0 + 15 + read-write + + + _10BIT + Set if local slave address is 10-bit + 31 + 1 + read-write + + + + + DATA + 0x1C + 0x20 + + + INT_RAW + 0x20 + 0x20 + + + SLAVE_TRANS_COMPLETE_INT_RAW + Slave accepted 1 byte and address matched + 3 + 1 + read-write + + + ARBITRATION_LOST_INT_RAW + Master lost arbitration + 4 + 1 + read-write + + + MASTER_TRANS_COMPLETE_INT_RAW + 5 + 1 + read-write + + + TRANS_COMPLETE_INT_RAW + Stop condition has been detected interrupt raw status + 6 + 1 + read-write + + + TIME_OUT_INT_RAW + time out interrupt raw status + 7 + 1 + read-only + + + + + INT_CLR + 0x24 + 0x20 + + + SLAVE_TRANS_COMPLETE_INT_CLR + 4 + 1 + read-write + + + ARBITRATION_LOST_INT_CLR + 5 + 1 + read-write + + + MASTER_TRANS_COMPLETE_INT_CLR + 6 + 1 + read-write + + + TRANS_COMPLETE_INT_CLR + 7 + 1 + read-write + + + TIME_OUT_INT_CLR + 8 + 1 + write-only + + + + + INT_EN + 0x28 + 0x20 + + + INT_ST + 0x2C + 0x20 + + + SDA_DUTY + 0x30 + 0x20 + + + SDA_DUTY + Number of FAST_CLK cycles SDA will switch after falling edge of SCL + 0 + 20 + read-write + + + + + SCL_HIGH_PERIOD + 0x38 + 0x20 + + + SCL_HIGH_PERIOD + Number of FAST_CLK cycles for SCL to be high + 0 + 20 + read-write + + + + + SCL_START_PERIOD + 0x40 + 0x20 + + + SCL_START_PERIOD + Number of FAST_CLK cycles to wait before generating start condition + 0 + 20 + read-write + + + + + SCL_STOP_PERIOD + 0x44 + 0x20 + + + SCL_STOP_PERIOD + Number of FAST_CLK cycles to wait before generating stop condition + 0 + 20 + read-write + + + + + CMD + 0x48 + 0x20 + + + VAL + Command content + 0 + 14 + read-write + + + DONE + Bit is set by HW when command is done + 31 + 1 + read-write + + + + + + + SDMMC + SD/MMC Host Controller + SDHOST + 0x3FF68000 + + 0x0 + 0xA4 + registers + + + + CTRL + Control register + 0x0 + 0x20 + + + CONTROLLER_RESET + To reset controller, firmware should set this bit. This bit is auto-cleared after two AHB and two sdhost_cclk_in clock cycles. + 0 + 1 + read-write + + + FIFO_RESET + To reset FIFO, firmware should set bit to 1. This bit is auto-cleared after completion of reset operation. +Note: FIFO pointers will be out of reset after 2 cycles of system clocks in addition to synchronization delay (2 cycles of card clock), after the fifo_reset is cleared. + 1 + 1 + read-write + + + DMA_RESET + To reset DMA interface, firmware should set bit to 1. This bit is auto-cleared after two AHB clocks. + 2 + 1 + read-write + + + INT_ENABLE + Global interrupt enable/disable bit. 0: Disable; 1: Enable. + 4 + 1 + read-write + + + READ_WAIT + For sending read-wait to SDIO cards. + 6 + 1 + read-write + + + SEND_IRQ_RESPONSE + Bit automatically clears once response is sent. To wait for MMC card interrupts, host issues CMD40 and waits for interrupt response from MMC card(s). In the meantime, if host wants SD/MMC to exit waiting for interrupt state, it can set this bit, at which time SD/MMC command state-machine sends CMD40 response on bus and returns to idle state. + 7 + 1 + read-write + + + ABORT_READ_DATA + After a suspend-command is issued during a read-operation, software polls the card to find when the suspend-event occurred. Once the suspend-event has occurred, software sets the bit which will reset the data state machine that is waiting for the next block of data. This bit is automatically cleared once the data state machine is reset to idle. + 8 + 1 + read-write + + + SEND_CCSD + When set, SD/MMC sends CCSD to the CE-ATA device. Software sets this bit only if the current command is expecting CCS (that is, RW_BLK), and if interrupts are enabled for the CE-ATA device. Once the CCSD pattern is sent to the device, SD/MMC automatically clears the SDHOST_SEND_CCSD bit. It also sets the Command Done (CD) bit in the SDHOST_RINTSTS_REG register, and generates an interrupt for the host, in case the Command Done interrupt is not masked. +NOTE: Once the SDHOST_SEND_CCSD bit is set, it takes two card clock cycles to drive the CCSD on the CMD line. Due to this, within the boundary conditions the CCSD may be sent to the CE-ATA device, even if the device has signalled CCS. + 9 + 1 + read-write + + + SEND_AUTO_STOP_CCSD + Always Set SDHOST_SEND_AUTO_STOP_CCSD and SDHOST_SEND_CCSD bits together; SDHOST_SEND_AUTO_STOP_CCSD should not be set independently of send_ccsd. When set, SD/MMC automatically sends an internally-generated STOP command (CMD12) to the CE-ATA device. After sending this internally-generated STOP command, the Auto Command Done (ACD) bit in SDHOST_RINTSTS_REG is set and an interrupt is generated for the host, in case the ACD interrupt is not masked. After sending the Command Completion Signal Disable (CCSD), SD/MMC automatically clears the SDHOST_SEND_AUTO_STOP_CCSD bit. + 10 + 1 + read-write + + + CEATA_DEVICE_INTERRUPT_STATUS + Software should appropriately write to this bit after the power-on reset or any other reset to the CE-ATA device. After reset, the CE-ATA device's interrupt is usually disabled (nIEN = 1). If the host enables the CE-ATA device's interrupt, then software should set this bit. + 11 + 1 + read-write + + + + + CLKDIV + Clock divider configuration register + 0x8 + 0x20 + + + CLK_DIVIDER0 + Clock divider0 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 0 + 8 + read-write + + + CLK_DIVIDER1 + Clock divider1 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 8 + 8 + read-write + + + CLK_DIVIDER2 + Clock divider2 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 16 + 8 + read-write + + + CLK_DIVIDER3 + Clock divider3 value. Clock divisor is 2*n, where n = 0 bypasses the divider (divisor of 1). For example, a value of 1 means divided by 2*1 = 2, a value of 0xFF means divided by 2*255 = 510, and so on. + 24 + 8 + read-write + + + + + CLKSRC + Clock source selection register + 0xC + 0x20 + + + CLKSRC + Clock divider source for two SD cards is supported. Each card has two bits assigned to it. For example, bit[1:0] are assigned for card 0, bit[3:2] are assigned for card 1. Card 0 maps and internally routes clock divider[0:3] outputs to cclk_out[1:0] pins, depending on bit value. +00 : Clock divider 0; +01 : Clock divider 1; +10 : Clock divider 2; +11 : Clock divider 3. + 0 + 4 + read-write + + + + + CLKENA + Clock enable register + 0x10 + 0x20 + + + CCLK_ENABLE + Clock-enable control for two SD card clocks and one MMC card clock is supported. One bit per card. +0: Clock disabled; +1: Clock enabled. + 0 + 2 + read-write + + + LP_ENABLE + Disable clock when the card is in IDLE state. One bit per card. +0: clock disabled; +1: clock enabled. + 16 + 2 + read-write + + + + + TMOUT + Data and response timeout configuration register + 0x14 + 0x20 + 0xFFFFFF40 + + + RESPONSE_TIMEOUT + Response timeout value. Value is specified in terms of number of card output clocks, i.e., sdhost_cclk_out. + 0 + 8 + read-write + + + DATA_TIMEOUT + Value for card data read timeout. This value is also used for data starvation by host timeout. The timeout counter is started only after the card clock is stopped. This value is specified in number of card output clocks, i.e. sdhost_cclk_out of the selected card. +NOTE: The software timer should be used if the timeout value is in the order of 100 ms. In this case, read data timeout interrupt needs to be disabled. + 8 + 24 + read-write + + + + + CTYPE + Card bus width configuration register + 0x18 + 0x20 + + + CARD_WIDTH4 + One bit per card indicates if card is 1-bit or 4-bit mode. +0: 1-bit mode; +1: 4-bit mode. +Bit[1:0] correspond to card[1:0] respectively. + 0 + 2 + read-write + + + CARD_WIDTH8 + One bit per card indicates if card is in 8-bit mode. +0: Non 8-bit mode; +1: 8-bit mode. +Bit[17:16] correspond to card[1:0] respectively. + 16 + 2 + read-write + + + + + BLKSIZ + Card data block size configuration register + 0x1C + 0x20 + 0x00000200 + + + BLOCK_SIZE + Block size. + 0 + 16 + read-write + + + + + BYTCNT + Data transfer length configuration register + 0x20 + 0x20 + 0x00000200 + + + BYTE_COUNT + Number of bytes to be transferred, should be an integral multiple of Block Size for block transfers. For data transfers of undefined byte lengths, byte count should be set to 0. When byte count is set to 0, it is the responsibility of host to explicitly send stop/abort command to terminate data transfer. + 0 + 32 + read-write + + + + + INTMASK + SDIO interrupt mask register + 0x24 + 0x20 + + + INT_MASK + These bits used to mask unwanted interrupts. A value of 0 masks interrupt, and a value of 1 enables the interrupt. +Bit 15 (EBE): End-bit error/no CRC error; +Bit 14 (ACD): Auto command done; +Bit 13 (SBE/BCI): Rx Start Bit Error; +Bit 12 (HLE): Hardware locked write error; +Bit 11 (FRUN): FIFO underrun/overrun error; +Bit 10 (HTO): Data starvation-by-host timeout; +Bit 9 (DRTO): Data read timeout; +Bit 8 (RTO): Response timeout; +Bit 7 (DCRC): Data CRC error; +Bit 6 (RCRC): Response CRC error; +Bit 5 (RXDR): Receive FIFO data request; +Bit 4 (TXDR): Transmit FIFO data request; +Bit 3 (DTO): Data transfer over; +Bit 2 (CD): Command done; +Bit 1 (RE): Response error; +Bit 0 (CD): Card detect. + 0 + 16 + read-write + + + SDIO_INT_MASK + SDIO interrupt mask, one bit for each card. Bit[17:16] correspond to card[15:0] respectively. When masked, SDIO interrupt detection for that card is disabled. 0 masks an interrupt, and 1 enables an interrupt. + 16 + 2 + read-write + + + + + CMDARG + Command argument data register + 0x28 + 0x20 + + + CMDARG + Value indicates command argument to be passed to the card. + 0 + 32 + read-write + + + + + CMD + Command and boot configuration register + 0x2C + 0x20 + 0x20000000 + + + INDEX + Command index. + 0 + 6 + read-write + + + RESPONSE_EXPECT + 0: No response expected from card; 1: Response expected from card. + 6 + 1 + read-write + + + RESPONSE_LENGTH + 0: Short response expected from card; 1: Long response expected from card. + 7 + 1 + read-write + + + CHECK_RESPONSE_CRC + 0: Do not check; 1: Check response CRC. +Some of command responses do not return valid CRC bits. Software should disable CRC checks for those commands in order to disable CRC checking by controller. + 8 + 1 + read-write + + + DATA_EXPECTED + 0: No data transfer expected; 1: Data transfer expected. + 9 + 1 + read-write + + + READ_WRITE + 0: Read from card; 1: Write to card. +Don't care if no data is expected from card. + 10 + 1 + read-write + + + TRANSFER_MODE + Block data transfer command; 1: Stream data transfer command. +Don't care if no data expected. + 11 + 1 + read-write + + + SEND_AUTO_STOP + 0: No stop command is sent at the end of data transfer; 1: Send stop command at the end of data transfer. + 12 + 1 + read-write + + + WAIT_PRVDATA_COMPLETE + 0: Send command at once, even if previous data transfer has not completed; 1: Wait for previous data transfer to complete before sending Command. +The SDHOST_WAIT_PRVDATA_COMPLETE] = 0 option is typically used to query status of card during data transfer or to stop current data transfer. SDHOST_CARD_NUMBERr should be same as in previous command. + 13 + 1 + read-write + + + STOP_ABORT_CMD + 0: Neither stop nor abort command can stop current data transfer. If abort is sent to function-number currently selected or not in data-transfer mode, then bit should be set to 0; 1: Stop or abort command intended to stop current data transfer in progress. +When open-ended or predefined data transfer is in progress, and host issues stop or abort command to stop data transfer, bit should be set so that command/data state-machines of CIU can return correctly to idle state. + 14 + 1 + read-write + + + SEND_INITIALIZATION + 0: Do not send initialization sequence (80 clocks of 1) before sending this command; 1: Send initialization sequence before sending this command. +After powered on, 80 clocks must be sent to card for initialization before sending any commands to card. Bit should be set while sending first command to card so that controller will initialize clocks before sending command to card. + 15 + 1 + read-write + + + CARD_NUMBER + Card number in use. Represents physical slot number of card being accessed. In SD-only mode, up to two cards are supported. + 16 + 5 + read-write + + + UPDATE_CLOCK_REGISTERS_ONLY + 0: Normal command sequence; 1: Do not send commands, just update clock register value into card clock domain. +Following register values are transferred into card clock domain: CLKDIV, CLRSRC, and CLKENA. +Changes card clocks (change frequency, truncate off or on, and set low-frequency mode). This is provided in order to change clock frequency or stop clock without having to send command to cards. During normal command sequence, when sdhost_update_clock_registers_only = 0, following control registers are transferred from BIU to CIU: CMD, CMDARG, TMOUT, CTYPE, BLKSIZ, and BYTCNT. CIU uses new register values for new command sequence to card(s). When bit is set, there are no Command Done interrupts because no command is sent to SD_MMC_CEATA cards. + 21 + 1 + read-write + + + READ_CEATA_DEVICE + Read access flag. +0: Host is not performing read access (RW_REG or RW_BLK)towards CE-ATA device; +1: Host is performing read access (RW_REG or RW_BLK) towards CE-ATA device. +Software should set this bit to indicate that CE-ATA device is being accessed for read transfer. This bit is used to disable read data timeout indication while performing CE-ATA read transfers. Maximum value of I/O transmission delay can be no less than 10 seconds. SD/MMC should not indicate read data timeout while waiting for data from CE-ATA device. + 22 + 1 + read-write + + + CCS_EXPECTED + Expected Command Completion Signal (CCS) configuration. +0: Interrupts are not enabled in CE-ATA device (nIEN = 1 in ATA control register), or command does not expect CCS from device; +1: Interrupts are enabled in CE-ATA device (nIEN = 0), and RW_BLK command expects command completion signal from CE-ATA device. +If the command expects Command Completion Signal (CCS) from the CE-ATA device, the software should set this control bit. SD/MMC sets Data Transfer Over (DTO) bit in RINTSTS register and generates interrupt to host if Data Transfer Over interrupt is not masked. + 23 + 1 + read-write + + + USE_HOLE + Use Hold Register. +0: CMD and DATA sent to card bypassing HOLD Register; +1: CMD and DATA sent to card through the HOLD Register. + 29 + 1 + read-write + + + START_CMD + Start command. Once command is served by the CIU, this bit is automatically cleared. When this bit is set, host should not attempt to write to any command registers. If a write is attempted, hardware lock error is set in raw interrupt register. Once command is sent and a response is received from SD_MMC_CEATA cards, Command Done bit is set in the raw interrupt Register. + 31 + 1 + read-write + + + + + RESP0 + Response data register + 0x30 + 0x20 + + + RESPONSE0 + Bit[31:0] of response. + 0 + 32 + read-only + + + + + RESP1 + Long response data register + 0x34 + 0x20 + + + RESPONSE1 + Bit[63:32] of long response. + 0 + 32 + read-only + + + + + RESP2 + Long response data register + 0x38 + 0x20 + + + RESPONSE2 + Bit[95:64] of long response. + 0 + 32 + read-only + + + + + RESP3 + Long response data register + 0x3C + 0x20 + + + RESPONSE3 + Bit[127:96] of long response. + 0 + 32 + read-only + + + + + MINTSTS + Masked interrupt status register + 0x40 + 0x20 + + + INT_STATUS_MSK + Interrupt enabled only if corresponding bit in interrupt mask register is set. +Bit 15 (EBE): End-bit error/no CRC error; +Bit 14 (ACD): Auto command done; +Bit 13 (SBE/BCI): RX Start Bit Error; +Bit 12 (HLE): Hardware locked write error; +Bit 11 (FRUN): FIFO underrun/overrun error; +Bit 10 (HTO): Data starvation by host timeout (HTO); +Bit 9 (DTRO): Data read timeout; +Bit 8 (RTO): Response timeout; +Bit 7 (DCRC): Data CRC error; +Bit 6 (RCRC): Response CRC error; +Bit 5 (RXDR): Receive FIFO data request; +Bit 4 (TXDR): Transmit FIFO data request; +Bit 3 (DTO): Data transfer over; +Bit 2 (CD): Command done; +Bit 1 (RE): Response error; +Bit 0 (CD): Card detect. + 0 + 16 + read-only + + + SDIO_INTERRUPT_MSK + Interrupt from SDIO card, one bit for each card. Bit[17:16] correspond to card1 and card0, respectively. SDIO interrupt for card is enabled only if corresponding sdhost_sdio_int_mask bit is set in Interrupt mask register (Setting mask bit enables interrupt). + 16 + 2 + read-only + + + + + RINTSTS + Raw interrupt status register + 0x44 + 0x20 + + + INT_STATUS_RAW + Setting a bit clears the corresponding interrupt and writing 0 has no effect. Bits are logged regardless of interrupt mask status. +Bit 15 (EBE): End-bit error/no CRC error; +Bit 14 (ACD): Auto command done; +Bit 13 (SBE/BCI): RX Start Bit Error; +Bit 12 (HLE): Hardware locked write error; +Bit 11 (FRUN): FIFO underrun/overrun error; +Bit 10 (HTO): Data starvation by host timeout (HTO); +Bit 9 (DTRO): Data read timeout; +Bit 8 (RTO): Response timeout; +Bit 7 (DCRC): Data CRC error; +Bit 6 (RCRC): Response CRC error; +Bit 5 (RXDR): Receive FIFO data request; +Bit 4 (TXDR): Transmit FIFO data request; +Bit 3 (DTO): Data transfer over; +Bit 2 (CD): Command done; +Bit 1 (RE): Response error; +Bit 0 (CD): Card detect. + 0 + 16 + read-write + + + SDIO_INTERRUPT_RAW + Interrupt from SDIO card, one bit for each card. Bit[17:16] correspond to card1 and card0, respectively. Setting a bit clears the corresponding interrupt bit and writing 0 has no effect. +0: No SDIO interrupt from card; +1: SDIO interrupt from card. + 16 + 2 + read-write + + + + + STATUS + SD/MMC status register + 0x48 + 0x20 + 0x00000716 + + + FIFO_RX_WATERMARK + FIFO reached Receive watermark level, not qualified with data transfer. + 0 + 1 + read-only + + + FIFO_TX_WATERMARK + FIFO reached Transmit watermark level, not qualified with data transfer. + 1 + 1 + read-only + + + FIFO_EMPTY + FIFO is empty status. + 2 + 1 + read-only + + + FIFO_FULL + FIFO is full status. + 3 + 1 + read-only + + + COMMAND_FSM_STATES + Command FSM states. +0: Idle; +1: Send init sequence; +2: Send cmd start bit; +3: Send cmd tx bit; +4: Send cmd index + arg; +5: Send cmd crc7; +6: Send cmd end bit; +7: Receive resp start bit; +8: Receive resp IRQ response; +9: Receive resp tx bit; +10: Receive resp cmd idx; +11: Receive resp data; +12: Receive resp crc7; +13: Receive resp end bit; +14: Cmd path wait NCC; +15: Wait, cmd-to-response turnaround. + 4 + 4 + read-only + + + DATA_3_STATUS + Raw selected sdhost_card_data[3], checks whether card is present. +0: card not present; +1: card present. + 8 + 1 + read-only + + + DATA_BUSY + Inverted version of raw selected sdhost_card_data[0]. +0: Card data not busy; +1: Card data busy. + 9 + 1 + read-only + + + DATA_STATE_MC_BUSY + Data transmit or receive state-machine is busy. + 10 + 1 + read-only + + + RESPONSE_INDEX + Index of previous response, including any auto-stop sent by core. + 11 + 6 + read-only + + + FIFO_COUNT + FIFO count, number of filled locations in FIFO. + 17 + 13 + read-only + + + + + FIFOTH + FIFO configuration register + 0x4C + 0x20 + + + TX_WMARK + FIFO threshold watermark level when transmitting data to card. When FIFO data count is less than or equal to this number, DMA/FIFO request is raised. If Interrupt is enabled, then interrupt occurs. During end of packet, request or interrupt is generated, regardless of threshold programming.In non-DMA mode, when transmit FIFO threshold (TXDR) interrupt is enabled, then interrupt is generated instead of DMA request. During end of packet, on last interrupt, host is responsible for filling FIFO with only required remaining bytes (not before FIFO is full or after CIU completes data transfers, because FIFO may not be empty). In DMA mode, at end of packet, if last transfer is less than burst size, DMA controller does single cycles until required bytes are transferred. + 0 + 12 + read-write + + + RX_WMARK + FIFO threshold watermark level when receiving data to card.When FIFO data count reaches greater than this number , DMA/FIFO request is raised. During end of packet, request is generated regardless of threshold programming in order to complete any remaining data.In non-DMA mode, when receiver FIFO threshold (RXDR) interrupt is enabled, then interrupt is generated instead of DMA request.During end of packet, interrupt is not generated if threshold programming is larger than any remaining data. It is responsibility of host to read remaining bytes on seeing Data Transfer Done interrupt.In DMA mode, at end of packet, even if remaining bytes are less than threshold, DMA request does single transfers to flush out any remaining bytes before Data Transfer Done interrupt is set. + 16 + 11 + read-write + + + DMA_MULTIPLE_TRANSACTION_SIZE + Burst size of multiple transaction, should be programmed same as DMA controller multiple-transaction-size SDHOST_SRC/DEST_MSIZE. +000: 1-byte transfer; +001: 4-byte transfer; +010: 8-byte transfer; +011: 16-byte transfer; +100: 32-byte transfer; +101: 64-byte transfer; +110: 128-byte transfer; +111: 256-byte transfer. + 28 + 3 + read-write + + + + + CDETECT + Card detect register + 0x50 + 0x20 + + + CARD_DETECT_N + Value on sdhost_card_detect_n input ports (1 bit per card), read-only bits. 0 represents presence of card. Only NUM_CARDS number of bits are implemented. + 0 + 2 + read-only + + + + + WRTPRT + Card write protection (WP) status register + 0x54 + 0x20 + + + WRITE_PROTECT + Value on sdhost_card_write_prt input ports (1 bit per card). 1 represents write protection. Only NUM_CARDS number of bits are implemented. + 0 + 2 + read-only + + + + + TCBCNT + Transferred byte count register + 0x5C + 0x20 + + + TCBCNT + Number of bytes transferred by CIU unit to card. + 0 + 32 + read-only + + + + + TBBCNT + Transferred byte count register + 0x60 + 0x20 + + + TBBCNT + Number of bytes transferred between Host/DMA memory and BIU FIFO. + 0 + 32 + read-only + + + + + DEBNCE + Debounce filter time configuration register + 0x64 + 0x20 + + + DEBOUNCE_COUNT + Number of host clocks (clk) used by debounce filter logic. The typical debounce time is 5 \verb+~+ 25 ms to prevent the card instability when the card is inserted or removed. + 0 + 24 + read-write + + + + + USRID + User ID (scratchpad) register + 0x68 + 0x20 + + + USRID + User identification register, value set by user. Can also be used as a scratchpad register by user. + 0 + 32 + read-write + + + + + VERID + Version ID (scratchpad) register + 0x6C + 0x20 + 0x5432270A + + + VERSIONID + Hardware version register. Can also be read by fireware. + 0 + 32 + read-only + + + + + HCON + Hardware feature register + 0x70 + 0x20 + 0x03444CC3 + + + CARD_TYPE + Hardware support SDIO and MMC. + 0 + 1 + read-only + + + CARD_NUM + Support card number is 2. + 1 + 5 + read-only + + + BUS_TYPE + Register config is APB bus. + 6 + 1 + read-only + + + DATA_WIDTH + Regisger data widht is 32. + 7 + 3 + read-only + + + ADDR_WIDTH + Register address width is 32. + 10 + 6 + read-only + + + DMA_WIDTH + DMA data witdth is 32. + 18 + 3 + read-only + + + RAM_INDISE + Inside RAM in SDMMC module. + 21 + 1 + read-only + + + HOLD + Have a hold regiser in data path . + 22 + 1 + read-only + + + NUM_CLK_DIV + Have 4 clk divider in design . + 24 + 2 + read-only + + + + + UHS + UHS-1 register + 0x74 + 0x20 + + + DDR + DDR mode selecton,1 bit for each card. +0-Non-DDR mdoe. +1-DDR mdoe. + 16 + 2 + read-write + + + + + RST_N + Card reset register + 0x78 + 0x20 + 0x00000001 + + + CARD_RESET + Hardware reset. +1: Active mode; +0: Reset. +These bits cause the cards to enter pre-idle state, which requires them to be re-initialized. SDHOST_RST_CARD_RESET[0] should be set to 1'b0 to reset card0, SDHOST_RST_CARD_RESET[1] should be set to 1'b0 to reset card1. + 0 + 2 + read-write + + + + + BMOD + Burst mode transfer configuration register + 0x80 + 0x20 + + + SWR + Software Reset. When set, the DMA Controller resets all its internal registers. It is automatically cleared after one clock cycle. + 0 + 1 + read-write + + + FB + Fixed Burst. Controls whether the AHB Master interface performs fixed burst transfers or not. When set, the AHB will use only SINGLE, INCR4, INCR8 or INCR16 during start of normal burst transfers. When reset, the AHB will use SINGLE and INCR burst transfer operations. + 1 + 1 + read-write + + + DE + IDMAC Enable. When set, the IDMAC is enabled. + 7 + 1 + read-write + + + PBL + Programmable Burst Length. These bits indicate the maximum number of beats to be performed in one IDMAC???Internal DMA Control???transaction. The IDMAC will always attempt to burst as specified in PBL each time it starts a burst transfer on the host bus. The permissible values are 1, 4, 8, 16, 32, 64, 128 and 256. This value is the mirror of MSIZE of FIFOTH register. In order to change this value, write the required value to FIFOTH register. This is an encode value as follows: +000: 1-byte transfer; +001: 4-byte transfer; +010: 8-byte transfer; +011: 16-byte transfer; +100: 32-byte transfer; +101: 64-byte transfer; +110: 128-byte transfer; +111: 256-byte transfer. +PBL is a read-only value and is applicable only for data access, it does not apply to descriptor access. + 8 + 3 + read-write + + + + + PLDMND + Poll demand configuration register + 0x84 + 0x20 + + + PD + Poll Demand. If the OWNER bit of a descriptor is not set, the FSM goes to the Suspend state. The host needs to write any value into this register for the IDMAC FSM to resume normal descriptor fetch operation. This is a write only . + 0 + 32 + write-only + + + + + DBADDR + Descriptor base address register + 0x88 + 0x20 + + + DBADDR + Start of Descriptor List. Contains the base address of the First Descriptor. The LSB bits [1:0] are ignored and taken as all-zero by the IDMAC internally. Hence these LSB bits may be treated as read-only. + 0 + 32 + read-write + + + + + IDSTS + IDMAC status register + 0x8C + 0x20 + + + TI + Transmit Interrupt. Indicates that data transmission is finished for a descriptor. Writing 1 clears this bit. + 0 + 1 + read-write + + + RI + Receive Interrupt. Indicates the completion of data reception for a descriptor. Writing 1 clears this bit. + 1 + 1 + read-write + + + FBE + Fatal Bus Error Interrupt. Indicates that a Bus Error occurred (IDSTS[12:10]) . When this bit is set, the DMA disables all its bus accesses. Writing 1 clears this bit. + 2 + 1 + read-write + + + DU + Descriptor Unavailable Interrupt. This bit is set when the descriptor is unavailable due to OWNER bit = 0 (DES0[31] = 0). Writing 1 clears this bit. + 4 + 1 + read-write + + + CES + Card Error Summary. Indicates the status of the transaction to/from the card, also present in RINTSTS. Indicates the logical OR of the following bits: +EBE : End Bit Error; +RTO : Response Timeout/Boot Ack Timeout; +RCRC : Response CRC; +SBE : Start Bit Error; +DRTO : Data Read Timeout/BDS timeout; +DCRC : Data CRC for Receive; +RE : Response Error. +Writing 1 clears this bit. The abort condition of the IDMAC depends on the setting of this CES bit. If the CES bit is enabled, then the IDMAC aborts on a response error. + 5 + 1 + read-write + + + NIS + Normal Interrupt Summary. Logical OR of the following: IDSTS[0] : Transmit Interrupt, IDSTS[1] : Receive Interrupt. Only unmasked bits affect this bit. This is a sticky bit and must be cleared each time a corresponding bit that causes NIS to be set is cleared. Writing 1 clears this bit. + 8 + 1 + read-write + + + AIS + Abnormal Interrupt Summary. Logical OR of the following: IDSTS[2] : Fatal Bus Interrupt, IDSTS[4] : DU bit Interrupt. Only unmasked bits affect this bit. This is a sticky bit and must be cleared each time a corresponding bit that causes AIS to be set is cleared. Writing 1 clears this bit. + 9 + 1 + read-write + + + FBE_CODE + Fatal Bus Error Code. Indicates the type of error that caused a Bus Error. Valid only when the Fatal Bus Error bit IDSTS[2] is set. This field does not generate an interrupt. +001: Host Abort received during transmission; +010: Host Abort received during reception; +Others: Reserved. + 10 + 3 + read-write + + + FSM + DMAC FSM present state. +0: DMA_IDLE (idle state); +1: DMA_SUSPEND (suspend state); +2: DESC_RD (descriptor reading state); +3: DESC_CHK (descriptor checking state); +4: DMA_RD_REQ_WAIT (read-data request waiting state); +5: DMA_WR_REQ_WAIT (write-data request waiting state); +6: DMA_RD (data-read state); +7: DMA_WR (data-write state); +8: DESC_CLOSE (descriptor close state). + 13 + 4 + read-write + + + + + IDINTEN + IDMAC interrupt enable register + 0x90 + 0x20 + + + TI + Transmit Interrupt Enable. When set with Normal Interrupt Summary Enable, Transmit Interrupt is enabled. When reset, Transmit Interrupt is disabled. + 0 + 1 + read-write + + + RI + Receive Interrupt Enable. When set with Normal Interrupt Summary Enable, Receive Interrupt is enabled. When reset, Receive Interrupt is disabled. + 1 + 1 + read-write + + + FBE + Fatal Bus Error Enable. When set with Abnormal Interrupt Summary Enable, the Fatal Bus Error Interrupt is enabled. When reset, Fatal Bus Error Enable Interrupt is disabled. + 2 + 1 + read-write + + + DU + Descriptor Unavailable Interrupt. When set along with Abnormal Interrupt Summary Enable, the DU interrupt is enabled. + 4 + 1 + read-write + + + CES + Card Error summary Interrupt Enable. When set, it enables the Card Interrupt summary. + 5 + 1 + read-write + + + NI + Normal Interrupt Summary Enable. When set, a normal interrupt is enabled. When reset, a normal interrupt is disabled. This bit enables the following bits: +IDINTEN[0]: Transmit Interrupt; +IDINTEN[1]: Receive Interrupt. + 8 + 1 + read-write + + + AI + Abnormal Interrupt Summary Enable. When set, an abnormal interrupt is enabled. This bit enables the following bits: +IDINTEN[2]: Fatal Bus Error Interrupt; +IDINTEN[4]: DU Interrupt. + 9 + 1 + read-write + + + + + DSCADDR + Host descriptor address pointer + 0x94 + 0x20 + + + DSCADDR + Host Descriptor Address Pointer, updated by IDMAC during operation and cleared on reset. This register points to the start address of the current descriptor read by the IDMAC. + 0 + 32 + read-only + + + + + BUFADDR + Host buffer address pointer register + 0x98 + 0x20 + + + BUFADDR + Host Buffer Address Pointer, updated by IDMAC during operation and cleared on reset. This register points to the current Data Buffer Address being accessed by the IDMAC. + 0 + 32 + read-only + + + + + CARDTHRCTL + Card Threshold Control register + 0x100 + 0x20 + + + CARDRDTHREN + Card read threshold enable. +1'b0-Card read threshold disabled. +1'b1-Card read threshold enabled. + 0 + 1 + read-write + + + CARDCLRINTEN + Busy clear interrupt generation: +1'b0-Busy clear interrypt disabled. +1'b1-Busy clear interrypt enabled. + 1 + 1 + read-write + + + CARDWRTHREN + Applicable when HS400 mode is enabled. +1'b0-Card write Threshold disabled. +1'b1-Card write Threshold enabled. + 2 + 1 + read-write + + + CARDTHRESHOLD + The inside FIFO size is 512,This register is applicable when SDHOST_CARDERTHREN_REG is set to 1 or SDHOST_CARDRDTHREN_REG set to 1. + 16 + 16 + read-write + + + + + EMMCDDR + eMMC DDR register + 0x10C + 0x20 + + + HALFSTARTBIT + Control for start bit detection mechanism duration of start bit.Each bit refers to one slot.Set this bit to 1 for eMMC4.5 and above,set to 0 for SD applications.For eMMC4.5,start bit can be: +1'b0-Full cycle. +1'b1-less than one full cycle. + 0 + 2 + read-write + + + HS400_MODE + Set 1 to enable HS400 mode. + 31 + 1 + read-write + + + + + ENSHIFT + Enable Phase Shift register + 0x110 + 0x20 + + + ENABLE_SHIFT + Control for the amount of phase shift provided on the default enables in the design.Two bits assigned for each card. +2'b00-Default phase shift. +2'b01-Enables shifted to next immediate positive edge. +2'b10-Enables shifted to next immediate negative edge. +2'b11-Reserved. + 0 + 4 + read-write + + + + + BUFFIFO + CPU write and read transmit data by FIFO + 0x200 + 0x20 + + + BUFFIFO + CPU write and read transmit data by FIFO. This register points to the current Data FIFO . + 0 + 32 + read-write + + + + + CLK_EDGE_SEL + SDIO control register. + 0x800 + 0x20 + 0x00820200 + + + CCLKIN_EDGE_DRV_SEL + It's used to select the clock phase of the output signal from phase 0, phase 90, phase 180, phase 270. + 0 + 3 + read-write + + + CCLKIN_EDGE_SAM_SEL + It's used to select the clock phase of the input signal from phase 0, phase 90, phase 180, phase 270. + 3 + 3 + read-write + + + CCLKIN_EDGE_SLF_SEL + It's used to select the clock phase of the internal signal from phase 0, phase 90, phase 180, phase 270. + 6 + 3 + read-write + + + CCLLKIN_EDGE_H + The high level of the divider clock. The value should be smaller than CCLKIN_EDGE_L. + 9 + 4 + read-write + + + CCLLKIN_EDGE_L + The low level of the divider clock. The value should be larger than CCLKIN_EDGE_H. + 13 + 4 + read-write + + + CCLLKIN_EDGE_N + The value should be equal to CCLKIN_EDGE_L. + 17 + 4 + read-write + + + ESDIO_MODE + Enable esdio mode. + 21 + 1 + read-write + + + ESD_MODE + Enable esd mode. + 22 + 1 + read-write + + + CCLK_EN + Sdio clock enable + 23 + 1 + read-write + + + + + + + SENS + Peripheral SENS + SENS + 0x3FF48800 + + 0x0 + 0xA8 + registers + + + + SAR_READ_CTRL + 0x0 + 0x20 + 0x00070902 + + + SAR1_CLK_DIV + clock divider + 0 + 8 + read-write + + + SAR1_SAMPLE_CYCLE + sample cycles for SAR ADC1 + 8 + 8 + read-write + + + SAR1_SAMPLE_BIT + 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width 11: for 12-bit width + 16 + 2 + read-write + + + SAR1_CLK_GATED + 18 + 1 + read-write + + + SAR1_SAMPLE_NUM + 19 + 8 + read-write + + + SAR1_DIG_FORCE + 1: SAR ADC1 controlled by DIG ADC1 CTRL 0: SAR ADC1 controlled by RTC ADC1 CTRL + 27 + 1 + read-write + + + SAR1_DATA_INV + Invert SAR ADC1 data + 28 + 1 + read-write + + + + + SAR_READ_STATUS1 + 0x4 + 0x20 + + + SAR1_READER_STATUS + 0 + 32 + read-only + + + + + SAR_MEAS_WAIT1 + 0x8 + 0x20 + 0x000A000A + + + SAR_AMP_WAIT1 + 0 + 16 + read-write + + + SAR_AMP_WAIT2 + 16 + 16 + read-write + + + + + SAR_MEAS_WAIT2 + 0xC + 0x20 + 0x0020000A + + + FORCE_XPD_SAR_SW + 0 + 1 + read-write + + + SAR_AMP_WAIT3 + 0 + 16 + read-write + + + FORCE_XPD_AMP + 16 + 2 + read-write + + + FORCE_XPD_SAR + 18 + 2 + read-write + + + SAR2_RSTB_WAIT + 20 + 8 + read-write + + + + + SAR_MEAS_CTRL + 0x10 + 0x20 + 0x0707338F + + + XPD_SAR_AMP_FSM + 0 + 4 + read-write + + + AMP_RST_FB_FSM + 4 + 4 + read-write + + + AMP_SHORT_REF_FSM + 8 + 4 + read-write + + + AMP_SHORT_REF_GND_FSM + 12 + 4 + read-write + + + XPD_SAR_FSM + 16 + 4 + read-write + + + SAR_RSTB_FSM + 20 + 4 + read-write + + + SAR2_XPD_WAIT + 24 + 8 + read-write + + + + + SAR_READ_STATUS2 + 0x14 + 0x20 + + + SAR2_READER_STATUS + 0 + 32 + read-only + + + + + ULP_CP_SLEEP_CYC0 + 0x18 + 0x20 + 0x000000C8 + + + SLEEP_CYCLES_S0 + sleep cycles for ULP-coprocessor timer + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC1 + 0x1C + 0x20 + 0x00000064 + + + SLEEP_CYCLES_S1 + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC2 + 0x20 + 0x20 + 0x00000032 + + + SLEEP_CYCLES_S2 + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC3 + 0x24 + 0x20 + 0x00000028 + + + SLEEP_CYCLES_S3 + 0 + 32 + read-write + + + + + ULP_CP_SLEEP_CYC4 + 0x28 + 0x20 + 0x00000014 + + + SLEEP_CYCLES_S4 + 0 + 32 + read-write + + + + + SAR_START_FORCE + 0x2C + 0x20 + 0x0000000F + + + SAR1_BIT_WIDTH + 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits + 0 + 2 + read-write + + + SAR2_BIT_WIDTH + 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits + 2 + 2 + read-write + + + SAR2_EN_TEST + SAR2_EN_TEST only active when reg_sar2_dig_force = 0 + 4 + 1 + read-write + + + SAR2_PWDET_CCT + SAR2_PWDET_CCT PA power detector capacitance tuning. + 5 + 3 + read-write + + + ULP_CP_FORCE_START_TOP + 1: ULP-coprocessor is started by SW 0: ULP-coprocessor is started by timer + 8 + 1 + read-write + + + ULP_CP_START_TOP + Write 1 to start ULP-coprocessor only active when reg_ulp_cp_force_start_top = 1 + 9 + 1 + read-write + + + SARCLK_EN + 10 + 1 + read-write + + + PC_INIT + initialized PC for ULP-coprocessor + 11 + 11 + read-write + + + SAR2_STOP + stop SAR ADC2 conversion + 22 + 1 + read-write + + + SAR1_STOP + stop SAR ADC1 conversion + 23 + 1 + read-write + + + SAR2_PWDET_EN + N/A + 24 + 1 + read-write + + + + + SAR_MEM_WR_CTRL + 0x30 + 0x20 + 0x00100200 + + + MEM_WR_ADDR_INIT + 0 + 11 + read-write + + + MEM_WR_ADDR_SIZE + 11 + 11 + read-write + + + RTC_MEM_WR_OFFST_CLR + 22 + 1 + write-only + + + + + SAR_ATTEN1 + 0x34 + 0x20 + 0xFFFFFFFF + + + SAR1_ATTEN + 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB + 0 + 32 + read-write + + + + + SAR_ATTEN2 + 0x38 + 0x20 + 0xFFFFFFFF + + + SAR2_ATTEN + 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB + 0 + 32 + read-write + + + + + SAR_SLAVE_ADDR1 + 0x3C + 0x20 + + + I2C_SLAVE_ADDR1 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR0 + 11 + 11 + read-write + + + MEAS_STATUS + 22 + 8 + read-only + + + + + SAR_SLAVE_ADDR2 + 0x40 + 0x20 + + + I2C_SLAVE_ADDR3 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR2 + 11 + 11 + read-write + + + + + SAR_SLAVE_ADDR3 + 0x44 + 0x20 + + + I2C_SLAVE_ADDR5 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR4 + 11 + 11 + read-write + + + TSENS_OUT + temperature sensor data out + 22 + 8 + read-only + + + TSENS_RDY_OUT + indicate temperature sensor out ready + 30 + 1 + read-only + + + + + SAR_SLAVE_ADDR4 + 0x48 + 0x20 + + + I2C_SLAVE_ADDR7 + 0 + 11 + read-write + + + I2C_SLAVE_ADDR6 + 11 + 11 + read-write + + + I2C_RDATA + I2C read data + 22 + 8 + read-only + + + I2C_DONE + indicate I2C done + 30 + 1 + read-only + + + + + SAR_TSENS_CTRL + 0x4C + 0x20 + 0x00066002 + + + TSENS_XPD_WAIT + 0 + 12 + read-write + + + TSENS_XPD_FORCE + 12 + 1 + read-write + + + TSENS_CLK_INV + 13 + 1 + read-write + + + TSENS_CLK_GATED + 14 + 1 + read-write + + + TSENS_IN_INV + invert temperature sensor data + 15 + 1 + read-write + + + TSENS_CLK_DIV + temperature sensor clock divider + 16 + 8 + read-write + + + TSENS_POWER_UP + temperature sensor power up + 24 + 1 + read-write + + + TSENS_POWER_UP_FORCE + 1: dump out & power up controlled by SW 0: by FSM + 25 + 1 + read-write + + + TSENS_DUMP_OUT + temperature sensor dump out only active when reg_tsens_power_up_force = 1 + 26 + 1 + read-write + + + + + SAR_I2C_CTRL + 0x50 + 0x20 + + + SAR_I2C_CTRL + I2C control data only active when reg_sar_i2c_start_force = 1 + 0 + 28 + read-write + + + SAR_I2C_START + start I2C only active when reg_sar_i2c_start_force = 1 + 28 + 1 + read-write + + + SAR_I2C_START_FORCE + 1: I2C started by SW 0: I2C started by FSM + 29 + 1 + read-write + + + + + SAR_MEAS_START1 + 0x54 + 0x20 + + + MEAS1_DATA_SAR + SAR ADC1 data + 0 + 16 + read-only + + + MEAS1_DONE_SAR + SAR ADC1 conversion done indication + 16 + 1 + read-only + + + MEAS1_START_SAR + SAR ADC1 controller (in RTC) starts conversion only active when reg_meas1_start_force = 1 + 17 + 1 + read-write + + + MEAS1_START_FORCE + 1: SAR ADC1 controller (in RTC) is started by SW 0: SAR ADC1 controller is started by ULP-coprocessor + 18 + 1 + read-write + + + SAR1_EN_PAD + SAR ADC1 pad enable bitmap only active when reg_sar1_en_pad_force = 1 + 19 + 12 + read-write + + + SAR1_EN_PAD_FORCE + 1: SAR ADC1 pad enable bitmap is controlled by SW 0: SAR ADC1 pad enable bitmap is controlled by ULP-coprocessor + 31 + 1 + read-write + + + + + SAR_TOUCH_CTRL1 + 0x58 + 0x20 + 0x02041000 + + + TOUCH_MEAS_DELAY + the meas length (in 8MHz) + 0 + 16 + read-write + + + TOUCH_XPD_WAIT + the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD + 16 + 8 + read-write + + + TOUCH_OUT_SEL + 1: when the counter is greater then the threshold the touch pad is considered as "touched" 0: when the counter is less than the threshold the touch pad is considered as "touched" + 24 + 1 + read-write + + + TOUCH_OUT_1EN + 1: wakeup interrupt is generated if SET1 is "touched" 0: wakeup interrupt is generated only if SET1 & SET2 is both "touched" + 25 + 1 + read-write + + + XPD_HALL_FORCE + 1: XPD HALL is controlled by SW. 0: XPD HALL is controlled by FSM in ULP-coprocessor + 26 + 1 + read-write + + + HALL_PHASE_FORCE + 1: HALL PHASE is controlled by SW 0: HALL PHASE is controlled by FSM in ULP-coprocessor + 27 + 1 + read-write + + + + + SAR_TOUCH_THRES1 + 0x5C + 0x20 + + + TOUCH_OUT_TH1 + the threshold for touch pad 1 + 0 + 16 + read-write + + + TOUCH_OUT_TH0 + the threshold for touch pad 0 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES2 + 0x60 + 0x20 + + + TOUCH_OUT_TH3 + the threshold for touch pad 3 + 0 + 16 + read-write + + + TOUCH_OUT_TH2 + the threshold for touch pad 2 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES3 + 0x64 + 0x20 + + + TOUCH_OUT_TH5 + the threshold for touch pad 5 + 0 + 16 + read-write + + + TOUCH_OUT_TH4 + the threshold for touch pad 4 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES4 + 0x68 + 0x20 + + + TOUCH_OUT_TH7 + the threshold for touch pad 7 + 0 + 16 + read-write + + + TOUCH_OUT_TH6 + the threshold for touch pad 6 + 16 + 16 + read-write + + + + + SAR_TOUCH_THRES5 + 0x6C + 0x20 + + + TOUCH_OUT_TH9 + the threshold for touch pad 9 + 0 + 16 + read-write + + + TOUCH_OUT_TH8 + the threshold for touch pad 8 + 16 + 16 + read-write + + + + + SAR_TOUCH_OUT1 + 0x70 + 0x20 + + + TOUCH_MEAS_OUT1 + the counter for touch pad 1 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT0 + the counter for touch pad 0 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT2 + 0x74 + 0x20 + + + TOUCH_MEAS_OUT3 + the counter for touch pad 3 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT2 + the counter for touch pad 2 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT3 + 0x78 + 0x20 + + + TOUCH_MEAS_OUT5 + the counter for touch pad 5 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT4 + the counter for touch pad 4 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT4 + 0x7C + 0x20 + + + TOUCH_MEAS_OUT7 + the counter for touch pad 7 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT6 + the counter for touch pad 6 + 16 + 16 + read-only + + + + + SAR_TOUCH_OUT5 + 0x80 + 0x20 + + + TOUCH_MEAS_OUT9 + the counter for touch pad 9 + 0 + 16 + read-only + + + TOUCH_MEAS_OUT8 + the counter for touch pad 8 + 16 + 16 + read-only + + + + + SAR_TOUCH_CTRL2 + 0x84 + 0x20 + 0x00400800 + + + TOUCH_MEAS_EN + 10-bit register to indicate which pads are "touched" + 0 + 10 + read-only + + + TOUCH_MEAS_DONE + fsm set 1 to indicate touch touch meas is done + 10 + 1 + read-only + + + TOUCH_START_FSM_EN + 1: TOUCH_START & TOUCH_XPD is controlled by touch fsm 0: TOUCH_START & TOUCH_XPD is controlled by registers + 11 + 1 + read-write + + + TOUCH_START_EN + 1: start touch fsm valid when reg_touch_start_force is set + 12 + 1 + read-write + + + TOUCH_START_FORCE + 1: to start touch fsm by SW 0: to start touch fsm by timer + 13 + 1 + read-write + + + TOUCH_SLEEP_CYCLES + sleep cycles for timer + 14 + 16 + read-write + + + TOUCH_MEAS_EN_CLR + to clear reg_touch_meas_en + 30 + 1 + write-only + + + + + SAR_TOUCH_ENABLE + 0x8C + 0x20 + 0x3FFFFFFF + + + TOUCH_PAD_WORKEN + Bitmap defining the working set during the measurement. + 0 + 10 + read-write + + + TOUCH_PAD_OUTEN2 + Bitmap defining SET2 for generating wakeup interrupt. SET2 is "touched" only if at least one of touch pad in SET2 is "touched". + 10 + 10 + read-write + + + TOUCH_PAD_OUTEN1 + Bitmap defining SET1 for generating wakeup interrupt. SET1 is "touched" only if at least one of touch pad in SET1 is "touched". + 20 + 10 + read-write + + + + + SAR_READ_CTRL2 + 0x90 + 0x20 + 0x00070902 + + + SAR2_CLK_DIV + clock divider + 0 + 8 + read-write + + + SAR2_SAMPLE_CYCLE + sample cycles for SAR ADC2 + 8 + 8 + read-write + + + SAR2_SAMPLE_BIT + 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width 11: for 12-bit width + 16 + 2 + read-write + + + SAR2_CLK_GATED + 18 + 1 + read-write + + + SAR2_SAMPLE_NUM + 19 + 8 + read-write + + + SAR2_PWDET_FORCE + 27 + 1 + read-write + + + SAR2_DIG_FORCE + 1: SAR ADC2 controlled by DIG ADC2 CTRL or PWDET CTRL 0: SAR ADC2 controlled by RTC ADC2 CTRL + 28 + 1 + read-write + + + SAR2_DATA_INV + Invert SAR ADC2 data + 29 + 1 + read-write + + + + + SAR_MEAS_START2 + 0x94 + 0x20 + + + MEAS2_DATA_SAR + SAR ADC2 data + 0 + 16 + read-only + + + MEAS2_DONE_SAR + SAR ADC2 conversion done indication + 16 + 1 + read-only + + + MEAS2_START_SAR + SAR ADC2 controller (in RTC) starts conversion only active when reg_meas2_start_force = 1 + 17 + 1 + read-write + + + MEAS2_START_FORCE + 1: SAR ADC2 controller (in RTC) is started by SW 0: SAR ADC2 controller is started by ULP-coprocessor + 18 + 1 + read-write + + + SAR2_EN_PAD + SAR ADC2 pad enable bitmap only active when reg_sar2_en_pad_force = 1 + 19 + 12 + read-write + + + SAR2_EN_PAD_FORCE + 1: SAR ADC2 pad enable bitmap is controlled by SW 0: SAR ADC2 pad enable bitmap is controlled by ULP-coprocessor + 31 + 1 + read-write + + + + + SAR_DAC_CTRL1 + 0x98 + 0x20 + + + SW_FSTEP + frequency step for CW generator can be used to adjust the frequency + 0 + 16 + read-write + + + SW_TONE_EN + 1: enable CW generator 0: disable CW generator + 16 + 1 + read-write + + + DEBUG_BIT_SEL + 17 + 5 + read-write + + + DAC_DIG_FORCE + 1: DAC1 & DAC2 use DMA 0: DAC1 & DAC2 do not use DMA + 22 + 1 + read-write + + + DAC_CLK_FORCE_LOW + 1: force PDAC_CLK to low + 23 + 1 + read-write + + + DAC_CLK_FORCE_HIGH + 1: force PDAC_CLK to high + 24 + 1 + read-write + + + DAC_CLK_INV + 1: invert PDAC_CLK + 25 + 1 + read-write + + + + + SAR_DAC_CTRL2 + 0x9C + 0x20 + 0x03000000 + + + DAC_DC1 + DC offset for DAC1 CW generator + 0 + 8 + read-write + + + DAC_DC2 + DC offset for DAC2 CW generator + 8 + 8 + read-write + + + DAC_SCALE1 + 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8 + 16 + 2 + read-write + + + DAC_SCALE2 + 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8 + 18 + 2 + read-write + + + DAC_INV1 + 00: do not invert any bits 01: invert all bits 10: invert MSB 11: invert all bits except MSB + 20 + 2 + read-write + + + DAC_INV2 + 00: do not invert any bits 01: invert all bits 10: invert MSB 11: invert all bits except MSB + 22 + 2 + read-write + + + DAC_CW_EN1 + 1: to select CW generator as source to PDAC1_DAC[7:0] 0: to select register reg_pdac1_dac[7:0] as source to PDAC1_DAC[7:0] + 24 + 1 + read-write + + + DAC_CW_EN2 + 1: to select CW generator as source to PDAC2_DAC[7:0] 0: to select register reg_pdac2_dac[7:0] as source to PDAC2_DAC[7:0] + 25 + 1 + read-write + + + + + SAR_MEAS_CTRL2 + 0xA0 + 0x20 + 0x00000003 + + + SAR1_DAC_XPD_FSM + 0 + 4 + read-write + + + SAR1_DAC_XPD_FSM_IDLE + 4 + 1 + read-write + + + XPD_SAR_AMP_FSM_IDLE + 5 + 1 + read-write + + + AMP_RST_FB_FSM_IDLE + 6 + 1 + read-write + + + AMP_SHORT_REF_FSM_IDLE + 7 + 1 + read-write + + + AMP_SHORT_REF_GND_FSM_IDLE + 8 + 1 + read-write + + + XPD_SAR_FSM_IDLE + 9 + 1 + read-write + + + SAR_RSTB_FSM_IDLE + 10 + 1 + read-write + + + SAR2_RSTB_FORCE + 11 + 2 + read-write + + + AMP_RST_FB_FORCE + 13 + 2 + read-write + + + AMP_SHORT_REF_FORCE + 15 + 2 + read-write + + + AMP_SHORT_REF_GND_FORCE + 17 + 2 + read-write + + + + + SAR_NOUSE + 0xF8 + 0x20 + + + SAR_NOUSE + 0 + 32 + read-write + + + + + SARDATE + 0xFC + 0x20 + 0x01605180 + + + SAR_DATE + 0 + 28 + read-write + + + + + + + SHA + SHA (Secure Hash Algorithm) Accelerator + SHA + 0x3FF03000 + + 0x0 + 0xC0 + registers + + + + 32 + 0x4 + TEXT_%s + 0x0 + 0x20 + + + TEXT + SHA Message block and hash result register. + 0 + 8 + read-write + + + + + SHA1_START + 0x80 + 0x20 + + + SHA1_START + Write 1 to start an SHA-1 operation on the first message block. + 0 + 1 + write-only + + + + + SHA1_CONTINUE + 0x80 + 0x20 + + + SHA1_CONTINUE + Write 1 to continue the SHA-1 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA1_LOAD + 0x88 + 0x20 + + + SHA1_LOAD + Write 1 to finish the SHA-1 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA1_BUSY + 0x8C + 0x20 + + + SHA1_BUSY + SHA-1 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + write-only + + + + + SHA256_START + 0x90 + 0x20 + + + SHA256_START + Write 1 to start an SHA-256 operation on the first message block. + 0 + 1 + write-only + + + + + SHA256_LOAD + 0x90 + 0x20 + + + SHA256_LOAD + Write 1 to finish the SHA-256 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA256_CONTINUE + 0x94 + 0x20 + + + SHA256_CONTINUE + Write 1 to continue the SHA-256 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA256_BUSY + 0x9C + 0x20 + + + SHA256_BUSY + SHA-256 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + read-only + + + + + SHA384_START + 0xA0 + 0x20 + + + SHA384_START + Write 1 to start an SHA-384 operation on the first message block. + 0 + 1 + write-only + + + + + SHA384_CONTINUE + 0xA4 + 0x20 + + + SHA384_CONTINUE + Write 1 to continue the SHA-384 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA384_LOAD + 0xA8 + 0x20 + + + SHA384_LOAD + Write 1 to finish the SHA-384 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA384_BUSY + 0xAC + 0x20 + + + SHA384_BUSY + SHA-384 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + read-only + + + + + SHA512_START + 0xB0 + 0x20 + + + SHA512_START + Write 1 to start an SHA-512 operation on the first message block. + 0 + 1 + write-only + + + + + SHA512_CONTINUE + 0xB4 + 0x20 + + + SHA512_CONTINUE + Write 1 to continue the SHA-512 operation with subsequent blocks. + 0 + 1 + write-only + + + + + SHA512_LOAD + 0xB8 + 0x20 + + + SHA512_LOAD + Write 1 to finish the SHA-512 operation to calculate the final message hash. + 0 + 1 + write-only + + + + + SHA512_BUSY + 0xBC + 0x20 + + + SHA512_BUSY + SHA-512 operation status: 1 if the SHA accelerator is processing data, 0 if it is idle. + 0 + 1 + read-only + + + + + + + SLC + Peripheral SLC + SLC + 0x3FF58000 + + 0x0 + 0x14C + registers + + + + CONF0 + 0x0 + 0x20 + 0xFF3CFF30 + + + SLC0_TX_RST + 0 + 1 + read-write + + + SLC0_RX_RST + 1 + 1 + read-write + + + AHBM_FIFO_RST + 2 + 1 + read-write + + + AHBM_RST + 3 + 1 + read-write + + + SLC0_TX_LOOP_TEST + 4 + 1 + read-write + + + SLC0_RX_LOOP_TEST + 5 + 1 + read-write + + + SLC0_RX_AUTO_WRBACK + 6 + 1 + read-write + + + SLC0_RX_NO_RESTART_CLR + 7 + 1 + read-write + + + SLC0_RXDSCR_BURST_EN + 8 + 1 + read-write + + + SLC0_RXDATA_BURST_EN + 9 + 1 + read-write + + + SLC0_RXLINK_AUTO_RET + 10 + 1 + read-write + + + SLC0_TXLINK_AUTO_RET + 11 + 1 + read-write + + + SLC0_TXDSCR_BURST_EN + 12 + 1 + read-write + + + SLC0_TXDATA_BURST_EN + 13 + 1 + read-write + + + SLC0_TOKEN_AUTO_CLR + 14 + 1 + read-write + + + SLC0_TOKEN_SEL + 15 + 1 + read-write + + + SLC1_TX_RST + 16 + 1 + read-write + + + SLC1_RX_RST + 17 + 1 + read-write + + + SLC0_WR_RETRY_MASK_EN + 18 + 1 + read-write + + + SLC1_WR_RETRY_MASK_EN + 19 + 1 + read-write + + + SLC1_TX_LOOP_TEST + 20 + 1 + read-write + + + SLC1_RX_LOOP_TEST + 21 + 1 + read-write + + + SLC1_RX_AUTO_WRBACK + 22 + 1 + read-write + + + SLC1_RX_NO_RESTART_CLR + 23 + 1 + read-write + + + SLC1_RXDSCR_BURST_EN + 24 + 1 + read-write + + + SLC1_RXDATA_BURST_EN + 25 + 1 + read-write + + + SLC1_RXLINK_AUTO_RET + 26 + 1 + read-write + + + SLC1_TXLINK_AUTO_RET + 27 + 1 + read-write + + + SLC1_TXDSCR_BURST_EN + 28 + 1 + read-write + + + SLC1_TXDATA_BURST_EN + 29 + 1 + read-write + + + SLC1_TOKEN_AUTO_CLR + 30 + 1 + read-write + + + SLC1_TOKEN_SEL + 31 + 1 + read-write + + + + + _0INT_RAW + 0x4 + 0x20 + + + FRHOST_BIT0_INT_RAW + 0 + 1 + read-only + + + FRHOST_BIT1_INT_RAW + 1 + 1 + read-only + + + FRHOST_BIT2_INT_RAW + 2 + 1 + read-only + + + FRHOST_BIT3_INT_RAW + 3 + 1 + read-only + + + FRHOST_BIT4_INT_RAW + 4 + 1 + read-only + + + FRHOST_BIT5_INT_RAW + 5 + 1 + read-only + + + FRHOST_BIT6_INT_RAW + 6 + 1 + read-only + + + FRHOST_BIT7_INT_RAW + 7 + 1 + read-only + + + SLC0_RX_START_INT_RAW + 8 + 1 + read-only + + + SLC0_TX_START_INT_RAW + 9 + 1 + read-only + + + SLC0_RX_UDF_INT_RAW + 10 + 1 + read-only + + + SLC0_TX_OVF_INT_RAW + 11 + 1 + read-only + + + SLC0_TOKEN0_1TO0_INT_RAW + 12 + 1 + read-only + + + SLC0_TOKEN1_1TO0_INT_RAW + 13 + 1 + read-only + + + SLC0_TX_DONE_INT_RAW + 14 + 1 + read-only + + + SLC0_TX_SUC_EOF_INT_RAW + 15 + 1 + read-only + + + SLC0_RX_DONE_INT_RAW + 16 + 1 + read-only + + + SLC0_RX_EOF_INT_RAW + 17 + 1 + read-only + + + SLC0_TOHOST_INT_RAW + 18 + 1 + read-only + + + SLC0_TX_DSCR_ERR_INT_RAW + 19 + 1 + read-only + + + SLC0_RX_DSCR_ERR_INT_RAW + 20 + 1 + read-only + + + SLC0_TX_DSCR_EMPTY_INT_RAW + 21 + 1 + read-only + + + SLC0_HOST_RD_ACK_INT_RAW + 22 + 1 + read-only + + + SLC0_WR_RETRY_DONE_INT_RAW + 23 + 1 + read-only + + + SLC0_TX_ERR_EOF_INT_RAW + 24 + 1 + read-only + + + CMD_DTC_INT_RAW + 25 + 1 + read-only + + + SLC0_RX_QUICK_EOF_INT_RAW + 26 + 1 + read-only + + + + + _0INT_ST + 0x8 + 0x20 + + + FRHOST_BIT0_INT_ST + 0 + 1 + read-only + + + FRHOST_BIT1_INT_ST + 1 + 1 + read-only + + + FRHOST_BIT2_INT_ST + 2 + 1 + read-only + + + FRHOST_BIT3_INT_ST + 3 + 1 + read-only + + + FRHOST_BIT4_INT_ST + 4 + 1 + read-only + + + FRHOST_BIT5_INT_ST + 5 + 1 + read-only + + + FRHOST_BIT6_INT_ST + 6 + 1 + read-only + + + FRHOST_BIT7_INT_ST + 7 + 1 + read-only + + + SLC0_RX_START_INT_ST + 8 + 1 + read-only + + + SLC0_TX_START_INT_ST + 9 + 1 + read-only + + + SLC0_RX_UDF_INT_ST + 10 + 1 + read-only + + + SLC0_TX_OVF_INT_ST + 11 + 1 + read-only + + + SLC0_TOKEN0_1TO0_INT_ST + 12 + 1 + read-only + + + SLC0_TOKEN1_1TO0_INT_ST + 13 + 1 + read-only + + + SLC0_TX_DONE_INT_ST + 14 + 1 + read-only + + + SLC0_TX_SUC_EOF_INT_ST + 15 + 1 + read-only + + + SLC0_RX_DONE_INT_ST + 16 + 1 + read-only + + + SLC0_RX_EOF_INT_ST + 17 + 1 + read-only + + + SLC0_TOHOST_INT_ST + 18 + 1 + read-only + + + SLC0_TX_DSCR_ERR_INT_ST + 19 + 1 + read-only + + + SLC0_RX_DSCR_ERR_INT_ST + 20 + 1 + read-only + + + SLC0_TX_DSCR_EMPTY_INT_ST + 21 + 1 + read-only + + + SLC0_HOST_RD_ACK_INT_ST + 22 + 1 + read-only + + + SLC0_WR_RETRY_DONE_INT_ST + 23 + 1 + read-only + + + SLC0_TX_ERR_EOF_INT_ST + 24 + 1 + read-only + + + CMD_DTC_INT_ST + 25 + 1 + read-only + + + SLC0_RX_QUICK_EOF_INT_ST + 26 + 1 + read-only + + + + + _0INT_ENA + 0xC + 0x20 + + + FRHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + FRHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + FRHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + FRHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + FRHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + FRHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + FRHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + FRHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + SLC0_RX_START_INT_ENA + 8 + 1 + read-write + + + SLC0_TX_START_INT_ENA + 9 + 1 + read-write + + + SLC0_RX_UDF_INT_ENA + 10 + 1 + read-write + + + SLC0_TX_OVF_INT_ENA + 11 + 1 + read-write + + + SLC0_TOKEN0_1TO0_INT_ENA + 12 + 1 + read-write + + + SLC0_TOKEN1_1TO0_INT_ENA + 13 + 1 + read-write + + + SLC0_TX_DONE_INT_ENA + 14 + 1 + read-write + + + SLC0_TX_SUC_EOF_INT_ENA + 15 + 1 + read-write + + + SLC0_RX_DONE_INT_ENA + 16 + 1 + read-write + + + SLC0_RX_EOF_INT_ENA + 17 + 1 + read-write + + + SLC0_TOHOST_INT_ENA + 18 + 1 + read-write + + + SLC0_TX_DSCR_ERR_INT_ENA + 19 + 1 + read-write + + + SLC0_RX_DSCR_ERR_INT_ENA + 20 + 1 + read-write + + + SLC0_TX_DSCR_EMPTY_INT_ENA + 21 + 1 + read-write + + + SLC0_HOST_RD_ACK_INT_ENA + 22 + 1 + read-write + + + SLC0_WR_RETRY_DONE_INT_ENA + 23 + 1 + read-write + + + SLC0_TX_ERR_EOF_INT_ENA + 24 + 1 + read-write + + + CMD_DTC_INT_ENA + 25 + 1 + read-write + + + SLC0_RX_QUICK_EOF_INT_ENA + 26 + 1 + read-write + + + + + _0INT_CLR + 0x10 + 0x20 + + + FRHOST_BIT0_INT_CLR + 0 + 1 + write-only + + + FRHOST_BIT1_INT_CLR + 1 + 1 + write-only + + + FRHOST_BIT2_INT_CLR + 2 + 1 + write-only + + + FRHOST_BIT3_INT_CLR + 3 + 1 + write-only + + + FRHOST_BIT4_INT_CLR + 4 + 1 + write-only + + + FRHOST_BIT5_INT_CLR + 5 + 1 + write-only + + + FRHOST_BIT6_INT_CLR + 6 + 1 + write-only + + + FRHOST_BIT7_INT_CLR + 7 + 1 + write-only + + + SLC0_RX_START_INT_CLR + 8 + 1 + write-only + + + SLC0_TX_START_INT_CLR + 9 + 1 + write-only + + + SLC0_RX_UDF_INT_CLR + 10 + 1 + write-only + + + SLC0_TX_OVF_INT_CLR + 11 + 1 + write-only + + + SLC0_TOKEN0_1TO0_INT_CLR + 12 + 1 + write-only + + + SLC0_TOKEN1_1TO0_INT_CLR + 13 + 1 + write-only + + + SLC0_TX_DONE_INT_CLR + 14 + 1 + write-only + + + SLC0_TX_SUC_EOF_INT_CLR + 15 + 1 + write-only + + + SLC0_RX_DONE_INT_CLR + 16 + 1 + write-only + + + SLC0_RX_EOF_INT_CLR + 17 + 1 + write-only + + + SLC0_TOHOST_INT_CLR + 18 + 1 + write-only + + + SLC0_TX_DSCR_ERR_INT_CLR + 19 + 1 + write-only + + + SLC0_RX_DSCR_ERR_INT_CLR + 20 + 1 + write-only + + + SLC0_TX_DSCR_EMPTY_INT_CLR + 21 + 1 + write-only + + + SLC0_HOST_RD_ACK_INT_CLR + 22 + 1 + write-only + + + SLC0_WR_RETRY_DONE_INT_CLR + 23 + 1 + write-only + + + SLC0_TX_ERR_EOF_INT_CLR + 24 + 1 + write-only + + + CMD_DTC_INT_CLR + 25 + 1 + write-only + + + SLC0_RX_QUICK_EOF_INT_CLR + 26 + 1 + write-only + + + + + _1INT_RAW + 0x14 + 0x20 + + + FRHOST_BIT8_INT_RAW + 0 + 1 + read-only + + + FRHOST_BIT9_INT_RAW + 1 + 1 + read-only + + + FRHOST_BIT10_INT_RAW + 2 + 1 + read-only + + + FRHOST_BIT11_INT_RAW + 3 + 1 + read-only + + + FRHOST_BIT12_INT_RAW + 4 + 1 + read-only + + + FRHOST_BIT13_INT_RAW + 5 + 1 + read-only + + + FRHOST_BIT14_INT_RAW + 6 + 1 + read-only + + + FRHOST_BIT15_INT_RAW + 7 + 1 + read-only + + + SLC1_RX_START_INT_RAW + 8 + 1 + read-only + + + SLC1_TX_START_INT_RAW + 9 + 1 + read-only + + + SLC1_RX_UDF_INT_RAW + 10 + 1 + read-only + + + SLC1_TX_OVF_INT_RAW + 11 + 1 + read-only + + + SLC1_TOKEN0_1TO0_INT_RAW + 12 + 1 + read-only + + + SLC1_TOKEN1_1TO0_INT_RAW + 13 + 1 + read-only + + + SLC1_TX_DONE_INT_RAW + 14 + 1 + read-only + + + SLC1_TX_SUC_EOF_INT_RAW + 15 + 1 + read-only + + + SLC1_RX_DONE_INT_RAW + 16 + 1 + read-only + + + SLC1_RX_EOF_INT_RAW + 17 + 1 + read-only + + + SLC1_TOHOST_INT_RAW + 18 + 1 + read-only + + + SLC1_TX_DSCR_ERR_INT_RAW + 19 + 1 + read-only + + + SLC1_RX_DSCR_ERR_INT_RAW + 20 + 1 + read-only + + + SLC1_TX_DSCR_EMPTY_INT_RAW + 21 + 1 + read-only + + + SLC1_HOST_RD_ACK_INT_RAW + 22 + 1 + read-only + + + SLC1_WR_RETRY_DONE_INT_RAW + 23 + 1 + read-only + + + SLC1_TX_ERR_EOF_INT_RAW + 24 + 1 + read-only + + + + + _1INT_ST + 0x18 + 0x20 + + + FRHOST_BIT8_INT_ST + 0 + 1 + read-only + + + FRHOST_BIT9_INT_ST + 1 + 1 + read-only + + + FRHOST_BIT10_INT_ST + 2 + 1 + read-only + + + FRHOST_BIT11_INT_ST + 3 + 1 + read-only + + + FRHOST_BIT12_INT_ST + 4 + 1 + read-only + + + FRHOST_BIT13_INT_ST + 5 + 1 + read-only + + + FRHOST_BIT14_INT_ST + 6 + 1 + read-only + + + FRHOST_BIT15_INT_ST + 7 + 1 + read-only + + + SLC1_RX_START_INT_ST + 8 + 1 + read-only + + + SLC1_TX_START_INT_ST + 9 + 1 + read-only + + + SLC1_RX_UDF_INT_ST + 10 + 1 + read-only + + + SLC1_TX_OVF_INT_ST + 11 + 1 + read-only + + + SLC1_TOKEN0_1TO0_INT_ST + 12 + 1 + read-only + + + SLC1_TOKEN1_1TO0_INT_ST + 13 + 1 + read-only + + + SLC1_TX_DONE_INT_ST + 14 + 1 + read-only + + + SLC1_TX_SUC_EOF_INT_ST + 15 + 1 + read-only + + + SLC1_RX_DONE_INT_ST + 16 + 1 + read-only + + + SLC1_RX_EOF_INT_ST + 17 + 1 + read-only + + + SLC1_TOHOST_INT_ST + 18 + 1 + read-only + + + SLC1_TX_DSCR_ERR_INT_ST + 19 + 1 + read-only + + + SLC1_RX_DSCR_ERR_INT_ST + 20 + 1 + read-only + + + SLC1_TX_DSCR_EMPTY_INT_ST + 21 + 1 + read-only + + + SLC1_HOST_RD_ACK_INT_ST + 22 + 1 + read-only + + + SLC1_WR_RETRY_DONE_INT_ST + 23 + 1 + read-only + + + SLC1_TX_ERR_EOF_INT_ST + 24 + 1 + read-only + + + + + _1INT_ENA + 0x1C + 0x20 + + + FRHOST_BIT8_INT_ENA + 0 + 1 + read-write + + + FRHOST_BIT9_INT_ENA + 1 + 1 + read-write + + + FRHOST_BIT10_INT_ENA + 2 + 1 + read-write + + + FRHOST_BIT11_INT_ENA + 3 + 1 + read-write + + + FRHOST_BIT12_INT_ENA + 4 + 1 + read-write + + + FRHOST_BIT13_INT_ENA + 5 + 1 + read-write + + + FRHOST_BIT14_INT_ENA + 6 + 1 + read-write + + + FRHOST_BIT15_INT_ENA + 7 + 1 + read-write + + + SLC1_RX_START_INT_ENA + 8 + 1 + read-write + + + SLC1_TX_START_INT_ENA + 9 + 1 + read-write + + + SLC1_RX_UDF_INT_ENA + 10 + 1 + read-write + + + SLC1_TX_OVF_INT_ENA + 11 + 1 + read-write + + + SLC1_TOKEN0_1TO0_INT_ENA + 12 + 1 + read-write + + + SLC1_TOKEN1_1TO0_INT_ENA + 13 + 1 + read-write + + + SLC1_TX_DONE_INT_ENA + 14 + 1 + read-write + + + SLC1_TX_SUC_EOF_INT_ENA + 15 + 1 + read-write + + + SLC1_RX_DONE_INT_ENA + 16 + 1 + read-write + + + SLC1_RX_EOF_INT_ENA + 17 + 1 + read-write + + + SLC1_TOHOST_INT_ENA + 18 + 1 + read-write + + + SLC1_TX_DSCR_ERR_INT_ENA + 19 + 1 + read-write + + + SLC1_RX_DSCR_ERR_INT_ENA + 20 + 1 + read-write + + + SLC1_TX_DSCR_EMPTY_INT_ENA + 21 + 1 + read-write + + + SLC1_HOST_RD_ACK_INT_ENA + 22 + 1 + read-write + + + SLC1_WR_RETRY_DONE_INT_ENA + 23 + 1 + read-write + + + SLC1_TX_ERR_EOF_INT_ENA + 24 + 1 + read-write + + + + + _1INT_CLR + 0x20 + 0x20 + + + FRHOST_BIT8_INT_CLR + 0 + 1 + write-only + + + FRHOST_BIT9_INT_CLR + 1 + 1 + write-only + + + FRHOST_BIT10_INT_CLR + 2 + 1 + write-only + + + FRHOST_BIT11_INT_CLR + 3 + 1 + write-only + + + FRHOST_BIT12_INT_CLR + 4 + 1 + write-only + + + FRHOST_BIT13_INT_CLR + 5 + 1 + write-only + + + FRHOST_BIT14_INT_CLR + 6 + 1 + write-only + + + FRHOST_BIT15_INT_CLR + 7 + 1 + write-only + + + SLC1_RX_START_INT_CLR + 8 + 1 + write-only + + + SLC1_TX_START_INT_CLR + 9 + 1 + write-only + + + SLC1_RX_UDF_INT_CLR + 10 + 1 + write-only + + + SLC1_TX_OVF_INT_CLR + 11 + 1 + write-only + + + SLC1_TOKEN0_1TO0_INT_CLR + 12 + 1 + write-only + + + SLC1_TOKEN1_1TO0_INT_CLR + 13 + 1 + write-only + + + SLC1_TX_DONE_INT_CLR + 14 + 1 + write-only + + + SLC1_TX_SUC_EOF_INT_CLR + 15 + 1 + write-only + + + SLC1_RX_DONE_INT_CLR + 16 + 1 + write-only + + + SLC1_RX_EOF_INT_CLR + 17 + 1 + write-only + + + SLC1_TOHOST_INT_CLR + 18 + 1 + write-only + + + SLC1_TX_DSCR_ERR_INT_CLR + 19 + 1 + write-only + + + SLC1_RX_DSCR_ERR_INT_CLR + 20 + 1 + write-only + + + SLC1_TX_DSCR_EMPTY_INT_CLR + 21 + 1 + write-only + + + SLC1_HOST_RD_ACK_INT_CLR + 22 + 1 + write-only + + + SLC1_WR_RETRY_DONE_INT_CLR + 23 + 1 + write-only + + + SLC1_TX_ERR_EOF_INT_CLR + 24 + 1 + write-only + + + + + RX_STATUS + 0x24 + 0x20 + 0x00020002 + + + SLC0_RX_FULL + 0 + 1 + read-only + + + SLC0_RX_EMPTY + 1 + 1 + read-only + + + SLC1_RX_FULL + 16 + 1 + read-only + + + SLC1_RX_EMPTY + 17 + 1 + read-only + + + + + _0RXFIFO_PUSH + 0x28 + 0x20 + + + SLC0_RXFIFO_WDATA + 0 + 9 + read-write + + + SLC0_RXFIFO_PUSH + 16 + 1 + read-write + + + + + _1RXFIFO_PUSH + 0x2C + 0x20 + + + SLC1_RXFIFO_WDATA + 0 + 9 + read-write + + + SLC1_RXFIFO_PUSH + 16 + 1 + read-write + + + + + TX_STATUS + 0x30 + 0x20 + 0x00020002 + + + SLC0_TX_FULL + 0 + 1 + read-only + + + SLC0_TX_EMPTY + 1 + 1 + read-only + + + SLC1_TX_FULL + 16 + 1 + read-only + + + SLC1_TX_EMPTY + 17 + 1 + read-only + + + + + _0TXFIFO_POP + 0x34 + 0x20 + + + SLC0_TXFIFO_RDATA + 0 + 11 + read-only + + + SLC0_TXFIFO_POP + 16 + 1 + read-write + + + + + _1TXFIFO_POP + 0x38 + 0x20 + + + SLC1_TXFIFO_RDATA + 0 + 11 + read-only + + + SLC1_TXFIFO_POP + 16 + 1 + read-write + + + + + _0RX_LINK + 0x3C + 0x20 + + + SLC0_RXLINK_ADDR + 0 + 20 + read-write + + + SLC0_RXLINK_STOP + 28 + 1 + read-write + + + SLC0_RXLINK_START + 29 + 1 + read-write + + + SLC0_RXLINK_RESTART + 30 + 1 + read-write + + + SLC0_RXLINK_PARK + 31 + 1 + read-only + + + + + _0TX_LINK + 0x40 + 0x20 + + + SLC0_TXLINK_ADDR + 0 + 20 + read-write + + + SLC0_TXLINK_STOP + 28 + 1 + read-write + + + SLC0_TXLINK_START + 29 + 1 + read-write + + + SLC0_TXLINK_RESTART + 30 + 1 + read-write + + + SLC0_TXLINK_PARK + 31 + 1 + read-only + + + + + _1RX_LINK + 0x44 + 0x20 + 0x00100000 + + + SLC1_RXLINK_ADDR + 0 + 20 + read-write + + + SLC1_BT_PACKET + 20 + 1 + read-write + + + SLC1_RXLINK_STOP + 28 + 1 + read-write + + + SLC1_RXLINK_START + 29 + 1 + read-write + + + SLC1_RXLINK_RESTART + 30 + 1 + read-write + + + SLC1_RXLINK_PARK + 31 + 1 + read-only + + + + + _1TX_LINK + 0x48 + 0x20 + + + SLC1_TXLINK_ADDR + 0 + 20 + read-write + + + SLC1_TXLINK_STOP + 28 + 1 + read-write + + + SLC1_TXLINK_START + 29 + 1 + read-write + + + SLC1_TXLINK_RESTART + 30 + 1 + read-write + + + SLC1_TXLINK_PARK + 31 + 1 + read-only + + + + + INTVEC_TOHOST + 0x4C + 0x20 + + + SLC0_TOHOST_INTVEC + 0 + 8 + write-only + + + SLC1_TOHOST_INTVEC + 16 + 8 + write-only + + + + + _0TOKEN0 + 0x50 + 0x20 + + + SLC0_TOKEN0_WDATA + 0 + 12 + write-only + + + SLC0_TOKEN0_WR + 12 + 1 + write-only + + + SLC0_TOKEN0_INC + 13 + 1 + write-only + + + SLC0_TOKEN0_INC_MORE + 14 + 1 + write-only + + + SLC0_TOKEN0 + 16 + 12 + read-only + + + + + _0TOKEN1 + 0x54 + 0x20 + + + SLC0_TOKEN1_WDATA + 0 + 12 + write-only + + + SLC0_TOKEN1_WR + 12 + 1 + write-only + + + SLC0_TOKEN1_INC + 13 + 1 + write-only + + + SLC0_TOKEN1_INC_MORE + 14 + 1 + write-only + + + SLC0_TOKEN1 + 16 + 12 + read-only + + + + + _1TOKEN0 + 0x58 + 0x20 + + + SLC1_TOKEN0_WDATA + 0 + 12 + write-only + + + SLC1_TOKEN0_WR + 12 + 1 + write-only + + + SLC1_TOKEN0_INC + 13 + 1 + write-only + + + SLC1_TOKEN0_INC_MORE + 14 + 1 + write-only + + + SLC1_TOKEN0 + 16 + 12 + read-only + + + + + _1TOKEN1 + 0x5C + 0x20 + + + SLC1_TOKEN1_WDATA + 0 + 12 + write-only + + + SLC1_TOKEN1_WR + 12 + 1 + write-only + + + SLC1_TOKEN1_INC + 13 + 1 + write-only + + + SLC1_TOKEN1_INC_MORE + 14 + 1 + write-only + + + SLC1_TOKEN1 + 16 + 12 + read-only + + + + + CONF1 + 0x60 + 0x20 + 0x00300078 + + + SLC0_CHECK_OWNER + 0 + 1 + read-write + + + SLC0_TX_CHECK_SUM_EN + 1 + 1 + read-write + + + SLC0_RX_CHECK_SUM_EN + 2 + 1 + read-write + + + CMD_HOLD_EN + 3 + 1 + read-write + + + SLC0_LEN_AUTO_CLR + 4 + 1 + read-write + + + SLC0_TX_STITCH_EN + 5 + 1 + read-write + + + SLC0_RX_STITCH_EN + 6 + 1 + read-write + + + SLC1_CHECK_OWNER + 16 + 1 + read-write + + + SLC1_TX_CHECK_SUM_EN + 17 + 1 + read-write + + + SLC1_RX_CHECK_SUM_EN + 18 + 1 + read-write + + + HOST_INT_LEVEL_SEL + 19 + 1 + read-write + + + SLC1_TX_STITCH_EN + 20 + 1 + read-write + + + SLC1_RX_STITCH_EN + 21 + 1 + read-write + + + CLK_EN + 22 + 1 + read-write + + + + + _0_STATE0 + 0x64 + 0x20 + + + SLC0_STATE0 + 0 + 32 + read-only + + + + + _0_STATE1 + 0x68 + 0x20 + + + SLC0_STATE1 + 0 + 32 + read-only + + + + + _1_STATE0 + 0x6C + 0x20 + + + SLC1_STATE0 + 0 + 32 + read-only + + + + + _1_STATE1 + 0x70 + 0x20 + + + SLC1_STATE1 + 0 + 32 + read-only + + + + + BRIDGE_CONF + 0x74 + 0x20 + 0x000A7720 + + + TXEOF_ENA + 0 + 6 + read-write + + + FIFO_MAP_ENA + 8 + 4 + read-write + + + SLC0_TX_DUMMY_MODE + 12 + 1 + read-write + + + HDA_MAP_128K + 13 + 1 + read-write + + + SLC1_TX_DUMMY_MODE + 14 + 1 + read-write + + + TX_PUSH_IDLE_NUM + 16 + 16 + read-write + + + + + _0_TO_EOF_DES_ADDR + 0x78 + 0x20 + + + SLC0_TO_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _0_TX_EOF_DES_ADDR + 0x7C + 0x20 + + + SLC0_TX_SUC_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _0_TO_EOF_BFR_DES_ADDR + 0x80 + 0x20 + + + SLC0_TO_EOF_BFR_DES_ADDR + 0 + 32 + read-only + + + + + _1_TO_EOF_DES_ADDR + 0x84 + 0x20 + + + SLC1_TO_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _1_TX_EOF_DES_ADDR + 0x88 + 0x20 + + + SLC1_TX_SUC_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _1_TO_EOF_BFR_DES_ADDR + 0x8C + 0x20 + + + SLC1_TO_EOF_BFR_DES_ADDR + 0 + 32 + read-only + + + + + AHB_TEST + 0x90 + 0x20 + + + AHB_TESTMODE + 0 + 3 + read-write + + + AHB_TESTADDR + 4 + 2 + read-write + + + + + SDIO_ST + 0x94 + 0x20 + + + CMD_ST + 0 + 3 + read-only + + + FUNC_ST + 4 + 4 + read-only + + + SDIO_WAKEUP + 8 + 1 + read-only + + + BUS_ST + 12 + 3 + read-only + + + FUNC1_ACC_STATE + 16 + 5 + read-only + + + FUNC2_ACC_STATE + 24 + 5 + read-only + + + + + RX_DSCR_CONF + 0x98 + 0x20 + 0x101B101A + + + SLC0_TOKEN_NO_REPLACE + 0 + 1 + read-write + + + SLC0_INFOR_NO_REPLACE + 1 + 1 + read-write + + + SLC0_RX_FILL_MODE + 2 + 1 + read-write + + + SLC0_RX_EOF_MODE + 3 + 1 + read-write + + + SLC0_RX_FILL_EN + 4 + 1 + read-write + + + SLC0_RD_RETRY_THRESHOLD + 5 + 11 + read-write + + + SLC1_TOKEN_NO_REPLACE + 16 + 1 + read-write + + + SLC1_INFOR_NO_REPLACE + 17 + 1 + read-write + + + SLC1_RX_FILL_MODE + 18 + 1 + read-write + + + SLC1_RX_EOF_MODE + 19 + 1 + read-write + + + SLC1_RX_FILL_EN + 20 + 1 + read-write + + + SLC1_RD_RETRY_THRESHOLD + 21 + 11 + read-write + + + + + _0_TXLINK_DSCR + 0x9C + 0x20 + + + SLC0_TXLINK_DSCR + 0 + 32 + read-only + + + + + _0_TXLINK_DSCR_BF0 + 0xA0 + 0x20 + + + SLC0_TXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _0_TXLINK_DSCR_BF1 + 0xA4 + 0x20 + + + SLC0_TXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _0_RXLINK_DSCR + 0xA8 + 0x20 + + + SLC0_RXLINK_DSCR + 0 + 32 + read-only + + + + + _0_RXLINK_DSCR_BF0 + 0xAC + 0x20 + + + SLC0_RXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _0_RXLINK_DSCR_BF1 + 0xB0 + 0x20 + + + SLC0_RXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _1_TXLINK_DSCR + 0xB4 + 0x20 + + + SLC1_TXLINK_DSCR + 0 + 32 + read-only + + + + + _1_TXLINK_DSCR_BF0 + 0xB8 + 0x20 + + + SLC1_TXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _1_TXLINK_DSCR_BF1 + 0xBC + 0x20 + + + SLC1_TXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _1_RXLINK_DSCR + 0xC0 + 0x20 + + + SLC1_RXLINK_DSCR + 0 + 32 + read-only + + + + + _1_RXLINK_DSCR_BF0 + 0xC4 + 0x20 + + + SLC1_RXLINK_DSCR_BF0 + 0 + 32 + read-only + + + + + _1_RXLINK_DSCR_BF1 + 0xC8 + 0x20 + + + SLC1_RXLINK_DSCR_BF1 + 0 + 32 + read-only + + + + + _0_TX_ERREOF_DES_ADDR + 0xCC + 0x20 + + + SLC0_TX_ERR_EOF_DES_ADDR + 0 + 32 + read-only + + + + + _1_TX_ERREOF_DES_ADDR + 0xD0 + 0x20 + + + SLC1_TX_ERR_EOF_DES_ADDR + 0 + 32 + read-only + + + + + TOKEN_LAT + 0xD4 + 0x20 + + + SLC0_TOKEN + 0 + 12 + read-only + + + SLC1_TOKEN + 16 + 12 + read-only + + + + + TX_DSCR_CONF + 0xD8 + 0x20 + 0x00000080 + + + WR_RETRY_THRESHOLD + 0 + 11 + read-write + + + + + CMD_INFOR0 + 0xDC + 0x20 + + + CMD_CONTENT0 + 0 + 32 + read-only + + + + + CMD_INFOR1 + 0xE0 + 0x20 + + + CMD_CONTENT1 + 0 + 32 + read-only + + + + + _0_LEN_CONF + 0xE4 + 0x20 + + + SLC0_LEN_WDATA + 0 + 20 + write-only + + + SLC0_LEN_WR + 20 + 1 + write-only + + + SLC0_LEN_INC + 21 + 1 + write-only + + + SLC0_LEN_INC_MORE + 22 + 1 + write-only + + + SLC0_RX_PACKET_LOAD_EN + 23 + 1 + read-write + + + SLC0_TX_PACKET_LOAD_EN + 24 + 1 + read-write + + + SLC0_RX_GET_USED_DSCR + 25 + 1 + write-only + + + SLC0_TX_GET_USED_DSCR + 26 + 1 + write-only + + + SLC0_RX_NEW_PKT_IND + 27 + 1 + read-only + + + SLC0_TX_NEW_PKT_IND + 28 + 1 + read-only + + + + + _0_LENGTH + 0xE8 + 0x20 + + + SLC0_LEN + 0 + 20 + read-only + + + + + _0_TXPKT_H_DSCR + 0xEC + 0x20 + + + SLC0_TX_PKT_H_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_TXPKT_E_DSCR + 0xF0 + 0x20 + + + SLC0_TX_PKT_E_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_RXPKT_H_DSCR + 0xF4 + 0x20 + + + SLC0_RX_PKT_H_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_RXPKT_E_DSCR + 0xF8 + 0x20 + + + SLC0_RX_PKT_E_DSCR_ADDR + 0 + 32 + read-write + + + + + _0_TXPKTU_H_DSCR + 0xFC + 0x20 + + + SLC0_TX_PKT_START_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_TXPKTU_E_DSCR + 0x100 + 0x20 + + + SLC0_TX_PKT_END_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_RXPKTU_H_DSCR + 0x104 + 0x20 + + + SLC0_RX_PKT_START_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_RXPKTU_E_DSCR + 0x108 + 0x20 + + + SLC0_RX_PKT_END_DSCR_ADDR + 0 + 32 + read-only + + + + + SEQ_POSITION + 0x114 + 0x20 + 0x00000509 + + + SLC0_SEQ_POSITION + 0 + 8 + read-write + + + SLC1_SEQ_POSITION + 8 + 8 + read-write + + + + + _0_DSCR_REC_CONF + 0x118 + 0x20 + 0x000003FF + + + SLC0_RX_DSCR_REC_LIM + 0 + 10 + read-write + + + + + SDIO_CRC_ST0 + 0x11C + 0x20 + + + DAT0_CRC_ERR_CNT + 0 + 8 + read-only + + + DAT1_CRC_ERR_CNT + 8 + 8 + read-only + + + DAT2_CRC_ERR_CNT + 16 + 8 + read-only + + + DAT3_CRC_ERR_CNT + 24 + 8 + read-only + + + + + SDIO_CRC_ST1 + 0x120 + 0x20 + + + CMD_CRC_ERR_CNT + 0 + 8 + read-only + + + ERR_CNT_CLR + 31 + 1 + read-write + + + + + _0_EOF_START_DES + 0x124 + 0x20 + + + SLC0_EOF_START_DES_ADDR + 0 + 32 + read-only + + + + + _0_PUSH_DSCR_ADDR + 0x128 + 0x20 + + + SLC0_RX_PUSH_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_DONE_DSCR_ADDR + 0x12C + 0x20 + + + SLC0_RX_DONE_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_SUB_START_DES + 0x130 + 0x20 + + + SLC0_SUB_PAC_START_DSCR_ADDR + 0 + 32 + read-only + + + + + _0_DSCR_CNT + 0x134 + 0x20 + + + SLC0_RX_DSCR_CNT_LAT + 0 + 10 + read-only + + + SLC0_RX_GET_EOF_OCC + 16 + 1 + read-only + + + + + _0_LEN_LIM_CONF + 0x138 + 0x20 + 0x00005400 + + + SLC0_LEN_LIM + 0 + 20 + read-write + + + + + _0INT_ST1 + 0x13C + 0x20 + + + FRHOST_BIT0_INT_ST1 + 0 + 1 + read-only + + + FRHOST_BIT1_INT_ST1 + 1 + 1 + read-only + + + FRHOST_BIT2_INT_ST1 + 2 + 1 + read-only + + + FRHOST_BIT3_INT_ST1 + 3 + 1 + read-only + + + FRHOST_BIT4_INT_ST1 + 4 + 1 + read-only + + + FRHOST_BIT5_INT_ST1 + 5 + 1 + read-only + + + FRHOST_BIT6_INT_ST1 + 6 + 1 + read-only + + + FRHOST_BIT7_INT_ST1 + 7 + 1 + read-only + + + SLC0_RX_START_INT_ST1 + 8 + 1 + read-only + + + SLC0_TX_START_INT_ST1 + 9 + 1 + read-only + + + SLC0_RX_UDF_INT_ST1 + 10 + 1 + read-only + + + SLC0_TX_OVF_INT_ST1 + 11 + 1 + read-only + + + SLC0_TOKEN0_1TO0_INT_ST1 + 12 + 1 + read-only + + + SLC0_TOKEN1_1TO0_INT_ST1 + 13 + 1 + read-only + + + SLC0_TX_DONE_INT_ST1 + 14 + 1 + read-only + + + SLC0_TX_SUC_EOF_INT_ST1 + 15 + 1 + read-only + + + SLC0_RX_DONE_INT_ST1 + 16 + 1 + read-only + + + SLC0_RX_EOF_INT_ST1 + 17 + 1 + read-only + + + SLC0_TOHOST_INT_ST1 + 18 + 1 + read-only + + + SLC0_TX_DSCR_ERR_INT_ST1 + 19 + 1 + read-only + + + SLC0_RX_DSCR_ERR_INT_ST1 + 20 + 1 + read-only + + + SLC0_TX_DSCR_EMPTY_INT_ST1 + 21 + 1 + read-only + + + SLC0_HOST_RD_ACK_INT_ST1 + 22 + 1 + read-only + + + SLC0_WR_RETRY_DONE_INT_ST1 + 23 + 1 + read-only + + + SLC0_TX_ERR_EOF_INT_ST1 + 24 + 1 + read-only + + + CMD_DTC_INT_ST1 + 25 + 1 + read-only + + + SLC0_RX_QUICK_EOF_INT_ST1 + 26 + 1 + read-only + + + + + _0INT_ENA1 + 0x140 + 0x20 + + + FRHOST_BIT0_INT_ENA1 + 0 + 1 + read-write + + + FRHOST_BIT1_INT_ENA1 + 1 + 1 + read-write + + + FRHOST_BIT2_INT_ENA1 + 2 + 1 + read-write + + + FRHOST_BIT3_INT_ENA1 + 3 + 1 + read-write + + + FRHOST_BIT4_INT_ENA1 + 4 + 1 + read-write + + + FRHOST_BIT5_INT_ENA1 + 5 + 1 + read-write + + + FRHOST_BIT6_INT_ENA1 + 6 + 1 + read-write + + + FRHOST_BIT7_INT_ENA1 + 7 + 1 + read-write + + + SLC0_RX_START_INT_ENA1 + 8 + 1 + read-write + + + SLC0_TX_START_INT_ENA1 + 9 + 1 + read-write + + + SLC0_RX_UDF_INT_ENA1 + 10 + 1 + read-write + + + SLC0_TX_OVF_INT_ENA1 + 11 + 1 + read-write + + + SLC0_TOKEN0_1TO0_INT_ENA1 + 12 + 1 + read-write + + + SLC0_TOKEN1_1TO0_INT_ENA1 + 13 + 1 + read-write + + + SLC0_TX_DONE_INT_ENA1 + 14 + 1 + read-write + + + SLC0_TX_SUC_EOF_INT_ENA1 + 15 + 1 + read-write + + + SLC0_RX_DONE_INT_ENA1 + 16 + 1 + read-write + + + SLC0_RX_EOF_INT_ENA1 + 17 + 1 + read-write + + + SLC0_TOHOST_INT_ENA1 + 18 + 1 + read-write + + + SLC0_TX_DSCR_ERR_INT_ENA1 + 19 + 1 + read-write + + + SLC0_RX_DSCR_ERR_INT_ENA1 + 20 + 1 + read-write + + + SLC0_TX_DSCR_EMPTY_INT_ENA1 + 21 + 1 + read-write + + + SLC0_HOST_RD_ACK_INT_ENA1 + 22 + 1 + read-write + + + SLC0_WR_RETRY_DONE_INT_ENA1 + 23 + 1 + read-write + + + SLC0_TX_ERR_EOF_INT_ENA1 + 24 + 1 + read-write + + + CMD_DTC_INT_ENA1 + 25 + 1 + read-write + + + SLC0_RX_QUICK_EOF_INT_ENA1 + 26 + 1 + read-write + + + + + _1INT_ST1 + 0x144 + 0x20 + + + FRHOST_BIT8_INT_ST1 + 0 + 1 + read-only + + + FRHOST_BIT9_INT_ST1 + 1 + 1 + read-only + + + FRHOST_BIT10_INT_ST1 + 2 + 1 + read-only + + + FRHOST_BIT11_INT_ST1 + 3 + 1 + read-only + + + FRHOST_BIT12_INT_ST1 + 4 + 1 + read-only + + + FRHOST_BIT13_INT_ST1 + 5 + 1 + read-only + + + FRHOST_BIT14_INT_ST1 + 6 + 1 + read-only + + + FRHOST_BIT15_INT_ST1 + 7 + 1 + read-only + + + SLC1_RX_START_INT_ST1 + 8 + 1 + read-only + + + SLC1_TX_START_INT_ST1 + 9 + 1 + read-only + + + SLC1_RX_UDF_INT_ST1 + 10 + 1 + read-only + + + SLC1_TX_OVF_INT_ST1 + 11 + 1 + read-only + + + SLC1_TOKEN0_1TO0_INT_ST1 + 12 + 1 + read-only + + + SLC1_TOKEN1_1TO0_INT_ST1 + 13 + 1 + read-only + + + SLC1_TX_DONE_INT_ST1 + 14 + 1 + read-only + + + SLC1_TX_SUC_EOF_INT_ST1 + 15 + 1 + read-only + + + SLC1_RX_DONE_INT_ST1 + 16 + 1 + read-only + + + SLC1_RX_EOF_INT_ST1 + 17 + 1 + read-only + + + SLC1_TOHOST_INT_ST1 + 18 + 1 + read-only + + + SLC1_TX_DSCR_ERR_INT_ST1 + 19 + 1 + read-only + + + SLC1_RX_DSCR_ERR_INT_ST1 + 20 + 1 + read-only + + + SLC1_TX_DSCR_EMPTY_INT_ST1 + 21 + 1 + read-only + + + SLC1_HOST_RD_ACK_INT_ST1 + 22 + 1 + read-only + + + SLC1_WR_RETRY_DONE_INT_ST1 + 23 + 1 + read-only + + + SLC1_TX_ERR_EOF_INT_ST1 + 24 + 1 + read-only + + + + + _1INT_ENA1 + 0x148 + 0x20 + + + FRHOST_BIT8_INT_ENA1 + 0 + 1 + read-write + + + FRHOST_BIT9_INT_ENA1 + 1 + 1 + read-write + + + FRHOST_BIT10_INT_ENA1 + 2 + 1 + read-write + + + FRHOST_BIT11_INT_ENA1 + 3 + 1 + read-write + + + FRHOST_BIT12_INT_ENA1 + 4 + 1 + read-write + + + FRHOST_BIT13_INT_ENA1 + 5 + 1 + read-write + + + FRHOST_BIT14_INT_ENA1 + 6 + 1 + read-write + + + FRHOST_BIT15_INT_ENA1 + 7 + 1 + read-write + + + SLC1_RX_START_INT_ENA1 + 8 + 1 + read-write + + + SLC1_TX_START_INT_ENA1 + 9 + 1 + read-write + + + SLC1_RX_UDF_INT_ENA1 + 10 + 1 + read-write + + + SLC1_TX_OVF_INT_ENA1 + 11 + 1 + read-write + + + SLC1_TOKEN0_1TO0_INT_ENA1 + 12 + 1 + read-write + + + SLC1_TOKEN1_1TO0_INT_ENA1 + 13 + 1 + read-write + + + SLC1_TX_DONE_INT_ENA1 + 14 + 1 + read-write + + + SLC1_TX_SUC_EOF_INT_ENA1 + 15 + 1 + read-write + + + SLC1_RX_DONE_INT_ENA1 + 16 + 1 + read-write + + + SLC1_RX_EOF_INT_ENA1 + 17 + 1 + read-write + + + SLC1_TOHOST_INT_ENA1 + 18 + 1 + read-write + + + SLC1_TX_DSCR_ERR_INT_ENA1 + 19 + 1 + read-write + + + SLC1_RX_DSCR_ERR_INT_ENA1 + 20 + 1 + read-write + + + SLC1_TX_DSCR_EMPTY_INT_ENA1 + 21 + 1 + read-write + + + SLC1_HOST_RD_ACK_INT_ENA1 + 22 + 1 + read-write + + + SLC1_WR_RETRY_DONE_INT_ENA1 + 23 + 1 + read-write + + + SLC1_TX_ERR_EOF_INT_ENA1 + 24 + 1 + read-write + + + + + DATE + 0x1F8 + 0x20 + 0x16022500 + + + DATE + 0 + 32 + read-write + + + + + ID + 0x1FC + 0x20 + 0x00000100 + + + ID + 0 + 32 + read-write + + + + + + + SLCHOST + Peripheral SLCHOST + SLCHOST + 0x3FF55000 + + 0x0 + 0x104 + registers + + + + HOST_SLCHOST_FUNC2_0 + 0x10 + 0x20 + + + HOST_SLC_FUNC2_INT + 24 + 1 + read-write + + + + + HOST_SLCHOST_FUNC2_1 + 0x14 + 0x20 + + + HOST_SLC_FUNC2_INT_EN + 0 + 1 + read-write + + + + + HOST_SLCHOST_FUNC2_2 + 0x20 + 0x20 + 0x00000001 + + + HOST_SLC_FUNC1_MDSTAT + 0 + 1 + read-write + + + + + HOST_SLCHOST_GPIO_STATUS0 + 0x34 + 0x20 + + + HOST_GPIO_SDIO_INT0 + 0 + 32 + read-only + + + + + HOST_SLCHOST_GPIO_STATUS1 + 0x38 + 0x20 + + + HOST_GPIO_SDIO_INT1 + 0 + 8 + read-only + + + + + HOST_SLCHOST_GPIO_IN0 + 0x3C + 0x20 + + + HOST_GPIO_SDIO_IN0 + 0 + 32 + read-only + + + + + HOST_SLCHOST_GPIO_IN1 + 0x40 + 0x20 + + + HOST_GPIO_SDIO_IN1 + 0 + 8 + read-only + + + + + HOST_SLC0HOST_TOKEN_RDATA + 0x44 + 0x20 + + + HOST_SLC0_TOKEN0 + 0 + 12 + read-only + + + HOST_SLC0_RX_PF_VALID + 12 + 1 + read-only + + + HOST_HOSTSLC0_TOKEN1 + 16 + 12 + read-only + + + HOST_SLC0_RX_PF_EOF + 28 + 4 + read-only + + + + + HOST_SLC0_HOST_PF + 0x48 + 0x20 + + + HOST_SLC0_PF_DATA + 0 + 32 + read-only + + + + + HOST_SLC1_HOST_PF + 0x4C + 0x20 + + + HOST_SLC1_PF_DATA + 0 + 32 + read-only + + + + + HOST_SLC0HOST_INT_RAW + 0x50 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_RAW + 0 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT1_INT_RAW + 1 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT2_INT_RAW + 2 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT3_INT_RAW + 3 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT4_INT_RAW + 4 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT5_INT_RAW + 5 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT6_INT_RAW + 6 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT7_INT_RAW + 7 + 1 + read-only + + + HOST_SLC0_TOKEN0_1TO0_INT_RAW + 8 + 1 + read-only + + + HOST_SLC0_TOKEN1_1TO0_INT_RAW + 9 + 1 + read-only + + + HOST_SLC0_TOKEN0_0TO1_INT_RAW + 10 + 1 + read-only + + + HOST_SLC0_TOKEN1_0TO1_INT_RAW + 11 + 1 + read-only + + + HOST_SLC0HOST_RX_SOF_INT_RAW + 12 + 1 + read-only + + + HOST_SLC0HOST_RX_EOF_INT_RAW + 13 + 1 + read-only + + + HOST_SLC0HOST_RX_START_INT_RAW + 14 + 1 + read-only + + + HOST_SLC0HOST_TX_START_INT_RAW + 15 + 1 + read-only + + + HOST_SLC0_RX_UDF_INT_RAW + 16 + 1 + read-only + + + HOST_SLC0_TX_OVF_INT_RAW + 17 + 1 + read-only + + + HOST_SLC0_RX_PF_VALID_INT_RAW + 18 + 1 + read-only + + + HOST_SLC0_EXT_BIT0_INT_RAW + 19 + 1 + read-only + + + HOST_SLC0_EXT_BIT1_INT_RAW + 20 + 1 + read-only + + + HOST_SLC0_EXT_BIT2_INT_RAW + 21 + 1 + read-only + + + HOST_SLC0_EXT_BIT3_INT_RAW + 22 + 1 + read-only + + + HOST_SLC0_RX_NEW_PACKET_INT_RAW + 23 + 1 + read-only + + + HOST_SLC0_HOST_RD_RETRY_INT_RAW + 24 + 1 + read-only + + + HOST_GPIO_SDIO_INT_RAW + 25 + 1 + read-only + + + + + HOST_SLC1HOST_INT_RAW + 0x54 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_RAW + 0 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT1_INT_RAW + 1 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT2_INT_RAW + 2 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT3_INT_RAW + 3 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT4_INT_RAW + 4 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT5_INT_RAW + 5 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT6_INT_RAW + 6 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT7_INT_RAW + 7 + 1 + read-only + + + HOST_SLC1_TOKEN0_1TO0_INT_RAW + 8 + 1 + read-only + + + HOST_SLC1_TOKEN1_1TO0_INT_RAW + 9 + 1 + read-only + + + HOST_SLC1_TOKEN0_0TO1_INT_RAW + 10 + 1 + read-only + + + HOST_SLC1_TOKEN1_0TO1_INT_RAW + 11 + 1 + read-only + + + HOST_SLC1HOST_RX_SOF_INT_RAW + 12 + 1 + read-only + + + HOST_SLC1HOST_RX_EOF_INT_RAW + 13 + 1 + read-only + + + HOST_SLC1HOST_RX_START_INT_RAW + 14 + 1 + read-only + + + HOST_SLC1HOST_TX_START_INT_RAW + 15 + 1 + read-only + + + HOST_SLC1_RX_UDF_INT_RAW + 16 + 1 + read-only + + + HOST_SLC1_TX_OVF_INT_RAW + 17 + 1 + read-only + + + HOST_SLC1_RX_PF_VALID_INT_RAW + 18 + 1 + read-only + + + HOST_SLC1_EXT_BIT0_INT_RAW + 19 + 1 + read-only + + + HOST_SLC1_EXT_BIT1_INT_RAW + 20 + 1 + read-only + + + HOST_SLC1_EXT_BIT2_INT_RAW + 21 + 1 + read-only + + + HOST_SLC1_EXT_BIT3_INT_RAW + 22 + 1 + read-only + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_RAW + 23 + 1 + read-only + + + HOST_SLC1_HOST_RD_RETRY_INT_RAW + 24 + 1 + read-only + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_RAW + 25 + 1 + read-only + + + + + HOST_SLC0HOST_INT_ST + 0x58 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_ST + 0 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT1_INT_ST + 1 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT2_INT_ST + 2 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT3_INT_ST + 3 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT4_INT_ST + 4 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT5_INT_ST + 5 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT6_INT_ST + 6 + 1 + read-only + + + HOST_SLC0_TOHOST_BIT7_INT_ST + 7 + 1 + read-only + + + HOST_SLC0_TOKEN0_1TO0_INT_ST + 8 + 1 + read-only + + + HOST_SLC0_TOKEN1_1TO0_INT_ST + 9 + 1 + read-only + + + HOST_SLC0_TOKEN0_0TO1_INT_ST + 10 + 1 + read-only + + + HOST_SLC0_TOKEN1_0TO1_INT_ST + 11 + 1 + read-only + + + HOST_SLC0HOST_RX_SOF_INT_ST + 12 + 1 + read-only + + + HOST_SLC0HOST_RX_EOF_INT_ST + 13 + 1 + read-only + + + HOST_SLC0HOST_RX_START_INT_ST + 14 + 1 + read-only + + + HOST_SLC0HOST_TX_START_INT_ST + 15 + 1 + read-only + + + HOST_SLC0_RX_UDF_INT_ST + 16 + 1 + read-only + + + HOST_SLC0_TX_OVF_INT_ST + 17 + 1 + read-only + + + HOST_SLC0_RX_PF_VALID_INT_ST + 18 + 1 + read-only + + + HOST_SLC0_EXT_BIT0_INT_ST + 19 + 1 + read-only + + + HOST_SLC0_EXT_BIT1_INT_ST + 20 + 1 + read-only + + + HOST_SLC0_EXT_BIT2_INT_ST + 21 + 1 + read-only + + + HOST_SLC0_EXT_BIT3_INT_ST + 22 + 1 + read-only + + + HOST_SLC0_RX_NEW_PACKET_INT_ST + 23 + 1 + read-only + + + HOST_SLC0_HOST_RD_RETRY_INT_ST + 24 + 1 + read-only + + + HOST_GPIO_SDIO_INT_ST + 25 + 1 + read-only + + + + + HOST_SLC1HOST_INT_ST + 0x5C + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_ST + 0 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT1_INT_ST + 1 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT2_INT_ST + 2 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT3_INT_ST + 3 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT4_INT_ST + 4 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT5_INT_ST + 5 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT6_INT_ST + 6 + 1 + read-only + + + HOST_SLC1_TOHOST_BIT7_INT_ST + 7 + 1 + read-only + + + HOST_SLC1_TOKEN0_1TO0_INT_ST + 8 + 1 + read-only + + + HOST_SLC1_TOKEN1_1TO0_INT_ST + 9 + 1 + read-only + + + HOST_SLC1_TOKEN0_0TO1_INT_ST + 10 + 1 + read-only + + + HOST_SLC1_TOKEN1_0TO1_INT_ST + 11 + 1 + read-only + + + HOST_SLC1HOST_RX_SOF_INT_ST + 12 + 1 + read-only + + + HOST_SLC1HOST_RX_EOF_INT_ST + 13 + 1 + read-only + + + HOST_SLC1HOST_RX_START_INT_ST + 14 + 1 + read-only + + + HOST_SLC1HOST_TX_START_INT_ST + 15 + 1 + read-only + + + HOST_SLC1_RX_UDF_INT_ST + 16 + 1 + read-only + + + HOST_SLC1_TX_OVF_INT_ST + 17 + 1 + read-only + + + HOST_SLC1_RX_PF_VALID_INT_ST + 18 + 1 + read-only + + + HOST_SLC1_EXT_BIT0_INT_ST + 19 + 1 + read-only + + + HOST_SLC1_EXT_BIT1_INT_ST + 20 + 1 + read-only + + + HOST_SLC1_EXT_BIT2_INT_ST + 21 + 1 + read-only + + + HOST_SLC1_EXT_BIT3_INT_ST + 22 + 1 + read-only + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_ST + 23 + 1 + read-only + + + HOST_SLC1_HOST_RD_RETRY_INT_ST + 24 + 1 + read-only + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_ST + 25 + 1 + read-only + + + + + HOST_SLCHOST_PKT_LEN + 0x60 + 0x20 + + + HOST_HOSTSLC0_LEN + 0 + 20 + read-only + + + HOST_HOSTSLC0_LEN_CHECK + 20 + 12 + read-only + + + + + HOST_SLCHOST_STATE_W0 + 0x64 + 0x20 + + + HOST_SLCHOST_STATE0 + 0 + 8 + read-only + + + HOST_SLCHOST_STATE1 + 8 + 8 + read-only + + + HOST_SLCHOST_STATE2 + 16 + 8 + read-only + + + HOST_SLCHOST_STATE3 + 24 + 8 + read-only + + + + + HOST_SLCHOST_STATE_W1 + 0x68 + 0x20 + + + HOST_SLCHOST_STATE4 + 0 + 8 + read-only + + + HOST_SLCHOST_STATE5 + 8 + 8 + read-only + + + HOST_SLCHOST_STATE6 + 16 + 8 + read-only + + + HOST_SLCHOST_STATE7 + 24 + 8 + read-only + + + + + HOST_SLCHOST_CONF_W0 + 0x6C + 0x20 + + + HOST_SLCHOST_CONF0 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF1 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF2 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF3 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W1 + 0x70 + 0x20 + + + HOST_SLCHOST_CONF4 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF5 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF6 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF7 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W2 + 0x74 + 0x20 + + + HOST_SLCHOST_CONF8 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF9 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF10 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF11 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W3 + 0x78 + 0x20 + 0x000000C0 + + + HOST_SLCHOST_CONF12 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF13 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF14 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF15 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W4 + 0x7C + 0x20 + 0x000001FF + + + HOST_SLCHOST_CONF16 + SLC timeout value + 0 + 8 + read-write + + + HOST_SLCHOST_CONF17 + SLC timeout enable + 8 + 8 + read-write + + + HOST_SLCHOST_CONF18 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF19 + Interrupt to target CPU + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W5 + 0x80 + 0x20 + + + HOST_SLCHOST_CONF20 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF21 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF22 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF23 + 24 + 8 + read-write + + + + + HOST_SLCHOST_WIN_CMD + 0x84 + 0x20 + + + HOST_SLCHOST_CONF_W6 + 0x88 + 0x20 + + + HOST_SLCHOST_CONF24 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF25 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF26 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF27 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W7 + 0x8C + 0x20 + + + HOST_SLCHOST_CONF28 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF29 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF30 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF31 + 24 + 8 + read-write + + + + + HOST_SLCHOST_PKT_LEN0 + 0x90 + 0x20 + + + HOST_HOSTSLC0_LEN0 + 0 + 20 + read-only + + + + + HOST_SLCHOST_PKT_LEN1 + 0x94 + 0x20 + + + HOST_HOSTSLC0_LEN1 + 0 + 20 + read-only + + + + + HOST_SLCHOST_PKT_LEN2 + 0x98 + 0x20 + + + HOST_HOSTSLC0_LEN2 + 0 + 20 + read-only + + + + + HOST_SLCHOST_CONF_W8 + 0x9C + 0x20 + + + HOST_SLCHOST_CONF32 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF33 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF34 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF35 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W9 + 0xA0 + 0x20 + + + HOST_SLCHOST_CONF36 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF37 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF38 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF39 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W10 + 0xA4 + 0x20 + + + HOST_SLCHOST_CONF40 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF41 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF42 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF43 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W11 + 0xA8 + 0x20 + + + HOST_SLCHOST_CONF44 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF45 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF46 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF47 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W12 + 0xAC + 0x20 + + + HOST_SLCHOST_CONF48 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF49 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF50 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF51 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W13 + 0xB0 + 0x20 + + + HOST_SLCHOST_CONF52 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF53 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF54 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF55 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W14 + 0xB4 + 0x20 + + + HOST_SLCHOST_CONF56 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF57 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF58 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF59 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CONF_W15 + 0xB8 + 0x20 + + + HOST_SLCHOST_CONF60 + 0 + 8 + read-write + + + HOST_SLCHOST_CONF61 + 8 + 8 + read-write + + + HOST_SLCHOST_CONF62 + 16 + 8 + read-write + + + HOST_SLCHOST_CONF63 + 24 + 8 + read-write + + + + + HOST_SLCHOST_CHECK_SUM0 + 0xBC + 0x20 + + + HOST_SLCHOST_CHECK_SUM0 + 0 + 32 + read-only + + + + + HOST_SLCHOST_CHECK_SUM1 + 0xC0 + 0x20 + + + HOST_SLCHOST_CHECK_SUM1 + 0 + 32 + read-only + + + + + HOST_SLC1HOST_TOKEN_RDATA + 0xC4 + 0x20 + + + HOST_SLC1_TOKEN0 + 0 + 12 + read-only + + + HOST_SLC1_RX_PF_VALID + 12 + 1 + read-only + + + HOST_HOSTSLC1_TOKEN1 + 16 + 12 + read-only + + + HOST_SLC1_RX_PF_EOF + 28 + 4 + read-only + + + + + HOST_SLC0HOST_TOKEN_WDATA + 0xC8 + 0x20 + + + HOST_SLC0HOST_TOKEN0_WD + 0 + 12 + read-write + + + HOST_SLC0HOST_TOKEN1_WD + 16 + 12 + read-write + + + + + HOST_SLC1HOST_TOKEN_WDATA + 0xCC + 0x20 + + + HOST_SLC1HOST_TOKEN0_WD + 0 + 12 + read-write + + + HOST_SLC1HOST_TOKEN1_WD + 16 + 12 + read-write + + + + + HOST_SLCHOST_TOKEN_CON + 0xD0 + 0x20 + + + HOST_SLC0HOST_TOKEN0_DEC + 0 + 1 + write-only + + + HOST_SLC0HOST_TOKEN1_DEC + 1 + 1 + write-only + + + HOST_SLC0HOST_TOKEN0_WR + 2 + 1 + write-only + + + HOST_SLC0HOST_TOKEN1_WR + 3 + 1 + write-only + + + HOST_SLC1HOST_TOKEN0_DEC + 4 + 1 + write-only + + + HOST_SLC1HOST_TOKEN1_DEC + 5 + 1 + write-only + + + HOST_SLC1HOST_TOKEN0_WR + 6 + 1 + write-only + + + HOST_SLC1HOST_TOKEN1_WR + 7 + 1 + write-only + + + HOST_SLC0HOST_LEN_WR + 8 + 1 + write-only + + + + + HOST_SLC0HOST_INT_CLR + 0xD4 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_CLR + 0 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT1_INT_CLR + 1 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT2_INT_CLR + 2 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT3_INT_CLR + 3 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT4_INT_CLR + 4 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT5_INT_CLR + 5 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT6_INT_CLR + 6 + 1 + write-only + + + HOST_SLC0_TOHOST_BIT7_INT_CLR + 7 + 1 + write-only + + + HOST_SLC0_TOKEN0_1TO0_INT_CLR + 8 + 1 + write-only + + + HOST_SLC0_TOKEN1_1TO0_INT_CLR + 9 + 1 + write-only + + + HOST_SLC0_TOKEN0_0TO1_INT_CLR + 10 + 1 + write-only + + + HOST_SLC0_TOKEN1_0TO1_INT_CLR + 11 + 1 + write-only + + + HOST_SLC0HOST_RX_SOF_INT_CLR + 12 + 1 + write-only + + + HOST_SLC0HOST_RX_EOF_INT_CLR + 13 + 1 + write-only + + + HOST_SLC0HOST_RX_START_INT_CLR + 14 + 1 + write-only + + + HOST_SLC0HOST_TX_START_INT_CLR + 15 + 1 + write-only + + + HOST_SLC0_RX_UDF_INT_CLR + 16 + 1 + write-only + + + HOST_SLC0_TX_OVF_INT_CLR + 17 + 1 + write-only + + + HOST_SLC0_RX_PF_VALID_INT_CLR + 18 + 1 + write-only + + + HOST_SLC0_EXT_BIT0_INT_CLR + 19 + 1 + write-only + + + HOST_SLC0_EXT_BIT1_INT_CLR + 20 + 1 + write-only + + + HOST_SLC0_EXT_BIT2_INT_CLR + 21 + 1 + write-only + + + HOST_SLC0_EXT_BIT3_INT_CLR + 22 + 1 + write-only + + + HOST_SLC0_RX_NEW_PACKET_INT_CLR + 23 + 1 + write-only + + + HOST_SLC0_HOST_RD_RETRY_INT_CLR + 24 + 1 + write-only + + + HOST_GPIO_SDIO_INT_CLR + 25 + 1 + write-only + + + + + HOST_SLC1HOST_INT_CLR + 0xD8 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_CLR + 0 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT1_INT_CLR + 1 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT2_INT_CLR + 2 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT3_INT_CLR + 3 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT4_INT_CLR + 4 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT5_INT_CLR + 5 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT6_INT_CLR + 6 + 1 + write-only + + + HOST_SLC1_TOHOST_BIT7_INT_CLR + 7 + 1 + write-only + + + HOST_SLC1_TOKEN0_1TO0_INT_CLR + 8 + 1 + write-only + + + HOST_SLC1_TOKEN1_1TO0_INT_CLR + 9 + 1 + write-only + + + HOST_SLC1_TOKEN0_0TO1_INT_CLR + 10 + 1 + write-only + + + HOST_SLC1_TOKEN1_0TO1_INT_CLR + 11 + 1 + write-only + + + HOST_SLC1HOST_RX_SOF_INT_CLR + 12 + 1 + write-only + + + HOST_SLC1HOST_RX_EOF_INT_CLR + 13 + 1 + write-only + + + HOST_SLC1HOST_RX_START_INT_CLR + 14 + 1 + write-only + + + HOST_SLC1HOST_TX_START_INT_CLR + 15 + 1 + write-only + + + HOST_SLC1_RX_UDF_INT_CLR + 16 + 1 + write-only + + + HOST_SLC1_TX_OVF_INT_CLR + 17 + 1 + write-only + + + HOST_SLC1_RX_PF_VALID_INT_CLR + 18 + 1 + write-only + + + HOST_SLC1_EXT_BIT0_INT_CLR + 19 + 1 + write-only + + + HOST_SLC1_EXT_BIT1_INT_CLR + 20 + 1 + write-only + + + HOST_SLC1_EXT_BIT2_INT_CLR + 21 + 1 + write-only + + + HOST_SLC1_EXT_BIT3_INT_CLR + 22 + 1 + write-only + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_CLR + 23 + 1 + write-only + + + HOST_SLC1_HOST_RD_RETRY_INT_CLR + 24 + 1 + write-only + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_CLR + 25 + 1 + write-only + + + + + HOST_SLC0HOST_FUNC1_INT_ENA + 0xDC + 0x20 + + + HOST_FN1_SLC0_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN1_SLC0_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN1_SLC0_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN1_SLC0HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN1_SLC0HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN1_SLC0HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN1_SLC0HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN1_SLC0_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN1_SLC0_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN1_SLC0_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN1_SLC0_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN1_SLC0_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN1_SLC0_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN1_GPIO_SDIO_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC1HOST_FUNC1_INT_ENA + 0xE0 + 0x20 + + + HOST_FN1_SLC1_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN1_SLC1_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN1_SLC1_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN1_SLC1HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN1_SLC1HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN1_SLC1HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN1_SLC1HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN1_SLC1_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN1_SLC1_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN1_SLC1_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN1_SLC1_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN1_SLC1_WIFI_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN1_SLC1_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN1_SLC1_BT_RX_NEW_PACKET_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC0HOST_FUNC2_INT_ENA + 0xE4 + 0x20 + + + HOST_FN2_SLC0_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN2_SLC0_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN2_SLC0_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN2_SLC0HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN2_SLC0HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN2_SLC0HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN2_SLC0HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN2_SLC0_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN2_SLC0_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN2_SLC0_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN2_SLC0_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN2_SLC0_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN2_SLC0_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN2_GPIO_SDIO_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC1HOST_FUNC2_INT_ENA + 0xE8 + 0x20 + + + HOST_FN2_SLC1_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_FN2_SLC1_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_FN2_SLC1_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_FN2_SLC1HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_FN2_SLC1HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_FN2_SLC1HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_FN2_SLC1HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_FN2_SLC1_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_FN2_SLC1_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_FN2_SLC1_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_FN2_SLC1_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_FN2_SLC1_WIFI_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_FN2_SLC1_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_FN2_SLC1_BT_RX_NEW_PACKET_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC0HOST_INT_ENA + 0xEC + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_SLC0_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_SLC0_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_SLC0_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_SLC0_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_SLC0HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_SLC0HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_SLC0HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_SLC0HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_SLC0_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_SLC0_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_SLC0_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_SLC0_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_SLC0_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_SLC0_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_SLC0_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_SLC0_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_SLC0_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_GPIO_SDIO_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC1HOST_INT_ENA + 0xF0 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_ENA + 0 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT1_INT_ENA + 1 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT2_INT_ENA + 2 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT3_INT_ENA + 3 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT4_INT_ENA + 4 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT5_INT_ENA + 5 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT6_INT_ENA + 6 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT7_INT_ENA + 7 + 1 + read-write + + + HOST_SLC1_TOKEN0_1TO0_INT_ENA + 8 + 1 + read-write + + + HOST_SLC1_TOKEN1_1TO0_INT_ENA + 9 + 1 + read-write + + + HOST_SLC1_TOKEN0_0TO1_INT_ENA + 10 + 1 + read-write + + + HOST_SLC1_TOKEN1_0TO1_INT_ENA + 11 + 1 + read-write + + + HOST_SLC1HOST_RX_SOF_INT_ENA + 12 + 1 + read-write + + + HOST_SLC1HOST_RX_EOF_INT_ENA + 13 + 1 + read-write + + + HOST_SLC1HOST_RX_START_INT_ENA + 14 + 1 + read-write + + + HOST_SLC1HOST_TX_START_INT_ENA + 15 + 1 + read-write + + + HOST_SLC1_RX_UDF_INT_ENA + 16 + 1 + read-write + + + HOST_SLC1_TX_OVF_INT_ENA + 17 + 1 + read-write + + + HOST_SLC1_RX_PF_VALID_INT_ENA + 18 + 1 + read-write + + + HOST_SLC1_EXT_BIT0_INT_ENA + 19 + 1 + read-write + + + HOST_SLC1_EXT_BIT1_INT_ENA + 20 + 1 + read-write + + + HOST_SLC1_EXT_BIT2_INT_ENA + 21 + 1 + read-write + + + HOST_SLC1_EXT_BIT3_INT_ENA + 22 + 1 + read-write + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_ENA + 23 + 1 + read-write + + + HOST_SLC1_HOST_RD_RETRY_INT_ENA + 24 + 1 + read-write + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_ENA + 25 + 1 + read-write + + + + + HOST_SLC0HOST_RX_INFOR + 0xF4 + 0x20 + + + HOST_SLC0HOST_RX_INFOR + 0 + 20 + read-write + + + + + HOST_SLC1HOST_RX_INFOR + 0xF8 + 0x20 + + + HOST_SLC1HOST_RX_INFOR + 0 + 20 + read-write + + + + + HOST_SLC0HOST_LEN_WD + 0xFC + 0x20 + + + HOST_SLC0HOST_LEN_WD + 0 + 32 + read-write + + + + + HOST_SLC_APBWIN_WDATA + 0x100 + 0x20 + + + HOST_SLC_APBWIN_WDATA + 0 + 32 + read-write + + + + + HOST_SLC_APBWIN_CONF + 0x104 + 0x20 + + + HOST_SLC_APBWIN_ADDR + 0 + 28 + read-write + + + HOST_SLC_APBWIN_WR + 28 + 1 + read-write + + + HOST_SLC_APBWIN_START + 29 + 1 + read-write + + + + + HOST_SLC_APBWIN_RDATA + 0x108 + 0x20 + + + HOST_SLC_APBWIN_RDATA + 0 + 32 + read-only + + + + + HOST_SLCHOST_RDCLR0 + 0x10C + 0x20 + 0x0003C044 + + + HOST_SLCHOST_SLC0_BIT7_CLRADDR + 0 + 9 + read-write + + + HOST_SLCHOST_SLC0_BIT6_CLRADDR + 9 + 9 + read-write + + + + + HOST_SLCHOST_RDCLR1 + 0x110 + 0x20 + 0x0003C1E0 + + + HOST_SLCHOST_SLC1_BIT7_CLRADDR + 0 + 9 + read-write + + + HOST_SLCHOST_SLC1_BIT6_CLRADDR + 9 + 9 + read-write + + + + + HOST_SLC0HOST_INT_ENA1 + 0x114 + 0x20 + + + HOST_SLC0_TOHOST_BIT0_INT_ENA1 + 0 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT1_INT_ENA1 + 1 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT2_INT_ENA1 + 2 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT3_INT_ENA1 + 3 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT4_INT_ENA1 + 4 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT5_INT_ENA1 + 5 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT6_INT_ENA1 + 6 + 1 + read-write + + + HOST_SLC0_TOHOST_BIT7_INT_ENA1 + 7 + 1 + read-write + + + HOST_SLC0_TOKEN0_1TO0_INT_ENA1 + 8 + 1 + read-write + + + HOST_SLC0_TOKEN1_1TO0_INT_ENA1 + 9 + 1 + read-write + + + HOST_SLC0_TOKEN0_0TO1_INT_ENA1 + 10 + 1 + read-write + + + HOST_SLC0_TOKEN1_0TO1_INT_ENA1 + 11 + 1 + read-write + + + HOST_SLC0HOST_RX_SOF_INT_ENA1 + 12 + 1 + read-write + + + HOST_SLC0HOST_RX_EOF_INT_ENA1 + 13 + 1 + read-write + + + HOST_SLC0HOST_RX_START_INT_ENA1 + 14 + 1 + read-write + + + HOST_SLC0HOST_TX_START_INT_ENA1 + 15 + 1 + read-write + + + HOST_SLC0_RX_UDF_INT_ENA1 + 16 + 1 + read-write + + + HOST_SLC0_TX_OVF_INT_ENA1 + 17 + 1 + read-write + + + HOST_SLC0_RX_PF_VALID_INT_ENA1 + 18 + 1 + read-write + + + HOST_SLC0_EXT_BIT0_INT_ENA1 + 19 + 1 + read-write + + + HOST_SLC0_EXT_BIT1_INT_ENA1 + 20 + 1 + read-write + + + HOST_SLC0_EXT_BIT2_INT_ENA1 + 21 + 1 + read-write + + + HOST_SLC0_EXT_BIT3_INT_ENA1 + 22 + 1 + read-write + + + HOST_SLC0_RX_NEW_PACKET_INT_ENA1 + 23 + 1 + read-write + + + HOST_SLC0_HOST_RD_RETRY_INT_ENA1 + 24 + 1 + read-write + + + HOST_GPIO_SDIO_INT_ENA1 + 25 + 1 + read-write + + + + + HOST_SLC1HOST_INT_ENA1 + 0x118 + 0x20 + + + HOST_SLC1_TOHOST_BIT0_INT_ENA1 + 0 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT1_INT_ENA1 + 1 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT2_INT_ENA1 + 2 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT3_INT_ENA1 + 3 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT4_INT_ENA1 + 4 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT5_INT_ENA1 + 5 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT6_INT_ENA1 + 6 + 1 + read-write + + + HOST_SLC1_TOHOST_BIT7_INT_ENA1 + 7 + 1 + read-write + + + HOST_SLC1_TOKEN0_1TO0_INT_ENA1 + 8 + 1 + read-write + + + HOST_SLC1_TOKEN1_1TO0_INT_ENA1 + 9 + 1 + read-write + + + HOST_SLC1_TOKEN0_0TO1_INT_ENA1 + 10 + 1 + read-write + + + HOST_SLC1_TOKEN1_0TO1_INT_ENA1 + 11 + 1 + read-write + + + HOST_SLC1HOST_RX_SOF_INT_ENA1 + 12 + 1 + read-write + + + HOST_SLC1HOST_RX_EOF_INT_ENA1 + 13 + 1 + read-write + + + HOST_SLC1HOST_RX_START_INT_ENA1 + 14 + 1 + read-write + + + HOST_SLC1HOST_TX_START_INT_ENA1 + 15 + 1 + read-write + + + HOST_SLC1_RX_UDF_INT_ENA1 + 16 + 1 + read-write + + + HOST_SLC1_TX_OVF_INT_ENA1 + 17 + 1 + read-write + + + HOST_SLC1_RX_PF_VALID_INT_ENA1 + 18 + 1 + read-write + + + HOST_SLC1_EXT_BIT0_INT_ENA1 + 19 + 1 + read-write + + + HOST_SLC1_EXT_BIT1_INT_ENA1 + 20 + 1 + read-write + + + HOST_SLC1_EXT_BIT2_INT_ENA1 + 21 + 1 + read-write + + + HOST_SLC1_EXT_BIT3_INT_ENA1 + 22 + 1 + read-write + + + HOST_SLC1_WIFI_RX_NEW_PACKET_INT_ENA1 + 23 + 1 + read-write + + + HOST_SLC1_HOST_RD_RETRY_INT_ENA1 + 24 + 1 + read-write + + + HOST_SLC1_BT_RX_NEW_PACKET_INT_ENA1 + 25 + 1 + read-write + + + + + HOST_SLCHOSTDATE + 0x178 + 0x20 + 0x16022500 + + + HOST_SLCHOST_DATE + 0 + 32 + read-write + + + + + HOST_SLCHOSTID + 0x17C + 0x20 + 0x00000600 + + + HOST_SLCHOST_ID + 0 + 32 + read-write + + + + + HOST_SLCHOST_CONF + 0x1F0 + 0x20 + + + HOST_FRC_SDIO11 + 0 + 5 + read-write + + + HOST_FRC_SDIO20 + 5 + 5 + read-write + + + HOST_FRC_NEG_SAMP + 10 + 5 + read-write + + + HOST_FRC_POS_SAMP + 15 + 5 + read-write + + + HOST_FRC_QUICK_IN + 20 + 5 + read-write + + + HOST_SDIO20_INT_DELAY + 25 + 1 + read-write + + + HOST_SDIO_PAD_PULLUP + 26 + 1 + read-write + + + HOST_HSPEED_CON_EN + 27 + 1 + read-write + + + + + HOST_SLCHOST_INF_ST + 0x1F4 + 0x20 + + + HOST_SDIO20_MODE + 0 + 5 + read-only + + + HOST_SDIO_NEG_SAMP + 5 + 5 + read-only + + + HOST_SDIO_QUICK_IN + 10 + 5 + read-only + + + + + + + SPI0 + SPI (Serial Peripheral Interface) Controller + SPI + 0x3FF43000 + + 0x0 + 0x110 + registers + + + SPI0 + 28 + + + + CMD + 0x0 + 0x20 + + + FLASH_PER + program erase resume bit program erase suspend operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 16 + 1 + read-write + + + FLASH_PES + program erase suspend bit program erase suspend operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 17 + 1 + read-write + + + USR + User define command enable. An operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 18 + 1 + read-write + + + FLASH_HPM + Drive Flash into high performance mode. The bit will be cleared once the operation done.1: enable 0: disable. + 19 + 1 + read-write + + + FLASH_RES + This bit combined with reg_resandres bit releases Flash from the power-down state or high performance mode and obtains the devices ID. The bit will be cleared once the operation done.1: enable 0: disable. + 20 + 1 + read-write + + + FLASH_DP + Drive Flash into power down. An operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 21 + 1 + read-write + + + FLASH_CE + Chip erase enable. Chip erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 22 + 1 + read-write + + + FLASH_BE + Block erase enable. A 64KB block is erased via SPI command D8H. Block erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 23 + 1 + read-write + + + FLASH_SE + Sector erase enable. A 4KB sector is erased via SPI command 20H. Sector erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 24 + 1 + read-write + + + FLASH_PP + Page program enable(1 byte ~256 bytes data to be programmed). Page program operation will be triggered when the bit is set. The bit will be cleared once the operation done .1: enable 0: disable. + 25 + 1 + read-write + + + FLASH_WRSR + Write status register enable. Write status operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 26 + 1 + read-write + + + FLASH_RDSR + Read status register-1. Read status operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable. + 27 + 1 + read-write + + + FLASH_RDID + Read JEDEC ID . Read ID command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 28 + 1 + read-write + + + FLASH_WRDI + Write flash disable. Write disable command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 29 + 1 + read-write + + + FLASH_WREN + Write flash enable. Write enable command will be sent when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 30 + 1 + read-write + + + FLASH_READ + Read flash enable. Read flash operation will be triggered when the bit is set. The bit will be cleared once the operation done. 1: enable 0: disable. + 31 + 1 + read-write + + + + + ADDR + 0x4 + 0x20 + + + CTRL + 0x8 + 0x20 + 0x0020A400 + + + FCS_CRC_EN + For SPI1 initialize crc32 module before writing encrypted data to flash. Active low. + 10 + 1 + read-write + + + TX_CRC_EN + For SPI1 enable crc32 when writing encrypted data to flash. 1: enable 0:disable + 11 + 1 + read-write + + + WAIT_FLASH_IDLE_EN + wait flash idle when program flash or erase flash. 1: enable 0: disable. + 12 + 1 + read-write + + + FASTRD_MODE + This bit enable the bits: spi_fread_qio spi_fread_dio spi_fread_qout and spi_fread_dout. 1: enable 0: disable. + 13 + 1 + read-write + + + FREAD_DUAL + In the read operations read-data phase apply 2 signals. 1: enable 0: disable. + 14 + 1 + read-write + + + RESANDRES + The Device ID is read out to SPI_RD_STATUS register, this bit combine with spi_flash_res bit. 1: enable 0: disable. + 15 + 1 + read-write + + + FREAD_QUAD + In the read operations read-data phase apply 4 signals. 1: enable 0: disable. + 20 + 1 + read-write + + + WP + Write protect signal output when SPI is idle. 1: output high 0: output low. + 21 + 1 + read-write + + + WRSR_2B + two bytes data will be written to status register when it is set. 1: enable 0: disable. + 22 + 1 + read-write + + + FREAD_DIO + In the read operations address phase and read-data phase apply 2 signals. 1: enable 0: disable. + 23 + 1 + read-write + + + FREAD_QIO + In the read operations address phase and read-data phase apply 4 signals. 1: enable 0: disable. + 24 + 1 + read-write + + + RD_BIT_ORDER + In read-data (MISO) phase 1: LSB first 0: MSB first + 25 + 1 + read-write + + + WR_BIT_ORDER + In command address write-data (MOSI) phases 1: LSB firs 0: MSB first + 26 + 1 + read-write + + + + + CTRL1 + 0xC + 0x20 + 0x5FFF0000 + + + CS_HOLD_DELAY_RES + Delay cycles of resume Flash when resume Flash is enable by spi clock. + 16 + 12 + read-write + + + CS_HOLD_DELAY + SPI cs signal is delayed by spi clock cycles + 28 + 4 + read-write + + + + + RD_STATUS + 0x10 + 0x20 + + + STATUS + In the slave mode, it is the status for master to read out. + 0 + 16 + read-write + + + WB_MODE + Mode bits in the flash fast read mode, it is combined with spi_fastrd_mode bit. + 16 + 8 + read-write + + + STATUS_EXT + In the slave mode,it is the status for master to read out. + 24 + 8 + read-write + + + + + CTRL2 + 0x14 + 0x20 + 0x00000011 + + + SETUP_TIME + (cycles-1) of ¡°prepare¡± phase by spi clock, this bits combined with spi_cs_setup bit. + 0 + 4 + read-write + + + HOLD_TIME + delay cycles of cs pin by spi clock, this bits combined with spi_cs_hold bit. + 4 + 4 + read-write + + + CK_OUT_LOW_MODE + modify spi clock duty ratio when the value is lager than 8, the bits are combined with spi_clkcnt_N bits and spi_clkcnt_L bits. + 8 + 4 + read-write + + + CK_OUT_HIGH_MODE + modify spi clock duty ratio when the value is lager than 8, the bits are combined with spi_clkcnt_N bits and spi_clkcnt_H bits. + 12 + 4 + read-write + + + MISO_DELAY_MODE + MISO signals are delayed by spi_clk. 0: zero 1: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by half cycle else delayed by one cycle 2: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by one cycle else delayed by half cycle 3: delayed one cycle + 16 + 2 + read-write + + + MISO_DELAY_NUM + MISO signals are delayed by system clock cycles + 18 + 3 + read-write + + + MOSI_DELAY_MODE + MOSI signals are delayed by spi_clk. 0: zero 1: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by half cycle else delayed by one cycle 2: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by one cycle else delayed by half cycle 3: delayed one cycle + 21 + 2 + read-write + + + MOSI_DELAY_NUM + MOSI signals are delayed by system clock cycles + 23 + 3 + read-write + + + CS_DELAY_MODE + spi_cs signal is delayed by spi_clk . 0: zero 1: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by half cycle else delayed by one cycle 2: if spi_ck_out_edge or spi_ck_i_edge is set 1 delayed by one cycle else delayed by half cycle 3: delayed one cycle + 26 + 2 + read-write + + + CS_DELAY_NUM + spi_cs signal is delayed by system clock cycles + 28 + 4 + read-write + + + + + CLOCK + 0x18 + 0x20 + 0x80003043 + + + CLKCNT_L + In the master mode it must be equal to spi_clkcnt_N. In the slave mode it must be 0. + 0 + 6 + read-write + + + CLKCNT_H + In the master mode it must be floor((spi_clkcnt_N+1)/2-1). In the slave mode it must be 0. + 6 + 6 + read-write + + + CLKCNT_N + In the master mode it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1) + 12 + 6 + read-write + + + CLKDIV_PRE + In the master mode it is pre-divider of spi_clk. + 18 + 13 + read-write + + + CLK_EQU_SYSCLK + In the master mode 1: spi_clk is eqaul to system 0: spi_clk is divided from system clock. + 31 + 1 + read-write + + + + + USER + 0x1C + 0x20 + 0x80000040 + + + DOUTDIN + Set the bit to enable full duplex communication. 1: enable 0: disable. + 0 + 1 + read-write + + + CS_HOLD + spi cs keep low when spi is in ¡°done¡± phase. 1: enable 0: disable. + 4 + 1 + read-write + + + CS_SETUP + spi cs is enable when spi is in ¡°prepare¡± phase. 1: enable 0: disable. + 5 + 1 + read-write + + + CK_I_EDGE + In the slave mode the bit is same as spi_ck_out_edge in master mode. It is combined with spi_miso_delay_mode bits. + 6 + 1 + read-write + + + CK_OUT_EDGE + the bit combined with spi_mosi_delay_mode bits to set mosi signal delay mode. + 7 + 1 + read-write + + + RD_BYTE_ORDER + In read-data (MISO) phase 1: big-endian 0: little_endian + 10 + 1 + read-write + + + WR_BYTE_ORDER + In command address write-data (MOSI) phases 1: big-endian 0: litte_endian + 11 + 1 + read-write + + + FWRITE_DUAL + In the write operations read-data phase apply 2 signals + 12 + 1 + read-write + + + FWRITE_QUAD + In the write operations read-data phase apply 4 signals + 13 + 1 + read-write + + + FWRITE_DIO + In the write operations address phase and read-data phase apply 2 signals. + 14 + 1 + read-write + + + FWRITE_QIO + In the write operations address phase and read-data phase apply 4 signals. + 15 + 1 + read-write + + + SIO + Set the bit to enable 3-line half duplex communication mosi and miso signals share the same pin. 1: enable 0: disable. + 16 + 1 + read-write + + + USR_HOLD_POL + It is combined with hold bits to set the polarity of spi hold line 1: spi will be held when spi hold line is high 0: spi will be held when spi hold line is low + 17 + 1 + read-write + + + USR_DOUT_HOLD + spi is hold at data out state the bit combined with spi_usr_hold_pol bit. + 18 + 1 + read-write + + + USR_DIN_HOLD + spi is hold at data in state the bit combined with spi_usr_hold_pol bit. + 19 + 1 + read-write + + + USR_DUMMY_HOLD + spi is hold at dummy state the bit combined with spi_usr_hold_pol bit. + 20 + 1 + read-write + + + USR_ADDR_HOLD + spi is hold at address state the bit combined with spi_usr_hold_pol bit. + 21 + 1 + read-write + + + USR_CMD_HOLD + spi is hold at command state the bit combined with spi_usr_hold_pol bit. + 22 + 1 + read-write + + + USR_PREP_HOLD + spi is hold at prepare state the bit combined with spi_usr_hold_pol bit. + 23 + 1 + read-write + + + USR_MISO_HIGHPART + read-data phase only access to high-part of the buffer spi_w8~spi_w15. 1: enable 0: disable. + 24 + 1 + read-write + + + USR_MOSI_HIGHPART + write-data phase only access to high-part of the buffer spi_w8~spi_w15. 1: enable 0: disable. + 25 + 1 + read-write + + + USR_DUMMY_IDLE + spi clock is disable in dummy phase when the bit is enable. + 26 + 1 + read-write + + + USR_MOSI + This bit enable the write-data phase of an operation. + 27 + 1 + read-write + + + USR_MISO + This bit enable the read-data phase of an operation. + 28 + 1 + read-write + + + USR_DUMMY + This bit enable the dummy phase of an operation. + 29 + 1 + read-write + + + USR_ADDR + This bit enable the address phase of an operation. + 30 + 1 + read-write + + + USR_COMMAND + This bit enable the command phase of an operation. + 31 + 1 + read-write + + + + + USER1 + 0x20 + 0x20 + 0x5C000007 + + + USR_DUMMY_CYCLELEN + The length in spi_clk cycles of dummy phase. The register value shall be (cycle_num-1). + 0 + 8 + read-write + + + USR_ADDR_BITLEN + The length in bits of address phase. The register value shall be (bit_num-1). + 26 + 6 + read-only + + + + + USER2 + 0x24 + 0x20 + 0x70000000 + + + USR_COMMAND_VALUE + The value of command. + 0 + 16 + read-write + + + USR_COMMAND_BITLEN + The length in bits of command phase. The register value shall be (bit_num-1) + 28 + 4 + read-write + + + + + MOSI_DLEN + 0x28 + 0x20 + + + USR_MOSI_DBITLEN + The length in bits of write-data. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + MISO_DLEN + 0x2C + 0x20 + + + USR_MISO_DBITLEN + The length in bits of read-data. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + SLV_WR_STATUS + 0x30 + 0x20 + + + SLV_WR_ST + In the slave mode this register are the status register for the master to write into. In the master mode this register are the higher 32bits in the 64 bits address condition. + 0 + 32 + read-write + + + + + PIN + 0x34 + 0x20 + 0x00000006 + + + CS0_DIS + SPI CS0 pin enable, 1: disable CS0, 0: spi_cs0 signal is from/to CS0 pin + 0 + 1 + read-write + + + CS1_DIS + SPI CS1 pin enable, 1: disable CS1, 0: spi_cs1 signal is from/to CS1 pin + 1 + 1 + read-write + + + CS2_DIS + SPI CS2 pin enable, 1: disable CS2, 0: spi_cs2 signal is from/to CS2 pin + 2 + 1 + read-write + + + CK_DIS + 1: spi clk out disable 0: spi clk out enable + 5 + 1 + read-write + + + MASTER_CS_POL + In the master mode the bits are the polarity of spi cs line the value is equivalent to spi_cs ^ spi_master_cs_pol. + 6 + 3 + read-write + + + MASTER_CK_SEL + In the master mode spi cs line is enable as spi clk it is combined with spi_cs0_dis spi_cs1_dis spi_cs2_dis. + 11 + 3 + read-write + + + CK_IDLE_EDGE + 1: spi clk line is high when idle 0: spi clk line is low when idle + 29 + 1 + read-write + + + CS_KEEP_ACTIVE + spi cs line keep low when the bit is set. + 30 + 1 + read-write + + + + + SLAVE + 0x38 + 0x20 + 0x00000020 + + + SLV_RD_BUF_DONE + The interrupt raw bit for the completion of read-buffer operation in the slave mode. + 0 + 1 + read-write + + + SLV_WR_BUF_DONE + The interrupt raw bit for the completion of write-buffer operation in the slave mode. + 1 + 1 + read-write + + + SLV_RD_STA_DONE + The interrupt raw bit for the completion of read-status operation in the slave mode. + 2 + 1 + read-write + + + SLV_WR_STA_DONE + The interrupt raw bit for the completion of write-status operation in the slave mode. + 3 + 1 + read-write + + + TRANS_DONE + The interrupt raw bit for the completion of any operation in both the master mode and the slave mode. + 4 + 1 + read-write + + + INT_EN + Interrupt enable bits for the below 5 sources + 5 + 5 + read-write + + + CS_I_MODE + In the slave mode this bits used to synchronize the input spi cs signal and eliminate spi cs jitter. + 10 + 2 + read-write + + + SLV_LAST_COMMAND + In the slave mode it is the value of command. + 17 + 3 + read-only + + + SLV_LAST_STATE + In the slave mode it is the state of spi state machine. + 20 + 3 + read-only + + + TRANS_CNT + The operations counter in both the master mode and the slave mode. 4: read-status + 23 + 4 + read-only + + + SLV_CMD_DEFINE + 1: slave mode commands are defined in SPI_SLAVE3. 0: slave mode commands are fixed as: 1: write-status 2: write-buffer and 3: read-buffer. + 27 + 1 + read-write + + + SLV_WR_RD_STA_EN + write and read status enable in the slave mode + 28 + 1 + read-write + + + SLV_WR_RD_BUF_EN + write and read buffer enable in the slave mode + 29 + 1 + read-write + + + MODE + 1: slave mode 0: master mode. + 30 + 1 + read-write + + + SYNC_RESET + Software reset enable, reset the spi clock line cs line and data lines. + 31 + 1 + read-write + + + + + SLAVE1 + 0x3C + 0x20 + 0x02000000 + + + SLV_RDBUF_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for read-buffer operations. + 0 + 1 + read-write + + + SLV_WRBUF_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for write-buffer operations. + 1 + 1 + read-write + + + SLV_RDSTA_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for read-status operations. + 2 + 1 + read-write + + + SLV_WRSTA_DUMMY_EN + In the slave mode it is the enable bit of dummy phase for write-status operations. + 3 + 1 + read-write + + + SLV_WR_ADDR_BITLEN + In the slave mode it is the address length in bits for write-buffer operation. The register value shall be (bit_num-1). + 4 + 6 + read-write + + + SLV_RD_ADDR_BITLEN + In the slave mode it is the address length in bits for read-buffer operation. The register value shall be (bit_num-1). + 10 + 6 + read-write + + + SLV_STATUS_READBACK + In the slave mode 1:read register of SPI_SLV_WR_STATUS 0: read register of SPI_RD_STATUS. + 25 + 1 + read-write + + + SLV_STATUS_FAST_EN + In the slave mode enable fast read status. + 26 + 1 + read-write + + + SLV_STATUS_BITLEN + In the slave mode it is the length of status bit. + 27 + 5 + read-write + + + + + SLAVE2 + 0x40 + 0x20 + + + SLV_RDSTA_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for read-status operations. The register value shall be (cycle_num-1). + 0 + 8 + read-write + + + SLV_WRSTA_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for write-status operations. The register value shall be (cycle_num-1). + 8 + 8 + read-write + + + SLV_RDBUF_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for read-buffer operations. The register value shall be (cycle_num-1). + 16 + 8 + read-write + + + SLV_WRBUF_DUMMY_CYCLELEN + In the slave mode it is the length in spi_clk cycles of dummy phase for write-buffer operations. The register value shall be (cycle_num-1). + 24 + 8 + read-write + + + + + SLAVE3 + 0x44 + 0x20 + + + SLV_RDBUF_CMD_VALUE + In the slave mode it is the value of read-buffer command. + 0 + 8 + read-write + + + SLV_WRBUF_CMD_VALUE + In the slave mode it is the value of write-buffer command. + 8 + 8 + read-write + + + SLV_RDSTA_CMD_VALUE + In the slave mode it is the value of read-status command. + 16 + 8 + read-write + + + SLV_WRSTA_CMD_VALUE + In the slave mode it is the value of write-status command. + 24 + 8 + read-write + + + + + SLV_WRBUF_DLEN + 0x48 + 0x20 + + + SLV_WRBUF_DBITLEN + In the slave mode it is the length in bits for write-buffer operations. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + SLV_RDBUF_DLEN + 0x4C + 0x20 + + + SLV_RDBUF_DBITLEN + In the slave mode it is the length in bits for read-buffer operations. The register value shall be (bit_num-1). + 0 + 24 + read-write + + + + + CACHE_FCTRL + 0x50 + 0x20 + + + CACHE_REQ_EN + For SPI0 Cache access enable 1: enable 0:disable. + 0 + 1 + read-write + + + CACHE_USR_CMD_4BYTE + For SPI0 cache read flash with 4 bytes command 1: enable 0:disable. + 1 + 1 + read-write + + + CACHE_FLASH_USR_CMD + For SPI0 cache read flash for user define command 1: enable 0:disable. + 2 + 1 + read-write + + + CACHE_FLASH_PES_EN + For SPI0 spi1 send suspend command before cache read flash 1: enable 0:disable. + 3 + 1 + read-write + + + + + CACHE_SCTRL + 0x54 + 0x20 + 0x15C04830 + + + USR_SRAM_DIO + For SPI0 In the spi sram mode spi dual I/O mode enable 1: enable 0:disable + 1 + 1 + read-write + + + USR_SRAM_QIO + For SPI0 In the spi sram mode spi quad I/O mode enable 1: enable 0:disable + 2 + 1 + read-write + + + USR_WR_SRAM_DUMMY + For SPI0 In the spi sram mode it is the enable bit of dummy phase for write operations. + 3 + 1 + read-write + + + USR_RD_SRAM_DUMMY + For SPI0 In the spi sram mode it is the enable bit of dummy phase for read operations. + 4 + 1 + read-write + + + CACHE_SRAM_USR_RCMD + For SPI0 In the spi sram mode cache read sram for user define command. + 5 + 1 + read-write + + + SRAM_BYTES_LEN + For SPI0 In the sram mode it is the byte length of spi read sram data. + 6 + 8 + read-write + + + SRAM_DUMMY_CYCLELEN + For SPI0 In the sram mode it is the length in bits of address phase. The register value shall be (bit_num-1). + 14 + 8 + read-write + + + SRAM_ADDR_BITLEN + For SPI0 In the sram mode it is the length in bits of address phase. The register value shall be (bit_num-1). + 22 + 6 + read-write + + + CACHE_SRAM_USR_WCMD + For SPI0 In the spi sram mode cache write sram for user define command + 28 + 1 + read-write + + + + + SRAM_CMD + 0x58 + 0x20 + + + SRAM_DIO + For SPI0 SRAM DIO mode enable . SRAM DIO enable command will be send when the bit is set. The bit will be cleared once the operation done. + 0 + 1 + read-write + + + SRAM_QIO + For SPI0 SRAM QIO mode enable . SRAM QIO enable command will be send when the bit is set. The bit will be cleared once the operation done. + 1 + 1 + read-write + + + SRAM_RSTIO + For SPI0 SRAM IO mode reset enable. SRAM IO mode reset operation will be triggered when the bit is set. The bit will be cleared once the operation done + 4 + 1 + read-write + + + + + SRAM_DRD_CMD + 0x5C + 0x20 + + + CACHE_SRAM_USR_RD_CMD_VALUE + For SPI0 When cache mode is enable it is the read command value of command phase for SRAM. + 0 + 16 + read-write + + + CACHE_SRAM_USR_RD_CMD_BITLEN + For SPI0 When cache mode is enable it is the length in bits of command phase for SRAM. The register value shall be (bit_num-1). + 28 + 4 + read-write + + + + + SRAM_DWR_CMD + 0x60 + 0x20 + + + CACHE_SRAM_USR_WR_CMD_VALUE + For SPI0 When cache mode is enable it is the write command value of command phase for SRAM. + 0 + 16 + read-write + + + CACHE_SRAM_USR_WR_CMD_BITLEN + For SPI0 When cache mode is enable it is the in bits of command phase for SRAM. The register value shall be (bit_num-1). + 28 + 4 + read-write + + + + + SLV_RD_BIT + 0x64 + 0x20 + + + SLV_RDATA_BIT + In the slave mode it is the bit length of read data. The value is the length - 1. + 0 + 24 + read-write + + + + + W0 + 0x80 + 0x20 + + + BUF0 + data buffer + 0 + 32 + read-write + + + + + W1 + 0x84 + 0x20 + + + BUF1 + data buffer + 0 + 32 + read-write + + + + + W2 + 0x88 + 0x20 + + + BUF2 + data buffer + 0 + 32 + read-write + + + + + W3 + 0x8C + 0x20 + + + BUF3 + data buffer + 0 + 32 + read-write + + + + + W4 + 0x90 + 0x20 + + + BUF4 + data buffer + 0 + 32 + read-write + + + + + W5 + 0x94 + 0x20 + + + BUF5 + data buffer + 0 + 32 + read-write + + + + + W6 + 0x98 + 0x20 + + + BUF6 + data buffer + 0 + 32 + read-write + + + + + W7 + 0x9C + 0x20 + + + BUF7 + data buffer + 0 + 32 + read-write + + + + + W8 + 0xA0 + 0x20 + + + BUF8 + data buffer + 0 + 32 + read-write + + + + + W9 + 0xA4 + 0x20 + + + BUF9 + data buffer + 0 + 32 + read-write + + + + + W10 + 0xA8 + 0x20 + + + BUF10 + data buffer + 0 + 32 + read-write + + + + + W11 + 0xAC + 0x20 + + + BUF11 + data buffer + 0 + 32 + read-write + + + + + W12 + 0xB0 + 0x20 + + + BUF12 + data buffer + 0 + 32 + read-write + + + + + W13 + 0xB4 + 0x20 + + + BUF13 + data buffer + 0 + 32 + read-write + + + + + W14 + 0xB8 + 0x20 + + + BUF14 + data buffer + 0 + 32 + read-write + + + + + W15 + 0xBC + 0x20 + + + BUF15 + data buffer + 0 + 32 + read-write + + + + + TX_CRC + 0xC0 + 0x20 + + + DATA + For SPI1 the value of crc32 for 256 bits data. + 0 + 32 + read-write + + + + + EXT0 + 0xF0 + 0x20 + 0x800A0050 + + + T_PP_TIME + page program delay time by system clock. + 0 + 12 + read-write + + + T_PP_SHIFT + page program delay time shift . + 16 + 4 + read-write + + + T_PP_ENA + page program delay enable. + 31 + 1 + read-write + + + + + EXT1 + 0xF4 + 0x20 + 0x800F0000 + + + T_ERASE_TIME + erase flash delay time by system clock. + 0 + 12 + read-write + + + T_ERASE_SHIFT + erase flash delay time shift. + 16 + 4 + read-write + + + T_ERASE_ENA + erase flash delay enable. + 31 + 1 + read-write + + + + + EXT2 + 0xF8 + 0x20 + + + ST + The status of spi state machine . + 0 + 3 + read-only + + + + + EXT3 + 0xFC + 0x20 + + + INT_HOLD_ENA + This register is for two SPI masters to share the same cs clock and data signals. The bits of one SPI are set if the other SPI is busy the SPI will be hold. 1(3): hold at ¡°idle¡± phase 2: hold at ¡°prepare¡± phase. + 0 + 2 + read-write + + + + + DMA_CONF + 0x100 + 0x20 + 0x00000200 + + + IN_RST + The bit is used to reset in dma fsm and in data fifo pointer. + 2 + 1 + read-write + + + OUT_RST + The bit is used to reset out dma fsm and out data fifo pointer. + 3 + 1 + read-write + + + AHBM_FIFO_RST + reset spi dma ahb master fifo pointer. + 4 + 1 + read-write + + + AHBM_RST + reset spi dma ahb master. + 5 + 1 + read-write + + + IN_LOOP_TEST + Set bit to test in link. + 6 + 1 + read-write + + + OUT_LOOP_TEST + Set bit to test out link. + 7 + 1 + read-write + + + OUT_AUTO_WRBACK + when the link is empty jump to next automatically. + 8 + 1 + read-write + + + OUT_EOF_MODE + out eof flag generation mode . 1: when dma pop all data from fifo 0:when ahb push all data to fifo. + 9 + 1 + read-write + + + OUTDSCR_BURST_EN + read descriptor use burst mode when read data for memory. + 10 + 1 + read-write + + + INDSCR_BURST_EN + read descriptor use burst mode when write data to memory. + 11 + 1 + read-write + + + OUT_DATA_BURST_EN + spi dma read data from memory in burst mode. + 12 + 1 + read-write + + + DMA_RX_STOP + spi dma read data stop when in continue tx/rx mode. + 14 + 1 + read-write + + + DMA_TX_STOP + spi dma write data stop when in continue tx/rx mode. + 15 + 1 + read-write + + + DMA_CONTINUE + spi dma continue tx/rx data. + 16 + 1 + read-write + + + + + DMA_OUT_LINK + 0x104 + 0x20 + + + OUTLINK_ADDR + The address of the first outlink descriptor. + 0 + 20 + read-write + + + OUTLINK_STOP + Set the bit to stop to use outlink descriptor. + 28 + 1 + read-write + + + OUTLINK_START + Set the bit to start to use outlink descriptor. + 29 + 1 + read-write + + + OUTLINK_RESTART + Set the bit to mount on new outlink descriptors. + 30 + 1 + read-write + + + + + DMA_IN_LINK + 0x108 + 0x20 + + + INLINK_ADDR + The address of the first inlink descriptor. + 0 + 20 + read-write + + + INLINK_AUTO_RET + when the bit is set inlink descriptor returns to the next descriptor while a packet is wrong + 20 + 1 + read-write + + + INLINK_STOP + Set the bit to stop to use inlink descriptor. + 28 + 1 + read-write + + + INLINK_START + Set the bit to start to use inlink descriptor. + 29 + 1 + read-write + + + INLINK_RESTART + Set the bit to mount on new inlink descriptors. + 30 + 1 + read-write + + + + + DMA_STATUS + 0x10C + 0x20 + + + DMA_RX_EN + spi dma read data status bit. + 0 + 1 + read-only + + + DMA_TX_EN + spi dma write data status bit. + 1 + 1 + read-only + + + + + DMA_INT_ENA + 0x110 + 0x20 + + + INLINK_DSCR_EMPTY_INT_ENA + The enable bit for lack of enough inlink descriptors. + 0 + 1 + read-write + + + OUTLINK_DSCR_ERROR_INT_ENA + The enable bit for outlink descriptor error. + 1 + 1 + read-write + + + INLINK_DSCR_ERROR_INT_ENA + The enable bit for inlink descriptor error. + 2 + 1 + read-write + + + IN_DONE_INT_ENA + The enable bit for completing usage of a inlink descriptor. + 3 + 1 + read-write + + + IN_ERR_EOF_INT_ENA + The enable bit for receiving error. + 4 + 1 + read-write + + + IN_SUC_EOF_INT_ENA + The enable bit for completing receiving all the packets from host. + 5 + 1 + read-write + + + OUT_DONE_INT_ENA + The enable bit for completing usage of a outlink descriptor . + 6 + 1 + read-write + + + OUT_EOF_INT_ENA + The enable bit for sending a packet to host done. + 7 + 1 + read-write + + + OUT_TOTAL_EOF_INT_ENA + The enable bit for sending all the packets to host done. + 8 + 1 + read-write + + + + + DMA_INT_RAW + 0x114 + 0x20 + + + INLINK_DSCR_EMPTY_INT_RAW + The raw bit for lack of enough inlink descriptors. + 0 + 1 + read-only + + + OUTLINK_DSCR_ERROR_INT_RAW + The raw bit for outlink descriptor error. + 1 + 1 + read-only + + + INLINK_DSCR_ERROR_INT_RAW + The raw bit for inlink descriptor error. + 2 + 1 + read-only + + + IN_DONE_INT_RAW + The raw bit for completing usage of a inlink descriptor. + 3 + 1 + read-only + + + IN_ERR_EOF_INT_RAW + The raw bit for receiving error. + 4 + 1 + read-only + + + IN_SUC_EOF_INT_RAW + The raw bit for completing receiving all the packets from host. + 5 + 1 + read-only + + + OUT_DONE_INT_RAW + The raw bit for completing usage of a outlink descriptor. + 6 + 1 + read-only + + + OUT_EOF_INT_RAW + The raw bit for sending a packet to host done. + 7 + 1 + read-only + + + OUT_TOTAL_EOF_INT_RAW + The raw bit for sending all the packets to host done. + 8 + 1 + read-only + + + + + DMA_INT_ST + 0x118 + 0x20 + + + INLINK_DSCR_EMPTY_INT_ST + The status bit for lack of enough inlink descriptors. + 0 + 1 + read-only + + + OUTLINK_DSCR_ERROR_INT_ST + The status bit for outlink descriptor error. + 1 + 1 + read-only + + + INLINK_DSCR_ERROR_INT_ST + The status bit for inlink descriptor error. + 2 + 1 + read-only + + + IN_DONE_INT_ST + The status bit for completing usage of a inlink descriptor. + 3 + 1 + read-only + + + IN_ERR_EOF_INT_ST + The status bit for receiving error. + 4 + 1 + read-only + + + IN_SUC_EOF_INT_ST + The status bit for completing receiving all the packets from host. + 5 + 1 + read-only + + + OUT_DONE_INT_ST + The status bit for completing usage of a outlink descriptor. + 6 + 1 + read-only + + + OUT_EOF_INT_ST + The status bit for sending a packet to host done. + 7 + 1 + read-only + + + OUT_TOTAL_EOF_INT_ST + The status bit for sending all the packets to host done. + 8 + 1 + read-only + + + + + DMA_INT_CLR + 0x11C + 0x20 + + + INLINK_DSCR_EMPTY_INT_CLR + The clear bit for lack of enough inlink descriptors. + 0 + 1 + read-write + + + OUTLINK_DSCR_ERROR_INT_CLR + The clear bit for outlink descriptor error. + 1 + 1 + read-write + + + INLINK_DSCR_ERROR_INT_CLR + The clear bit for inlink descriptor error. + 2 + 1 + read-write + + + IN_DONE_INT_CLR + The clear bit for completing usage of a inlink descriptor. + 3 + 1 + read-write + + + IN_ERR_EOF_INT_CLR + The clear bit for receiving error. + 4 + 1 + read-write + + + IN_SUC_EOF_INT_CLR + The clear bit for completing receiving all the packets from host. + 5 + 1 + read-write + + + OUT_DONE_INT_CLR + The clear bit for completing usage of a outlink descriptor. + 6 + 1 + read-write + + + OUT_EOF_INT_CLR + The clear bit for sending a packet to host done. + 7 + 1 + read-write + + + OUT_TOTAL_EOF_INT_CLR + The clear bit for sending all the packets to host done. + 8 + 1 + read-write + + + + + IN_ERR_EOF_DES_ADDR + 0x120 + 0x20 + + + DMA_IN_ERR_EOF_DES_ADDR + The inlink descriptor address when spi dma produce receiving error. + 0 + 32 + read-only + + + + + IN_SUC_EOF_DES_ADDR + 0x124 + 0x20 + + + DMA_IN_SUC_EOF_DES_ADDR + The last inlink descriptor address when spi dma produce from_suc_eof. + 0 + 32 + read-only + + + + + INLINK_DSCR + 0x128 + 0x20 + + + DMA_INLINK_DSCR + The content of current in descriptor pointer. + 0 + 32 + read-only + + + + + INLINK_DSCR_BF0 + 0x12C + 0x20 + + + DMA_INLINK_DSCR_BF0 + The content of next in descriptor pointer. + 0 + 32 + read-only + + + + + INLINK_DSCR_BF1 + 0x130 + 0x20 + + + DMA_INLINK_DSCR_BF1 + The content of current in descriptor data buffer pointer. + 0 + 32 + read-only + + + + + OUT_EOF_BFR_DES_ADDR + 0x134 + 0x20 + + + DMA_OUT_EOF_BFR_DES_ADDR + The address of buffer relative to the outlink descriptor that produce eof. + 0 + 32 + read-only + + + + + OUT_EOF_DES_ADDR + 0x138 + 0x20 + + + DMA_OUT_EOF_DES_ADDR + The last outlink descriptor address when spi dma produce to_eof. + 0 + 32 + read-only + + + + + OUTLINK_DSCR + 0x13C + 0x20 + + + DMA_OUTLINK_DSCR + The content of current out descriptor pointer. + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF0 + 0x140 + 0x20 + + + DMA_OUTLINK_DSCR_BF0 + The content of next out descriptor pointer. + 0 + 32 + read-only + + + + + OUTLINK_DSCR_BF1 + 0x144 + 0x20 + + + DMA_OUTLINK_DSCR_BF1 + The content of current out descriptor data buffer pointer. + 0 + 32 + read-only + + + + + DMA_RSTATUS + 0x148 + 0x20 + + + DMA_OUT_STATUS + spi dma read data from memory status. + 0 + 32 + read-only + + + + + DMA_TSTATUS + 0x14C + 0x20 + + + DMA_IN_STATUS + spi dma write data to memory status. + 0 + 32 + read-only + + + + + DATE + 0x3FC + 0x20 + 0x01604270 + + + DATE + SPI register version. + 0 + 28 + read-only + + + + + + + SPI1 + SPI (Serial Peripheral Interface) Controller + 0x3FF42000 + + SPI1 + 29 + + + SPI1_DMA + 52 + + + + SPI2 + SPI (Serial Peripheral Interface) Controller + 0x3FF64000 + + SPI2 + 30 + + + SPI2_DMA + 53 + + + + SPI3 + SPI (Serial Peripheral Interface) Controller + 0x3FF65000 + + SPI3 + 31 + + + SPI3_DMA + 54 + + + + TIMG0 + Timer Group + TIMG + 0x3FF5F000 + + 0x0 + 0xB0 + registers + + + TG0_T0_LEVEL + 14 + + + TG0_T1_LEVEL + 15 + + + TG0_WDT_LEVEL + 16 + + + TG0_LACT_LEVEL + 17 + + + TG0_T0_EDGE + 58 + + + TG0_T1_EDGE + 59 + + + TG0_WDT_EDGE + 60 + + + TG0_LACT_EDGE + 61 + + + + T0CONFIG + 0x0 + 0x20 + 0x60002000 + + + ALARM_EN + When set alarm is enabled + 10 + 1 + read-write + + + LEVEL_INT_EN + When set level type interrupt will be generated during alarm + 11 + 1 + read-write + + + EDGE_INT_EN + When set edge type interrupt will be generated during alarm + 12 + 1 + read-write + + + DIVIDER + Timer 0 clock (T0_clk) prescale value. + 13 + 16 + read-write + + + AUTORELOAD + When set timer 0 auto-reload at alarming is enabled + 29 + 1 + read-write + + + INCREASE + When set timer 0 time-base counter increment. When cleared timer 0 time-base counter decrement. + 30 + 1 + read-write + + + EN + When set timer 0 time-base counter is enabled + 31 + 1 + read-write + + + + + T0LO + 0x4 + 0x20 + + + LO + Register to store timer 0 time-base counter current value lower 32 bits. + 0 + 32 + read-only + + + + + T0HI + 0x8 + 0x20 + + + HI + Register to store timer 0 time-base counter current value higher 32 bits. + 0 + 32 + read-only + + + + + T0UPDATE + 0xC + 0x20 + + + UPDATE + Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above) + 0 + 32 + write-only + + + + + T0ALARMLO + 0x10 + 0x20 + + + ALARM_LO + Timer 0 time-base counter value lower 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T0ALARMHI + 0x14 + 0x20 + + + ALARM_HI + Timer 0 time-base counter value higher 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T0LOADLO + 0x18 + 0x20 + + + LOAD_LO + Lower 32 bits of the value that will load into timer 0 time-base counter + 0 + 32 + read-write + + + + + T0LOADHI + 0x1C + 0x20 + + + LOAD_HI + higher 32 bits of the value that will load into timer 0 time-base counter + 0 + 32 + read-write + + + + + T0LOAD + 0x20 + 0x20 + + + LOAD + Write any value will trigger timer 0 time-base counter reload + 0 + 32 + write-only + + + + + T1CONFIG + 0x24 + 0x20 + 0x60002000 + + + ALARM_EN + When set alarm is enabled + 10 + 1 + read-write + + + LEVEL_INT_EN + When set level type interrupt will be generated during alarm + 11 + 1 + read-write + + + EDGE_INT_EN + When set edge type interrupt will be generated during alarm + 12 + 1 + read-write + + + DIVIDER + Timer 1 clock (T1_clk) prescale value. + 13 + 16 + read-write + + + AUTORELOAD + When set timer 1 auto-reload at alarming is enabled + 29 + 1 + read-write + + + INCREASE + When set timer 1 time-base counter increment. When cleared timer 1 time-base counter decrement. + 30 + 1 + read-write + + + EN + When set timer 1 time-base counter is enabled + 31 + 1 + read-write + + + + + T1LO + 0x28 + 0x20 + + + LO + Register to store timer 1 time-base counter current value lower 32 bits. + 0 + 32 + read-only + + + + + T1HI + 0x2C + 0x20 + + + HI + Register to store timer 1 time-base counter current value higher 32 bits. + 0 + 32 + read-only + + + + + T1UPDATE + 0x30 + 0x20 + + + UPDATE + Write any value will trigger a timer 1 time-base counter value update (timer 1 current value will be stored in registers above) + 0 + 32 + write-only + + + + + T1ALARMLO + 0x34 + 0x20 + + + ALARM_LO + Timer 1 time-base counter value lower 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T1ALARMHI + 0x38 + 0x20 + + + ALARM_HI + Timer 1 time-base counter value higher 32 bits that will trigger the alarm + 0 + 32 + read-write + + + + + T1LOADLO + 0x3C + 0x20 + + + LOAD_LO + Lower 32 bits of the value that will load into timer 1 time-base counter + 0 + 32 + read-write + + + + + T1LOADHI + 0x40 + 0x20 + + + LOAD_HI + higher 32 bits of the value that will load into timer 1 time-base counter + 0 + 32 + read-write + + + + + T1LOAD + 0x44 + 0x20 + + + LOAD + Write any value will trigger timer 1 time-base counter reload + 0 + 32 + write-only + + + + + WDTCONFIG0 + 0x48 + 0x20 + 0x0004C000 + + + WDT_FLASHBOOT_MOD_EN + When set flash boot protection is enabled + 14 + 1 + read-write + + + WDT_SYS_RESET_LENGTH + length of system reset selection. 0: 100ns 1: 200ns 2: 300ns 3: 400ns 4: 500ns 5: 800ns 6: 1.6us 7: 3.2us + 15 + 3 + read-write + + WDT_SYS_RESET_LENGTH + read-write + + NS100 + 100ns + 0 + + + NS200 + 200ns + 1 + + + NS300 + 300ns + 2 + + + NS400 + 400ns + 3 + + + NS500 + 500ns + 4 + + + NS800 + 800ns + 5 + + + NS1600 + 1.6us + 6 + + + NS3200 + 3.2us + 7 + + + + + WDT_CPU_RESET_LENGTH + length of CPU reset selection. 0: 100ns 1: 200ns 2: 300ns 3: 400ns 4: 500ns 5: 800ns 6: 1.6us 7: 3.2us + 18 + 3 + read-write + + WDT_CPU_RESET_LENGTH + read-write + + NS100 + 100ns + 0 + + + NS200 + 200ns + 1 + + + NS300 + 300ns + 2 + + + NS400 + 400ns + 3 + + + NS500 + 500ns + 4 + + + NS800 + 800ns + 5 + + + NS1600 + 1.6us + 6 + + + NS3200 + 3.2us + 7 + + + + + WDT_LEVEL_INT_EN + When set level type interrupt generation is enabled + 21 + 1 + read-write + + + WDT_EDGE_INT_EN + When set edge type interrupt generation is enabled + 22 + 1 + read-write + + + WDT_STG3 + Stage 3 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 23 + 2 + read-write + + WDT_STG3 + read-write + + OFF + Off + 0 + + + INTERRUPT + Interrupt + 1 + + + RESET + Reset CPU + 2 + + + RESET_SYS + Reset system + 3 + + + + + WDT_STG2 + Stage 2 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 25 + 2 + read-write + + + + WDT_STG1 + Stage 1 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 27 + 2 + read-write + + + + WDT_STG0 + Stage 0 configuration. 0: off 1: interrupt 2: reset CPU 3: reset system + 29 + 2 + read-write + + + + WDT_EN + When set SWDT is enabled + 31 + 1 + read-write + + + + + WDTCONFIG1 + 0x4C + 0x20 + 0x00010000 + + + WDT_CLK_PRESCALE + SWDT clock prescale value. Period = 12.5ns * value stored in this register + 16 + 16 + read-write + + + + + WDTCONFIG2 + 0x50 + 0x20 + 0x018CBA80 + + + WDT_STG0_HOLD + Stage 0 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTCONFIG3 + 0x54 + 0x20 + 0x07FFFFFF + + + WDT_STG1_HOLD + Stage 1 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTCONFIG4 + 0x58 + 0x20 + 0x000FFFFF + + + WDT_STG2_HOLD + Stage 2 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTCONFIG5 + 0x5C + 0x20 + 0x000FFFFF + + + WDT_STG3_HOLD + Stage 3 timeout value in SWDT clock cycles + 0 + 32 + read-write + + + + + WDTFEED + 0x60 + 0x20 + + + WDT_FEED + Write any value will feed SWDT + 0 + 32 + write-only + + + + + WDTWPROTECT + 0x64 + 0x20 + 0x50D83AA1 + + + WDT_WKEY + If change its value from default then write protection is on. + 0 + 32 + read-write + + + + + RTCCALICFG + 0x68 + 0x20 + 0x00013000 + + + RTC_CALI_START_CYCLING + 12 + 1 + read-write + + + RTC_CALI_CLK_SEL + 13 + 2 + read-write + + + RTC_CALI_RDY + 15 + 1 + read-only + + + RTC_CALI_MAX + 16 + 15 + read-write + + + RTC_CALI_START + 31 + 1 + read-write + + + + + RTCCALICFG1 + 0x6C + 0x20 + + + RTC_CALI_VALUE + 7 + 25 + read-only + + + + + LACTCONFIG + 0x70 + 0x20 + 0x60002300 + + + LACT_RTC_ONLY + 7 + 1 + read-write + + + LACT_CPST_EN + 8 + 1 + read-write + + + LACT_LAC_EN + 9 + 1 + read-write + + + LACT_ALARM_EN + 10 + 1 + read-write + + + LACT_LEVEL_INT_EN + 11 + 1 + read-write + + + LACT_EDGE_INT_EN + 12 + 1 + read-write + + + LACT_DIVIDER + 13 + 16 + read-write + + + LACT_AUTORELOAD + 29 + 1 + read-write + + + LACT_INCREASE + 30 + 1 + read-write + + + LACT_EN + 31 + 1 + read-write + + + + + LACTRTC + 0x74 + 0x20 + + + LACT_RTC_STEP_LEN + 6 + 26 + read-write + + + + + LACTLO + 0x78 + 0x20 + + + LACT_LO + 0 + 32 + read-only + + + + + LACTHI + 0x7C + 0x20 + + + LACT_HI + 0 + 32 + read-only + + + + + LACTUPDATE + 0x80 + 0x20 + + + LACT_UPDATE + 0 + 32 + write-only + + + + + LACTALARMLO + 0x84 + 0x20 + + + LACT_ALARM_LO + 0 + 32 + read-write + + + + + LACTALARMHI + 0x88 + 0x20 + + + LACT_ALARM_HI + 0 + 32 + read-write + + + + + LACTLOADLO + 0x8C + 0x20 + + + LACT_LOAD_LO + 0 + 32 + read-write + + + + + LACTLOADHI + 0x90 + 0x20 + + + LACT_LOAD_HI + 0 + 32 + read-write + + + + + LACTLOAD + 0x94 + 0x20 + + + LACT_LOAD + 0 + 32 + write-only + + + + + INT_ENA_TIMERS + 0x98 + 0x20 + + + T0_INT_ENA + interrupt when timer0 alarm + 0 + 1 + read-write + + + T1_INT_ENA + interrupt when timer1 alarm + 1 + 1 + read-write + + + WDT_INT_ENA + Interrupt when an interrupt stage timeout + 2 + 1 + read-write + + + LACT_INT_ENA + 3 + 1 + read-write + + + + + INT_RAW_TIMERS + 0x9C + 0x20 + + + T0_INT_RAW + interrupt when timer0 alarm + 0 + 1 + read-only + + + T1_INT_RAW + interrupt when timer1 alarm + 1 + 1 + read-only + + + WDT_INT_RAW + Interrupt when an interrupt stage timeout + 2 + 1 + read-only + + + LACT_INT_RAW + 3 + 1 + read-only + + + + + INT_ST_TIMERS + 0xA0 + 0x20 + + + T0_INT_ST + interrupt when timer0 alarm + 0 + 1 + read-only + + + T1_INT_ST + interrupt when timer1 alarm + 1 + 1 + read-only + + + WDT_INT_ST + Interrupt when an interrupt stage timeout + 2 + 1 + read-only + + + LACT_INT_ST + 3 + 1 + read-only + + + + + INT_CLR_TIMERS + 0xA4 + 0x20 + + + T0_INT_CLR + interrupt when timer0 alarm + 0 + 1 + write-only + + + T1_INT_CLR + interrupt when timer1 alarm + 1 + 1 + write-only + + + WDT_INT_CLR + Interrupt when an interrupt stage timeout + 2 + 1 + write-only + + + LACT_INT_CLR + 3 + 1 + write-only + + + + + NTIMERS_DATE + 0xF8 + 0x20 + 0x01604290 + + + NTIMERS_DATE + Version of this regfile + 0 + 28 + read-write + + + + + TIMGCLK + 0xFC + 0x20 + + + CLK_EN + Force clock enable for this regfile + 31 + 1 + read-write + + + + + + + TIMG1 + Timer Group + 0x3FF60000 + + TG1_T0_LEVEL + 18 + + + TG1_T1_LEVEL + 19 + + + TG1_WDT_LEVEL + 20 + + + TG1_LACT_LEVEL + 21 + + + TG1_T0_EDGE + 62 + + + TG1_T1_EDGE + 63 + + + TG1_WDT_EDGE + 64 + + + TG1_LACT_EDGE + 65 + + + + TWAI + Two-Wire Automotive Interface + TWAI + 0x3FF6B000 + + 0x0 + 0x6C + registers + + + TWAI + 45 + + + + MODE + Mode Register + 0x0 + 0x20 + 0x00000001 + + + RESET_MODE + This bit is used to configure the operating mode of the TWAI Controller. 1: Reset mode; 0: Operating mode. + 0 + 1 + read-write + + + LISTEN_ONLY_MODE + 1: Listen only mode. In this mode the nodes will only receive messages from the bus, without generating the acknowledge signal nor updating the RX error counter. + 1 + 1 + read-write + + + SELF_TEST_MODE + 1: Self test mode. In this mode the TX nodes can perform a successful transmission without receiving the acknowledge signal. This mode is often used to test a single node with the self reception request command. + 2 + 1 + read-write + + + RX_FILTER_MODE + This bit is used to configure the filter mode. 0: Dual filter mode; 1: Single filter mode. + 3 + 1 + read-write + + + + + CMD + Command Register + 0x4 + 0x20 + + + TX_REQ + Set the bit to 1 to allow the driving nodes start transmission. + 0 + 1 + write-only + + + ABORT_TX + Set the bit to 1 to cancel a pending transmission request. + 1 + 1 + write-only + + + RELEASE_BUF + Set the bit to 1 to release the RX buffer. + 2 + 1 + write-only + + + CLR_OVERRUN + Set the bit to 1 to clear the data overrun status bit. + 3 + 1 + write-only + + + SELF_RX_REQ + Self reception request command. Set the bit to 1 to allow a message be transmitted and received simultaneously. + 4 + 1 + write-only + + + + + STATUS + Status register + 0x8 + 0x20 + + + RX_BUF_ST + 1: The data in the RX buffer is not empty, with at least one received data packet. + 0 + 1 + read-only + + + OVERRUN_ST + 1: The RX FIFO is full and data overrun has occurred. + 1 + 1 + read-only + + + TX_BUF_ST + 1: The TX buffer is empty, the CPU may write a message into it. + 2 + 1 + read-only + + + TX_COMPLETE + 1: The TWAI controller has successfully received a packet from the bus. + 3 + 1 + read-only + + + RX_ST + 1: The TWAI Controller is receiving a message from the bus. + 4 + 1 + read-only + + + TX_ST + 1: The TWAI Controller is transmitting a message to the bus. + 5 + 1 + read-only + + + ERR_ST + 1: At least one of the RX/TX error counter has reached or exceeded the value set in register TWAI_ERR_WARNING_LIMIT_REG. + 6 + 1 + read-only + + + BUS_OFF_ST + 1: In bus-off status, the TWAI Controller is no longer involved in bus activities. + 7 + 1 + read-only + + + MISS_ST + This bit reflects whether the data packet in the RX FIFO is complete. 1: The current packet is missing; 0: The current packet is complete + 8 + 1 + read-only + + + + + INT_RAW + Interrupt Register + 0xC + 0x20 + + + RX_INT_ST + Receive interrupt. If this bit is set to 1, it indicates there are messages to be handled in the RX FIFO. + 0 + 1 + read-only + + + TX_INT_ST + Transmit interrupt. If this bit is set to 1, it indicates the message transmitting mis- sion is finished and a new transmission is able to execute. + 1 + 1 + read-only + + + ERR_WARN_INT_ST + Error warning interrupt. If this bit is set to 1, it indicates the error status signal and the bus-off status signal of Status register have changed (e.g., switched from 0 to 1 or from 1 to 0). + 2 + 1 + read-only + + + OVERRUN_INT_ST + Data overrun interrupt. If this bit is set to 1, it indicates a data overrun interrupt is generated in the RX FIFO. + 3 + 1 + read-only + + + ERR_PASSIVE_INT_ST + Error passive interrupt. If this bit is set to 1, it indicates the TWAI Controller is switched between error active status and error passive status due to the change of error counters. + 5 + 1 + read-only + + + ARB_LOST_INT_ST + Arbitration lost interrupt. If this bit is set to 1, it indicates an arbitration lost interrupt is generated. + 6 + 1 + read-only + + + BUS_ERR_INT_ST + Error interrupt. If this bit is set to 1, it indicates an error is detected on the bus. + 7 + 1 + read-only + + + + + INT_ENA + Interrupt Enable Register + 0x10 + 0x20 + + + RX_INT_ENA + Set this bit to 1 to enable receive interrupt. + 0 + 1 + read-write + + + TX_INT_ENA + Set this bit to 1 to enable transmit interrupt. + 1 + 1 + read-write + + + ERR_WARN_INT_ENA + Set this bit to 1 to enable error warning interrupt. + 2 + 1 + read-write + + + OVERRUN_INT_ENA + Set this bit to 1 to enable data overrun interrupt. + 3 + 1 + read-write + + + ERR_PASSIVE_INT_ENA + Set this bit to 1 to enable error passive interrupt. + 5 + 1 + read-write + + + ARB_LOST_INT_ENA + Set this bit to 1 to enable arbitration lost interrupt. + 6 + 1 + read-write + + + BUS_ERR_INT_ENA + Set this bit to 1 to enable error interrupt. + 7 + 1 + read-write + + + + + BUS_TIMING_0 + Bus Timing Register 0 + 0x18 + 0x20 + + + BAUD_PRESC + Baud Rate Prescaler, determines the frequency dividing ratio. + 0 + 14 + + + SYNC_JUMP_WIDTH + Synchronization Jump Width (SJW), 1 \verb+~+ 14 Tq wide. + 14 + 2 + + + + + BUS_TIMING_1 + Bus Timing Register 1 + 0x1C + 0x20 + + + TIME_SEG1 + The width of PBS1. + 0 + 4 + + + TIME_SEG2 + The width of PBS2. + 4 + 3 + + + TIME_SAMP + The number of sample points. 0: the bus is sampled once; 1: the bus is sampled three times + 7 + 1 + + + + + ARB_LOST_CAP + Arbitration Lost Capture Register + 0x2C + 0x20 + + + ARB_LOST_CAP + This register contains information about the bit position of lost arbitration. + 0 + 5 + read-only + + + + + ERR_CODE_CAP + Error Code Capture Register + 0x30 + 0x20 + + + ECC_SEGMENT + This register contains information about the location of errors, see Table 181 for details. + 0 + 5 + read-only + + + ECC_DIRECTION + This register contains information about transmission direction of the node when error occurs. 1: Error occurs when receiving a message; 0: Error occurs when transmitting a message + 5 + 1 + read-only + + + ECC_TYPE + This register contains information about error types: 00: bit error; 01: form error; 10: stuff error; 11: other type of error + 6 + 2 + read-only + + + + + ERR_WARNING_LIMIT + Error Warning Limit Register + 0x34 + 0x20 + 0x00000060 + + + ERR_WARNING_LIMIT + Error warning threshold. In the case when any of a error counter value exceeds the threshold, or all the error counter values are below the threshold, an error warning interrupt will be triggered (given the enable signal is valid). + 0 + 8 + + + + + RX_ERR_CNT + Receive Error Counter Register + 0x38 + 0x20 + + + RX_ERR_CNT + The RX error counter register, reflects value changes under reception status. + 0 + 8 + + + + + TX_ERR_CNT + Transmit Error Counter Register + 0x3C + 0x20 + + + TX_ERR_CNT + The TX error counter register, reflects value changes under transmission status. + 0 + 8 + + + + + DATA_0 + Data register 0 + 0x40 + 0x20 + + + TX_BYTE_0 + In reset mode, it is acceptance code register 0 with R/W Permission. In operation mode, it stores the 0th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_1 + Data register 1 + 0x44 + 0x20 + + + TX_BYTE_1 + In reset mode, it is acceptance code register 1 with R/W Permission. In operation mode, it stores the 1st byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_2 + Data register 2 + 0x48 + 0x20 + + + TX_BYTE_2 + In reset mode, it is acceptance code register 2 with R/W Permission. In operation mode, it stores the 2nd byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_3 + Data register 3 + 0x4C + 0x20 + + + TX_BYTE_3 + In reset mode, it is acceptance code register 3 with R/W Permission. In operation mode, it stores the 3rd byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_4 + Data register 4 + 0x50 + 0x20 + + + TX_BYTE_4 + In reset mode, it is acceptance mask register 0 with R/W Permission. In operation mode, it stores the 4th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_5 + Data register 5 + 0x54 + 0x20 + + + TX_BYTE_5 + In reset mode, it is acceptance mask register 1 with R/W Permission. In operation mode, it stores the 5th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_6 + Data register 6 + 0x58 + 0x20 + + + TX_BYTE_6 + In reset mode, it is acceptance mask register 2 with R/W Permission. In operation mode, it stores the 6th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_7 + Data register 7 + 0x5C + 0x20 + + + TX_BYTE_7 + In reset mode, it is acceptance mask register 3 with R/W Permission. In operation mode, it stores the 7th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_8 + Data register 8 + 0x60 + 0x20 + + + TX_BYTE_8 + Stored the 8th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_9 + Data register 9 + 0x64 + 0x20 + + + TX_BYTE_9 + Stored the 9th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_10 + Data register 10 + 0x68 + 0x20 + + + TX_BYTE_10 + Stored the 10th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_11 + Data register 11 + 0x6C + 0x20 + + + TX_BYTE_11 + Stored the 11th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + DATA_12 + Data register 12 + 0x70 + 0x20 + + + TX_BYTE_12 + Stored the 12th byte information of the data to be transmitted under operating mode. + 0 + 8 + write-only + + + + + RX_MESSAGE_CNT + Receive Message Counter Register + 0x74 + 0x20 + + + RX_MESSAGE_COUNTER + This register reflects the number of messages available within the RX FIFO. + 0 + 7 + read-only + + + + + CLOCK_DIVIDER + Clock Divider register + 0x7C + 0x20 + + + CD + These bits are used to configure frequency dividing coefficients of the external CLKOUT pin. + 0 + 8 + read-write + + + CLOCK_OFF + This bit can be configured under reset mode. 1: Disable the external CLKOUT pin; 0: Enable the external CLKOUT pin + 8 + 1 + + + + + + + UART0 + UART (Universal Asynchronous Receiver-Transmitter) Controller + UART + 0x3FF40000 + + 0x0 + 0x7C + registers + + + UART0 + 34 + + + + FIFO + 0x0 + 0x20 + + + RXFIFO_RD_BYTE + This register stores one byte data read by rx fifo. + 0 + 8 + read-write + + + + + INT_RAW + 0x4 + 0x20 + + + RXFIFO_FULL_INT_RAW + This interrupt raw bit turns to high level when receiver receives more data than (rx_flow_thrhd_h3 rx_flow_thrhd). + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_RAW + This interrupt raw bit turns to high level when the amount of data in transmitter's fifo is less than ((tx_mem_cnttxfifo_cnt) . + 1 + 1 + read-only + + + PARITY_ERR_INT_RAW + This interrupt raw bit turns to high level when receiver detects the parity error of data. + 2 + 1 + read-only + + + FRM_ERR_INT_RAW + This interrupt raw bit turns to high level when receiver detects data's frame error . + 3 + 1 + read-only + + + RXFIFO_OVF_INT_RAW + This interrupt raw bit turns to high level when receiver receives more data than the fifo can store. + 4 + 1 + read-only + + + DSR_CHG_INT_RAW + This interrupt raw bit turns to high level when receiver detects the edge change of dsrn signal. + 5 + 1 + read-only + + + CTS_CHG_INT_RAW + This interrupt raw bit turns to high level when receiver detects the edge change of ctsn signal. + 6 + 1 + read-only + + + BRK_DET_INT_RAW + This interrupt raw bit turns to high level when receiver detects the 0 after the stop bit. + 7 + 1 + read-only + + + RXFIFO_TOUT_INT_RAW + This interrupt raw bit turns to high level when receiver takes more time than rx_tout_thrhd to receive a byte. + 8 + 1 + read-only + + + SW_XON_INT_RAW + This interrupt raw bit turns to high level when receiver receives xoff char with uart_sw_flow_con_en is set to 1. + 9 + 1 + read-only + + + SW_XOFF_INT_RAW + This interrupt raw bit turns to high level when receiver receives xon char with uart_sw_flow_con_en is set to 1. + 10 + 1 + read-only + + + GLITCH_DET_INT_RAW + This interrupt raw bit turns to high level when receiver detects the start bit. + 11 + 1 + read-only + + + TX_BRK_DONE_INT_RAW + This interrupt raw bit turns to high level when transmitter completes sendding 0 after all the datas in transmitter's fifo are send. + 12 + 1 + read-only + + + TX_BRK_IDLE_DONE_INT_RAW + This interrupt raw bit turns to high level when transmitter has kept the shortest duration after the last data has been send. + 13 + 1 + read-only + + + TX_DONE_INT_RAW + This interrupt raw bit turns to high level when transmitter has send all the data in fifo. + 14 + 1 + read-only + + + RS485_PARITY_ERR_INT_RAW + This interrupt raw bit turns to high level when rs485 detects the parity error. + 15 + 1 + read-only + + + RS485_FRM_ERR_INT_RAW + This interrupt raw bit turns to high level when rs485 detects the data frame error. + 16 + 1 + read-only + + + RS485_CLASH_INT_RAW + This interrupt raw bit turns to high level when rs485 detects the clash between transmitter and receiver. + 17 + 1 + read-only + + + AT_CMD_CHAR_DET_INT_RAW + This interrupt raw bit turns to high level when receiver detects the configured at_cmd chars. + 18 + 1 + read-only + + + + + INT_ST + 0x8 + 0x20 + + + RXFIFO_FULL_INT_ST + This is the status bit for rxfifo_full_int_raw when rxfifo_full_int_ena is set to 1. + 0 + 1 + read-only + + + TXFIFO_EMPTY_INT_ST + This is the status bit for txfifo_empty_int_raw when txfifo_empty_int_ena is set to 1. + 1 + 1 + read-only + + + PARITY_ERR_INT_ST + This is the status bit for parity_err_int_raw when parity_err_int_ena is set to 1. + 2 + 1 + read-only + + + FRM_ERR_INT_ST + This is the status bit for frm_err_int_raw when fm_err_int_ena is set to 1. + 3 + 1 + read-only + + + RXFIFO_OVF_INT_ST + This is the status bit for rxfifo_ovf_int_raw when rxfifo_ovf_int_ena is set to 1. + 4 + 1 + read-only + + + DSR_CHG_INT_ST + This is the status bit for dsr_chg_int_raw when dsr_chg_int_ena is set to 1. + 5 + 1 + read-only + + + CTS_CHG_INT_ST + This is the status bit for cts_chg_int_raw when cts_chg_int_ena is set to 1. + 6 + 1 + read-only + + + BRK_DET_INT_ST + This is the status bit for brk_det_int_raw when brk_det_int_ena is set to 1. + 7 + 1 + read-only + + + RXFIFO_TOUT_INT_ST + This is the status bit for rxfifo_tout_int_raw when rxfifo_tout_int_ena is set to 1. + 8 + 1 + read-only + + + SW_XON_INT_ST + This is the status bit for sw_xon_int_raw when sw_xon_int_ena is set to 1. + 9 + 1 + read-only + + + SW_XOFF_INT_ST + This is the status bit for sw_xoff_int_raw when sw_xoff_int_ena is set to 1. + 10 + 1 + read-only + + + GLITCH_DET_INT_ST + This is the status bit for glitch_det_int_raw when glitch_det_int_ena is set to 1. + 11 + 1 + read-only + + + TX_BRK_DONE_INT_ST + This is the status bit for tx_brk_done_int_raw when tx_brk_done_int_ena is set to 1. + 12 + 1 + read-only + + + TX_BRK_IDLE_DONE_INT_ST + This is the stauts bit for tx_brk_idle_done_int_raw when tx_brk_idle_done_int_ena is set to 1. + 13 + 1 + read-only + + + TX_DONE_INT_ST + This is the status bit for tx_done_int_raw when tx_done_int_ena is set to 1. + 14 + 1 + read-only + + + RS485_PARITY_ERR_INT_ST + This is the status bit for rs485_parity_err_int_raw when rs485_parity_int_ena is set to 1. + 15 + 1 + read-only + + + RS485_FRM_ERR_INT_ST + This is the status bit for rs485_fm_err_int_raw when rs485_fm_err_int_ena is set to 1. + 16 + 1 + read-only + + + RS485_CLASH_INT_ST + This is the status bit for rs485_clash_int_raw when rs485_clash_int_ena is set to 1. + 17 + 1 + read-only + + + AT_CMD_CHAR_DET_INT_ST + This is the status bit for at_cmd_det_int_raw when at_cmd_char_det_int_ena is set to 1. + 18 + 1 + read-only + + + + + INT_ENA + 0xC + 0x20 + + + RXFIFO_FULL_INT_ENA + This is the enable bit for rxfifo_full_int_st register. + 0 + 1 + read-write + + + TXFIFO_EMPTY_INT_ENA + This is the enable bit for rxfifo_full_int_st register. + 1 + 1 + read-write + + + PARITY_ERR_INT_ENA + This is the enable bit for parity_err_int_st register. + 2 + 1 + read-write + + + FRM_ERR_INT_ENA + This is the enable bit for frm_err_int_st register. + 3 + 1 + read-write + + + RXFIFO_OVF_INT_ENA + This is the enable bit for rxfifo_ovf_int_st register. + 4 + 1 + read-write + + + DSR_CHG_INT_ENA + This is the enable bit for dsr_chg_int_st register. + 5 + 1 + read-write + + + CTS_CHG_INT_ENA + This is the enable bit for cts_chg_int_st register. + 6 + 1 + read-write + + + BRK_DET_INT_ENA + This is the enable bit for brk_det_int_st register. + 7 + 1 + read-write + + + RXFIFO_TOUT_INT_ENA + This is the enable bit for rxfifo_tout_int_st register. + 8 + 1 + read-write + + + SW_XON_INT_ENA + This is the enable bit for sw_xon_int_st register. + 9 + 1 + read-write + + + SW_XOFF_INT_ENA + This is the enable bit for sw_xoff_int_st register. + 10 + 1 + read-write + + + GLITCH_DET_INT_ENA + This is the enable bit for glitch_det_int_st register. + 11 + 1 + read-write + + + TX_BRK_DONE_INT_ENA + This is the enable bit for tx_brk_done_int_st register. + 12 + 1 + read-write + + + TX_BRK_IDLE_DONE_INT_ENA + This is the enable bit for tx_brk_idle_done_int_st register. + 13 + 1 + read-write + + + TX_DONE_INT_ENA + This is the enable bit for tx_done_int_st register. + 14 + 1 + read-write + + + RS485_PARITY_ERR_INT_ENA + This is the enable bit for rs485_parity_err_int_st register. + 15 + 1 + read-write + + + RS485_FRM_ERR_INT_ENA + This is the enable bit for rs485_parity_err_int_st register. + 16 + 1 + read-write + + + RS485_CLASH_INT_ENA + This is the enable bit for rs485_clash_int_st register. + 17 + 1 + read-write + + + AT_CMD_CHAR_DET_INT_ENA + This is the enable bit for at_cmd_char_det_int_st register. + 18 + 1 + read-write + + + + + INT_CLR + 0x10 + 0x20 + + + RXFIFO_FULL_INT_CLR + Set this bit to clear the rxfifo_full_int_raw interrupt. + 0 + 1 + write-only + + + TXFIFO_EMPTY_INT_CLR + Set this bit to clear txfifo_empty_int_raw interrupt. + 1 + 1 + write-only + + + PARITY_ERR_INT_CLR + Set this bit to clear parity_err_int_raw interrupt. + 2 + 1 + write-only + + + FRM_ERR_INT_CLR + Set this bit to clear frm_err_int_raw interrupt. + 3 + 1 + write-only + + + RXFIFO_OVF_INT_CLR + Set this bit to clear rxfifo_ovf_int_raw interrupt. + 4 + 1 + write-only + + + DSR_CHG_INT_CLR + Set this bit to clear the dsr_chg_int_raw interrupt. + 5 + 1 + write-only + + + CTS_CHG_INT_CLR + Set this bit to clear the cts_chg_int_raw interrupt. + 6 + 1 + write-only + + + BRK_DET_INT_CLR + Set this bit to clear the brk_det_int_raw interrupt. + 7 + 1 + write-only + + + RXFIFO_TOUT_INT_CLR + Set this bit to clear the rxfifo_tout_int_raw interrupt. + 8 + 1 + write-only + + + SW_XON_INT_CLR + Set this bit to clear the sw_xon_int_raw interrupt. + 9 + 1 + write-only + + + SW_XOFF_INT_CLR + Set this bit to clear the sw_xon_int_raw interrupt. + 10 + 1 + write-only + + + GLITCH_DET_INT_CLR + Set this bit to clear the glitch_det_int_raw interrupt. + 11 + 1 + write-only + + + TX_BRK_DONE_INT_CLR + Set this bit to clear the tx_brk_done_int_raw interrupt.. + 12 + 1 + write-only + + + TX_BRK_IDLE_DONE_INT_CLR + Set this bit to clear the tx_brk_idle_done_int_raw interrupt. + 13 + 1 + write-only + + + TX_DONE_INT_CLR + Set this bit to clear the tx_done_int_raw interrupt. + 14 + 1 + write-only + + + RS485_PARITY_ERR_INT_CLR + Set this bit to clear the rs485_parity_err_int_raw interrupt. + 15 + 1 + write-only + + + RS485_FRM_ERR_INT_CLR + Set this bit to clear the rs485_frm_err_int_raw interrupt. + 16 + 1 + write-only + + + RS485_CLASH_INT_CLR + Set this bit to clear the rs485_clash_int_raw interrupt. + 17 + 1 + write-only + + + AT_CMD_CHAR_DET_INT_CLR + Set this bit to clear the at_cmd_char_det_int_raw interrupt. + 18 + 1 + write-only + + + + + CLKDIV + 0x14 + 0x20 + 0x000002B6 + + + CLKDIV + The register value is the integer part of the frequency divider's factor. + 0 + 20 + read-write + + + FRAG + The register value is the decimal part of the frequency divider's factor. + 20 + 4 + read-write + + + + + AUTOBAUD + 0x18 + 0x20 + 0x00001000 + + + EN + This is the enable bit for detecting baudrate. + 0 + 1 + read-write + + + GLITCH_FILT + when input pulse width is lower then this value igore this pulse.this register is used in autobaud detect process. + 8 + 8 + read-write + + + + + STATUS + 0x1C + 0x20 + + + RXFIFO_CNT + (rx_mem_cnt rxfifo_cnt) stores the byte num of valid datas in receiver's fifo. rx_mem_cnt register stores the 3 most significant bits rxfifo_cnt stores the 8 least significant bits. + 0 + 8 + read-only + + + ST_URX_OUT + This register stores the value of receiver's finite state machine. 0:RX_IDLE 1:RX_STRT 2:RX_DAT0 3:RX_DAT1 4:RX_DAT2 5:RX_DAT3 6:RX_DAT4 7:RX_DAT5 8:RX_DAT6 9:RX_DAT7 10:RX_PRTY 11:RX_STP1 12:RX_STP2 13:RX_DL1 + 8 + 4 + read-only + + + DSRN + This register stores the level value of the internal uart dsr signal. + 13 + 1 + read-only + + + CTSN + This register stores the level value of the internal uart cts signal. + 14 + 1 + read-only + + + RXD + This register stores the level value of the internal uart rxd signal. + 15 + 1 + read-only + + + TXFIFO_CNT + (tx_mem_cnt txfifo_cnt) stores the byte num of valid datas in transmitter's fifo.tx_mem_cnt stores the 3 most significant bits txfifo_cnt stores the 8 least significant bits. + 16 + 8 + read-only + + + ST_UTX_OUT + This register stores the value of transmitter's finite state machine. 0:TX_IDLE 1:TX_STRT 2:TX_DAT0 3:TX_DAT1 4:TX_DAT2 5:TX_DAT3 6:TX_DAT4 7:TX_DAT5 8:TX_DAT6 9:TX_DAT7 10:TX_PRTY 11:TX_STP1 12:TX_STP2 13:TX_DL0 14:TX_DL1 + 24 + 4 + read-only + + + DTRN + The register represent the level value of the internal uart dsr signal. + 29 + 1 + read-only + + + RTSN + This register represent the level value of the internal uart cts signal. + 30 + 1 + read-only + + + TXD + This register represent the level value of the internal uart rxd signal. + 31 + 1 + read-only + + + + + CONF0 + 0x20 + 0x20 + 0x0800001C + + + PARITY + This register is used to configure the parity check mode. 0:even 1:odd + 0 + 1 + read-write + + + PARITY_EN + Set this bit to enable uart parity check. + 1 + 1 + read-write + + + BIT_NUM + This registe is used to set the length of data: 0:5bits 1:6bits 2:7bits 3:8bits + 2 + 2 + read-write + + + STOP_BIT_NUM + This register is used to set the length of stop bit. 1:1bit 2:1.5bits 3:2bits + 4 + 2 + read-write + + + SW_RTS + This register is used to configure the software rts signal which is used in software flow control. + 6 + 1 + read-write + + + SW_DTR + This register is used to configure the software dtr signal which is used in software flow control.. + 7 + 1 + read-write + + + TXD_BRK + Set this bit to enbale transmitter to send 0 when the process of sending data is done. + 8 + 1 + read-write + + + IRDA_DPLX + Set this bit to enable irda loopback mode. + 9 + 1 + read-write + + + IRDA_TX_EN + This is the start enable bit for irda transmitter. + 10 + 1 + read-write + + + IRDA_WCTL + 1.the irda transmitter's 11th bit is the same to the 10th bit. 0.set irda transmitter's 11th bit to 0. + 11 + 1 + read-write + + + IRDA_TX_INV + Set this bit to inverse the level value of irda transmitter's level. + 12 + 1 + read-write + + + IRDA_RX_INV + Set this bit to inverse the level value of irda receiver's level. + 13 + 1 + read-write + + + LOOPBACK + Set this bit to enable uart loopback test mode. + 14 + 1 + read-write + + + TX_FLOW_EN + Set this bit to enable transmitter's flow control function. + 15 + 1 + read-write + + + IRDA_EN + Set this bit to enable irda protocol. + 16 + 1 + read-write + + + RXFIFO_RST + Set this bit to reset uart receiver's fifo. + 17 + 1 + read-write + + + TXFIFO_RST + Set this bit to reset uart transmitter's fifo. + 18 + 1 + read-write + + + RXD_INV + Set this bit to inverse the level value of uart rxd signal. + 19 + 1 + read-write + + + CTS_INV + Set this bit to inverse the level value of uart cts signal. + 20 + 1 + read-write + + + DSR_INV + Set this bit to inverse the level value of uart dsr signal. + 21 + 1 + read-write + + + TXD_INV + Set this bit to inverse the level value of uart txd signal. + 22 + 1 + read-write + + + RTS_INV + Set this bit to inverse the level value of uart rts signal. + 23 + 1 + read-write + + + DTR_INV + Set this bit to inverse the level value of uart dtr signal. + 24 + 1 + read-write + + + CLK_EN + 1.force clock on for registers.support clock only when write registers + 25 + 1 + read-write + + + ERR_WR_MASK + 1.receiver stops storing data int fifo when data is wrong. 0.receiver stores the data even if the received data is wrong. + 26 + 1 + read-write + + + TICK_REF_ALWAYS_ON + This register is used to select the clock.1.apb clock 0:ref_tick + 27 + 1 + read-write + + + + + CONF1 + 0x24 + 0x20 + 0x00006060 + + + RXFIFO_FULL_THRHD + When receiver receives more data than its threshold value.receiver will produce rxfifo_full_int_raw interrupt.the threshold value is (rx_flow_thrhd_h3 rxfifo_full_thrhd). + 0 + 7 + read-write + + + TXFIFO_EMPTY_THRHD + when the data amount in transmitter fifo is less than its threshold value. it will produce txfifo_empty_int_raw interrupt. the threshold value is (tx_mem_empty_thrhd txfifo_empty_thrhd) + 8 + 7 + read-write + + + RX_FLOW_THRHD + when receiver receives more data than its threshold value. receiver produce signal to tell the transmitter stop transferring data. the threshold value is (rx_flow_thrhd_h3 rx_flow_thrhd). + 16 + 7 + read-write + + + RX_FLOW_EN + This is the flow enable bit for uart receiver. 1:choose software flow control with configuring sw_rts signal + 23 + 1 + read-write + + + RX_TOUT_THRHD + This register is used to configure the timeout value for uart receiver receiving a byte. + 24 + 7 + read-write + + + RX_TOUT_EN + This is the enble bit for uart receiver's timeout function. + 31 + 1 + read-write + + + + + LOWPULSE + 0x28 + 0x20 + 0x000FFFFF + + + MIN_CNT + This register stores the value of the minimum duration time for the low level pulse. it is used in baudrate-detect process. + 0 + 20 + read-only + + + + + HIGHPULSE + 0x2C + 0x20 + 0x000FFFFF + + + MIN_CNT + This register stores the value of the maxinum duration time for the high level pulse. it is used in baudrate-detect process. + 0 + 20 + read-only + + + + + RXD_CNT + 0x30 + 0x20 + + + RXD_EDGE_CNT + This register stores the count of rxd edge change. it is used in baudrate-detect process. + 0 + 10 + read-only + + + + + FLOW_CONF + 0x34 + 0x20 + + + SW_FLOW_CON_EN + Set this bit to enable software flow control. it is used with register sw_xon or sw_xoff . + 0 + 1 + read-write + + + XONOFF_DEL + Set this bit to remove flow control char from the received data. + 1 + 1 + read-write + + + FORCE_XON + Set this bit to clear ctsn to stop the transmitter from sending data. + 2 + 1 + read-write + + + FORCE_XOFF + Set this bit to set ctsn to enable the transmitter to go on sending data. + 3 + 1 + read-write + + + SEND_XON + Set this bit to send xon char. it is cleared by hardware automatically. + 4 + 1 + read-write + + + SEND_XOFF + Set this bit to send xoff char. it is cleared by hardware automatically. + 5 + 1 + read-write + + + + + SLEEP_CONF + 0x38 + 0x20 + 0x000000F0 + + + ACTIVE_THRESHOLD + When the input rxd edge changes more than this register value. the uart is active from light sleeping mode. + 0 + 10 + read-write + + + + + SWFC_CONF + 0x3C + 0x20 + 0x1311E000 + + + XON_THRESHOLD + when the data amount in receiver's fifo is more than this register value. it will send a xoff char with uart_sw_flow_con_en set to 1. + 0 + 8 + read-write + + + XOFF_THRESHOLD + When the data amount in receiver's fifo is less than this register value. it will send a xon char with uart_sw_flow_con_en set to 1. + 8 + 8 + read-write + + + XON_CHAR + This register stores the xon flow control char. + 16 + 8 + read-write + + + XOFF_CHAR + This register stores the xoff flow control char. + 24 + 8 + read-write + + + + + IDLE_CONF + 0x40 + 0x20 + 0x00A40100 + + + RX_IDLE_THRHD + when receiver takes more time than this register value to receive a byte data. it will produce frame end signal for uhci to stop receiving data. + 0 + 10 + read-write + + + TX_IDLE_NUM + This register is used to configure the duration time between transfers. + 10 + 10 + read-write + + + TX_BRK_NUM + This register is used to configure the num of 0 send after the process of sending data is done. it is active when txd_brk is set to 1. + 20 + 8 + read-write + + + + + RS485_CONF + 0x44 + 0x20 + + + RS485_EN + Set this bit to choose rs485 mode. + 0 + 1 + read-write + + + DL0_EN + Set this bit to delay the stop bit by 1 bit. + 1 + 1 + read-write + + + DL1_EN + Set this bit to delay the stop bit by 1 bit. + 2 + 1 + read-write + + + RS485TX_RX_EN + Set this bit to enable loopback transmitter's output data signal to receiver's input data signal. + 3 + 1 + read-write + + + RS485RXBY_TX_EN + 1: enable rs485's transmitter to send data when rs485's receiver is busy. 0:rs485's transmitter should not send data when its receiver is busy. + 4 + 1 + read-write + + + RS485_RX_DLY_NUM + This register is used to delay the receiver's internal data signal. + 5 + 1 + read-write + + + RS485_TX_DLY_NUM + This register is used to delay the transmitter's internal data signal. + 6 + 4 + read-write + + + + + AT_CMD_PRECNT + 0x48 + 0x20 + 0x00186A00 + + + PRE_IDLE_NUM + This register is used to configure the idle duration time before the first at_cmd is received by receiver. when the the duration is less than this register value it will not take the next data received as at_cmd char. + 0 + 24 + read-write + + + + + AT_CMD_POSTCNT + 0x4C + 0x20 + 0x00186A00 + + + POST_IDLE_NUM + This register is used to configure the duration time between the last at_cmd and the next data. when the duration is less than this register value it will not take the previous data as at_cmd char. + 0 + 24 + read-write + + + + + AT_CMD_GAPTOUT + 0x50 + 0x20 + 0x00001E00 + + + RX_GAP_TOUT + This register is used to configure the duration time between the at_cmd chars. when the duration time is less than this register value it will not take the datas as continous at_cmd chars. + 0 + 24 + read-write + + + + + AT_CMD_CHAR + 0x54 + 0x20 + 0x0000032B + + + AT_CMD_CHAR + This register is used to configure the content of at_cmd char. + 0 + 8 + read-write + + + CHAR_NUM + This register is used to configure the num of continous at_cmd chars received by receiver. + 8 + 8 + read-write + + + + + MEM_CONF + 0x58 + 0x20 + 0x00000088 + + + MEM_PD + Set this bit to power down mem.when reg_mem_pd registers in the 3 uarts are all set to 1 mem will enter low power mode. + 0 + 1 + read-write + + + RX_SIZE + This register is used to configure the amount of mem allocated to receiver's fifo. the default byte num is 128. + 3 + 4 + read-write + + + TX_SIZE + This register is used to configure the amount of mem allocated to transmitter's fifo.the default byte num is 128. + 7 + 4 + read-write + + + RX_FLOW_THRHD_H3 + refer to the rx_flow_thrhd's describtion. + 15 + 3 + read-write + + + RX_TOUT_THRHD_H3 + refer to the rx_tout_thrhd's describtion. + 18 + 3 + read-write + + + XON_THRESHOLD_H2 + refer to the uart_xon_threshold's describtion. + 21 + 2 + read-write + + + XOFF_THRESHOLD_H2 + refer to the uart_xoff_threshold's describtion. + 23 + 2 + read-write + + + RX_MEM_FULL_THRHD + refer to the rxfifo_full_thrhd's describtion. + 25 + 3 + read-write + + + TX_MEM_EMPTY_THRHD + refer to txfifo_empty_thrhd 's describtion. + 28 + 3 + read-write + + + + + MEM_TX_STATUS + 0x5C + 0x20 + + + MEM_TX_STATUS + 0 + 24 + read-only + + + + + MEM_RX_STATUS + 0x60 + 0x20 + + + MEM_RX_STATUS + This register stores the current uart rx mem read address and rx mem write address + 0 + 24 + read-only + + + MEM_RX_RD_ADDR + This register stores the rx mem read address + 2 + 11 + read-only + + + MEM_RX_WR_ADDR + This register stores the rx mem write address + 13 + 11 + read-only + + + + + MEM_CNT_STATUS + 0x64 + 0x20 + + + RX_MEM_CNT + refer to the rxfifo_cnt's describtion. + 0 + 3 + read-only + + + TX_MEM_CNT + refer to the txfifo_cnt's describtion. + 3 + 3 + read-only + + + + + POSPULSE + 0x68 + 0x20 + 0x000FFFFF + + + POSEDGE_MIN_CNT + This register stores the count of rxd posedge edge. it is used in boudrate-detect process. + 0 + 20 + read-only + + + + + NEGPULSE + 0x6C + 0x20 + 0x000FFFFF + + + NEGEDGE_MIN_CNT + This register stores the count of rxd negedge edge. it is used in boudrate-detect process. + 0 + 20 + read-only + + + + + DATE + 0x78 + 0x20 + 0x15122500 + + + DATE + 0 + 32 + read-write + + + + + ID + 0x7C + 0x20 + 0x00000500 + + + ID + 0 + 32 + read-write + + + + + + + UART1 + UART (Universal Asynchronous Receiver-Transmitter) Controller + 0x3FF50000 + + UART1 + 35 + + + + UART2 + UART (Universal Asynchronous Receiver-Transmitter) Controller + 0x3FF6E000 + + UART2 + 36 + + + + UHCI0 + Universal Host Controller Interface + UHCI + 0x3FF54000 + + 0x0 + 0xC8 + registers + + + UHCI0 + 12 + + + + CONF0 + 0x0 + 0x20 + 0x00370100 + + + IN_RST + Set this bit to reset in link operations. + 0 + 1 + read-write + + + OUT_RST + Set this bit to reset out link operations. + 1 + 1 + read-write + + + AHBM_FIFO_RST + Set this bit to reset dma ahb fifo. + 2 + 1 + read-write + + + AHBM_RST + Set this bit to reset dma ahb interface. + 3 + 1 + read-write + + + IN_LOOP_TEST + Set this bit to enable loop test for in links. + 4 + 1 + read-write + + + OUT_LOOP_TEST + Set this bit to enable loop test for out links. + 5 + 1 + read-write + + + OUT_AUTO_WRBACK + when in link's length is 0 go on to use the next in link automatically. + 6 + 1 + read-write + + + OUT_NO_RESTART_CLR + don't use + 7 + 1 + read-write + + + OUT_EOF_MODE + Set this bit to produce eof after DMA pops all data clear this bit to produce eof after DMA pushes all data + 8 + 1 + read-write + + + UART0_CE + Set this bit to use UART to transmit or receive data. + 9 + 1 + read-write + + + UART1_CE + Set this bit to use UART1 to transmit or receive data. + 10 + 1 + read-write + + + UART2_CE + Set this bit to use UART2 to transmit or receive data. + 11 + 1 + read-write + + + OUTDSCR_BURST_EN + Set this bit to enable DMA in links to use burst mode. + 12 + 1 + read-write + + + INDSCR_BURST_EN + Set this bit to enable DMA out links to use burst mode. + 13 + 1 + read-write + + + OUT_DATA_BURST_EN + Set this bit to enable DMA burst MODE + 14 + 1 + read-write + + + MEM_TRANS_EN + 15 + 1 + read-write + + + SEPER_EN + Set this bit to use special char to separate the data frame. + 16 + 1 + read-write + + + HEAD_EN + Set this bit to enable to use head packet before the data frame. + 17 + 1 + read-write + + + CRC_REC_EN + Set this bit to enable receiver''s ability of crc calculation when crc_en bit in head packet is 1 then there will be crc bytes after data_frame + 18 + 1 + read-write + + + UART_IDLE_EOF_EN + Set this bit to enable to use idle time when the idle time after data frame is satisfied this means the end of a data frame. + 19 + 1 + read-write + + + LEN_EOF_EN + Set this bit to enable to use packet_len in packet head when the received data is equal to packet_len this means the end of a data frame. + 20 + 1 + read-write + + + ENCODE_CRC_EN + Set this bit to enable crc calculation for data frame when bit6 in the head packet is 1. + 21 + 1 + read-write + + + CLK_EN + Set this bit to enable clock-gating for read or write registers. + 22 + 1 + read-write + + + UART_RX_BRK_EOF_EN + Set this bit to enable to use brk char as the end of a data frame. + 23 + 1 + read-write + + + + + INT_RAW + 0x4 + 0x20 + + + RX_START_INT_RAW + when a separator char has been send it will produce uhci_rx_start_int interrupt. + 0 + 1 + read-only + + + TX_START_INT_RAW + when DMA detects a separator char it will produce uhci_tx_start_int interrupt. + 1 + 1 + read-only + + + RX_HUNG_INT_RAW + when DMA takes a lot of time to receive a data it will produce uhci_rx_hung_int interrupt. + 2 + 1 + read-only + + + TX_HUNG_INT_RAW + when DMA takes a lot of time to read a data from RAM it will produce uhci_tx_hung_int interrupt. + 3 + 1 + read-only + + + IN_DONE_INT_RAW + when a in link descriptor has been completed it will produce uhci_in_done_int interrupt. + 4 + 1 + read-only + + + IN_SUC_EOF_INT_RAW + when a data packet has been received it will produce uhci_in_suc_eof_int interrupt. + 5 + 1 + read-only + + + IN_ERR_EOF_INT_RAW + when there are some errors about eof in in link descriptor it will produce uhci_in_err_eof_int interrupt. + 6 + 1 + read-only + + + OUT_DONE_INT_RAW + when a out link descriptor is completed it will produce uhci_out_done_int interrupt. + 7 + 1 + read-only + + + OUT_EOF_INT_RAW + when the current descriptor's eof bit is 1 it will produce uhci_out_eof_int interrupt. + 8 + 1 + read-only + + + IN_DSCR_ERR_INT_RAW + when there are some errors about the out link descriptor it will produce uhci_in_dscr_err_int interrupt. + 9 + 1 + read-only + + + OUT_DSCR_ERR_INT_RAW + when there are some errors about the in link descriptor it will produce uhci_out_dscr_err_int interrupt. + 10 + 1 + read-only + + + IN_DSCR_EMPTY_INT_RAW + when there are not enough in links for DMA it will produce uhci_in_dscr_err_int interrupt. + 11 + 1 + read-only + + + OUTLINK_EOF_ERR_INT_RAW + when there are some errors about eof in outlink descriptor it will produce uhci_outlink_eof_err_int interrupt. + 12 + 1 + read-only + + + OUT_TOTAL_EOF_INT_RAW + When all data have been send it will produce uhci_out_total_eof_int interrupt. + 13 + 1 + read-only + + + SEND_S_Q_INT_RAW + When use single send registers to send a short packets it will produce this interrupt when dma has send the short packet. + 14 + 1 + read-only + + + SEND_A_Q_INT_RAW + When use always_send registers to send a series of short packets it will produce this interrupt when dma has send the short packet. + 15 + 1 + read-only + + + DMA_INFIFO_FULL_WM_INT_RAW + 16 + 1 + read-only + + + + + INT_ST + 0x8 + 0x20 + + + RX_START_INT_ST + 0 + 1 + read-only + + + TX_START_INT_ST + 1 + 1 + read-only + + + RX_HUNG_INT_ST + 2 + 1 + read-only + + + TX_HUNG_INT_ST + 3 + 1 + read-only + + + IN_DONE_INT_ST + 4 + 1 + read-only + + + IN_SUC_EOF_INT_ST + 5 + 1 + read-only + + + IN_ERR_EOF_INT_ST + 6 + 1 + read-only + + + OUT_DONE_INT_ST + 7 + 1 + read-only + + + OUT_EOF_INT_ST + 8 + 1 + read-only + + + IN_DSCR_ERR_INT_ST + 9 + 1 + read-only + + + OUT_DSCR_ERR_INT_ST + 10 + 1 + read-only + + + IN_DSCR_EMPTY_INT_ST + 11 + 1 + read-only + + + OUTLINK_EOF_ERR_INT_ST + 12 + 1 + read-only + + + OUT_TOTAL_EOF_INT_ST + 13 + 1 + read-only + + + SEND_S_Q_INT_ST + 14 + 1 + read-only + + + SEND_A_Q_INT_ST + 15 + 1 + read-only + + + DMA_INFIFO_FULL_WM_INT_ST + 16 + 1 + read-only + + + + + INT_ENA + 0xC + 0x20 + + + RX_START_INT_ENA + 0 + 1 + read-write + + + TX_START_INT_ENA + 1 + 1 + read-write + + + RX_HUNG_INT_ENA + 2 + 1 + read-write + + + TX_HUNG_INT_ENA + 3 + 1 + read-write + + + IN_DONE_INT_ENA + 4 + 1 + read-write + + + IN_SUC_EOF_INT_ENA + 5 + 1 + read-write + + + IN_ERR_EOF_INT_ENA + 6 + 1 + read-write + + + OUT_DONE_INT_ENA + 7 + 1 + read-write + + + OUT_EOF_INT_ENA + 8 + 1 + read-write + + + IN_DSCR_ERR_INT_ENA + 9 + 1 + read-write + + + OUT_DSCR_ERR_INT_ENA + 10 + 1 + read-write + + + IN_DSCR_EMPTY_INT_ENA + 11 + 1 + read-write + + + OUTLINK_EOF_ERR_INT_ENA + 12 + 1 + read-write + + + OUT_TOTAL_EOF_INT_ENA + 13 + 1 + read-write + + + SEND_S_Q_INT_ENA + 14 + 1 + read-write + + + SEND_A_Q_INT_ENA + 15 + 1 + read-write + + + DMA_INFIFO_FULL_WM_INT_ENA + 16 + 1 + read-write + + + + + INT_CLR + 0x10 + 0x20 + + + RX_START_INT_CLR + 0 + 1 + write-only + + + TX_START_INT_CLR + 1 + 1 + write-only + + + RX_HUNG_INT_CLR + 2 + 1 + write-only + + + TX_HUNG_INT_CLR + 3 + 1 + write-only + + + IN_DONE_INT_CLR + 4 + 1 + write-only + + + IN_SUC_EOF_INT_CLR + 5 + 1 + write-only + + + IN_ERR_EOF_INT_CLR + 6 + 1 + write-only + + + OUT_DONE_INT_CLR + 7 + 1 + write-only + + + OUT_EOF_INT_CLR + 8 + 1 + write-only + + + IN_DSCR_ERR_INT_CLR + 9 + 1 + write-only + + + OUT_DSCR_ERR_INT_CLR + 10 + 1 + write-only + + + IN_DSCR_EMPTY_INT_CLR + 11 + 1 + write-only + + + OUTLINK_EOF_ERR_INT_CLR + 12 + 1 + write-only + + + OUT_TOTAL_EOF_INT_CLR + 13 + 1 + write-only + + + SEND_S_Q_INT_CLR + 14 + 1 + write-only + + + SEND_A_Q_INT_CLR + 15 + 1 + write-only + + + DMA_INFIFO_FULL_WM_INT_CLR + 16 + 1 + write-only + + + + + DMA_OUT_STATUS + 0x14 + 0x20 + 0x00000002 + + + OUT_FULL + 1:DMA out link descriptor's fifo is full. + 0 + 1 + read-only + + + OUT_EMPTY + 1:DMA in link descriptor's fifo is empty. + 1 + 1 + read-only + + + + + DMA_OUT_PUSH + 0x18 + 0x20 + + + OUTFIFO_WDATA + This is the data need to be pushed into out link descriptor's fifo. + 0 + 9 + read-write + + + OUTFIFO_PUSH + Set this bit to push data in out link descriptor's fifo. + 16 + 1 + read-write + + + + + DMA_IN_STATUS + 0x1C + 0x20 + 0x00000002 + + + IN_FULL + 0 + 1 + read-only + + + IN_EMPTY + 1 + 1 + read-only + + + RX_ERR_CAUSE + This register stores the errors caused in out link descriptor's data packet. + 4 + 3 + read-only + + + + + DMA_IN_POP + 0x20 + 0x20 + + + INFIFO_RDATA + This register stores the data pop from in link descriptor's fifo. + 0 + 12 + read-only + + + INFIFO_POP + Set this bit to pop data in in link descriptor's fifo. + 16 + 1 + read-write + + + + + DMA_OUT_LINK + 0x24 + 0x20 + + + OUTLINK_ADDR + This register stores the least 20 bits of the first out link descriptor's address. + 0 + 20 + read-write + + + OUTLINK_STOP + Set this bit to stop dealing with the out link descriptors. + 28 + 1 + read-write + + + OUTLINK_START + Set this bit to start dealing with the out link descriptors. + 29 + 1 + read-write + + + OUTLINK_RESTART + Set this bit to mount on new out link descriptors + 30 + 1 + read-write + + + OUTLINK_PARK + 1£º the out link descriptor's fsm is in idle state. 0:the out link descriptor's fsm is working. + 31 + 1 + read-only + + + + + DMA_IN_LINK + 0x28 + 0x20 + 0x00100000 + + + INLINK_ADDR + This register stores the least 20 bits of the first in link descriptor's address. + 0 + 20 + read-write + + + INLINK_AUTO_RET + 1:when a packet is wrong in link descriptor returns to the descriptor which is lately used. + 20 + 1 + read-write + + + INLINK_STOP + Set this bit to stop dealing with the in link descriptors. + 28 + 1 + read-write + + + INLINK_START + Set this bit to start dealing with the in link descriptors. + 29 + 1 + read-write + + + INLINK_RESTART + Set this bit to mount on new in link descriptors + 30 + 1 + read-write + + + INLINK_PARK + 1:the in link descriptor's fsm is in idle state. 0:the in link descriptor's fsm is working + 31 + 1 + read-only + + + + + CONF1 + 0x2C + 0x20 + 0x00000033 + + + CHECK_SUM_EN + Set this bit to enable decoder to check check_sum in packet header. + 0 + 1 + read-write + + + CHECK_SEQ_EN + Set this bit to enable decoder to check seq num in packet header. + 1 + 1 + read-write + + + CRC_DISABLE + Set this bit to disable crc calculation. + 2 + 1 + read-write + + + SAVE_HEAD + Set this bit to save packet header . + 3 + 1 + read-write + + + TX_CHECK_SUM_RE + Set this bit to enable hardware replace check_sum in packet header automatically. + 4 + 1 + read-write + + + TX_ACK_NUM_RE + Set this bit to enable hardware replace ack num in packet header automatically. + 5 + 1 + read-write + + + CHECK_OWNER + Set this bit to check the owner bit in link descriptor. + 6 + 1 + read-write + + + WAIT_SW_START + Set this bit to enable software way to add packet header. + 7 + 1 + read-write + + + SW_START + Set this bit to start inserting the packet header. + 8 + 1 + read-write + + + DMA_INFIFO_FULL_THRS + when data amount in link descriptor's fifo is more than this register value it will produce uhci_dma_infifo_full_wm_int interrupt. + 9 + 12 + read-write + + + + + STATE0 + 0x30 + 0x20 + + + STATE0 + 0 + 32 + read-only + + + + + STATE1 + 0x34 + 0x20 + + + STATE1 + 0 + 32 + read-only + + + + + DMA_OUT_EOF_DES_ADDR + 0x38 + 0x20 + + + OUT_EOF_DES_ADDR + This register stores the address of out link descriptoir when eof bit in this descriptor is 1. + 0 + 32 + read-only + + + + + DMA_IN_SUC_EOF_DES_ADDR + 0x3C + 0x20 + + + IN_SUC_EOF_DES_ADDR + This register stores the address of in link descriptor when eof bit in this descriptor is 1. + 0 + 32 + read-only + + + + + DMA_IN_ERR_EOF_DES_ADDR + 0x40 + 0x20 + + + IN_ERR_EOF_DES_ADDR + This register stores the address of in link descriptor when there are some errors in this descriptor. + 0 + 32 + read-only + + + + + DMA_OUT_EOF_BFR_DES_ADDR + 0x44 + 0x20 + + + OUT_EOF_BFR_DES_ADDR + This register stores the address of out link descriptor when there are some errors in this descriptor. + 0 + 32 + read-only + + + + + AHB_TEST + 0x48 + 0x20 + + + AHB_TESTMODE + bit2 is ahb bus test enable ,bit1 is used to choose wrtie(1) or read(0) mode. bit0 is used to choose test only once(1) or continue(0) + 0 + 3 + read-write + + + AHB_TESTADDR + The two bits represent ahb bus address bit[20:19] + 4 + 2 + read-write + + + + + DMA_IN_DSCR + 0x4C + 0x20 + + + INLINK_DSCR + The content of current in link descriptor's third dword + 0 + 32 + read-only + + + + + DMA_IN_DSCR_BF0 + 0x50 + 0x20 + + + INLINK_DSCR_BF0 + The content of current in link descriptor's first dword + 0 + 32 + read-only + + + + + DMA_IN_DSCR_BF1 + 0x54 + 0x20 + + + INLINK_DSCR_BF1 + The content of current in link descriptor's second dword + 0 + 32 + read-only + + + + + DMA_OUT_DSCR + 0x58 + 0x20 + + + OUTLINK_DSCR + The content of current out link descriptor's third dword + 0 + 32 + read-only + + + + + DMA_OUT_DSCR_BF0 + 0x5C + 0x20 + + + OUTLINK_DSCR_BF0 + The content of current out link descriptor's first dword + 0 + 32 + read-only + + + + + DMA_OUT_DSCR_BF1 + 0x60 + 0x20 + + + OUTLINK_DSCR_BF1 + The content of current out link descriptor's second dword + 0 + 32 + read-only + + + + + ESCAPE_CONF + 0x64 + 0x20 + 0x00000033 + + + TX_C0_ESC_EN + Set this bit to enable 0xc0 char decode when DMA receives data. + 0 + 1 + read-write + + + TX_DB_ESC_EN + Set this bit to enable 0xdb char decode when DMA receives data. + 1 + 1 + read-write + + + TX_11_ESC_EN + Set this bit to enable flow control char 0x11 decode when DMA receives data. + 2 + 1 + read-write + + + TX_13_ESC_EN + Set this bit to enable flow control char 0x13 decode when DMA receives data. + 3 + 1 + read-write + + + RX_C0_ESC_EN + Set this bit to enable 0xc0 char replace when DMA sends data. + 4 + 1 + read-write + + + RX_DB_ESC_EN + Set this bit to enable 0xdb char replace when DMA sends data. + 5 + 1 + read-write + + + RX_11_ESC_EN + Set this bit to enable flow control char 0x11 replace when DMA sends data. + 6 + 1 + read-write + + + RX_13_ESC_EN + Set this bit to enable flow control char 0x13 replace when DMA sends data. + 7 + 1 + read-write + + + + + HUNG_CONF + 0x68 + 0x20 + 0x00810810 + + + TXFIFO_TIMEOUT + This register stores the timeout value.when DMA takes more time than this register value to receive a data it will produce uhci_tx_hung_int interrupt. + 0 + 8 + read-write + + + TXFIFO_TIMEOUT_SHIFT + The tick count is cleared when its value >=(17'd8000>>reg_txfifo_timeout_shift) + 8 + 3 + read-write + + + TXFIFO_TIMEOUT_ENA + The enable bit for txfifo receive data timeout + 11 + 1 + read-write + + + RXFIFO_TIMEOUT + This register stores the timeout value.when DMA takes more time than this register value to read a data from RAM it will produce uhci_rx_hung_int interrupt. + 12 + 8 + read-write + + + RXFIFO_TIMEOUT_SHIFT + The tick count is cleared when its value >=(17'd8000>>reg_rxfifo_timeout_shift) + 20 + 3 + read-write + + + RXFIFO_TIMEOUT_ENA + This is the enable bit for DMA send data timeout + 23 + 1 + read-write + + + + + ACK_NUM + 0x6C + 0x20 + + + RX_HEAD + 0x70 + 0x20 + + + RX_HEAD + This register stores the packet header received by DMA + 0 + 32 + read-only + + + + + QUICK_SENT + 0x74 + 0x20 + + + SINGLE_SEND_NUM + The bits are used to choose which short packet + 0 + 3 + read-write + + + SINGLE_SEND_EN + Set this bit to enable send a short packet + 3 + 1 + read-write + + + ALWAYS_SEND_NUM + The bits are used to choose which short packet + 4 + 3 + read-write + + + ALWAYS_SEND_EN + Set this bit to enable continuously send the same short packet + 7 + 1 + read-write + + + + + Q0_WORD0 + 0x78 + 0x20 + + + SEND_Q0_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q0_WORD1 + 0x7C + 0x20 + + + SEND_Q0_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q1_WORD0 + 0x80 + 0x20 + + + SEND_Q1_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q1_WORD1 + 0x84 + 0x20 + + + SEND_Q1_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q2_WORD0 + 0x88 + 0x20 + + + SEND_Q2_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q2_WORD1 + 0x8C + 0x20 + + + SEND_Q2_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q3_WORD0 + 0x90 + 0x20 + + + SEND_Q3_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q3_WORD1 + 0x94 + 0x20 + + + SEND_Q3_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q4_WORD0 + 0x98 + 0x20 + + + SEND_Q4_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q4_WORD1 + 0x9C + 0x20 + + + SEND_Q4_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q5_WORD0 + 0xA0 + 0x20 + + + SEND_Q5_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q5_WORD1 + 0xA4 + 0x20 + + + SEND_Q5_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + Q6_WORD0 + 0xA8 + 0x20 + + + SEND_Q6_WORD0 + This register stores the content of short packet's first dword + 0 + 32 + read-write + + + + + Q6_WORD1 + 0xAC + 0x20 + + + SEND_Q6_WORD1 + This register stores the content of short packet's second dword + 0 + 32 + read-write + + + + + ESC_CONF0 + 0xB0 + 0x20 + 0x00DCDBC0 + + + SEPER_CHAR + This register stores the seperator char seperator char is used to seperate the data frame. + 0 + 8 + read-write + + + SEPER_ESC_CHAR0 + This register stores thee first char used to replace seperator char in data. + 8 + 8 + read-write + + + SEPER_ESC_CHAR1 + This register stores the second char used to replace seperator char in data . 0xdc 0xdb replace 0xc0 by default. + 16 + 8 + read-write + + + + + ESC_CONF1 + 0xB4 + 0x20 + 0x00DDDBDB + + + ESC_SEQ0 + This register stores the first substitute char used to replace the seperator char. + 0 + 8 + read-write + + + ESC_SEQ0_CHAR0 + This register stores the first char used to replace reg_esc_seq0 in data. + 8 + 8 + read-write + + + ESC_SEQ0_CHAR1 + This register stores the second char used to replace the reg_esc_seq0 in data + 16 + 8 + read-write + + + + + ESC_CONF2 + 0xB8 + 0x20 + 0x00DEDB11 + + + ESC_SEQ1 + This register stores the flow control char to turn on the flow_control + 0 + 8 + read-write + + + ESC_SEQ1_CHAR0 + This register stores the first char used to replace the reg_esc_seq1 in data. + 8 + 8 + read-write + + + ESC_SEQ1_CHAR1 + This register stores the second char used to replace the reg_esc_seq1 in data. + 16 + 8 + read-write + + + + + ESC_CONF3 + 0xBC + 0x20 + 0x00DFDB13 + + + ESC_SEQ2 + This register stores the flow_control char to turn off the flow_control + 0 + 8 + read-write + + + ESC_SEQ2_CHAR0 + This register stores the first char used to replace the reg_esc_seq2 in data. + 8 + 8 + read-write + + + ESC_SEQ2_CHAR1 + This register stores the second char used to replace the reg_esc_seq2 in data. + 16 + 8 + read-write + + + + + PKT_THRES + 0xC0 + 0x20 + 0x00000080 + + + PKT_THRS + when the amount of packet payload is greater than this value the process of receiving data is done. + 0 + 13 + read-write + + + + + DATE + 0xFC + 0x20 + 0x16041001 + + + DATE + version information + 0 + 32 + read-write + + + + + + + UHCI1 + Universal Host Controller Interface + 0x3FF4C000 + + UHCI1 + 13 + + + + \ No newline at end of file diff --git a/src/debug_custom.json b/src/debug_custom.json new file mode 100644 index 0000000..4dbe431 --- /dev/null +++ b/src/debug_custom.json @@ -0,0 +1,19 @@ +{ + "name":"Arduino on ESP32", + "toolchainPrefix":"xtensa-esp32-elf", + "svdFile":"debug.svd", + "request":"attach", + "postAttachCommands":[ + "set remote hardware-watchpoint-limit 2", + "monitor reset halt", + "monitor gdb_sync", + "thb setup", + "c" + ], + "overrideRestartCommands":[ + "monitor reset halt", + "monitor gdb_sync", + "thb setup", + "c" + ] +} \ No newline at end of file diff --git a/src/detect.cpp b/src/detect.cpp new file mode 100644 index 0000000..54a0646 --- /dev/null +++ b/src/detect.cpp @@ -0,0 +1,169 @@ +#include +#include +// Similar to https://github.com/Levi--G/IMU-WhoAmIVerifier + +//Do be aware that MPU9150's will report as 6050s, this is because a 9150 is a 6050 with a magnetometer +//if you have a 9250 board and it reports as a 6050, it's most likely a 9150. + +//This code will check for an IMU when reset and, if one is found, it will report what it is. +//To re run the check without resetting the Arduino, pull pin 4 to GND. + +#define NUM_IMUS 40 + +bool errorflag; + +typedef struct IMU { + uint8_t Address1; + uint8_t Address2; + uint8_t Register; + uint8_t ExpectedID; + const char* IMUName PROGMEM; + const char* IMUCapabilities PROGMEM; + bool LibSupported; +}; + +const IMU IMUList[NUM_IMUS] = +{ + {0x68, 0x69, 0x75, 0x68, "MPU6050", "3A,3G", true}, + {0x68, 0x69, 0x75, 0x70, "MPU6500", "3A,3G", true}, + {0x68, 0x69, 0x75, 0x74, "MPU6515", "3A,3G", true}, + {0x68, 0x69, 0x75, 0x19, "MPU6886", "3A,3G", true}, + {0x68, 0x69, 0x75, 0x71, "MPU9250", "3A,3G,3M", true}, + {0x68, 0x69, 0x75, 0x73, "MPU9255", "3A,3G,3M", true}, + {0x69, 0x68, 0x00, 0xD1, "BMI160", "3A,3G", true}, + {0x6B, 0x6A, 0x0F, 0x69, "LSM6DS3", "3A,3G", true}, + {0x6B, 0x6A, 0x0F, 0x6A, "LSM6DSL", "3A,3G", true}, + {0x68, 0x69, 0x75, 0x98, "ICM20689", "3A,3G", true}, + {0x68, 0x69, 0x75, 0x20, "ICM20690", "3A,3G", true}, + {0x6B, 0x6A, 0x00, 0x05, "QMI8658", "3A,3G", true}, + {0x18, 0x19, 0x00, 0xFA, "BMI055 or BMX055", "3A,3G or 3A,3G,3M", true}, + {0x0D, 0x0D, 0x0D, 0xFF, "QMC5883L", "3M", true}, + {0x68, 0x69, 0x75, 0x75, "Unknown or fake Invensense IMU, use 'IMU_Generic'", "3A,3G, possibly 3M?", true}, + {0x6B, 0x6A, 0x0F, 0x6B, "LSM6DSR", "3A,3G", false}, + {0x6B, 0x6A, 0x0F, 0x6C, "LSM6DSO", "3A,3G", false}, + {0x6B, 0x6A, 0x00, 0xFC, "QMI8610", "3A,3G", false}, + {0x68, 0x69, 0x75, 0x92, "ICG20330", "3G", false}, + {0x68, 0x69, 0x75, 0xB5, "IAM20380", "3A", false}, + {0x68, 0x69, 0x75, 0xB6, "IAM20381", "3G", false}, + {0x68, 0x69, 0x75, 0x11, "ICM20600", "3A,3G", false}, + {0x68, 0x69, 0x75, 0xAC, "ICM20601", "3A,3G", false}, + {0x68, 0x69, 0x75, 0x12, "ICM20602", "3A,3G", false}, + {0x68, 0x69, 0x75, 0xAF, "ICM20608-G", "3A,3G", false}, + {0x68, 0x69, 0x75, 0xA6, "ICM20609", "3A,3G", false}, + {0x68, 0x69, 0x00, 0xE0, "ICM20648", "3A,3G", false}, + {0x68, 0x69, 0x00, 0xE1, "ICM20649", "3A,3G", false}, + {0x68, 0x69, 0x75, 0xA9, "ICG20660", "3A,3G", false}, + {0x68, 0x69, 0x75, 0x91, "IAM20680", "3A,3G", false}, + {0x68, 0x69, 0x00, 0xEA, "ICM20948", "3A,3G,3M", false}, + {0x68, 0x69, 0x75, 0x6C, "IIM42351", "3A", false}, + {0x68, 0x69, 0x75, 0x6D, "IIM42352", "3A", false}, + {0x68, 0x69, 0x75, 0x4E, "ICM40627", "3A,3G", false}, + {0x68, 0x69, 0x75, 0x42, "ICM42605", "3A,3G", false}, + {0x68, 0x69, 0x75, 0x6F, "IIM42652", "3A,3G", false}, + {0x68, 0x69, 0x75, 0x67, "ICM42670-P", "3A,3G", false}, + {0x68, 0x69, 0x75, 0xDB, "ICM42688-V", "3A,3G", false}, + {0x68, 0x69, 0x00, 0x68, "MPU3050", "3G", false}, + {0x1E, 0x1E, 0x0C, 0x33, "HMC5883L", "3M", false}, +}; + +void setup() { + Serial.begin(9600); + while (!Serial) ; + errorflag = false; + pinMode(4, INPUT_PULLUP); + Wire.begin(); +#ifdef WIRE_HAS_TIMEOUT + Wire.setWireTimeout(3000); +#endif + Serial.println(F("\n=========== IMU Identifier ===========")); +} + +uint8_t readByte(uint8_t address, uint8_t subAddress) +{ + uint8_t data; // `data` will store the register data + Wire.beginTransmission(address); // Initialize the Tx buffer + Wire.write(subAddress); // Put slave register address in Tx buffer + int i = Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive + if (i == 5) { + return 0; + errorflag = true; + } + i = Wire.requestFrom(address, (uint8_t) 1, true); // Read one byte from slave register address + if (i == 0) { + return 0; + errorflag = true; + } + if (Wire.available()) { + data = Wire.read(); // Fill Rx buffer with result + } + return data; // Return data read from slave register +} + +void loop() { + static int a = 0; + while (digitalRead(4) && a != 0) ; //do once + a = 1; + bool detected = false; + for (int i = 0; i < NUM_IMUS; i++) + { +#ifdef WIRE_HAS_TIMEOUT + if (errorflag || Wire.getWireTimeoutFlag()) { + Serial.print(F("Error while reading address 0x")); + Serial.print(IMUList[i].Address1, HEX); + Serial.print(F(": ")); + if (Wire.getWireTimeoutFlag()) { + Serial.println(F("I2C bus timed out. (Bad IMU? check wiring.)")); + } + else { + Serial.println(F("Unknown error while reading/writing")); + } + Serial.println(F("======================================")); + Wire.clearWireTimeoutFlag(); + errorflag = false; + delay(2000); + return; + } +#endif + if (readByte(IMUList[i].Address1, IMUList[i].Register) == IMUList[i].ExpectedID) + { + detected = true; + Serial.print(F("IMU Found: ")); + Serial.print(IMUList[i].IMUName); + Serial.print(F(" On address: 0x")); + Serial.println(IMUList[i].Address1, HEX); + Serial.print(F("This IMU is capable of the following axis: ")); + Serial.println(IMUList[i].IMUCapabilities); + if (IMUList[i].LibSupported) { + Serial.println(F("This IMU is supported by the FastIMU library.")); + } + else + { + Serial.println(F("This IMU is not supported by the FastIMU library.")); + } + Serial.println(F("======================================")); + } + else if (readByte(IMUList[i].Address2, IMUList[i].Register) == IMUList[i].ExpectedID) + { + detected = true; + Serial.print(F("IMU Found: ")); + Serial.print(IMUList[i].IMUName); + Serial.print(F(" On address: 0x")); + Serial.println(IMUList[i].Address2, HEX); + Serial.print(F("This IMU is capable of the following axis: ")); + Serial.println(IMUList[i].IMUCapabilities); + if (IMUList[i].LibSupported) { + Serial.println(F("This IMU is supported by the FastIMU library.")); + } + else + { + Serial.println(F(" This IMU is not supported by the FastIMU library.")); + } + Serial.println(F("======================================")); + } + } + if (!detected) { + Serial.println(F("No IMU detected")); + Serial.println(F("======================================")); + } + delay(1000); +} diff --git a/src/kalibracija.cpp b/src/kalibracija.cpp new file mode 100644 index 0000000..8d7d36d --- /dev/null +++ b/src/kalibracija.cpp @@ -0,0 +1,364 @@ +// MPU6050 offset-finder, based on Jeff Rowberg's MPU6050_RAW +// 2016-10-19 by Robert R. Fenichel (bob@fenichel.net) + +// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class +// 10/7/2011 by Jeff Rowberg +// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib +// +// Changelog: +// 2019-07-11 - added PID offset generation at begninning Generates first offsets +// - in @ 6 seconds and completes with 4 more sets @ 10 seconds +// - then continues with origional 2016 calibration code. +// 2016-11-25 - added delays to reduce sampling rate to ~200 Hz +// added temporizing printing during long computations +// 2016-10-25 - requires inequality (Low < Target, High > Target) during expansion +// dynamic speed change when closing in +// 2016-10-22 - cosmetic changes +// 2016-10-19 - initial release of IMU_Zero +// 2013-05-08 - added multiple output formats +// - added seamless Fastwire support +// 2011-10-07 - initial release of MPU6050_RAW + +/* ============================================ +I2Cdev device library code is placed under the MIT license +Copyright (c) 2011 Jeff Rowberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + If an MPU6050 + * is an ideal member of its tribe, + * is properly warmed up, + * is at rest in a neutral position, + * is in a location where the pull of gravity is exactly 1g, and + * has been loaded with the best possible offsets, +then it will report 0 for all accelerations and displacements, except for +Z acceleration, for which it will report 16384 (that is, 2^14). Your device +probably won't do quite this well, but good offsets will all get the baseline +outputs close to these target values. + + Put the MPU6050 on a flat and horizontal surface, and leave it operating for +5-10 minutes so its temperature gets stabilized. + + Run this program. A "----- done -----" line will indicate that it has done its best. +With the current accuracy-related constants (NFast = 1000, NSlow = 10000), it will take +a few minutes to get there. + + Along the way, it will generate a dozen or so lines of output, showing that for each +of the 6 desired offsets, it is + * first, trying to find two estimates, one too low and one too high, and + * then, closing in until the bracket can't be made smaller. + + The line just above the "done" line will look something like + [567,567] --> [-1,2] [-2223,-2223] --> [0,1] [1131,1132] --> [16374,16404] [155,156] --> [-1,1] [-25,-24] --> [0,3] [5,6] --> [0,4] +As will have been shown in interspersed header lines, the six groups making up this +line describe the optimum offsets for the X acceleration, Y acceleration, Z acceleration, +X gyro, Y gyro, and Z gyro, respectively. In the sample shown just above, the trial showed +that +567 was the best offset for the X acceleration, -2223 was best for Y acceleration, +and so on. + + The need for the delay between readings (usDelay) was brought to my attention by Nikolaus Doppelhammer. +=============================================== +*/ + +// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files +// for both classes must be in the include path of your project +#include +#include "I2Cdev.h" +#include "MPU6050.h" + +// I2C MPU6050 +#define SDApin 1 +#define SCLpin 3 + +// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation +// is used in I2Cdev.h +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + #include "Wire.h" +#endif + +// class default I2C address is 0x68 +// specific I2C addresses may be passed as a parameter here +// AD0 low = 0x68 (default for InvenSense evaluation board) +// AD0 high = 0x69 +MPU6050 accelgyro; +//MPU6050 accelgyro(0x69); // <-- use for AD0 high + + +const char LBRACKET = '['; +const char RBRACKET = ']'; +const char COMMA = ','; +const char BLANK = ' '; +const char PERIOD = '.'; + +const int iAx = 0; +const int iAy = 1; +const int iAz = 2; +const int iGx = 3; +const int iGy = 4; +const int iGz = 5; + +const int usDelay = 3150; // empirical, to hold sampling to 200 Hz +const int NFast = 1000; // the bigger, the better (but slower) +const int NSlow = 10000; // .. +const int LinesBetweenHeaders = 5; + int LowValue[6]; + int HighValue[6]; + int Smoothed[6]; + int LowOffset[6]; + int HighOffset[6]; + int Target[6]; + int LinesOut; + int N; + +void ForceHeader() + { LinesOut = 99; } + +void SetAveraging(int NewN) + { N = NewN; + Serial.print("averaging "); + Serial.print(N); + Serial.println(" readings each time"); + } // SetAveraging + + +void GetSmoothed() + { int16_t RawValue[6]; + int i; + long Sums[6]; + for (i = iAx; i <= iGz; i++) + { Sums[i] = 0; } +// unsigned long Start = micros(); + + for (i = 1; i <= N; i++) + { // get sums + accelgyro.getMotion6(&RawValue[iAx], &RawValue[iAy], &RawValue[iAz], + &RawValue[iGx], &RawValue[iGy], &RawValue[iGz]); + if ((i % 500) == 0) + Serial.print(PERIOD); + delayMicroseconds(usDelay); + for (int j = iAx; j <= iGz; j++) + Sums[j] = Sums[j] + RawValue[j]; + } // get sums +// unsigned long usForN = micros() - Start; +// Serial.print(" reading at "); +// Serial.print(1000000/((usForN+N/2)/N)); +// Serial.println(" Hz"); + for (i = iAx; i <= iGz; i++) + { Smoothed[i] = (Sums[i] + N/2) / N ; } + } // GetSmoothed + +void Initialize() + { + // join I2C bus (I2Cdev library doesn't do this automatically) + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(SDApin, SCLpin); + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + + Serial.begin(9600); + + // initialize device + Serial.println("Initializing I2C devices..."); + accelgyro.initialize(); + + // verify connection + Serial.println("Testing device connections..."); + Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); + Serial.println("PID tuning Each Dot = 100 readings"); + /*A tidbit on how PID (PI actually) tuning works. + When we change the offset in the MPU6050 we can get instant results. This allows us to use Proportional and + integral of the PID to discover the ideal offsets. Integral is the key to discovering these offsets, Integral + uses the error from set-point (set-point is zero), it takes a fraction of this error (error * ki) and adds it + to the integral value. Each reading narrows the error down to the desired offset. The greater the error from + set-point, the more we adjust the integral value. The proportional does its part by hiding the noise from the + integral math. The Derivative is not used because of the noise and because the sensor is stationary. With the + noise removed the integral value lands on a solid offset after just 600 readings. At the end of each set of 100 + readings, the integral value is used for the actual offsets and the last proportional reading is ignored due to + the fact it reacts to any noise. + */ + accelgyro.CalibrateAccel(6); + accelgyro.CalibrateGyro(6); + Serial.println("\nat 600 Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("700 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("800 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("900 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println(); + accelgyro.CalibrateAccel(1); + accelgyro.CalibrateGyro(1); + Serial.println("1000 Total Readings"); + accelgyro.PrintActiveOffsets(); + Serial.println("\n\n Any of the above offsets will work nice \n\n Lets proof the PID tuning using another method:"); + } // Initialize + +void SetOffsets(int TheOffsets[6]) + { accelgyro.setXAccelOffset(TheOffsets [iAx]); + accelgyro.setYAccelOffset(TheOffsets [iAy]); + accelgyro.setZAccelOffset(TheOffsets [iAz]); + accelgyro.setXGyroOffset (TheOffsets [iGx]); + accelgyro.setYGyroOffset (TheOffsets [iGy]); + accelgyro.setZGyroOffset (TheOffsets [iGz]); + } // SetOffsets + +void ShowProgress() + { if (LinesOut >= LinesBetweenHeaders) + { // show header + Serial.println("\tXAccel\t\t\tYAccel\t\t\t\tZAccel\t\t\tXGyro\t\t\tYGyro\t\t\tZGyro"); + LinesOut = 0; + } // show header + Serial.print(BLANK); + for (int i = iAx; i <= iGz; i++) + { Serial.print(LBRACKET); + Serial.print(LowOffset[i]), + Serial.print(COMMA); + Serial.print(HighOffset[i]); + Serial.print("] --> ["); + Serial.print(LowValue[i]); + Serial.print(COMMA); + Serial.print(HighValue[i]); + if (i == iGz) + { Serial.println(RBRACKET); } + else + { Serial.print("]\t"); } + } + LinesOut++; + } // ShowProgress + +void PullBracketsIn() + { boolean AllBracketsNarrow; + boolean StillWorking; + int NewOffset[6]; + + Serial.println("\nclosing in:"); + AllBracketsNarrow = false; + ForceHeader(); + StillWorking = true; + while (StillWorking) + { StillWorking = false; + if (AllBracketsNarrow && (N == NFast)) + { SetAveraging(NSlow); } + else + { AllBracketsNarrow = true; }// tentative + for (int i = iAx; i <= iGz; i++) + { if (HighOffset[i] <= (LowOffset[i]+1)) + { NewOffset[i] = LowOffset[i]; } + else + { // binary search + StillWorking = true; + NewOffset[i] = (LowOffset[i] + HighOffset[i]) / 2; + if (HighOffset[i] > (LowOffset[i] + 10)) + { AllBracketsNarrow = false; } + } // binary search + } + SetOffsets(NewOffset); + GetSmoothed(); + for (int i = iAx; i <= iGz; i++) + { // closing in + if (Smoothed[i] > Target[i]) + { // use lower half + HighOffset[i] = NewOffset[i]; + HighValue[i] = Smoothed[i]; + } // use lower half + else + { // use upper half + LowOffset[i] = NewOffset[i]; + LowValue[i] = Smoothed[i]; + } // use upper half + } // closing in + ShowProgress(); + } // still working + + } // PullBracketsIn + +void PullBracketsOut() + { boolean Done = false; + int NextLowOffset[6]; + int NextHighOffset[6]; + + Serial.println("expanding:"); + ForceHeader(); + + while (!Done) + { Done = true; + SetOffsets(LowOffset); + GetSmoothed(); + for (int i = iAx; i <= iGz; i++) + { // got low values + LowValue[i] = Smoothed[i]; + if (LowValue[i] >= Target[i]) + { Done = false; + NextLowOffset[i] = LowOffset[i] - 1000; + } + else + { NextLowOffset[i] = LowOffset[i]; } + } // got low values + + SetOffsets(HighOffset); + GetSmoothed(); + for (int i = iAx; i <= iGz; i++) + { // got high values + HighValue[i] = Smoothed[i]; + if (HighValue[i] <= Target[i]) + { Done = false; + NextHighOffset[i] = HighOffset[i] + 1000; + } + else + { NextHighOffset[i] = HighOffset[i]; } + } // got high values + ShowProgress(); + for (int i = iAx; i <= iGz; i++) + { LowOffset[i] = NextLowOffset[i]; // had to wait until ShowProgress done + HighOffset[i] = NextHighOffset[i]; // .. + } + } // keep going + } // PullBracketsOut + +void setup() + { Initialize(); + for (int i = iAx; i <= iGz; i++) + { // set targets and initial guesses + Target[i] = 0; // must fix for ZAccel + HighOffset[i] = 0; + LowOffset[i] = 0; + } // set targets and initial guesses + Target[iAz] = 16384; + SetAveraging(NFast); + + PullBracketsOut(); + PullBracketsIn(); + + Serial.println("-------------- done --------------"); + } // setup + +void loop() + { + } // loop diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d686a6b --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,267 @@ +#include "Wire.h" +#include "MPU6050_6Axis_MotionApps612.h" +#include + +// I2C MPU6050 +#define SDApin 1 +#define SCLpin 3 + +// RGB LED +#define NUMPIXELS 1 +#define PIXELPIN 18 + +// ID kegla mora bit unikaten za vsakega! (se poslje poleg parametrov) +#define SENZOR_ID 1 + +// Stanje baterije +#define BATTERYPIN 8 + +#include +#include + +uint8_t sprejemnikMac[] = {0x08, 0x3A, 0xF2, 0x50, 0xEF, 0x6C }; + +typedef struct sensor_msg { + uint8_t id; + /* + float aX; + float aY; + float aZ; + */ + float qX; + float qY; + float qZ; + float qW; + double bat; +} sensor_msg; + +sensor_msg odcitek; +esp_now_peer_info_t peerInfo; + + +// Motion sensor object +MPU6050 mpu; + +// MPU control/status vars +bool dmpReady = false; // set true if DMP init was successful +uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU +uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) +uint16_t packetSize; // expected DMP packet size (default is 42 bytes) +uint16_t fifoCount; // count of all bytes currently in FIFO +uint8_t fifoBuffer[64]; // FIFO storage buffer + +// orientation/motion vars +Quaternion q; // [w, x, y, z] quaternion container +Quaternion pq; // [w, x, y, z] previous quaternion container +Quaternion diff; // [w, x, y, z] quaternion derivate container +Quaternion cq; // [w, x, y, z] calibration quaternion +VectorInt16 aa; // [x, y, z] accel sensor measurements +VectorInt16 gy; // [x, y, z] gyro sensor measurements +VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements +VectorFloat gravity; // [x, y, z] gravity vector +float ypr[3]; + +// Neopixel! +Adafruit_NeoPixel pixels(NUMPIXELS, PIXELPIN, NEO_GRB + NEO_KHZ800); + +int cas = 0; + +void setup() { + Serial.begin(115200); // set this as high as you can reliably run on your platform + + Serial.print("Gravitacija perspektive senzor init "); + Serial.println(SENZOR_ID); + + pixels.begin(); + + // Modra za init + pixels.setPixelColor(0, pixels.Color(0, 0, 255)); + pixels.show(); + + Wire.begin(SDApin, SCLpin); + Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties + + // Start MPU + mpu.initialize(); + + // Set sensitivity / range + //mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_250); + //mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2); + + // DMP init + devStatus = mpu.dmpInitialize(); + + // supply your own gyro offsets here, scaled for min sensitivity + // !!! Run Zero IMU to get readings (read comments for instructions) + + /* Senzorpaket broj jedan (roka) */ + mpu.setXAccelOffset(5439); + mpu.setYAccelOffset(-4509); + mpu.setZAccelOffset(10719); + mpu.setXGyroOffset(-30); + mpu.setYGyroOffset(-25); + mpu.setZGyroOffset(-19); + + + /* Senzorpaket II (glava) + mpu.setXAccelOffset(6555); + mpu.setYAccelOffset(-5252); + mpu.setZAccelOffset(9537); + mpu.setXGyroOffset(28); + mpu.setYGyroOffset(91); + mpu.setZGyroOffset(16); + */ + + /* Senzorpaket III (bekap) + mpu.setXAccelOffset(-3751); + mpu.setYAccelOffset(4927); + mpu.setZAccelOffset(8661); + mpu.setXGyroOffset(-130); + mpu.setYGyroOffset(-100); + mpu.setZGyroOffset(-4); + */ + + // make sure it worked (returns 0 if so) + if (devStatus == 0) { + // Calibration Time: generate offsets and calibrate our MPU6050 + mpu.CalibrateAccel(6); + mpu.CalibrateGyro(6); + //Serial.println(); + //mpu.PrintActiveOffsets(); + // turn on the DMP, now that it's ready + //Serial.println(F("Enabling DMP...")); + mpu.setDMPEnabled(true); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + //Serial.println(F("DMP ready! Waiting for first interrupt...")); + dmpReady = true; + + // get expected DMP packet size for later comparison + packetSize = mpu.dmpGetFIFOPacketSize(); + } else { + Serial.println("DMP Initialization failed (code " + String(devStatus) + ")"); + // ERROR! + // 1 = initial memory load failed + // 2 = DMP configuration updates failed + // (if it's going to break, usually the code will be 1) + + // Rdeca za fejl + pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + pixels.show(); + return; + } + + // Zelena za wifi init + pixels.setPixelColor(0, pixels.Color(0, 255, 0)); + pixels.show(); + + // WIFI init + WiFi.mode(WIFI_STA); + if (esp_now_init() != ESP_OK) { + Serial.println("Error initializing ESP-NOW"); + // Vijolicna za wifi fejl + pixels.setPixelColor(0, pixels.Color(255, 0, 255)); + pixels.show(); + return; + } + + memcpy(peerInfo.peer_addr, sprejemnikMac, 6); + peerInfo.channel = 0; + peerInfo.encrypt = false; + + if (esp_now_add_peer(&peerInfo) != ESP_OK){ + Serial.println("WIFI registracija ni uspela"); + // Rumena za drug wifi fejl + pixels.setPixelColor(0, pixels.Color(255, 255, 0)); + pixels.show(); + return; + } + + // bel pixel za sve ok + pixels.setPixelColor(0, pixels.Color(255, 255, 255)); + pixels.show(); + + // zacnemo + cas = millis(); +} + +void loop() { + // if programming failed, don't try to do anything + if (!dmpReady) return; + + // read a packet from FIFO + if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { // Get the Latest packet + + // Store last Q value + pq = Quaternion(q.w,q.x,q.y,q.z); + + // get quaternion values in easy matrix form: w x y z + mpu.dmpGetQuaternion(&q, fifoBuffer); + q = q.getProduct(cq); + + mpu.dmpGetAccel(&aa, fifoBuffer); + mpu.dmpGetGravity(&gravity, &q); + //mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); + mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); + + odcitek.id = SENZOR_ID; + + // Quaternion - rotacija + odcitek.qX = q.x * -1; + odcitek.qY = q.y * -1; + odcitek.qZ = q.z; + odcitek.qW = q.w; + + Serial.print("Quaternion: "); + Serial.print(q.x * -1); + Serial.print(" "); + Serial.print(q.y * -1); + Serial.print(" "); + Serial.print(q.z); + Serial.print(" "); + Serial.println(q.w); + + // display real acceleration, adjusted to remove gravity + /* + odcitek.aX = aaReal.x; + odcitek.aY = aaReal.y; + odcitek.aZ = aaReal.z; + + Serial.print("Accel: "); + Serial.print(aaReal.x); + Serial.print(" "); + Serial.print(aaReal.y); + Serial.print(" "); + Serial.println(aaReal.z); + */ + + Serial.print("YPR: "); + Serial.print(ypr[0]); + Serial.print(" "); + Serial.print(ypr[1]); + Serial.print(" "); + Serial.println(ypr[2]); + + // Nastavimo LED! + /* + analogWrite(26, abs(ypr[0]) / M_PI * 255); + analogWrite(18, abs(ypr[1]) / M_PI * 255); + analogWrite(19, abs(ypr[2]) / M_PI * 255); + */ + + // Vsako sekundo odcitamo baterijo + if (millis() - cas > 1000) { + cas = millis(); + odcitek.bat = analogRead(BATTERYPIN) * (1.1 / 8192); + } + + esp_err_t result = esp_now_send(sprejemnikMac, (uint8_t *) &odcitek, sizeof(odcitek)); + + if (result == ESP_OK) { + Serial.println("Uspesno poslano"); + } else { + Serial.println("Napaka pri posiljanju"); + Serial.println(result); + } + } +} diff --git a/src/sprejemnik.cpp b/src/sprejemnik.cpp new file mode 100644 index 0000000..1e68b9b --- /dev/null +++ b/src/sprejemnik.cpp @@ -0,0 +1,162 @@ +#include + +#include +#include +#include + +#include +#include + +//#define DEBUG + +#ifdef BOARD_HAS_USB_SERIAL +#include +SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB ); +#else +#include +SLIPEncodedSerial SLIPSerial(Serial); // Change to Serial1 or Serial2 etc. for boards with multiple serial ports that don’t have Serial +#endif + +// Set your new MAC Address +// MAC naslov sprejemnika: 08:3A:F2:50:EF:6C +uint8_t newMACAddress[] = {0x08, 0x3A, 0xF2, 0x50, 0xEF, 0x6C}; + +typedef struct sensor_msg { + uint8_t id; + /* + float aX; + float aY; + float aZ; + */ + float qX; + float qY; + float qZ; + float qW; + double bat; +} sensor_msg; + +//sensor_msg odcitek; + +// Maksimalno stevilo +#define ST_KEGLOV 10 + +int odcitekId; +sensor_msg odcitki[ST_KEGLOV]; +bool poslji[ST_KEGLOV]; + +void prejemPodatkov(const uint8_t * mac_addr, const uint8_t * noviPodatki, int len) { + + char macNaslov[18]; + snprintf(macNaslov, sizeof(macNaslov), "%02x:%02x:%02x:%02x:%02x:%02x", + mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); + + #ifdef DEBUG + Serial.print("Prejel podatke od "); + Serial.println(macNaslov); + #endif + + // ID odcitka je na prvem mestu! + memcpy(&odcitekId, noviPodatki, sizeof(uint8_t)); + + #ifdef DEBUG + Serial.print("RAZBIRAM ID "); + Serial.println(odcitekId); + #endif + + memcpy(&odcitki[odcitekId], noviPodatki, sizeof(sensor_msg)); + + #ifdef DEBUG + /* + Serial.printf("aX: %i \n", odcitki[odcitekId].aX); + Serial.printf("aY: %i \n", odcitki[odcitekId].aY); + Serial.printf("aZ: %i \n", odcitki[odcitekId].aZ); + */ + Serial.printf("qX: %f \n", odcitki[odcitekId].qX); + Serial.printf("qY: %f \n", odcitki[odcitekId].qY); + Serial.printf("qZ: %f \n", odcitki[odcitekId].qZ); + Serial.printf("qW: %f \n", odcitki[odcitekId].qW); + Serial.printf("bat: %d \n", odcitki[odcitekId].bat); + Serial.println(); + #endif + + poslji[odcitekId] = true; +} + +void setup() { + SLIPSerial.begin(115200); + + // Ne posiljaj preden se podatki napolnijo + for (int i = 0; i < ST_KEGLOV; i++) { + poslji[0] = false; + } + + Serial.println("Inicializiram WIFI..."); + WiFi.mode(WIFI_STA); + + esp_wifi_set_mac(WIFI_IF_STA, &newMACAddress[0]); + + esp_err_t result = esp_now_init(); + if (result != ESP_OK) { + Serial.println("Error initializing ESP-NOW"); + Serial.println(result); + return; + } + Serial.print("MAC naslov: "); + Serial.println(WiFi.macAddress()); + esp_now_register_recv_cb(prejemPodatkov); +} + +void loop() { + /* OSC MSG channels */ + OSCBundle bundle; + char glava[32]; + + for (int i = 0; i < ST_KEGLOV; i++) { + if (poslji[i]) { + + /* + sprintf(glava, "/ww/%d/accel", i); + // Serial.print("Posiljam "); + // Serial.println(glava); + bundle.add(glava) + .add(odcitki[i].aX) + .add(odcitki[i].aY) + .add(odcitki[i].aZ); + */ + + sprintf(glava, "/ww/%d/quaternion", i); + /* + Serial.print("Posiljam "); + Serial.println(glava); + */ + bundle.add(glava) + .add(odcitki[i].qW) + .add(odcitki[i].qX) + .add(odcitki[i].qY) + .add(odcitki[i].qZ); + + sprintf(glava, "/ww/%d/bat", i); + bundle.add(glava) + .add(odcitki[i].bat); + + /* + Serial.printf("XaX: %i \n", odcitki[i].aX); + Serial.printf("XaY: %i \n", odcitki[i].aY); + Serial.printf("XaZ: %i \n", odcitki[i].aZ); + Serial.printf("XqX: %f \n", odcitki[i].qX); + Serial.printf("XqY: %f \n", odcitki[i].qY); + Serial.printf("XqZ: %f \n", odcitki[i].qZ); + Serial.printf("XqW: %f \n", odcitki[i].qW); + Serial.println(); + */ + + SLIPSerial.beginPacket(); + bundle.send(SLIPSerial); + SLIPSerial.endPacket(); + + bundle.empty(); + poslji[i] = false; + } + } + //delay(10); +}

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¬#lL>wJ|;oNyj3mG(^ZQ7N|&;DAlgJkH45IlcAD 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⩔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%0A;NyZQ4x(UspYttqbgU+u9LBh&RO%g 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