Blame |
Last modification |
View Log
| RSS feed
/**************************************************************************************************************************************
* File: twimaster.c
*
* Purpose: controlling I2C
*
* Functions: int main(void)
*
* hardware: AVR-Ctrl experimental board without LCD display as I2C bus is used
*
* Created: Jan 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) *****************************************************************************************************