/*
 * File:   I2CPractice.c
 * Author: Matthew Domenech
 *
 * Created on February 7, 2018, 4:26 PM
 */

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <math.h>
#include "SDlib16.h"
#include "SDlib16_LCD.h"
#include "math.h"
#include "./configbits-16ex8.h"


/*I2C Misc Notes
 * SDA = Data Line || SCL = Clock Signal
 *  Start: Master signals a transition start by making SDA go low while SCL is high
 *  Stop: Master signals end of transmission by making SDA go high while SCL is high
 *  Repeated Start: Same bit transitions as start, but tells slave to watch for a new device address byte
 *
 * Whoever is sending data is in control of SDA line.
 * I2CxTRN is where transmit data is sent.  Can only be written to when bus is Idle
 *
 * This code controls the SLAVE ONLY. Master is an Arduino
 */

unsigned short I2Crx_buffer;
int data = 5;      //data variable
int dIndex; 
int check_RW;   //holds read/write bit
int check_DA;
int read_write;   //enter into read_write loop when == 1
int test_data = 1;  //dummy data to test program
int address = 0x05;   //address of the PIC32
int interruptcheck = 0;

#define Read_Write I2C3STATbits.R_W
#define Data_Addr  I2C3STATbits.D_A
#define interruptcheck IFS0bits.I2C3SIF

int main(void) {
    //TRISD = 0;  //Set all D pins as outputs.  Used for debugging with a logic analyzer.
    //LATD = 0;   //Initialize all D pins to zero. Used for debugging.
    //I2C Initialization
    IEC0bits.I2C3SIE = 1;
    IEC0bits.I2C3MIE = 1;
    I2C3CONbits.A10M = 0; //sets I2CxADD to 7 bit address mode
    I2C3ADD = address; //first set address of slave to 0000000 in binary
    I2C3CONbits.ON = 1;
    //Infinite Loop
    while(1){
            
        if ((interruptcheck == 1) && (Read_Write == 0) && (Data_Addr == 0)){
             //(0)INPUT from Master  (0) ADDRESS bit
            //if(IFS0bits.I2C3MIF == 1){  //interrupt if address matches
                I2Crx_buffer = I2C3RCV; //do a dummy read
                //delay_ms(1);    //1ms delay            
                I2C3CONbits.SCLREL = 1; //release clock
            //}
        }
        else if ((interruptcheck == 1) && (Read_Write == 0) && (Data_Addr == 1)){
         //(0)INPUT from Master       (1) DATA bit
            //if(I2C3STATbits.ACKSTAT == 0){  //if ACK recieved
                data = I2C3RCV; //get data from receive buffer
                //delay_ms(1);    //1ms delay
                I2C3CONbits.SCLREL = 1; //release clock
            //}
        }
        else if ((interruptcheck == 1) && (Read_Write == 1) && (Data_Addr == 0)){
         //(1)OUTPUT from Slave       (0) ADDRESS bit
            //if(IFS0bits.I2C3MIF == 1){
                I2C3CONbits.SCLREL = 0;
                I2Crx_buffer = I2C3RCV; //do a dummy read
                I2C3TRN = data; //load transmit buffer with test data
                delay_ms(5);    //1ms delay
                I2C3CONbits.SCLREL = 1; //release clock
                dIndex = 0;
                
            //}
        }
        else if ((interruptcheck == 1) && (Read_Write == 1) && (Data_Addr == 1)){
         //(1)OUTPUT from Slave       (1) DATA bit

            if (dIndex == 0) {
                I2C3TRN = data; //load transmit buffer with test data
                delay_ms(5);    //1ms delay
                I2C3CONbits.SCLREL = 1;
                dIndex++;
            }
            //interruptcheck = 0;
        }
        if(I2C3STATbits.ACKSTAT == 1){ //1 means ACK not recieved, no more data required.
            
        }
    }
}
     //read_write = 0;
    //this next part loops forever
    /*while(1){
        if (I2C1RCV == 0b00000001 || I2C1RCV == 0b00000000){    //check if address received matches slave address
            check_RW = I2C1STATbits.R_W;    //check read (1) write (0) bit
            check_DA = I2C1STATbits.D_A;    //check if last bit was data (1) or address (0)
            read_write = 1;
            while (read_write) {

                switch (check_RW) {  //Read/Write switch case

                    case 0: //write bit enabled. GET DATA FROM MASTER
                        rx_buffer = I2C1RCV; //get data from receive buffer
                        //delay_ms(1);    //1ms delay
                        I2C1CONbits.SCLREL = 1; //release clock
                        dummy = rx_buffer;
                        read_write = 0;
                        break;

                    case 1: //read bit enabled. SEND DATA TO MASTER

                        I2C1TRN = dummy; //load transmit buffer with test data

                        if(I2C1STATbits.TBF){ //if transmit buffer is full
                            dummy = dummy+5;
                        }
                        delay_ms(5);    //5ms delay
                        //Need Delay here?
                        I2C1CONbits.SCLREL = 1;
                        //dummy = I2C1TRN;

                        read_write = 0;
                        break;
                }
                
                if (I2C1STATbits.ACKSTAT = 0) { //if acknowledged, then do not exit switch case and go back to idle
                    read_write = 1;
                    //dummy = dummy+5
                }
            }
        }
        else{

        }
    }

    return (EXIT_SUCCESS);
}
*/
