/*
 $License:
   Copyright 2011 InvenSense, Inc.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
  $
 */

/******************************************************************************
 * $Id: mlsl_linux_mpu.c 5653 2011-06-16 21:06:55Z nroyer $
 *****************************************************************************/

/**
 *  @defgroup MLSL (Motion Library - Serial Layer)
 *  @brief  The Motion Library System Layer provides the Motion Library the
 *          interface to the system functions.
 *
 *  @{
 *      @file   mlsl_linux_mpu.c
 *      @brief  The Motion Library System Layer.
 *
 */

/* ------------------ */
/* - Include Files. - */
/* ------------------ */
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <string.h>
#include <signal.h>
#include <time.h>

#include "mpu.h"
#if defined CONFIG_MPU_SENSORS_MPU6050A2
#    include "mpu6050a2.h"
#elif defined CONFIG_MPU_SENSORS_MPU6050B1
#    include "mpu6050b1.h"
#elif defined CONFIG_MPU_SENSORS_MPU3050
#  include "mpu3050.h"
#else
#error Invalid or undefined CONFIG_MPU_SENSORS_MPUxxxx
#endif

#include "mlsl.h"
#include "mlos.h"
#include "mlmath.h"
#include "mlinclude.h"

#define MLCAL_ID      (0x0A0B0C0DL)
#define MLCAL_FILE    "/data/cal.bin"
#define MLCFG_ID      (0x01020304L)
#define MLCFG_FILE    "/data/cfg.bin"

#include <log.h>
#undef MPL_LOG_TAG
#define MPL_LOG_TAG "MPL-mlsl"

#ifndef I2CDEV
#define I2CDEV "/dev/mpu"
#endif

#define SERIAL_FULL_DEBUG (0)

/* --------------- */
/* - Prototypes. - */
/* --------------- */

/* ----------------------- */
/* -  Function Pointers. - */
/* ----------------------- */

/* --------------------------- */
/* - Global and Static vars. - */
/* --------------------------- */

/* ---------------- */
/* - Definitions. - */
/* ---------------- */

inv_error_t inv_serial_read_cfg(unsigned char *cfg, unsigned int len)
{
    FILE *fp;
    int bytesRead;

    fp = fopen(MLCFG_FILE, "rb");
    if (fp == NULL) {
        MPL_LOGE("Unable to open \"%s\" for read\n", MLCFG_FILE);
        return INV_ERROR_FILE_OPEN;
    }
    bytesRead = fread(cfg, 1, len, fp);
    if (bytesRead != len) {
        MPL_LOGE("bytes read (%d) don't match requested length (%d)\n",
                 bytesRead, len);
        return INV_ERROR_FILE_READ;
    }
    fclose(fp);

    if (((unsigned int)cfg[0] << 24 | cfg[1] << 16 | cfg[2] << 8 | cfg[3])
        != MLCFG_ID) {
        return INV_ERROR_ASSERTION_FAILURE;
    }

    return INV_SUCCESS;
}

inv_error_t inv_serial_write_cfg(unsigned char *cfg, unsigned int len)
{
    FILE *fp;
    int bytesWritten;
    unsigned char cfgId[4];

    fp = fopen(MLCFG_FILE,"wb");
    if (fp == NULL) {
        MPL_LOGE("Unable to open \"%s\" for write\n", MLCFG_FILE);
        return INV_ERROR_FILE_OPEN;
    }

    cfgId[0] = (unsigned char)(MLCFG_ID >> 24);
    cfgId[1] = (unsigned char)(MLCFG_ID >> 16);
    cfgId[2] = (unsigned char)(MLCFG_ID >> 8);
    cfgId[3] = (unsigned char)(MLCFG_ID);
    bytesWritten = fwrite(cfgId, 1, 4, fp);
    if (bytesWritten != 4) {
        MPL_LOGE("CFG ID could not be written on file\n");
        return INV_ERROR_FILE_WRITE;
    }

    bytesWritten = fwrite(cfg, 1, len, fp);
    if (bytesWritten != len) {
        MPL_LOGE("bytes write (%d) don't match requested length (%d)\n",
                 bytesWritten, len);
        return INV_ERROR_FILE_WRITE;
    }

    fclose(fp);

    return INV_SUCCESS;
}

inv_error_t inv_serial_read_cal(unsigned char *cal, unsigned int len)
{
    FILE *fp;
    int bytesRead;
    inv_error_t result = INV_SUCCESS;

    fp = fopen(MLCAL_FILE,"rb");
    if (fp == NULL) {
        MPL_LOGE("Cannot open file \"%s\" for read\n", MLCAL_FILE);
        return INV_ERROR_FILE_OPEN;
    }
    bytesRead = fread(cal, 1, len, fp);
    if (bytesRead != len) {
        MPL_LOGE("bytes read (%d) don't match requested length (%d)\n",
                 bytesRead, len);
        result = INV_ERROR_FILE_READ;
        goto read_cal_end;
    }

    /* MLCAL_ID not used
    if (((unsigned int)cal[0] << 24 | cal[1] << 16 | cal[2] << 8 | cal[3])
        != MLCAL_ID) {
        result = INV_ERROR_ASSERTION_FAILURE;
        goto read_cal_end;
    }
    */
read_cal_end:
    fclose(fp);
    return result;
}

inv_error_t inv_serial_write_cal(unsigned char *cal, unsigned int len)
{
    FILE *fp;
    int bytesWritten;
    inv_error_t result = INV_SUCCESS;

    fp = fopen(MLCAL_FILE,"wb");
    if (fp == NULL) {
        MPL_LOGE("Cannot open file \"%s\" for write\n", MLCAL_FILE);
        return INV_ERROR_FILE_OPEN;
    }
    bytesWritten = fwrite(cal, 1, len, fp);
    if (bytesWritten != len) {
        MPL_LOGE("bytes written (%d) don't match requested length (%d)\n",
                 bytesWritten, len);
        result = INV_ERROR_FILE_WRITE;
    }
    fclose(fp);
    return result;
}

inv_error_t inv_serial_get_cal_length(unsigned int *len)
{
    FILE *calFile;
    *len = 0;

    calFile = fopen(MLCAL_FILE, "rb");
    if (calFile == NULL) {
        MPL_LOGE("Cannot open file \"%s\" for read\n", MLCAL_FILE);
        return INV_ERROR_FILE_OPEN;
    }

    *len += (unsigned char)fgetc(calFile) << 24;
    *len += (unsigned char)fgetc(calFile) << 16;
    *len += (unsigned char)fgetc(calFile) << 8;
    *len += (unsigned char)fgetc(calFile);

    fclose(calFile);

    if (*len <= 0)
        return INV_ERROR_FILE_READ;

    return INV_SUCCESS;
}

inv_error_t inv_serial_open(char const *port, void **sl_handle)
{
    INVENSENSE_FUNC_START;

    if (NULL == port) {
        port = I2CDEV;
    }
    *sl_handle = (void*) open(port, O_RDWR);
    if(sl_handle < 0) {
        /* ERROR HANDLING; you can check errno to see what went wrong */
        MPL_LOGE("inv_serial_open\n");
        MPL_LOGE("I2C Error %d: Cannot open Adapter %s\n", errno, port);
        return INV_ERROR_SERIAL_OPEN_ERROR;
    } else {
        MPL_LOGI("inv_serial_open: %s\n", port);
    }

    return INV_SUCCESS;
}

inv_error_t inv_serial_close(void *sl_handle)
{
    INVENSENSE_FUNC_START;

    close((int)sl_handle);

    return INV_SUCCESS;
}

inv_error_t inv_serial_reset(void *sl_handle)
{
    return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
}

inv_error_t inv_serial_single_write(void *sl_handle,
                               unsigned char slaveAddr,
                               unsigned char registerAddr,
                               unsigned char data)
{
    unsigned char buf[2];
    buf[0] = registerAddr;
    buf[1] = data;
    return inv_serial_write(sl_handle, slaveAddr, 2, buf);
}

inv_error_t inv_serial_write(void *sl_handle,
                         unsigned char slaveAddr,
                         unsigned short length,
                         unsigned char const *data)
{
    INVENSENSE_FUNC_START;
    struct mpu_read_write msg;
    inv_error_t result;

    if (NULL == data) {
        return INV_ERROR_INVALID_PARAMETER;
    }

    msg.address = 0; /* not used */
    msg.length  = length;
    msg.data    = (unsigned char*)data;

    if ((result = ioctl((int)sl_handle, MPU_WRITE, &msg))) {
        MPL_LOGE("I2C Error: could not write: R:%02x L:%d %d \n",
                 data[0], length, result);
       return result;
    } else if (SERIAL_FULL_DEBUG) {
        char data_buff[4096] = "";
        char strchar[3];
        int ii;
        for (ii = 0; ii < length; ii++) {
            snprintf(strchar, sizeof(strchar), "%02x", data[0]);
            strncat(data_buff, strchar, sizeof(data_buff));
        }
        MPL_LOGI("I2C Write Success %02x %02x: %s \n",
                 data[0], length, data_buff);
    }

    return INV_SUCCESS;
}

inv_error_t inv_serial_read(void *sl_handle,
                        unsigned char  slaveAddr,
                        unsigned char  registerAddr,
                        unsigned short length,
                        unsigned char  *data)
{
    INVENSENSE_FUNC_START;
    int result = INV_SUCCESS;
    struct mpu_read_write msg;

    if (NULL == data) {
        return INV_ERROR_INVALID_PARAMETER;
    }

    msg.address = registerAddr;
    msg.length  = length;
    msg.data    = data;

    result = ioctl((int)sl_handle, MPU_READ, &msg);

    if (result != INV_SUCCESS) {
        MPL_LOGE("I2C Error %08x: could not read: R:%02x L:%d\n",
                 result, registerAddr, length);
        result = INV_ERROR_SERIAL_READ;
    } else if (SERIAL_FULL_DEBUG) {
        char data_buff[4096] = "";
        char strchar[3];
        int ii;
        for (ii = 0; ii < length; ii++) {
            snprintf(strchar, sizeof(strchar), "%02x", data[0]);
            strncat(data_buff, strchar, sizeof(data_buff));
        }
        MPL_LOGI("I2C Read  Success %02x %02x: %s \n",
                  registerAddr, length, data_buff);
    }

    return (inv_error_t) result;
}

inv_error_t inv_serial_write_mem(void *sl_handle,
                            unsigned char mpu_addr,
                            unsigned short memAddr,
                            unsigned short length,
                            const unsigned char *data)
{
    INVENSENSE_FUNC_START;
    struct mpu_read_write msg;
    int result;

    msg.address = memAddr;
    msg.length  = length;
    msg.data    = (unsigned char *)data;

    result = ioctl((int)sl_handle, MPU_WRITE_MEM, &msg);
    if (result) {
        LOG_RESULT_LOCATION(result);
        return result;
    } else if (SERIAL_FULL_DEBUG) {
        char data_buff[4096] = "";
        char strchar[3];
        int ii;
        for (ii = 0; ii < length; ii++) {
            snprintf(strchar, sizeof(strchar), "%02x", data[0]);
            strncat(data_buff, strchar, sizeof(data_buff));
        }
        MPL_LOGI("I2C WriteMem Success %04x %04x: %s \n",
                 memAddr, length, data_buff);
    }
    return INV_SUCCESS;
}

inv_error_t inv_serial_read_mem(void *sl_handle,
                           unsigned char  mpu_addr,
                           unsigned short memAddr,
                           unsigned short length,
                           unsigned char  *data)
{
    INVENSENSE_FUNC_START;
    struct mpu_read_write msg;
    int result;

    if (NULL == data) {
        return INV_ERROR_INVALID_PARAMETER;
    }

    msg.address = memAddr;
    msg.length  = length;
    msg.data    = data;

    result = ioctl((int)sl_handle, MPU_READ_MEM, &msg);
    if (result != INV_SUCCESS) {
        MPL_LOGE("I2C Error %08x: could not read memory: A:%04x L:%d\n",
                 result, memAddr, length);
        return INV_ERROR_SERIAL_READ;
    } else if (SERIAL_FULL_DEBUG) {
        char data_buff[4096] = "";
        char strchar[3];
        int ii;
        for (ii = 0; ii < length; ii++) {
            snprintf(strchar, sizeof(strchar), "%02x", data[0]);
            strncat(data_buff, strchar, sizeof(data_buff));
        }
        MPL_LOGI("I2C ReadMem Success %04x %04x: %s\n",
                 memAddr, length, data_buff);
    }
    return INV_SUCCESS;
}

inv_error_t inv_serial_write_fifo(void *sl_handle,
                             unsigned char mpu_addr,
                             unsigned short length,
                             const unsigned char *data)
{
    INVENSENSE_FUNC_START;
    struct mpu_read_write msg;
    int result;

    if (NULL == data) {
        return INV_ERROR_INVALID_PARAMETER;
    }

    msg.address = 0; /* Not used */
    msg.length  = length;
    msg.data    = (unsigned char *)data;

    result = ioctl((int)sl_handle, MPU_WRITE_FIFO, &msg);
    if (result != INV_SUCCESS) {
        MPL_LOGE("I2C Error: could not write fifo: %02x %02x\n",
                  MPUREG_FIFO_R_W, length);
        return INV_ERROR_SERIAL_WRITE;
    } else if (SERIAL_FULL_DEBUG) {
        char data_buff[4096] = "";
        char strchar[3];
        int ii;
        for (ii = 0; ii < length; ii++) {
            snprintf(strchar, sizeof(strchar), "%02x", data[0]);
            strncat(data_buff, strchar, sizeof(data_buff));
        }
        MPL_LOGI("I2C Write Success %02x %02x: %s\n",
                 MPUREG_FIFO_R_W, length, data_buff);
    }
    return (inv_error_t) result;
}

inv_error_t inv_serial_read_fifo(void *sl_handle,
                            unsigned char  mpu_addr,
                            unsigned short length,
                            unsigned char  *data)
{
    INVENSENSE_FUNC_START;
    struct mpu_read_write msg;
    int result;

    if (NULL == data) {
        return INV_ERROR_INVALID_PARAMETER;
    }

    msg.address = MPUREG_FIFO_R_W; /* Not used */
    msg.length  = length;
    msg.data    = data;

    result = ioctl((int)sl_handle, MPU_READ_FIFO, &msg);
    if (result != INV_SUCCESS) {
        MPL_LOGE("I2C Error %08x: could not read fifo: R:%02x L:%d\n",
                 result, MPUREG_FIFO_R_W, length);
        return INV_ERROR_SERIAL_READ;
    } else if (SERIAL_FULL_DEBUG) {
        char data_buff[4096] = "";
        char strchar[3];
        int ii;
        for (ii = 0; ii < length; ii++) {
            snprintf(strchar, sizeof(strchar), "%02x", data[0]);
            strncat(data_buff, strchar, sizeof(data_buff));
        }
        MPL_LOGI("I2C ReadFifo Success %02x %02x: %s\n",
                 MPUREG_FIFO_R_W, length, data_buff);
    }
    return INV_SUCCESS;
}

/**
 *  @}
 */


