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.
MSP430F2617 I2C Repeated Start - stefan_huseyinoff - Sep 13 22:51:32 2009
Hi All,
I need a little help implementing I2C code to use repeated starts on a MSP430F2617. I
have read the app note SLAA382, but this only give examples of simple write and reads. I
have used this code successfully to read and write to an FRAM. This worked fine by using
the start of a write command to set the FRAM internal address, then not actually write any
data. Issuing a read command immediately after then works well.
However now I am wanting to read a device which requires a repeated start after sending a
write command to read.
I would like to use the USCI peripheral rather than bit bang it.
Any help or guidance would be greatly appreciated.
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: MSP430F2617 I2C Repeated Start - tintronic - Sep 14 16:07:06 2009
I might be wrong, but aren't both cases exactly the same? You issue a start, send a write
command to set the internal memory pointer, then issue a start again with a read command
and start reading data.
Or do you need to issue a stop in the first case but not in the second?
Anyway, in both cases, after sending the write command and address, you need to write the
buffer with the next byte you want to send, at which time you can choose to issue a start,
right? It is quite black on white in the User's Guide. I quote: "Setting UCTXSTT will
generate a repeated START condition. In this case, UCTR may be set or cleared to configure
transmitter or receiver, and a different slave address may be written into UCBxI2CSA if
desired."
You need to read the USCI I2C chapter again, from top to bottom. That quote alone might
not do much sense without the context.
Michael K.
--- In m...@yahoogroups.com, "stefan_huseyinoff"
wrote:
>
> Hi All,
>
> I need a little help implementing I2C code to use repeated starts on a MSP430F2617. I
have read the app note SLAA382, but this only give examples of simple write and reads. I
have used this code successfully to read and write to an FRAM. This worked fine by using
the start of a write command to set the FRAM internal address, then not actually write any
data. Issuing a read command immediately after then works well.
>
> However now I am wanting to read a device which requires a repeated start after sending
a write command to read.
>
> I would like to use the USCI peripheral rather than bit bang it.
>
> Any help or guidance would be greatly appreciated.
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: MSP430F2617 I2C Repeated Start - stefan_huseyinoff - Sep 14 19:24:30 2009
I have read the chapter many times over, while attempting to modify the sample code
contained in SLAA382. Using the same technique to read the FRAM device does not work as I
read back 0xFF all the time.
The data sheet specifies the new IC requires a repeated start to read the device. From my
understanding to perform a repeated start condition I would need to do the following. Set
up the USCI as a transmitter to transmit 1 byte. This will send the slave address with
the write bit, followed by the command code. Then rather than sending a stop bit, I then
have to reconfigure the USCI as a receiver, send another start bit, which will then send
the slave address and the read bit, followed by the required clocks to receive the
data.
The sample code contained in SLAA382 has the USCI TX interrupt send the stop command after
sending the last byte ( if (byteCtr == 0) ). I have tried clearing the UCTR bit here and
setting the UCTXSTT bit which did not work.
I also tried commenting out the stop command in the interrupt and used the following
sequence of TI sample functions with no success.
TI_USCI_I2C_transmitinit(SLAVE_ADDRESS,I2C_SPEED);
while ( TI_USCI_I2C_notready() );
TI_USCI_I2C_transmit(1,array); // send command code
while ( TI_USCI_I2C_notready() ); // interrupt stop bit removed
TI_USCI_I2C_receiveinit(SLAVE_ADDRESS,I2C_SPEED);
while ( TI_USCI_I2C_notready() );
TI_USCI_I2C_receive(2,store);
while ( TI_USCI_I2C_notready() );
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: MSP430F2617 I2C Repeated Start - tintronic - Sep 15 16:06:30 2009
I think your problem is trying to adapt TI's code to your case. You can't just try to put
a call here and comment an instruction there.
I don't think you understand the program flow of TI's example code.
I recommend you forget about interrupts and make a program to exclusively learn to handle
the USCI I2C hardware for the I2C slave at hand. Then you can go back to TI code and
modify it accordingly. Write a well ordered sequential program, without so many functions
to jump into and back from.
I tell you this because many years ago I also had trouble when I tried to modify an I2C
code for the MSP USART to meet another I2C slave requirements. It too used interrupts and
trying to make it work was a pain.
Regards,
Michael K.
--- In m...@yahoogroups.com, "stefan_huseyinoff"
wrote:
>
> I have read the chapter many times over, while attempting to modify the sample code
contained in SLAA382. Using the same technique to read the FRAM device does not work as I
read back 0xFF all the time.
>
> The data sheet specifies the new IC requires a repeated start to read the device. From
my understanding to perform a repeated start condition I would need to do the following.
Set up the USCI as a transmitter to transmit 1 byte. This will send the slave address
with the write bit, followed by the command code. Then rather than sending a stop bit, I
then have to reconfigure the USCI as a receiver, send another start bit, which will then
send the slave address and the read bit, followed by the required clocks to receive the
data.
>
> The sample code contained in SLAA382 has the USCI TX interrupt send the stop command
after sending the last byte ( if (byteCtr == 0) ). I have tried clearing the UCTR bit
here and setting the UCTXSTT bit which did not work.
>
> I also tried commenting out the stop command in the interrupt and used the following
sequence of TI sample functions with no success.
>
> TI_USCI_I2C_transmitinit(SLAVE_ADDRESS,I2C_SPEED);
> while ( TI_USCI_I2C_notready() );
> TI_USCI_I2C_transmit(1,array); // send command code
> while ( TI_USCI_I2C_notready() ); // interrupt stop bit removed
>
> TI_USCI_I2C_receiveinit(SLAVE_ADDRESS,I2C_SPEED);
> while ( TI_USCI_I2C_notready() );
> TI_USCI_I2C_receive(2,store);
> while ( TI_USCI_I2C_notready() );
>
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )Re: MSP430F2617 I2C Repeated Start - stefan_huseyinoff - Sep 18 2:48:10 2009
Thanks for your input here, but that is essentially what I am doing. I am running bare
bones code using the TI code samples to get the IC2 bus functioning as I would expect.
Using the USCI requires the use of USCI interrupts to send and receive the data, there is
no other way around that.
A repeated start requires sending a start event again, as opposed to the stop condition
the sample code sends for a basic write. So that is why I started by commenting out the
stop command.
I have made progress with this problem and found that that I was not enabling the RX
interrupt after sending repeated start.
#pragma vector = USCIAB1TX_VECTOR
__interrupt void USCIAB1TX_ISR(void)
{
if (UC1IFG & UCB1RXIFG){
if ( byteCtr == 0 ){
UCB1CTL1 |= UCTXSTP; // I2C stop condition
*TI_receive_field = UCB1RXBUF;
TI_receive_field++;
}
else {
*TI_receive_field = UCB1RXBUF;
TI_receive_field++;
byteCtr--;
}
}
else {
if (byteCtr == 0){
//UCB1CTL1 |= UCTXSTP; // I2C stop condition - DON'T WANT THIS
UC1IFG &= ~UCB1TXIFG; // Clear USCI_B0 TX int flag
byteCtr = 0; // set counter to RX two bytes
UCB1CTL1 &= ~UCTR; // set USCI to RX mode
UCB1CTL1 |= UCTXSTT; // send repeated start
UC1IE |= UCB1RXIE; // enable RX interrupt
}
else {
UCB1TXBUF = *TI_transmit_field;
TI_transmit_field++;
byteCtr--;
}
}
}
This code is still a massive work in progress still requires some heavy modification to
allow for all manners of I2C read and writes. I was just wondering if there was something
already available from TI that caters for all the scenarios ie repeated start reads,
single byte read/write, block read/write etc.
------------------------------------

(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )
Re: Re: MSP430F2617 I2C Repeated Start - Joe Radomski - Sep 18 3:08:51 2009
you do not need interrupts to use the USCI modules... you can poll the need=
ed bits..
=A0
--- On Fri, 9/18/09, stefan_huseyinoff
wrote:
From: stefan_huseyinoff
Subject: [msp430] Re: MSP430F2617 I2C Repeated Start
To: m...@yahoogroups.com
Date: Friday, September 18, 2009, 2:47 AM
=A0=20
Thanks for your input here, but that is essentially what I am doing. I am r=
unning bare bones code using the TI code samples to get the IC2 bus functio=
ning as I would expect. Using the USCI requires the use of USCI interrupts =
to send and receive the data, there is no other way around that.
A repeated start requires sending a start event again, as opposed to the st=
op condition the sample code sends for a basic write. So that is why I star=
ted by commenting out the stop command.
I have made progress with this problem and found that that I was not enabli=
ng the RX interrupt after sending repeated start.
#pragma vector =3D USCIAB1TX_VECTOR
__interrupt void USCIAB1TX_ISR( void)
{
if (UC1IFG & UCB1RXIFG){
if ( byteCtr =3D=3D 0 ){
UCB1CTL1 |=3D UCTXSTP; // I2C stop condition
*TI_receive_ field =3D UCB1RXBUF;
TI_receive_field+ +;
}
else {
*TI_receive_ field =3D UCB1RXBUF;
TI_receive_field+ +;
byteCtr--;
}
}
else {
if (byteCtr =3D=3D 0){
//UCB1CTL1 |=3D UCTXSTP; // I2C stop condition - DON'T WANT THIS
UC1IFG &=3D ~UCB1TXIFG; // Clear USCI_B0 TX int flag
byteCtr =3D 0; // set counter to RX two bytes
UCB1CTL1 &=3D ~UCTR; // set USCI to RX mode
UCB1CTL1 |=3D UCTXSTT; // send repeated start
UC1IE |=3D UCB1RXIE; // enable RX interrupt
}
else {
UCB1TXBUF =3D *TI_transmit_ field;
TI_transmit_ field++;
byteCtr--;
}
}
}
This code is still a massive work in progress still requires some heavy mod=
ification to allow for all manners of I2C read and writes. I was just wonde=
ring if there was something already available from TI that caters for all t=
he scenarios ie repeated start reads, single byte read/write, block read/wr=
ite etc.
[Non-text portions of this message have been removed]
------------------------------------

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