Jaime Garcia

I2C Problem with EEPROM 24AA01T with FRDM KL25Z

Discussion created by Jaime Garcia on Mar 22, 2013
Latest reply on Mar 4, 2017 by Viral Shah

I'm trying to write to an EEPROM and can't seem to be able to generate a STOP signal. I've checked the registers in debug mode and the RXAK bit does not reset, so I'm not able to correctly poll the ACK bit. All of this is without Processor Expert.

I'm using the Freedom Board with the KL25z128.

 

The pull-ups are 4.7k and are externally connected to the EEPROM on a separate circuit board.

 

This is the Code I'm using.

/*

* main implementation: use this 'C' sample to create your own application

*

*/

#include "derivative.h" /* include peripheral declarations */

 

 

int config(void);

int i2cinit(void);

void EEPROMWrite(uint8_t addr, uint8_t data);

int main(void)

{

  int i;

  uint8_t d;

  config(); //Start Hardware configuration

  i2cinit(); //Start I2C Configuration

 

       EEPROMWrite(0x11, 0xAA);

 

}

 

 

int config(void)

{

  //Configuration

  SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK |

                SIM_SCGC5_PORTD_MASK |

                SIM_SCGC5_PORTC_MASK |

                SIM_SCGC5_PORTB_MASK |

                SIM_SCGC5_PORTA_MASK;   /* Enable clock gate for ports to enable pin routing */

   /* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */

   SIM_CLKDIV1 = 0x00U;                 /* Update system prescalers */

   /* SIM_SOPT2: PLLFLLSEL=0 */

   SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_PLLFLLSEL_MASK); /* Select FLL as a clock source for various peripherals */

   /* SIM_SOPT1: OSC32KSEL=3 */

   SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */

   /* SIM_SOPT2: TPMSRC=1 */

   SIM_SOPT2 = (uint32_t)((SIM_SOPT2 & (uint32_t)~(uint32_t)(

                SIM_SOPT2_TPMSRC(0x02)

               )) | (uint32_t)(

                SIM_SOPT2_TPMSRC(0x01)

               ));                      /* Set the TPM clock */

   /* Switch to FEI Mode */

   /* MCG_C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */

   MCG_C1 = (MCG_C1_IREFS_MASK | MCG_C1_IRCLKEN_MASK);                                                  

   /* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */

   MCG_C2 = 0x00U;                                                  

   /* MCG_C4: DMX32=0,DRST_DRS=0 */

   MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));                                                  

   /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */

   OSC0_CR = OSC_CR_ERCLKEN_MASK;                                                  

   /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */

   MCG_C5 = 0x00U;                                                  

   /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */

   MCG_C6 = 0x00U;                  

   while((MCG_S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */

    }

    while((MCG_S & 0x0CU) != 0x00U) {    /* Wait until output of the FLL is selected */

    }

 

 

}

int i2cinit(void)

{

  /* SIM_SCGC4: I2C0=1 */

   SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK;                                                  

   /* I2C0_C1: IICEN=0,IICIE=0,MST=0,TX=0,TXAK=0,RSTA=0,WUEN=0,DMAEN=0 */

   I2C1_C1 = 0x00U;                     /* Clear control register */

   /* I2C0_FLT: SHEN=0,STOPF=1,STOPIE=0,FLT=0 */

   I2C1_FLT = I2C_FLT_STOPF_MASK;       /* Clear bus status interrupt flags */

   /* I2C0_S: TCF=0,IAAS=0,BUSY=0,ARBL=0,RAM=0,SRW=0,IICIF=1,RXAK=0 */

   I2C1_S = I2C_S_IICIF_MASK;           /* Clear interrupt flag */

  PORTE_PCR0 &= ~(PORT_PCR_MUX_MASK);

  PORTE_PCR0 |= (PORT_PCR_MUX(6));

  

  PORTE_PCR1 &= ~(PORT_PCR_MUX_MASK);

  PORTE_PCR1 |= (PORT_PCR_MUX(6));

 

 

 

  

   /* I2C0_C2: GCAEN=0,ADEXT=0,HDRS=0,SBRC=0,RMEN=0,AD=0 */

     I2C1_C2 = 0x00U;                                                  

     /* I2C0_FLT: SHEN=0,STOPF=0,STOPIE=0,FLT=0 */

     I2C1_FLT = 0x00U;                    /* Set glitch filter register */

     /* I2C0_SMB: FACK=0,ALERTEN=0,SIICAEN=0,TCKSEL=0,SLTF=1,SHTF1=0,SHTF2=0,SHTF2IE=0 */

     I2C1_SMB = I2C_SMB_SLTF_MASK;                                                  

     /* I2C0_F: MULT=0,ICR=0 */

     I2C1_F = 0x00U;                      /* Set prescaler bits */

    

     I2C1_C1 |=(I2C_C1_IICEN_MASK|I2C_C1_IICIE_MASK|I2C_C1_TXAK_MASK);

    

}

void EEPROMWrite(uint8_t addr, uint8_t data)

{

  int i;

  I2C1_C1 |= I2C_C1_TX_MASK;  //Enable Transmit

  I2C1_C1 |= I2C_C1_MST_MASK; //Enable Master Mode (Send Start Signal)

 

  I2C1_D = 0xA0; //Send Write Command to EEPROM (Addr. 1010xxx0)

  while(!(I2C1_S & I2C_S_TCF_MASK)); //Waits until transfer is finished

 

  if((I2C1_S & I2C_S_RXAK_MASK) == 0x00) //If ACK received

  {

  I2C1_C1|=I2C_C1_TXAK_MASK; //Reset ACK Flag

 

  I2C1_D = addr; //Send Address to write

  while(!(I2C1_S & I2C_S_TCF_MASK)); //Waits until transfer is finished

 

  if((I2C1_S & I2C_S_RXAK_MASK) == 0x00) //If ACK received

  {

  I2C1_C1|=I2C_C1_TXAK_MASK; //Reset ACK Flag

  I2C1_D = data; //Send Data

 

  while(!(I2C1_S & I2C_S_TCF_MASK)); //Waits until transfer is finished

 

 

  if((I2C1_S & I2C_S_RXAK_MASK) == 0x00) //if ACK received

  {

  I2C1_C1|=I2C_C1_TXAK_MASK; //Reset ACK Flag

  I2C1_C1 &= ~(I2C_C1_MST_MASK); //Disable Master Mode (Send Stop Signal)

  }//end if((I2C1_S & I2C_S_RXAK_MASK) == 0x00)

  }//end if((I2C1_S & I2C_S_RXAK_MASK) == 0x00)

  }//end if((I2C1_S & I2C_S_RXAK_MASK) == 0x00)

}

 

 

I'm using a Logic Device that shows this:

Logic device.png

Any help will be appreciated.

 

Thanks.

Outcomes