This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DS1307 interfacing to Tiva

Other Parts Discussed in Thread: TM4C123GH6PM

Hi everyone,

I am trying to interface 1307 rtc to tiva using I2C communication. I have configured my launchpad for I2C as given in the datasheet. http://www.ti.com/lit/gpn/tm4c123gh6pm

After configuration I am not able to write to I2C_MDR register.

Here is my code so far


// ***** 1. Pre-processor Directives Section *****
#include <stdint.h>
#include "tm4c123gh6pm.h"


void port_e_i2c_init(){
	unsigned long volatile delay;
	SYSCTL_RCGCI2C_R  |= 0x00000004;  // Enable and provide clock to I2C module 2 in Run mode.
	delay = SYSCTL_RCGCI2C_R;         // wait 3-5 bus cycles
	SYSCTL_RCGC2_R |= 0x10;           // Port E clock
	delay = SYSCTL_RCGC2_R;           // wait 3-5 bus cycles
	GPIO_PORTE_AFSEL_R |= 0x00000030; // pin 4 & 5 functions as peripheral signal & is controlled by alternate H/W function
	GPIO_PORTE_AMSEL_R &= ~0xFF;      // no analog
	GPIO_PORTE_ODR_R |= 0x00000020;   // pin 5 (SDA) is configured as open drain.
	GPIO_PORTE_PCTL_R |= 0x00330000;  // set I2C function on pin 4 & 5
	GPIO_PORTE_DEN_R |= 0x30;         // Digital enable on pin 4 & 5
	I2C2_MCR_R = 0x00000010;          // initialize the I2C master
	I2C2_MTPR_R = 0x00000009;	  // set SCL clock speed to 100 Kbps
	I2C2_MSA_R = 0x00000076;	  // slave address -> 3B, next operation -> transmit (as last bit is 0)
	I2C2_MDR_R = 0x00000068;	  // place the data byte to be transmitted in the Master Data Register
	I2C2_MCS_R = 0x00000007;	  // single byte transmit of data from master to slave
	while((I2C2_MCS_R & 0x00000040)); // wait till transmission is done
}

void i2c_tx(){
//	I2C2_MDR_R = 0x00000068;		// place the data byte to be transmitted in the Master Data Register
//	I2C2_MCS_R = 0x00000007;	    // single byte transmit of data from master to slave
//	while((I2C2_MCS_R & 0x00000040));
}

/*
 * main.c
 */
int main(void) {


	port_e_i2c_init();
	i2c_tx();

	return 0;
}

please help.

 

  • Hello Nikhil,

    Direct register access macro's pose a tough readability when debugging. May I first suggest moving to TivaWare API's as the examples are also well written for it

    Secondly, the MDR register is a entry point register in I2C. It means that a write is transmitted and a read will push the read buffer value. Since a read has not been done by the I2C, the buffer's reset value will show up when a debugger read is done.

    Also the following threads are on the same Slave Device so may be some hints from here will help you.

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/335980.aspx?pi307171=1

    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/328206.aspx

    Regards

    Amit

  • Amit Thanks for your response. I have gone through these threads but was not able to figure out my mistakes. Anyways, when I am doing a write operation I am not receiving ack from the slave device. My MCR register shows 0x2E (meaning there was some error during last operation) Also what should be the value of TPR register for 100 KHz clk rate.? According to the data sheet I have to set it to 0x09 for 20MHz system clock. I have tried to use I2C library but couldn't get it working. I was not able to include the header files In the Project.
  • Hello Nikhil,

    Please send the updated code with the Tiva Library call. We can figure the code issue out.

    If you are not receiving the ACK from the Slave device then the only cause that can be there is that the address to the slave in the MSA register is not correct. Can you try getting a scope snapshot and compare the address that is expected against the one expected by DS1307.

    Regards

    Amit

  • I am creating a new project using i2c lib but I am unable to include some header files. (screenshots below)

    I have slightly modified my previous code. The slave address is configured properly, it should be 0xD0 to write data into the slave. Still MCS register reads 0x2E ! (I can't understand what am I doing wrong)

    Also I want to know the system clock frequency for SCL calculation. (I have taken it as 20MHz)

    // ***** 1. Pre-processor Directives Section *************************
    #include <stdint.h>
    #include "tm4c123gh6pm.h"
    
    // ***** 2. Function Definations *************************************
    //
    // Initialize port E for i2c function
    //
    void port_e_i2c_init(){
    	unsigned long volatile delay;
    
    	SYSCTL_RCGC2_R |= 0x10;           // Port E clock
    	delay = SYSCTL_RCGC2_R;           // wait 3-5 bus cycles
    	SYSCTL_RCGCI2C_R  |= 0x00000004;  // Enable and provide clock to I2C module 2 in Run mode.
    	delay = SYSCTL_RCGCI2C_R;         // wait 3-5 bus cycles
    
    	GPIO_PORTE_AFSEL_R |= 0x00000030; // pin 4 & 5 functions as peripheral signal & is controlled by alternate H/W function
    	GPIO_PORTE_AMSEL_R &= ~0xFF;      // no analog
    	GPIO_PORTE_DEN_R |= 0x30;		  // Digital enable on pin 4 & 5
    	GPIO_PORTE_ODR_R |= 0x00000020;   // pin 5 (SDA) is configured as open drain.
    	GPIO_PORTE_PCTL_R |= 0x00330000;  // set I2C function on pin 4 & 5
    
    }
    
    //
    // set up i2c module 2 registers
    //
    void i2c2_init(){
    	I2C2_MCR_R = 0x00000010;          	// initialize the I2C master
    	I2C2_MTPR_R = 0x09;				  	// set SCL clock speed to 100 Kbps
    
    }
    
    
    void i2c_tx(){
    	I2C2_MSA_R = 0x000000D0;	      	// slave address -> 68, next operation -> transmit (as last bit is 0)
    
    
    	I2C2_MDR_R = 0x00;				  	// place the data byte to be transmitted in the Master Data Register
    	I2C2_MCS_R = 0x03;			      	// multiple byte transmit of data from master to slave
    	while((I2C2_MCS_R & 0x40));       	// wait till transmission is done
    
    	I2C2_MDR_R = 0x06;				  	// place the data byte to be transmitted in the Master Data Register
    	while((I2C2_MCS_R & 0x40)); 		// wait till transmission is done
    
    	I2C2_MCS_R = 0x05;					// stop transmission
    	while((I2C2_MCS_R & 0x40)); 		// wait till transmission is done
    
    
    }
    
    
    /*
     * main.c
     */
    int main(void) {
    
    
    	port_e_i2c_init();
    	i2c2_init();
    	i2c_tx();
    
    	return 0;
    }
    

    I2C with library function calls (image below):