Sign in

username:

password:



Not a member?

Search msp430



Search tips

Subscribe to msp430



Ads

Discussion Groups

The purpose of this group is to foster exchange of information on the Texas Instruments MSP430 family of microcontrollers and related tools. Everyone welcome, all levels of familiarity/expertise.

i2c usi - Dan Bloomquist - Aug 11 17:38:57 2008


Hi,
I got some time and have the usi doing byte streams both ways now. I was
curious if I have the optimum solution, (or missed something and didn't
need a hack), for the awk when the slave is being read.

With this method, I don't have to dissable the start interrupt or loop
till condition.

After the 8 bits are sent from my slave I set up the USISRL and one
count and output. In the TI examples they appear to break the rule as to
keeping the awk low while SCL is high, I don't see how this will work.
They set SDA to input while the clock is high and that lets the data
line go high.

What I did was to use the port interrupt in just this special case to
watch for the clock to go low before setting SDA back to input.

if( ..awk on read )
P1IFG= 0;
P1IES= BIT6;
P1IE= BIT6;
...
Am I missing something or is there a more elegant way? USI stuff below.

Thanks, Dan.

interrupt ( USI_VECTOR ) usi_interrupt( void )
{
if( USICTL1 & USISTTIFG ) // START received....
{
USICTL1&= ~USISTTIFG; // Clear START flag...
USICNT= 0x08 | USISCLREL; // Clears USISCLREL
usi_state= USISTATE_RCVADR; //Next is receive address
USICTL0&= ~USIOE;
USICTL1|= USIIE; // Enable Counter Interrupt
return;
}
if( USICTL & USISTP )//A stop condition was detected
{
initialize_i2c( );//reset USI
return;
}
//Address and r/w should be in shift reg...
if( usi_state & USISTATE_RCVADR )
{
//Is it _not_ our address?
if( USISRL >> 1 != USI_OURADDRESS )
{
usi_state= USISTATE_NULL;
initialize_i2c( );//reset USI, Wait for next start
return;
}
//else our address, get the r/w bit next
if( USISRL & 0x01 )
{
usi_state= USISTATE_WRITE | USISTATE_AWK;
usi_buf_ptr= 0xf800;
}
else
{
usi_state= USISTATE_READ | USISTATE_AWK;
usi_buf_ptr= buffer;
}
USISRL= 0;
USICNT= 0x01 | USISCLREL; //Get ready to awk
USICTL0|= USIOE; //Take SDA.
return;
}
if( usi_state & USISTATE_AWK )
{
if( usi_state & USISTATE_READ )
{
P1IFG= 0;
P1IES= BIT6;
P1IE= BIT6;
}
else
USISRL= *usi_buf_ptr++;

USICNT= 0x08 | USISCLREL;
usi_state&= ~USISTATE_AWK;
return;
}
if( usi_state & USISTATE_AWK_WRITE )
{
if( USISRL & 0X01 )
initialize_i2c( ); //Master said no more...
else
{
usi_state= USISTATE_WRITE;
USICTL0|= USIOE; //Take SDA.
USISRL= *usi_buf_ptr++;
USICNT= 0x08 | USISCLREL;
}
return;
}
//Recieve/transmit data from/to the master
if( usi_state & USISTATE_READ )
{
*usi_buf_ptr++= USISRL;

//Do awk
usi_state|= USISTATE_AWK;
USISRL= 0;
USICNT= 0x01 | USISCLREL;
USICTL0|= USIOE; //Take SDA.
return;
}
if( usi_state & USISTATE_WRITE )
{
usi_state|= USISTATE_AWK_WRITE;
USICTL0&= ~USIOE; //Release SDA.
USISRL= 0;
USICNT= 0x01 | USISCLREL;
return;
}
}

void initialize_i2c( void )
{
USICTL0= USIPE6 | USIPE7 | USISWRST;//Port, I2C slave
USICTL1= USII2C | USISTTIE; //Enable I2C mode, disable
counter
USICKCTL= USICKPL; //Setup clock polarity
USICNT= USISCLREL; //SCL released
USICTL0&= ~USISWRST; // Clear Reset of USI

//Initialize State machine and sit idle until START condition
usi_state= USISTATE_NULL;
}

interrupt ( PORT1_VECTOR ) usi_interrupt2( void )
{
P1IES= 0;
P1IE= 0;
P1IFG= 0;
USICTL0&= ~USIOE;
}

--
email: y...@lakeweb.com but drop the 'x'.
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )