Tool/software:
Hello,
I am currently working on writing data on a FT24C256A eeprom using a MSP430FR5969 and I2C protocol. I am using a MSP430FR5969 launchpad and use the P1.6 and P1.7 for my SCL and SDA.
I have connected the a0, a1 and a2 pins to GND which leads to the address being 1010000 (0x50). When I try and sent data using the write function in my code (code is down below) I keep getting stuck in the second while (!(UCB0IFG & UCTXIFG)); function which with the research I have done means that the eeprom doesn't send an ACK back. How do I fix this problem?
I also have measured the SCL and SDA lines and came to the observation that there is no block signal on the SCL which I would expect. Also when I measured the SDA line the signal on the line was high and when I sent an startbit (using UCB0CTLW0 |= UCTR + UCTXSTT;) it becomes low. So my question is, is there anything wrong with my code?
#include <msp430fr5969.h>
#define EEPROM_ADDR 0x50
void i2c_init(void) {
// Zet pinfunctie voor I2C
P1SEL1 |= BIT6 + BIT7;
P1SEL0 &= ~(BIT6 + BIT7);
// Zet eUSCI_B0 in reset
UCB0CTLW0 = UCSWRST;
// Configureer als I2C master
UCB0CTLW0 |= UCMODE_3 + UCMST + UCSYNC + UCSSEL__SMCLK;
UCB0BRW = 160; // SCL = SMCLK / 160 = ~100kHz bij 16 MHz
UCB0I2CSA = EEPROM_ADDR;
UCB0CTLW0 &= ~UCSWRST; // Haal uit reset
}
void i2c_write_byte(unsigned int mem_addr, unsigned char data) {
while (UCB0STATW & UCBBUSY); // Wacht tot bus vrij is
UCB0CTLW0 |= UCTR + UCTXSTT; // Master transmitter, START
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = (mem_addr >> 8) & 0xFF;
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = mem_addr & 0xFF; // Laag byte
while (!(UCB0IFG & UCTXIFG));
UCB0TXBUF = data; // Gegevensbyte
while (!(UCB0IFG & UCTXIFG));
UCB0CTLW0 |= UCTXSTP; // STOP
while (UCB0CTLW0 & UCTXSTP);
}
unsigned char i2c_read_byte(unsigned int mem_addr) {
unsigned char val;
while (UCB0STATW & UCBBUSY);
UCB0CTLW0 |= UCTR + UCTXSTT; // Transmit START
while (!(UCB0IFG & UCTXIFG0));
UCB0TXBUF = mem_addr >> 8;
while (UCB0IFG & UCTXIFG0);
UCB0TXBUF = mem_addr & 0xFF;
while (UCB0IFG & UCTXIFG0);
UCB0CTLW0 &= ~UCTR; // Switch naar receive
UCB0CTLW0 |= UCTXSTT; // Repeated START
while (UCB0CTLW0 & UCTXSTT); // Wacht tot START klaar
UCB0CTLW0 |= UCTXSTP;
val = UCB0RXBUF;
return val;
}
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop de watchdog timer
PM5CTL0 &= ~LOCKLPM5; // Zet GPIO pins actief (voor FRAM-specific)
// Zet P1.3, P1.4, P1.5 en P3.0 als output en trek ze laag
P1DIR |= BIT3 | BIT4 | BIT5; // Output
P1OUT &= ~(BIT3 | BIT4 | BIT5); // Zet omlaag
P3DIR |= BIT0;
P3OUT &= ~BIT0;
// Zet P4.3 als output en trek die omhoog
P4DIR |= BIT3;
P4OUT |= BIT3;
i2c_init(); // Initialiseer I2C
// __delay_cycles(160000); // EEPROM warm-up tijd
//
// // Schrijf een byte naar de EEPROM op geheugenadres 0x00
// StartStopTest(0x00);
__delay_cycles(320000); // EEPROM warm-up tijd
// Schrijf een byte naar de EEPROM op geheugenadres 0x00
i2c_write_byte(0x50, 0x42);
__delay_cycles(320000); // Wacht even voor de EEPROM om te schrijven
// Lees de byte terug van geheugenadres 0x00
unsigned char val = i2c_read_byte(0x0000);
// Stop de uitvoering, gebruik een breakpoint hier om 'val' te bekijken
while (1);
}