//*****************************************************************************
//
// pressure_bmp180.c - Example to use of the SensorLib with the BMP180
//
// Copyright (c) 2013-2017 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 2.1.4.178 of the EK-TM4C123GXL Firmware Package.
//
//*****************************************************************************

#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/debug.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "sensorlib/hw_bmp180.h"
#include "sensorlib/i2cm_drv.h"
#include "sensorlib/bmp180.h"
#include "drivers/rgb.h"
#include "sensorlib/ak8975.h"
#include "sensorlib/mpu9150.h"
#include "sensorlib/mpu6050.h"
#include "sensorlib/hw_mpu9150.h"
#include <stdint.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>


#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_hibernate.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/hibernate.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/rom.h"
#define PWM_FREQUENCY 55
//*****************************************************************************
//
//! \addtogroup example_list
//! <h1>Pressure Measurement with the BMP180 (pressure_bmp180)</h1>
//!
//! This example demonstrates the basic use of the Sensor Library, TM4C123G
//! LaunchPad and the SensHub BoosterPack to obtain air pressure and
//! temperature measurements with the BMP180 sensor.
//!
//! Connect a serial terminal program to the LaunchPad's ICDI virtual serial
//! port at 115,200 baud.  Use eight bits per byte, no parity and one stop bit.
//! The raw sensor measurements are printed to the terminal.  The RGB LED
//! blinks at 1Hz once the initialization is complete and the example is
//! running.
//
//*****************************************************************************

//*****************************************************************************
//
// Define BMP180 I2C Address.
//
//*****************************************************************************
#define BMP180_I2C_ADDRESS      0x77
//*****************************************************************************
#define MPU9150_I2C_ADDRESS     0X68

//*****************************************************************************
//
// Global array for holding the color values for the RGB.
//
//*****************************************************************************
uint32_t g_pui32Colors[3];

//*****************************************************************************
//
// Global instance structure for the I2C master driver.
//
//*****************************************************************************
tI2CMInstance g_sI2CInst;

//*****************************************************************************
//
// Global instance structure for the BMP180 sensor driver.
//
//*****************************************************************************
tBMP180 g_sBMP180Inst;
//*****************************************************************************
// Global instance structure for MPU9150 sensor driver
//
//*****************************************************************************
tMPU9150 sMPU9150;
//*****************************************************************************
//
// Global new data flag to alert main that BMP180 data is ready.
//
//*****************************************************************************
volatile uint_fast8_t g_vui8DataFlag;

//*****************************************************************************
//
// A boolean that is set when a MPU9150 command has completed.
//
//*****************************************************************************
volatile bool g_bMPU9150Done;

//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

int32_t functie(int32_t n)
{
    int32_t rez;
    rez = 2*n;
    return(rez);
}


void comenzi(char *str, float *com1, float *com2)

{


    float temp[3];
    char buffer[16];
    char com[5];
    int32_t i, j, k, p;
    int32_t n, ns, nf;

    i=0;j=0;k=0;p=0;
    n=0;ns=0;nf=0;

    strcpy(buffer, str);
    n=strlen(buffer);

    for(i=0;i<n; i++)
    {
        if(buffer[i] ==',')
        {
            nf = i;
            for(j=ns;j<nf;j++)
            {
                com[p] = buffer[j];
                p++;
            }
            com[p]='\0';
            temp[k] = atof(com);
                p   = 0;
                com[p] ='\0';
                k++;
                ns  = i+1;
        }
    }

    *com1 =temp[0];
    *com2 =temp[1]/2;
}
//*****************************************************************************
//
// BMP180 Sensor callback function.  Called at the end of BMP180 sensor driver
// transactions. This is called from I2C interrupt context. Therefore, we just
// set a flag and let main do the bulk of the computations and display.
//
//*****************************************************************************
void BMP180AppCallback(void* pvCallbackData, uint_fast8_t ui8Status)
{
    if(ui8Status == I2CM_STATUS_SUCCESS)
    {
        g_vui8DataFlag = 1;
    }
}

//*******************************************************************************
//
// The function that is provided by this example as a callback when MPU9150
// transactions have completed.
void MPU9150Callback(void *pvCallbackData, uint_fast8_t ui8Status)
{
    //
    // See if an error occurred.
    //
    if(ui8Status != I2CM_STATUS_SUCCESS)
    {
    //
    // An error occurred, so handle it here if required.
    //
    }
    //
    // Indicate that the MPU9150 transaction has completed.
    //
    g_bMPU9150Done = true;
}


//*****************************************************************************
//
// Called by the NVIC as a result of I2C3 Interrupt. I2C3 is the I2C connection
// to the BMP180.
//
//*****************************************************************************
void
BMP180I2CIntHandler(void)
{
    //
    // Pass through to the I2CM interrupt handler provided by sensor library.
    // This is required to be at application level so that I2CMIntHandler can
    // receive the instance structure pointer as an argument.
    //
    I2CMIntHandler(&g_sI2CInst);
}
//*****************************************************************************
//
// Called by the NVIC as a result of I2C3 Interrupt. I2C3 is the I2C connection
// to the MPU9150.
//
//*****************************************************************************
void
MPU9150I2CIntHandler(void)
{
    //
    // Pass through to the I2CM interrupt handler provided by sensor library.
    // This is required to be at application level so that I2CMIntHandler can
    // receive the instance structure pointer as an argument.
    //
    I2CMIntHandler(&g_sI2CInst);
}

//*****************************************************************************
//
// Called by the NVIC as a SysTick interrupt, which is used to generate the
// sample interval
//
//*****************************************************************************
void
SysTickIntHandler()
{
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);
    BMP180DataRead(&g_sBMP180Inst, BMP180AppCallback, &g_sBMP180Inst);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x00);
}

//*****************************************************************************
//
// Configure the UART and its pins.  This must be called before UARTprintf().
//
//*****************************************************************************
void
ConfigureUART(void)
{
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable UART0
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure GPIO Pins for UART mode.
    //
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 9600, 16000000);
}

//*****************************************************************************
//
// Main 'C' Language entry point.
//
//*****************************************************************************
int
main(void)
{
    volatile uint32_t ui32Load;
          volatile uint32_t ui32PWMClock;
          volatile uint8_t ui8Adjust;
          ui8Adjust = 83;


    ///////////////////////---------
    float fTemperature, fPressure, fAltitude;
    int32_t i32IntegerPart, i32IntegerPartAx, i32IntegerPartAy, i32IntegerPartAz;
    int32_t i32FractionPart, i32FractionPartAx,i32FractionPartAy, i32FractionPartAz;
    uint_fast16_t TemperatureRaw;
    float fAccel[3], fGyro[3];
    uint_fast16_t fMagneto[3];


    //
    // Setup the system clock to run at 40 MHz from PLL with crystal reference
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                       SYSCTL_OSC_MAIN);

    //
    // Initialize the UART.
    //
    ConfigureUART();

    //
    // Print the welcome message to the terminal.
    //
    UARTprintf("\033[2JBMP180 Example\n");

    //
    // Set the color to a white approximation.
    //
    g_pui32Colors[RED] = 0x8000;
    g_pui32Colors[BLUE] = 0x8000;
    g_pui32Colors[GREEN] = 0x8000;

    //
    // Initialize RGB driver. Use a default intensity and blink rate.
    //
    RGBInit(0);
    RGBColorSet(g_pui32Colors);
    RGBIntensitySet(0.5f);
    RGBEnable();

    //
    // The I2C3 peripheral must be enabled before use.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    //
    // Configure the pin muxing for I2C3 functions on port D0 and D1.
    // This step is not necessary if your part does not support pin muxing.
    //
    ROM_GPIOPinConfigure(GPIO_PD0_I2C3SCL);
    ROM_GPIOPinConfigure(GPIO_PD1_I2C3SDA);

    //
    // Select the I2C function for these pins.  This function will also
    // configure the GPIO pins pins for I2C operation, setting them to
    // open-drain operation with weak pull-ups.  Consult the data sheet
    // to see which functions are allocated per pin.
    //
    GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
    ROM_GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);

    //
    // Initialize the GPIO for the LED.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
    ROM_GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0x00);
    ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_64);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
          ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
          ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
          ROM_GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);

    //
    // Enable interrupts to the processor.
    //
    ROM_IntMasterEnable();

    //
    // Initialize the I2C3 peripheral.
    //
    I2CMInit(&g_sI2CInst, I2C3_BASE, INT_I2C3, 0xff, 0xff,
             ROM_SysCtlClockGet());

    //
    // Initialize the BMP180.
    //
    BMP180Init(&g_sBMP180Inst, &g_sI2CInst, BMP180_I2C_ADDRESS,
               BMP180AppCallback, &g_sBMP180Inst);

    //
    // Wait for initialization callback to indicate reset request is complete.
    //
    while(g_vui8DataFlag == 0)
    {
        //
        // Wait for I2C Transactions to complete.
        //
    }

    //
    // Reset the data ready flag
    //
    g_vui8DataFlag = 0;

   //Initialize the MPU9150.

    g_bMPU9150Done == false;

    MPU9150Init(&sMPU9150, &g_sI2CInst, MPU9150_I2C_ADDRESS, MPU9150Callback, 0);
    while(!g_bMPU9150Done)
    {

    }

    g_bMPU9150Done = false;

    MPU9150ReadModifyWrite(&sMPU9150, MPU9150_O_ACCEL_CONFIG,
    ~MPU9150_ACCEL_CONFIG_AFS_SEL_M,
    MPU9150_ACCEL_CONFIG_AFS_SEL_4G, MPU9150Callback,
    0);

    //
    // Enable the system ticks at 10 Hz.
    //
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / (10 * 3));
    ROM_SysTickIntEnable();
    ROM_SysTickEnable();

    //
    // After all the init and config we start blink the LED
    //
    RGBBlinkRateSet(1.0f);

    //
    // Begin the data collection and printing.  Loop Forever.
// mere 
    ROM_GPIOPinConfigure(GPIO_PB4_M0PWM2);
    ui32PWMClock = SysCtlClockGet() / 64;
         ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;

         PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
         PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, ui32Load);

         ROM_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);
         ROM_PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
         ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_0);
         char  g_cInput[16];
         float d1, d2;

         ROM_FPUEnable();
         ROM_FPUStackingEnable();
         UARTprintf("TEST");
    while(1)
    {


       if(UARTPeek('\r') !=-1)
               {
                   ///



                  ///

                   UARTgets(g_cInput,sizeof(g_cInput));
                   UARTprintf("Ce s-a printat: %s\n",g_cInput);
                   comenzi(g_cInput, &d1, &d2);
                   UARTprintf("%d, %d\n", (int32_t)d1, (int32_t)d2);
               }




                          ui8Adjust = (int32_t)d1;

                      ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);

                 ROM_SysCtlDelay(100000);




        //
        // Read the data from the BMP180 over I2C.  This command starts a
        // temperature measurement.  Then polls until temperature is ready.
        // Then automatically starts a pressure measurement and polls for that
        // to complete. When both measurement are complete and in the local
        // buffer then the application callback is called from the I2C
        // interrupt context.  Polling is done on I2C interrupts allowing
        // processor to continue doing other tasks as needed.
        //
        BMP180DataRead(&g_sBMP180Inst, BMP180AppCallback, &g_sBMP180Inst);
        while(g_vui8DataFlag == 0)
        {
            //
            // Wait for the new data set to be available.
            //
        }

        //
        // Reset the data ready flag.
        //
        g_vui8DataFlag = 0;

        while(!g_bMPU9150Done)
           {
           }

        g_bMPU9150Done = false;
        MPU9150DataRead(&sMPU9150, MPU9150Callback, 0);
        while(!g_bMPU9150Done)
        {
        }

        MPU9150DataAccelGetFloat(&sMPU9150, &fAccel[0], &fAccel[1], &fAccel[2]);

        //
        // Get a local copy of the latest temperature data in float format.
        //
        BMP180DataTemperatureGetFloat(&g_sBMP180Inst, &fTemperature);
        BMP180DataTemperatureGetRaw(&g_sBMP180Inst, &TemperatureRaw);

        //
        // Convert the floats to an integer part and fraction part for easy
        // print.
        //
        /*
        i32IntegerPart = (int32_t) fTemperature;
        i32FractionPart =(int32_t) (fTemperature * 1000.0f);
        i32FractionPart = i32FractionPart - (i32IntegerPart * 1000);
        if(i32FractionPart < 0)
        {
            i32FractionPart *= -1;
        }
       */

        i32IntegerPartAx = (int32_t) fAccel[0];
        i32FractionPartAx =(int32_t) (fAccel[0] * 1000.0f);
        i32FractionPartAx = i32FractionPartAx - (i32IntegerPartAx * 1000);
        if(i32FractionPartAx < 0)
        {
            i32FractionPartAx *= -1;
        }

        i32IntegerPartAy = (int32_t) fAccel[1];
        i32FractionPartAy =(int32_t) (fAccel[1] * 1000.0f);
        i32FractionPartAy = i32FractionPartAy - (i32IntegerPartAy * 1000);

        if(i32FractionPartAy < 0)
        {
            i32FractionPartAy *= -1;
        }

        i32IntegerPartAz = (int32_t) fAccel[2];
        i32FractionPartAz =(int32_t) (fAccel[2] * 1000.0f);
        i32FractionPartAz = i32FractionPartAz - (i32IntegerPartAz * 1000);

        if(i32FractionPartAz < 0)
        {
            i32FractionPartAz *= -1;
        }





        //banana
        // Print temperature with three digits of decimal precision.
        //
        // UARTprintf("Temperature %3d.%03d\t\t", i32IntegerPart, i32FractionPart);
        // UARTprintf("%3d.%3d %3d.%3d %3d.%3d", i32IntegerPartAx, i32FractionPartAx, i32IntegerPartAy, i32FractionPartAy, i32IntegerPartAz, i32FractionPartAz);
        UARTprintf("%3d.%03d", i32IntegerPartAx, i32FractionPartAx);
        UARTprintf(",");
        UARTprintf("%3d.%03d", i32IntegerPartAy, i32FractionPartAy);
        UARTprintf(",");
        UARTprintf("%3d.%03d", i32IntegerPartAz, i32FractionPartAz);

        //UARTprintf("\033[5;63H%3d.%03d", i32IntegerPartAx, i32FractionPartAx);
        //UARTprintf("\033[5;63H%3d.%03d", i32IntegerPartAy, i32FractionPartAy);



        //UARTprintf("%3d.%3d \n", i32IntegerPartAy, i32FractionPartAy);
        //UARTprintf("%3d.%3d \n", i32IntegerPartAz, i32FractionPartAz);
        // UARTprintf("x %3d.%03d\t\t", i32IntegerPart, i32FractionPart);
        // UARTprintf("%d",fAccel[2]);
        // UARTprintf("Pressure %.6f",fTemperature);
        //
        // Get a local copy of the latest air pressure data in float format.
        //
        //BMP180DataPressureGetFloat(&g_sBMP180Inst, &fPressure);
        MPU9150DataMagnetoGetRaw(&sMPU9150, &fMagneto[0], &fMagneto[1], &fMagneto[2]);

        //
        // Convert the floats to an integer part and fraction part for easy
        // print.
        //
        i32IntegerPart = (int32_t) fMagneto[0];
        i32FractionPart =(int32_t) (fMagneto[0] * 1000.0f);
        i32FractionPart = i32FractionPart - (i32IntegerPart * 1000);
        if(i32FractionPart < 0)
        {
            i32FractionPart *= -1;
        }

        //
        // Print Pressure with three digits of decimal precision.
        //
        //UARTprintf("MagX %3d.%03d\t\t", i32IntegerPart, i32FractionPart);

        //
        // Calculate the altitude.
        //
        fAltitude = 44330.0f * (1.0f - powf(fPressure / 101325.0f,
                                            1.0f / 5.255f));

        //
        // Convert the floats to an integer part and fraction part for easy
        // print.
        //
        i32IntegerPart = (int32_t) fAltitude;
        i32FractionPart =(int32_t) (fAltitude * 1000.0f);
        i32FractionPart = i32FractionPart - (i32IntegerPart * 1000);
        if(i32FractionPart < 0)
        {
            i32FractionPart *= -1;
        }

        //
        // Print altitude with three digits of decimal precision.
        //
        //UARTprintf("Altitude %3d.%03d", i32IntegerPart, i32FractionPart);

        //
        // Print new line.
        //
        UARTprintf("\n");

        //
        // Delay to keep printing speed reasonable. About 100 milliseconds.
        //
        ROM_SysCtlDelay(ROM_SysCtlClockGet() / (10 * 3));

    }//while end
}
