commit 5d4d14a3a119bb8b75f59eaa33496d46e5963a7a
Author: Thomas Schöpping <tschoepp@cit-ec.uni-bielefeld.de>
Date:   Thu Feb 7 10:44:14 2019 +0100

    manually merged MPU6050 driver to master branch.
    NOTE: implementation requires some rework and enhancements

diff --git a/include/MPU6050/alld_MPU6050.h b/include/MPU6050/alld_MPU6050.h
new file mode 100644
index 0000000..7b75a7e
--- /dev/null
+++ b/include/MPU6050/alld_MPU6050.h
@@ -0,0 +1,43 @@
+/*
+AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
+
+This program 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 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file    alld_MPU6050.h
+ *
+ * @addtogroup lld_mems
+ * @{
+ */
+
+#ifndef AMIROLLD_MPU6050_H
+#define AMIROLLD_MPU6050_H
+
+#include <amiro-lld.h>
+
+#if defined(AMIROLLD_CFG_MPU6050)
+
+#if (AMIROLLD_CFG_MPU6050 == 1)
+  #include "v1/alld_MPU6050_v1.h"
+#else
+  #error "invalid value assigned to AMIROLLD_CFG_MPU6050 in alldconf.h"
+#endif
+
+#endif /* defined(AMIROLLD_CFG_MPU6050) */
+
+#endif /* AMIROLLD_MPU6050_H */
+
+/** @} */
diff --git a/include/MPU6050/v1/alld_MPU6050_v1.h b/include/MPU6050/v1/alld_MPU6050_v1.h
new file mode 100644
index 0000000..16103f6
--- /dev/null
+++ b/include/MPU6050/v1/alld_MPU6050_v1.h
@@ -0,0 +1,194 @@
+/*
+AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
+
+This program 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 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file    alld_MPU6050_v1.h
+ * @brief   Gyro & Accelerometer macros and structures.
+ *
+ * @addtogroup lld_mems
+ * @{
+ */
+
+#ifndef AMIROLLD_MPU6050_V1_H
+#define AMIROLLD_MPU6050_V1_H
+
+#include <amiro-lld.h>
+
+#if (defined(AMIROLLD_CFG_MPU6050) && (AMIROLLD_CFG_MPU6050 == 1)) || defined(__DOXYGEN__)
+
+/******************************************************************************/
+/* CONSTANTS                                                                  */
+/******************************************************************************/
+
+/**
+ * @brief Maximum I2C frequency.
+ */
+#define MPU6050_LLD_I2C_MAXFREQUENCY    400000
+
+#define SD_MPU6050_DataRate_8KHz        0   /**< Sample rate set to 8 kHz */
+#define SD_MPU6050_DataRate_4KHz        1   /**< Sample rate set to 4 kHz */
+#define SD_MPU6050_DataRate_2KHz        3   /**< Sample rate set to 2 kHz */
+#define SD_MPU6050_DataRate_1KHz        7   /**< Sample rate set to 1 kHz */
+#define SD_MPU6050_DataRate_500Hz       15  /**< Sample rate set to 500 Hz */
+#define SD_MPU6050_DataRate_250Hz       31  /**< Sample rate set to 250 Hz */
+#define SD_MPU6050_DataRate_125Hz       63  /**< Sample rate set to 125 Hz */
+#define SD_MPU6050_DataRate_100Hz       79  /**< Sample rate set to 100 Hz */
+
+/******************************************************************************/
+/* SETTINGS                                                                   */
+/******************************************************************************/
+
+/******************************************************************************/
+/* CHECKS                                                                     */
+/******************************************************************************/
+
+/******************************************************************************/
+/* DATA STRUCTURES AND TYPES                                                  */
+/******************************************************************************/
+
+/**
+ * @brief I2C address masks. TODO: Set to MPU6050 adresses!
+ */
+enum {
+  MPU6050_LLD_I2C_ADDR_FIXED   = 0x0040u,
+  MPU6050_LLD_I2C_ADDR_A0      = 0x0001u,
+  MPU6050_LLD_I2C_ADDR_A1      = 0x0004u,
+};
+
+/**
+ * @brief Registers. TODO: Adjust to MPU6050 registers
+ */
+typedef enum {
+  MPU6050_LLD_REGISTER_CONFIGURATION = 0x00,
+  MPU6050_LLD_REGISTER_SHUNT_VOLTAGE = 0x01,
+  MPU6050_LLD_REGISTER_BUS_VOLTAGE   = 0x02,
+  MPU6050_LLD_REGISTER_POWER         = 0x03,
+  MPU6050_LLD_REGISTER_CURRENT       = 0x04,
+  MPU6050_LLD_REGISTER_CALIBRATION   = 0x05,
+} mpu6050_lld_register_t;
+
+/**
+ * @brief  MPU6050 can have 2 different slave addresses, depends on it's input AD0 pin
+ *         This feature allows you to use 2 different sensors with this library at the same time
+ */
+typedef enum  {
+	SD_MPU6050_Device_0 = 0x00, /*!< AD0 pin is set to low */
+	SD_MPU6050_Device_1 = 0x02  /*!< AD0 pin is set to high */
+} SD_MPU6050_Device;
+
+/**
+ * @brief  MPU6050 result enumeration
+ */
+typedef enum  {
+	SD_MPU6050_Result_Ok = 0x00,          /*!< Everything OK */
+	SD_MPU6050_Result_Error,              /*!< Unknown error */
+	SD_MPU6050_Result_DeviceNotConnected, /*!< There is no device with valid slave address */
+	SD_MPU6050_Result_DeviceInvalid       /*!< Connected device with address is not MPU6050 */
+} SD_MPU6050_Result;
+
+/**
+ * @brief  Parameters for accelerometer range
+ */
+typedef enum  {
+	SD_MPU6050_Accelerometer_2G = 0x00, /*!< Range is +- 2G */
+	SD_MPU6050_Accelerometer_4G = 0x01, /*!< Range is +- 4G */
+	SD_MPU6050_Accelerometer_8G = 0x02, /*!< Range is +- 8G */
+	SD_MPU6050_Accelerometer_16G = 0x03 /*!< Range is +- 16G */
+} SD_MPU6050_Accelerometer;
+
+/**
+ * @brief  Parameters for gyroscope range
+ */
+typedef enum {
+	SD_MPU6050_Gyroscope_250s = 0x00,  /*!< Range is +- 250 degrees/s */
+	SD_MPU6050_Gyroscope_500s = 0x01,  /*!< Range is +- 500 degrees/s */
+	SD_MPU6050_Gyroscope_1000s = 0x02, /*!< Range is +- 1000 degrees/s */
+	SD_MPU6050_Gyroscope_2000s = 0x03  /*!< Range is +- 2000 degrees/s */
+} SD_MPU6050_Gyroscope;
+
+
+/**
+ * @brief  Interrupts union and structure
+ */
+typedef union {
+	struct {
+		uint8_t DataReady:1;       /*!< Data ready interrupt */
+		uint8_t reserved2:2;       /*!< Reserved bits */
+		uint8_t Master:1;          /*!< Master interrupt. Not enabled with library */
+		uint8_t FifoOverflow:1;    /*!< FIFO overflow interrupt. Not enabled with library */
+		uint8_t reserved1:1;       /*!< Reserved bit */
+		uint8_t MotionDetection:1; /*!< Motion detected interrupt */
+		uint8_t reserved0:1;       /*!< Reserved bit */
+	} F;
+	uint8_t Status;
+} SD_MPU6050_Interrupt;
+
+/**
+ * @brief Config register.
+ */
+typedef union {
+  uint16_t data;
+  struct {
+    /**
+    ina219_lld_mode_t mode : 3;
+    ina219_lld_adc_t sadc : 4;
+    ina219_lld_adc_t badc : 4;
+    ina219_lld_gain_t gain : 2;
+    ina219_lld_brng_t brng : 1;
+    */
+    uint8_t zero : 1;
+    uint8_t reset : 1;
+  } options;
+} mpu6050_lld_cfg_t;
+
+
+/**
+ * @brief The MPU6050 struct.
+ */
+typedef struct {
+  apalI2CDriver_t* i2cd;
+  apalI2Caddr_t addr;   /**<The address of the module for I2C communication */
+  uint16_t current_lsb_uA;
+  mpu6050_lld_cfg_t *config;
+} MPU6050Driver;
+
+/******************************************************************************/
+/* MACROS                                                                     */
+/******************************************************************************/
+
+/******************************************************************************/
+/* EXTERN DECLARATIONS                                                        */
+/******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  apalExitStatus_t mpu6050_lld_read_register(const MPU6050Driver* const mpu6050, const mpu6050_lld_register_t addr, uint16_t* const data, const uint8_t num, const apalTime_t timeout);
+  apalExitStatus_t mpu6050_lld_write_register(const MPU6050Driver* const mpu6050, const mpu6050_lld_register_t addr, const uint16_t* const data, const uint8_t num, const apalTime_t timeout);
+#ifdef __cplusplus
+}
+#endif
+
+/******************************************************************************/
+/* INLINE FUNCTIONS                                                           */
+/******************************************************************************/
+
+#endif /* defined(AMIROLLD_CFG_MPU6050) && (AMIROLLD_CFG_MPU6050 == 1) */
+
+#endif /* AMIROLLD_MPU6050_V1_H */
+
diff --git a/source/MPU6050/v1/alld_MPU6050_v1.c b/source/MPU6050/v1/alld_MPU6050_v1.c
new file mode 100644
index 0000000..9187f39
--- /dev/null
+++ b/source/MPU6050/v1/alld_MPU6050_v1.c
@@ -0,0 +1,161 @@
+/*
+ * sd_hal_mpu6050.c
+ *
+ *  Created on: Feb 19, 2016
+ *      Author: Sina Darvishi
+ *  Edited on: Jan 15, 2019
+ *      Editor: Simon Welzel
+ */
+
+/**
+ * |----------------------------------------------------------------------
+ * | Copyright (C) Sina Darvishi,2016
+ * |
+ * | This program is free software: you can redistribute it and/or modify
+ * | it under the terms of the GNU General Public License as published by
+ * | the Free Software Foundation, either version 3 of the License, or
+ * | any later version.
+ * |
+ * | This program is distributed in the hope that it will be useful,
+ * | but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * | GNU General Public License for more details.
+ * |
+ * | You should have received a copy of the GNU General Public License
+ * | along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * |----------------------------------------------------------------------
+ */
+
+#include <alld_MPU6050.h>
+
+#if (defined(AMIROLLD_CFG_MPU6050) && (AMIROLLD_CFG_MPU6050 == 1)) || defined(__DOXYGEN__)
+
+/******************************************************************************/
+/* LOCAL DEFINITIONS                                                          */
+/******************************************************************************/
+
+/* Default I2C address */
+#define MPU6050_I2C_ADDR   0xD0
+
+/* Who I am register value */
+#define MPU6050_I_AM    0x68
+
+/* MPU6050 registers */
+#define MPU6050_AUX_VDDIO   0x01
+#define MPU6050_SMPLRT_DIV   0x19
+#define MPU6050_CONFIG    0x1A
+#define MPU6050_GYRO_CONFIG   0x1B
+#define MPU6050_ACCEL_CONFIG  0x1C
+#define MPU6050_MOTION_THRESH  0x1F
+#define MPU6050_INT_PIN_CFG   0x37
+#define MPU6050_INT_ENABLE   0x38
+#define MPU6050_INT_STATUS   0x3A
+#define MPU6050_ACCEL_XOUT_H  0x3B
+#define MPU6050_ACCEL_XOUT_L  0x3C
+#define MPU6050_ACCEL_YOUT_H  0x3D
+#define MPU6050_ACCEL_YOUT_L  0x3E
+#define MPU6050_ACCEL_ZOUT_H  0x3F
+#define MPU6050_ACCEL_ZOUT_L  0x40
+#define MPU6050_TEMP_OUT_H   0x41
+#define MPU6050_TEMP_OUT_L   0x42
+#define MPU6050_GYRO_XOUT_H   0x43
+#define MPU6050_GYRO_XOUT_L   0x44
+#define MPU6050_GYRO_YOUT_H   0x45
+#define MPU6050_GYRO_YOUT_L   0x46
+#define MPU6050_GYRO_ZOUT_H   0x47
+#define MPU6050_GYRO_ZOUT_L   0x48
+#define MPU6050_MOT_DETECT_STATUS 0x61
+#define MPU6050_SIGNAL_PATH_RESET 0x68
+#define MPU6050_MOT_DETECT_CTRL  0x69
+#define MPU6050_USER_CTRL   0x6A
+#define MPU6050_PWR_MGMT_1   0x6B
+#define MPU6050_PWR_MGMT_2   0x6C
+#define MPU6050_FIFO_COUNTH   0x72
+#define MPU6050_FIFO_COUNTL   0x73
+#define MPU6050_FIFO_R_W   0x74
+#define MPU6050_WHO_AM_I   0x75
+
+/* Gyro sensitivities in degrees/s */
+#define MPU6050_GYRO_SENS_250  ((float) 131)
+#define MPU6050_GYRO_SENS_500  ((float) 65.5)
+#define MPU6050_GYRO_SENS_1000  ((float) 32.8)
+#define MPU6050_GYRO_SENS_2000  ((float) 16.4)
+
+/* Acce sensitivities in g/s */
+#define MPU6050_ACCE_SENS_2   ((float) 16384)
+#define MPU6050_ACCE_SENS_4   ((float) 8192)
+#define MPU6050_ACCE_SENS_8   ((float) 4096)
+#define MPU6050_ACCE_SENS_16  ((float) 2048)
+
+/******************************************************************************/
+/* EXPORTED VARIABLES                                                         */
+/******************************************************************************/
+
+/******************************************************************************/
+/* LOCAL TYPES                                                                */
+/******************************************************************************/
+
+/******************************************************************************/
+/* LOCAL VARIABLES                                                            */
+/******************************************************************************/
+
+/******************************************************************************/
+/* LOCAL FUNCTIONS                                                            */
+/******************************************************************************/
+
+/******************************************************************************/
+/* EXPORTED FUNCTIONS                                                         */
+/******************************************************************************/
+
+// from alld_ina219.c
+/**
+ * @brief Read the value of one or more of the registers.
+ * @param[in]   i2cd        i2c driver
+ * @param[in]   inad        ina219 driver
+ * @param[in]   addr        register address
+ * @param[out]  data        register content
+ * @param[in]   num         number of subsequent registers to read
+ * @param[in]   timeout     timeout
+ * @return                  An indicator whether the call was successfull
+ */
+apalExitStatus_t mpu6050_lld_read_register(const MPU6050Driver* const mpu6050, const mpu6050_lld_register_t addr, uint16_t* const data, const uint8_t num, const apalTime_t timeout)
+{
+  apalDbgAssert(mpu6050 != 0);
+  apalDbgAssert(mpu6050->i2cd != 0);
+  apalDbgAssert(data != 0);
+
+  uint8_t buffer[num*2];
+  apalExitStatus_t status = apalI2CMasterTransmit(mpu6050->i2cd, (MPU6050_LLD_I2C_ADDR_FIXED | mpu6050->addr), (uint8_t*)&addr, 1, buffer, 2*num, timeout);
+  for (uint8_t dataIdx = 0; dataIdx < num; dataIdx++) {
+    data[dataIdx] = (buffer[2*dataIdx] << 8) | buffer[2*dataIdx+1];
+  }
+  return status;
+}
+
+/**
+ * @brief Write the value of one or more of the registers.
+ * @param[in]   i2cd        i2c driver
+ * @param[in]   inad        ina219 driver
+ * @param[in]   addr        register address
+ * @param[in]   data        data to write
+ * @param[in]   num         number of subsequent registers to read
+ * @param[in]   timeout     timeout
+ * @return                  An indicator whether the call was successfull
+ */
+apalExitStatus_t mpu6050_lld_write_register(const MPU6050Driver* const mpu6050, const mpu6050_lld_register_t addr, const uint16_t* const data, const uint8_t num, const apalTime_t timeout)
+{
+  apalDbgAssert(mpu6050 != 0);
+  apalDbgAssert(mpu6050->i2cd != 0);
+  apalDbgAssert(data != 0);
+
+  uint8_t buffer[1+2*num];
+  buffer[0] = addr;
+  for (uint8_t dataIdx = 0; dataIdx < num; dataIdx++) {
+    buffer[dataIdx*2+1] = data[dataIdx] >> 8;
+    buffer[dataIdx*2+2] = data[dataIdx] & (0x00FFu);
+  }
+  return apalI2CMasterTransmit(mpu6050->i2cd, (MPU6050_LLD_I2C_ADDR_FIXED | mpu6050->addr), buffer, 1+2*num, NULL, 0, timeout);
+}
+
+#endif /* defined(AMIROLLD_CFG_MPU6050) && (AMIROLLD_CFG_MPU6050 == 1) */
+
