// ------------------------- Szitkovits Gábor ---- ADXL 312 accelerometer I2C teszt ----------------
// ------------------------- Kezdet: 2012.03.20 ------ jó 2012.03.30 ? -----------------------------
// ---- Mikrovezérlő: MP430G2xx3
// ---- 
#include "io430.h"
#include "in430.h"

unsigned char rxtemp[6];
signed int x, y, z;
unsigned char rx_szam_1, rx_szam;

void i2c_init(void);
void delay_ms(volatile unsigned int t);

// -------------------- Delay ms -------------------------------------------------------------------
void delay_ms(volatile unsigned int t){       // A "t" értéke határozza meg a kéleltetés idejét
  unsigned int i;                             // "i" változó deklarálása
  for(i=0; i<t; i++){                         // "for" ciklus, ahol 1: i=0, 2: i vizsgálata 3: i=i+1
    __delay_cycles(1000);                     // 1000 uS = 1 mS
  }                    // for ciklus
}                      // void delay_ms
// -------------------- adxl312 inicializálás ------------------------------------------------------
void adxl_init(unsigned char reg, unsigned char adat){
    UCB0CTL1 |= UCTR + UCTXSTT;            // adat küldés, i2c tx, plusz start
    while (!(IFG2 & UCNACKIFG));
    UCB0TXBUF = reg;                       // regiszter
    while (!(IFG2 & UCNACKIFG));
    UCB0TXBUF = adat;                      // adat
    while (!(IFG2 & UCNACKIFG));
    UCB0CTL1 |= UCTXSTP;                   // I2C stop 
    while (UCB0CTL1 & UCTXSTP);            // Stop kész?
}                      // void 
// -------------------- adxl312 írás ---------------------------------------------------------------
void adxl_write(unsigned char reg){
    UCB0CTL1 |= UCTR + UCTXSTT;            // adat küldés, i2c tx, plusz start
    while (!(IFG2 & UCNACKIFG));
    UCB0TXBUF = reg;                       // reggiszter
    while (!(IFG2 & UCNACKIFG));
    UCB0CTL1 |= UCTXSTP;                   // I2C stop
    while (UCB0CTL1 & UCTXSTP);            // Stop kész?
}                     // void
// -------------------- adxl312 olvasás ------------------------------------------------------------
void adxl_read(void){
    rx_szam=6;                             // számláló értéke
    rx_szam_1 = rx_szam;                   // érték másolása, második számlálóba
    UCB0CTL1 &= ~UCTR;                     // adat fogadás, i2c rx
    UCB0CTL1 |= UCTXNACK + UCTXSTT;        // start plusz NACK
    __bis_SR_register(CPUOFF + GIE);       // LPM0 megszakítás
}                      // void
// -------------------- Main fügvény ---------------------------------------------------------------
void main( void ){
    
    WDTCTL = WDTPW + WDTHOLD;                // Stop WDT
    BCSCTL1 = CALBC1_1MHZ;                   // kalibrált 1MHz
    DCOCTL = CALDCO_1MHZ;
        
    P1DIR = BIT0;                            // BIT0 kimenet
    P1OUT &= ~BIT0;                          // BIT0 alacsony
    
    P1SEL |= BIT1 + BIT2;                    // P1.1 = TXD, P1.2=RXD
    P1SEL2|= BIT1 + BIT2;                    // P1.1 = TXD, P1.2=RXD
    UCA0CTL1 |= UCSSEL_2;                    // CLK = smclk
    UCA0BR0 = 104;                           // 1MHz SMCLK / 104 = ~9600 
    UCA0BR1 = 0;
    UCA0MCTL = UCBRS0;                       // Moduláció
    UCA0CTL1 &= ~UCSWRST;                    // UCA0 reset tiltás
 
    i2c_init();                              // I2C inicializálása

// -------------------- adxl312 inicializáló regiszterek/adatok küldése ----------------------------
    delay_ms(20);                     // várunk
    adxl_init(0x31,0x09);             // adxl312 data_format: full_res, 3g
    adxl_init(0x2d,0x08);             // adxl312 power_ctl: measure
    adxl_init(0x1e,0x00);             // adxl312 x tengely offset
    adxl_init(0x1f,0x00);             // adxl312 y tengely offset
    adxl_init(0x20,0xb0);             // adxl312 z tengely offset
    
    delay_ms(15);                     // várunk
// -------------------- Fő ciklus ------------------------------------------------------------------
    ///////////    Csak próba olvasás   //////////
    adxl_write(0x32);   // adxl312 tengelyek olvasási kezdőcíme /x=0x32,0x33,y=0x34,0x35,z=0x36,0x37
    adxl_read();        // kiolvasás
    
    x = rxtemp[1] << 8 | rxtemp[0];    // X érték összeállítása
    y = rxtemp[3] << 8 | rxtemp[2];    // Y érték összeállítása
    z = rxtemp[5] << 8 | rxtemp[4];    // Z érték összeállítása
    
    ///////////   próba olvasás vége   //////////

    while(1){
        P1OUT ^= BIT0;                     // ellenörző led be
        for(char i=0; i < 6; i++){         // ciklus az adat küldésre
            while (!(IFG2&UCA0TXIFG));     // üres a TX buffer? Vagy valami hasonló.
            UCA0TXBUF = rxtemp[i];         // adat küldése bluetooth-on
        }
        adxl_write(0x32);                  // adxl312 olvasási kedőcím
        adxl_read();                       // kiolvasás
        x = rxtemp[1] << 8 | rxtemp[0];    // X érték összeállítása
        y = rxtemp[3] << 8 | rxtemp[2];    // Y érték összeállítása
        z = rxtemp[5] << 8 | rxtemp[4];    // Z érték összeállítása
        delay_ms(100);                     // várunk
        P1OUT ^= BIT0;                     // ellenörző led ki
        for(char i=0; i < 6; i++){         // ism
            while (!(IFG2&UCA0TXIFG));     // ism
            UCA0TXBUF = rxtemp[i];         // ism
        }
        
        return;                           // megállunk, vizsgálódni, értékeket nézegetni, stb...

    }                         // while
}                             // main
// ---------------------I2C init -------------------------------------------------------------------
void i2c_init(void){
    P1SEL |= BIT6 + BIT7;                     // I2C pin
    P1SEL2|= BIT6 + BIT7;                     // I2C pin
    UCB0CTL1 |= UCSWRST;                      // SW reset engedélyezés
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C mód kiválasztása, I2C Master, szinkron mód
    UCB0CTL1 = UCSSEL_2 + UCSWRST;            // SMCLK,  SW rezet
    UCB0BR0 = 10;                             // SMCLK/10 = 100kHz, I2C freki
    UCB0BR1 = 0;
    UCB0I2CSA = 0x53;                         // Slave cím
    UCB0CTL1 &= ~UCSWRST;                     // reset tiltás
    IE2 |= UCB0RXIE;                          // rx megszakítás engedélyezése
}                      // void i2c init
// -------------------------------------------------------------------------------------------------
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void){
    
    if(rx_szam_1 > 0){                                // ha rx_szam_1 nagyobb mint nulla
        rxtemp[rx_szam - rx_szam_1] = UCB0RXBUF;      // rxtemp-be rx buffer tartalma
        rx_szam_1--;                                  // rx_szam - 1
    }
    else if(rx_szam_1 == 0){                          // ha rx_szam_1 nulla i2c stop

        UCB0CTL1 |= UCTXSTP;                   // I2C stop 
        while (UCB0CTL1 & UCTXSTP);            // Stop kész?
        IFG2 &= ~UCB0RXIFG;                    // rx flag törlése
        __bic_SR_register_on_exit(CPUOFF);     // Ébresztő
    } 
}
