The following code is for EEPROM that I used in my MSP code.
InitI2C(SlaveAddress); EEPROM_ByteWrite(0x0001, '&'); val_read[0] = EEPROM_RandomRead(0x0000);
where EEPROM_ByteWrite is as follows.
void EEPROM_ByteWrite(unsigned int Address, unsigned char Data) { unsigned char adr_hi; unsigned char adr_lo; I2CBuffer = '0'; while (UCB1STAT & UCBUSY); // wait until I2C module has // finished all operations. adr_hi = Address >> 8; // calculate high byte adr_lo = Address & 0xFF; // and low byte of address I2CBufferArray[2] = adr_hi; // Low byte address. I2CBufferArray[1] = adr_lo; // High byte address. I2CBufferArray[0] = Data; PtrTransmit = 1; // set I2CBufferArray Pointer I2CWriteInit(); UCB1CTL1 |= UCTXSTT; // start condition generation // => I2C communication is started __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts UCB1CTL1 |= UCTXSTP; // I2C stop condition while(UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent }
And EEPROM_RandomRead() is as follows.
unsigned char EEPROM_RandomRead(unsigned int Address) { unsigned char adr_hi; unsigned char adr_lo; I2CBuffer = '0'; while (UCB1STAT & UCBUSY); // wait until I2C module has // finished all operations adr_hi = Address >> 8; // calculate high byte adr_lo = Address & 0xFF; // and low byte of address I2CBufferArray[2] = adr_hi; // store single bytes that have to I2CBufferArray[1] = adr_lo; // be sent in the I2CBuffer. PtrTransmit = 1; // set I2CBufferArray Pointer // Write Address first I2CWriteInit(); UCB1CTL1 |= UCTXSTT; // start condition generation // => I2C communication is started __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts // Read Data byte I2CReadInit(); UCB1CTL1 |= UCTXSTT; // I2C start condition // while(UCB1CTL1 & UCTXSTT); // Start condition sent? // UCB1CTL1 |= UCTXSTP; // I2C stop condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts UCB1CTL1 |= UCTXSTP; while(UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent return I2CBuffer; }
And InitI2C() as follows.
void InitI2C(unsigned char eeprom_i2c_address) { I2C_PORT_SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B1 // Recommended initialisation steps of I2C module as shown in User Guide: UCB1CTL1 |= UCSWRST; // Enable SW reset UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB1CTL1 = UCSSEL_2 + UCTR + UCSWRST; // Use SMCLK, TX mode, keep SW reset UCB1BR0 = SCL_CLOCK_DIV; // fSCL = SMCLK/12 = ~100kHz UCB1BR1 = 0; UCB1I2CSA = eeprom_i2c_address; // define Slave Address // In this case the Slave Address // defines the control byte that is // sent to the EEPROM. //UCB1I2COA = 0x01A5; // own address. UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation if (UCB1STAT & UCBBUSY) // test if bus to be free { // otherwise a manual Clock on is // generated I2C_PORT_SEL &= ~SCL_PIN; // Select Port function for SCL I2C_PORT_OUT &= ~SCL_PIN; // I2C_PORT_DIR |= SCL_PIN; // drive SCL low I2C_PORT_SEL |= SDA_PIN + SCL_PIN; // select module function for the // used I2C pins }; }
So basically when I read back is sometimes 0x26 which is '&' , sometimes 0x01, and sometimes 0x00!!! Do I have timing issue?!
Having said this, I do not have any issue with this in an standalone program with only EEPROM code. As long as I implement this code to my firmware for the MSP, it starts to act weird and after a while it crashes down!
So, I am sure something in the code interrupts my EEPROM code!
What do you think?