/* 
 * File:   newmain.c
 * Author: drthom
 *
 * Created on April 10, 2015, 6:12 AM
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// PIC12F1840 Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)



/*
 * 
 */
void delayzz(void)
        {              int i, j;
                        for(i=0;i<32767;i++)
                {
                          for(j=0;j<5;j++)
                      {           /* Well its Just a Timer */            }    }   }

void putch(char c)      // RS232 comms character output
{
    while(!TRMT);
    TXREG = c;
}

// I2C functions BEGIN


// i2c_Wait - wait for I2C transfer to finish
void i2c_Wait(void){
    while ( ( SSP1CON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
}

// i2c_Start - Start I2C communication
void i2c_Start(void)
{
    i2c_Wait();
    SEN=1;
}

// i2c_Restart - Re-Start I2C communication
void i2c_Restart(void){
    i2c_Wait();
    RSEN=1;
}

// i2c_Stop - Stop I2C communication
void i2c_Stop(void)
{
    i2c_Wait();
    PEN=1;
}

// i2c_Write - Sends one byte of data
void i2c_Write(unsigned char data)
{
    i2c_Wait();
    SSPBUF = data;
}

// i2c_Address - Sends Slave Address and Read/Write mode
// mode is either I2C_WRITE or I2C_READ
void i2c_Address(unsigned char address, unsigned char mode)
{
    unsigned char l_address;

    l_address=address<<1;
    l_address+=mode;
    i2c_Wait();
    SSPBUF = l_address;
}

// i2c_Read - Reads a byte from Slave device
unsigned char i2c_Read(unsigned char ack)
{
    // Read data from slave
    // ack should be 1 if there is going to be more data read
    // ack should be 0 if this is the last byte of data read
    unsigned char i2cReadData;

    i2c_Wait();
    RCEN=1;
    i2c_Wait();
    i2cReadData = SSPBUF;
    i2c_Wait();
    if ( ack ) ACKDT=0;	        // Ack
    else       ACKDT=1;	        // NAck
    ACKEN=1;                    // send acknowledge sequence

    return( i2cReadData );
}

// I2C functions END



void main(void) {
    unsigned char oldval;

    OSCCON = 0b01111000;// 16 MHz Internal Clock

    APFCON = 0b1001100; // Alternate Pin Function Control Register
                        // bit 7 = 1 = RX/DT function is on RA5
                        //     6 = 0 = SDO function is on RA0
                        //     5 = 0 = SS* function is on RA3
                        //     4 = 1 = unimplemented
                        //     3 = 1 = T1G function is on RA3
                        //     2 = 1 = TX/CK function is on RA4
                        //     1 = 0 = P1B function is on RA0
                        //     0 = 0 = CCP1/P1A function is on RA2
    
    TRISA = 0b00100110; // Sets PortA pins
                        // bit 7 = x = unused
                        //     6 = x = unused
                        //     5 = 1 = input Rx data
                        //     4 = 0 = output Tx data
                        //     3 = 0 = RA3 don't care
                        //     2 = 1 = I2C SDA data
                        //     1 = 1 = I2C SCL clock
                        //     0 = 0 = RA0 don't care

	TXEN=1;         // Enables EUSART xmtr
        SYNC=0;         // Asynchronous operation
        SPEN=1;         // Enables EUSART and configures TX/CK I/O pin as output
	BRGH=1;         // Async mode Hi Speed

	//RCSTA
	SPEN=1;         // Enables EUSART and configures TX/CK I/O pin as output
	CREN=0;         // Enable Receiver (RX)

	//BAUDCON
	BRG16=0;        // 8 bit Baud Rate Generator is used

    //TXSTA = 0b00100010;            // set BRGH bit in TXSTA register = 1 for High speed
    //    SPBRGH = 0x00;
    //   SPBRGL = 32; // assume 4 MHz Internal Osc, setup baud rate for 9600
                // http://www.microcontrollerboard.com/pic_serial_communication.html#EnabComm
    SPBRG=100;           // sets Baud Rate for RS232 serial data

    // *** I2C setup START ***
    //  info from:
    //    http://www.xappsoftware.com/wordpress/2011/12/23/how-to-use-the-i2c-bus-with-pic12f1840-a-simple-library/
    //    http://www.hobbytronics.co.uk/hi-tech-c-i2c-master
    //
    ANSELA = 0b00000000;    // no analog input

    SSP1ADD = 39;         // baud rate =  50 khz    SSP1ADD = 79 , Baud rate = 100Khz SPP1ADD = 39 Baud rate 400Khz SSP1ADD = 9

    SSP1STAT    = 0x80  ;     // slew rate dis  8 , SMBUS disabled

    SSPCON1 = 0b00101000; // I2C enabled, Master Mode

    SSPCON2 = 0b00000000;

    // *** I2C setup END ***



    int c = 1;

    unsigned char send_ack = 1;            // send_ack s/b 1 if more data, 0 if last data
    int data_read[4];

    // send a string
    while (1) {
    printf("Hello World  ");  // see if the board is running
    printf("%d\r\n", c);

    c++;

    //delayzz();

//  *** I2C Communication START ***

    i2c_Start();              // start I2C comms
 //   i2c_Restart();
 //   i2c_Write("D");         // send a character


//  Measurement Request
    i2c_Address(0x27, 0);   // address 27 hex, mode 0
    i2c_Stop();
    delayzz();

/*
// Humidity Data Fetch, Two Bytes
    i2c_Start();
    i2c_Address(0x27, 1);
    send_ack = 0;
    data_read[0] = i2c_Read(send_ack);
    send_ack = 1;
    data_read[1] = i2c_Read(send_ack);
    printf("Data Read, %d\r\n", data_read[0]);
    printf("Data Read, %d\r\n", data_read[1]);

 */


//  Humidity and Temp Data Fetch, Four Bytes
    i2c_Start();
    i2c_Address(0x27, 1);   // address 27 hex, mode 1
    int i = 0;              // iterator
    unsigned char send_ack = 1;            // send_ack s/b 1 if more data, 0 if last data
    for (i=0; i<4; i++) {
        if ( i == 3 )
            send_ack = 0;
        data_read[i] = i2c_Read(send_ack);
    
    }

//  Print out data read
    for (i=0; i<4; i++) {
    printf("Data Read, %d %d 0x%0X\r\n", i, data_read[i], data_read[i]);
    }

// Convert array into humidity and temperature
    //use a 32 bit value here so that scaling arithmetic does not overflow
    unsigned long humidity;
    humidity = data_read[1] | data_read[0]<<8;
    
    printf("Raw Humidity:  ");
    printf("%u 0x%0lX\r\n", humidity, humidity);
    
    //use a 32 bit value here so that the scaling arithmetic does not underflow
    unsigned long scaled_humidity = ((humidity*100) / ( 16383 ));
    printf("Converted Humidity:  ");
    printf("%d\r\n", scaled_humidity);
    printf("\r\n");

    // temperature



    printf("data_read[2] 0x%X", data_read[2]);
    printf("\r\n");
    printf("data_read[3] 0x%X", data_read[3]);
    printf("\r\n");

    
    int temp_counts = 0;

    temp_counts = ( ( (data_read[2] & 0xFF) <<6 ) | ( (data_read[3] & 0xFC) >>2 ) & 0x3F );
    printf("temp_counts   %d\r\n ", temp_counts);
    //temperature = temperature>>2;

    //printf("Raw Temp:  ");
    //printf("%u 0x%01X\r\n", temperature, temperature);

    double temp = (165*((double)temp_counts/16383)-40);
    printf("Converted Temperature:  ");
    printf("%d\r\n", (int)temp);



    printf("\r\n");

//  Convert Humidity Data to ASCII string, transmit with printf()

    
//  Convert Temp Data to ASCII string, transmit with printf()


//  *** I2C Communication END ***
    
    delayzz();
    }


    return;
}

