I'm trying to interface an F2617 with an AD5242 digital potentiometer http://www.analog.com/static/imported-files/data_sheets/AD5241_5242.pdf
The code hangs on line 40: while (UCB0CTL1 & UCTXSTT);
If I comment that line out, it instead hangs on line 43: while ((IFG2 & UCB0TXIFG) == 0);
Pull-up resistors are 10kohm on both lines
I can program the AD5242 just fine from an AVR Mega32, so its not faulty.
I've been trying several I2C examples as well as writing my own code from the datasheets info, and have tried the the Launchpad/G2553 as well, with no success.
Does someone have working I2C master-slave/device code that they can share?
Can anyone see what I'm doing wrong?
The code (also attached):
#include "msp430f2617.h" #define I2C_MASTER_ADDRESS 0x007F // 7-bit addressing, MSB is "respond to general calls" // I2C pot address: b010.11xx = 0x2C or 0x2D or 0x2E or 0x2F #define I2C_POTMETER_ADDRESS 0x2C // 7-bit addressing, do not include write-bit #define I2C_POTMETER_INSTRUCTION 0x00 // RADC1, no reset, no shutdown, no logic pin outputs #define I2C_POTMETER_TAPS (int)255 /* USCI module is configured as an synchronous mode I2C master in a single-master enviroment. Both master and slave use 7-bit addressing. Master does not respond to general calls. Clock used is SMCLK/12 = 1.2GHz/12 = 100kHz. Master is configured as transmitter. P3.1 = SDA I2C data P3.2 = SCL I2C clock */ void I2C_init() { UCB0CTL1 |= UCSWRST; // Enable USCI SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Single I2C master, synchronous mode, 7-bit addressing (both master and slave) UCB0CTL1 = UCSSEL_2 + UCTR + UCSWRST; // Use SMCLK, transmitter mode, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2COA = I2C_MASTER_ADDRESS; // Master address, MSB = 0 to not respond to general calls UCB0I2CSA = I2C_POTMETER_ADDRESS; // Slave address P3SEL |= BIT1 + BIT2; // Assign I2C pins to USCI_B0 (secondary peripheral module) // P3SEL2 |= BIT1 + BIT2; // Assign I2C pins to USCI_B0 (secondary peripheral module) UCB0CTL1 &= ~UCSWRST; // Clear USCI SW reset, resume operation IE2 |= UCB0TXIE; // Enable TX interrupt } /* The digital potmeter is written over I2C. Default is to write a new potmeter tap value. */ void I2C_write_pot_value(int value) { if (value > I2C_POTMETER_TAPS) value = I2C_POTMETER_TAPS; while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTR + UCTXSTT; // Switch to I2C transmit mode, send START condition while (UCB0CTL1 & UCTXSTT); // Wait for slave to acknowledges the address while ((IFG2 & UCB0TXIFG) == 0); // Wait for transmit buffer to clear UCB0TXBUF = I2C_POTMETER_INSTRUCTION; // Send instruction while ((IFG2 & UCB0TXIFG) == 0); // Wait for transmit buffer to clear UCB0TXBUF = value; // Send data while ((IFG2 & UCB0TXIFG) == 0); // Wait for transmit buffer to clear UCB0CTL1 |= UCTR + UCTXSTP; // Send STOP condition } int I2C_read_pot_value(void) { return 0; } void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT I2C_init(); while(1) { I2C_write_pot_value(1); } }
#include "msp430f2617.h"
#define I2C_MASTER_ADDRESS 0x007F // 7-bit addressing, MSB is "respond to general calls"
// I2C pot address: b010.11xx = 0x2C or 0x2D or 0x2E or 0x2F
#define I2C_POTMETER_ADDRESS 0x2C // 7-bit addressing, do not include write-bit
#define I2C_POTMETER_INSTRUCTION 0x00 // RADC1, no reset, no shutdown, no logic pin outputs
#define I2C_POTMETER_TAPS (int)255
/*
USCI module is configured as an synchronous mode I2C master in a single-master enviroment.
Both master and slave use 7-bit addressing. Master does not respond to general calls.
Clock used is SMCLK/12 = 1.2GHz/12 = 100kHz. Master is configured as transmitter.
P3.1 = SDA I2C data
P3.2 = SCL I2C clock
*/
void I2C_init()
{
UCB0CTL1 |= UCSWRST; // Enable USCI SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Single I2C master, synchronous mode, 7-bit addressing (both master and slave)
UCB0CTL1 = UCSSEL_2 + UCTR + UCSWRST; // Use SMCLK, transmitter mode, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2COA = I2C_MASTER_ADDRESS; // Master address, MSB = 0 to not respond to general calls
UCB0I2CSA = I2C_POTMETER_ADDRESS; // Slave address
P3SEL |= BIT1 + BIT2; // Assign I2C pins to USCI_B0 (secondary peripheral module)
// P3SEL2 |= BIT1 + BIT2; // Assign I2C pins to USCI_B0 (secondary peripheral module)
UCB0CTL1 &= ~UCSWRST; // Clear USCI SW reset, resume operation
IE2 |= UCB0TXIE; // Enable TX interrupt
}
/*
The digital potmeter is written over I2C. Default is to write a new potmeter tap value.
*/
void I2C_write_pot_value(int value)
{
if (value > I2C_POTMETER_TAPS)
value = I2C_POTMETER_TAPS;
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT; // Switch to I2C transmit mode, send START condition
while (UCB0CTL1 & UCTXSTT); // Wait for slave to acknowledges the address
while ((IFG2 & UCB0TXIFG) == 0); // Wait for transmit buffer to clear
UCB0TXBUF = I2C_POTMETER_INSTRUCTION; // Send instruction
while ((IFG2 & UCB0TXIFG) == 0); // Wait for transmit buffer to clear
UCB0TXBUF = value; // Send data
while ((IFG2 & UCB0TXIFG) == 0); // Wait for transmit buffer to clear
UCB0CTL1 |= UCTR + UCTXSTP; // Send STOP condition
}
int I2C_read_pot_value(void)
{
return 0;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
I2C_init();
while(1)
{
I2C_write_pot_value(1);
}
}