#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_i2c.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

/* OS/ALERT bit will start the conversion. While setting the config register I set the OS/ALERT bit to be 1. So it will start the conversion.
    OR
    We can set the config register later. */
#define SLAVE_ADDRESS 0x4A

//*****************************************************************************
//
// Configure the UART and its pins.  This must be called before UARTprintf().
//
//*****************************************************************************
void
ConfigureUART(void)
{
    //
    // Enable GPIOA
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable UART0
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    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, 115200, 16000000);
}

int
main(void)
{
    uint8_t 	ui8I2CTransmitData[3] = {0x02, 0x81, 0xF0};
    uint8_t 	ui8I2CReceiveData[3]  = {0x00, 0x00, 0x00};
    uint32_t 	ui32SysClock;
    uint32_t    ui32Index;

    ui32SysClock = SysCtlClockFreqSet(SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ | SYSCTL_CFG_VCO_480, 120000000);

    ConfigureUART();

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C6);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlDelay(10);

    GPIOPinConfigure(GPIO_PB6_I2C6SCL);
    GPIOPinConfigure(GPIO_PB7_I2C6SDA);
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_6);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_7);

    //
    // Configure The I2C Master
    //
    I2CMasterInitExpClk(I2C6_BASE, ui32SysClock, false);
    I2CTxFIFOConfigSet(I2C6_BASE,(I2C_FIFO_CFG_TX_MASTER|I2C_FIFO_CFG_TX_TRIG_3));
    I2CRxFIFOConfigSet(I2C6_BASE,(I2C_FIFO_CFG_RX_MASTER|I2C_FIFO_CFG_RX_TRIG_3));
    I2CTxFIFOFlush(I2C6_BASE);
    I2CRxFIFOFlush(I2C6_BASE);

    UARTprintf("I2C Master Ready.\n");

    /*  Threshold Register */
    I2CMasterBurstLengthSet(I2C6_BASE,0x3);
    I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDRESS, false);
    for(ui32Index=0;ui32Index<3;ui32Index++)
    {
    	I2CFIFODataPut(I2C6_BASE, ui8I2CTransmitData[ui32Index]);
    }
    I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE);
    while(!(I2CMasterBusy(I2C6_BASE)));
    while(I2CMasterBusy(I2C6_BASE));

    /*  Configuration Register */
    I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDRESS, false);
    I2CMasterDataPut(I2C6_BASE,0x02);
    I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    while(!(I2CMasterBusy(I2C6_BASE)));
    while(I2CMasterBusy(I2C6_BASE));
    I2CMasterBurstLengthSet(I2C6_BASE,0x3);
    I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDRESS, true);
    I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE);
    for(ui32Index=0;ui32Index<3;ui32Index++)
    {
    	ui8I2CReceiveData[ui32Index] = I2CFIFODataGet(I2C6_BASE);
    }

    while(1);

}
