I2C Problem with EEPROM 24AA01T with FRDM KL25Z

cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Problem with EEPROM 24AA01T with FRDM KL25Z

2,148 Views
jaimegarcia
Contributor I

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.

Tags (3)
0 Kudos
6 Replies

587 Views
adriansc
Contributor IV

Hi Jaime,

I am not really sure about what you are missing or what is wrong. In the attachments you can find the initialization code and driver for I2C for FRDM-KL25Z and, also the functions to configure, write and read to/from Accelerometer MMA8451.

I think is better to check for IICIF (Interrupt Flag) register to ensure complete transfer and ACK return.

Hope this helps.

0 Kudos

587 Views
viralshah
Contributor I

Hello, Adrian,

I am using your I2C library on Kl26Z Microcontroller to store data on EEPROM 24AA01T. Whenever I write on particular location say 0x01 and try to read that using I2C read function I always get 255. 

Below is my main.c which uses your I2C library.

hal_i2c0_init(I2C0_BASE_PTR);

send_string_debug("I2C Writing...\r\n");  //Sent to Terminal
I2C_write(0xA0,0x01,32);
 send_string_debug("I2C Writing Done...\r\n");  ////Sent to Terminal
 delay(1000);
 send_string_debug("I2C Reading...\r\n");  ////Sent to Terminal
 I2C_R=I2C_Read(0xA0,0x01);
 send_string_debug("I2C Reading Done...\r\n");  ////Sent to Terminal
 sprintf(VR,"I2C Value is %d\r\n",I2C_R);  //Converting to String
 send_string_debug(VR);  //Sent to Terminal

What do you think could be wrong here?

Thanks

0 Kudos

587 Views
atwoz
Contributor I

Modify your post and style your code (use the advanced editor and select c++ syntax).

0 Kudos

587 Views
erikmalund
Contributor I

All of this is without Processor Expert. Just curious, Why?

0 Kudos

587 Views
adrianhernández
Contributor I

I have the same problem! Can anybody help here please? Any help will be appreciated! Best regards!

0 Kudos

587 Views
JimDon
Senior Contributor III
0 Kudos