/*******************************************************************************
  MPLAB Harmony Application Source File

  Company:
    Microchip Technology Inc.

  File Name:
    app_drv_i2c2.c

  Summary:
    This file contains the source code for the MPLAB Harmony application.

  Description:
    This file contains the source code for the MPLAB Harmony application.  It
    implements the logic of the application's state machine and it may call
    API routines of other MPLAB Harmony modules in the system, such as drivers,
    system services, and middleware.  However, it does not call any of the
    system interfaces (such as the "Initialize" and "Tasks" functions) of any of
    the modules in the system or make any assumptions about when those functions
    are called.  That is the responsibility of the configuration-specific system
    files.
 *******************************************************************************/

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include "app_drv_i2c2.h"
#include "app_drv_usart1.h"
#include "app_drv_usart2.h"
#include "driver/i2c/drv_i2c.h"
#include "system/time/sys_time.h"
#include <stdio.h>
#include <string.h>

// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************
#define KXTJ3_ADDRESS   0x0E

DRV_HANDLE  I2C2Handle_TJ3;
DRV_I2C_TRANSFER_HANDLE I2C2WriteReadHandle_TJ3;
volatile int I2C2Complete_TJ3 = false;
char I2C2WriteBuf_TJ3[20];
char I2C2ReadBuf_TJ3[20];
int  AxisOutRegIdx = 0;
char AxisOutReg[6] = { 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B };
char AxisOutByte[6];

// *****************************************************************************
/* Application Data

  Summary:
    Holds application data

  Description:
    This structure holds the application's data.

  Remarks:
    This structure should be initialized by the APP_DRV_I2C2_Initialize function.

    Application strings and buffers are be defined outside this structure.
*/

APP_DRV_I2C2_DATA app_drv_i2c2Data;

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************
void I2C2TransferHandler_TJ3( DRV_I2C_TRANSFER_EVENT event,
                              DRV_I2C_TRANSFER_HANDLE transferHandle,
                              uintptr_t context )
{
    switch( event )
    {
    case DRV_I2C_TRANSFER_EVENT_PENDING:        break;
    case DRV_I2C_TRANSFER_EVENT_COMPLETE:
        I2C2Complete_TJ3 = true;
        break;
    case DRV_I2C_TRANSFER_EVENT_HANDLE_EXPIRED:
    case DRV_I2C_TRANSFER_EVENT_ERROR:
    case DRV_I2C_TRANSFER_EVENT_HANDLE_INVALID:
        app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_ERROR;
        break;
    }
}

// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************


/* TODO:  Add any necessary local functions.
*/


// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void APP_DRV_I2C2_Initialize ( void )

  Remarks:
    See prototype in app_drv_i2c2.h.
 */

void APP_DRV_I2C2_Initialize ( void )
{
    /* Place the App state machine in its initial state. */
    app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_INIT;



    /* TODO: Initialize your application's state machine and other
     * parameters.
     */
}


/******************************************************************************
  Function:
    void APP_DRV_I2C2_Tasks ( void )

  Remarks:
    See prototype in app_drv_i2c2.h.
 */

void APP_DRV_I2C2_Tasks ( void )
{
    switch ( app_drv_i2c2Data.state )
    {
    case APP_DRV_I2C2_STATE_INIT:
        I2C2Handle_TJ3 = DRV_I2C_Open(DRV_I2C_INDEX_1, DRV_IO_INTENT_READWRITE);
        if(I2C2Handle_TJ3 == DRV_HANDLE_INVALID)
        {
            app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_ERROR;
            break;
        }

        I2C2WriteBuf_TJ3[0] = 0x1D;
        I2C2WriteBuf_TJ3[1] = 0x80;
        DRV_I2C_WriteTransferAdd( I2C2Handle_TJ3, KXTJ3_ADDRESS,
                                           I2C2WriteBuf_TJ3, 2, &I2C2WriteReadHandle_TJ3 );
        while( DRV_I2C_TransferStatusGet(I2C2WriteReadHandle_TJ3) != 
                                                       DRV_I2C_TRANSFER_EVENT_COMPLETE) {}
        SYS_TIME_HANDLE TimeHandle;
        SYS_TIME_DelayMS(10, &TimeHandle );
        while(!SYS_TIME_DelayIsComplete(TimeHandle)) {}

        USART1printf("G-Sensor Software Reset Completed\r\n");

        I2C2WriteBuf_TJ3[0] = 0x0F;
        DRV_I2C_WriteReadTransferAdd( I2C2Handle_TJ3, KXTJ3_ADDRESS,
                       I2C2WriteBuf_TJ3, 1, I2C2ReadBuf_TJ3, 1, &I2C2WriteReadHandle_TJ3 );
        while( DRV_I2C_TransferStatusGet(I2C2WriteReadHandle_TJ3) != 
                                                       DRV_I2C_TRANSFER_EVENT_COMPLETE) {}
        if( I2C2ReadBuf_TJ3[0] != 0x35 )
        {
            app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_ERROR;
            break;
        }

        USART1printf("G-Sensor WHO AM I : 0x%X\r\n", I2C2ReadBuf_TJ3[0]);

        I2C2WriteBuf_TJ3[0] = 0x1B;
        I2C2WriteBuf_TJ3[1] = 0xF0;
        DRV_I2C_WriteTransferAdd( I2C2Handle_TJ3, KXTJ3_ADDRESS,
                                           I2C2WriteBuf_TJ3, 2, &I2C2WriteReadHandle_TJ3 );
        while( DRV_I2C_TransferStatusGet(I2C2WriteReadHandle_TJ3) != 
                                                       DRV_I2C_TRANSFER_EVENT_COMPLETE) {}

        USART1printf("G-Sensor Initial Completed\r\n");

        DRV_I2C_TransferEventHandlerSet(I2C2Handle_TJ3, I2C2TransferHandler_TJ3, 0);

        app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WRITE_READ_DRDY_TJ3;
        break;

    case APP_DRV_I2C2_STATE_WRITE_READ_DRDY_TJ3:
        I2C2WriteBuf_TJ3[0] = 0x16;
        DRV_I2C_WriteReadTransferAdd( I2C2Handle_TJ3, KXTJ3_ADDRESS,
                       I2C2WriteBuf_TJ3, 1, I2C2ReadBuf_TJ3, 1, &I2C2WriteReadHandle_TJ3 );

        if(I2C2WriteReadHandle_TJ3 == DRV_I2C_TRANSFER_HANDLE_INVALID)
        {
            app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_ERROR;
            break;
        }

        app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WAIT_COMPLETE_DRDY_TJ3;
        break;

    case APP_DRV_I2C2_STATE_WAIT_COMPLETE_DRDY_TJ3:
        if(I2C2Complete_TJ3 == true)
        {
            I2C2Complete_TJ3 = false;
				
            if(I2C2ReadBuf_TJ3[0] & (1<<4))
            {
                AxisOutRegIdx = 0;
                app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WRITE_READ_AXIS_TJ3;
                break;
            }
            app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WRITE_READ_DRDY_TJ3;
        }
        break;

    case APP_DRV_I2C2_STATE_WRITE_READ_AXIS_TJ3:
        I2C2WriteBuf_TJ3[0] = AxisOutReg[AxisOutRegIdx];
        DRV_I2C_WriteReadTransferAdd( I2C2Handle_TJ3, KXTJ3_ADDRESS,
                       I2C2WriteBuf_TJ3, 1, I2C2ReadBuf_TJ3, 1, &I2C2WriteReadHandle_TJ3 );

        if(I2C2WriteReadHandle_TJ3 == DRV_I2C_TRANSFER_HANDLE_INVALID)
        {
            app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_ERROR;
            break;
        }

        app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WAIT_COMPLETE_AXIS_TJ3;
        break;

    case APP_DRV_I2C2_STATE_WAIT_COMPLETE_AXIS_TJ3:
        if(I2C2Complete_TJ3 == true)
        {
            I2C2Complete_TJ3 = false;
				
            AxisOutByte[AxisOutRegIdx] = I2C2ReadBuf_TJ3[0];
            if(++ AxisOutRegIdx >= 6)
            {
                USART1printf("\t\t\t\tG-Sensor = (%5d, %5d, %5d)\r",
                               (short)(AxisOutByte[1]<<8|AxisOutByte[0]),
                               (short)(AxisOutByte[3]<<8|AxisOutByte[2]),
                               (short)(AxisOutByte[5]<<8|AxisOutByte[4]));

                app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WRITE_READ_DRDY_TJ3;
                break;
            }
            app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_WRITE_READ_AXIS_TJ3;
        }
        break;

    case APP_DRV_I2C2_STATE_ERROR:
        USART1printf("DRV_I2C2 error!\r\n");

        app_drv_i2c2Data.state = APP_DRV_I2C2_STATE_IDLE;
        break;

    case APP_DRV_I2C2_STATE_IDLE:
        break;
    }
}


/*******************************************************************************
 End of File
 */
