Hi there.
I have a very strange problem regarding my MSP420F2272. I would like to address an external EEPROM to store some values and read them back later. The EEPROM is a AT24C512B and needs to be addressed wit 2 Bytes.
Reading is working fine. i'll transmit 2 address bytes send a restart and read all the bytes i request.
Writing instead is finished with a stop condition after the first address byte.
I set a breakpoint to every stop condition. none was reached. I have absolutly no idea what's going wrong.
Attached my I2C Code:
/*
* I2C.c
*
* Created on: 02.08.2012
* Author: l-doerner
*/
#include "I2C.h"
UINT8 History_Page = HISTORY_START_PAGE;
UINT8 History_Position = 0;
UINT16 Address = 0;
UINT16 Length = 0;
UINT8 *pTransmit = 0;
UINT8 *pReceive = 0;
UINT8 *pAddress = 0;
UINT8 Target = WRITE_HISTORY;
UINT8 Addressing_Flag = 0;
void fnInitI2C (void)
{
UCB0CTL1 = UCSWRST;
/* I2C | master | single master | synchronous mode | slave address 7bit | own address 7bit */
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
/* enable SW reset | use SMCLK | normal ACK | no START | no STOP | reciver */
UCB0CTL1 = UCSSEL_2 + UCSWRST;
/* 12MHz/120 = 100KHz */
UCB0BR0 = 0x78;
UCB0BR1 = 0x00;
//UCB0BR0 = 0x12; // set prescaler
// UCB0BR1 = 0;
UCB0I2CSA = EEPROM;
UCB0CTL1 &= ~UCSWRST;
UCB0I2CIE = UCNACKIE; /* Not-acknowledge interrupt enable*/
}
void fnStoreHistory (void)
{
fnInitI2C();
Target = WRITE_HISTORY;
Address = History_Page * 128 + History_Position;
pAddress = (UINT8 *)& Address;
pTransmit = (UINT8 *) &history.Cylce;
Length = sizeof(history);
Addressing_Flag = 1;
IE2 = UCB0TXIE; /* USCI_B0 transmit interrupt enable */
UCB0CTL1 |= UCTR + UCTXSTT; /* start condition I2C transmit */
while (UCB0STAT & UCBBUSY);
}
void fnStoreSystemValues (void )
{
fnInitI2C();
Target = WRITE_SYSTEM;
Address = 0x01;
pAddress = (UINT8 *) &Address;
pTransmit = (UINT8 *) &System.Cycle_Count;
Length = sizeof(System);
Addressing_Flag = 1;
IE2 = UCB0TXIE; /* USCI_B0 transmit interrupt enable */
UCB0CTL1 |= UCTR + UCTXSTT; /* start condition I2C transmit */
while (UCB0STAT & UCBBUSY);
}
void fnReadHistory (UINT16 Start_Address, UINT16 Length)
{
fnInitI2C();
Target = READ_HISTORY;
Address = Start_Address;
pAddress = (UINT8 *) &Address;
Length = Length;
Addressing_Flag = 1;
IE2 = UCB0TXIE; /* USCI_B0 transmit interrupt enable */
UCB0CTL1 |= UCTR + UCTXSTT; /* start condition I2C transmit */
while (UCB0STAT & UCBBUSY);
}
void fnReadSystemValue (void)
{
fnInitI2C();
Target = READ_SYSTEM;
Address = 0x0000;
pAddress = (UINT8 *) &Address;
pReceive = (UINT8 *)& System.Cycle_Count;
Length = sizeof(System);
Addressing_Flag = 1;
IE2 = UCB0TXIE; /* USCI_B0 transmit interrupt enable */
UCB0CTL1 |= UCTR + UCTXSTT; /* start condition I2C transmit */
while (UCB0STAT & UCBBUSY);
}
void fnCheck_Page_Overflow(void)
{
History_Position++;
if(History_Position == 128)
{
History_Position = 0;
if (History_Page == 511)
{
History_Page = HISTORY_START_PAGE;
}
else
{
History_Page++;
}
Addressing_Flag = 1;
Address = History_Page * 128 + History_Position;
pAddress = (UINT8 *) &Address;
}
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
if (UCB0STAT & UCNACKIFG)
{
UCB0CTL1 |=UCTXSTP; // if slave send NACK, master generate STOP
UCB0STAT &= ~UCNACKIFG; // reset Not-acknowledge received interrupt flag
}
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR (void)
{
static UINT8 Address_length = 2;
if (IFG2 & UCB0RXIFG) // UCB0RXIFG is set when UCB0RXBUF has received a complete character
{
switch (Target) {
case READ_HISTORY:
if ( Length == 1) // all Bytes read
{
UCB0CTL1 |= UCTXSTP; // stop condition I2C
IFG2 &= ~UCB0TXIFG; // USCI_B0 clear transmit interrupt flag
// UARTBUFFER= UCB0RXBUF; //UARTBUFFER todo
}
else
{
// UARTBUFFER= UCB0RXBUF;
Length--;
}
break;
case READ_SYSTEM:
if ( Length == 1) // all Bytes read
{
UCB0CTL1 |= UCTXSTP; // stop condition I2C
IFG2 &= ~UCB0TXIFG; // USCI_B0 clear transmit interrupt flag
*pReceive = UCB0RXBUF;
Length--;
}
else
{
*pReceive = UCB0RXBUF;
pReceive++;
Length--;
}
break;
default:
break;
}
}
else
if (IFG2 & UCB0TXIFG)
{
if (Addressing_Flag)
{
if(Address_length == 0)
{
Addressing_Flag = 0;
Address_length = 2;
fnInitI2C();
switch (Target)
{
case WRITE_HISTORY:
UCB0TXBUF = *pTransmit;
pTransmit++;
Length--;
fnCheck_Page_Overflow();
break;
case WRITE_SYSTEM:
UCB0TXBUF = *pTransmit;
pTransmit++;
Length--;
break;
case READ_HISTORY:
case READ_SYSTEM:
IFG2 &= ~UCB0TXIFG; // USCI_B0 clear transmit interrupt flag
IE2 = UCB0RXIE; /* USCI_B0 receive interrupt enable */
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT; /* start condition I2C receive */
break;
default:
break;
}
}
else
{
UCB0TXBUF = *pAddress;
delay(20);
pAddress++;
Address_length--;
}
}
else
{
if ( Length == 1)
{
UCB0CTL1 |= UCTXSTP; // stop condition I2C
IFG2 &= ~UCB0TXIFG; // USCI_B0 clear transmit interrupt flag
}
else
{
UCB0TXBUF = *pTransmit;
pTransmit++;
Length--;
fnCheck_Page_Overflow();
}
}
}
}
Thx for the help.