// --------- Szitkoivts Gábor 2012.05.29- ----------------------------------------------------------
// ------------------------g2xx2 - I2C kommunikáció pcf8574-el -------------------------------------

#include "io430.h"
#include "in430.h"
#include "stdint.h"

void i2c_init(void);
void i2c_start(void);
void i2c_stop(void);
uint8_t i2c_write_byte(uint8_t byte);
uint8_t i2c_read_byte(void);
void i2c_ack(char ack);
uint8_t i2c_slave_cim(uint8_t scim, char olvas);

char adat;

void main(void){
    
    WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog
    BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
    DCOCTL = CALDCO_1MHZ;
    
    i2c_init();
    
    while(1){

        i2c_start();                // i2c start
        
        i2c_slave_cim(0x20,1);      // slave cím, olvas(1) vagy ír(0)
        
        adat = i2c_read_byte();     // pcf-rő beolvasott érték
        
        i2c_ack(1);                 // ACK küldés
        
        i2c_stop();
    }
}
void i2c_init(void){
    USICTL0 = USIPE7 + USIPE6 + USIMST + USIOE + USISWRST;
    // master mód, adat ki engedélyezés, P1.6 SCL P1.7 SDA engedélyezés, szoftveres reset
    USICKCTL = USIDIV_7 + USISSEL_2 + USICKPL;                // óra=SMCLK/64
    USICTL1 = USII2C;                                         // I2C mód
    USICTL0 &= ~USISWRST;                                     // reset
    USICTL1 &= ~(USIIFG + USISTTIFG);
}
void i2c_start(void){
    USISRL = 0xFF;
    USICTL0 |= USIGE;
    USICTL0 &= ~(USIGE + USIOE);  
    __delay_cycles(100);
    USISRL = 0x00;
    USICTL0 |= USIGE + USIOE;
    USICTL0 &= ~USIGE;
}
void i2c_stop(void){
    USICTL0 |= USIOE;
    USISRL = 0x00;
    USICNT = 1;
    while((USICTL1 & USIIFG) != 0x01);      // várunk míg USIIFG, egy nem lesz
    USISRL = 0xFF;
    USICTL0 |= USIGE;
    USICTL0 &= ~(USIGE + USIOE);
}
uint8_t i2c_write_byte(uint8_t byte){
    USICTL0 |= USIOE;
    USISRL = byte;
    USICNT = (USICNT & 0xE0) + 8;
    while((USICTL1 & USIIFG) != 0x01);      // várunk míg USIIFG, egy nem lesz
// ------------------------ NACK/ACK ellenőrzés -------------------------------
    USICTL0 &= ~USIOE;
    USICNT = (USICNT & 0xE0) + 1;
    while((USICTL1 & USIIFG) != 0x01);      // várunk míg USIIFG, egy nem lesz

    if(USISRL & 0x01){
	return 0;
    }
    return 1;
}
uint8_t i2c_read_byte(void){
    USICTL0 &= ~USIOE;
    USICNT = 8;
    while((USICTL1 & USIIFG) != 0x01);      // várunk míg USIIFG, egy nem lesz
    return USISRL;
}
void i2c_ack(char ack){           // (N)ACK bit küldése
    USICTL0 |= USIOE;
    if(ack){
        USISRL = 0x00;
    }
    else{
        USISRL = 0xFF;
    }
    USICNT = (USICNT & 0xE0) + 1;
    while((USICTL1 & USIIFG) != 0x01);      // várunk míg USIIFG, egy nem lesz
    USICTL0 &= ~USIOE;
}
uint8_t i2c_slave_cim(uint8_t scim, char olvas){
    scim <<= 1;
    if(olvas){
        scim |= 0x01;
    }
    return(i2c_write_byte(scim));
}