please dont rip this site

TI MSP430 Microcontroller I2C Bit Bang Master

I2C Master Bit Banged code from Dan Bloomquist as posted to msp430@yahoogroups.com

I2C_master.h


//I2C_Master.h

/*
use i2cm_out(...) and i2cm_in(...) between calls to i2cm_start(...) and i2cm_stop(...)

typical use(...) 
{
//this is an example of reading the config register of a DS1631
//in this case 'device' is a select number of 0000xxx0

	i2cm_start( );
	
	if( i2cm_out( 0x90 | device ) ) //send write control byte
		return;
	
	else if( i2cm_out( 0xac ) )//send config command byte
		return;
	
	i2cm_start( );//device wants start again to read
	
	if( i2cm_out( 0x91 | device ) ) //send read control byte
		return;
	
	i2cm_in( buf, 1 ); //input the config byte to 'buf'

	i2cm_stop( );
	//device was not busy or failed...
	//set sucsess flag if needed before return
	
} typical use end......

i2cm_out(...) returns true if device did not ack output byte
with mspgcc compiled for optimum code size this is about 256 bytes

*/

//Defines the port to be used
#define I2C_MASTER_REN P1REN
#define I2C_MASTER_DIR P1DIR
#define I2C_MASTER_OUT P1OUT
#define I2C_MASTER_IN  P1IN
//port pins
#define IC2_MASTER_SCL BIT2
#define I2C_MASTER_SDA BIT3

//Declarations
//sends a start condition
//will set sda and scl high and delay before start
void i2cm_start( void );

//send stop condition
//will set sda low before delay and stop
void i2cm_stop( void );

//Output one byte
//assumes sda and scl low and leaves sda, scl low if ack.
//returns true if no ack from device
unsigned char i2cm_out( register unsigned int data );

//input count of bytes into buf[ ]
//Assumes scl low and leaves scl low
//sends ack to device until last byte then no ack
void i2cm_in( unsigned char* buf, int count );


I2C_Master.C


#include  <msp430x11x1.h>
#include "I2C_master.h"

static void __inline__ brief_pause( register unsigned int n )
{
__asm__ __volatile__ (
		"1: \n"
		" dec %[n] \n"
		" jne 1b \n" : [n] "+r"(n)
		);
}

//Send data byte out on bang i2c, return false if ack
//Assumes start has been set up or a next byte
//so  both lines are assumed low
// **Lower byte of data is sent**
unsigned char i2cm_out( register unsigned int data )
{
	volatile unsigned int i= 0; //will be register
	//output eight bits of 'data'
	for( ; i < 8; ++i )
	{
		//send the data bit
		if( data & 0x80 )
			I2C_MASTER_OUT|= I2C_MASTER_SDA;
		else
			I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
		
		//Set Clock High
		I2C_MASTER_OUT|= IC2_MASTER_SCL;
		
		//Set Clock Low
		brief_pause( 0x04 );
		I2C_MASTER_OUT&= ~IC2_MASTER_SCL;
		
		//shift next data bit
		data= data << 1;
	}

	I2C_MASTER_DIR&= ~I2C_MASTER_SDA;

	//Set Clock High
	I2C_MASTER_OUT|= IC2_MASTER_SCL;

	//get the ack bit and leave sda in last state
	unsigned char ack= I2C_MASTER_IN & I2C_MASTER_SDA;
	if( ack )
		I2C_MASTER_OUT|= I2C_MASTER_SDA;
	else
		I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
	
	//take the pin back for output
	I2C_MASTER_DIR|= I2C_MASTER_SDA;

	//Set Clock Low
	I2C_MASTER_OUT&= ~IC2_MASTER_SCL;

	return ack;
}

//Assumes the IC2_MASTER_SCL is low
void i2cm_in( unsigned char* buf, int count )
{
	unsigned char data;
	for( ; count--; )
	{
		data= 0;
		I2C_MASTER_DIR&= ~I2C_MASTER_SDA;
		volatile unsigned int i= 0;
		for( ; i < 8; ++i )
		{
			//Set Clock High
			I2C_MASTER_OUT|= IC2_MASTER_SCL;
			
			//shift the bit over
			data= data << 1;
		
			if( I2C_MASTER_IN & I2C_MASTER_SDA )
				data|= 0x01;
			
			//Set Clock Low
			I2C_MASTER_OUT&= ~IC2_MASTER_SCL;
		}
		//put the input data byte into the buffer, inc buffer pointer
		*buf++= data;
		
		//No Ack after last byte
		if( count )
			I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
		else
			I2C_MASTER_OUT|= I2C_MASTER_SDA;

		//take sda to output ack
		I2C_MASTER_DIR|= I2C_MASTER_SDA;

		//Set Clock High
		I2C_MASTER_OUT|= IC2_MASTER_SCL;
		
		//Set Clock Low
		brief_pause( 0x04 );
		I2C_MASTER_OUT&= ~IC2_MASTER_SCL;
	}
}

void i2cm_start( void )
{
	I2C_MASTER_OUT|= I2C_MASTER_SDA;
	I2C_MASTER_OUT|= IC2_MASTER_SCL;
	
    brief_pause( 0x20 );
	I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
	
    brief_pause( 0x20 );
	I2C_MASTER_OUT&= ~IC2_MASTER_SCL;
}

//Assumes the clock is low
void i2cm_stop( void )
{
	I2C_MASTER_OUT&= ~I2C_MASTER_SDA;
	
    brief_pause( 0x20 );
	I2C_MASTER_OUT|= IC2_MASTER_SCL;
	
    brief_pause( 0x20 );
	I2C_MASTER_OUT|= I2C_MASTER_SDA;
}

Questions:


file: /Techref/ti/msp430/iic-mm-db.htm, 5KB, , updated: 2013/5/30 13:49, local time: 2024/11/24 22:48,
TOP NEW HELP FIND: 
18.225.175.230:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://massmind.org/techref/ti/msp430/iic-mm-db.htm"> TI MSP430 Microcontroller I2C Bit Bang Master</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 

Welcome to massmind.org!

 

Welcome to massmind.org!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .