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

TWI / I2c device unable to read / write the device ? irrespective of following reference manual.

Here are my functions which i wrote for reading / writing the i2c slave device ( after reading reference manual (nrf51422) . Unfortunately they are not working. Plz help me with the code.

void twi_init_slz(void )
{
	(*(unsigned volatile int *)0x040003500)= 0x00;               //Disable SPI AND TWI
	//(*(unsigned volatile int *)0x040003200)= 0x00; 							//SHORTCUT REGISTER
	(*(unsigned volatile int *)0x040003508)= 30U;								 //PSELSCL	
	(*(unsigned volatile int *)0x04000350C)= 7U;									//PSELSDA
	(*(unsigned volatile int *)0x050000518)= ~((1UL<<30)|(1UL<<7));
	(*(unsigned volatile int *)0x050000778)= (6UL<<8)|(3UL<<2);		//set pin
	(*(unsigned volatile int *)0x05000071C)= (6UL<<8)|(3UL<<2);		//set pin
	//(*(unsigned volatile int *)0x040003300)= (1UL<<2)|(1UL<<7)|(1UL<<7)|(1UL<<9)|(1UL<<14);	//INTEN
	(*(unsigned volatile int *)0x040003304)= (1UL<<2)|(1UL<<7)|(1UL<<7)|(1UL<<9)|(1UL<<14);	//INTENSET
	(*(unsigned volatile int *)0x040003524)= 0x01980000;				//FREQUENCY		
	(*(unsigned volatile int *)0x040003124)= 1UL;				//ERROR	

	(*(unsigned volatile int *)0x040003500)= 0x05;     //ENABLE TWI
}

void set_address_twi_slz(int address)
{
	(*(unsigned volatile int *)0x040003588)= address;				//I2C ADDRESS

}

int read_twi_slz(void)
{	
	nrf_delay_ms(10); 
	printf("In read\n");
	//(*(unsigned volatile int *)0x40003588)|= 1UL;	
	(*(unsigned volatile int *)0x40003000)= 1;						//STARTRX
	nrf_delay_ms(10); while(!((*(unsigned volatile int *)0x40003108))); //wait for RXREADY EVENT   
	nrf_delay_ms(10); 
	int read_i2c_value = (*(unsigned volatile int *)0x40003518); //copying RX Register
	nrf_delay_ms(10); 
	(*(unsigned volatile int *)0x40003014)= 1;		 //Stop
	return read_i2c_value;
}

bool write_twi_slz(int data)
{
	(*(unsigned volatile int *)0x40003008)=1;
	(*(unsigned volatile int *)0x4000351C)=data;
	int check =(*(unsigned volatile int *)0x04000351C);
	if(check)
	{
			return 1; // successfully sent
	}
	else
	{
			return 0; //Sent error
	}
}
Parents
  • Why are you using the register addresses instead of the register names defined in nrf51.h? It makes your code really hard to read.

    There is a TWI driver in the SDK that you can use instead of making all the low level functions your self. developer.nordicsemi.com/.../a00016.html

    Also, can you please update your question with what is actually not working. If you are able to see any activity at all using a logic analyzer or oscilloscope, and your test setup in general. How do you know it doesn't work?

  • The shifting is just a part of the TWI specification. TWI uses 7 bit addressing + a read/write bit: www.totalphase.com/.../200349176-7-bit-8-bit-and-10-bit-I2C-Slave-Addressing

    So when using the TWI driver in the SDK you need to shift the address one bit left and add the R/W bit as LSB before passing the resulting uint8_t variable to the TWI functions.

    If you write to the ADDRESS register directly, you can see in the data sheet that it consists of 7 bits, so no shifting is necessary.

    You do not need any external pull ups for the SCL and SDA. When the PSELSCL and PSELSDA registers are set the pins are configured correctly.

Reply
  • The shifting is just a part of the TWI specification. TWI uses 7 bit addressing + a read/write bit: www.totalphase.com/.../200349176-7-bit-8-bit-and-10-bit-I2C-Slave-Addressing

    So when using the TWI driver in the SDK you need to shift the address one bit left and add the R/W bit as LSB before passing the resulting uint8_t variable to the TWI functions.

    If you write to the ADDRESS register directly, you can see in the data sheet that it consists of 7 bits, so no shifting is necessary.

    You do not need any external pull ups for the SCL and SDA. When the PSELSCL and PSELSDA registers are set the pins are configured correctly.

Children
No Data