Subversion Repositories FlightCtrl

Rev

Blame | Last modification | View Log | RSS feed

/**************************************************************************************************************************************
* File:                 twimaster.c
*
* Purpose:              controlling I2C
*
* Functions:    int     void i2c_init(void)
*                               void i2c_reset(void)
*                               void i2c_start(void)
*                               void i2c_stop(void)
*                               void i2c_write_byte(unsigned char byte)
*                               void I2C_ReceiveByte(void)
*                               void I2C_ReceiveLastByte(void)
*                               ISR(TWI_vect)
*
* hardware:             AVR-Ctrl experimental board without LCD display as I2C bus is used
*
* Created:              Feb 2013
*
* Version:              1.00    experimental version
*
* Copyright:    (c)2013 dk9nw -at- darc.de
*                               All rights reserved. This software is available only for non-commercial amateur radio or educational applications.  
*                               Other uses are prohibited. This software may be modified only if
*                               the resulting code be made available publicly and the original author(s) given credit.
*
******************************************************************************************************************************************/

#include "twimaster.h"

unsigned char twi_state = 0;
volatile unsigned char Motor[4];                                // turn rate of the connected electrical motor 0 - 255


// **************************************************************************************************************************
//      initialize the I2C Bus (TWI)                        
//
void i2c_init(void)
{
        static unsigned char sreg;
        sreg = SREG;                                                            // save backup status register , to be reseted later
        cli();                                                                          // switch off I-Bit Global Interrupt
       
        //--------------------------------------------------------------------------------------------------------------------
        // TWSR = TWI Status Register containing: TWS7 TWS6 TWS5 TWS4 TWS3 – TWPS1 TWPS0
        // -------------------------
        // TWPS: TWI Prescaler Bits
        //
        TWSR &= ~((1<<TWPS1)|(1<<TWPS0));                       // TWI Status Register Bits 1..0 – TWPS: TWI Prescaler Bits 00=1:1 01=1:4 10=1:16 11=1:64
       
        //--------------------------------------------------------------------------------------------------------------------
        // TWBR = TWI Bit Rate Register containing: TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0
        // set TWI Bit Rate Register                            // SCL_frequency = ( CPU_Clock_frequency / ( 16 + 2 * TWBR ) * 4**TWPS )
        //                                                                                      //
        TWBR = ((SYSCLK/SCL_CLOCK)-16)/2;                       // TWI Bit Rate (formula is only valid if TWSR=0)

        twi_state       = 0;

        i2c_start();
       
        SREG = sreg;                                                            // write back to old state,
        sei();                                                                          // Interrupt is activated again
}
// **************************************************************************************************************************



// **************************************************************************************************************************
//      reset I2C Bus
//
void i2c_reset(void)
{      
        i2c_stop();                                                                     // stop i2c Bus
        twi_state = 0;
        TWCR = (1<<TWINT);                                              // reset to original state incl. interrupt flag reset
        TWAR = 0;
        TWDR = 0;
        TWSR = 0;
        TWBR = 0;
        i2c_init();                                                                     // initialize the I2C Bus (TWI)  
        i2c_start();
        i2c_write_byte(0);
}
// **************************************************************************************************************************



// **************************************************************************************************************************
//      start of I2C Bus
//
void i2c_start(void)
{
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
        // --------------------------------------------------------------------
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag .
        // TWSTA = TWI start and should be set to one, that TWI is started as Master.
        // TWEN = TWI enable -> now TWI/I2C is working  properly.
        // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set
        TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)|(1<<TWIE);
       
        //while( !(TWCR & (1<<TWINT) ) );       // wait, that TWINT is zero again, that means that the start conditions have been transferred
}
// **************************************************************************************************************************



// **************************************************************************************************************************
//      stop the I2C Bus
//
void i2c_stop(void)
{
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
        // --------------------------------------------------------------------
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag .
        // TWSTO TWI STOP Condition Bit (TWSTO = 1) -> now will be stoped
        // TWEN = TWI enable -> now TWI/I2C is working  properly.
        TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
// **************************************************************************************************************************




// **************************************************************************************************************************
//      Write to I2C                      
//
void i2c_write_byte(unsigned char byte)
{
        //TWSR = 0x00;                                                                  // TWI Status Register
       
        TWDR = byte;                                                                    // move byte to send into TWI Data Register
       
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
        // --------------------------------------------------------------------
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag .
        // TWEN = TWI enable -> now TWI/I2C is working  properly.
        // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set
        //
        TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);
}
// **************************************************************************************************************************



// **************************************************************************************************************************
//      Receive byte and send ACK
//
void I2C_ReceiveByte(void)
{
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
        // ---------------------------------------------------------------------------
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag .
        // TWEA = TWI Acknowledge Bit (TWEA = 1)
        // TWEN = TWI enable -> now TWI/I2C is working  properly.
        // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set
        //
        TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE) ;
}
// **************************************************************************************************************************



// **************************************************************************************************************************
//      I2C receive last byte and send no ACK
//
void I2C_ReceiveLastByte(void)
{
        // TWCR = TWI Control Register -> TWINT TWEA TWSTA TWSTO TWWC TWEN – TWIE
        // ---------------------------------------------------------------------------
        // TWINT = TWI interrupt flag - to be set to one, to reset the TWINT Flag .
        // TWEN = TWI enable -> now TWI/I2C is working  properly.
        // TWIE = TWI Interrupt enable is the TWIE Bit -> should be set
        //
        TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE);
}
// **************************************************************************************************************************



// **************************************************************************************************************************
// Interrupt I2C
//---------------------------------------------------------------------------------------------------------------------------
ISR(TWI_vect)
{
        switch(twi_state++)
        {
                //-------------------------------------------------------------------------------------------------------------------
                //      write Motor-Data to BL-Ctrl
                //-------------------------------------------------------------------------------------------------------------------
                case 0:
                        i2c_write_byte(0x52);  
                break;
               
                case 1:
                        i2c_write_byte(Motor[0]);
                break;
               
                case 2:
                        i2c_stop();
                        i2c_start();
                break;
               
                case 3:
                        i2c_write_byte(0x54);  
                break;
               
                case 4:
                        i2c_write_byte(Motor[1]);
                break;
               
                case 5:
                        i2c_stop();
                        i2c_start();
                break;
               
                case 6:
                        i2c_write_byte(0x56);  
                        break;
               
                case 7:
                        i2c_write_byte(Motor[2]);
                break;
               
                case 8:
                        i2c_stop();
                        i2c_start();
                break;
               
                case 9:
                        i2c_write_byte(0x58);  
                        break;
               
                case 10:
                        i2c_write_byte(Motor[3]);
                break;
               
                case 11:
                        i2c_stop();
                        twi_state = 0;
                        i2c_start();
                break;
               
                default:
                        twi_state = 0;
                break;        
        }
}
// EOF ISR(TWI_vect) *****************************************************************************************************