This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 TWI with EEPROM using registers directly

I am trying to interface I2C EEPROM (AT24C512) with nrf52840 and I am directly writing to and reading from the registers mentioned in the datasheet. I am seeing the i2c waveforms on DSO and I think I am getting the start pulse correctly but not the further address and ACK and data. I tried to run and debug the code to check the data written and read but I am not getting the correct data.

Also I think I have not really written the ACK or NACK conditions correctly .  ERRORSRC This is the register I am checking for ACK.

I have attached the code. Please can anyone help me figure out what is going wrong. Because I really need to make it work ASAP.

Thank You


#define	EEPROM_SIZE 0xFFFF
#define EEPROM_DEVADDR 	0xA0
#define EEReadAddress 0xA1
#define EEWriteAddress 0x00

#define TWI_SCL 27
#define TWI_SDA 26

uint8_t *MAIN_u8buffer1 ;
//uint8_t MAIN_u8temp12[2][2]={0,1,2,3};
uint8_t MAIN_u8temp12[2] ;
uint8_t MAIN_u8buffer2[20] ;
uint8_t MAIN_u8temp = 0;

/*
Initialize I2C (TWI) interface
*/

void I2CInit()
{

 /* NRF_GPIO->PIN_CNF[TWI_SCL] = 0x0000000F ; //configure pins with pullup
  NRF_GPIO->PIN_CNF[TWI_SDA] = 0x0000000F ;*/
  NRF_TWI0->SHORTS = 0 ; //disable all shortcuts
  NRF_TWI0->INTENSET = 0 ; //disable all twi interrupts 
  NRF_TWI0->FREQUENCY = NRF_DRV_TWI_FREQ_100K ;
  NRF_TWI0->PSEL.SCL = TWI_SCL ;
  NRF_TWI0->PSEL.SDA = TWI_SDA ;
 // NRF_TWI0->ADDRESS = EEPROM_DEVADDR ; //I2C EEPROM Address AT24C512
  NRF_TWI0->ENABLE = 5 ;   //For enabling TWI we need to write 5 to the enable register according to datasheet
 
}


/*
Writes data to EEPROM.
Return:	True on successful write and 
		False on time out or any error with device 
*/
unsigned char I2C_WriteToEEPROM (unsigned int u32startAddr, unsigned char *u8data, unsigned int u32len)
{
       unsigned int u32i,u32j;
	
	//1. Check for upper limit
	if (u32startAddr + u32len > EEPROM_SIZE)
		return false;

       //2.Generate Start
       NRF_TWI0->TASKS_STARTTX = 1 ;

       //3.Transmit Device Address+Write
        NRF_TWI0->ADDRESS = EEWriteAddress ;

       //4.Wait for ACK
        while(!((NRF_TWI0->ERRORSRC & 0x00000002) == 0x00000000))     //ANACK Address NACK is 0 that is Address ACK is received
          {
               //wait till bit B in ERRORSRC register is not 0
          }
        

       //5.First Word Address (u32startAddr & 0x000000FF)(MSB)
          NRF_TWI0->ADDRESS = (u32startAddr & 0x000000FF);


       //6.Wait for ACK
         while(!((NRF_TWI0->ERRORSRC & 0x00000002) == 0x00000000))     //ANACK Address NACK is 0 that is Data ACK is received
          {
            //wait till bit B in ERRORSRC register is not 0
          }

       //7.Second Word Address (((u32startAddr & 0x0000FF00)>>8) &0xFF)(LSB)
       //8.Wait for ACK

       //9.Data
          NRF_TWI0->TXD = ((u8data[u32i])&0x000000FF);
          u32startAddr++;

       //10.Wait for ACK
         while(!((NRF_TWI0->ERRORSRC & 0x00000004) == 0x00000000))     //DNACK Address NACK is 0 that is Data ACK is received
          {
              //wait till bit B in ERRORSRC register is not 0
          }

       //11.Generate Stop
            NRF_TWI0->TASKS_STOP = 1 ;

         
         return true ;
         
}



/*
Reads data from EEPROM.
Return:	True on valid data and 
		False on time out or any error with device 
*/
unsigned char I2C_ReadFromEEPROM (unsigned int u32startAddr, unsigned char *u8data, unsigned int u32len)
{
	unsigned int	u32i;

        //1.Dummy Write. Reapeat the write routine
     for(u32i=0;u32i<u32len;u32i++)
     {
        //1. Check for upper limit
	if (u32startAddr + u32len > EEPROM_SIZE)
		return false;

       //2.Generate Start
       NRF_TWI0->TASKS_STARTTX = 1 ;

       //3.Transmit Device Address+Write
        NRF_TWI0->ADDRESS = EEWriteAddress ;

       //4.Wait for ACK
        while(!((NRF_TWI0->ERRORSRC & 0x00000002) == 0x00000000))     //ANACK Address NACK is 0 that is Address ACK is received
          {
               //wait till bit B in ERRORSRC register is not 0
          }
        

       //5.First Word Address (u32startAddr & 0x000000FF)(MSB)
          NRF_TWI0->ADDRESS = (u32startAddr & 0x000000FF);


       //6.Wait for ACK
         while(!((NRF_TWI0->ERRORSRC & 0x00000002) == 0x00000000))     //ANACK Address NACK is 0 that is Data ACK is received
          {
            //wait till bit B in ERRORSRC register is not 0
          }

       //7.Second Word Address (((u32startAddr & 0x0000FF00)>>8) &0xFF)(LSB)
       //8.Wait for ACK

       // Read data - Sequential mode.
         //1.Generate Start
           NRF_TWI0->TASKS_STARTRX = 1 ;

        //2.Transmit Device Address+Read
         NRF_TWI0->ADDRESS = EEReadAddress ;

       //3.Wait for ACK
        while(!((NRF_TWI0->ERRORSRC & 0x00000002) == 0x00000000))     //ANACK Address NACK is 0 that is Address ACK is received
          {
               //wait till bit B in ERRORSRC register is not 0
          }

        //4.Read Data
  /*      while(!(NRF_TWI0->EVENTS_RXDREADY))
         {
            //Wait till received data is ready
         }*/

         u8data[u32i] = (unsigned char)(NRF_TWI0->RXD) ;
		u32startAddr++;
                        
         //5.Transmit STOP
         NRF_TWI0->TASKS_STOP = 1 ;

     }

     return true ;

}


I2CInit() ;
    //for(uint8_t i = 0 ; i < 10 ; i++) ;
   MAIN_u8buffer1 = 0 ;
    MAIN_u8temp12[0] = 'a' ;
   // MAIN_u8temp=MAIN_u8temp12[0]; 
  MAIN_u8buffer1 = /*(uint8_t*)*/MAIN_u8temp12[0];
   

    while (true)
    {
      
     if (I2C_WriteToEEPROM(0,  MAIN_u8buffer1, 1) == true) ;
      

     if (I2C_ReadFromEEPROM(0, MAIN_u8buffer2 , 1) == true) ;

    }
}

Related