EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

TI I2C Example Problems

Started by mrai...@hofferflow.com March 26, 2014
Hey Folks,

Some of you may remember I just had a problem bit-banging an i2c interface to an eeprom, Microchip

24FC1025. That problem remains unsolved, with IAR and myself continuing to work on it, but right now, I am

trying to interface with the eeprom using the TI built-in I2C USCIB2. I have been fighting to make a very

simple (I thought) TI example titled "MSP430x54x_uscib0_i2c_08". I have minimally altered the example so I

can test it on our development board and view diagnostic msgs on hyperterminal on a PC. I can send the code

if you think it is needed.

The example program takes an array of 5 unsigned chars, sets the pointer to the start of the array and

the byte counter to sizeof the array. I then reset a write protect pin and call the start condition with

UCTR set. I can tell from msgs embedded in the ISR that the isr executed 5 times. I am viewing output of

clk and data on a scope. The patterns seem normal, and the slave address is sent and it appears that I

receive an ack because the data line remains low.

The problem is that I see no scope patterns indicating data bytes have been sent. Can someone please

suggest what to try next? This is the isr:

//------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------
#pragma vector = USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
{
switch(__even_in_range(UCB2IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG

if (TXByteCtr) // Check TX byte counter
{
#if 1 // print out??
sprintf(outBuf, "ISR::%X", *PTxData);
TxBuffer(outBuf, 10, 1);
#endif // print out??

UCB2TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB2CTL1 |= UCTXSTP; // I2C stop condition
UCB2IFG &= ~UCTXIFG; // Clear USCI_B2 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
default: break;
}
}

Thanks,
Mike Raines

Beginning Microcontrollers with the MSP430

Hi,

Hey Folks,

Some of you may remember I just had a problem bit-banging an i2c interface to an eeprom, Microchip

24FC1025. That problem remains unsolved, with IAR and myself continuing to work on it, but right now, I am

trying to interface with the eeprom using the TI built-in I2C USCIB2. I have been fighting to make a very

simple (I thought) TI example titled "MSP430x54x_uscib0_i2c_08". I have minimally altered the example so I

can test it on our development board and view diagnostic msgs on hyperterminal on a PC. I can send the code

if you think it is needed.

The example program takes an array of 5 unsigned chars, sets the pointer to the start of the array and

the byte counter to sizeof the array. I then reset a write protect pin and call the start condition with

UCTR set. I can tell from msgs embedded in the ISR that the isr executed 5 times. I am viewing output of

clk and data on a scope. The patterns seem normal, and the slave address is sent and it appears that I

receive an ack because the data line remains low.

The problem is that I see no scope patterns indicating data bytes have been sent. Can someone please

suggest what to try next? This is the isr:

So, you mean that (a) there are no clocks on SCL or (b) there are clocks on SCL but SDA is stuck high/low?

Why don’t you breakpoint in the ISR, rather than using sprintf in it, and step and see what happens with the I2C signals? See what’s loaded from the pointer into the transmit register by single stepping at assembly level? And why not do something with the other subvectors – do you get an ISR from the I2C peripheral that indicates a NACK, for instance? Right now you seem to ignore these.

If you step, you’ll be able to capture what happens on a scope when the transmission data register is written…

Best regards,

-- Paul Curtis

==============================================================
Check out our new CrossWorks Technology products that include

Networking, SD/MMC storage, and handy source code packages!

TCP/IP http://goo.gl/hkmpIY Mass Storage http://goo.gl/mZ048i
Paul,
Thanks for the reply. I put a breakpoint in the isr on line:
UCB2TXBUF = *PTxData++;
Then I set up the scope and hit "go" on the debugger. I got the correct scope patterns for all 5 data bytes (if I did this 5 times) followed by the stop condition. I had thought I was not sending the data bytes because I did not see anything on my scope beyond the slave address even though I set the time period/division to 2.5 ms for a span of 25 ms.
I was feeling better about this until, suddenly now, sometimes I get no scope pattern, and the disassembly window shows software stuck on:
Add.b R5, R4

Any ideas? Of course, when this happens, the execution never returns from the isr.

Thanks again,
Mike Raines
________________________________
On 26 Mar 2014, at 19:44, Mike Raines wrote:

> I was feeling better about this until, suddenly now, sometimes I get no scope pattern, and the disassembly window shows software stuck on:
> Add.b R5, R4
>
> Any ideas? Of course, when this happens, the execution never returns from the isr.

Suspect you have an interrupt condition that you are not correctly servicing, and not clearing the flag for it, hence you reenter the interrupt service routine?

Paul.
You might want to add while(UCB2STAT & UCBUSY); before you shut down the I2C to make sure the transmission of the last byte of data has completed.

----- Original Message -----
From: m...@hofferflow.com
To: m...
Sent: Wednesday, March 26, 2014 11:21
Subject: [msp430] TI I2C Example Problems

Hey Folks,
Some of you may remember I just had a problem bit-banging an i2c interface to an eeprom, Microchip
24FC1025. That problem remains unsolved, with IAR and myself continuing to work on it, but right now, I am
trying to interface with the eeprom using the TI built-in I2C USCIB2. I have been fighting to make a very
simple (I thought) TI example titled "MSP430x54x_uscib0_i2c_08". I have minimally altered the example so I
can test it on our development board and view diagnostic msgs on hyperterminal on a PC. I can send the code
if you think it is needed.
The example program takes an array of 5 unsigned chars, sets the pointer to the start of the array and
the byte counter to sizeof the array. I then reset a write protect pin and call the start condition with
UCTR set. I can tell from msgs embedded in the ISR that the isr executed 5 times. I am viewing output of
clk and data on a scope. The patterns seem normal, and the slave address is sent and it appears that I
receive an ack because the data line remains low.
The problem is that I see no scope patterns indicating data bytes have been sent. Can someone please
suggest what to try next? This is the isr:

//------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------
#pragma vector = USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
{
switch(__even_in_range(UCB2IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG

if (TXByteCtr) // Check TX byte counter
{
#if 1 // print out??
sprintf(outBuf, "ISR::%X", *PTxData);
TxBuffer(outBuf, 10, 1);
#endif // print out??

UCB2TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB2CTL1 |= UCTXSTP; // I2C stop condition
UCB2IFG &= ~UCTXIFG; // Clear USCI_B2 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
default: break;
}
}
Thanks,
Mike Raines
Paul,

Damn, you're good! But you already knew that ( -;)
I first put a msg in each isr case and found I was entering the default case. I then put a print in the default case and got this output:
***MAIN***
ISR::11
ISR::default

***MAIN***
ISR::11
ISR::default
UCB2IV is: 0

But case 0: is no interrupts. Why didn't the switch statement go there? And what does it mean that UCB2IV is 0?

Thanks again,
Mike Raines
#pragma vector = USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
{
switch(__even_in_range(UCB2IV,12))
{
case 0:
TxBuffer("ISR::No interrupts", 20, 1);
break; // Vector 0: No interrupts
case 2:
TxBuffer("ISR::ALIFG", 20, 1);
break; // Vector 2: ALIFG
case 4:
TxBuffer("ISR::NACKIFG", 20, 1);
break; // Vector 4: NACKIFG
case 6:
TxBuffer("ISR::STTIFG", 20, 1);
break; // Vector 6: STTIFG
case 8:
TxBuffer("ISR::STPIFG", 20, 1);
break; // Vector 8: STPIFG
case 10:
TxBuffer("ISR::RXIFG", 20, 1);
break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG
if (TXByteCtr) // Check TX byte counter
{
#if 1 // print out??
sprintf(outBuf, "ISR::%X", *PTxData);
TxBuffer(outBuf, 10, 1);
#endif // print out??

DelayI2cEeprom();
UCB2TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB2CTL1 |= UCTXSTP; // I2C stop condition
UCB2IFG &= ~UCTXIFG; // Clear USCI_B2 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
default:
TxBuffer("ISR::default", 20, 1);
sprintf(outBuf, "UCB2IV is: %X", UCB2IV);
TxBuffer(outBuf, 30, 1);
break;
}
}

________________________________
From: m... [mailto:m...] On Behalf Of Paul Curtis
Sent: Wednesday, March 26, 2014 4:09 PM
To: m...
Subject: Re: [msp430] TI I2C Example Problems

On 26 Mar 2014, at 19:44, Mike Raines > wrote:
I was feeling better about this until, suddenly now, sometimes I get no scope pattern, and the disassembly window shows software stuck on:
Add.b R5, R4

Any ideas? Of course, when this happens, the execution never returns from the isr.

Suspect you have an interrupt condition that you are not correctly servicing, and not clearing the flag for it, hence you reenter the interrupt service routine?

- Paul.
size=1 width="100%" noshade color="#a0a0a0" alignter>
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2014.0.4354 / Virus Database: 3722/7248 - Release Date: 03/25/14
On 03/26/2014 01:21 PM, m...@hofferflow.com wrote:
> Hey Folks,
>
> Some of you may remember I just had a problem bit-banging an i2c
> interface to an eeprom, Microchip
>
> 24FC1025. That problem remains unsolved, with IAR and myself continuing
> to work on it, but right now, I am
>
> trying to interface with the eeprom using the TI built-in I2C USCIB2. I
> have been fighting to make a very
>
> simple (I thought) TI example titled "MSP430x54x_uscib0_i2c_08". I have
> minimally altered the example so I

I recently worked at getting the I2C USCI on the G2955 working and it
wasn't easy. I try to record some notes when I work on a project and the
notes for this one start:

"I have been beating my brain against the USCI I2C problem for a while."

I even reverted to my ancient bit banged routines just to verify that
the slave and connections were OK. I did eventually get it to work and
your interrupt code looks very much like mine:

if(IFG2 & UCB0TXIFG) // I2C transmit char interrupt
{
if (dcount == 0)
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
IE2 &= ~UCB0TXIE; // disable transmit interrupt

}
else
{
UCB0TXBUF = *datap++;
dcount--;
}
}

--
David W. Schultz
http://home.earthlink.net/~david.schultz
Returned for Regrooving



Hey everyone,

Since I have seen this issue pop up rather frequently, do you think it would
be a good idea to place some MSP430 I2C code in a repository, like Github?
That way our fellow group members wouldn't "reinventing the wheel".

Thanks,

Marty

From: "David W. Schultz"
Organization: State of Total Disorganization
Reply-To: "msp430@yahoogroups. com"
Date: Wednesday, March 26, 2014 5:04 PM
To: "msp430@yahoogroups. com"
Subject: Re: [msp430] TI I2C Example Problems

On 03/26/2014 01:21 PM, m...@hofferflow.com wrote:
> Hey Folks,
>
> Some of you may remember I just had a problem bit-banging an i2c
> interface to an eeprom, Microchip
>
> 24FC1025. That problem remains unsolved, with IAR and myself continuing
> to work on it, but right now, I am
>
> trying to interface with the eeprom using the TI built-in I2C USCIB2. I
> have been fighting to make a very
>
> simple (I thought) TI example titled "MSP430x54x_uscib0_i2c_08". I have
> minimally altered the example so I

I recently worked at getting the I2C USCI on the G2955 working and it
wasn't easy. I try to record some notes when I work on a project and the
notes for this one start:

"I have been beating my brain against the USCI I2C problem for a while."

I even reverted to my ancient bit banged routines just to verify that
the slave and connections were OK. I did eventually get it to work and
your interrupt code looks very much like mine:

if(IFG2 & UCB0TXIFG) // I2C transmit char interrupt
{
if (dcount == 0)
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
IE2 &= ~UCB0TXIE; // disable transmit interrupt

}
else
{
UCB0TXBUF = *datap++;
dcount--;
}
}

--
David W. Schultz
http://home.earthlink.net/~david.schultz
Returned for Regrooving
You know there is no break statement at the end of case 12, and that case flows straight into the default handler!

This is really where you need to invest in something that is designed for picking up errors like this. PC-lint is a neat piece of software (though I have reported a couple of bugs in it). Just get into the habit of using it to check your software, youll be amazed at what it can pick up because it is designed to do that.

I suspect, though am not completely sure, that USBIV==0 indicates that there is no interrupt pending. You entered case 12, handled the interrupt, the IV got set to zero, and you fell into the default branch.

Paul.

On 26 Mar 2014, at 20:57, Mike Raines wrote:

> Paul,
>
> Damn, youre good! But you already knew that ( -;)
> I first put a msg in each isr case and found I was entering the default case. I then put a print in the default case and got this output:
>
>
> ***MAIN***
> ISR::11
> ISR::default
>
>
>
>
>
> ***MAIN***
> ISR::11
> ISR::default
> UCB2IV is: 0
>
> But case 0: is no interrupts. Why didnt the switch statement go there? And what does it mean that UCB2IV is 0?
>
> Thanks again,
> Mike Raines
> #pragma vector = USCI_B2_VECTOR
> __interrupt void USCI_B2_ISR(void)
> {
> switch(__even_in_range(UCB2IV,12))
> {
> case 0:
> TxBuffer("ISR::No interrupts", 20, 1);
> break; // Vector 0: No interrupts
> case 2:
> TxBuffer("ISR::ALIFG", 20, 1);
> break; // Vector 2: ALIFG
> case 4:
> TxBuffer("ISR::NACKIFG", 20, 1);
> break; // Vector 4: NACKIFG
> case 6:
> TxBuffer("ISR::STTIFG", 20, 1);
> break; // Vector 6: STTIFG
> case 8:
> TxBuffer("ISR::STPIFG", 20, 1);
> break; // Vector 8: STPIFG
> case 10:
> TxBuffer("ISR::RXIFG", 20, 1);
> break; // Vector 10: RXIFG
> case 12: // Vector 12: TXIFG
>
>
> if (TXByteCtr) // Check TX byte counter
> {
> #if 1 // print out??
> sprintf(outBuf, "ISR::%X", *PTxData);
> TxBuffer(outBuf, 10, 1);
> #endif // print out??
>
> DelayI2cEeprom();
> UCB2TXBUF = *PTxData++; // Load TX buffer
> TXByteCtr--; // Decrement TX byte counter
> }
> else
> {
> UCB2CTL1 |= UCTXSTP; // I2C stop condition
> UCB2IFG &= ~UCTXIFG; // Clear USCI_B2 TX int flag
> __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
> }
> default:
> TxBuffer("ISR::default", 20, 1);
> sprintf(outBuf, "UCB2IV is: %X", UCB2IV);
> TxBuffer(outBuf, 30, 1);
> break;
> }
> }
>
> From: m... [mailto:m...] On Behalf Of Paul Curtis
> Sent: Wednesday, March 26, 2014 4:09 PM
> To: m...
> Subject: Re: [msp430] TI I2C Example Problems
>
>
>
>
> On 26 Mar 2014, at 19:44, Mike Raines wrote:
> I was feeling better about this until, suddenly now, sometimes I get no scope pattern, and the disassembly window shows software stuck on:
> Add.b R5, R4
>
> Any ideas? Of course, when this happens, the execution never returns from the isr.
>
> Suspect you have an interrupt condition that you are not correctly servicing, and not clearing the flag for it, hence you reenter the interrupt service routine?
>
> Paul.
>
> size=1 width="100%" noshade color="#a0a0a0" alignter>
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 2014.0.4354 / Virus Database: 3722/7248 - Release Date: 03/25/14
>
Marty,

Althought to some, I'M just a dumba$$ that works in a cubicle, I think that's an excellent idea. It occurred to me while working on this that there are probably several million ways to try TI I2C and only one (or maybe 2, 3) THAT WILL WORK. If I get through this, I will contribute.

Thanks,
Mike Raines

________________________________
From: m... [mailto:m...] On Behalf Of Martin Bruner
Sent: Wednesday, March 26, 2014 7:16 PM
To: msp430@yahoogroups. com
Subject: [SPAM] Re: [msp430] TI I2C Example Problems
Importance: Low
Hey everyone,

Since I have seen this issue pop up rather frequently, do you think it would be a good idea to place some MSP430 I2C code in a repository, like Github? That way our fellow group members wouldn't "reinventing the wheel".

Thanks,

Marty

From: "David W. Schultz" >
Organization: State of Total Disorganization
Reply-To: "msp430@yahoogroups. com" >
Date: Wednesday, March 26, 2014 5:04 PM
To: "msp430@yahoogroups. com" >
Subject: Re: [msp430] TI I2C Example Problems

On 03/26/2014 01:21 PM, m...@hofferflow.com wrote:
> Hey Folks,
>
> Some of you may remember I just had a problem bit-banging an i2c
> interface to an eeprom, Microchip
>
> 24FC1025. That problem remains unsolved, with IAR and myself continuing
> to work on it, but right now, I am
>
> trying to interface with the eeprom using the TI built-in I2C USCIB2. I
> have been fighting to make a very
>
> simple (I thought) TI example titled "MSP430x54x_uscib0_i2c_08". I have
> minimally altered the example so I

I recently worked at getting the I2C USCI on the G2955 working and it
wasn't easy. I try to record some notes when I work on a project and the
notes for this one start:

"I have been beating my brain against the USCI I2C problem for a while."

I even reverted to my ancient bit banged routines just to verify that
the slave and connections were OK. I did eventually get it to work and
your interrupt code looks very much like mine:

if(IFG2 & UCB0TXIFG) // I2C transmit char interrupt
{
if (dcount == 0)
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
IE2 &= ~UCB0TXIE; // disable transmit interrupt

}
else
{
UCB0TXBUF = *datap++;
dcount--;
}
}

--
David W. Schultz
http://home.earthlink.net/~david.schultz
Returned for Regrooving

size=1 width="100%" noshade color="#a0a0a0" alignter>
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2014.0.4354 / Virus Database: 3722/7252 - Release Date: 03/26/14

The 2024 Embedded Online Conference