From 323aa18c0ee57cf5fee65511e45ae63d3d2a77ed Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 16 Jan 2014 14:16:38 -0800 Subject: [PATCH] remove MotionDriver and pthread libraries --- cmake/modules/FindMotionDriver.cmake | 44 - interface/CMakeLists.txt | 4 - .../external/MotionDriver/CMakeLists.txt | 14 - interface/external/MotionDriver/License.txt | 218 -- .../external/MotionDriver/include/dmpKey.h | 494 --- .../external/MotionDriver/include/dmpmap.h | 264 -- .../external/MotionDriver/include/inv_mpu.h | 127 - .../include/inv_mpu_dmp_motion_driver.h | 97 - .../external/MotionDriver/include/inv_tty.h | 22 - .../MotionDriver/lib/MacOS/libMotionDriver.a | Bin 59312 -> 0 bytes .../MotionDriver/lib/UNIX/libMotionDriver.a | Bin 62086 -> 0 bytes interface/external/MotionDriver/src/inv_mpu.c | 2798 ----------------- .../src/inv_mpu_dmp_motion_driver.c | 1373 -------- interface/external/MotionDriver/src/inv_tty.c | 113 - .../external/pthreads/WIN32/pthread_lib.lib | Bin 241598 -> 0 bytes interface/external/pthreads/include/pthread.h | 1403 --------- interface/external/pthreads/include/sched.h | 189 -- libraries/shared/src/NodeList.cpp | 1 - 18 files changed, 7161 deletions(-) delete mode 100644 cmake/modules/FindMotionDriver.cmake delete mode 100644 interface/external/MotionDriver/CMakeLists.txt delete mode 100644 interface/external/MotionDriver/License.txt delete mode 100644 interface/external/MotionDriver/include/dmpKey.h delete mode 100644 interface/external/MotionDriver/include/dmpmap.h delete mode 100644 interface/external/MotionDriver/include/inv_mpu.h delete mode 100644 interface/external/MotionDriver/include/inv_mpu_dmp_motion_driver.h delete mode 100644 interface/external/MotionDriver/include/inv_tty.h delete mode 100644 interface/external/MotionDriver/lib/MacOS/libMotionDriver.a delete mode 100644 interface/external/MotionDriver/lib/UNIX/libMotionDriver.a delete mode 100644 interface/external/MotionDriver/src/inv_mpu.c delete mode 100644 interface/external/MotionDriver/src/inv_mpu_dmp_motion_driver.c delete mode 100644 interface/external/MotionDriver/src/inv_tty.c delete mode 100644 interface/external/pthreads/WIN32/pthread_lib.lib delete mode 100644 interface/external/pthreads/include/pthread.h delete mode 100644 interface/external/pthreads/include/sched.h diff --git a/cmake/modules/FindMotionDriver.cmake b/cmake/modules/FindMotionDriver.cmake deleted file mode 100644 index b24511161b..0000000000 --- a/cmake/modules/FindMotionDriver.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# Try to find the MotionDriver library to access the InvenSense gyros -# -# You must provide a MOTIONDRIVER_ROOT_DIR which contains lib and include directories -# -# Once done this will define -# -# MOTIONDRIVER_FOUND - system found MotionDriver -# MOTIONDRIVER_INCLUDE_DIRS - the MotionDriver include directory -# MOTIONDRIVER_LIBRARIES - Link this to use MotionDriver -# -# Created on 7/9/2013 by Andrzej Kapolka -# Copyright (c) 2013 High Fidelity -# - -if (MOTIONDRIVER_LIBRARIES AND MOTIONDRIVER_INCLUDE_DIRS) - # in cache already - set(MOTIONDRIVER_FOUND TRUE) -else (MOTIONDRIVER_LIBRARIES AND MOTIONDRIVER_INCLUDE_DIRS) - find_path(MOTIONDRIVER_INCLUDE_DIRS inv_mpu.h ${MOTIONDRIVER_ROOT_DIR}/include) - - if (APPLE) - find_library(MOTIONDRIVER_LIBRARIES libMotionDriver.a ${MOTIONDRIVER_ROOT_DIR}/lib/MacOS/) - elseif (UNIX) - find_library(MOTIONDRIVER_LIBRARIES libMotionDriver.a ${MOTIONDRIVER_ROOT_DIR}/lib/UNIX/) - endif () - - if (MOTIONDRIVER_INCLUDE_DIRS AND MOTIONDRIVER_LIBRARIES) - set(MOTIONDRIVER_FOUND TRUE) - endif (MOTIONDRIVER_INCLUDE_DIRS AND MOTIONDRIVER_LIBRARIES) - - if (MOTIONDRIVER_FOUND) - if (NOT MOTIONDRIVER_FIND_QUIETLY) - message(STATUS "Found MotionDriver: ${MOTIONDRIVER_LIBRARIES}") - endif (NOT MOTIONDRIVER_FIND_QUIETLY) - else (MOTIONDRIVER_FOUND) - if (MOTIONDRIVER_FIND_REQUIRED) - message(FATAL_ERROR "Could not find MotionDriver") - endif (MOTIONDRIVER_FIND_REQUIRED) - endif (MOTIONDRIVER_FOUND) - - # show the MOTIONDRIVER_INCLUDE_DIRS and MOTIONDRIVER_LIBRARIES variables only in the advanced view - mark_as_advanced(MOTIONDRIVER_INCLUDE_DIRS MOTIONDRIVER_LIBRARIES) - -endif (MOTIONDRIVER_LIBRARIES AND MOTIONDRIVER_INCLUDE_DIRS) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 65fd74bc98..b1e4305cbf 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -10,7 +10,6 @@ project(${TARGET_NAME}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") set(FACESHIFT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/faceshift) set(LIBOVR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LibOVR) -set(MOTIONDRIVER_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/MotionDriver) set(SIXENSE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense) if (DEFINED ENV{JOB_ID}) @@ -128,7 +127,6 @@ link_hifi_library(script-engine ${TARGET_NAME} ${ROOT_DIR}) find_package(Faceshift) find_package(GLM REQUIRED) find_package(LibOVR) -find_package(MotionDriver) find_package(Sixense) find_package(ZLIB) @@ -166,7 +164,6 @@ include_directories( SYSTEM ${FACESHIFT_INCLUDE_DIRS} ${GLM_INCLUDE_DIRS} - ${MOTIONDRIVER_INCLUDE_DIRS} ) MESSAGE("here..." ${FACESHIFT_LIBRARIES} ) @@ -174,7 +171,6 @@ MESSAGE("here..." ${FACESHIFT_LIBRARIES} ) target_link_libraries( ${TARGET_NAME} ${FACESHIFT_LIBRARIES} - ${MOTIONDRIVER_LIBRARIES} ${ZLIB_LIBRARIES} ) diff --git a/interface/external/MotionDriver/CMakeLists.txt b/interface/external/MotionDriver/CMakeLists.txt deleted file mode 100644 index 521f3f8096..0000000000 --- a/interface/external/MotionDriver/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set(TARGET_NAME MotionDriver) -project(${TARGET_NAME}) - -# let the library know which device we're using -add_definitions(-DMPU9150) - -# grab the implemenation and header files -file(GLOB MOTION_DRIVER_SRCS include/*.h src/*.c) - -include_directories(include) - -add_library(${TARGET_NAME} ${MOTION_DRIVER_SRCS}) diff --git a/interface/external/MotionDriver/License.txt b/interface/external/MotionDriver/License.txt deleted file mode 100644 index ed2e2e1f24..0000000000 --- a/interface/external/MotionDriver/License.txt +++ /dev/null @@ -1,218 +0,0 @@ -SOFTWARE LICENSE AGREEMENT - -Unless you and InvenSense Corporation ("InvenSense") execute a separate written -software license agreement governing use of the accompanying software, this -software is licensed to you under the terms of this Software License -Agreement ("Agreement"). - -ANY USE, REPRODUCTION OR DISTRIBUTION OF THE SOFTWARE CONSTITUTES YOUR -ACCEPTANCE OF THIS AGREEMENT. - -1. DEFINITIONS. - -1.1. "InvenSense Product" means any of the proprietary integrated circuit -product(s) sold by InvenSense with which the Software was designed to be used, -or their successors. - -1.2. "Licensee" means you or if you are accepting on behalf of an entity -then the entity and its affiliates exercising rights under, and complying -with all of the terms of this Agreement. - -1.3. "Software" shall mean that software made available by InvenSense to -Licensee in binary code form with this Agreement. - -2. LICENSE GRANT; OWNERSHIP - -2.1. License Grants. Subject to the terms and conditions of this Agreement, -InvenSense hereby grants to Licensee a non-exclusive, non-transferable, -royalty-free license (i) to use and integrate the Software in conjunction -with any other software; and (ii) to reproduce and distribute the Software -complete, unmodified and only for use with a InvenSense Product. - -2.2. Restriction on Modification. If and to the extent that the Software is -designed to be compliant with any published communications standard -(including, without limitation, DOCSIS, HomePNA, IEEE, and ITU standards), -Licensee may not make any modifications to the Software that would cause the -Software or the accompanying InvenSense Products to be incompatible with such -standard. - -2.3. Restriction on Distribution. Licensee shall only distribute the -Software (a) under the terms of this Agreement and a copy of this Agreement -accompanies such distribution, and (b) agrees to defend and indemnify -InvenSense and its licensors from and against any damages, costs, liabilities, -settlement amounts and/or expenses (including attorneys' fees) incurred in -connection with any claim, lawsuit or action by any third party that arises -or results from the use or distribution of any and all Software by the -Licensee except as contemplated herein. - -2.4. Proprietary Notices. Licensee shall not remove, efface or obscure any -copyright or trademark notices from the Software. Licensee shall include -reproductions of the InvenSense copyright notice with each copy of the -Software, except where such Software is embedded in a manner not readily -accessible to the end user. Licensee acknowledges that any symbols, -trademarks, tradenames, and service marks adopted by InvenSense to identify the -Software belong to InvenSense and that Licensee shall have no rights therein. - -2.5. Ownership. InvenSense shall retain all right, title and interest, -including all intellectual property rights, in and to the Software. Licensee -hereby covenants that it will not assert any claim that the Software created -by or for InvenSense infringe any intellectual property right owned or -controlled by Licensee. - -2.6. No Other Rights Granted; Restrictions. Apart from the license rights -expressly set forth in this Agreement, InvenSense does not grant and Licensee -does not receive any ownership right, title or interest nor any security -interest or other interest in any intellectual property rights relating to -the Software, nor in any copy of any part of the foregoing. No license is -granted to Licensee in any human readable code of the Software (source code). -Licensee shall not (i) use, license, sell or otherwise distribute the -Software except as provided in this Agreement, (ii) attempt to reverse -engineer, decompile or disassemble any portion of the Software; or (iii) use -the Software or other material in violation of any applicable law or -regulation, including but not limited to any regulatory agency, such as FCC, -rules. - -3. NO WARRANTY OR SUPPORT - -3.1. No Warranty. THE SOFTWARE IS OFFERED "AS IS," AND INVENSENSE GRANTS AND -LICENSEE RECEIVES NO WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, BY STATUTE, -COMMUNICATION OR CONDUCT WITH LICENSEE, OR OTHERWISE. INVENSENSE SPECIFICALLY -DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A SPECIFIC -PURPOSE OR NONINFRINGEMENT CONCERNING THE SOFTWARE OR ANY UPGRADES TO OR -DOCUMENTATION FOR THE SOFTWARE. WITHOUT LIMITATION OF THE ABOVE, INVENSENSE -GRANTS NO WARRANTY THAT THE SOFTWARE IS ERROR-FREE OR WILL OPERATE WITHOUT -INTERRUPTION, AND GRANTS NO WARRANTY REGARDING ITS USE OR THE RESULTS -THEREFROM INCLUDING, WITHOUT LIMITATION, ITS CORRECTNESS, ACCURACY OR -RELIABILITY. - -3.2. No Support. Nothing in this agreement shall obligate InvenSense to -provide any support for the Software. InvenSense may, but shall be under no -obligation to, correct any defects in the Software and/or provide updates to -licensees of the Software. Licensee shall make reasonable efforts to -promptly report to InvenSense any defects it finds in the Software, as an aid -to creating improved revisions of the Software. - -3.3. Dangerous Applications. The Software is not designed, intended, or -certified for use in components of systems intended for the operation of -weapons, weapons systems, nuclear installations, means of mass -transportation, aviation, life-support computers or equipment (including -resuscitation equipment and surgical implants), pollution control, hazardous -substances management, or for any other dangerous application in which the -failure of the Software could create a situation where personal injury or -death may occur. Licensee understands that use of the Software in such -applications is fully at the risk of Licensee. - -4. TERM AND TERMINATION - -4.1. Termination. This Agreement will automatically terminate if Licensee -fails to comply with any of the terms and conditions hereof. In such event, -Licensee must destroy all copies of the Software and all of its component -parts. - -4.2. Effect Of Termination. Upon any termination of this Agreement, the -rights and licenses granted to Licensee under this Agreement shall -immediately terminate. - -4.3. Survival. The rights and obligations under this Agreement which by -their nature should survive termination will remain in effect after -expiration or termination of this Agreement. - -5. CONFIDENTIALITY - -5.1. Obligations. Licensee acknowledges and agrees that any documentation -relating to the Software, and any other information (if such other -information is identified as confidential or should be recognized as -confidential under the circumstances) provided to Licensee by InvenSense -hereunder (collectively, "Confidential Information") constitute the -confidential and proprietary information of InvenSense, and that Licensee's -protection thereof is an essential condition to Licensee's use and possession -of the Software. Licensee shall retain all Confidential Information in -strict confidence and not disclose it to any third party or use it in any way -except under a written agreement with terms and conditions at least as -protective as the terms of this Section. Licensee will exercise at least the -same amount of diligence in preserving the secrecy of the Confidential -Information as it uses in preserving the secrecy of its own most valuable -confidential information, but in no event less than reasonable diligence. -Information shall not be considered Confidential Information if and to the -extent that it: (i) was in the public domain at the time it was disclosed or -has entered the public domain through no fault of Licensee; (ii) was known to -Licensee, without restriction, at the time of disclosure as proven by the -files of Licensee in existence at the time of disclosure; or (iii) becomes -known to Licensee, without restriction, from a source other than InvenSense -without breach of this Agreement by Licensee and otherwise not in violation -of InvenSense's rights. - -5.2. Return of Confidential Information. Notwithstanding the foregoing, all -documents and other tangible objects containing or representing InvenSense -Confidential Information and all copies thereof which are in the possession -of Licensee shall be and remain the property of InvenSense, and shall be -promptly returned to InvenSense upon written request by InvenSense or upon -termination of this Agreement. - -6. LIMITATION OF LIABILITY -TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL INVENSENSE OR ANY OF -INVENSENSE'S LICENSORS HAVE ANY LIABILITY FOR ANY INDIRECT, INCIDENTAL, -SPECIAL, OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER FOR BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE) OR -OTHERWISE, ARISING OUT OF THIS AGREEMENT, INCLUDING BUT NOT LIMITED TO LOSS -OF PROFITS, EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. IN NO EVENT WILL INVENSENSE'S LIABILITY WHETHER IN CONTRACT, TORT -(INCLUDING NEGLIGENCE), OR OTHERWISE, EXCEED THE AMOUNT PAID BY LICENSEE FOR -SOFTWARE UNDER THIS AGREEMENT. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING -ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. - -7. MISCELLANEOUS - -7.1. Export Regulations. YOU UNDERSTAND AND AGREE THAT THE SOFTWARE IS -SUBJECT TO UNITED STATES AND OTHER APPLICABLE EXPORT-RELATED LAWS AND -REGULATIONS AND THAT YOU MAY NOT EXPORT, RE-EXPORT OR TRANSFER THE SOFTWARE -OR ANY DIRECT PRODUCT OF THE SOFTWARE EXCEPT AS PERMITTED UNDER THOSE LAWS. -WITHOUT LIMITING THE FOREGOING, EXPORT, RE-EXPORT OR TRANSFER OF THE SOFTWARE -TO CUBA, IRAN, NORTH KOREA, SUDAN AND SYRIA IS PROHIBITED. - -7.2 Assignment. This Agreement shall be binding upon and inure to the -benefit of the parties and their respective successors and assigns, provided, -however that Licensee may not assign this Agreement or any rights or -obligation hereunder, directly or indirectly, by operation of law or -otherwise, without the prior written consent of InvenSense, and any such -attempted assignment shall be void. Notwithstanding the foregoing, Licensee -may assign this Agreement to a successor to all or substantially all of its -business or assets to which this Agreement relates that is not a competitor -of InvenSense. - -7.3. Governing Law; Venue. This Agreement shall be governed by the laws of -California without regard to any conflict-of-laws rules, and the United -Nations Convention on Contracts for the International Sale of Goods is hereby -excluded. The sole jurisdiction and venue for actions related to the subject -matter hereof shall be the state and federal courts located in the County of -Orange, California, and both parties hereby consent to such jurisdiction and -venue. - -7.4. Severability. All terms and provisions of this Agreement shall, if -possible, be construed in a manner which makes them valid, but in the event -any term or provision of this Agreement is found by a court of competent -jurisdiction to be illegal or unenforceable, the validity or enforceability -of the remainder of this Agreement shall not be affected if the illegal or -unenforceable provision does not materially affect the intent of this -Agreement. If the illegal or unenforceable provision materially affects the -intent of the parties to this Agreement, this Agreement shall become -terminated. - -7.5. Equitable Relief. Licensee hereby acknowledges that its breach of this -Agreement would cause irreparable harm and significant injury to InvenSense -that may be difficult to ascertain and that a remedy at law would be -inadequate. Accordingly, Licensee agrees that InvenSense shall have the right -to seek and obtain immediate injunctive relief to enforce obligations under -the Agreement in addition to any other rights and remedies it may have. - -7.6. Waiver. The waiver of, or failure to enforce, any breach or default -hereunder shall not constitute the waiver of any other or subsequent breach -or default. - -7.7. Entire Agreement. This Agreement sets forth the entire Agreement -between the parties and supersedes any and all prior proposals, agreements -and representations between them, whether written or oral concerning the -Software. This Agreement may be changed only by mutual agreement of the -parties in writing. - - diff --git a/interface/external/MotionDriver/include/dmpKey.h b/interface/external/MotionDriver/include/dmpKey.h deleted file mode 100644 index 72f95d69d4..0000000000 --- a/interface/external/MotionDriver/include/dmpKey.h +++ /dev/null @@ -1,494 +0,0 @@ -/* - $License: - Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. - $ - */ -#ifndef DMPKEY_H__ -#define DMPKEY_H__ - -#define KEY_CFG_25 (0) -#define KEY_CFG_24 (KEY_CFG_25 + 1) -#define KEY_CFG_26 (KEY_CFG_24 + 1) -#define KEY_CFG_27 (KEY_CFG_26 + 1) -#define KEY_CFG_21 (KEY_CFG_27 + 1) -#define KEY_CFG_20 (KEY_CFG_21 + 1) -#define KEY_CFG_TAP4 (KEY_CFG_20 + 1) -#define KEY_CFG_TAP5 (KEY_CFG_TAP4 + 1) -#define KEY_CFG_TAP6 (KEY_CFG_TAP5 + 1) -#define KEY_CFG_TAP7 (KEY_CFG_TAP6 + 1) -#define KEY_CFG_TAP0 (KEY_CFG_TAP7 + 1) -#define KEY_CFG_TAP1 (KEY_CFG_TAP0 + 1) -#define KEY_CFG_TAP2 (KEY_CFG_TAP1 + 1) -#define KEY_CFG_TAP3 (KEY_CFG_TAP2 + 1) -#define KEY_CFG_TAP_QUANTIZE (KEY_CFG_TAP3 + 1) -#define KEY_CFG_TAP_JERK (KEY_CFG_TAP_QUANTIZE + 1) -#define KEY_CFG_DR_INT (KEY_CFG_TAP_JERK + 1) -#define KEY_CFG_AUTH (KEY_CFG_DR_INT + 1) -#define KEY_CFG_TAP_SAVE_ACCB (KEY_CFG_AUTH + 1) -#define KEY_CFG_TAP_CLEAR_STICKY (KEY_CFG_TAP_SAVE_ACCB + 1) -#define KEY_CFG_FIFO_ON_EVENT (KEY_CFG_TAP_CLEAR_STICKY + 1) -#define KEY_FCFG_ACCEL_INPUT (KEY_CFG_FIFO_ON_EVENT + 1) -#define KEY_FCFG_ACCEL_INIT (KEY_FCFG_ACCEL_INPUT + 1) -#define KEY_CFG_23 (KEY_FCFG_ACCEL_INIT + 1) -#define KEY_FCFG_1 (KEY_CFG_23 + 1) -#define KEY_FCFG_3 (KEY_FCFG_1 + 1) -#define KEY_FCFG_2 (KEY_FCFG_3 + 1) -#define KEY_CFG_3D (KEY_FCFG_2 + 1) -#define KEY_CFG_3B (KEY_CFG_3D + 1) -#define KEY_CFG_3C (KEY_CFG_3B + 1) -#define KEY_FCFG_5 (KEY_CFG_3C + 1) -#define KEY_FCFG_4 (KEY_FCFG_5 + 1) -#define KEY_FCFG_7 (KEY_FCFG_4 + 1) -#define KEY_FCFG_FSCALE (KEY_FCFG_7 + 1) -#define KEY_FCFG_AZ (KEY_FCFG_FSCALE + 1) -#define KEY_FCFG_6 (KEY_FCFG_AZ + 1) -#define KEY_FCFG_LSB4 (KEY_FCFG_6 + 1) -#define KEY_CFG_12 (KEY_FCFG_LSB4 + 1) -#define KEY_CFG_14 (KEY_CFG_12 + 1) -#define KEY_CFG_15 (KEY_CFG_14 + 1) -#define KEY_CFG_16 (KEY_CFG_15 + 1) -#define KEY_CFG_18 (KEY_CFG_16 + 1) -#define KEY_CFG_6 (KEY_CFG_18 + 1) -#define KEY_CFG_7 (KEY_CFG_6 + 1) -#define KEY_CFG_4 (KEY_CFG_7 + 1) -#define KEY_CFG_5 (KEY_CFG_4 + 1) -#define KEY_CFG_2 (KEY_CFG_5 + 1) -#define KEY_CFG_3 (KEY_CFG_2 + 1) -#define KEY_CFG_1 (KEY_CFG_3 + 1) -#define KEY_CFG_EXTERNAL (KEY_CFG_1 + 1) -#define KEY_CFG_8 (KEY_CFG_EXTERNAL + 1) -#define KEY_CFG_9 (KEY_CFG_8 + 1) -#define KEY_CFG_ORIENT_3 (KEY_CFG_9 + 1) -#define KEY_CFG_ORIENT_2 (KEY_CFG_ORIENT_3 + 1) -#define KEY_CFG_ORIENT_1 (KEY_CFG_ORIENT_2 + 1) -#define KEY_CFG_GYRO_SOURCE (KEY_CFG_ORIENT_1 + 1) -#define KEY_CFG_ORIENT_IRQ_1 (KEY_CFG_GYRO_SOURCE + 1) -#define KEY_CFG_ORIENT_IRQ_2 (KEY_CFG_ORIENT_IRQ_1 + 1) -#define KEY_CFG_ORIENT_IRQ_3 (KEY_CFG_ORIENT_IRQ_2 + 1) -#define KEY_FCFG_MAG_VAL (KEY_CFG_ORIENT_IRQ_3 + 1) -#define KEY_FCFG_MAG_MOV (KEY_FCFG_MAG_VAL + 1) -#define KEY_CFG_LP_QUAT (KEY_FCFG_MAG_MOV + 1) - -/* MPU6050 keys */ -#define KEY_CFG_ACCEL_FILTER (KEY_CFG_LP_QUAT + 1) -#define KEY_CFG_MOTION_BIAS (KEY_CFG_ACCEL_FILTER + 1) -#define KEY_TEMPLABEL (KEY_CFG_MOTION_BIAS + 1) - -#define KEY_D_0_22 (KEY_TEMPLABEL + 1) -#define KEY_D_0_24 (KEY_D_0_22 + 1) -#define KEY_D_0_36 (KEY_D_0_24 + 1) -#define KEY_D_0_52 (KEY_D_0_36 + 1) -#define KEY_D_0_96 (KEY_D_0_52 + 1) -#define KEY_D_0_104 (KEY_D_0_96 + 1) -#define KEY_D_0_108 (KEY_D_0_104 + 1) -#define KEY_D_0_163 (KEY_D_0_108 + 1) -#define KEY_D_0_188 (KEY_D_0_163 + 1) -#define KEY_D_0_192 (KEY_D_0_188 + 1) -#define KEY_D_0_224 (KEY_D_0_192 + 1) -#define KEY_D_0_228 (KEY_D_0_224 + 1) -#define KEY_D_0_232 (KEY_D_0_228 + 1) -#define KEY_D_0_236 (KEY_D_0_232 + 1) - -#define KEY_DMP_PREVPTAT (KEY_D_0_236 + 1) -#define KEY_D_1_2 (KEY_DMP_PREVPTAT + 1) -#define KEY_D_1_4 (KEY_D_1_2 + 1) -#define KEY_D_1_8 (KEY_D_1_4 + 1) -#define KEY_D_1_10 (KEY_D_1_8 + 1) -#define KEY_D_1_24 (KEY_D_1_10 + 1) -#define KEY_D_1_28 (KEY_D_1_24 + 1) -#define KEY_D_1_36 (KEY_D_1_28 + 1) -#define KEY_D_1_40 (KEY_D_1_36 + 1) -#define KEY_D_1_44 (KEY_D_1_40 + 1) -#define KEY_D_1_72 (KEY_D_1_44 + 1) -#define KEY_D_1_74 (KEY_D_1_72 + 1) -#define KEY_D_1_79 (KEY_D_1_74 + 1) -#define KEY_D_1_88 (KEY_D_1_79 + 1) -#define KEY_D_1_90 (KEY_D_1_88 + 1) -#define KEY_D_1_92 (KEY_D_1_90 + 1) -#define KEY_D_1_96 (KEY_D_1_92 + 1) -#define KEY_D_1_98 (KEY_D_1_96 + 1) -#define KEY_D_1_100 (KEY_D_1_98 + 1) -#define KEY_D_1_106 (KEY_D_1_100 + 1) -#define KEY_D_1_108 (KEY_D_1_106 + 1) -#define KEY_D_1_112 (KEY_D_1_108 + 1) -#define KEY_D_1_128 (KEY_D_1_112 + 1) -#define KEY_D_1_152 (KEY_D_1_128 + 1) -#define KEY_D_1_160 (KEY_D_1_152 + 1) -#define KEY_D_1_168 (KEY_D_1_160 + 1) -#define KEY_D_1_175 (KEY_D_1_168 + 1) -#define KEY_D_1_176 (KEY_D_1_175 + 1) -#define KEY_D_1_178 (KEY_D_1_176 + 1) -#define KEY_D_1_179 (KEY_D_1_178 + 1) -#define KEY_D_1_218 (KEY_D_1_179 + 1) -#define KEY_D_1_232 (KEY_D_1_218 + 1) -#define KEY_D_1_236 (KEY_D_1_232 + 1) -#define KEY_D_1_240 (KEY_D_1_236 + 1) -#define KEY_D_1_244 (KEY_D_1_240 + 1) -#define KEY_D_1_250 (KEY_D_1_244 + 1) -#define KEY_D_1_252 (KEY_D_1_250 + 1) -#define KEY_D_2_12 (KEY_D_1_252 + 1) -#define KEY_D_2_96 (KEY_D_2_12 + 1) -#define KEY_D_2_108 (KEY_D_2_96 + 1) -#define KEY_D_2_208 (KEY_D_2_108 + 1) -#define KEY_FLICK_MSG (KEY_D_2_208 + 1) -#define KEY_FLICK_COUNTER (KEY_FLICK_MSG + 1) -#define KEY_FLICK_LOWER (KEY_FLICK_COUNTER + 1) -#define KEY_CFG_FLICK_IN (KEY_FLICK_LOWER + 1) -#define KEY_FLICK_UPPER (KEY_CFG_FLICK_IN + 1) -#define KEY_CGNOTICE_INTR (KEY_FLICK_UPPER + 1) -#define KEY_D_2_224 (KEY_CGNOTICE_INTR + 1) -#define KEY_D_2_244 (KEY_D_2_224 + 1) -#define KEY_D_2_248 (KEY_D_2_244 + 1) -#define KEY_D_2_252 (KEY_D_2_248 + 1) - -#define KEY_D_GYRO_BIAS_X (KEY_D_2_252 + 1) -#define KEY_D_GYRO_BIAS_Y (KEY_D_GYRO_BIAS_X + 1) -#define KEY_D_GYRO_BIAS_Z (KEY_D_GYRO_BIAS_Y + 1) -#define KEY_D_ACC_BIAS_X (KEY_D_GYRO_BIAS_Z + 1) -#define KEY_D_ACC_BIAS_Y (KEY_D_ACC_BIAS_X + 1) -#define KEY_D_ACC_BIAS_Z (KEY_D_ACC_BIAS_Y + 1) -#define KEY_D_GYRO_ENABLE (KEY_D_ACC_BIAS_Z + 1) -#define KEY_D_ACCEL_ENABLE (KEY_D_GYRO_ENABLE + 1) -#define KEY_D_QUAT_ENABLE (KEY_D_ACCEL_ENABLE +1) -#define KEY_D_OUTPUT_ENABLE (KEY_D_QUAT_ENABLE + 1) -#define KEY_D_CR_TIME_G (KEY_D_OUTPUT_ENABLE + 1) -#define KEY_D_CR_TIME_A (KEY_D_CR_TIME_G + 1) -#define KEY_D_CR_TIME_Q (KEY_D_CR_TIME_A + 1) -#define KEY_D_CS_TAX (KEY_D_CR_TIME_Q + 1) -#define KEY_D_CS_TAY (KEY_D_CS_TAX + 1) -#define KEY_D_CS_TAZ (KEY_D_CS_TAY + 1) -#define KEY_D_CS_TGX (KEY_D_CS_TAZ + 1) -#define KEY_D_CS_TGY (KEY_D_CS_TGX + 1) -#define KEY_D_CS_TGZ (KEY_D_CS_TGY + 1) -#define KEY_D_CS_TQ0 (KEY_D_CS_TGZ + 1) -#define KEY_D_CS_TQ1 (KEY_D_CS_TQ0 + 1) -#define KEY_D_CS_TQ2 (KEY_D_CS_TQ1 + 1) -#define KEY_D_CS_TQ3 (KEY_D_CS_TQ2 + 1) - -/* Compass keys */ -#define KEY_CPASS_BIAS_X (KEY_D_CS_TQ3 + 1) -#define KEY_CPASS_BIAS_Y (KEY_CPASS_BIAS_X + 1) -#define KEY_CPASS_BIAS_Z (KEY_CPASS_BIAS_Y + 1) -#define KEY_CPASS_MTX_00 (KEY_CPASS_BIAS_Z + 1) -#define KEY_CPASS_MTX_01 (KEY_CPASS_MTX_00 + 1) -#define KEY_CPASS_MTX_02 (KEY_CPASS_MTX_01 + 1) -#define KEY_CPASS_MTX_10 (KEY_CPASS_MTX_02 + 1) -#define KEY_CPASS_MTX_11 (KEY_CPASS_MTX_10 + 1) -#define KEY_CPASS_MTX_12 (KEY_CPASS_MTX_11 + 1) -#define KEY_CPASS_MTX_20 (KEY_CPASS_MTX_12 + 1) -#define KEY_CPASS_MTX_21 (KEY_CPASS_MTX_20 + 1) -#define KEY_CPASS_MTX_22 (KEY_CPASS_MTX_21 + 1) - -/* Gesture Keys */ -#define KEY_DMP_TAPW_MIN (KEY_CPASS_MTX_22 + 1) -#define KEY_DMP_TAP_THR_X (KEY_DMP_TAPW_MIN + 1) -#define KEY_DMP_TAP_THR_Y (KEY_DMP_TAP_THR_X + 1) -#define KEY_DMP_TAP_THR_Z (KEY_DMP_TAP_THR_Y + 1) -#define KEY_DMP_SH_TH_Y (KEY_DMP_TAP_THR_Z + 1) -#define KEY_DMP_SH_TH_X (KEY_DMP_SH_TH_Y + 1) -#define KEY_DMP_SH_TH_Z (KEY_DMP_SH_TH_X + 1) -#define KEY_DMP_ORIENT (KEY_DMP_SH_TH_Z + 1) -#define KEY_D_ACT0 (KEY_DMP_ORIENT + 1) -#define KEY_D_ACSX (KEY_D_ACT0 + 1) -#define KEY_D_ACSY (KEY_D_ACSX + 1) -#define KEY_D_ACSZ (KEY_D_ACSY + 1) - -#define KEY_X_GRT_Y_TMP (KEY_D_ACSZ + 1) -#define KEY_SKIP_X_GRT_Y_TMP (KEY_X_GRT_Y_TMP + 1) -#define KEY_SKIP_END_COMPARE (KEY_SKIP_X_GRT_Y_TMP + 1) -#define KEY_END_COMPARE_Y_X_TMP2 (KEY_SKIP_END_COMPARE + 1) -#define KEY_CFG_ANDROID_ORIENT_INT (KEY_END_COMPARE_Y_X_TMP2 + 1) -#define KEY_NO_ORIENT_INTERRUPT (KEY_CFG_ANDROID_ORIENT_INT + 1) -#define KEY_END_COMPARE_Y_X_TMP (KEY_NO_ORIENT_INTERRUPT + 1) -#define KEY_END_ORIENT_1 (KEY_END_COMPARE_Y_X_TMP + 1) -#define KEY_END_COMPARE_Y_X (KEY_END_ORIENT_1 + 1) -#define KEY_END_ORIENT (KEY_END_COMPARE_Y_X + 1) -#define KEY_X_GRT_Y (KEY_END_ORIENT + 1) -#define KEY_NOT_TIME_MINUS_1 (KEY_X_GRT_Y + 1) -#define KEY_END_COMPARE_Y_X_TMP3 (KEY_NOT_TIME_MINUS_1 + 1) -#define KEY_X_GRT_Y_TMP2 (KEY_END_COMPARE_Y_X_TMP3 + 1) - -/* Authenticate Keys */ -#define KEY_D_AUTH_OUT (KEY_X_GRT_Y_TMP2 + 1) -#define KEY_D_AUTH_IN (KEY_D_AUTH_OUT + 1) -#define KEY_D_AUTH_A (KEY_D_AUTH_IN + 1) -#define KEY_D_AUTH_B (KEY_D_AUTH_A + 1) - -/* Pedometer standalone only keys */ -#define KEY_D_PEDSTD_BP_B (KEY_D_AUTH_B + 1) -#define KEY_D_PEDSTD_HP_A (KEY_D_PEDSTD_BP_B + 1) -#define KEY_D_PEDSTD_HP_B (KEY_D_PEDSTD_HP_A + 1) -#define KEY_D_PEDSTD_BP_A4 (KEY_D_PEDSTD_HP_B + 1) -#define KEY_D_PEDSTD_BP_A3 (KEY_D_PEDSTD_BP_A4 + 1) -#define KEY_D_PEDSTD_BP_A2 (KEY_D_PEDSTD_BP_A3 + 1) -#define KEY_D_PEDSTD_BP_A1 (KEY_D_PEDSTD_BP_A2 + 1) -#define KEY_D_PEDSTD_INT_THRSH (KEY_D_PEDSTD_BP_A1 + 1) -#define KEY_D_PEDSTD_CLIP (KEY_D_PEDSTD_INT_THRSH + 1) -#define KEY_D_PEDSTD_SB (KEY_D_PEDSTD_CLIP + 1) -#define KEY_D_PEDSTD_SB_TIME (KEY_D_PEDSTD_SB + 1) -#define KEY_D_PEDSTD_PEAKTHRSH (KEY_D_PEDSTD_SB_TIME + 1) -#define KEY_D_PEDSTD_TIML (KEY_D_PEDSTD_PEAKTHRSH + 1) -#define KEY_D_PEDSTD_TIMH (KEY_D_PEDSTD_TIML + 1) -#define KEY_D_PEDSTD_PEAK (KEY_D_PEDSTD_TIMH + 1) -#define KEY_D_PEDSTD_TIMECTR (KEY_D_PEDSTD_PEAK + 1) -#define KEY_D_PEDSTD_STEPCTR (KEY_D_PEDSTD_TIMECTR + 1) -#define KEY_D_PEDSTD_WALKTIME (KEY_D_PEDSTD_STEPCTR + 1) -#define KEY_D_PEDSTD_DECI (KEY_D_PEDSTD_WALKTIME + 1) - -/*Host Based No Motion*/ -#define KEY_D_HOST_NO_MOT (KEY_D_PEDSTD_DECI + 1) - -/* EIS keys */ -#define KEY_P_EIS_FIFO_FOOTER (KEY_D_HOST_NO_MOT + 1) -#define KEY_P_EIS_FIFO_YSHIFT (KEY_P_EIS_FIFO_FOOTER + 1) -#define KEY_P_EIS_DATA_RATE (KEY_P_EIS_FIFO_YSHIFT + 1) -#define KEY_P_EIS_FIFO_XSHIFT (KEY_P_EIS_DATA_RATE + 1) -#define KEY_P_EIS_FIFO_SYNC (KEY_P_EIS_FIFO_XSHIFT + 1) -#define KEY_P_EIS_FIFO_ZSHIFT (KEY_P_EIS_FIFO_SYNC + 1) -#define KEY_P_EIS_FIFO_READY (KEY_P_EIS_FIFO_ZSHIFT + 1) -#define KEY_DMP_FOOTER (KEY_P_EIS_FIFO_READY + 1) -#define KEY_DMP_INTX_HC (KEY_DMP_FOOTER + 1) -#define KEY_DMP_INTX_PH (KEY_DMP_INTX_HC + 1) -#define KEY_DMP_INTX_SH (KEY_DMP_INTX_PH + 1) -#define KEY_DMP_AINV_SH (KEY_DMP_INTX_SH + 1) -#define KEY_DMP_A_INV_XH (KEY_DMP_AINV_SH + 1) -#define KEY_DMP_AINV_PH (KEY_DMP_A_INV_XH + 1) -#define KEY_DMP_CTHX_H (KEY_DMP_AINV_PH + 1) -#define KEY_DMP_CTHY_H (KEY_DMP_CTHX_H + 1) -#define KEY_DMP_CTHZ_H (KEY_DMP_CTHY_H + 1) -#define KEY_DMP_NCTHX_H (KEY_DMP_CTHZ_H + 1) -#define KEY_DMP_NCTHY_H (KEY_DMP_NCTHX_H + 1) -#define KEY_DMP_NCTHZ_H (KEY_DMP_NCTHY_H + 1) -#define KEY_DMP_CTSQ_XH (KEY_DMP_NCTHZ_H + 1) -#define KEY_DMP_CTSQ_YH (KEY_DMP_CTSQ_XH + 1) -#define KEY_DMP_CTSQ_ZH (KEY_DMP_CTSQ_YH + 1) -#define KEY_DMP_INTX_H (KEY_DMP_CTSQ_ZH + 1) -#define KEY_DMP_INTY_H (KEY_DMP_INTX_H + 1) -#define KEY_DMP_INTZ_H (KEY_DMP_INTY_H + 1) -//#define KEY_DMP_HPX_H (KEY_DMP_INTZ_H + 1) -//#define KEY_DMP_HPY_H (KEY_DMP_HPX_H + 1) -//#define KEY_DMP_HPZ_H (KEY_DMP_HPY_H + 1) - -/* Stream keys */ -#define KEY_STREAM_P_GYRO_Z (KEY_DMP_INTZ_H + 1) -#define KEY_STREAM_P_GYRO_Y (KEY_STREAM_P_GYRO_Z + 1) -#define KEY_STREAM_P_GYRO_X (KEY_STREAM_P_GYRO_Y + 1) -#define KEY_STREAM_P_TEMP (KEY_STREAM_P_GYRO_X + 1) -#define KEY_STREAM_P_AUX_Y (KEY_STREAM_P_TEMP + 1) -#define KEY_STREAM_P_AUX_X (KEY_STREAM_P_AUX_Y + 1) -#define KEY_STREAM_P_AUX_Z (KEY_STREAM_P_AUX_X + 1) -#define KEY_STREAM_P_ACCEL_Y (KEY_STREAM_P_AUX_Z + 1) -#define KEY_STREAM_P_ACCEL_X (KEY_STREAM_P_ACCEL_Y + 1) -#define KEY_STREAM_P_FOOTER (KEY_STREAM_P_ACCEL_X + 1) -#define KEY_STREAM_P_ACCEL_Z (KEY_STREAM_P_FOOTER + 1) - -#define NUM_KEYS (KEY_STREAM_P_ACCEL_Z + 1) - -typedef struct { - unsigned short key; - unsigned short addr; -} tKeyLabel; - -#define DINA0A 0x0a -#define DINA22 0x22 -#define DINA42 0x42 -#define DINA5A 0x5a - -#define DINA06 0x06 -#define DINA0E 0x0e -#define DINA16 0x16 -#define DINA1E 0x1e -#define DINA26 0x26 -#define DINA2E 0x2e -#define DINA36 0x36 -#define DINA3E 0x3e -#define DINA46 0x46 -#define DINA4E 0x4e -#define DINA56 0x56 -#define DINA5E 0x5e -#define DINA66 0x66 -#define DINA6E 0x6e -#define DINA76 0x76 -#define DINA7E 0x7e - -#define DINA00 0x00 -#define DINA08 0x08 -#define DINA10 0x10 -#define DINA18 0x18 -#define DINA20 0x20 -#define DINA28 0x28 -#define DINA30 0x30 -#define DINA38 0x38 -#define DINA40 0x40 -#define DINA48 0x48 -#define DINA50 0x50 -#define DINA58 0x58 -#define DINA60 0x60 -#define DINA68 0x68 -#define DINA70 0x70 -#define DINA78 0x78 - -#define DINA04 0x04 -#define DINA0C 0x0c -#define DINA14 0x14 -#define DINA1C 0x1C -#define DINA24 0x24 -#define DINA2C 0x2c -#define DINA34 0x34 -#define DINA3C 0x3c -#define DINA44 0x44 -#define DINA4C 0x4c -#define DINA54 0x54 -#define DINA5C 0x5c -#define DINA64 0x64 -#define DINA6C 0x6c -#define DINA74 0x74 -#define DINA7C 0x7c - -#define DINA01 0x01 -#define DINA09 0x09 -#define DINA11 0x11 -#define DINA19 0x19 -#define DINA21 0x21 -#define DINA29 0x29 -#define DINA31 0x31 -#define DINA39 0x39 -#define DINA41 0x41 -#define DINA49 0x49 -#define DINA51 0x51 -#define DINA59 0x59 -#define DINA61 0x61 -#define DINA69 0x69 -#define DINA71 0x71 -#define DINA79 0x79 - -#define DINA25 0x25 -#define DINA2D 0x2d -#define DINA35 0x35 -#define DINA3D 0x3d -#define DINA4D 0x4d -#define DINA55 0x55 -#define DINA5D 0x5D -#define DINA6D 0x6d -#define DINA75 0x75 -#define DINA7D 0x7d - -#define DINADC 0xdc -#define DINAF2 0xf2 -#define DINAAB 0xab -#define DINAAA 0xaa -#define DINAF1 0xf1 -#define DINADF 0xdf -#define DINADA 0xda -#define DINAB1 0xb1 -#define DINAB9 0xb9 -#define DINAF3 0xf3 -#define DINA8B 0x8b -#define DINAA3 0xa3 -#define DINA91 0x91 -#define DINAB6 0xb6 -#define DINAB4 0xb4 - - -#define DINC00 0x00 -#define DINC01 0x01 -#define DINC02 0x02 -#define DINC03 0x03 -#define DINC08 0x08 -#define DINC09 0x09 -#define DINC0A 0x0a -#define DINC0B 0x0b -#define DINC10 0x10 -#define DINC11 0x11 -#define DINC12 0x12 -#define DINC13 0x13 -#define DINC18 0x18 -#define DINC19 0x19 -#define DINC1A 0x1a -#define DINC1B 0x1b - -#define DINC20 0x20 -#define DINC21 0x21 -#define DINC22 0x22 -#define DINC23 0x23 -#define DINC28 0x28 -#define DINC29 0x29 -#define DINC2A 0x2a -#define DINC2B 0x2b -#define DINC30 0x30 -#define DINC31 0x31 -#define DINC32 0x32 -#define DINC33 0x33 -#define DINC38 0x38 -#define DINC39 0x39 -#define DINC3A 0x3a -#define DINC3B 0x3b - -#define DINC40 0x40 -#define DINC41 0x41 -#define DINC42 0x42 -#define DINC43 0x43 -#define DINC48 0x48 -#define DINC49 0x49 -#define DINC4A 0x4a -#define DINC4B 0x4b -#define DINC50 0x50 -#define DINC51 0x51 -#define DINC52 0x52 -#define DINC53 0x53 -#define DINC58 0x58 -#define DINC59 0x59 -#define DINC5A 0x5a -#define DINC5B 0x5b - -#define DINC60 0x60 -#define DINC61 0x61 -#define DINC62 0x62 -#define DINC63 0x63 -#define DINC68 0x68 -#define DINC69 0x69 -#define DINC6A 0x6a -#define DINC6B 0x6b -#define DINC70 0x70 -#define DINC71 0x71 -#define DINC72 0x72 -#define DINC73 0x73 -#define DINC78 0x78 -#define DINC79 0x79 -#define DINC7A 0x7a -#define DINC7B 0x7b - -#define DIND40 0x40 - - -#define DINA80 0x80 -#define DINA90 0x90 -#define DINAA0 0xa0 -#define DINAC9 0xc9 -#define DINACB 0xcb -#define DINACD 0xcd -#define DINACF 0xcf -#define DINAC8 0xc8 -#define DINACA 0xca -#define DINACC 0xcc -#define DINACE 0xce -#define DINAD8 0xd8 -#define DINADD 0xdd -#define DINAF8 0xf0 -#define DINAFE 0xfe - -#define DINBF8 0xf8 -#define DINAC0 0xb0 -#define DINAC1 0xb1 -#define DINAC2 0xb4 -#define DINAC3 0xb5 -#define DINAC4 0xb8 -#define DINAC5 0xb9 -#define DINBC0 0xc0 -#define DINBC2 0xc2 -#define DINBC4 0xc4 -#define DINBC6 0xc6 - - - -#endif // DMPKEY_H__ diff --git a/interface/external/MotionDriver/include/dmpmap.h b/interface/external/MotionDriver/include/dmpmap.h deleted file mode 100644 index f63e140398..0000000000 --- a/interface/external/MotionDriver/include/dmpmap.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - $License: - Copyright (C) 2011 InvenSense Corporation, All Rights Reserved. - $ - */ -#ifndef DMPMAP_H -#define DMPMAP_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define DMP_PTAT 0 -#define DMP_XGYR 2 -#define DMP_YGYR 4 -#define DMP_ZGYR 6 -#define DMP_XACC 8 -#define DMP_YACC 10 -#define DMP_ZACC 12 -#define DMP_ADC1 14 -#define DMP_ADC2 16 -#define DMP_ADC3 18 -#define DMP_BIASUNC 20 -#define DMP_FIFORT 22 -#define DMP_INVGSFH 24 -#define DMP_INVGSFL 26 -#define DMP_1H 28 -#define DMP_1L 30 -#define DMP_BLPFSTCH 32 -#define DMP_BLPFSTCL 34 -#define DMP_BLPFSXH 36 -#define DMP_BLPFSXL 38 -#define DMP_BLPFSYH 40 -#define DMP_BLPFSYL 42 -#define DMP_BLPFSZH 44 -#define DMP_BLPFSZL 46 -#define DMP_BLPFMTC 48 -#define DMP_SMC 50 -#define DMP_BLPFMXH 52 -#define DMP_BLPFMXL 54 -#define DMP_BLPFMYH 56 -#define DMP_BLPFMYL 58 -#define DMP_BLPFMZH 60 -#define DMP_BLPFMZL 62 -#define DMP_BLPFC 64 -#define DMP_SMCTH 66 -#define DMP_0H2 68 -#define DMP_0L2 70 -#define DMP_BERR2H 72 -#define DMP_BERR2L 74 -#define DMP_BERR2NH 76 -#define DMP_SMCINC 78 -#define DMP_ANGVBXH 80 -#define DMP_ANGVBXL 82 -#define DMP_ANGVBYH 84 -#define DMP_ANGVBYL 86 -#define DMP_ANGVBZH 88 -#define DMP_ANGVBZL 90 -#define DMP_BERR1H 92 -#define DMP_BERR1L 94 -#define DMP_ATCH 96 -#define DMP_BIASUNCSF 98 -#define DMP_ACT2H 100 -#define DMP_ACT2L 102 -#define DMP_GSFH 104 -#define DMP_GSFL 106 -#define DMP_GH 108 -#define DMP_GL 110 -#define DMP_0_5H 112 -#define DMP_0_5L 114 -#define DMP_0_0H 116 -#define DMP_0_0L 118 -#define DMP_1_0H 120 -#define DMP_1_0L 122 -#define DMP_1_5H 124 -#define DMP_1_5L 126 -#define DMP_TMP1AH 128 -#define DMP_TMP1AL 130 -#define DMP_TMP2AH 132 -#define DMP_TMP2AL 134 -#define DMP_TMP3AH 136 -#define DMP_TMP3AL 138 -#define DMP_TMP4AH 140 -#define DMP_TMP4AL 142 -#define DMP_XACCW 144 -#define DMP_TMP5 146 -#define DMP_XACCB 148 -#define DMP_TMP8 150 -#define DMP_YACCB 152 -#define DMP_TMP9 154 -#define DMP_ZACCB 156 -#define DMP_TMP10 158 -#define DMP_DZH 160 -#define DMP_DZL 162 -#define DMP_XGCH 164 -#define DMP_XGCL 166 -#define DMP_YGCH 168 -#define DMP_YGCL 170 -#define DMP_ZGCH 172 -#define DMP_ZGCL 174 -#define DMP_YACCW 176 -#define DMP_TMP7 178 -#define DMP_AFB1H 180 -#define DMP_AFB1L 182 -#define DMP_AFB2H 184 -#define DMP_AFB2L 186 -#define DMP_MAGFBH 188 -#define DMP_MAGFBL 190 -#define DMP_QT1H 192 -#define DMP_QT1L 194 -#define DMP_QT2H 196 -#define DMP_QT2L 198 -#define DMP_QT3H 200 -#define DMP_QT3L 202 -#define DMP_QT4H 204 -#define DMP_QT4L 206 -#define DMP_CTRL1H 208 -#define DMP_CTRL1L 210 -#define DMP_CTRL2H 212 -#define DMP_CTRL2L 214 -#define DMP_CTRL3H 216 -#define DMP_CTRL3L 218 -#define DMP_CTRL4H 220 -#define DMP_CTRL4L 222 -#define DMP_CTRLS1 224 -#define DMP_CTRLSF1 226 -#define DMP_CTRLS2 228 -#define DMP_CTRLSF2 230 -#define DMP_CTRLS3 232 -#define DMP_CTRLSFNLL 234 -#define DMP_CTRLS4 236 -#define DMP_CTRLSFNL2 238 -#define DMP_CTRLSFNL 240 -#define DMP_TMP30 242 -#define DMP_CTRLSFJT 244 -#define DMP_TMP31 246 -#define DMP_TMP11 248 -#define DMP_CTRLSF2_2 250 -#define DMP_TMP12 252 -#define DMP_CTRLSF1_2 254 -#define DMP_PREVPTAT 256 -#define DMP_ACCZB 258 -#define DMP_ACCXB 264 -#define DMP_ACCYB 266 -#define DMP_1HB 272 -#define DMP_1LB 274 -#define DMP_0H 276 -#define DMP_0L 278 -#define DMP_ASR22H 280 -#define DMP_ASR22L 282 -#define DMP_ASR6H 284 -#define DMP_ASR6L 286 -#define DMP_TMP13 288 -#define DMP_TMP14 290 -#define DMP_FINTXH 292 -#define DMP_FINTXL 294 -#define DMP_FINTYH 296 -#define DMP_FINTYL 298 -#define DMP_FINTZH 300 -#define DMP_FINTZL 302 -#define DMP_TMP1BH 304 -#define DMP_TMP1BL 306 -#define DMP_TMP2BH 308 -#define DMP_TMP2BL 310 -#define DMP_TMP3BH 312 -#define DMP_TMP3BL 314 -#define DMP_TMP4BH 316 -#define DMP_TMP4BL 318 -#define DMP_STXG 320 -#define DMP_ZCTXG 322 -#define DMP_STYG 324 -#define DMP_ZCTYG 326 -#define DMP_STZG 328 -#define DMP_ZCTZG 330 -#define DMP_CTRLSFJT2 332 -#define DMP_CTRLSFJTCNT 334 -#define DMP_PVXG 336 -#define DMP_TMP15 338 -#define DMP_PVYG 340 -#define DMP_TMP16 342 -#define DMP_PVZG 344 -#define DMP_TMP17 346 -#define DMP_MNMFLAGH 352 -#define DMP_MNMFLAGL 354 -#define DMP_MNMTMH 356 -#define DMP_MNMTML 358 -#define DMP_MNMTMTHRH 360 -#define DMP_MNMTMTHRL 362 -#define DMP_MNMTHRH 364 -#define DMP_MNMTHRL 366 -#define DMP_ACCQD4H 368 -#define DMP_ACCQD4L 370 -#define DMP_ACCQD5H 372 -#define DMP_ACCQD5L 374 -#define DMP_ACCQD6H 376 -#define DMP_ACCQD6L 378 -#define DMP_ACCQD7H 380 -#define DMP_ACCQD7L 382 -#define DMP_ACCQD0H 384 -#define DMP_ACCQD0L 386 -#define DMP_ACCQD1H 388 -#define DMP_ACCQD1L 390 -#define DMP_ACCQD2H 392 -#define DMP_ACCQD2L 394 -#define DMP_ACCQD3H 396 -#define DMP_ACCQD3L 398 -#define DMP_XN2H 400 -#define DMP_XN2L 402 -#define DMP_XN1H 404 -#define DMP_XN1L 406 -#define DMP_YN2H 408 -#define DMP_YN2L 410 -#define DMP_YN1H 412 -#define DMP_YN1L 414 -#define DMP_YH 416 -#define DMP_YL 418 -#define DMP_B0H 420 -#define DMP_B0L 422 -#define DMP_A1H 424 -#define DMP_A1L 426 -#define DMP_A2H 428 -#define DMP_A2L 430 -#define DMP_SEM1 432 -#define DMP_FIFOCNT 434 -#define DMP_SH_TH_X 436 -#define DMP_PACKET 438 -#define DMP_SH_TH_Y 440 -#define DMP_FOOTER 442 -#define DMP_SH_TH_Z 444 -#define DMP_TEMP29 448 -#define DMP_TEMP30 450 -#define DMP_XACCB_PRE 452 -#define DMP_XACCB_PREL 454 -#define DMP_YACCB_PRE 456 -#define DMP_YACCB_PREL 458 -#define DMP_ZACCB_PRE 460 -#define DMP_ZACCB_PREL 462 -#define DMP_TMP22 464 -#define DMP_TAP_TIMER 466 -#define DMP_TAP_THX 468 -#define DMP_TAP_THY 472 -#define DMP_TAP_THZ 476 -#define DMP_TAPW_MIN 478 -#define DMP_TMP25 480 -#define DMP_TMP26 482 -#define DMP_TMP27 484 -#define DMP_TMP28 486 -#define DMP_ORIENT 488 -#define DMP_THRSH 490 -#define DMP_ENDIANH 492 -#define DMP_ENDIANL 494 -#define DMP_BLPFNMTCH 496 -#define DMP_BLPFNMTCL 498 -#define DMP_BLPFNMXH 500 -#define DMP_BLPFNMXL 502 -#define DMP_BLPFNMYH 504 -#define DMP_BLPFNMYL 506 -#define DMP_BLPFNMZH 508 -#define DMP_BLPFNMZL 510 -#ifdef __cplusplus -} -#endif -#endif // DMPMAP_H diff --git a/interface/external/MotionDriver/include/inv_mpu.h b/interface/external/MotionDriver/include/inv_mpu.h deleted file mode 100644 index 9610124f04..0000000000 --- a/interface/external/MotionDriver/include/inv_mpu.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - $License: - Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. - See included License.txt for License information. - $ - */ -/** - * @addtogroup DRIVERS Sensor Driver Layer - * @brief Hardware drivers to communicate with sensors via I2C. - * - * @{ - * @file inv_mpu.h - * @brief An I2C-based driver for Invensense gyroscopes. - * @details This driver currently works for the following devices: - * MPU6050 - * MPU6500 - * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus) - * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus) - */ - -#ifndef _INV_MPU_H_ -#define _INV_MPU_H_ - -#define INV_X_GYRO (0x40) -#define INV_Y_GYRO (0x20) -#define INV_Z_GYRO (0x10) -#define INV_XYZ_GYRO (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO) -#define INV_XYZ_ACCEL (0x08) -#define INV_XYZ_COMPASS (0x01) - -struct int_param_s { -#if defined EMPL_TARGET_MSP430 || defined MOTION_DRIVER_TARGET_MSP430 - void (*cb)(void); - unsigned short pin; - unsigned char lp_exit; - unsigned char active_low; -#elif defined EMPL_TARGET_UC3L0 - unsigned long pin; - void (*cb)(volatile void*); - void *arg; -#endif -}; - -#define MPU_INT_STATUS_DATA_READY (0x0001) -#define MPU_INT_STATUS_DMP (0x0002) -#define MPU_INT_STATUS_PLL_READY (0x0004) -#define MPU_INT_STATUS_I2C_MST (0x0008) -#define MPU_INT_STATUS_FIFO_OVERFLOW (0x0010) -#define MPU_INT_STATUS_ZMOT (0x0020) -#define MPU_INT_STATUS_MOT (0x0040) -#define MPU_INT_STATUS_FREE_FALL (0x0080) -#define MPU_INT_STATUS_DMP_0 (0x0100) -#define MPU_INT_STATUS_DMP_1 (0x0200) -#define MPU_INT_STATUS_DMP_2 (0x0400) -#define MPU_INT_STATUS_DMP_3 (0x0800) -#define MPU_INT_STATUS_DMP_4 (0x1000) -#define MPU_INT_STATUS_DMP_5 (0x2000) - -/* Set up APIs */ -int mpu_init(struct int_param_s *int_param); -int mpu_init_slave(void); -int mpu_set_bypass(unsigned char bypass_on); - -/* Configuration APIs */ -int mpu_lp_accel_mode(unsigned char rate); -int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, - unsigned char lpa_freq); -int mpu_set_int_level(unsigned char active_low); -int mpu_set_int_latched(unsigned char enable); - -int mpu_set_dmp_state(unsigned char enable); -int mpu_get_dmp_state(unsigned char *enabled); - -int mpu_get_lpf(unsigned short *lpf); -int mpu_set_lpf(unsigned short lpf); - -int mpu_get_gyro_fsr(unsigned short *fsr); -int mpu_set_gyro_fsr(unsigned short fsr); - -int mpu_get_accel_fsr(unsigned char *fsr); -int mpu_set_accel_fsr(unsigned char fsr); - -int mpu_get_compass_fsr(unsigned short *fsr); - -int mpu_get_gyro_sens(float *sens); -int mpu_get_accel_sens(unsigned short *sens); - -int mpu_get_sample_rate(unsigned short *rate); -int mpu_set_sample_rate(unsigned short rate); -int mpu_get_compass_sample_rate(unsigned short *rate); -int mpu_set_compass_sample_rate(unsigned short rate); - -int mpu_get_fifo_config(unsigned char *sensors); -int mpu_configure_fifo(unsigned char sensors); - -int mpu_get_power_state(unsigned char *power_on); -int mpu_set_sensors(unsigned char sensors); - -int mpu_set_accel_bias(const long *accel_bias); - -/* Data getter/setter APIs */ -int mpu_get_gyro_reg(short *data, unsigned long *timestamp); -int mpu_get_accel_reg(short *data, unsigned long *timestamp); -int mpu_get_compass_reg(short *data, unsigned long *timestamp); -int mpu_get_temperature(long *data, unsigned long *timestamp); - -int mpu_get_int_status(short *status); -int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, - unsigned char *sensors, unsigned char *more); -int mpu_read_fifo_stream(unsigned short length, unsigned char *data, - unsigned char *more); -int mpu_reset_fifo(void); - -int mpu_write_mem(unsigned short mem_addr, unsigned short length, - unsigned char *data); -int mpu_read_mem(unsigned short mem_addr, unsigned short length, - unsigned char *data); -int mpu_load_firmware(unsigned short length, const unsigned char *firmware, - unsigned short start_addr, unsigned short sample_rate); - -int mpu_reg_dump(void); -int mpu_read_reg(unsigned char reg, unsigned char *data); -int mpu_run_self_test(long *gyro, long *accel); -int mpu_register_tap_cb(void (*func)(unsigned char, unsigned char)); - -#endif /* #ifndef _INV_MPU_H_ */ - diff --git a/interface/external/MotionDriver/include/inv_mpu_dmp_motion_driver.h b/interface/external/MotionDriver/include/inv_mpu_dmp_motion_driver.h deleted file mode 100644 index b0afea6caf..0000000000 --- a/interface/external/MotionDriver/include/inv_mpu_dmp_motion_driver.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - $License: - Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. - See included License.txt for License information. - $ - */ -/** - * @addtogroup DRIVERS Sensor Driver Layer - * @brief Hardware drivers to communicate with sensors via I2C. - * - * @{ - * @file inv_mpu_dmp_motion_driver.h - * @brief DMP image and interface functions. - * @details All functions are preceded by the dmp_ prefix to - * differentiate among MPL and general driver function calls. - */ -#ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ -#define _INV_MPU_DMP_MOTION_DRIVER_H_ - -#define TAP_X (0x01) -#define TAP_Y (0x02) -#define TAP_Z (0x04) -#define TAP_XYZ (0x07) - -#define TAP_X_UP (0x01) -#define TAP_X_DOWN (0x02) -#define TAP_Y_UP (0x03) -#define TAP_Y_DOWN (0x04) -#define TAP_Z_UP (0x05) -#define TAP_Z_DOWN (0x06) - -#define ANDROID_ORIENT_PORTRAIT (0x00) -#define ANDROID_ORIENT_LANDSCAPE (0x01) -#define ANDROID_ORIENT_REVERSE_PORTRAIT (0x02) -#define ANDROID_ORIENT_REVERSE_LANDSCAPE (0x03) - -#define DMP_INT_GESTURE (0x01) -#define DMP_INT_CONTINUOUS (0x02) - -#define DMP_FEATURE_TAP (0x001) -#define DMP_FEATURE_ANDROID_ORIENT (0x002) -#define DMP_FEATURE_LP_QUAT (0x004) -#define DMP_FEATURE_PEDOMETER (0x008) -#define DMP_FEATURE_6X_LP_QUAT (0x010) -#define DMP_FEATURE_GYRO_CAL (0x020) -#define DMP_FEATURE_SEND_RAW_ACCEL (0x040) -#define DMP_FEATURE_SEND_RAW_GYRO (0x080) -#define DMP_FEATURE_SEND_CAL_GYRO (0x100) - -#define INV_WXYZ_QUAT (0x100) - -/* Set up functions. */ -int dmp_load_motion_driver_firmware(void); -int dmp_set_fifo_rate(unsigned short rate); -int dmp_get_fifo_rate(unsigned short *rate); -int dmp_enable_feature(unsigned short mask); -int dmp_get_enabled_features(unsigned short *mask); -int dmp_set_interrupt_mode(unsigned char mode); -int dmp_set_orientation(unsigned short orient); -int dmp_set_gyro_bias(long *bias); -int dmp_set_accel_bias(long *bias); - -/* Tap functions. */ -int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)); -int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh); -int dmp_set_tap_axes(unsigned char axis); -int dmp_set_tap_count(unsigned char min_taps); -int dmp_set_tap_time(unsigned short time); -int dmp_set_tap_time_multi(unsigned short time); -int dmp_set_shake_reject_thresh(long sf, unsigned short thresh); -int dmp_set_shake_reject_time(unsigned short time); -int dmp_set_shake_reject_timeout(unsigned short time); - -/* Android orientation functions. */ -int dmp_register_android_orient_cb(void (*func)(unsigned char)); - -/* LP quaternion functions. */ -int dmp_enable_lp_quat(unsigned char enable); -int dmp_enable_6x_lp_quat(unsigned char enable); - -/* Pedometer functions. */ -int dmp_get_pedometer_step_count(unsigned long *count); -int dmp_set_pedometer_step_count(unsigned long count); -int dmp_get_pedometer_walk_time(unsigned long *time); -int dmp_set_pedometer_walk_time(unsigned long time); - -/* DMP gyro calibration functions. */ -int dmp_enable_gyro_cal(unsigned char enable); - -/* Read function. This function should be called whenever the MPU interrupt is - * detected. - */ -int dmp_read_fifo(short *gyro, short *accel, long *quat, - unsigned long *timestamp, short *sensors, unsigned char *more); - -#endif /* #ifndef _INV_MPU_DMP_MOTION_DRIVER_H_ */ - diff --git a/interface/external/MotionDriver/include/inv_tty.h b/interface/external/MotionDriver/include/inv_tty.h deleted file mode 100644 index d92ece2017..0000000000 --- a/interface/external/MotionDriver/include/inv_tty.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// inv_tty.h -// interface -// -// Created by Andrzej Kapolka on 7/9/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __interface__inv_tty__ -#define __interface__inv_tty__ - -void tty_set_file_descriptor(int file_descriptor); - -int tty_i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data); - -int tty_i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data); - -void tty_delay_ms(unsigned long num_ms); - -void tty_get_ms(unsigned long *count); - -#endif /* defined(__interface__inv_tty__) */ diff --git a/interface/external/MotionDriver/lib/MacOS/libMotionDriver.a b/interface/external/MotionDriver/lib/MacOS/libMotionDriver.a deleted file mode 100644 index 5911eb9f9994aa7b4da6b094995ef41ff39a4910..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59312 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 z 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 diff --git a/interface/external/MotionDriver/src/inv_mpu.c b/interface/external/MotionDriver/src/inv_mpu.c deleted file mode 100644 index 9969465596..0000000000 --- a/interface/external/MotionDriver/src/inv_mpu.c +++ /dev/null @@ -1,2798 +0,0 @@ -/* - $License: - Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. - See included License.txt for License information. - $ - */ -/** - * @addtogroup DRIVERS Sensor Driver Layer - * @brief Hardware drivers to communicate with sensors via I2C. - * - * @{ - * @file inv_mpu.c - * @brief An I2C-based driver for Invensense gyroscopes. - * @details This driver currently works for the following devices: - * MPU6050 - * MPU6500 - * MPU9150 (or MPU6050 w/ AK8975 on the auxiliary bus) - * MPU9250 (or MPU6500 w/ AK8963 on the auxiliary bus) - */ -#include -#include -#include -#include -#include -#include "inv_mpu.h" -#include "inv_tty.h" - -/* The following functions must be defined for this platform: - * i2c_write(unsigned char slave_addr, unsigned char reg_addr, - * unsigned char length, unsigned char const *data) - * i2c_read(unsigned char slave_addr, unsigned char reg_addr, - * unsigned char length, unsigned char *data) - * delay_ms(unsigned long num_ms) - * get_ms(unsigned long *count) - * reg_int_cb(void (*cb)(void), unsigned char port, unsigned char pin) - * labs(long x) - * fabsf(float x) - * min(int a, int b) - */ -#if defined MOTION_DRIVER_TARGET_MSP430 -#include "msp430.h" -#include "msp430_i2c.h" -#include "msp430_clock.h" -#include "msp430_interrupt.h" -#define i2c_write msp430_i2c_write -#define i2c_read msp430_i2c_read -#define delay_ms msp430_delay_ms -#define get_ms msp430_get_clock_ms -static inline int reg_int_cb(struct int_param_s *int_param) -{ - return msp430_reg_int_cb(int_param->cb, int_param->pin, int_param->lp_exit, - int_param->active_low); -} -#define log_i(...) do {} while (0) -#define log_e(...) do {} while (0) -/* labs is already defined by TI's toolchain. */ -/* fabs is for doubles. fabsf is for floats. */ -#define fabs fabsf -#define min(a,b) ((acb, int_param->pin, int_param->lp_exit, - int_param->active_low); -} -#define log_i MPL_LOGI -#define log_e MPL_LOGE -/* labs is already defined by TI's toolchain. */ -/* fabs is for doubles. fabsf is for floats. */ -#define fabs fabsf -#define min(a,b) ((apin, int_param->cb, int_param->arg); - return 0; -} -#define log_i MPL_LOGI -#define log_e MPL_LOGE -/* UC3 is a 32-bit processor, so abs and labs are equivalent. */ -#define labs abs -#define fabs(x) (((x)>0)?(x):-(x)) -#else -#define i2c_write tty_i2c_write -#define i2c_read tty_i2c_read -#define delay_ms tty_delay_ms -#define get_ms tty_get_ms -#define min(a,b) ((a> 3 & 0x03 */ - unsigned char gyro_fsr; - /* Matches accel_cfg >> 3 & 0x03 */ - unsigned char accel_fsr; - /* Enabled sensors. Uses same masks as fifo_en, NOT pwr_mgmt_2. */ - unsigned char sensors; - /* Matches config register. */ - unsigned char lpf; - unsigned char clk_src; - /* Sample rate, NOT rate divider. */ - unsigned short sample_rate; - /* Matches fifo_en register. */ - unsigned char fifo_enable; - /* Matches int enable register. */ - unsigned char int_enable; - /* 1 if devices on auxiliary I2C bus appear on the primary. */ - unsigned char bypass_mode; - /* 1 if half-sensitivity. - * NOTE: This doesn't belong here, but everything else in hw_s is const, - * and this allows us to save some precious RAM. - */ - unsigned char accel_half; - /* 1 if device in low-power accel-only mode. */ - unsigned char lp_accel_mode; - /* 1 if interrupts are only triggered on motion events. */ - unsigned char int_motion_only; - struct motion_int_cache_s cache; - /* 1 for active low interrupts. */ - unsigned char active_low_int; - /* 1 for latched interrupts. */ - unsigned char latched_int; - /* 1 if DMP is enabled. */ - unsigned char dmp_on; - /* Ensures that DMP will only be loaded once. */ - unsigned char dmp_loaded; - /* Sampling rate used when DMP is enabled. */ - unsigned short dmp_sample_rate; -#ifdef AK89xx_SECONDARY - /* Compass sample rate. */ - unsigned short compass_sample_rate; - unsigned char compass_addr; - short mag_sens_adj[3]; -#endif -}; - -/* Information for self-test. */ -struct test_s { - unsigned long gyro_sens; - unsigned long accel_sens; - unsigned char reg_rate_div; - unsigned char reg_lpf; - unsigned char reg_gyro_fsr; - unsigned char reg_accel_fsr; - unsigned short wait_ms; - unsigned char packet_thresh; - float min_dps; - float max_dps; - float max_gyro_var; - float min_g; - float max_g; - float max_accel_var; -}; - -/* Gyro driver state variables. */ -struct gyro_state_s { - const struct gyro_reg_s *reg; - const struct hw_s *hw; - struct chip_cfg_s chip_cfg; - const struct test_s *test; -}; - -/* Filter configurations. */ -enum lpf_e { - INV_FILTER_256HZ_NOLPF2 = 0, - INV_FILTER_188HZ, - INV_FILTER_98HZ, - INV_FILTER_42HZ, - INV_FILTER_20HZ, - INV_FILTER_10HZ, - INV_FILTER_5HZ, - INV_FILTER_2100HZ_NOLPF, - NUM_FILTER -}; - -/* Full scale ranges. */ -enum gyro_fsr_e { - INV_FSR_250DPS = 0, - INV_FSR_500DPS, - INV_FSR_1000DPS, - INV_FSR_2000DPS, - NUM_GYRO_FSR -}; - -/* Full scale ranges. */ -enum accel_fsr_e { - INV_FSR_2G = 0, - INV_FSR_4G, - INV_FSR_8G, - INV_FSR_16G, - NUM_ACCEL_FSR -}; - -/* Clock sources. */ -enum clock_sel_e { - INV_CLK_INTERNAL = 0, - INV_CLK_PLL, - NUM_CLK -}; - -/* Low-power accel wakeup rates. */ -enum lp_accel_rate_e { -#if defined MPU6050 - INV_LPA_1_25HZ, - INV_LPA_5HZ, - INV_LPA_20HZ, - INV_LPA_40HZ -#elif defined MPU6500 - INV_LPA_0_3125HZ, - INV_LPA_0_625HZ, - INV_LPA_1_25HZ, - INV_LPA_2_5HZ, - INV_LPA_5HZ, - INV_LPA_10HZ, - INV_LPA_20HZ, - INV_LPA_40HZ, - INV_LPA_80HZ, - INV_LPA_160HZ, - INV_LPA_320HZ, - INV_LPA_640HZ -#endif -}; - -#define BIT_I2C_MST_VDDIO (0x80) -#define BIT_FIFO_EN (0x40) -#define BIT_DMP_EN (0x80) -#define BIT_FIFO_RST (0x04) -#define BIT_DMP_RST (0x08) -#define BIT_FIFO_OVERFLOW (0x10) -#define BIT_DATA_RDY_EN (0x01) -#define BIT_DMP_INT_EN (0x02) -#define BIT_MOT_INT_EN (0x40) -#define BITS_FSR (0x18) -#define BITS_LPF (0x07) -#define BITS_HPF (0x07) -#define BITS_CLK (0x07) -#define BIT_FIFO_SIZE_1024 (0x40) -#define BIT_FIFO_SIZE_2048 (0x80) -#define BIT_FIFO_SIZE_4096 (0xC0) -#define BIT_RESET (0x80) -#define BIT_SLEEP (0x40) -#define BIT_S0_DELAY_EN (0x01) -#define BIT_S2_DELAY_EN (0x04) -#define BITS_SLAVE_LENGTH (0x0F) -#define BIT_SLAVE_BYTE_SW (0x40) -#define BIT_SLAVE_GROUP (0x10) -#define BIT_SLAVE_EN (0x80) -#define BIT_I2C_READ (0x80) -#define BITS_I2C_MASTER_DLY (0x1F) -#define BIT_AUX_IF_EN (0x20) -#define BIT_ACTL (0x80) -#define BIT_LATCH_EN (0x20) -#define BIT_ANY_RD_CLR (0x10) -#define BIT_BYPASS_EN (0x02) -#define BITS_WOM_EN (0xC0) -#define BIT_LPA_CYCLE (0x20) -#define BIT_STBY_XA (0x20) -#define BIT_STBY_YA (0x10) -#define BIT_STBY_ZA (0x08) -#define BIT_STBY_XG (0x04) -#define BIT_STBY_YG (0x02) -#define BIT_STBY_ZG (0x01) -#define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA) -#define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG) - -#if defined AK8975_SECONDARY -#define SUPPORTS_AK89xx_HIGH_SENS (0x00) -#define AK89xx_FSR (9830) -#elif defined AK8963_SECONDARY -#define SUPPORTS_AK89xx_HIGH_SENS (0x10) -#define AK89xx_FSR (4915) -#endif - -#ifdef AK89xx_SECONDARY -#define AKM_REG_WHOAMI (0x00) - -#define AKM_REG_ST1 (0x02) -#define AKM_REG_HXL (0x03) -#define AKM_REG_ST2 (0x09) - -#define AKM_REG_CNTL (0x0A) -#define AKM_REG_ASTC (0x0C) -#define AKM_REG_ASAX (0x10) -#define AKM_REG_ASAY (0x11) -#define AKM_REG_ASAZ (0x12) - -#define AKM_DATA_READY (0x01) -#define AKM_DATA_OVERRUN (0x02) -#define AKM_OVERFLOW (0x80) -#define AKM_DATA_ERROR (0x40) - -#define AKM_BIT_SELF_TEST (0x40) - -#define AKM_POWER_DOWN (0x00 | SUPPORTS_AK89xx_HIGH_SENS) -#define AKM_SINGLE_MEASUREMENT (0x01 | SUPPORTS_AK89xx_HIGH_SENS) -#define AKM_FUSE_ROM_ACCESS (0x0F | SUPPORTS_AK89xx_HIGH_SENS) -#define AKM_MODE_SELF_TEST (0x08 | SUPPORTS_AK89xx_HIGH_SENS) - -#define AKM_WHOAMI (0x48) -#endif - -#if defined MPU6050 -const struct gyro_reg_s reg = { - .who_am_i = 0x75, - .rate_div = 0x19, - .lpf = 0x1A, - .prod_id = 0x0C, - .user_ctrl = 0x6A, - .fifo_en = 0x23, - .gyro_cfg = 0x1B, - .accel_cfg = 0x1C, - .motion_thr = 0x1F, - .motion_dur = 0x20, - .fifo_count_h = 0x72, - .fifo_r_w = 0x74, - .raw_gyro = 0x43, - .raw_accel = 0x3B, - .temp = 0x41, - .int_enable = 0x38, - .dmp_int_status = 0x39, - .int_status = 0x3A, - .pwr_mgmt_1 = 0x6B, - .pwr_mgmt_2 = 0x6C, - .int_pin_cfg = 0x37, - .mem_r_w = 0x6F, - .accel_offs = 0x06, - .i2c_mst = 0x24, - .bank_sel = 0x6D, - .mem_start_addr = 0x6E, - .prgm_start_h = 0x70 -#ifdef AK89xx_SECONDARY - ,.raw_compass = 0x49, - .yg_offs_tc = 0x01, - .s0_addr = 0x25, - .s0_reg = 0x26, - .s0_ctrl = 0x27, - .s1_addr = 0x28, - .s1_reg = 0x29, - .s1_ctrl = 0x2A, - .s4_ctrl = 0x34, - .s0_do = 0x63, - .s1_do = 0x64, - .i2c_delay_ctrl = 0x67 -#endif -}; -const struct hw_s hw = { - .addr = 0x68, - .max_fifo = 1024, - .num_reg = 118, - .temp_sens = 340, - .temp_offset = -521, - .bank_size = 256 -#if defined AK89xx_SECONDARY - ,.compass_fsr = AK89xx_FSR -#endif -}; - -const struct test_s test = { - .gyro_sens = 32768/250, - .accel_sens = 32768/16, - .reg_rate_div = 0, /* 1kHz. */ - .reg_lpf = 1, /* 188Hz. */ - .reg_gyro_fsr = 0, /* 250dps. */ - .reg_accel_fsr = 0x18, /* 16g. */ - .wait_ms = 50, - .packet_thresh = 5, /* 5% */ - .min_dps = 10.f, - .max_dps = 105.f, - .max_gyro_var = 0.14f, - .min_g = 0.3f, - .max_g = 0.95f, - .max_accel_var = 0.14f -}; - -static struct gyro_state_s st = { - .reg = ®, - .hw = &hw, - .test = &test -}; -#elif defined MPU6500 -const struct gyro_reg_s reg = { - .who_am_i = 0x75, - .rate_div = 0x19, - .lpf = 0x1A, - .prod_id = 0x0C, - .user_ctrl = 0x6A, - .fifo_en = 0x23, - .gyro_cfg = 0x1B, - .accel_cfg = 0x1C, - .accel_cfg2 = 0x1D, - .lp_accel_odr = 0x1E, - .motion_thr = 0x1F, - .motion_dur = 0x20, - .fifo_count_h = 0x72, - .fifo_r_w = 0x74, - .raw_gyro = 0x43, - .raw_accel = 0x3B, - .temp = 0x41, - .int_enable = 0x38, - .dmp_int_status = 0x39, - .int_status = 0x3A, - .accel_intel = 0x69, - .pwr_mgmt_1 = 0x6B, - .pwr_mgmt_2 = 0x6C, - .int_pin_cfg = 0x37, - .mem_r_w = 0x6F, - .accel_offs = 0x77, - .i2c_mst = 0x24, - .bank_sel = 0x6D, - .mem_start_addr = 0x6E, - .prgm_start_h = 0x70 -#ifdef AK89xx_SECONDARY - ,.raw_compass = 0x49, - .s0_addr = 0x25, - .s0_reg = 0x26, - .s0_ctrl = 0x27, - .s1_addr = 0x28, - .s1_reg = 0x29, - .s1_ctrl = 0x2A, - .s4_ctrl = 0x34, - .s0_do = 0x63, - .s1_do = 0x64, - .i2c_delay_ctrl = 0x67 -#endif -}; -const struct hw_s hw = { - .addr = 0x68, - .max_fifo = 1024, - .num_reg = 128, - .temp_sens = 321, - .temp_offset = 0, - .bank_size = 256 -#if defined AK89xx_SECONDARY - ,.compass_fsr = AK89xx_FSR -#endif -}; - -const struct test_s test = { - .gyro_sens = 32768/250, - .accel_sens = 32768/16, - .reg_rate_div = 0, /* 1kHz. */ - .reg_lpf = 1, /* 188Hz. */ - .reg_gyro_fsr = 0, /* 250dps. */ - .reg_accel_fsr = 0x18, /* 16g. */ - .wait_ms = 50, - .packet_thresh = 5, /* 5% */ - .min_dps = 10.f, - .max_dps = 105.f, - .max_gyro_var = 0.14f, - .min_g = 0.3f, - .max_g = 0.95f, - .max_accel_var = 0.14f -}; - -static struct gyro_state_s st = { - .reg = ®, - .hw = &hw, - .test = &test -}; -#endif - -#define MAX_PACKET_LENGTH (12) - -#ifdef AK89xx_SECONDARY -static int setup_compass(void); -#define MAX_COMPASS_SAMPLE_RATE (100) -#endif - -/** - * @brief Enable/disable data ready interrupt. - * If the DMP is on, the DMP interrupt is enabled. Otherwise, the data ready - * interrupt is used. - * @param[in] enable 1 to enable interrupt. - * @return 0 if successful. - */ -static int set_int_enable(unsigned char enable) -{ - unsigned char tmp; - - if (st.chip_cfg.dmp_on) { - if (enable) - tmp = BIT_DMP_INT_EN; - else - tmp = 0x00; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) - return -1; - st.chip_cfg.int_enable = tmp; - } else { - if (!st.chip_cfg.sensors) - return -1; - if (enable && st.chip_cfg.int_enable) - return 0; - if (enable) - tmp = BIT_DATA_RDY_EN; - else - tmp = 0x00; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &tmp)) - return -1; - st.chip_cfg.int_enable = tmp; - } - return 0; -} - -/** - * @brief Register dump for testing. - * @return 0 if successful. - */ -int mpu_reg_dump(void) -{ - unsigned char ii; - unsigned char data; - - for (ii = 0; ii < st.hw->num_reg; ii++) { - if (ii == st.reg->fifo_r_w || ii == st.reg->mem_r_w) - continue; - if (i2c_read(st.hw->addr, ii, 1, &data)) - return -1; - log_i("%#5x: %#5x\r\n", ii, data); - } - return 0; -} - -/** - * @brief Read from a single register. - * NOTE: The memory and FIFO read/write registers cannot be accessed. - * @param[in] reg Register address. - * @param[out] data Register data. - * @return 0 if successful. - */ -int mpu_read_reg(unsigned char reg, unsigned char *data) -{ - if (reg == st.reg->fifo_r_w || reg == st.reg->mem_r_w) - return -1; - if (reg >= st.hw->num_reg) - return -1; - return i2c_read(st.hw->addr, reg, 1, data); -} - -/** - * @brief Initialize hardware. - * Initial configuration:\n - * Gyro FSR: +/- 2000DPS\n - * Accel FSR +/- 2G\n - * DLPF: 42Hz\n - * FIFO rate: 50Hz\n - * Clock source: Gyro PLL\n - * FIFO: Disabled.\n - * Data ready interrupt: Disabled, active low, unlatched. - * @param[in] int_param Platform-specific parameters to interrupt API. - * @return 0 if successful. - */ -int mpu_init(struct int_param_s *int_param) -{ - unsigned char data[6], rev; - - /* Reset device. */ - data[0] = BIT_RESET; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) - return -1; - delay_ms(100); - - /* Wake up chip. */ - data[0] = 0x00; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) - return -1; - -#if defined MPU6050 - /* Check product revision. */ - if (i2c_read(st.hw->addr, st.reg->accel_offs, 6, data)) - return -1; - rev = ((data[5] & 0x01) << 2) | ((data[3] & 0x01) << 1) | - (data[1] & 0x01); - - if (rev) { - /* Congrats, these parts are better. */ - if (rev == 1) - st.chip_cfg.accel_half = 1; - else if (rev == 2) - st.chip_cfg.accel_half = 0; - else { - log_e("Unsupported software product rev %d.\n", rev); - return -1; - } - } else { - if (i2c_read(st.hw->addr, st.reg->prod_id, 1, data)) - return -1; - rev = data[0] & 0x0F; - if (!rev) { - log_e("Product ID read as 0 indicates device is either " - "incompatible or an MPU3050.\n"); - return -1; - } else if (rev == 4) { - log_i("Half sensitivity part found.\n"); - st.chip_cfg.accel_half = 1; - } else - st.chip_cfg.accel_half = 0; - } -#elif defined MPU6500 -#define MPU6500_MEM_REV_ADDR (0x17) - if (mpu_read_mem(MPU6500_MEM_REV_ADDR, 1, &rev)) - return -1; - if (rev == 0x1) - st.chip_cfg.accel_half = 0; - else { - log_e("Unsupported software product rev %d.\n", rev); - return -1; - } - - /* MPU6500 shares 4kB of memory between the DMP and the FIFO. Since the - * first 3kB are needed by the DMP, we'll use the last 1kB for the FIFO. - */ - data[0] = BIT_FIFO_SIZE_1024 | 0x8; - if (i2c_write(st.hw->addr, st.reg->accel_cfg2, 1, data)) - return -1; -#endif - - /* Set to invalid values to ensure no I2C writes are skipped. */ - st.chip_cfg.sensors = 0xFF; - st.chip_cfg.gyro_fsr = 0xFF; - st.chip_cfg.accel_fsr = 0xFF; - st.chip_cfg.lpf = 0xFF; - st.chip_cfg.sample_rate = 0xFFFF; - st.chip_cfg.fifo_enable = 0xFF; - st.chip_cfg.bypass_mode = 0xFF; -#ifdef AK89xx_SECONDARY - st.chip_cfg.compass_sample_rate = 0xFFFF; -#endif - /* mpu_set_sensors always preserves this setting. */ - st.chip_cfg.clk_src = INV_CLK_PLL; - /* Handled in next call to mpu_set_bypass. */ - st.chip_cfg.active_low_int = 1; - st.chip_cfg.latched_int = 0; - st.chip_cfg.int_motion_only = 0; - st.chip_cfg.lp_accel_mode = 0; - memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache)); - st.chip_cfg.dmp_on = 0; - st.chip_cfg.dmp_loaded = 0; - st.chip_cfg.dmp_sample_rate = 0; - - if (mpu_set_gyro_fsr(2000)) - return -1; - if (mpu_set_accel_fsr(2)) - return -1; - if (mpu_set_lpf(42)) - return -1; - if (mpu_set_sample_rate(50)) - return -1; - if (mpu_configure_fifo(0)) - return -1; - - if (int_param) - reg_int_cb(int_param); - -#ifdef AK89xx_SECONDARY - setup_compass(); - if (mpu_set_compass_sample_rate(10)) - return -1; -#else - /* Already disabled by setup_compass. */ - if (mpu_set_bypass(0)) - return -1; -#endif - - mpu_set_sensors(0); - return 0; -} - -/** - * @brief Enter low-power accel-only mode. - * In low-power accel mode, the chip goes to sleep and only wakes up to sample - * the accelerometer at one of the following frequencies: - * \n MPU6050: 1.25Hz, 5Hz, 20Hz, 40Hz - * \n MPU6500: 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz - * \n If the requested rate is not one listed above, the device will be set to - * the next highest rate. Requesting a rate above the maximum supported - * frequency will result in an error. - * \n To select a fractional wake-up frequency, round down the value passed to - * @e rate. - * @param[in] rate Minimum sampling rate, or zero to disable LP - * accel mode. - * @return 0 if successful. - */ -int mpu_lp_accel_mode(unsigned char rate) -{ - unsigned char tmp[2]; - - if (rate > 40) - return -1; - - if (!rate) { - mpu_set_int_latched(0); - tmp[0] = 0; - tmp[1] = BIT_STBY_XYZG; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) - return -1; - st.chip_cfg.lp_accel_mode = 0; - return 0; - } - /* For LP accel, we automatically configure the hardware to produce latched - * interrupts. In LP accel mode, the hardware cycles into sleep mode before - * it gets a chance to deassert the interrupt pin; therefore, we shift this - * responsibility over to the MCU. - * - * Any register read will clear the interrupt. - */ - mpu_set_int_latched(1); -#if defined MPU6050 - tmp[0] = BIT_LPA_CYCLE; - if (rate == 1) { - tmp[1] = INV_LPA_1_25HZ; - mpu_set_lpf(5); - } else if (rate <= 5) { - tmp[1] = INV_LPA_5HZ; - mpu_set_lpf(5); - } else if (rate <= 20) { - tmp[1] = INV_LPA_20HZ; - mpu_set_lpf(10); - } else { - tmp[1] = INV_LPA_40HZ; - mpu_set_lpf(20); - } - tmp[1] = (tmp[1] << 6) | BIT_STBY_XYZG; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, tmp)) - return -1; -#elif defined MPU6500 - /* Set wake frequency. */ - if (rate == 1) - tmp[0] = INV_LPA_1_25HZ; - else if (rate == 2) - tmp[0] = INV_LPA_2_5HZ; - else if (rate <= 5) - tmp[0] = INV_LPA_5HZ; - else if (rate <= 10) - tmp[0] = INV_LPA_10HZ; - else if (rate <= 20) - tmp[0] = INV_LPA_20HZ; - else if (rate <= 40) - tmp[0] = INV_LPA_40HZ; - else if (rate <= 80) - tmp[0] = INV_LPA_80HZ; - else if (rate <= 160) - tmp[0] = INV_LPA_160HZ; - else if (rate <= 320) - tmp[0] = INV_LPA_320HZ; - else - tmp[0] = INV_LPA_640HZ; - if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, tmp)) - return -1; - tmp[0] = BIT_LPA_CYCLE; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, tmp)) - return -1; -#endif - st.chip_cfg.sensors = INV_XYZ_ACCEL; - st.chip_cfg.clk_src = 0; - st.chip_cfg.lp_accel_mode = 1; - mpu_configure_fifo(0); - - return 0; -} - -/** - * @brief Read raw gyro data directly from the registers. - * @param[out] data Raw data in hardware units. - * @param[out] timestamp Timestamp in milliseconds. Null if not needed. - * @return 0 if successful. - */ -int mpu_get_gyro_reg(short *data, unsigned long *timestamp) -{ - unsigned char tmp[6]; - - if (!(st.chip_cfg.sensors & INV_XYZ_GYRO)) - return -1; - - if (i2c_read(st.hw->addr, st.reg->raw_gyro, 6, tmp)) - return -1; - data[0] = (tmp[0] << 8) | tmp[1]; - data[1] = (tmp[2] << 8) | tmp[3]; - data[2] = (tmp[4] << 8) | tmp[5]; - if (timestamp) - get_ms(timestamp); - return 0; -} - -/** - * @brief Read raw accel data directly from the registers. - * @param[out] data Raw data in hardware units. - * @param[out] timestamp Timestamp in milliseconds. Null if not needed. - * @return 0 if successful. - */ -int mpu_get_accel_reg(short *data, unsigned long *timestamp) -{ - unsigned char tmp[6]; - - if (!(st.chip_cfg.sensors & INV_XYZ_ACCEL)) - return -1; - - if (i2c_read(st.hw->addr, st.reg->raw_accel, 6, tmp)) - return -1; - data[0] = (tmp[0] << 8) | tmp[1]; - data[1] = (tmp[2] << 8) | tmp[3]; - data[2] = (tmp[4] << 8) | tmp[5]; - if (timestamp) - get_ms(timestamp); - return 0; -} - -/** - * @brief Read temperature data directly from the registers. - * @param[out] data Data in q16 format. - * @param[out] timestamp Timestamp in milliseconds. Null if not needed. - * @return 0 if successful. - */ -int mpu_get_temperature(long *data, unsigned long *timestamp) -{ - unsigned char tmp[2]; - short raw; - - if (!(st.chip_cfg.sensors)) - return -1; - - if (i2c_read(st.hw->addr, st.reg->temp, 2, tmp)) - return -1; - raw = (tmp[0] << 8) | tmp[1]; - if (timestamp) - get_ms(timestamp); - - data[0] = (long)((35 + ((raw - (float)st.hw->temp_offset) / st.hw->temp_sens)) * 65536L); - return 0; -} - -/** - * @brief Push biases to the accel bias registers. - * This function expects biases relative to the current sensor output, and - * these biases will be added to the factory-supplied values. - * @param[in] accel_bias New biases. - * @return 0 if successful. - */ -int mpu_set_accel_bias(const long *accel_bias) -{ - unsigned char data[6]; - short accel_hw[3]; - short got_accel[3]; - short fg[3]; - - if (!accel_bias) - return -1; - if (!accel_bias[0] && !accel_bias[1] && !accel_bias[2]) - return 0; - - if (i2c_read(st.hw->addr, 3, 3, data)) - return -1; - fg[0] = ((data[0] >> 4) + 8) & 0xf; - fg[1] = ((data[1] >> 4) + 8) & 0xf; - fg[2] = ((data[2] >> 4) + 8) & 0xf; - - accel_hw[0] = (short)(accel_bias[0] * 2 / (64 + fg[0])); - accel_hw[1] = (short)(accel_bias[1] * 2 / (64 + fg[1])); - accel_hw[2] = (short)(accel_bias[2] * 2 / (64 + fg[2])); - - if (i2c_read(st.hw->addr, 0x06, 6, data)) - return -1; - - got_accel[0] = ((short)data[0] << 8) | data[1]; - got_accel[1] = ((short)data[2] << 8) | data[3]; - got_accel[2] = ((short)data[4] << 8) | data[5]; - - accel_hw[0] += got_accel[0]; - accel_hw[1] += got_accel[1]; - accel_hw[2] += got_accel[2]; - - data[0] = (accel_hw[0] >> 8) & 0xff; - data[1] = (accel_hw[0]) & 0xff; - data[2] = (accel_hw[1] >> 8) & 0xff; - data[3] = (accel_hw[1]) & 0xff; - data[4] = (accel_hw[2] >> 8) & 0xff; - data[5] = (accel_hw[2]) & 0xff; - - if (i2c_write(st.hw->addr, 0x06, 6, data)) - return -1; - return 0; -} - -/** - * @brief Reset FIFO read/write pointers. - * @return 0 if successful. - */ -int mpu_reset_fifo(void) -{ - unsigned char data; - - if (!(st.chip_cfg.sensors)) - return -1; - - data = 0; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) - return -1; - - if (st.chip_cfg.dmp_on) { - data = BIT_FIFO_RST | BIT_DMP_RST; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) - return -1; - delay_ms(50); - data = BIT_DMP_EN | BIT_FIFO_EN; - if (st.chip_cfg.sensors & INV_XYZ_COMPASS) - data |= BIT_AUX_IF_EN; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) - return -1; - if (st.chip_cfg.int_enable) - data = BIT_DMP_INT_EN; - else - data = 0; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) - return -1; - data = 0; - if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &data)) - return -1; - } else { - data = BIT_FIFO_RST; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) - return -1; - if (st.chip_cfg.bypass_mode || !(st.chip_cfg.sensors & INV_XYZ_COMPASS)) - data = BIT_FIFO_EN; - else - data = BIT_FIFO_EN | BIT_AUX_IF_EN; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &data)) - return -1; - delay_ms(50); - if (st.chip_cfg.int_enable) - data = BIT_DATA_RDY_EN; - else - data = 0; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, &data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, &st.chip_cfg.fifo_enable)) - return -1; - } - return 0; -} - -/** - * @brief Get the gyro full-scale range. - * @param[out] fsr Current full-scale range. - * @return 0 if successful. - */ -int mpu_get_gyro_fsr(unsigned short *fsr) -{ - switch (st.chip_cfg.gyro_fsr) { - case INV_FSR_250DPS: - fsr[0] = 250; - break; - case INV_FSR_500DPS: - fsr[0] = 500; - break; - case INV_FSR_1000DPS: - fsr[0] = 1000; - break; - case INV_FSR_2000DPS: - fsr[0] = 2000; - break; - default: - fsr[0] = 0; - break; - } - return 0; -} - -/** - * @brief Set the gyro full-scale range. - * @param[in] fsr Desired full-scale range. - * @return 0 if successful. - */ -int mpu_set_gyro_fsr(unsigned short fsr) -{ - unsigned char data; - - if (!(st.chip_cfg.sensors)) - return -1; - - switch (fsr) { - case 250: - data = INV_FSR_250DPS << 3; - break; - case 500: - data = INV_FSR_500DPS << 3; - break; - case 1000: - data = INV_FSR_1000DPS << 3; - break; - case 2000: - data = INV_FSR_2000DPS << 3; - break; - default: - return -1; - } - - if (st.chip_cfg.gyro_fsr == (data >> 3)) - return 0; - if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, &data)) - return -1; - st.chip_cfg.gyro_fsr = data >> 3; - return 0; -} - -/** - * @brief Get the accel full-scale range. - * @param[out] fsr Current full-scale range. - * @return 0 if successful. - */ -int mpu_get_accel_fsr(unsigned char *fsr) -{ - switch (st.chip_cfg.accel_fsr) { - case INV_FSR_2G: - fsr[0] = 2; - break; - case INV_FSR_4G: - fsr[0] = 4; - break; - case INV_FSR_8G: - fsr[0] = 8; - break; - case INV_FSR_16G: - fsr[0] = 16; - break; - default: - return -1; - } - if (st.chip_cfg.accel_half) - fsr[0] <<= 1; - return 0; -} - -/** - * @brief Set the accel full-scale range. - * @param[in] fsr Desired full-scale range. - * @return 0 if successful. - */ -int mpu_set_accel_fsr(unsigned char fsr) -{ - unsigned char data; - - if (!(st.chip_cfg.sensors)) - return -1; - - switch (fsr) { - case 2: - data = INV_FSR_2G << 3; - break; - case 4: - data = INV_FSR_4G << 3; - break; - case 8: - data = INV_FSR_8G << 3; - break; - case 16: - data = INV_FSR_16G << 3; - break; - default: - return -1; - } - - if (st.chip_cfg.accel_fsr == (data >> 3)) - return 0; - if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, &data)) - return -1; - st.chip_cfg.accel_fsr = data >> 3; - return 0; -} - -/** - * @brief Get the current DLPF setting. - * @param[out] lpf Current LPF setting. - * 0 if successful. - */ -int mpu_get_lpf(unsigned short *lpf) -{ - switch (st.chip_cfg.lpf) { - case INV_FILTER_188HZ: - lpf[0] = 188; - break; - case INV_FILTER_98HZ: - lpf[0] = 98; - break; - case INV_FILTER_42HZ: - lpf[0] = 42; - break; - case INV_FILTER_20HZ: - lpf[0] = 20; - break; - case INV_FILTER_10HZ: - lpf[0] = 10; - break; - case INV_FILTER_5HZ: - lpf[0] = 5; - break; - case INV_FILTER_256HZ_NOLPF2: - case INV_FILTER_2100HZ_NOLPF: - default: - lpf[0] = 0; - break; - } - return 0; -} - -/** - * @brief Set digital low pass filter. - * The following LPF settings are supported: 188, 98, 42, 20, 10, 5. - * @param[in] lpf Desired LPF setting. - * @return 0 if successful. - */ -int mpu_set_lpf(unsigned short lpf) -{ - unsigned char data; - - if (!(st.chip_cfg.sensors)) - return -1; - - if (lpf >= 188) - data = INV_FILTER_188HZ; - else if (lpf >= 98) - data = INV_FILTER_98HZ; - else if (lpf >= 42) - data = INV_FILTER_42HZ; - else if (lpf >= 20) - data = INV_FILTER_20HZ; - else if (lpf >= 10) - data = INV_FILTER_10HZ; - else - data = INV_FILTER_5HZ; - - if (st.chip_cfg.lpf == data) - return 0; - if (i2c_write(st.hw->addr, st.reg->lpf, 1, &data)) - return -1; - st.chip_cfg.lpf = data; - return 0; -} - -/** - * @brief Get sampling rate. - * @param[out] rate Current sampling rate (Hz). - * @return 0 if successful. - */ -int mpu_get_sample_rate(unsigned short *rate) -{ - if (st.chip_cfg.dmp_on) - return -1; - else - rate[0] = st.chip_cfg.sample_rate; - return 0; -} - -/** - * @brief Set sampling rate. - * Sampling rate must be between 4Hz and 1kHz. - * @param[in] rate Desired sampling rate (Hz). - * @return 0 if successful. - */ -int mpu_set_sample_rate(unsigned short rate) -{ - unsigned char data; - - if (!(st.chip_cfg.sensors)) - return -1; - - if (st.chip_cfg.dmp_on) - return -1; - else { - if (st.chip_cfg.lp_accel_mode) { - if (rate && (rate <= 40)) { - /* Just stay in low-power accel mode. */ - mpu_lp_accel_mode(rate); - return 0; - } - /* Requested rate exceeds the allowed frequencies in LP accel mode, - * switch back to full-power mode. - */ - mpu_lp_accel_mode(0); - } - if (rate < 4) - rate = 4; - else if (rate > 1000) - rate = 1000; - - data = 1000 / rate - 1; - if (i2c_write(st.hw->addr, st.reg->rate_div, 1, &data)) - return -1; - - st.chip_cfg.sample_rate = 1000 / (1 + data); - -#ifdef AK89xx_SECONDARY - mpu_set_compass_sample_rate(min(st.chip_cfg.compass_sample_rate, MAX_COMPASS_SAMPLE_RATE)); -#endif - - /* Automatically set LPF to 1/2 sampling rate. */ - mpu_set_lpf(st.chip_cfg.sample_rate >> 1); - return 0; - } -} - -/** - * @brief Get compass sampling rate. - * @param[out] rate Current compass sampling rate (Hz). - * @return 0 if successful. - */ -int mpu_get_compass_sample_rate(unsigned short *rate) -{ -#ifdef AK89xx_SECONDARY - rate[0] = st.chip_cfg.compass_sample_rate; - return 0; -#else - rate[0] = 0; - return -1; -#endif -} - -/** - * @brief Set compass sampling rate. - * The compass on the auxiliary I2C bus is read by the MPU hardware at a - * maximum of 100Hz. The actual rate can be set to a fraction of the gyro - * sampling rate. - * - * \n WARNING: The new rate may be different than what was requested. Call - * mpu_get_compass_sample_rate to check the actual setting. - * @param[in] rate Desired compass sampling rate (Hz). - * @return 0 if successful. - */ -int mpu_set_compass_sample_rate(unsigned short rate) -{ -#ifdef AK89xx_SECONDARY - unsigned char div; - if (!rate || rate > st.chip_cfg.sample_rate || rate > MAX_COMPASS_SAMPLE_RATE) - return -1; - - div = st.chip_cfg.sample_rate / rate - 1; - if (i2c_write(st.hw->addr, st.reg->s4_ctrl, 1, &div)) - return -1; - st.chip_cfg.compass_sample_rate = st.chip_cfg.sample_rate / (div + 1); - return 0; -#else - return -1; -#endif -} - -/** - * @brief Get gyro sensitivity scale factor. - * @param[out] sens Conversion from hardware units to dps. - * @return 0 if successful. - */ -int mpu_get_gyro_sens(float *sens) -{ - switch (st.chip_cfg.gyro_fsr) { - case INV_FSR_250DPS: - sens[0] = 131.f; - break; - case INV_FSR_500DPS: - sens[0] = 65.5f; - break; - case INV_FSR_1000DPS: - sens[0] = 32.8f; - break; - case INV_FSR_2000DPS: - sens[0] = 16.4f; - break; - default: - return -1; - } - return 0; -} - -/** - * @brief Get accel sensitivity scale factor. - * @param[out] sens Conversion from hardware units to g's. - * @return 0 if successful. - */ -int mpu_get_accel_sens(unsigned short *sens) -{ - switch (st.chip_cfg.accel_fsr) { - case INV_FSR_2G: - sens[0] = 16384; - break; - case INV_FSR_4G: - sens[0] = 8092; - break; - case INV_FSR_8G: - sens[0] = 4096; - break; - case INV_FSR_16G: - sens[0] = 2048; - break; - default: - return -1; - } - if (st.chip_cfg.accel_half) - sens[0] >>= 1; - return 0; -} - -/** - * @brief Get current FIFO configuration. - * @e sensors can contain a combination of the following flags: - * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO - * \n INV_XYZ_GYRO - * \n INV_XYZ_ACCEL - * @param[out] sensors Mask of sensors in FIFO. - * @return 0 if successful. - */ -int mpu_get_fifo_config(unsigned char *sensors) -{ - sensors[0] = st.chip_cfg.fifo_enable; - return 0; -} - -/** - * @brief Select which sensors are pushed to FIFO. - * @e sensors can contain a combination of the following flags: - * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO - * \n INV_XYZ_GYRO - * \n INV_XYZ_ACCEL - * @param[in] sensors Mask of sensors to push to FIFO. - * @return 0 if successful. - */ -int mpu_configure_fifo(unsigned char sensors) -{ - unsigned char prev; - int result = 0; - - /* Compass data isn't going into the FIFO. Stop trying. */ - sensors &= ~INV_XYZ_COMPASS; - - if (st.chip_cfg.dmp_on) - return 0; - else { - if (!(st.chip_cfg.sensors)) - return -1; - prev = st.chip_cfg.fifo_enable; - st.chip_cfg.fifo_enable = sensors & st.chip_cfg.sensors; - if (st.chip_cfg.fifo_enable != sensors) - /* You're not getting what you asked for. Some sensors are - * asleep. - */ - result = -1; - else - result = 0; - if (sensors || st.chip_cfg.lp_accel_mode) - set_int_enable(1); - else - set_int_enable(0); - if (sensors) { - if (mpu_reset_fifo()) { - st.chip_cfg.fifo_enable = prev; - return -1; - } - } - } - - return result; -} - -/** - * @brief Get current power state. - * @param[in] power_on 1 if turned on, 0 if suspended. - * @return 0 if successful. - */ -int mpu_get_power_state(unsigned char *power_on) -{ - if (st.chip_cfg.sensors) - power_on[0] = 1; - else - power_on[0] = 0; - return 0; -} - -/** - * @brief Turn specific sensors on/off. - * @e sensors can contain a combination of the following flags: - * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO - * \n INV_XYZ_GYRO - * \n INV_XYZ_ACCEL - * \n INV_XYZ_COMPASS - * @param[in] sensors Mask of sensors to wake. - * @return 0 if successful. - */ -int mpu_set_sensors(unsigned char sensors) -{ - unsigned char data; -#ifdef AK89xx_SECONDARY - unsigned char user_ctrl; -#endif - - if (sensors & INV_XYZ_GYRO) - data = INV_CLK_PLL; - else if (sensors) - data = 0; - else - data = BIT_SLEEP; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, &data)) { - st.chip_cfg.sensors = 0; - return -1; - } - st.chip_cfg.clk_src = data & ~BIT_SLEEP; - - data = 0; - if (!(sensors & INV_X_GYRO)) - data |= BIT_STBY_XG; - if (!(sensors & INV_Y_GYRO)) - data |= BIT_STBY_YG; - if (!(sensors & INV_Z_GYRO)) - data |= BIT_STBY_ZG; - if (!(sensors & INV_XYZ_ACCEL)) - data |= BIT_STBY_XYZA; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_2, 1, &data)) { - st.chip_cfg.sensors = 0; - return -1; - } - - if (sensors && (sensors != INV_XYZ_ACCEL)) - /* Latched interrupts only used in LP accel mode. */ - mpu_set_int_latched(0); - -#ifdef AK89xx_SECONDARY -#ifdef AK89xx_BYPASS - if (sensors & INV_XYZ_COMPASS) - mpu_set_bypass(1); - else - mpu_set_bypass(0); -#else - if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) - return -1; - /* Handle AKM power management. */ - if (sensors & INV_XYZ_COMPASS) { - data = AKM_SINGLE_MEASUREMENT; - user_ctrl |= BIT_AUX_IF_EN; - } else { - data = AKM_POWER_DOWN; - user_ctrl &= ~BIT_AUX_IF_EN; - } - if (st.chip_cfg.dmp_on) - user_ctrl |= BIT_DMP_EN; - else - user_ctrl &= ~BIT_DMP_EN; - if (i2c_write(st.hw->addr, st.reg->s1_do, 1, &data)) - return -1; - /* Enable/disable I2C master mode. */ - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &user_ctrl)) - return -1; -#endif -#endif - - st.chip_cfg.sensors = sensors; - st.chip_cfg.lp_accel_mode = 0; - delay_ms(50); - return 0; -} - -/** - * @brief Read the MPU interrupt status registers. - * @param[out] status Mask of interrupt bits. - * @return 0 if successful. - */ -int mpu_get_int_status(short *status) -{ - unsigned char tmp[2]; - if (!st.chip_cfg.sensors) - return -1; - if (i2c_read(st.hw->addr, st.reg->dmp_int_status, 2, tmp)) - return -1; - status[0] = (tmp[0] << 8) | tmp[1]; - return 0; -} - -/** - * @brief Get one packet from the FIFO. - * If @e sensors does not contain a particular sensor, disregard the data - * returned to that pointer. - * \n @e sensors can contain a combination of the following flags: - * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO - * \n INV_XYZ_GYRO - * \n INV_XYZ_ACCEL - * \n If the FIFO has no new data, @e sensors will be zero. - * \n If the FIFO is disabled, @e sensors will be zero and this function will - * return a non-zero error code. - * @param[out] gyro Gyro data in hardware units. - * @param[out] accel Accel data in hardware units. - * @param[out] timestamp Timestamp in milliseconds. - * @param[out] sensors Mask of sensors read from FIFO. - * @param[out] more Number of remaining packets. - * @return 0 if successful. - */ -int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, - unsigned char *sensors, unsigned char *more) -{ - /* Assumes maximum packet size is gyro (6) + accel (6). */ - unsigned char data[MAX_PACKET_LENGTH]; - unsigned char packet_size = 0; - unsigned short fifo_count, index = 0; - - if (st.chip_cfg.dmp_on) - return -1; - - sensors[0] = 0; - if (!st.chip_cfg.sensors) - return -1; - if (!st.chip_cfg.fifo_enable) - return -1; - - if (st.chip_cfg.fifo_enable & INV_X_GYRO) - packet_size += 2; - if (st.chip_cfg.fifo_enable & INV_Y_GYRO) - packet_size += 2; - if (st.chip_cfg.fifo_enable & INV_Z_GYRO) - packet_size += 2; - if (st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) - packet_size += 6; - - if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) - return -1; - fifo_count = (data[0] << 8) | data[1]; - if (fifo_count < packet_size) - return 0; -// log_i("FIFO count: %hd\n", fifo_count); - if (fifo_count > (st.hw->max_fifo >> 1)) { - /* FIFO is 50% full, better check overflow bit. */ - if (i2c_read(st.hw->addr, st.reg->int_status, 1, data)) - return -1; - if (data[0] & BIT_FIFO_OVERFLOW) { - mpu_reset_fifo(); - return -2; - } - } - get_ms((unsigned long*)timestamp); - - if (i2c_read(st.hw->addr, st.reg->fifo_r_w, packet_size, data)) - return -1; - more[0] = fifo_count / packet_size - 1; - sensors[0] = 0; - - if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_XYZ_ACCEL) { - accel[0] = (data[index+0] << 8) | data[index+1]; - accel[1] = (data[index+2] << 8) | data[index+3]; - accel[2] = (data[index+4] << 8) | data[index+5]; - sensors[0] |= INV_XYZ_ACCEL; - index += 6; - } - if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_X_GYRO) { - gyro[0] = (data[index+0] << 8) | data[index+1]; - sensors[0] |= INV_X_GYRO; - index += 2; - } - if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Y_GYRO) { - gyro[1] = (data[index+0] << 8) | data[index+1]; - sensors[0] |= INV_Y_GYRO; - index += 2; - } - if ((index != packet_size) && st.chip_cfg.fifo_enable & INV_Z_GYRO) { - gyro[2] = (data[index+0] << 8) | data[index+1]; - sensors[0] |= INV_Z_GYRO; - index += 2; - } - - return 0; -} - -/** - * @brief Get one unparsed packet from the FIFO. - * This function should be used if the packet is to be parsed elsewhere. - * @param[in] length Length of one FIFO packet. - * @param[in] data FIFO packet. - * @param[in] more Number of remaining packets. - */ -int mpu_read_fifo_stream(unsigned short length, unsigned char *data, - unsigned char *more) -{ - unsigned char tmp[2]; - unsigned short fifo_count; - if (!st.chip_cfg.dmp_on) - return -1; - if (!st.chip_cfg.sensors) - return -1; - - if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp)) - return -1; - fifo_count = (tmp[0] << 8) | tmp[1]; - if (fifo_count < length) { - more[0] = 0; - return -1; - } - if (fifo_count > (st.hw->max_fifo >> 1)) { - /* FIFO is 50% full, better check overflow bit. */ - if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp)) - return -1; - if (tmp[0] & BIT_FIFO_OVERFLOW) { - mpu_reset_fifo(); - return -2; - } - } - - if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data)) - return -1; - more[0] = fifo_count / length - 1; - return 0; -} - -/** - * @brief Set device to bypass mode. - * @param[in] bypass_on 1 to enable bypass mode. - * @return 0 if successful. - */ -int mpu_set_bypass(unsigned char bypass_on) -{ - unsigned char tmp; - - if (st.chip_cfg.bypass_mode == bypass_on) - return 0; - - if (bypass_on) { - if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) - return -1; - tmp &= ~BIT_AUX_IF_EN; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) - return -1; - delay_ms(3); - tmp = BIT_BYPASS_EN; - if (st.chip_cfg.active_low_int) - tmp |= BIT_ACTL; - if (st.chip_cfg.latched_int) - tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; - if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) - return -1; - } else { - /* Enable I2C master mode if compass is being used. */ - if (i2c_read(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) - return -1; - if (st.chip_cfg.sensors & INV_XYZ_COMPASS) - tmp |= BIT_AUX_IF_EN; - else - tmp &= ~BIT_AUX_IF_EN; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, &tmp)) - return -1; - delay_ms(3); - if (st.chip_cfg.active_low_int) - tmp = BIT_ACTL; - else - tmp = 0; - if (st.chip_cfg.latched_int) - tmp |= BIT_LATCH_EN | BIT_ANY_RD_CLR; - if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) - return -1; - } - st.chip_cfg.bypass_mode = bypass_on; - return 0; -} - -/** - * @brief Set interrupt level. - * @param[in] active_low 1 for active low, 0 for active high. - * @return 0 if successful. - */ -int mpu_set_int_level(unsigned char active_low) -{ - st.chip_cfg.active_low_int = active_low; - return 0; -} - -/** - * @brief Enable latched interrupts. - * Any MPU register will clear the interrupt. - * @param[in] enable 1 to enable, 0 to disable. - * @return 0 if successful. - */ -int mpu_set_int_latched(unsigned char enable) -{ - unsigned char tmp; - if (st.chip_cfg.latched_int == enable) - return 0; - - if (enable) - tmp = BIT_LATCH_EN | BIT_ANY_RD_CLR; - else - tmp = 0; - if (st.chip_cfg.bypass_mode) - tmp |= BIT_BYPASS_EN; - if (st.chip_cfg.active_low_int) - tmp |= BIT_ACTL; - if (i2c_write(st.hw->addr, st.reg->int_pin_cfg, 1, &tmp)) - return -1; - st.chip_cfg.latched_int = enable; - return 0; -} - -#ifdef MPU6050 -static int get_accel_prod_shift(float *st_shift) -{ - unsigned char tmp[4], shift_code[3], ii; - - if (i2c_read(st.hw->addr, 0x0D, 4, tmp)) - return 0x07; - - shift_code[0] = ((tmp[0] & 0xE0) >> 3) | ((tmp[3] & 0x30) >> 4); - shift_code[1] = ((tmp[1] & 0xE0) >> 3) | ((tmp[3] & 0x0C) >> 2); - shift_code[2] = ((tmp[2] & 0xE0) >> 3) | (tmp[3] & 0x03); - for (ii = 0; ii < 3; ii++) { - if (!shift_code[ii]) { - st_shift[ii] = 0.f; - continue; - } - /* Equivalent to.. - * st_shift[ii] = 0.34f * powf(0.92f/0.34f, (shift_code[ii]-1) / 30.f) - */ - st_shift[ii] = 0.34f; - while (--shift_code[ii]) - st_shift[ii] *= 1.034f; - } - return 0; -} - -static int accel_self_test(long *bias_regular, long *bias_st) -{ - int jj, result = 0; - float st_shift[3], st_shift_cust, st_shift_var; - - get_accel_prod_shift(st_shift); - for(jj = 0; jj < 3; jj++) { - st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; - if (st_shift[jj]) { - st_shift_var = st_shift_cust / st_shift[jj] - 1.f; - if (fabs(st_shift_var) > test.max_accel_var) - result |= 1 << jj; - } else if ((st_shift_cust < test.min_g) || - (st_shift_cust > test.max_g)) - result |= 1 << jj; - } - - return result; -} - -static int gyro_self_test(long *bias_regular, long *bias_st) -{ - int jj, result = 0; - unsigned char tmp[3]; - float st_shift, st_shift_cust, st_shift_var; - - if (i2c_read(st.hw->addr, 0x0D, 3, tmp)) - return 0x07; - - tmp[0] &= 0x1F; - tmp[1] &= 0x1F; - tmp[2] &= 0x1F; - - for (jj = 0; jj < 3; jj++) { - st_shift_cust = labs(bias_regular[jj] - bias_st[jj]) / 65536.f; - if (tmp[jj]) { - st_shift = 3275.f / test.gyro_sens; - while (--tmp[jj]) - st_shift *= 1.046f; - st_shift_var = st_shift_cust / st_shift - 1.f; - if (fabs(st_shift_var) > test.max_gyro_var) - result |= 1 << jj; - } else if ((st_shift_cust < test.min_dps) || - (st_shift_cust > test.max_dps)) - result |= 1 << jj; - } - return result; -} - -#ifdef AK89xx_SECONDARY -static int compass_self_test(void) -{ - unsigned char tmp[6]; - unsigned char tries = 10; - int result = 0x07; - short data; - - mpu_set_bypass(1); - - tmp[0] = AKM_POWER_DOWN; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) - return 0x07; - tmp[0] = AKM_BIT_SELF_TEST; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp)) - goto AKM_restore; - tmp[0] = AKM_MODE_SELF_TEST; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp)) - goto AKM_restore; - - do { - delay_ms(10); - if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 1, tmp)) - goto AKM_restore; - if (tmp[0] & AKM_DATA_READY) - break; - } while (tries--); - if (!(tmp[0] & AKM_DATA_READY)) - goto AKM_restore; - - if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_HXL, 6, tmp)) - goto AKM_restore; - - result = 0; - data = (short)(tmp[1] << 8) | tmp[0]; - if ((data > 100) || (data < -100)) - result |= 0x01; - data = (short)(tmp[3] << 8) | tmp[2]; - if ((data > 100) || (data < -100)) - result |= 0x02; - data = (short)(tmp[5] << 8) | tmp[4]; - if ((data > -300) || (data < -1000)) - result |= 0x04; - -AKM_restore: - tmp[0] = 0 | SUPPORTS_AK89xx_HIGH_SENS; - i2c_write(st.chip_cfg.compass_addr, AKM_REG_ASTC, 1, tmp); - tmp[0] = SUPPORTS_AK89xx_HIGH_SENS; - i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp); - mpu_set_bypass(0); - return result; -} -#endif -#endif - -static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) -{ - unsigned char data[MAX_PACKET_LENGTH]; - unsigned char packet_count, ii; - unsigned short fifo_count; - - data[0] = 0x01; - data[1] = 0; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) - return -1; - delay_ms(200); - data[0] = 0; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) - return -1; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) - return -1; - data[0] = BIT_FIFO_RST | BIT_DMP_RST; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) - return -1; - delay_ms(15); - data[0] = st.test->reg_lpf; - if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) - return -1; - data[0] = st.test->reg_rate_div; - if (i2c_write(st.hw->addr, st.reg->rate_div, 1, data)) - return -1; - if (hw_test) - data[0] = st.test->reg_gyro_fsr | 0xE0; - else - data[0] = st.test->reg_gyro_fsr; - if (i2c_write(st.hw->addr, st.reg->gyro_cfg, 1, data)) - return -1; - - if (hw_test) - data[0] = st.test->reg_accel_fsr | 0xE0; - else - data[0] = test.reg_accel_fsr; - if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) - return -1; - if (hw_test) - delay_ms(200); - - /* Fill FIFO for test.wait_ms milliseconds. */ - data[0] = BIT_FIFO_EN; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 1, data)) - return -1; - - data[0] = INV_XYZ_GYRO | INV_XYZ_ACCEL; - if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) - return -1; - delay_ms(test.wait_ms); - data[0] = 0; - if (i2c_write(st.hw->addr, st.reg->fifo_en, 1, data)) - return -1; - - if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, data)) - return -1; - - fifo_count = (data[0] << 8) | data[1]; - packet_count = fifo_count / MAX_PACKET_LENGTH; - gyro[0] = gyro[1] = gyro[2] = 0; - accel[0] = accel[1] = accel[2] = 0; - - for (ii = 0; ii < packet_count; ii++) { - short accel_cur[3], gyro_cur[3]; - if (i2c_read(st.hw->addr, st.reg->fifo_r_w, MAX_PACKET_LENGTH, data)) - return -1; - accel_cur[0] = ((short)data[0] << 8) | data[1]; - accel_cur[1] = ((short)data[2] << 8) | data[3]; - accel_cur[2] = ((short)data[4] << 8) | data[5]; - accel[0] += (long)accel_cur[0]; - accel[1] += (long)accel_cur[1]; - accel[2] += (long)accel_cur[2]; - gyro_cur[0] = (((short)data[6] << 8) | data[7]); - gyro_cur[1] = (((short)data[8] << 8) | data[9]); - gyro_cur[2] = (((short)data[10] << 8) | data[11]); - gyro[0] += (long)gyro_cur[0]; - gyro[1] += (long)gyro_cur[1]; - gyro[2] += (long)gyro_cur[2]; - } -#ifdef EMPL_NO_64BIT - gyro[0] = (long)(((float)gyro[0]*65536.f) / test.gyro_sens / packet_count); - gyro[1] = (long)(((float)gyro[1]*65536.f) / test.gyro_sens / packet_count); - gyro[2] = (long)(((float)gyro[2]*65536.f) / test.gyro_sens / packet_count); - if (has_accel) { - accel[0] = (long)(((float)accel[0]*65536.f) / test.accel_sens / - packet_count); - accel[1] = (long)(((float)accel[1]*65536.f) / test.accel_sens / - packet_count); - accel[2] = (long)(((float)accel[2]*65536.f) / test.accel_sens / - packet_count); - /* Don't remove gravity! */ - accel[2] -= 65536L; - } -#else - gyro[0] = (long)(((long long)gyro[0]<<16) / test.gyro_sens / packet_count); - gyro[1] = (long)(((long long)gyro[1]<<16) / test.gyro_sens / packet_count); - gyro[2] = (long)(((long long)gyro[2]<<16) / test.gyro_sens / packet_count); - accel[0] = (long)(((long long)accel[0]<<16) / test.accel_sens / - packet_count); - accel[1] = (long)(((long long)accel[1]<<16) / test.accel_sens / - packet_count); - accel[2] = (long)(((long long)accel[2]<<16) / test.accel_sens / - packet_count); - /* Don't remove gravity! */ - if (accel[2] > 0L) - accel[2] -= 65536L; - else - accel[2] += 65536L; -#endif - - return 0; -} - -/** - * @brief Trigger gyro/accel/compass self-test. - * On success/error, the self-test returns a mask representing the sensor(s) - * that failed. For each bit, a one (1) represents a "pass" case; conversely, - * a zero (0) indicates a failure. - * - * \n The mask is defined as follows: - * \n Bit 0: Gyro. - * \n Bit 1: Accel. - * \n Bit 2: Compass. - * - * \n Currently, the hardware self-test is unsupported for MPU6500. However, - * this function can still be used to obtain the accel and gyro biases. - * - * \n This function must be called with the device either face-up or face-down - * (z-axis is parallel to gravity). - * @param[out] gyro Gyro biases in q16 format. - * @param[out] accel Accel biases (if applicable) in q16 format. - * @return Result mask (see above). - */ -int mpu_run_self_test(long *gyro, long *accel) -{ -#ifdef MPU6050 - const unsigned char tries = 2; - long gyro_st[3], accel_st[3]; - unsigned char accel_result, gyro_result; -#ifdef AK89xx_SECONDARY - unsigned char compass_result; -#endif - int ii; -#endif - int result; - unsigned char accel_fsr, fifo_sensors, sensors_on; - unsigned short gyro_fsr, sample_rate, lpf; - unsigned char dmp_was_on; - - if (st.chip_cfg.dmp_on) { - mpu_set_dmp_state(0); - dmp_was_on = 1; - } else - dmp_was_on = 0; - - /* Get initial settings. */ - mpu_get_gyro_fsr(&gyro_fsr); - mpu_get_accel_fsr(&accel_fsr); - mpu_get_lpf(&lpf); - mpu_get_sample_rate(&sample_rate); - sensors_on = st.chip_cfg.sensors; - mpu_get_fifo_config(&fifo_sensors); - - /* For older chips, the self-test will be different. */ -#if defined MPU6050 - for (ii = 0; ii < tries; ii++) - if (!get_st_biases(gyro, accel, 0)) - break; - if (ii == tries) { - /* If we reach this point, we most likely encountered an I2C error. - * We'll just report an error for all three sensors. - */ - result = 0; - goto restore; - } - for (ii = 0; ii < tries; ii++) - if (!get_st_biases(gyro_st, accel_st, 1)) - break; - if (ii == tries) { - /* Again, probably an I2C error. */ - result = 0; - goto restore; - } - accel_result = accel_self_test(accel, accel_st); - gyro_result = gyro_self_test(gyro, gyro_st); - - result = 0; - if (!gyro_result) - result |= 0x01; - if (!accel_result) - result |= 0x02; - -#ifdef AK89xx_SECONDARY - compass_result = compass_self_test(); - if (!compass_result) - result |= 0x04; -#endif -restore: -#elif defined MPU6500 - /* For now, this function will return a "pass" result for all three sensors - * for compatibility with current test applications. - */ - get_st_biases(gyro, accel, 0); - result = 0x7; -#endif - /* Set to invalid values to ensure no I2C writes are skipped. */ - st.chip_cfg.gyro_fsr = 0xFF; - st.chip_cfg.accel_fsr = 0xFF; - st.chip_cfg.lpf = 0xFF; - st.chip_cfg.sample_rate = 0xFFFF; - st.chip_cfg.sensors = 0xFF; - st.chip_cfg.fifo_enable = 0xFF; - st.chip_cfg.clk_src = INV_CLK_PLL; - mpu_set_gyro_fsr(gyro_fsr); - mpu_set_accel_fsr(accel_fsr); - mpu_set_lpf(lpf); - mpu_set_sample_rate(sample_rate); - mpu_set_sensors(sensors_on); - mpu_configure_fifo(fifo_sensors); - - if (dmp_was_on) - mpu_set_dmp_state(1); - - return result; -} - -/** - * @brief Write to the DMP memory. - * This function prevents I2C writes past the bank boundaries. The DMP memory - * is only accessible when the chip is awake. - * @param[in] mem_addr Memory location (bank << 8 | start address) - * @param[in] length Number of bytes to write. - * @param[in] data Bytes to write to memory. - * @return 0 if successful. - */ -int mpu_write_mem(unsigned short mem_addr, unsigned short length, - unsigned char *data) -{ - unsigned char tmp[2]; - - if (!data) - return -1; - if (!st.chip_cfg.sensors) - return -1; - - tmp[0] = (unsigned char)(mem_addr >> 8); - tmp[1] = (unsigned char)(mem_addr & 0xFF); - - /* Check bank boundaries. */ - if (tmp[1] + length > st.hw->bank_size) - return -1; - - if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) - return -1; - if (i2c_write(st.hw->addr, st.reg->mem_r_w, length, data)) - return -1; - return 0; -} - -/** - * @brief Read from the DMP memory. - * This function prevents I2C reads past the bank boundaries. The DMP memory - * is only accessible when the chip is awake. - * @param[in] mem_addr Memory location (bank << 8 | start address) - * @param[in] length Number of bytes to read. - * @param[out] data Bytes read from memory. - * @return 0 if successful. - */ -int mpu_read_mem(unsigned short mem_addr, unsigned short length, - unsigned char *data) -{ - unsigned char tmp[2]; - - if (!data) - return -1; - if (!st.chip_cfg.sensors) - return -1; - - tmp[0] = (unsigned char)(mem_addr >> 8); - tmp[1] = (unsigned char)(mem_addr & 0xFF); - - /* Check bank boundaries. */ - if (tmp[1] + length > st.hw->bank_size) - return -1; - - if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp)) - return -1; - if (i2c_read(st.hw->addr, st.reg->mem_r_w, length, data)) - return -1; - return 0; -} - -/** - * @brief Load and verify DMP image. - * @param[in] length Length of DMP image. - * @param[in] firmware DMP code. - * @param[in] start_addr Starting address of DMP code memory. - * @param[in] sample_rate Fixed sampling rate used when DMP is enabled. - * @return 0 if successful. - */ -int mpu_load_firmware(unsigned short length, const unsigned char *firmware, - unsigned short start_addr, unsigned short sample_rate) -{ - unsigned short ii; - unsigned short this_write; - /* Must divide evenly into st.hw->bank_size to avoid bank crossings. */ -#define LOAD_CHUNK (16) - unsigned char cur[LOAD_CHUNK], tmp[2]; - - if (st.chip_cfg.dmp_loaded) - /* DMP should only be loaded once. */ - return -1; - - if (!firmware) - return -1; - for (ii = 0; ii < length; ii += this_write) { - this_write = min(LOAD_CHUNK, length - ii); - if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii])) - return -1; - if (mpu_read_mem(ii, this_write, cur)) - return -1; - if (memcmp(firmware+ii, cur, this_write)) - return -2; - } - - /* Set program start address. */ - tmp[0] = start_addr >> 8; - tmp[1] = start_addr & 0xFF; - if (i2c_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp)) - return -1; - - st.chip_cfg.dmp_loaded = 1; - st.chip_cfg.dmp_sample_rate = sample_rate; - return 0; -} - -/** - * @brief Enable/disable DMP support. - * @param[in] enable 1 to turn on the DMP. - * @return 0 if successful. - */ -int mpu_set_dmp_state(unsigned char enable) -{ - unsigned char tmp; - if (st.chip_cfg.dmp_on == enable) - return 0; - - if (enable) { - if (!st.chip_cfg.dmp_loaded) - return -1; - /* Disable data ready interrupt. */ - set_int_enable(0); - /* Disable bypass mode. */ - mpu_set_bypass(0); - /* Keep constant sample rate, FIFO rate controlled by DMP. */ - mpu_set_sample_rate(st.chip_cfg.dmp_sample_rate); - /* Remove FIFO elements. */ - tmp = 0; - i2c_write(st.hw->addr, 0x23, 1, &tmp); - st.chip_cfg.dmp_on = 1; - /* Enable DMP interrupt. */ - set_int_enable(1); - mpu_reset_fifo(); - } else { - /* Disable DMP interrupt. */ - set_int_enable(0); - /* Restore FIFO settings. */ - tmp = st.chip_cfg.fifo_enable; - i2c_write(st.hw->addr, 0x23, 1, &tmp); - st.chip_cfg.dmp_on = 0; - mpu_reset_fifo(); - } - return 0; -} - -/** - * @brief Get DMP state. - * @param[out] enabled 1 if enabled. - * @return 0 if successful. - */ -int mpu_get_dmp_state(unsigned char *enabled) -{ - enabled[0] = st.chip_cfg.dmp_on; - return 0; -} - - -/* This initialization is similar to the one in ak8975.c. */ -int setup_compass(void) -{ -#ifdef AK89xx_SECONDARY - unsigned char data[4], akm_addr; - - mpu_set_bypass(1); - - /* Find compass. Possible addresses range from 0x0C to 0x0F. */ - for (akm_addr = 0x0C; akm_addr <= 0x0F; akm_addr++) { - int result; - result = i2c_read(akm_addr, AKM_REG_WHOAMI, 1, data); - if (!result && (data[0] == AKM_WHOAMI)) - break; - } - - if (akm_addr > 0x0F) { - /* TODO: Handle this case in all compass-related functions. */ - log_e("Compass not found.\n"); - return -1; - } - - st.chip_cfg.compass_addr = akm_addr; - - data[0] = AKM_POWER_DOWN; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) - return -1; - delay_ms(1); - - data[0] = AKM_FUSE_ROM_ACCESS; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) - return -1; - delay_ms(1); - - /* Get sensitivity adjustment data from fuse ROM. */ - if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ASAX, 3, data)) - return -1; - st.chip_cfg.mag_sens_adj[0] = (long)data[0] + 128; - st.chip_cfg.mag_sens_adj[1] = (long)data[1] + 128; - st.chip_cfg.mag_sens_adj[2] = (long)data[2] + 128; - - data[0] = AKM_POWER_DOWN; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, data)) - return -1; - delay_ms(1); - - mpu_set_bypass(0); - - /* Set up master mode, master clock, and ES bit. */ - data[0] = 0x40; - if (i2c_write(st.hw->addr, st.reg->i2c_mst, 1, data)) - return -1; - - /* Slave 0 reads from AKM data registers. */ - data[0] = BIT_I2C_READ | st.chip_cfg.compass_addr; - if (i2c_write(st.hw->addr, st.reg->s0_addr, 1, data)) - return -1; - - /* Compass reads start at this register. */ - data[0] = AKM_REG_ST1; - if (i2c_write(st.hw->addr, st.reg->s0_reg, 1, data)) - return -1; - - /* Enable slave 0, 8-byte reads. */ - data[0] = BIT_SLAVE_EN | 8; - if (i2c_write(st.hw->addr, st.reg->s0_ctrl, 1, data)) - return -1; - - /* Slave 1 changes AKM measurement mode. */ - data[0] = st.chip_cfg.compass_addr; - if (i2c_write(st.hw->addr, st.reg->s1_addr, 1, data)) - return -1; - - /* AKM measurement mode register. */ - data[0] = AKM_REG_CNTL; - if (i2c_write(st.hw->addr, st.reg->s1_reg, 1, data)) - return -1; - - /* Enable slave 1, 1-byte writes. */ - data[0] = BIT_SLAVE_EN | 1; - if (i2c_write(st.hw->addr, st.reg->s1_ctrl, 1, data)) - return -1; - - /* Set slave 1 data. */ - data[0] = AKM_SINGLE_MEASUREMENT; - if (i2c_write(st.hw->addr, st.reg->s1_do, 1, data)) - return -1; - - /* Trigger slave 0 and slave 1 actions at each sample. */ - data[0] = 0x03; - if (i2c_write(st.hw->addr, st.reg->i2c_delay_ctrl, 1, data)) - return -1; - -#ifdef MPU9150 - /* For the MPU9150, the auxiliary I2C bus needs to be set to VDD. */ - data[0] = BIT_I2C_MST_VDDIO; - if (i2c_write(st.hw->addr, st.reg->yg_offs_tc, 1, data)) - return -1; -#endif - - return 0; -#else - return -1; -#endif -} - -/** - * @brief Read raw compass data. - * @param[out] data Raw data in hardware units. - * @param[out] timestamp Timestamp in milliseconds. Null if not needed. - * @return 0 if successful. - */ -int mpu_get_compass_reg(short *data, unsigned long *timestamp) -{ -#ifdef AK89xx_SECONDARY - unsigned char tmp[9]; - - if (!(st.chip_cfg.sensors & INV_XYZ_COMPASS)) - return -1; - -#ifdef AK89xx_BYPASS - if (i2c_read(st.chip_cfg.compass_addr, AKM_REG_ST1, 8, tmp)) - return -1; - tmp[8] = AKM_SINGLE_MEASUREMENT; - if (i2c_write(st.chip_cfg.compass_addr, AKM_REG_CNTL, 1, tmp+8)) - return -1; -#else - if (i2c_read(st.hw->addr, st.reg->raw_compass, 8, tmp)) - return -1; -#endif - -#if defined AK8975_SECONDARY - /* AK8975 doesn't have the overrun error bit. */ - if (!(tmp[0] & AKM_DATA_READY)) - return -2; - if ((tmp[7] & AKM_OVERFLOW) || (tmp[7] & AKM_DATA_ERROR)) - return -3; -#elif defined AK8963_SECONDARY - /* AK8963 doesn't have the data read error bit. */ - if (!(tmp[0] & AKM_DATA_READY) || (tmp[0] & AKM_DATA_OVERRUN)) - return -2; - if (tmp[7] & AKM_OVERFLOW) - return -3; -#endif - data[0] = (tmp[2] << 8) | tmp[1]; - data[1] = (tmp[4] << 8) | tmp[3]; - data[2] = (tmp[6] << 8) | tmp[5]; - - data[0] = ((long)data[0] * st.chip_cfg.mag_sens_adj[0]) >> 8; - data[1] = ((long)data[1] * st.chip_cfg.mag_sens_adj[1]) >> 8; - data[2] = ((long)data[2] * st.chip_cfg.mag_sens_adj[2]) >> 8; - - if (timestamp) - get_ms(timestamp); - return 0; -#else - return -1; -#endif -} - -/** - * @brief Get the compass full-scale range. - * @param[out] fsr Current full-scale range. - * @return 0 if successful. - */ -int mpu_get_compass_fsr(unsigned short *fsr) -{ -#ifdef AK89xx_SECONDARY - fsr[0] = st.hw->compass_fsr; - return 0; -#else - return -1; -#endif -} - -/** - * @brief Enters LP accel motion interrupt mode. - * The behavior of this feature is very different between the MPU6050 and the - * MPU6500. Each chip's version of this feature is explained below. - * - * \n MPU6050: - * \n When this mode is first enabled, the hardware captures a single accel - * sample, and subsequent samples are compared with this one to determine if - * the device is in motion. Therefore, whenever this "locked" sample needs to - * be changed, this function must be called again. - * - * \n The hardware motion threshold can be between 32mg and 8160mg in 32mg - * increments. - * - * \n Low-power accel mode supports the following frequencies: - * \n 1.25Hz, 5Hz, 20Hz, 40Hz - * - * \n MPU6500: - * \n Unlike the MPU6050 version, the hardware does not "lock in" a reference - * sample. The hardware monitors the accel data and detects any large change - * over a short period of time. - * - * \n The hardware motion threshold can be between 4mg and 1020mg in 4mg - * increments. - * - * \n MPU6500 Low-power accel mode supports the following frequencies: - * \n 1.25Hz, 2.5Hz, 5Hz, 10Hz, 20Hz, 40Hz, 80Hz, 160Hz, 320Hz, 640Hz - * - * \n\n NOTES: - * \n The driver will round down @e thresh to the nearest supported value if - * an unsupported threshold is selected. - * \n To select a fractional wake-up frequency, round down the value passed to - * @e lpa_freq. - * \n The MPU6500 does not support a delay parameter. If this function is used - * for the MPU6500, the value passed to @e time will be ignored. - * \n To disable this mode, set @e lpa_freq to zero. The driver will restore - * the previous configuration. - * - * @param[in] thresh Motion threshold in mg. - * @param[in] time Duration in milliseconds that the accel data must - * exceed @e thresh before motion is reported. - * @param[in] lpa_freq Minimum sampling rate, or zero to disable. - * @return 0 if successful. - */ -int mpu_lp_motion_interrupt(unsigned short thresh, unsigned char time, - unsigned char lpa_freq) -{ - unsigned char data[3]; - - if (lpa_freq) { - unsigned char thresh_hw; - -#if defined MPU6050 - /* TODO: Make these const/#defines. */ - /* 1LSb = 32mg. */ - if (thresh > 8160) - thresh_hw = 255; - else if (thresh < 32) - thresh_hw = 1; - else - thresh_hw = thresh >> 5; -#elif defined MPU6500 - /* 1LSb = 4mg. */ - if (thresh > 1020) - thresh_hw = 255; - else if (thresh < 4) - thresh_hw = 1; - else - thresh_hw = thresh >> 2; -#endif - - if (!time) - /* Minimum duration must be 1ms. */ - time = 1; - -#if defined MPU6050 - if (lpa_freq > 40) -#elif defined MPU6500 - if (lpa_freq > 640) -#endif - /* At this point, the chip has not been re-configured, so the - * function can safely exit. - */ - return -1; - - if (!st.chip_cfg.int_motion_only) { - /* Store current settings for later. */ - if (st.chip_cfg.dmp_on) { - mpu_set_dmp_state(0); - st.chip_cfg.cache.dmp_on = 1; - } else - st.chip_cfg.cache.dmp_on = 0; - mpu_get_gyro_fsr(&st.chip_cfg.cache.gyro_fsr); - mpu_get_accel_fsr(&st.chip_cfg.cache.accel_fsr); - mpu_get_lpf(&st.chip_cfg.cache.lpf); - mpu_get_sample_rate(&st.chip_cfg.cache.sample_rate); - st.chip_cfg.cache.sensors_on = st.chip_cfg.sensors; - mpu_get_fifo_config(&st.chip_cfg.cache.fifo_sensors); - } - -#ifdef MPU6050 - /* Disable hardware interrupts for now. */ - set_int_enable(0); - - /* Enter full-power accel-only mode. */ - mpu_lp_accel_mode(0); - - /* Override current LPF (and HPF) settings to obtain a valid accel - * reading. - */ - data[0] = INV_FILTER_256HZ_NOLPF2; - if (i2c_write(st.hw->addr, st.reg->lpf, 1, data)) - return -1; - - /* NOTE: Digital high pass filter should be configured here. Since this - * driver doesn't modify those bits anywhere, they should already be - * cleared by default. - */ - - /* Configure the device to send motion interrupts. */ - /* Enable motion interrupt. */ - data[0] = BIT_MOT_INT_EN; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) - goto lp_int_restore; - - /* Set motion interrupt parameters. */ - data[0] = thresh_hw; - data[1] = time; - if (i2c_write(st.hw->addr, st.reg->motion_thr, 2, data)) - goto lp_int_restore; - - /* Force hardware to "lock" current accel sample. */ - delay_ms(5); - data[0] = (st.chip_cfg.accel_fsr << 3) | BITS_HPF; - if (i2c_write(st.hw->addr, st.reg->accel_cfg, 1, data)) - goto lp_int_restore; - - /* Set up LP accel mode. */ - data[0] = BIT_LPA_CYCLE; - if (lpa_freq == 1) - data[1] = INV_LPA_1_25HZ; - else if (lpa_freq <= 5) - data[1] = INV_LPA_5HZ; - else if (lpa_freq <= 20) - data[1] = INV_LPA_20HZ; - else - data[1] = INV_LPA_40HZ; - data[1] = (data[1] << 6) | BIT_STBY_XYZG; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 2, data)) - goto lp_int_restore; - - st.chip_cfg.int_motion_only = 1; - return 0; -#elif defined MPU6500 - /* Disable hardware interrupts. */ - set_int_enable(0); - - /* Enter full-power accel-only mode, no FIFO/DMP. */ - data[0] = 0; - data[1] = 0; - data[2] = BIT_STBY_XYZG; - if (i2c_write(st.hw->addr, st.reg->user_ctrl, 3, data)) - goto lp_int_restore; - - /* Set motion threshold. */ - data[0] = thresh_hw; - if (i2c_write(st.hw->addr, st.reg->motion_thr, 1, data)) - goto lp_int_restore; - - /* Set wake frequency. */ - if (lpa_freq == 1) - data[0] = INV_LPA_1_25HZ; - else if (lpa_freq == 2) - data[0] = INV_LPA_2_5HZ; - else if (lpa_freq <= 5) - data[0] = INV_LPA_5HZ; - else if (lpa_freq <= 10) - data[0] = INV_LPA_10HZ; - else if (lpa_freq <= 20) - data[0] = INV_LPA_20HZ; - else if (lpa_freq <= 40) - data[0] = INV_LPA_40HZ; - else if (lpa_freq <= 80) - data[0] = INV_LPA_80HZ; - else if (lpa_freq <= 160) - data[0] = INV_LPA_160HZ; - else if (lpa_freq <= 320) - data[0] = INV_LPA_320HZ; - else - data[0] = INV_LPA_640HZ; - if (i2c_write(st.hw->addr, st.reg->lp_accel_odr, 1, data)) - goto lp_int_restore; - - /* Enable motion interrupt (MPU6500 version). */ - data[0] = BITS_WOM_EN; - if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) - goto lp_int_restore; - - /* Enable cycle mode. */ - data[0] = BIT_LPA_CYCLE; - if (i2c_write(st.hw->addr, st.reg->pwr_mgmt_1, 1, data)) - goto lp_int_restore; - - /* Enable interrupt. */ - data[0] = BIT_MOT_INT_EN; - if (i2c_write(st.hw->addr, st.reg->int_enable, 1, data)) - goto lp_int_restore; - - st.chip_cfg.int_motion_only = 1; - return 0; -#endif - } else { - /* Don't "restore" the previous state if no state has been saved. */ - int ii; - char *cache_ptr = (char*)&st.chip_cfg.cache; - for (ii = 0; ii < sizeof(st.chip_cfg.cache); ii++) { - if (cache_ptr[ii] != 0) - goto lp_int_restore; - } - /* If we reach this point, motion interrupt mode hasn't been used yet. */ - return -1; - } -lp_int_restore: - /* Set to invalid values to ensure no I2C writes are skipped. */ - st.chip_cfg.gyro_fsr = 0xFF; - st.chip_cfg.accel_fsr = 0xFF; - st.chip_cfg.lpf = 0xFF; - st.chip_cfg.sample_rate = 0xFFFF; - st.chip_cfg.sensors = 0xFF; - st.chip_cfg.fifo_enable = 0xFF; - st.chip_cfg.clk_src = INV_CLK_PLL; - mpu_set_sensors(st.chip_cfg.cache.sensors_on); - mpu_set_gyro_fsr(st.chip_cfg.cache.gyro_fsr); - mpu_set_accel_fsr(st.chip_cfg.cache.accel_fsr); - mpu_set_lpf(st.chip_cfg.cache.lpf); - mpu_set_sample_rate(st.chip_cfg.cache.sample_rate); - mpu_configure_fifo(st.chip_cfg.cache.fifo_sensors); - - if (st.chip_cfg.cache.dmp_on) - mpu_set_dmp_state(1); - -#ifdef MPU6500 - /* Disable motion interrupt (MPU6500 version). */ - data[0] = 0; - if (i2c_write(st.hw->addr, st.reg->accel_intel, 1, data)) - goto lp_int_restore; -#endif - - st.chip_cfg.int_motion_only = 0; - return 0; -} - -/** - * @} - */ - diff --git a/interface/external/MotionDriver/src/inv_mpu_dmp_motion_driver.c b/interface/external/MotionDriver/src/inv_mpu_dmp_motion_driver.c deleted file mode 100644 index db71b4b74c..0000000000 --- a/interface/external/MotionDriver/src/inv_mpu_dmp_motion_driver.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - $License: - Copyright (C) 2011-2012 InvenSense Corporation, All Rights Reserved. - See included License.txt for License information. - $ - */ -/** - * @addtogroup DRIVERS Sensor Driver Layer - * @brief Hardware drivers to communicate with sensors via I2C. - * - * @{ - * @file inv_mpu_dmp_motion_driver.c - * @brief DMP image and interface functions. - * @details All functions are preceded by the dmp_ prefix to - * differentiate among MPL and general driver function calls. - */ -#include -#include -#include -#include -#include -#include "inv_mpu.h" -#include "inv_mpu_dmp_motion_driver.h" -#include "dmpKey.h" -#include "dmpmap.h" -#include "inv_tty.h" - -/* The following functions must be defined for this platform: - * i2c_write(unsigned char slave_addr, unsigned char reg_addr, - * unsigned char length, unsigned char const *data) - * i2c_read(unsigned char slave_addr, unsigned char reg_addr, - * unsigned char length, unsigned char *data) - * delay_ms(unsigned long num_ms) - * get_ms(unsigned long *count) - */ -#if defined MOTION_DRIVER_TARGET_MSP430 -#include "msp430.h" -#include "msp430_clock.h" -#define delay_ms msp430_delay_ms -#define get_ms msp430_get_clock_ms -#define log_i(...) do {} while (0) -#define log_e(...) do {} while (0) - -#elif defined EMPL_TARGET_MSP430 -#include "msp430.h" -#include "msp430_clock.h" -#include "log.h" -#define delay_ms msp430_delay_ms -#define get_ms msp430_get_clock_ms -#define log_i MPL_LOGI -#define log_e MPL_LOGE - -#elif defined EMPL_TARGET_UC3L0 -/* Instead of using the standard TWI driver from the ASF library, we're using - * a TWI driver that follows the slave address + register address convention. - */ -#include "delay.h" -#include "sysclk.h" -#include "log.h" -#include "uc3l0_clock.h" -/* delay_ms is a function already defined in ASF. */ -#define get_ms uc3l0_get_clock_ms -#define log_i MPL_LOGI -#define log_e MPL_LOGE - -#else -#define i2c_write tty_i2c_write -#define i2c_read tty_i2c_read -#define delay_ms tty_delay_ms -#define get_ms tty_get_clock_ms -#endif - -/* These defines are copied from dmpDefaultMPU6050.c in the general MPL - * releases. These defines may change for each DMP image, so be sure to modify - * these values when switching to a new image. - */ -#define CFG_LP_QUAT (2712) -#define END_ORIENT_TEMP (1866) -#define CFG_27 (2742) -#define CFG_20 (2224) -#define CFG_23 (2745) -#define CFG_FIFO_ON_EVENT (2690) -#define END_PREDICTION_UPDATE (1761) -#define CGNOTICE_INTR (2620) -#define X_GRT_Y_TMP (1358) -#define CFG_DR_INT (1029) -#define CFG_AUTH (1035) -#define UPDATE_PROP_ROT (1835) -#define END_COMPARE_Y_X_TMP2 (1455) -#define SKIP_X_GRT_Y_TMP (1359) -#define SKIP_END_COMPARE (1435) -#define FCFG_3 (1088) -#define FCFG_2 (1066) -#define FCFG_1 (1062) -#define END_COMPARE_Y_X_TMP3 (1434) -#define FCFG_7 (1073) -#define FCFG_6 (1106) -#define FLAT_STATE_END (1713) -#define SWING_END_4 (1616) -#define SWING_END_2 (1565) -#define SWING_END_3 (1587) -#define SWING_END_1 (1550) -#define CFG_8 (2718) -#define CFG_15 (2727) -#define CFG_16 (2746) -#define CFG_EXT_GYRO_BIAS (1189) -#define END_COMPARE_Y_X_TMP (1407) -#define DO_NOT_UPDATE_PROP_ROT (1839) -#define CFG_7 (1205) -#define FLAT_STATE_END_TEMP (1683) -#define END_COMPARE_Y_X (1484) -#define SKIP_SWING_END_1 (1551) -#define SKIP_SWING_END_3 (1588) -#define SKIP_SWING_END_2 (1566) -#define TILTG75_START (1672) -#define CFG_6 (2753) -#define TILTL75_END (1669) -#define END_ORIENT (1884) -#define CFG_FLICK_IN (2573) -#define TILTL75_START (1643) -#define CFG_MOTION_BIAS (1208) -#define X_GRT_Y (1408) -#define TEMPLABEL (2324) -#define CFG_ANDROID_ORIENT_INT (1853) -#define CFG_GYRO_RAW_DATA (2722) -#define X_GRT_Y_TMP2 (1379) - -#define D_0_22 (22+512) -#define D_0_24 (24+512) - -#define D_0_36 (36) -#define D_0_52 (52) -#define D_0_96 (96) -#define D_0_104 (104) -#define D_0_108 (108) -#define D_0_163 (163) -#define D_0_188 (188) -#define D_0_192 (192) -#define D_0_224 (224) -#define D_0_228 (228) -#define D_0_232 (232) -#define D_0_236 (236) - -#define D_1_2 (256 + 2) -#define D_1_4 (256 + 4) -#define D_1_8 (256 + 8) -#define D_1_10 (256 + 10) -#define D_1_24 (256 + 24) -#define D_1_28 (256 + 28) -#define D_1_36 (256 + 36) -#define D_1_40 (256 + 40) -#define D_1_44 (256 + 44) -#define D_1_72 (256 + 72) -#define D_1_74 (256 + 74) -#define D_1_79 (256 + 79) -#define D_1_88 (256 + 88) -#define D_1_90 (256 + 90) -#define D_1_92 (256 + 92) -#define D_1_96 (256 + 96) -#define D_1_98 (256 + 98) -#define D_1_106 (256 + 106) -#define D_1_108 (256 + 108) -#define D_1_112 (256 + 112) -#define D_1_128 (256 + 144) -#define D_1_152 (256 + 12) -#define D_1_160 (256 + 160) -#define D_1_176 (256 + 176) -#define D_1_178 (256 + 178) -#define D_1_218 (256 + 218) -#define D_1_232 (256 + 232) -#define D_1_236 (256 + 236) -#define D_1_240 (256 + 240) -#define D_1_244 (256 + 244) -#define D_1_250 (256 + 250) -#define D_1_252 (256 + 252) -#define D_2_12 (512 + 12) -#define D_2_96 (512 + 96) -#define D_2_108 (512 + 108) -#define D_2_208 (512 + 208) -#define D_2_224 (512 + 224) -#define D_2_236 (512 + 236) -#define D_2_244 (512 + 244) -#define D_2_248 (512 + 248) -#define D_2_252 (512 + 252) - -#define CPASS_BIAS_X (35 * 16 + 4) -#define CPASS_BIAS_Y (35 * 16 + 8) -#define CPASS_BIAS_Z (35 * 16 + 12) -#define CPASS_MTX_00 (36 * 16) -#define CPASS_MTX_01 (36 * 16 + 4) -#define CPASS_MTX_02 (36 * 16 + 8) -#define CPASS_MTX_10 (36 * 16 + 12) -#define CPASS_MTX_11 (37 * 16) -#define CPASS_MTX_12 (37 * 16 + 4) -#define CPASS_MTX_20 (37 * 16 + 8) -#define CPASS_MTX_21 (37 * 16 + 12) -#define CPASS_MTX_22 (43 * 16 + 12) -#define D_EXT_GYRO_BIAS_X (61 * 16) -#define D_EXT_GYRO_BIAS_Y (61 * 16) + 4 -#define D_EXT_GYRO_BIAS_Z (61 * 16) + 8 -#define D_ACT0 (40 * 16) -#define D_ACSX (40 * 16 + 4) -#define D_ACSY (40 * 16 + 8) -#define D_ACSZ (40 * 16 + 12) - -#define FLICK_MSG (45 * 16 + 4) -#define FLICK_COUNTER (45 * 16 + 8) -#define FLICK_LOWER (45 * 16 + 12) -#define FLICK_UPPER (46 * 16 + 12) - -#define D_AUTH_OUT (992) -#define D_AUTH_IN (996) -#define D_AUTH_A (1000) -#define D_AUTH_B (1004) - -#define D_PEDSTD_BP_B (768 + 0x1C) -#define D_PEDSTD_HP_A (768 + 0x78) -#define D_PEDSTD_HP_B (768 + 0x7C) -#define D_PEDSTD_BP_A4 (768 + 0x40) -#define D_PEDSTD_BP_A3 (768 + 0x44) -#define D_PEDSTD_BP_A2 (768 + 0x48) -#define D_PEDSTD_BP_A1 (768 + 0x4C) -#define D_PEDSTD_INT_THRSH (768 + 0x68) -#define D_PEDSTD_CLIP (768 + 0x6C) -#define D_PEDSTD_SB (768 + 0x28) -#define D_PEDSTD_SB_TIME (768 + 0x2C) -#define D_PEDSTD_PEAKTHRSH (768 + 0x98) -#define D_PEDSTD_TIML (768 + 0x2A) -#define D_PEDSTD_TIMH (768 + 0x2E) -#define D_PEDSTD_PEAK (768 + 0X94) -#define D_PEDSTD_STEPCTR (768 + 0x60) -#define D_PEDSTD_TIMECTR (964) -#define D_PEDSTD_DECI (768 + 0xA0) - -#define D_HOST_NO_MOT (976) -#define D_ACCEL_BIAS (660) - -#define D_ORIENT_GAP (76) - -#define D_TILT0_H (48) -#define D_TILT0_L (50) -#define D_TILT1_H (52) -#define D_TILT1_L (54) -#define D_TILT2_H (56) -#define D_TILT2_L (58) -#define D_TILT3_H (60) -#define D_TILT3_L (62) - -#define DMP_CODE_SIZE (3062) - -static const unsigned char dmp_memory[DMP_CODE_SIZE] = { - /* bank # 0 */ - 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x65, 0x00, 0x54, 0xff, 0xef, 0x00, 0x00, 0xfa, 0x80, 0x00, 0x0b, 0x12, 0x82, 0x00, 0x01, - 0x03, 0x0c, 0x30, 0xc3, 0x0e, 0x8c, 0x8c, 0xe9, 0x14, 0xd5, 0x40, 0x02, 0x13, 0x71, 0x0f, 0x8e, - 0x38, 0x83, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, 0x25, 0x8e, 0xf8, 0x83, 0x30, 0x00, 0xf8, 0x83, - 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfe, 0xa9, 0xd6, 0x24, 0x00, 0x04, 0x00, 0x1a, 0x82, 0x79, 0xa1, - 0x00, 0x00, 0x00, 0x3c, 0xff, 0xff, 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, - 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x6e, 0x00, 0x00, 0x06, 0x92, 0x0a, 0x16, 0xc0, 0xdf, - 0xff, 0xff, 0x02, 0x56, 0xfd, 0x8c, 0xd3, 0x77, 0xff, 0xe1, 0xc4, 0x96, 0xe0, 0xc5, 0xbe, 0xaa, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0x2b, 0x00, 0x00, 0x16, 0x57, 0x00, 0x00, 0x03, 0x59, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xfa, 0x00, 0x02, 0x6c, 0x1d, 0x00, 0x00, 0x00, 0x00, - 0x3f, 0xff, 0xdf, 0xeb, 0x00, 0x3e, 0xb3, 0xb6, 0x00, 0x0d, 0x22, 0x78, 0x00, 0x00, 0x2f, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x42, 0xb5, 0x00, 0x00, 0x39, 0xa2, 0x00, 0x00, 0xb3, 0x65, - 0xd9, 0x0e, 0x9f, 0xc9, 0x1d, 0xcf, 0x4c, 0x34, 0x30, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x3b, 0xb6, 0x7a, 0xe8, 0x00, 0x64, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* bank # 1 */ - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfa, 0x92, 0x10, 0x00, 0x22, 0x5e, 0x00, 0x0d, 0x22, 0x9f, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0xff, 0x46, 0x00, 0x00, 0x63, 0xd4, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x04, 0xd6, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x72, 0x00, 0x00, 0x00, 0x40, 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, 0x05, 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, - 0xff, 0x9b, 0xfc, 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, 0x10, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xb2, 0x6a, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x01, 0xfb, 0x83, 0x00, 0x68, 0x00, 0x00, 0x00, 0xd9, 0xfc, 0x00, 0x7c, 0xf1, 0xff, 0x83, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x03, 0xe8, 0x00, 0x64, 0x00, 0x28, - 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x10, 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, 0x05, 0x00, 0x05, 0xba, 0xc6, 0x00, 0x47, 0x78, 0xa2, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x25, 0x4d, 0x00, 0x2f, 0x70, 0x6d, 0x00, 0x00, 0x05, 0xae, 0x00, 0x0c, 0x02, 0xd0, - 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, 0x64, 0x00, 0x00, 0x00, 0x08, 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, 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, 0x0e, 0x00, 0x0e, - 0x00, 0x00, 0x0a, 0xc7, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0xff, 0xff, 0xff, 0x9c, - 0x00, 0x00, 0x0b, 0x2b, 0x00, 0x00, 0x00, 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x96, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 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, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd7, 0x84, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x93, 0x8f, 0x9d, 0x1e, 0x1b, 0x1c, 0x19, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x18, 0x85, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 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, 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, 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, 0xc5, 0xcd, 0xc7, 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, 0xa3, 0xa3, - 0xa3, 0xa3, 0xb2, 0x8b, 0xb6, 0x9b, 0xf2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, - 0xa3, 0xf1, 0xb0, 0x87, 0xb5, 0x9a, 0xa3, 0xf3, 0x9b, 0xa3, 0xa3, 0xdc, 0xba, 0xac, 0xdf, 0xb9, - 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 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 -}; - -static const unsigned short sStartAddress = 0x0400; - -/* END OF SECTION COPIED FROM dmpDefaultMPU6050.c */ - -#define INT_SRC_TAP (0x01) -#define INT_SRC_ANDROID_ORIENT (0x08) - -#define DMP_FEATURE_SEND_ANY_GYRO (DMP_FEATURE_SEND_RAW_GYRO | \ - DMP_FEATURE_SEND_CAL_GYRO) - -#define MAX_PACKET_LENGTH (32) - -#define DMP_SAMPLE_RATE (200) -#define GYRO_SF (46850825LL * 200 / DMP_SAMPLE_RATE) - -#define FIFO_CORRUPTION_CHECK -#ifdef FIFO_CORRUPTION_CHECK -#define QUAT_ERROR_THRESH (1L<<24) -#define QUAT_MAG_SQ_NORMALIZED (1L<<28) -#define QUAT_MAG_SQ_MIN (QUAT_MAG_SQ_NORMALIZED - QUAT_ERROR_THRESH) -#define QUAT_MAG_SQ_MAX (QUAT_MAG_SQ_NORMALIZED + QUAT_ERROR_THRESH) -#endif - -struct dmp_s { - void (*tap_cb)(unsigned char count, unsigned char direction); - void (*android_orient_cb)(unsigned char orientation); - unsigned short orient; - unsigned short feature_mask; - unsigned short fifo_rate; - unsigned char packet_length; -}; - -static struct dmp_s dmp = { - .tap_cb = NULL, - .android_orient_cb = NULL, - .orient = 0, - .feature_mask = 0, - .fifo_rate = 0, - .packet_length = 0 -}; - -/** - * @brief Load the DMP with this image. - * @return 0 if successful. - */ -int dmp_load_motion_driver_firmware(void) -{ - return mpu_load_firmware(DMP_CODE_SIZE, dmp_memory, sStartAddress, - DMP_SAMPLE_RATE); -} - -/** - * @brief Push gyro and accel orientation to the DMP. - * The orientation is represented here as the output of - * @e inv_orientation_matrix_to_scalar. - * @param[in] orient Gyro and accel orientation in body frame. - * @return 0 if successful. - */ -int dmp_set_orientation(unsigned short orient) -{ - unsigned char gyro_regs[3], accel_regs[3]; - const unsigned char gyro_axes[3] = {DINA4C, DINACD, DINA6C}; - const unsigned char accel_axes[3] = {DINA0C, DINAC9, DINA2C}; - const unsigned char gyro_sign[3] = {DINA36, DINA56, DINA76}; - const unsigned char accel_sign[3] = {DINA26, DINA46, DINA66}; - - gyro_regs[0] = gyro_axes[orient & 3]; - gyro_regs[1] = gyro_axes[(orient >> 3) & 3]; - gyro_regs[2] = gyro_axes[(orient >> 6) & 3]; - accel_regs[0] = accel_axes[orient & 3]; - accel_regs[1] = accel_axes[(orient >> 3) & 3]; - accel_regs[2] = accel_axes[(orient >> 6) & 3]; - - /* Chip-to-body, axes only. */ - if (mpu_write_mem(FCFG_1, 3, gyro_regs)) - return -1; - if (mpu_write_mem(FCFG_2, 3, accel_regs)) - return -1; - - memcpy(gyro_regs, gyro_sign, 3); - memcpy(accel_regs, accel_sign, 3); - if (orient & 4) { - gyro_regs[0] |= 1; - accel_regs[0] |= 1; - } - if (orient & 0x20) { - gyro_regs[1] |= 1; - accel_regs[1] |= 1; - } - if (orient & 0x100) { - gyro_regs[2] |= 1; - accel_regs[2] |= 1; - } - - /* Chip-to-body, sign only. */ - if (mpu_write_mem(FCFG_3, 3, gyro_regs)) - return -1; - if (mpu_write_mem(FCFG_7, 3, accel_regs)) - return -1; - dmp.orient = orient; - return 0; -} - -/** - * @brief Push gyro biases to the DMP. - * Because the gyro integration is handled in the DMP, any gyro biases - * calculated by the MPL should be pushed down to DMP memory to remove - * 3-axis quaternion drift. - * \n NOTE: If the DMP-based gyro calibration is enabled, the DMP will - * overwrite the biases written to this location once a new one is computed. - * @param[in] bias Gyro biases in q16. - * @return 0 if successful. - */ -int dmp_set_gyro_bias(long *bias) -{ - long gyro_bias_body[3]; - unsigned char regs[4]; - - gyro_bias_body[0] = bias[dmp.orient & 3]; - if (dmp.orient & 4) - gyro_bias_body[0] *= -1; - gyro_bias_body[1] = bias[(dmp.orient >> 3) & 3]; - if (dmp.orient & 0x20) - gyro_bias_body[1] *= -1; - gyro_bias_body[2] = bias[(dmp.orient >> 6) & 3]; - if (dmp.orient & 0x100) - gyro_bias_body[2] *= -1; - -#ifdef EMPL_NO_64BIT - gyro_bias_body[0] = (long)(((float)gyro_bias_body[0] * GYRO_SF) / 1073741824.f); - gyro_bias_body[1] = (long)(((float)gyro_bias_body[1] * GYRO_SF) / 1073741824.f); - gyro_bias_body[2] = (long)(((float)gyro_bias_body[2] * GYRO_SF) / 1073741824.f); -#else - gyro_bias_body[0] = (long)(((long long)gyro_bias_body[0] * GYRO_SF) >> 30); - gyro_bias_body[1] = (long)(((long long)gyro_bias_body[1] * GYRO_SF) >> 30); - gyro_bias_body[2] = (long)(((long long)gyro_bias_body[2] * GYRO_SF) >> 30); -#endif - - regs[0] = (unsigned char)((gyro_bias_body[0] >> 24) & 0xFF); - regs[1] = (unsigned char)((gyro_bias_body[0] >> 16) & 0xFF); - regs[2] = (unsigned char)((gyro_bias_body[0] >> 8) & 0xFF); - regs[3] = (unsigned char)(gyro_bias_body[0] & 0xFF); - if (mpu_write_mem(D_EXT_GYRO_BIAS_X, 4, regs)) - return -1; - - regs[0] = (unsigned char)((gyro_bias_body[1] >> 24) & 0xFF); - regs[1] = (unsigned char)((gyro_bias_body[1] >> 16) & 0xFF); - regs[2] = (unsigned char)((gyro_bias_body[1] >> 8) & 0xFF); - regs[3] = (unsigned char)(gyro_bias_body[1] & 0xFF); - if (mpu_write_mem(D_EXT_GYRO_BIAS_Y, 4, regs)) - return -1; - - regs[0] = (unsigned char)((gyro_bias_body[2] >> 24) & 0xFF); - regs[1] = (unsigned char)((gyro_bias_body[2] >> 16) & 0xFF); - regs[2] = (unsigned char)((gyro_bias_body[2] >> 8) & 0xFF); - regs[3] = (unsigned char)(gyro_bias_body[2] & 0xFF); - return mpu_write_mem(D_EXT_GYRO_BIAS_Z, 4, regs); -} - -/** - * @brief Push accel biases to the DMP. - * These biases will be removed from the DMP 6-axis quaternion. - * @param[in] bias Accel biases in q16. - * @return 0 if successful. - */ -int dmp_set_accel_bias(long *bias) -{ - long accel_bias_body[3]; - unsigned char regs[12]; - long long accel_sf; - unsigned short accel_sens; - - mpu_get_accel_sens(&accel_sens); - accel_sf = (long long)accel_sens << 15; - __no_operation(); - - accel_bias_body[0] = bias[dmp.orient & 3]; - if (dmp.orient & 4) - accel_bias_body[0] *= -1; - accel_bias_body[1] = bias[(dmp.orient >> 3) & 3]; - if (dmp.orient & 0x20) - accel_bias_body[1] *= -1; - accel_bias_body[2] = bias[(dmp.orient >> 6) & 3]; - if (dmp.orient & 0x100) - accel_bias_body[2] *= -1; - -#ifdef EMPL_NO_64BIT - accel_bias_body[0] = (long)(((float)accel_bias_body[0] * accel_sf) / 1073741824.f); - accel_bias_body[1] = (long)(((float)accel_bias_body[1] * accel_sf) / 1073741824.f); - accel_bias_body[2] = (long)(((float)accel_bias_body[2] * accel_sf) / 1073741824.f); -#else - accel_bias_body[0] = (long)(((long long)accel_bias_body[0] * accel_sf) >> 30); - accel_bias_body[1] = (long)(((long long)accel_bias_body[1] * accel_sf) >> 30); - accel_bias_body[2] = (long)(((long long)accel_bias_body[2] * accel_sf) >> 30); -#endif - - regs[0] = (unsigned char)((accel_bias_body[0] >> 24) & 0xFF); - regs[1] = (unsigned char)((accel_bias_body[0] >> 16) & 0xFF); - regs[2] = (unsigned char)((accel_bias_body[0] >> 8) & 0xFF); - regs[3] = (unsigned char)(accel_bias_body[0] & 0xFF); - regs[4] = (unsigned char)((accel_bias_body[1] >> 24) & 0xFF); - regs[5] = (unsigned char)((accel_bias_body[1] >> 16) & 0xFF); - regs[6] = (unsigned char)((accel_bias_body[1] >> 8) & 0xFF); - regs[7] = (unsigned char)(accel_bias_body[1] & 0xFF); - regs[8] = (unsigned char)((accel_bias_body[2] >> 24) & 0xFF); - regs[9] = (unsigned char)((accel_bias_body[2] >> 16) & 0xFF); - regs[10] = (unsigned char)((accel_bias_body[2] >> 8) & 0xFF); - regs[11] = (unsigned char)(accel_bias_body[2] & 0xFF); - return mpu_write_mem(D_ACCEL_BIAS, 12, regs); -} - -/** - * @brief Set DMP output rate. - * Only used when DMP is on. - * @param[in] rate Desired fifo rate (Hz). - * @return 0 if successful. - */ -int dmp_set_fifo_rate(unsigned short rate) -{ - const unsigned char regs_end[12] = {DINAFE, DINAF2, DINAAB, - 0xc4, DINAAA, DINAF1, DINADF, DINADF, 0xBB, 0xAF, DINADF, DINADF}; - unsigned short div; - unsigned char tmp[8]; - - if (rate > DMP_SAMPLE_RATE) - return -1; - div = DMP_SAMPLE_RATE / rate - 1; - tmp[0] = (unsigned char)((div >> 8) & 0xFF); - tmp[1] = (unsigned char)(div & 0xFF); - if (mpu_write_mem(D_0_22, 2, tmp)) - return -1; - if (mpu_write_mem(CFG_6, 12, (unsigned char*)regs_end)) - return -1; - - dmp.fifo_rate = rate; - return 0; -} - -/** - * @brief Get DMP output rate. - * @param[out] rate Current fifo rate (Hz). - * @return 0 if successful. - */ -int dmp_get_fifo_rate(unsigned short *rate) -{ - rate[0] = dmp.fifo_rate; - return 0; -} - -/** - * @brief Set tap threshold for a specific axis. - * @param[in] axis 1, 2, and 4 for XYZ accel, respectively. - * @param[in] thresh Tap threshold, in mg/ms. - * @return 0 if successful. - */ -int dmp_set_tap_thresh(unsigned char axis, unsigned short thresh) -{ - unsigned char tmp[4], accel_fsr; - float scaled_thresh; - unsigned short dmp_thresh, dmp_thresh_2; - if (!(axis & TAP_XYZ) || thresh > 1600) - return -1; - - scaled_thresh = (float)thresh / DMP_SAMPLE_RATE; - - mpu_get_accel_fsr(&accel_fsr); - switch (accel_fsr) { - case 2: - dmp_thresh = (unsigned short)(scaled_thresh * 16384); - /* dmp_thresh * 0.75 */ - dmp_thresh_2 = (unsigned short)(scaled_thresh * 12288); - break; - case 4: - dmp_thresh = (unsigned short)(scaled_thresh * 8192); - /* dmp_thresh * 0.75 */ - dmp_thresh_2 = (unsigned short)(scaled_thresh * 6144); - break; - case 8: - dmp_thresh = (unsigned short)(scaled_thresh * 4096); - /* dmp_thresh * 0.75 */ - dmp_thresh_2 = (unsigned short)(scaled_thresh * 3072); - break; - case 16: - dmp_thresh = (unsigned short)(scaled_thresh * 2048); - /* dmp_thresh * 0.75 */ - dmp_thresh_2 = (unsigned short)(scaled_thresh * 1536); - break; - default: - return -1; - } - tmp[0] = (unsigned char)(dmp_thresh >> 8); - tmp[1] = (unsigned char)(dmp_thresh & 0xFF); - tmp[2] = (unsigned char)(dmp_thresh_2 >> 8); - tmp[3] = (unsigned char)(dmp_thresh_2 & 0xFF); - - if (axis & TAP_X) { - if (mpu_write_mem(DMP_TAP_THX, 2, tmp)) - return -1; - if (mpu_write_mem(D_1_36, 2, tmp+2)) - return -1; - } - if (axis & TAP_Y) { - if (mpu_write_mem(DMP_TAP_THY, 2, tmp)) - return -1; - if (mpu_write_mem(D_1_40, 2, tmp+2)) - return -1; - } - if (axis & TAP_Z) { - if (mpu_write_mem(DMP_TAP_THZ, 2, tmp)) - return -1; - if (mpu_write_mem(D_1_44, 2, tmp+2)) - return -1; - } - return 0; -} - -/** - * @brief Set which axes will register a tap. - * @param[in] axis 1, 2, and 4 for XYZ, respectively. - * @return 0 if successful. - */ -int dmp_set_tap_axes(unsigned char axis) -{ - unsigned char tmp = 0; - - if (axis & TAP_X) - tmp |= 0x30; - if (axis & TAP_Y) - tmp |= 0x0C; - if (axis & TAP_Z) - tmp |= 0x03; - return mpu_write_mem(D_1_72, 1, &tmp); -} - -/** - * @brief Set minimum number of taps needed for an interrupt. - * @param[in] min_taps Minimum consecutive taps (1-4). - * @return 0 if successful. - */ -int dmp_set_tap_count(unsigned char min_taps) -{ - unsigned char tmp; - - if (min_taps < 1) - min_taps = 1; - else if (min_taps > 4) - min_taps = 4; - - tmp = min_taps - 1; - return mpu_write_mem(D_1_79, 1, &tmp); -} - -/** - * @brief Set length between valid taps. - * @param[in] time Milliseconds between taps. - * @return 0 if successful. - */ -int dmp_set_tap_time(unsigned short time) -{ - unsigned short dmp_time; - unsigned char tmp[2]; - - dmp_time = time / (1000 / DMP_SAMPLE_RATE); - tmp[0] = (unsigned char)(dmp_time >> 8); - tmp[1] = (unsigned char)(dmp_time & 0xFF); - return mpu_write_mem(DMP_TAPW_MIN, 2, tmp); -} - -/** - * @brief Set max time between taps to register as a multi-tap. - * @param[in] time Max milliseconds between taps. - * @return 0 if successful. - */ -int dmp_set_tap_time_multi(unsigned short time) -{ - unsigned short dmp_time; - unsigned char tmp[2]; - - dmp_time = time / (1000 / DMP_SAMPLE_RATE); - tmp[0] = (unsigned char)(dmp_time >> 8); - tmp[1] = (unsigned char)(dmp_time & 0xFF); - return mpu_write_mem(D_1_218, 2, tmp); -} - -/** - * @brief Set shake rejection threshold. - * If the DMP detects a gyro sample larger than @e thresh, taps are rejected. - * @param[in] sf Gyro scale factor. - * @param[in] thresh Gyro threshold in dps. - * @return 0 if successful. - */ -int dmp_set_shake_reject_thresh(long sf, unsigned short thresh) -{ - unsigned char tmp[4]; - long thresh_scaled = sf / 1000 * thresh; - tmp[0] = (unsigned char)(((long)thresh_scaled >> 24) & 0xFF); - tmp[1] = (unsigned char)(((long)thresh_scaled >> 16) & 0xFF); - tmp[2] = (unsigned char)(((long)thresh_scaled >> 8) & 0xFF); - tmp[3] = (unsigned char)((long)thresh_scaled & 0xFF); - return mpu_write_mem(D_1_92, 4, tmp); -} - -/** - * @brief Set shake rejection time. - * Sets the length of time that the gyro must be outside of the threshold set - * by @e gyro_set_shake_reject_thresh before taps are rejected. A mandatory - * 60 ms is added to this parameter. - * @param[in] time Time in milliseconds. - * @return 0 if successful. - */ -int dmp_set_shake_reject_time(unsigned short time) -{ - unsigned char tmp[2]; - - time /= (1000 / DMP_SAMPLE_RATE); - tmp[0] = time >> 8; - tmp[1] = time & 0xFF; - return mpu_write_mem(D_1_90,2,tmp); -} - -/** - * @brief Set shake rejection timeout. - * Sets the length of time after a shake rejection that the gyro must stay - * inside of the threshold before taps can be detected again. A mandatory - * 60 ms is added to this parameter. - * @param[in] time Time in milliseconds. - * @return 0 if successful. - */ -int dmp_set_shake_reject_timeout(unsigned short time) -{ - unsigned char tmp[2]; - - time /= (1000 / DMP_SAMPLE_RATE); - tmp[0] = time >> 8; - tmp[1] = time & 0xFF; - return mpu_write_mem(D_1_88,2,tmp); -} - -/** - * @brief Get current step count. - * @param[out] count Number of steps detected. - * @return 0 if successful. - */ -int dmp_get_pedometer_step_count(unsigned long *count) -{ - unsigned char tmp[4]; - if (!count) - return -1; - - if (mpu_read_mem(D_PEDSTD_STEPCTR, 4, tmp)) - return -1; - - count[0] = ((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | - ((unsigned long)tmp[2] << 8) | tmp[3]; - return 0; -} - -/** - * @brief Overwrite current step count. - * WARNING: This function writes to DMP memory and could potentially encounter - * a race condition if called while the pedometer is enabled. - * @param[in] count New step count. - * @return 0 if successful. - */ -int dmp_set_pedometer_step_count(unsigned long count) -{ - unsigned char tmp[4]; - - tmp[0] = (unsigned char)((count >> 24) & 0xFF); - tmp[1] = (unsigned char)((count >> 16) & 0xFF); - tmp[2] = (unsigned char)((count >> 8) & 0xFF); - tmp[3] = (unsigned char)(count & 0xFF); - return mpu_write_mem(D_PEDSTD_STEPCTR, 4, tmp); -} - -/** - * @brief Get duration of walking time. - * @param[in] time Walk time in milliseconds. - * @return 0 if successful. - */ -int dmp_get_pedometer_walk_time(unsigned long *time) -{ - unsigned char tmp[4]; - if (!time) - return -1; - - if (mpu_read_mem(D_PEDSTD_TIMECTR, 4, tmp)) - return -1; - - time[0] = (((unsigned long)tmp[0] << 24) | ((unsigned long)tmp[1] << 16) | - ((unsigned long)tmp[2] << 8) | tmp[3]) * 20; - return 0; -} - -/** - * @brief Overwrite current walk time. - * WARNING: This function writes to DMP memory and could potentially encounter - * a race condition if called while the pedometer is enabled. - * @param[in] time New walk time in milliseconds. - */ -int dmp_set_pedometer_walk_time(unsigned long time) -{ - unsigned char tmp[4]; - - time /= 20; - - tmp[0] = (unsigned char)((time >> 24) & 0xFF); - tmp[1] = (unsigned char)((time >> 16) & 0xFF); - tmp[2] = (unsigned char)((time >> 8) & 0xFF); - tmp[3] = (unsigned char)(time & 0xFF); - return mpu_write_mem(D_PEDSTD_TIMECTR, 4, tmp); -} - -/** - * @brief Enable DMP features. - * The following \#define's are used in the input mask: - * \n DMP_FEATURE_TAP - * \n DMP_FEATURE_ANDROID_ORIENT - * \n DMP_FEATURE_LP_QUAT - * \n DMP_FEATURE_6X_LP_QUAT - * \n DMP_FEATURE_GYRO_CAL - * \n DMP_FEATURE_SEND_RAW_ACCEL - * \n DMP_FEATURE_SEND_RAW_GYRO - * \n NOTE: DMP_FEATURE_LP_QUAT and DMP_FEATURE_6X_LP_QUAT are mutually - * exclusive. - * \n NOTE: DMP_FEATURE_SEND_RAW_GYRO and DMP_FEATURE_SEND_CAL_GYRO are also - * mutually exclusive. - * @param[in] mask Mask of features to enable. - * @return 0 if successful. - */ -int dmp_enable_feature(unsigned short mask) -{ - unsigned char tmp[10]; - - /* TODO: All of these settings can probably be integrated into the default - * DMP image. - */ - /* Set integration scale factor. */ - tmp[0] = (unsigned char)((GYRO_SF >> 24) & 0xFF); - tmp[1] = (unsigned char)((GYRO_SF >> 16) & 0xFF); - tmp[2] = (unsigned char)((GYRO_SF >> 8) & 0xFF); - tmp[3] = (unsigned char)(GYRO_SF & 0xFF); - mpu_write_mem(D_0_104, 4, tmp); - - /* Send sensor data to the FIFO. */ - tmp[0] = 0xA3; - if (mask & DMP_FEATURE_SEND_RAW_ACCEL) { - tmp[1] = 0xC0; - tmp[2] = 0xC8; - tmp[3] = 0xC2; - } else { - tmp[1] = 0xA3; - tmp[2] = 0xA3; - tmp[3] = 0xA3; - } - if (mask & DMP_FEATURE_SEND_ANY_GYRO) { - tmp[4] = 0xC4; - tmp[5] = 0xCC; - tmp[6] = 0xC6; - } else { - tmp[4] = 0xA3; - tmp[5] = 0xA3; - tmp[6] = 0xA3; - } - tmp[7] = 0xA3; - tmp[8] = 0xA3; - tmp[9] = 0xA3; - mpu_write_mem(CFG_15,10,tmp); - - /* Send gesture data to the FIFO. */ - if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) - tmp[0] = DINA20; - else - tmp[0] = 0xD8; - mpu_write_mem(CFG_27,1,tmp); - - if (mask & DMP_FEATURE_GYRO_CAL) - dmp_enable_gyro_cal(1); - else - dmp_enable_gyro_cal(0); - - if (mask & DMP_FEATURE_SEND_ANY_GYRO) { - if (mask & DMP_FEATURE_SEND_CAL_GYRO) { - tmp[0] = 0xB2; - tmp[1] = 0x8B; - tmp[2] = 0xB6; - tmp[3] = 0x9B; - } else { - tmp[0] = DINAC0; - tmp[1] = DINA80; - tmp[2] = DINAC2; - tmp[3] = DINA90; - } - mpu_write_mem(CFG_GYRO_RAW_DATA, 4, tmp); - } - - if (mask & DMP_FEATURE_TAP) { - /* Enable tap. */ - tmp[0] = 0xF8; - mpu_write_mem(CFG_20, 1, tmp); - dmp_set_tap_thresh(TAP_XYZ, 250); - dmp_set_tap_axes(TAP_XYZ); - dmp_set_tap_count(1); - dmp_set_tap_time(100); - dmp_set_tap_time_multi(500); - - dmp_set_shake_reject_thresh(GYRO_SF, 200); - dmp_set_shake_reject_time(40); - dmp_set_shake_reject_timeout(10); - } else { - tmp[0] = 0xD8; - mpu_write_mem(CFG_20, 1, tmp); - } - - if (mask & DMP_FEATURE_ANDROID_ORIENT) { - tmp[0] = 0xD9; - } else - tmp[0] = 0xD8; - mpu_write_mem(CFG_ANDROID_ORIENT_INT, 1, tmp); - - if (mask & DMP_FEATURE_LP_QUAT) - dmp_enable_lp_quat(1); - else - dmp_enable_lp_quat(0); - - if (mask & DMP_FEATURE_6X_LP_QUAT) - dmp_enable_6x_lp_quat(1); - else - dmp_enable_6x_lp_quat(0); - - /* Pedometer is always enabled. */ - dmp.feature_mask = mask | DMP_FEATURE_PEDOMETER; - mpu_reset_fifo(); - - dmp.packet_length = 0; - if (mask & DMP_FEATURE_SEND_RAW_ACCEL) - dmp.packet_length += 6; - if (mask & DMP_FEATURE_SEND_ANY_GYRO) - dmp.packet_length += 6; - if (mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) - dmp.packet_length += 16; - if (mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) - dmp.packet_length += 4; - - return 0; -} - -/** - * @brief Get list of currently enabled DMP features. - * @param[out] Mask of enabled features. - * @return 0 if successful. - */ -int dmp_get_enabled_features(unsigned short *mask) -{ - mask[0] = dmp.feature_mask; - return 0; -} - -/** - * @brief Calibrate the gyro data in the DMP. - * After eight seconds of no motion, the DMP will compute gyro biases and - * subtract them from the quaternion output. If @e dmp_enable_feature is - * called with @e DMP_FEATURE_SEND_CAL_GYRO, the biases will also be - * subtracted from the gyro output. - * @param[in] enable 1 to enable gyro calibration. - * @return 0 if successful. - */ -int dmp_enable_gyro_cal(unsigned char enable) -{ - if (enable) { - unsigned char regs[9] = {0xb8, 0xaa, 0xb3, 0x8d, 0xb4, 0x98, 0x0d, 0x35, 0x5d}; - return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); - } else { - unsigned char regs[9] = {0xb8, 0xaa, 0xaa, 0xaa, 0xb0, 0x88, 0xc3, 0xc5, 0xc7}; - return mpu_write_mem(CFG_MOTION_BIAS, 9, regs); - } -} - -/** - * @brief Generate 3-axis quaternions from the DMP. - * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually - * exclusive. - * @param[in] enable 1 to enable 3-axis quaternion. - * @return 0 if successful. - */ -int dmp_enable_lp_quat(unsigned char enable) -{ - unsigned char regs[4]; - if (enable) { - regs[0] = DINBC0; - regs[1] = DINBC2; - regs[2] = DINBC4; - regs[3] = DINBC6; - } - else - memset(regs, 0x8B, 4); - - mpu_write_mem(CFG_LP_QUAT, 4, regs); - - return mpu_reset_fifo(); -} - -/** - * @brief Generate 6-axis quaternions from the DMP. - * In this driver, the 3-axis and 6-axis DMP quaternion features are mutually - * exclusive. - * @param[in] enable 1 to enable 6-axis quaternion. - * @return 0 if successful. - */ -int dmp_enable_6x_lp_quat(unsigned char enable) -{ - unsigned char regs[4]; - if (enable) { - regs[0] = DINA20; - regs[1] = DINA28; - regs[2] = DINA30; - regs[3] = DINA38; - } else - memset(regs, 0xA3, 4); - - mpu_write_mem(CFG_8, 4, regs); - - return mpu_reset_fifo(); -} - -/** - * @brief Decode the four-byte gesture data and execute any callbacks. - * @param[in] gesture Gesture data from DMP packet. - * @return 0 if successful. - */ -static int decode_gesture(unsigned char *gesture) -{ - unsigned char tap, android_orient; - - android_orient = gesture[3] & 0xC0; - tap = 0x3F & gesture[3]; - - if (gesture[1] & INT_SRC_TAP) { - unsigned char direction, count; - direction = tap >> 3; - count = (tap % 8) + 1; - if (dmp.tap_cb) - dmp.tap_cb(direction, count); - } - - if (gesture[1] & INT_SRC_ANDROID_ORIENT) { - if (dmp.android_orient_cb) - dmp.android_orient_cb(android_orient >> 6); - } - - return 0; -} - -/** - * @brief Specify when a DMP interrupt should occur. - * A DMP interrupt can be configured to trigger on either of the two - * conditions below: - * \n a. One FIFO period has elapsed (set by @e mpu_set_sample_rate). - * \n b. A tap event has been detected. - * @param[in] mode DMP_INT_GESTURE or DMP_INT_CONTINUOUS. - * @return 0 if successful. - */ -int dmp_set_interrupt_mode(unsigned char mode) -{ - const unsigned char regs_continuous[11] = - {0xd8, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9}; - const unsigned char regs_gesture[11] = - {0xda, 0xb1, 0xb9, 0xf3, 0x8b, 0xa3, 0x91, 0xb6, 0xda, 0xb4, 0xda}; - - switch (mode) { - case DMP_INT_CONTINUOUS: - return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, - (unsigned char*)regs_continuous); - case DMP_INT_GESTURE: - return mpu_write_mem(CFG_FIFO_ON_EVENT, 11, - (unsigned char*)regs_gesture); - default: - return -1; - } -} - -/** - * @brief Get one packet from the FIFO. - * If @e sensors does not contain a particular sensor, disregard the data - * returned to that pointer. - * \n @e sensors can contain a combination of the following flags: - * \n INV_X_GYRO, INV_Y_GYRO, INV_Z_GYRO - * \n INV_XYZ_GYRO - * \n INV_XYZ_ACCEL - * \n INV_WXYZ_QUAT - * \n If the FIFO has no new data, @e sensors will be zero. - * \n If the FIFO is disabled, @e sensors will be zero and this function will - * return a non-zero error code. - * @param[out] gyro Gyro data in hardware units. - * @param[out] accel Accel data in hardware units. - * @param[out] quat 3-axis quaternion data in hardware units. - * @param[out] timestamp Timestamp in milliseconds. - * @param[out] sensors Mask of sensors read from FIFO. - * @param[out] more Number of remaining packets. - * @return 0 if successful. - */ -int dmp_read_fifo(short *gyro, short *accel, long *quat, - unsigned long *timestamp, short *sensors, unsigned char *more) -{ - unsigned char fifo_data[MAX_PACKET_LENGTH]; - unsigned char ii = 0; - - /* TODO: sensors[0] only changes when dmp_enable_feature is called. We can - * cache this value and save some cycles. - */ - sensors[0] = 0; - - /* Get a packet. */ - if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more)) - return -1; - - /* Parse DMP packet. */ - if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) { -#ifdef FIFO_CORRUPTION_CHECK - long quat_q14[4], quat_mag_sq; -#endif - quat[0] = ((long)fifo_data[0] << 24) | ((long)fifo_data[1] << 16) | - ((long)fifo_data[2] << 8) | fifo_data[3]; - quat[1] = ((long)fifo_data[4] << 24) | ((long)fifo_data[5] << 16) | - ((long)fifo_data[6] << 8) | fifo_data[7]; - quat[2] = ((long)fifo_data[8] << 24) | ((long)fifo_data[9] << 16) | - ((long)fifo_data[10] << 8) | fifo_data[11]; - quat[3] = ((long)fifo_data[12] << 24) | ((long)fifo_data[13] << 16) | - ((long)fifo_data[14] << 8) | fifo_data[15]; - ii += 16; -#ifdef FIFO_CORRUPTION_CHECK - /* We can detect a corrupted FIFO by monitoring the quaternion data and - * ensuring that the magnitude is always normalized to one. This - * shouldn't happen in normal operation, but if an I2C error occurs, - * the FIFO reads might become misaligned. - * - * Let's start by scaling down the quaternion data to avoid long long - * math. - */ - quat_q14[0] = quat[0] >> 16; - quat_q14[1] = quat[1] >> 16; - quat_q14[2] = quat[2] >> 16; - quat_q14[3] = quat[3] >> 16; - quat_mag_sq = quat_q14[0] * quat_q14[0] + quat_q14[1] * quat_q14[1] + - quat_q14[2] * quat_q14[2] + quat_q14[3] * quat_q14[3]; - if ((quat_mag_sq < QUAT_MAG_SQ_MIN) || - (quat_mag_sq > QUAT_MAG_SQ_MAX)) { - /* Quaternion is outside of the acceptable threshold. */ - mpu_reset_fifo(); - sensors[0] = 0; - return -1; - } - sensors[0] |= INV_WXYZ_QUAT; -#endif - } - - if (dmp.feature_mask & DMP_FEATURE_SEND_RAW_ACCEL) { - accel[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; - accel[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; - accel[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; - ii += 6; - sensors[0] |= INV_XYZ_ACCEL; - } - - if (dmp.feature_mask & DMP_FEATURE_SEND_ANY_GYRO) { - gyro[0] = ((short)fifo_data[ii+0] << 8) | fifo_data[ii+1]; - gyro[1] = ((short)fifo_data[ii+2] << 8) | fifo_data[ii+3]; - gyro[2] = ((short)fifo_data[ii+4] << 8) | fifo_data[ii+5]; - ii += 6; - sensors[0] |= INV_XYZ_GYRO; - } - - /* Gesture data is at the end of the DMP packet. Parse it and call - * the gesture callbacks (if registered). - */ - if (dmp.feature_mask & (DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT)) - decode_gesture(fifo_data + ii); - - get_ms(timestamp); - return 0; -} - -/** - * @brief Register a function to be executed on a tap event. - * The tap direction is represented by one of the following: - * \n TAP_X_UP - * \n TAP_X_DOWN - * \n TAP_Y_UP - * \n TAP_Y_DOWN - * \n TAP_Z_UP - * \n TAP_Z_DOWN - * @param[in] func Callback function. - * @return 0 if successful. - */ -int dmp_register_tap_cb(void (*func)(unsigned char, unsigned char)) -{ - dmp.tap_cb = func; - return 0; -} - -/** - * @brief Register a function to be executed on a android orientation event. - * @param[in] func Callback function. - * @return 0 if successful. - */ -int dmp_register_android_orient_cb(void (*func)(unsigned char)) -{ - dmp.android_orient_cb = func; - return 0; -} - -/** - * @} - */ - diff --git a/interface/external/MotionDriver/src/inv_tty.c b/interface/external/MotionDriver/src/inv_tty.c deleted file mode 100644 index 30a3fceb55..0000000000 --- a/interface/external/MotionDriver/src/inv_tty.c +++ /dev/null @@ -1,113 +0,0 @@ -// -// inv_tty.c -// interface -// -// Created by Andrzej Kapolka on 7/9/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. - -#include -#include -#include - -#include "inv_tty.h" - -// the file descriptor of the tty -static int ttyFileDescriptor; - -void tty_set_file_descriptor(int file_descriptor) { - ttyFileDescriptor = file_descriptor; -} - -static char to_hex_digit(unsigned char value) { - return (value < 10) ? '0' + value : 'A' + (value - 10); -} - -static unsigned char from_hex_digit(char digit) { - return (digit < 'A') ? digit - '0' : (digit - 'A') + 10; -} - -static int write_byte(unsigned char value) { - char chars[] = { to_hex_digit(value / 16), to_hex_digit(value % 16) }; - return write(ttyFileDescriptor, chars, 2) != 2; -} - -static int read_byte(unsigned char* value) { - char chars[2]; - if (read(ttyFileDescriptor, chars, 2) != 2) { - return 1; - } - *value = from_hex_digit(chars[0]) * 16 + from_hex_digit(chars[1]); - return 0; -} - -int tty_i2c_write(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char const *data) { - if (write(ttyFileDescriptor, "WR", 2) != 2) { - return 1; - } - if (write_byte(slave_addr)) { - return 1; - } - if (write_byte(reg_addr)) { - return 1; - } - int i; - for (i = 0; i < length; i++) { - if (write_byte(data[i])) { - return 1; - } - } - if (write(ttyFileDescriptor, "\n", 1) != 1) { - return 1; - } - - char response[8]; - return read(ttyFileDescriptor, response, 8) != 8; -} - -int tty_i2c_read(unsigned char slave_addr, unsigned char reg_addr, unsigned char length, unsigned char *data) { - if (write(ttyFileDescriptor, "RD", 2) != 2) { - return 1; - } - if (write_byte(slave_addr)) { - return 1; - } - if (write_byte(reg_addr)) { - return 1; - } - if (write_byte(length)) { - return 1; - } - if (write(ttyFileDescriptor, "\n", 1) != 1) { - return 1; - } - - char prefix[6]; - if (read(ttyFileDescriptor, prefix, 6) != 6) { - return 1; - } - int i; - for (i = 0; i < length; i++) { - if (read_byte(data + i)) { - return 1; - } - } - - char suffix[2]; - return read(ttyFileDescriptor, suffix, 2) != 2; -} - -void tty_delay_ms(unsigned long num_ms) { - struct timespec required, remaining; - required.tv_sec = 0; - const long NANOSECONDS_PER_MILLISECOND = 1000000; - required.tv_nsec = num_ms * NANOSECONDS_PER_MILLISECOND; - nanosleep(&required, &remaining); -} - -void tty_get_ms(unsigned long *count) { - struct timeval time; - gettimeofday(&time, 0); - const long MILLISECONDS_PER_SECOND = 1000; - const long MICROSECONDS_PER_MILLISECOND = 1000; - *count = time.tv_sec * MILLISECONDS_PER_SECOND + time.tv_usec / MICROSECONDS_PER_MILLISECOND; -} diff --git a/interface/external/pthreads/WIN32/pthread_lib.lib b/interface/external/pthreads/WIN32/pthread_lib.lib deleted file mode 100644 index 9fa00e29d624b9e30688940d92b622c0697e507b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 241598 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 z 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

B1D90`C|Xgy@3>(;%BZ{!*N1g1KsqXJY?fJQMnQ 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 diff --git a/interface/external/pthreads/include/pthread.h b/interface/external/pthreads/include/pthread.h deleted file mode 100644 index f910eb4b0e..0000000000 --- a/interface/external/pthreads/include/pthread.h +++ /dev/null @@ -1,1403 +0,0 @@ -/* This is an implementation of the threads API of POSIX 1003.1-2001. - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#if !defined( PTHREAD_H ) -#define PTHREAD_H - -#define PTW32_STATIC_LIB - -/* - * See the README file for an explanation of the pthreads-win32 version - * numbering scheme and how the DLL is named etc. - */ -#define PTW32_VERSION 2,10,0,0 -#define PTW32_VERSION_STRING "2, 10, 0, 0\0" - -/* There are three implementations of cancel cleanup. - * Note that pthread.h is included in both application - * compilation units and also internally for the library. - * The code here and within the library aims to work - * for all reasonable combinations of environments. - * - * The three implementations are: - * - * WIN32 SEH - * C - * C++ - * - * Please note that exiting a push/pop block via - * "return", "exit", "break", or "continue" will - * lead to different behaviour amongst applications - * depending upon whether the library was built - * using SEH, C++, or C. For example, a library built - * with SEH will call the cleanup routine, while both - * C++ and C built versions will not. - */ - -/* - * Define defaults for cleanup code. - * Note: Unless the build explicitly defines one of the following, then - * we default to standard C style cleanup. This style uses setjmp/longjmp - * in the cancellation and thread exit implementations and therefore won't - * do stack unwinding if linked to applications that have it (e.g. - * C++ apps). This is currently consistent with most/all commercial Unix - * POSIX threads implementations. - */ -#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) -/* - [i_a] fix for apps using pthreads-Win32: when they do not define __CLEANUP_SEH themselves, - they're screwed as they'll receive the '__CLEANUP_C' macros which do NOT work when - the pthreads library code itself has actually been build with __CLEANUP_SEH, - which is the case when building this stuff in MSVC. - - Hence this section is made to 'sensibly autodetect' the cleanup mode, when it hasn't - been hardwired in the makefiles / project files. - - After all, who expects he MUST define one of these __CLEANUP_XXX defines in his own - code when using pthreads-Win32, for whatever reason. - */ -#if (defined(_MSC_VER) || defined(PTW32_RC_MSC)) -#define __CLEANUP_SEH -#elif defined(__cplusplus) -#define __CLEANUP_CXX -#else -#define __CLEANUP_C -#endif -#endif - -#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) -#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. -#endif - -/* - * Stop here if we are being included by the resource compiler. - */ -#if !defined(RC_INVOKED) - -#undef PTW32_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_LEVEL -#define PTW32_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_LEVEL -#define PTW32_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) -#define PTW32_LEVEL PTW32_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(_UWIN) -# define HAVE_STRUCT_TIMESPEC 1 -# define HAVE_SIGNAL_H 1 -# undef HAVE_PTW32_CONFIG_H -# pragma comment(lib, "pthread") -#endif - -#if defined(__MINGW32__) || defined(__MINGW64__) -# define PTW32_CONFIG_MINGW -#endif -#if defined(_MSC_VER) -# if _MSC_VER < 1300 -# define PTW32_CONFIG_MSVC6 -# endif -# if _MSC_VER < 1400 -# define PTW32_CONFIG_MSVC7 -# endif -#endif - -/* - * ------------------------------------------------------------- - * - * - * Module: pthread.h - * - * Purpose: - * Provides an implementation of PThreads based upon the - * standard: - * - * POSIX 1003.1-2001 - * and - * The Single Unix Specification version 3 - * - * (these two are equivalent) - * - * in order to enhance code portability between Windows, - * various commercial Unix implementations, and Linux. - * - * See the ANNOUNCE file for a full list of conforming - * routines and defined constants, and a list of missing - * routines and constants not defined in this implementation. - * - * Authors: - * There have been many contributors to this library. - * The initial implementation was contributed by - * John Bossom, and several others have provided major - * sections or revisions of parts of the implementation. - * Often significant effort has been contributed to - * find and fix important bugs and other problems to - * improve the reliability of the library, which sometimes - * is not reflected in the amount of code which changed as - * result. - * As much as possible, the contributors are acknowledged - * in the ChangeLog file in the source code distribution - * where their changes are noted in detail. - * - * Contributors are listed in the CONTRIBUTORS file. - * - * As usual, all bouquets go to the contributors, and all - * brickbats go to the project maintainer. - * - * Maintainer: - * The code base for this project is coordinated and - * eventually pre-tested, packaged, and made available by - * - * Ross Johnson - * - * QA Testers: - * Ultimately, the library is tested in the real world by - * a host of competent and demanding scientists and - * engineers who report bugs and/or provide solutions - * which are then fixed or incorporated into subsequent - * versions of the library. Each time a bug is fixed, a - * test case is written to prove the fix and ensure - * that later changes to the code don't reintroduce the - * same error. The number of test cases is slowly growing - * and therefore so is the code reliability. - * - * Compliance: - * See the file ANNOUNCE for the list of implemented - * and not-implemented routines and defined options. - * Of course, these are all defined is this file as well. - * - * Web site: - * The source code and other information about this library - * are available from - * - * http://sources.redhat.com/pthreads-win32/ - * - * ------------------------------------------------------------- - */ - -/* Try to avoid including windows.h */ -#if defined(PTW32_CONFIG_MINGW) && defined(__cplusplus) -#define PTW32_INCLUDE_WINDOWS_H -#endif - -#if defined(PTW32_INCLUDE_WINDOWS_H) -#include -#endif - -#if defined(PTW32_CONFIG_MSVC6) || defined(__DMC__) -/* - * VC++6.0 or early compiler's header has no DWORD_PTR type. - */ -typedef unsigned long DWORD_PTR; -typedef unsigned long ULONG_PTR; -#endif -/* - * ----------------- - * autoconf switches - * ----------------- - */ - -#if defined(HAVE_PTW32_CONFIG_H) -#include "config.h" -#endif /* HAVE_PTW32_CONFIG_H */ - -#if !defined(NEED_FTIME) -#include -#else /* NEED_FTIME */ -/* use native WIN32 time API */ -#endif /* NEED_FTIME */ - -#if defined(HAVE_SIGNAL_H) -#include -#endif /* HAVE_SIGNAL_H */ - -#include - -/* - * Boolean values to make us independent of system includes. - */ -enum { - PTW32_FALSE = 0, - PTW32_TRUE = (! PTW32_FALSE) -}; - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Several systems don't define some error numbers. - */ -#if !defined(ENOTSUP) -# define ENOTSUP 48 /* This is the value in Solaris. */ -#endif - -#if !defined(ETIMEDOUT) -# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ -#endif - -#if !defined(ENOSYS) -# define ENOSYS 140 /* Semi-arbitrary value */ -#endif - -#if !defined(EDEADLK) -# if defined(EDEADLOCK) -# define EDEADLK EDEADLOCK -# else -# define EDEADLK 36 /* This is the value in MSVC. */ -# endif -#endif - -/* POSIX 2008 - related to robust mutexes */ -#if !defined(EOWNERDEAD) -# define EOWNERDEAD 43 -#endif -#if !defined(ENOTRECOVERABLE) -# define ENOTRECOVERABLE 44 -#endif - -#include - -/* - * To avoid including windows.h we define only those things that we - * actually need from it. - */ -#if !defined(PTW32_INCLUDE_WINDOWS_H) -#if !defined(HANDLE) -# define PTW32__HANDLE_DEF -# define HANDLE void * -#endif -#if !defined(DWORD) -# define PTW32__DWORD_DEF -# define DWORD unsigned long -#endif -#endif - -#if !defined(HAVE_STRUCT_TIMESPEC) -#define HAVE_STRUCT_TIMESPEC -#if !defined(_TIMESPEC_DEFINED) -#define _TIMESPEC_DEFINED -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif /* _TIMESPEC_DEFINED */ -#endif /* HAVE_STRUCT_TIMESPEC */ - -#if !defined(SIG_BLOCK) -#define SIG_BLOCK 0 -#endif /* SIG_BLOCK */ - -#if !defined(SIG_UNBLOCK) -#define SIG_UNBLOCK 1 -#endif /* SIG_UNBLOCK */ - -#if !defined(SIG_SETMASK) -#define SIG_SETMASK 2 -#endif /* SIG_SETMASK */ - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -/* - * ------------------------------------------------------------- - * - * POSIX 1003.1-2001 Options - * ========================= - * - * Options are normally set in , which is not provided - * with pthreads-win32. - * - * For conformance with the Single Unix Specification (version 3), all of the - * options below are defined, and have a value of either -1 (not supported) - * or 200112L (supported). - * - * These options can neither be left undefined nor have a value of 0, because - * either indicates that sysconf(), which is not implemented, may be used at - * runtime to check the status of the option. - * - * _POSIX_THREADS (== 200112L) - * If == 200112L, you can use threads - * - * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) - * If == 200112L, you can control the size of a thread's - * stack - * pthread_attr_getstacksize - * pthread_attr_setstacksize - * - * _POSIX_THREAD_ATTR_STACKADDR (== -1) - * If == 200112L, you can allocate and control a thread's - * stack. If not supported, the following functions - * will return ENOSYS, indicating they are not - * supported: - * pthread_attr_getstackaddr - * pthread_attr_setstackaddr - * - * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) - * If == 200112L, you can use realtime scheduling. - * This option indicates that the behaviour of some - * implemented functions conforms to the additional TPS - * requirements in the standard. E.g. rwlocks favour - * writers over readers when threads have equal priority. - * - * _POSIX_THREAD_PRIO_INHERIT (== -1) - * If == 200112L, you can create priority inheritance - * mutexes. - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PRIO_PROTECT (== -1) - * If == 200112L, you can create priority ceiling mutexes - * Indicates the availability of: - * pthread_mutex_getprioceiling - * pthread_mutex_setprioceiling - * pthread_mutexattr_getprioceiling - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprioceiling - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PROCESS_SHARED (== -1) - * If set, you can create mutexes and condition - * variables that can be shared with another - * process.If set, indicates the availability - * of: - * pthread_mutexattr_getpshared - * pthread_mutexattr_setpshared - * pthread_condattr_getpshared - * pthread_condattr_setpshared - * - * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) - * If == 200112L you can use the special *_r library - * functions that provide thread-safe behaviour - * - * _POSIX_READER_WRITER_LOCKS (== 200112L) - * If == 200112L, you can use read/write locks - * - * _POSIX_SPIN_LOCKS (== 200112L) - * If == 200112L, you can use spin locks - * - * _POSIX_BARRIERS (== 200112L) - * If == 200112L, you can use barriers - * - * + These functions provide both 'inherit' and/or - * 'protect' protocol, based upon these macro - * settings. - * - * ------------------------------------------------------------- - */ - -/* - * POSIX Options - */ -#undef _POSIX_THREADS -#define _POSIX_THREADS 200809L - -#undef _POSIX_READER_WRITER_LOCKS -#define _POSIX_READER_WRITER_LOCKS 200809L - -#undef _POSIX_SPIN_LOCKS -#define _POSIX_SPIN_LOCKS 200809L - -#undef _POSIX_BARRIERS -#define _POSIX_BARRIERS 200809L - -#undef _POSIX_THREAD_SAFE_FUNCTIONS -#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L - -#undef _POSIX_THREAD_ATTR_STACKSIZE -#define _POSIX_THREAD_ATTR_STACKSIZE 200809L - -/* - * The following options are not supported - */ -#undef _POSIX_THREAD_ATTR_STACKADDR -#define _POSIX_THREAD_ATTR_STACKADDR -1 - -#undef _POSIX_THREAD_PRIO_INHERIT -#define _POSIX_THREAD_PRIO_INHERIT -1 - -#undef _POSIX_THREAD_PRIO_PROTECT -#define _POSIX_THREAD_PRIO_PROTECT -1 - -/* TPS is not fully supported. */ -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 - -#undef _POSIX_THREAD_PROCESS_SHARED -#define _POSIX_THREAD_PROCESS_SHARED -1 - - -/* - * POSIX 1003.1-2001 Limits - * =========================== - * - * These limits are normally set in , which is not provided with - * pthreads-win32. - * - * PTHREAD_DESTRUCTOR_ITERATIONS - * Maximum number of attempts to destroy - * a thread's thread-specific data on - * termination (must be at least 4) - * - * PTHREAD_KEYS_MAX - * Maximum number of thread-specific data keys - * available per process (must be at least 128) - * - * PTHREAD_STACK_MIN - * Minimum supported stack size for a thread - * - * PTHREAD_THREADS_MAX - * Maximum number of threads supported per - * process (must be at least 64). - * - * SEM_NSEMS_MAX - * The maximum number of semaphores a process can have. - * (must be at least 256) - * - * SEM_VALUE_MAX - * The maximum value a semaphore can have. - * (must be at least 32767) - * - */ -#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 - -#undef PTHREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS - -#undef _POSIX_THREAD_KEYS_MAX -#define _POSIX_THREAD_KEYS_MAX 128 - -#undef PTHREAD_KEYS_MAX -#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX - -#undef PTHREAD_STACK_MIN -#define PTHREAD_STACK_MIN 0 - -#undef _POSIX_THREAD_THREADS_MAX -#define _POSIX_THREAD_THREADS_MAX 64 - - /* Arbitrary value */ -#undef PTHREAD_THREADS_MAX -#define PTHREAD_THREADS_MAX 2019 - -#undef _POSIX_SEM_NSEMS_MAX -#define _POSIX_SEM_NSEMS_MAX 256 - - /* Arbitrary value */ -#undef SEM_NSEMS_MAX -#define SEM_NSEMS_MAX 1024 - -#undef _POSIX_SEM_VALUE_MAX -#define _POSIX_SEM_VALUE_MAX 32767 - -#undef SEM_VALUE_MAX -#define SEM_VALUE_MAX INT_MAX - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * The Open Watcom C/C++ compiler uses a non-standard calling convention - * that passes function args in registers unless __cdecl is explicitly specified - * in exposed function prototypes. - * - * We force all calls to cdecl even though this could slow Watcom code down - * slightly. If you know that the Watcom compiler will be used to build both - * the DLL and application, then you can probably define this as a null string. - * Remember that pthread.h (this file) is used for both the DLL and application builds. - */ -#define PTW32_CDECL __cdecl - -#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX -# include -#else -/* - * Generic handle type - intended to extend uniqueness beyond - * that available with a simple pointer. It should scale for either - * IA-32 or IA-64. - */ -typedef struct { - void * p; /* Pointer to actual object */ - unsigned int x; /* Extra information - reuse count etc */ -} ptw32_handle_t; - -typedef ptw32_handle_t pthread_t; -typedef struct pthread_attr_t_ * pthread_attr_t; -typedef struct pthread_once_t_ pthread_once_t; -typedef struct pthread_key_t_ * pthread_key_t; -typedef struct pthread_mutex_t_ * pthread_mutex_t; -typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; -typedef struct pthread_cond_t_ * pthread_cond_t; -typedef struct pthread_condattr_t_ * pthread_condattr_t; -#endif -typedef struct pthread_rwlock_t_ * pthread_rwlock_t; -typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; -typedef struct pthread_spinlock_t_ * pthread_spinlock_t; -typedef struct pthread_barrier_t_ * pthread_barrier_t; -typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; - -/* - * ==================== - * ==================== - * POSIX Threads - * ==================== - * ==================== - */ - -enum { -/* - * pthread_attr_{get,set}detachstate - */ - PTHREAD_CREATE_JOINABLE = 0, /* Default */ - PTHREAD_CREATE_DETACHED = 1, - -/* - * pthread_attr_{get,set}inheritsched - */ - PTHREAD_INHERIT_SCHED = 0, - PTHREAD_EXPLICIT_SCHED = 1, /* Default */ - -/* - * pthread_{get,set}scope - */ - PTHREAD_SCOPE_PROCESS = 0, - PTHREAD_SCOPE_SYSTEM = 1, /* Default */ - -/* - * pthread_setcancelstate paramters - */ - PTHREAD_CANCEL_ENABLE = 0, /* Default */ - PTHREAD_CANCEL_DISABLE = 1, - -/* - * pthread_setcanceltype parameters - */ - PTHREAD_CANCEL_ASYNCHRONOUS = 0, - PTHREAD_CANCEL_DEFERRED = 1, /* Default */ - -/* - * pthread_mutexattr_{get,set}pshared - * pthread_condattr_{get,set}pshared - */ - PTHREAD_PROCESS_PRIVATE = 0, - PTHREAD_PROCESS_SHARED = 1, - -/* - * pthread_mutexattr_{get,set}robust - */ - PTHREAD_MUTEX_STALLED = 0, /* Default */ - PTHREAD_MUTEX_ROBUST = 1, - -/* - * pthread_barrier_wait - */ - PTHREAD_BARRIER_SERIAL_THREAD = -1 -}; - -/* - * ==================== - * ==================== - * cancellation - * ==================== - * ==================== - */ -#define PTHREAD_CANCELED ((void *)(size_t) -1) - - -/* - * ==================== - * ==================== - * Once Key - * ==================== - * ==================== - */ -#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} - -struct pthread_once_t_ -{ - int done; /* indicates if user function has been executed */ - void * lock; - int reserved1; - int reserved2; -}; - - -/* - * ==================== - * ==================== - * Object initialisers - * ==================== - * ==================== - */ -#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) - -/* - * Compatibility with LinuxThreads - */ -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER - -#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) - -#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) - -#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) - - -/* - * Mutex types. - */ -enum -{ - /* Compatibility with LinuxThreads */ - PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, - /* For compatibility with POSIX */ - PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL -}; - - -typedef struct ptw32_cleanup_t ptw32_cleanup_t; - -#if defined(_MSC_VER) -/* Disable MSVC 'anachronism used' warning */ -#pragma warning( disable : 4229 ) -#endif - -typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); - -#if defined(_MSC_VER) -#pragma warning( default : 4229 ) -#endif - -struct ptw32_cleanup_t -{ - ptw32_cleanup_callback_t routine; - void *arg; - struct ptw32_cleanup_t *prev; -}; - -#if defined(__CLEANUP_SEH) - /* - * WIN32 SEH version of cancel cleanup. - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ - _cleanup.arg = (_arg); \ - __try \ - { \ - -#define pthread_cleanup_pop( _execute ) \ - } \ - __finally \ - { \ - if( _execute || AbnormalTermination()) \ - { \ - (*(_cleanup.routine))( _cleanup.arg ); \ - } \ - } \ - } - -#else /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_C) - - /* - * C implementation of PThreads cancel cleanup - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ - -#define pthread_cleanup_pop( _execute ) \ - (void) ptw32_pop_cleanup( _execute ); \ - } - -#else /* __CLEANUP_C */ - -#if defined(__CLEANUP_CXX) - - /* - * C++ version of cancel cleanup. - * - John E. Bossom. - */ - - class PThreadCleanup { - /* - * PThreadCleanup - * - * Purpose - * This class is a C++ helper class that is - * used to implement pthread_cleanup_push/ - * pthread_cleanup_pop. - * The destructor of this class automatically - * pops the pushed cleanup routine regardless - * of how the code exits the scope - * (i.e. such as by an exception) - */ - ptw32_cleanup_callback_t cleanUpRout; - void * obj; - int executeIt; - - public: - PThreadCleanup() : - cleanUpRout( 0 ), - obj( 0 ), - executeIt( 0 ) - /* - * No cleanup performed - */ - { - } - - PThreadCleanup( - ptw32_cleanup_callback_t routine, - void * arg ) : - cleanUpRout( routine ), - obj( arg ), - executeIt( 1 ) - /* - * Registers a cleanup routine for 'arg' - */ - { - } - - ~PThreadCleanup() - { - if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) - { - (void) (*cleanUpRout)( obj ); - } - } - - void execute( int exec ) - { - executeIt = exec; - } - }; - - /* - * C++ implementation of PThreads cancel cleanup; - * This implementation takes advantage of a helper - * class who's destructor automatically calls the - * cleanup routine if we exit our scope weirdly - */ -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ - (void *) (_arg) ); - -#define pthread_cleanup_pop( _execute ) \ - cleanup.execute( _execute ); \ - } - -#else - -#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. - -#endif /* __CLEANUP_CXX */ - -#endif /* __CLEANUP_C */ - -#endif /* __CLEANUP_SEH */ - -/* - * =============== - * =============== - * Methods - * =============== - * =============== - */ - -/* - * PThread Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, - int *detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, - void **stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, - size_t * stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, - int detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, - void *stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, - size_t stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, - int *); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, - int inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, - int * inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, - int *); - -/* - * PThread Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, - const pthread_attr_t * attr, - void *(PTW32_CDECL *start) (void *), - void *arg); - -PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); - -PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, - pthread_t t2); - -PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); - -PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, - void **value_ptr); - -PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, - int *oldstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, - int *oldtype); - -PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, - void (PTW32_CDECL *init_routine) (void)); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); - -PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, - ptw32_cleanup_callback_t routine, - void *arg); -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread Specific Data Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, - void (PTW32_CDECL *destructor) (void *)); - -PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); - -PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, - const void *value); - -PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); - - -/* - * Mutex Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, - int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( - pthread_mutexattr_t *attr, - int robust); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( - const pthread_mutexattr_t * attr, - int * robust); - -/* - * Barrier Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, - int pshared); - -/* - * Mutex Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, - const pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); - -/* - * Spinlock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); - -/* - * Barrier Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, - const pthread_barrierattr_t * attr, - unsigned int count); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); - -/* - * Condition Variable Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, - int pshared); - -/* - * Condition Variable Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, - const pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, - pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, - pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); - -/* - * Scheduling - */ -PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, - int policy, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, - int *policy, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); - -PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); - -/* - * Read-Write Lock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, - const pthread_rwlockattr_t *attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, - int pshared); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 - -/* - * Signal Functions. Should be defined in but MSVC and MinGW32 - * already have signal.h that don't define these. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); - -/* - * Non-portable functions - */ - -/* - * Compatibility with Linux. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, - int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, - int *kind); -PTW32_DLLPORT int PTW32_CDECL pthread_timedjoin_np(pthread_t thread, - void **value_ptr, - const struct timespec *abstime); - -/* - * Possibly supported by other POSIX threads implementations - */ -PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); -PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); -PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); - -/* - * Useful if an application wants to statically link - * the lib rather than load the DLL at run-time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); - -/* - * Features that are auto-detected at load/run time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); -enum ptw32_features { - PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ - PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ -}; - -/* - * Register a system time change with the library. - * Causes the library to perform various functions - * in response to the change. Should be called whenever - * the application's top level window receives a - * WM_TIMECHANGE message. It can be passed directly to - * pthread_create() as a new thread if desired. - */ -PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); - -#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* - * Returns the Win32 HANDLE for the POSIX thread. - */ -PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); -/* - * Returns the win32 thread ID for POSIX thread. - */ -PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); - - -/* - * Protected Methods - * - * This function blocks until the given WIN32 handle - * is signaled or pthread_cancel had been called. - * This function allows the caller to hook into the - * PThreads cancel mechanism. It is implemented using - * - * WaitForMultipleObjects - * - * on 'waitHandle' and a manually reset WIN32 Event - * used to implement pthread_cancel. The 'timeout' - * argument to TimedWait is simply passed to - * WaitForMultipleObjects. - */ -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, - DWORD timeout); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread-Safe C Runtime Library Mappings. - */ -#if !defined(_UWIN) -# if defined(NEED_ERRNO) - PTW32_DLLPORT int * PTW32_CDECL _errno( void ); -# else -# if !defined(errno) -# if (defined(_MT) || defined(_DLL)) - __declspec(dllimport) extern int * __cdecl _errno(void); -# define errno (*_errno()) -# endif -# endif -# endif -#endif - -/* - * Some compiler environments don't define some things. - */ -#if defined(__BORLANDC__) -# define _ftime ftime -# define _timeb timeb -#endif - -#if defined(__cplusplus) - -/* - * Internal exceptions - */ -class ptw32_exception {}; -class ptw32_exception_cancel : public ptw32_exception {}; -class ptw32_exception_exit : public ptw32_exception {}; - -#endif - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* FIXME: This is only required if the library was built using SEH */ -/* - * Get internal SEH tag - */ -PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -#if !defined(PTW32_BUILD) - -#if defined(__CLEANUP_SEH) - -/* - * Redefine the SEH __except keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#define __except( E ) \ - __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ - ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) - -#endif /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_CXX) - -/* - * Redefine the C++ catch keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#if defined(_MSC_VER) - /* - * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' - * if you want Pthread-Win32 cancellation and pthread_exit to work. - */ - -#if !defined(PtW32NoCatchWarn) - -#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") -#pragma message("------------------------------------------------------------------") -#pragma message("When compiling applications with MSVC++ and C++ exception handling:") -#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") -#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") -#pragma message(" cancellation and pthread_exit to work. For example:") -#pragma message("") -#pragma message(" #if defined(PtW32CatchAll)") -#pragma message(" PtW32CatchAll") -#pragma message(" #else") -#pragma message(" catch(...)") -#pragma message(" #endif") -#pragma message(" {") -#pragma message(" /* Catchall block processing */") -#pragma message(" }") -#pragma message("------------------------------------------------------------------") - -#endif - -#define PtW32CatchAll \ - catch( ptw32_exception & ) { throw; } \ - catch( ... ) - -#else /* _MSC_VER */ - -#define catch( E ) \ - catch( ptw32_exception & ) { throw; } \ - catch( E ) - -#endif /* _MSC_VER */ - -#endif /* __CLEANUP_CXX */ - -#endif /* ! PTW32_BUILD */ - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#if defined(PTW32__HANDLE_DEF) -# undef HANDLE -#endif -#if defined(PTW32__DWORD_DEF) -# undef DWORD -#endif - -#undef PTW32_LEVEL -#undef PTW32_LEVEL_MAX - -#endif /* ! RC_INVOKED */ - -#endif /* PTHREAD_H */ diff --git a/interface/external/pthreads/include/sched.h b/interface/external/pthreads/include/sched.h deleted file mode 100644 index d43ff8dcb2..0000000000 --- a/interface/external/pthreads/include/sched.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Module: sched.h - * - * Purpose: - * Provides an implementation of POSIX realtime extensions - * as defined in - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined(_SCHED_H) -#define _SCHED_H - -#undef PTW32_SCHED_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SCHED_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SCHED_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) -#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX -/* Include everything */ -#endif - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ - -#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) -# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -/* For pid_t */ -# include -/* Required by Unix 98 */ -# include -# else - typedef int pid_t; -# endif -#else - /* [i_a] fix for using pthread_win32 with mongoose code, which #define's its own pid_t akin to typedef HANDLE pid_t; */ - #undef pid_t -# if defined(_MSC_VER) - typedef void *pid_t; -# else - typedef int pid_t; -# endif -#endif - -/* Thread scheduling policies */ - -enum { - SCHED_OTHER = 0, - SCHED_FIFO, - SCHED_RR, - SCHED_MIN = SCHED_OTHER, - SCHED_MAX = SCHED_RR -}; - -struct sched_param { - int sched_priority; -}; - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -PTW32_DLLPORT int __cdecl sched_yield (void); - -PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); - -PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); - -PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); - -PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); - -/* - * Note that this macro returns ENOTSUP rather than - * ENOSYS as might be expected. However, returning ENOSYS - * should mean that sched_get_priority_{min,max} are - * not implemented as well as sched_rr_get_interval. - * This is not the case, since we just don't support - * round-robin scheduling. Therefore I have chosen to - * return the same value as sched_setscheduler when - * SCHED_RR is passed to it. - */ -#define sched_rr_get_interval(_pid, _interval) \ - ( errno = ENOTSUP, (int) -1 ) - - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SCHED_LEVEL -#undef PTW32_SCHED_LEVEL_MAX - -#endif /* !_SCHED_H */ - diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 736c94dfed..1dadcab421 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -6,7 +6,6 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include #include #include #include