From 323aa18c0ee57cf5fee65511e45ae63d3d2a77ed Mon Sep 17 00:00:00 2001 From: Stephen Birarda <commit@birarda.com> 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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 Kk*07$DfJKip#q-( diff --git a/interface/external/MotionDriver/lib/UNIX/libMotionDriver.a b/interface/external/MotionDriver/lib/UNIX/libMotionDriver.a deleted file mode 100644 index 82ca139b508839f9a7f2efba4610ef1ba522f72e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62086 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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 <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#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) ((a<b)?a:b) -#elif defined EMPL_TARGET_MSP430 -#include "msp430.h" -#include "msp430_i2c.h" -#include "msp430_clock.h" -#include "msp430_interrupt.h" -#include "log.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 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) ((a<b)?a:b) -#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 "twi.h" -#include "delay.h" -#include "sysclk.h" -#include "log.h" -#include "sensors_xplained.h" -#include "uc3l0_clock.h" -#define i2c_write(a, b, c, d) twi_write(a, b, d, c) -#define i2c_read(a, b, c, d) twi_read(a, b, d, c) -/* delay_ms is a function already defined in ASF. */ -#define get_ms uc3l0_get_clock_ms -static inline int reg_int_cb(struct int_param_s *int_param) -{ - sensor_board_irq_connect(int_param->pin, 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<b)?a:b) -#define log_i printf -#define log_e printf -static inline int reg_int_cb(struct int_param_s *int_param) -{ - return 0; // no-op -} -#endif - -#if !defined MPU6050 && !defined MPU9150 && !defined MPU6500 && !defined MPU9250 -#error Which gyro are you using? Define MPUxxxx in your compiler options. -#endif - -/* Time for some messy macro work. =] - * #define MPU9150 - * is equivalent to.. - * #define MPU6050 - * #define AK8975_SECONDARY - * - * #define MPU9250 - * is equivalent to.. - * #define MPU6500 - * #define AK8963_SECONDARY - */ -#if defined MPU9150 -#ifndef MPU6050 -#define MPU6050 -#endif /* #ifndef MPU6050 */ -#if defined AK8963_SECONDARY -#error "MPU9150 and AK8963_SECONDARY cannot both be defined." -#elif !defined AK8975_SECONDARY /* #if defined AK8963_SECONDARY */ -#define AK8975_SECONDARY -#endif /* #if defined AK8963_SECONDARY */ -#elif defined MPU9250 /* #if defined MPU9150 */ -#ifndef MPU6500 -#define MPU6500 -#endif /* #ifndef MPU6500 */ -#if defined AK8975_SECONDARY -#error "MPU9250 and AK8975_SECONDARY cannot both be defined." -#elif !defined AK8963_SECONDARY /* #if defined AK8975_SECONDARY */ -#define AK8963_SECONDARY -#endif /* #if defined AK8975_SECONDARY */ -#endif /* #if defined MPU9150 */ - -#if defined AK8975_SECONDARY || defined AK8963_SECONDARY -#define AK89xx_SECONDARY -#else -/* #warning "No compass = less profit for Invensense. Lame." */ -#endif - -static int set_int_enable(unsigned char enable); - -/* Hardware registers needed by driver. */ -struct gyro_reg_s { - unsigned char who_am_i; - unsigned char rate_div; - unsigned char lpf; - unsigned char prod_id; - unsigned char user_ctrl; - unsigned char fifo_en; - unsigned char gyro_cfg; - unsigned char accel_cfg; - unsigned char accel_cfg2; - unsigned char lp_accel_odr; - unsigned char motion_thr; - unsigned char motion_dur; - unsigned char fifo_count_h; - unsigned char fifo_r_w; - unsigned char raw_gyro; - unsigned char raw_accel; - unsigned char temp; - unsigned char int_enable; - unsigned char dmp_int_status; - unsigned char int_status; - unsigned char accel_intel; - unsigned char pwr_mgmt_1; - unsigned char pwr_mgmt_2; - unsigned char int_pin_cfg; - unsigned char mem_r_w; - unsigned char accel_offs; - unsigned char i2c_mst; - unsigned char bank_sel; - unsigned char mem_start_addr; - unsigned char prgm_start_h; -#if defined AK89xx_SECONDARY - unsigned char s0_addr; - unsigned char s0_reg; - unsigned char s0_ctrl; - unsigned char s1_addr; - unsigned char s1_reg; - unsigned char s1_ctrl; - unsigned char s4_ctrl; - unsigned char s0_do; - unsigned char s1_do; - unsigned char i2c_delay_ctrl; - unsigned char raw_compass; - /* The I2C_MST_VDDIO bit is in this register. */ - unsigned char yg_offs_tc; -#endif -}; - -/* Information specific to a particular device. */ -struct hw_s { - unsigned char addr; - unsigned short max_fifo; - unsigned char num_reg; - unsigned short temp_sens; - short temp_offset; - unsigned short bank_size; -#if defined AK89xx_SECONDARY - unsigned short compass_fsr; -#endif -}; - -/* When entering motion interrupt mode, the driver keeps track of the - * previous state so that it can be restored at a later time. - * TODO: This is tacky. Fix it. - */ -struct motion_int_cache_s { - unsigned short gyro_fsr; - unsigned char accel_fsr; - unsigned short lpf; - unsigned short sample_rate; - unsigned char sensors_on; - unsigned char fifo_sensors; - unsigned char dmp_on; -}; - -/* Cached chip configuration data. - * TODO: A lot of these can be handled with a bitmask. - */ -struct chip_cfg_s { - /* Matches gyro_cfg >> 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 <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#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 <time.h> -#include <unistd.h> -#include <sys/time.h> - -#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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 Tg>fPE&*@O4{vcGvQR4pxfx17m 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 <rpj@callisto.canberra.edu.au> - * - * 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 <windows.h> -#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 <time.h> -#else /* NEED_FTIME */ -/* use native WIN32 time API */ -#endif /* NEED_FTIME */ - -#if defined(HAVE_SIGNAL_H) -#include <signal.h> -#endif /* HAVE_SIGNAL_H */ - -#include <limits.h> - -/* - * 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 <errno.h> -#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 <sched.h> - -/* - * 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 <unistd.h>, 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 <limits.h>, 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 <sys/types.h> -#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 <signal.h> 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 <errno.h> -#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 <sys/types.h> -/* Required by Unix 98 */ -# include <time.h> -# 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 <pthread.h> #include <cstring> #include <cstdlib> #include <cstdio>