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.

AM3358: I2C not working

Part Number: AM3358

Hi team ,

Greeting of the day !

I have been working on I2C of AM3358 for last one and half month and still it is not working . I want to tell you that I am not using any driver functions and library functions for this task. I am trying to write a raw code which can access I2C controller and I  have taken guidance from TI AM335X technical reference manual. In addition to I have no CRO (Cathode ray oscillator ) and DCRO( Digital Cathode Ray Oscillator) to check SDA and SCL .I am writing my steps(logic ) to access I2C controller  and hope you will go through all the steps and aware me my fault .

STEPS :-

Step 1:- Enable I2C2 Module of AM3358

      (a)  PINMUXING

           #define CNTRL_MDL   0X44E10000      // Memory mapped address , Reference :- AM335X TRM Section no.2.1, Page no.158

#define I2C_ADD    0x4819C000           // Memory mapped address :- Reference :- AM3358 TRM section no. 2.1 , Page no.160

#define MUX_ADD 0x800                         // MUX control registe , Reference :- AM335X TRM Section no. 9.3, Page no.758

#define I2C2_SCL 0x17C

#define I2C2_SDA 0x178

CNTRL_MDL_BASE=ioremap(CNTRL_MDL, 128*1024);

 I2C2_ADD_BASE=ioremap(I2C2_ADD,4095);

writel_relaxed(0x00000013,CNTRL_MDL_BASE+MUX_ADD+I2C2_SCL);

writel_relaxed(0x00000013,CNTRL_MDL_BASE+MUX_ADD+I2C2_SDA);

(b) Enable clock for I2C2

#define CM_PER  0x44E00000       // Clock Module register address Reference :- AM335x TRM ,Section 2.1 page no .-157

CM_PER_BASE=ioremap(CM_PER, 1024);

writel_relaxed(0x2,CM_PER_BASE+CM_PER_L4LS_CLKCTRL);    // Reference :- AM335x TRM Section no. -8.1.12.1.20 page no . -570

mdelay(5);

 writel_relaxed(0x2,CM_PER_BASE+CM_PER_I2C2_CLKCTRL);  // Reference :- AM335X TRM Section no.:- 8.1.12.1.16 page no.:-566

mdelay(5);

Step 2:- I2C2 Module Configuration        // Reference AM335X TRM Section no.-21.3.15.1 page no.-3714

(a) Program prescaler to get 12 Mhz Internal clock frequency(ICLK) and compute SCLL value and SCLH value

        writel_relaxed(0x03,I2C2_ADD_BASE+I2C_PSC);  // Reference : - AM335X TRM ,Section no . - 21.4.1.22 , page no.-3754
        mdelay(10);
        writel_relaxed( 0x31,I2C2_ADD_BASE+I2C_SCLL);  // Reference :- AM335X TRM, Section no.:- 21.4.1.23, Page no:- 3755
        mdelay(10);
        writel_relaxed(0x2B,I2C2_ADD_BASE+I2C_SCLH);   //Reference :- AM335X TRM Section no.:- 21.4.1.24 , Page no:- 3756
        mdelay(10);

     

  
    
(b) I2C2 Initialization procedure , Configuration of DATA COUNT Register and initiation of data transfer 

      

        writel_relaxed((1<<15),I2C2_ADD_BASE+I2C_CON); //Enable I2C Module , Reference :- AM335x , Section no.:-21.4.1.19, Page no.:- 3749
        writel_relaxed(0x2,I2C2_ADD_BASE+I2C_CNT);       // Number of byte to be transferred , Reference :- Am335x , Section no .:- 21.4.1.17 , Page no.:-3747 i    

      while((readl_relaxed(I2C2_ADD_BASE+I2C_IRQSTATUS_RAW)&(1<<12))); // Check Is Bus free , Reference :- AM335x , Section no.:- 21.4.1.4 Page no.:- 3721
      pr_info(KERN_INFO"BUS IS FREE \n");

      udelay(1);   
        k=readl_relaxed(I2C2_ADD_BASE+I2C_CON);
        writel_relaxed(1<<10|k,I2C2_ADD_BASE+I2C_CON);  // Transmitter mode , Reference :- AM335X TRM Section no.:- 21.4.1.19, Page no.: -3750

          k=readl_relaxed(I2C2_ADD_BASE+I2C_CON);
        writel_relaxed(1<<0|k,I2C2_ADD_BASE+I2C_CON); //  Start Condition , Reference :- AM335X TRM Section no.:- 21.4.1.19 Page no.:-3751
        udelay(5.5);
        k=readl_relaxed(I2C2_ADD_BASE+I2C_CON);
         writel_relaxed(1<<1|k,I2C2_ADD_BASE+I2C_CON);  // Stop Condition , Reference :- AM335X TRM Section no.:- 21..4.1.19 Page no.:- 3751

         k=readl_relaxed(I2C2_ADD_BASE+I2C_CON);
        writel_relaxed(1<<9|k,I2C2_ADD_BASE+I2C_CON); // Enable transmitter mode , Reference :-AM335X TRM Section no.:- 21.4.1.19 Page no.:-3750

(C) Write Operation :-

 writel_relaxed(0X0D , I2C2_ADD_BASE+I2C_Data );   // I am trying to make communication with TINY RTC Module(DS 1307 whose address 0x68  ) TRM suggests send address with write/read bit and send MSB first , so i am sending 0X0D.

while(!(readl_relaxed(I2C2_ADD_BASE+I2C_IRQSTATUS_RAW)&(1<<4)));
        pr_info("DATA SENT AND READY FOR NEXT  \n");
       udelay(0.25);
        writel_relaxed(1<<4,I2C2_ADD_BASE+I2C_IRQSTATUS_RAW); // clear bit



 writel_relaxed(0X00 , I2C2_ADD_BASE+I2C_Data );   // I am trying to access address 0x00 of slave device , Reference :- AM335x TRM Section no.:- 21.4.1.18 , Page no .:-3748

while(!(readl_relaxed(I2C2_ADD_BASE+I2C_IRQSTATUS_RAW)&(1<<4)));  // Check transmission status , Reference :- AM335X TRM Section no.:- 21.4.1.4 ,Page no.:-3725
        pr_info("DATA SENT AND READY FOR NEXT  \n");

(d) STOP BIT detection

 while(!(readl_relaxed(I2C2_ADD_BASE+I2C_IRQSTATUS_RAW)&1<<2)); //Check status of stop bit  , Reference :- AM335x TRM Section no.:- 21.4.1.4 , Page no .:- 3726

After above all steps only start condition is detecting and after that SDA line goes to LOW for while .I could not check SCL and SDA signal because i have not Digital CRO or CRO to check waveform . Kindly aware me my fault .

Thank you