/*
 * File:   newmain.c
 * Author: User
 *
 * Created on 19 ?????? 2024 ?., 14:20
 */

#include <htc.h>

#pragma config WDTE=OFF, MCLRE=OFF, FOSC=INTRCIO, CP=OFF

#define _XTAL_FREQ 4000000
#define DIO GPIO0 //pin7
#define CLK GPIO1 //pin6
#define DIOio TRISIO0 //DIO input or output 
#define min_pb GPIO2	//pin5
#define hour_pb GPIO3	//pin4
#define SDA GPIO4    //pin3
#define SCL GPIO5	//pin2
#define sdaIO TRISIO4
//prototypes
void display( unsigned char addr, unsigned char fig );
void sendData(unsigned char dataB);
void startBit(void);
void stopBit(void);
void clock(void);
void display_min();
void display_hour();
void i2cSend(unsigned char dataB);
void i2cStart(void);
void i2cStop(void);
void i2cClock(void);
void i2cCmnd( unsigned char comm);
void setTime (unsigned char reg, unsigned char setting);
unsigned char readTime (unsigned char reg);
unsigned char i2cRead();
unsigned char addr=0x78;  //0b1111000
unsigned char min, hour, minS, hourS,point=0x80;
const unsigned char  num[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0,1,2,3...9
unsigned char minL, minH, hourL, hourH;
unsigned int addr2=0xD0;  //clock write
unsigned int addr2r=0xD1;  //clock read
void main(void){

    GPIO = 0b00000000; 
    TRISIO = 0b00001100; // 
    
    ANSEL = 0; // 
    CMCON = 7; //
	
    OPTION_REG = 0;	//pullup
    SCL=1;
    SDA=1;
    CLK=1;
    DIO=1;
  display_min();
  display_hour();
    
	while(1){
 min=readTime(1);
 hour=readTime(2);
 hourL=hour & 15;
 hourH=hour>>4 & 3;
 minH=min>>4 & 7;
 minL=min & 15;
//sec=readTime(0);
            //set minutes        
        while(!min_pb){
       ++minL;
            if(minL>9){minL=0; ++minH;} 
            if(minH>5){minH=0;}
       minS=0;
            minS=(minH<<4) + minL;
            setTime(1,minS);
        display_min();
        __delay_ms(500);
        }
            //set hours
        while(!hour_pb){
         ++hourL;
            if(hourL>9){hourL=0; ++hourH;}
            if((hourH==2) && (hourL>3)){hourH=0; hourL=0;}
         hourS=0;
            hourS=(hourH<<4) + hourL;
            setTime(2,hourS);
        display_hour();
        __delay_ms(500);
        }
 // while(!hour_pb&&!min_pb){setTime(0,0x00);}
     point=0x00;
    display_min();
    display_hour();
     __delay_ms(1000);
     point=0x80;
    display_min();
    display_hour();
    __delay_ms(1000);
	}
    
}   

void display_min(){
     
    display(2,num[minH]);
    display(3,num[minL]);
}

void display_hour(){
   
    if(hourH==0){ display(0,0x00);}
    else{display(0,num[hourH]);}
    display(1,num[hourL]);
}
void sendData(unsigned char dataB)
{
    for(unsigned char b=0;b<8;b++){
       DIO=(dataB >> b) % 2;
       clock();
    }
    DIOio=1;   //make DIO input
    clock();
    __delay_us(5);
    DIOio=0;   //make DIO output

}

void clock(void)
{
   __delay_us(4);
   CLK=1;
   __delay_us(5);
   CLK=0;
   __delay_us(4);
}

void startBit(void)
{
    DIO=0;
    __delay_us(5);
    CLK=0;
}

void stopBit(void)
{
    CLK=1;
    __delay_us(5);
    DIO=1;
}

    //includes brightness and point setting.
void display( unsigned char addr, unsigned char fig ){
    unsigned char mode=0b01000100;// control=0b10001100;  //0b10001010
    unsigned char brightness=7; //brightness can be selected 0 to 7
    unsigned char control=136+brightness;
    fig=fig+point;    //0x80 is point 
    addr +=192;
    startBit();
    sendData(mode);            // command1-data 
    stopBit();
    startBit();
    sendData(addr);            // command2-address
    sendData(fig);
    stopBit();
    startBit();
    sendData(control);             // command3-control
    stopBit();
}
unsigned char readTime (unsigned char reg){
    unsigned char date;
    i2cStart();
    i2cSend(addr2);
    i2cSend(reg);   //3231 reg
    i2cStart(); //restart
    i2cSend(addr2r);
    date=i2cRead();
    i2cStop();
    return date;
}

void setTime (unsigned char reg, unsigned char setting){
    i2cStart();
    i2cSend(addr2);
    i2cSend(reg);   //3231 reg
    i2cSend(setting);
    i2cStop();
}

//Software I2C
void i2cSend(unsigned char dataB){
    for(unsigned char b=0;b<8;b++){
        SDA=(dataB >> (7-b)) % 2;
        i2cClock();
    }
    sdaIO=1;   //SDA input
    i2cClock(); //ack
    __delay_us(10);
    sdaIO=0;   //SDA output
    __delay_us(10); //50
}
 
unsigned char i2cRead(){
    unsigned char x=0;
    
    sdaIO=1;   //SDA input
    for(unsigned char b=0;b<8;b++){
        SCL=0; 
        __delay_us(5);
        SCL=1;
        __delay_us(5);
        x=x+(SDA<<(7-b));
        SCL=0;
        __delay_us(5);

    }
    sdaIO=0;   //SDA output
    SDA=1;  //send nack
    i2cClock();
    __delay_us(10);
    return x;

}
void i2cClock(void){
   SCL=0; 
   __delay_us(5);
   SCL=1;
   __delay_us(5);
   SCL=0;
   __delay_us(5);
}

void i2cStart(void){
    SDA=1;
    //__delay_us(5);
    SCL=1;
    __delay_us(10);
    SDA=0;
    __delay_us(10);
    SCL=0;
    __delay_us(10); //50
    
}

void i2cStop(void){
    SCL=1;
    SDA=0;
    __delay_us(10); //50
    SDA=1;
}
