[PATCH 2/2] Beagle i2c: Update Beaglebone i2c driver code

Sichen Zhao 1473996754 at qq.com
Fri Mar 31 05:42:22 UTC 2017


This patch modify the i2c code for Beaglebone Black based on PV works:
- bbb-i2c.c: Modify the interrupt handler, transfer funciton, read function, am335x_i2c_busbusy function etc. Add flush_fifo function
- include/i2c.h: Modify some macros, such as BBB_I2C_IRQ_ERROR

Now the i2c is working on Beaglebone Black, it can read the EEPROM information.
---
 c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c | 378 +++++++++++-------------------
 c/src/lib/libbsp/arm/beagle/include/i2c.h |  11 +-
 2 files changed, 150 insertions(+), 239 deletions(-)

diff --git a/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c b/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c
index 6b790e5..4d22831 100644
--- a/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c
+++ b/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c
@@ -21,88 +21,8 @@
 #include <bsp/bbb-gpio.h>
 #include <rtems/score/assert.h>
 
-/*
-static bool am335x_i2c_pinmux(bbb_i2c_bus *bus)
-{
-  bool status =true;
-
-    // We will check i2c_bus_id in am335x_i2c_bus_register
-    // Apart from mode and pull_up register what about SCREWCTRL & RXACTIVE ??
-  if (bus->i2c_bus_id == I2C1) {
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_CS0) = (BBB_MUXMODE(MODE2) | BBB_PU_EN);
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D1) = (BBB_MUXMODE(MODE2) | BBB_PU_EN);
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_UART1_TXD) = (BBB_MUXMODE(MODE3) | BBB_PU_EN);
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_UART1_RXD) = (BBB_MUXMODE(MODE3) | BBB_PU_EN);
-  } else if (bus->i2c_bus_id == I2C2) {
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_UART1_RTSN) = (BBB_MUXMODE(MODE3) | BBB_PU_EN);
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_UART1_CTSN) = (BBB_MUXMODE(MODE3) | BBB_PU_EN);
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = (BBB_MUXMODE(MODE3) | BBB_PU_EN);
-    REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = (BBB_MUXMODE(MODE3) | BBB_PU_EN);
-  } else {
-  status = false;  
-  }
-  return status;   
-}
-*/
-
-/* ref. Table 21-4 I2C Clock Signals */
-/* 
- For I2C1/2
-
- Interface clock - 100MHz - CORE_LKOUTM4 / 2 - pd_per_l4ls_gclk
-
- Functional clock - 48MHz - PER_CLKOUTM2 / 4 - pd_per_ic2_fclk
-*/
 
-/*
-static void am335x_i2c1_i2c2_module_clk_config(bbb_i2c_bus *bus)
-{
-*/
-/*0x2 = SW_WKUP : SW_WKUP: Start a software forced wake-up
-transition on the domain. */
-/*
-  REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_L4LS_CLKSTCTRL) |=
-                        AM335X_CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
-  while((REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_L4LS_CLKSTCTRL) &
-                        AM335X_CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL) !=
-                        AM335X_CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP);
-*/
-
-/* 0x2 = ENABLE : Module is explicitly enabled. Interface clock (if not
-used for functions) may be gated according to the clock domain
-state. Functional clocks are guarantied to stay present. As long as in
-this configuration, power domain sleep transition cannot happen.*/
- /* REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_L4LS_CLKCTRL) |=
-                        AM335X_CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE;
-
-  while((REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_L4LS_CLKCTRL) &
-      AM335X_CM_PER_L4LS_CLKCTRL_MODULEMODE) != AM335X_CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE);
-*/
-/*0x2 = ENABLE : Module is explicitly enabled. Interface clock (if not
-used for functions) may be gated according to the clock domain
-state. Functional clocks are guarantied to stay present. As long as in
-this configuration, power domain sleep transition cannot happen.*/
-/*
-  if (bus->i2c_bus_id == I2C1) {
-  REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_I2C1_CLKCTRL) |=
-                             AM335X_CM_PER_I2C1_CLKCTRL_MODULEMODE_ENABLE;
-
-  while(REG((AM335X_CM_PER_ADDR + AM335X_CM_PER_I2C1_CLKCTRL) &
-     AM335X_CM_PER_I2C1_CLKCTRL_MODULEMODE) != AM335X_CM_PER_I2C1_CLKCTRL_MODULEMODE_ENABLE);
-  } else if (bus->i2c_bus_id == I2C2) {
-  REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_I2C2_CLKCTRL) |=
-                             AM335X_CM_PER_I2C2_CLKCTRL_MODULEMODE_ENABLE;
-
-  while(REG((AM335X_CM_PER_ADDR + AM335X_CM_PER_I2C2_CLKCTRL) &
-     AM335X_CM_PER_I2C2_CLKCTRL_MODULEMODE) != AM335X_CM_PER_I2C2_CLKCTRL_MODULEMODE_ENABLE);
-
-  while(!(REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_L4LS_CLKSTCTRL) &
-           (AM335X_CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK |
-            AM335X_CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_I2C_FCLK)));
-
-  }
-}
-*/
+static void flush_fifo(i2c_bus *base);
 
 static void am335x_i2c0_pinmux(bbb_i2c_bus *bus)
 {
@@ -303,43 +223,59 @@ static void I2C0ModuleClkConfig(void)
            CM_WKUP_I2C0_CLKCTRL_IDLEST));
 }
 
-/*
-void am335x_i2c_init(bbb_i2c_bus *bus, uint32_t input_clock)
-{
-  // am335x_i2c_pinmux()
-  // am335x_i2c1_i2c2_module_clk_config
-}
-*/
+
 
 static bool am335x_i2c_busbusy(volatile bbb_i2c_regs *regs)
 {
   bool status;
+  int stat;
+  int timeout=I2C_TIMEOUT;
+
+
+   while ((stat = readw(&regs->BBB_I2C_IRQSTATUS_RAW) &
+    AM335X_I2C_IRQSTATUS_RAW_BB) && timeout--) {
+
+    writew(stat, &regs->BBB_I2C_IRQSTATUS);
+    udelay(100);
+  }
 
-  if (REG(&regs->BBB_I2C_IRQSTATUS_RAW) & AM335X_I2C_IRQSTATUS_RAW_BB)
+  if (timeout <= 0) {
+    printf("Timed out in wait_for_bb: status=%04x\n",
+           stat);
+   status = true;
+  }
+  else
   {
-    status = true; 
-  } else {
-    status = false;
+  writew(0xFFFF, &regs->BBB_I2C_IRQSTATUS);   /* clear delayed stuff*/
+   status = false;
   }
+
   return status; 
 }
 
 static void am335x_i2c_reset(bbb_i2c_bus *bus)
 {
   volatile bbb_i2c_regs *regs = bus->regs;
-  printk("reset bus->reg is %x \n",bus->regs);
-  /* Disable I2C module at the time of initialization*/
-  /*Should I use write32 ?? I guess mmio_clear is correct choice here*/
-  printk("inside BBB_I2C_CON value is %x \n",&regs->BBB_I2C_CON);
-  mmio_clear((&regs->BBB_I2C_CON),AM335X_I2C_CON_I2C_EN);
-  mmio_clear((&regs->BBB_I2C_SYSC),AM335X_I2C_SYSC_AUTOIDLE);  
-  //REG(bus->regs + AM335X_I2C_CON) &= ~(AM335X_I2C_CON_I2C_EN);
-  //REG(bus->regs + AM335X_I2C_SYSC) &= ~(AM335X_I2C_SYSC_AUTOIDLE);
-  
-  /*
-  can I clear all the interrupt here ?
-  mmio_write(get_reg_addr(bbb_i2c_bus->reg->AM335X_I2C_IRQ_ENABLE_CLR), ??)
-  */
+   int timeout = I2C_TIMEOUT; 
+ 
+   if (readw(&regs->BBB_I2C_CON) & I2C_CON_EN) {
+    writew(0, &regs->BBB_I2C_CON);
+    udelay(50000);
+  }
+
+  writew(0x2, &regs->BBB_I2C_SYSC); /* for ES2 after soft reset */
+  udelay(1000);
+
+  writew(I2C_CON_EN, &regs->BBB_I2C_CON);
+  while (!(readw(&regs->BBB_I2C_SYSS) & I2C_SYSS_RDONE) && timeout--) {
+    if (timeout <= 0) {
+      puts("ERROR: Timeout in soft-reset\n");
+      return;
+    }
+    udelay(1000);
+  }
+
+
 }
 
 /*
@@ -368,7 +304,7 @@ static void am335x_i2c_next_byte(bbb_i2c_bus *bus)
 {
   i2c_msg *msg;
   
-  printk("Enter next_byte\n");
+
   ++bus->msgs;
   --bus->msg_todo;
 
@@ -410,61 +346,26 @@ static void am335x_clean_interrupts(volatile bbb_i2c_regs *regs)
 static void am335x_i2c_setup_read_transfer(bbb_i2c_bus *bus, volatile bbb_i2c_regs *regs, const i2c_msg *msgs, bool send_stop)
 { 
   volatile unsigned int no_bytes;
-  //am335x_i2c_masterint_enable(regs, AM335X_I2C_INT_RECV_READY);
-   // No of data to be transmitted at a time
-  REG(&regs->BBB_I2C_CNT) = 0x02;
-  no_bytes = REG(&regs->BBB_I2C_CNT);
-
-  // I2C Controller in Master Mode
-  REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_MST_TX | AM335X_I2C_CON_I2C_EN | AM335X_I2C_CON_START | AM335X_I2C_CON_MST;
-  printk("set master in transmission mode %x \n",REG(&regs->BBB_I2C_CON));
+  int status;
 
-  // Set Slave address & Master enable, bring out of reset
-  REG(&regs->BBB_I2C_SA) = msgs->addr;
-  printf("slave address : %x\n",REG(&regs->BBB_I2C_SA));
-
-  // clear status of all interrupts
-  am335x_clean_interrupts(regs);
-  printk("\n set memory address to read\n");
-    
-  // transmit interrupt is enabled
-  am335x_i2c_masterint_enable(regs,AM335X_I2C_IRQSTATUS_XRDY);
-  printk("Enable transmit interrupt \n");
-  //start condition 
-  REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_START;
-  printk("start transmission \n");
-  while(am335x_i2c_busbusy(regs) == 0);
-  printk("bus is free \n"); 
-  printk("CNT : %x\n", no_bytes);
-  while(0 != no_bytes);
-  printk("total msg count for tranmission is zero \n");
-  while( !(am335x_i2c_intrawstatus(regs) & (AM335X_I2C_IRQSTATUS_ARDY)));
+    REG(&regs->BBB_I2C_CNT) = bus->current_msg_todo;
   
-  printk("Enter read transfer \n");
-   // No of data to be received at a time(msg_count!!)
-  printk("msg_todo for read is %d \n",bus->msg_todo);
-  REG(&regs->BBB_I2C_CNT) = bus->msg_todo;
-  
-  // clear status of all interrupts
-  //am335x_clean_interrupts(regs);
-
   // I2C Controller in Master Mode
   REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_MST_RX | AM335X_I2C_CON_I2C_EN | AM335X_I2C_CON_MST;
-  printk("Set master to receiver mode %x \n", REG(&regs->BBB_I2C_CON));
+  
   // receive interrupt is enabled
   am335x_i2c_masterint_enable(regs, AM335X_I2C_INT_RECV_READY | AM335X_I2C_INT_STOP_CONDITION);
-  
+
+
   if (send_stop) {
     // stop condition
-    printk("stop to read\n");
     REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_STOP; 
   } else {
     // start condition
-    printk("start to read\n");
     REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_START;
   }
-  while(am335x_i2c_busbusy(regs) == 0);
-  printk("Exit read transfer\n");
+
+
 }
 
 
@@ -473,85 +374,63 @@ static void am335x_i2c_continue_read_transfer(
   volatile bbb_i2c_regs *regs
 )
 {
-  printk("enter continue read transfer \n");
+   
   bus->current_msg_byte[bus->already_transferred] = REG(&regs->BBB_I2C_DATA);
+ 
   bus->already_transferred++;
   am335x_int_clear(regs,AM335X_I2C_INT_RECV_READY);
-  printk("clear RRDY in continue read transfer\n");
+  
   
   if (bus->already_transferred == REG(&regs->BBB_I2C_CNT)) {
-    printk("continue read transfer finished \n");
-    //am335x_i2c_setup_read_transfer(bus,regs,false);
+    
+
     am335x_i2c_masterint_disable(regs, AM335X_I2C_INT_RECV_READY);
-    printk("disable RRDY in continue read transfer\n");
+    
     REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_STOP;
-    printk("stop condition in continue read transfer %x\n",REG(&regs->BBB_I2C_CON));
+    
   }
 }
 
+
 static void am335x_i2c_continue_write(bbb_i2c_bus *bus, volatile bbb_i2c_regs *regs)
 { 
-   REG(&regs->BBB_I2C_DATA) = 0x00;
-   am335x_int_clear(regs, AM335X_I2C_IRQSTATUS_XRDY);
-   printk("clear XRDY continue write\n");
-   /*
-   if (bus->already_transferred == REG(&regs->BBB_I2C_CNT)) {
-   printk("\n finished transfer \n");
-   am335x_i2c_masterint_disable(regs, AM335X_I2C_IRQSTATUS_XRDY);
-   printk("disable XRDY continue write \n");
-   REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_STOP;
-   } else {
-     printk("write memory address \n");
-     REG(&regs->BBB_I2C_DATA) = *bus->current_msg_byte;
-  }
-   */
 
-  /* 
-   if (bus->already_transferred == bus->msg_todo) {
-     printk("finished transfer \n");
-     am335x_int_clear(regs, AM335X_I2C_IRQSTATUS_XRDY);
-     REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_STOP;
-   } else { 
-     printk("remaining byte \n");
-     REG(&regs->BBB_I2C_DATA) = bus->current_msg_byte[bus->already_transferred];
-     printk("%s",REG(&regs->BBB_I2C_DATA));
-     bus->already_transferred++;   
-   }
-   */
+  
+  writeb(0x0,&regs->BBB_I2C_DATA);
+
+   writew(AM335X_I2C_IRQSTATUS_XRDY, &regs->BBB_I2C_IRQSTATUS);
+  
+
 }
 
-static void am335x_i2c_setup_write_transfer(bbb_i2c_bus *bus,volatile bbb_i2c_regs *regs)
+static void am335x_i2c_setup_write_transfer(bbb_i2c_bus *bus,volatile bbb_i2c_regs *regs, const i2c_msg *msgs)
 {
   volatile unsigned int no_bytes; 
-  printk(" \n Enter write transfer \n"); 
  
+
   // Following data count specify bytes to be transmitted
-  REG(&regs->BBB_I2C_CNT) = bus->msg_todo;
+  REG(&regs->BBB_I2C_CNT) = bus->current_msg_todo;
   no_bytes = REG(&regs->BBB_I2C_CNT);
-  // clear status of all interrupts
-  // Already cleaned during reset
-  am335x_clean_interrupts(regs);
-  
+  REG(&regs->BBB_I2C_SA) = msgs->addr;
+
   // I2C Controller in Master transmitter Mode
   REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_MST_TX | AM335X_I2C_CON_I2C_EN;
-  printk("enable master in transmiter mode setup write %x\n",REG(&regs->BBB_I2C_CON));
+
+  am335x_clean_interrupts(regs);
   
   // transmit interrupt is enabled
-  am335x_i2c_masterint_enable(regs,AM335X_I2C_IRQSTATUS_XRDY);
-  printk("enable XRDY setup write\n");
+  am335x_i2c_masterint_enable(regs,AM335X_I2C_IRQSTATUS_XRDY );
+  
  
   //start condition 
   REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_START;
-  printk("set start condition in setup write %x \n",REG(&regs->BBB_I2C_CON));
+
   
-  while(am335x_i2c_busbusy(regs) == 0);
-  printk("CNT in setup write : %x \n",REG(&regs->BBB_I2C_CNT));
-  printk("setup write msg_todo %x \n",bus->current_todo);
-  while(0 != no_bytes);
-  printk("check whether ???\n");
-  printk("RAW =  %x",REG(&regs->BBB_I2C_IRQSTATUS_RAW));
+  while(am335x_i2c_busbusy(regs)==0);
+
+ 
   while( !((am335x_i2c_intrawstatus(regs)) & (AM335X_I2C_IRQSTATUS_ARDY)));
-  printk("exit setup write \n");
+
 }
 
 
@@ -562,9 +441,7 @@ static void am335x_i2c_setup_transfer(bbb_i2c_bus *bus, volatile bbb_i2c_regs *r
   bool send_stop = false;
   uint32_t i;
 
-  printk("Enter setup transfer\n");
   bus->current_todo = msgs[0].len;
-
   for (i = 1; i < msg_todo && (msgs[i].flags & I2C_M_NOSTART) != 0; ++i) {
     bus->current_todo += msgs[i].len;
   }
@@ -574,18 +451,22 @@ static void am335x_i2c_setup_transfer(bbb_i2c_bus *bus, volatile bbb_i2c_regs *r
   REG(&bus->regs->BBB_I2C_BUF) |= AM335X_I2C_BUF_TXFIFO_CLR;
   REG(&bus->regs->BBB_I2C_BUF) |= AM335X_I2C_BUF_RXFIFO_CLR;
   am335x_i2c_set_address_size(msgs,regs);
-  bus->read = ((bus->read == true) ? 0:1); 
+
+ 
+  bus->read = (msgs->flags & I2C_M_RD) != 0;
+    
   bus->already_transferred = (bus->read == true) ? 0 : 1;
 
   if (bus->read) {
     if (REG(&regs->BBB_I2C_CNT) == 1) {
+     
       send_stop = true;
     }
-    printk("configure to read bus\n");
+ 
     am335x_i2c_setup_read_transfer(bus,regs,msgs,send_stop);
   } else {
-    printk("configure to write bus\n");
-    am335x_i2c_setup_write_transfer(bus,regs);
+    
+    am335x_i2c_setup_write_transfer(bus,regs,msgs);
   }
   
 }
@@ -597,42 +478,45 @@ static void am335x_i2c_interrupt(void *arg)
   /* get status of enabled interrupts */
   uint32_t irqstatus = REG(&regs->BBB_I2C_IRQSTATUS);
   bool done = false;
-  printk("\n inside interrupt function \n");
   /* Clear all enabled interrupt except receive ready and transmit ready interrupt in status register */ 
-  REG(&regs->BBB_I2C_IRQSTATUS) = (irqstatus & ~(AM335X_I2C_IRQSTATUS_RRDY | AM335X_I2C_IRQSTATUS_XRDY));
-  printk("\n irqstatus = %x \n",REG(&regs->BBB_I2C_IRQSTATUS));
+  REG(&regs->BBB_I2C_IRQSTATUS) = (irqstatus & ~( AM335X_I2C_IRQSTATUS_RRDY | AM335X_I2C_IRQSTATUS_XRDY));
 
   if (irqstatus & AM335X_I2C_INT_RECV_READY) {
-     printk("\nInside receive interrupt\n");
+   delay_bbb_i2c
+
     am335x_i2c_continue_read_transfer(bus, regs);
   }
  
   if (irqstatus & AM335X_I2C_IRQSTATUS_XRDY) {
-    printk("\ninside transmit interrupt \n");
+
     am335x_i2c_continue_write(bus,regs);
   }
  
   if (irqstatus & AM335X_I2C_IRQSTATUS_NACK) {
     done = true;
-    printk("inside NACK\n");
+   
     am335x_i2c_masterint_disable(regs,AM335X_I2C_IRQSTATUS_NACK);
   }
 
+  if (irqstatus & AM335X_I2C_IRQSTATUS_ARDY) {
+   done = true;
+  writew(I2C_STAT_ARDY, &regs->BBB_I2C_IRQSTATUS);
+  }
+
+
   if (irqstatus & AM335X_I2C_IRQSTATUS_BF) {
     done = true;
-    printk("inside BF \n ");
+   
   }
 
   if (done) {
     uint32_t err = irqstatus & BBB_I2C_IRQ_ERROR;
-    printk("interrupt done \n");
-   
+
     am335x_i2c_next_byte(bus);
 
-    if (bus->msg_todo == 0 || err != 0) {
+    if (bus->msg_todo == 0 ) {
     rtems_status_code sc;
-  
-    // am335x_i2c_disable_interrupts(regs);
+
     am335x_i2c_masterint_disable(regs, (AM335X_I2C_IRQSTATUS_RRDY | AM335X_I2C_IRQSTATUS_XRDY | AM335X_I2C_IRQSTATUS_BF));
 
     REG(&regs->BBB_I2C_IRQSTATUS) = err;
@@ -641,6 +525,7 @@ static void am335x_i2c_interrupt(void *arg)
     _Assert(sc == RTEMS_SUCCESSFUL);
     (void) sc;
     } else {
+    
       am335x_i2c_setup_transfer(bus, regs);
     }
   }
@@ -652,7 +537,6 @@ static int am335x_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
   bbb_i2c_bus *bus = (bbb_i2c_bus *)base;
   volatile bbb_i2c_regs *regs;
   uint32_t i;
- printk("\n enter transfer ");
   rtems_task_wake_after(1);
   
 
@@ -668,11 +552,11 @@ static int am335x_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
   
   bus->msgs = &msgs[0];
   bus->msg_todo = msg_count;
-  printk("total msg = msg_count : %x \n",bus->msg_todo);
+ 
+  
   bus->current_msg_todo = msgs[0].len;// current data size
   bus->current_msg_byte = msgs[0].buf;// current data
-  printk("\n current_msg_todo %x \n ",msgs[0].len);
-  printk("\n current_msg_byte %x \n ",msgs[0].buf);
+  
   bus->task_id = rtems_task_self();
 
   regs = bus->regs;
@@ -688,8 +572,6 @@ static int am335x_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
 
     return -ETIMEDOUT;
   }
-  printk("exit transfer\n");
-  // return bus->regs->BBB_I2C_IRQSTATUS == 0 ? 0 : -EIO;
   return 0;
 }
 
@@ -699,21 +581,17 @@ static int am335x_i2c_set_clock(i2c_bus *base, unsigned long clock)
   volatile bbb_i2c_regs *regs = bus->regs;
   uint32_t prescaler,divider;
 
-  printk("set clock start\n"); 
+  
   prescaler = (BBB_I2C_SYSCLK / BBB_I2C_INTERNAL_CLK) -1;
-  printk("PSC offset %x \n ",&regs->BBB_I2C_PSC);
-  printk("PSC offset %x \n", &bus->regs->BBB_I2C_PSC);
-  //mmio_write((&regs->BBB_I2C_PSC), prescaler);
+
   REG(&bus->regs->BBB_I2C_PSC) = prescaler;
   
   divider = BBB_I2C_INTERNAL_CLK/(2*clock);
-  printk("SCLL offset %x \n",&bus->regs->BBB_I2C_SCLL); 
-  //mmio_write((&regs->BBB_I2C_SCLL), (divider - 7));
+  
   REG(&bus->regs->BBB_I2C_SCLL) = (divider - 7);
-  //mmio_write((&regs->BBB_I2C_SCLH), (divider - 5));
-  printk("SCHL offset %x\n",&bus->regs->BBB_I2C_SCLH);
+  
   REG(&bus->regs->BBB_I2C_SCLH) = (divider - 5);
-  printk("set clock end \n");
+
   return 0;
 }
 
@@ -721,11 +599,11 @@ static void am335x_i2c_destroy(i2c_bus *base)
 {
   bbb_i2c_bus *bus = (bbb_i2c_bus *) base;
   rtems_status_code sc;
-  printk(" starting destroy\n"); 
+ 
   sc = rtems_interrupt_handler_remove(bus->irq, am335x_i2c_interrupt, bus);
   _Assert(sc == RTEMS_SUCCESSFUL);
   (void)sc;
-  printk("end destroy\n");
+ 
   i2c_bus_destroy_and_free(&bus->base);
 }
 
@@ -759,7 +637,7 @@ int am335x_i2c_bus_register(
 // 4. configure bus speed  
   bus->input_clock = input_clock; // By default 100KHz. Normally pass 100KHz as argument 
  
-  printk("Before set clock \n"); 
+  
   err = am335x_i2c_set_clock(&bus->base, I2C_BUS_CLOCK_DEFAULT);
  
   if (err != 0) {
@@ -771,7 +649,11 @@ int am335x_i2c_bus_register(
   
   //bring I2C out of reset
 
-   REG(&bus->regs->BBB_I2C_CON) |= AM335X_I2C_CON_I2C_EN;
+   udelay(1000);
+  flush_fifo(&bus->base);
+  writew(0xFFFF, &bus->regs->BBB_I2C_IRQSTATUS);
+
+
  
   // 5. Start interrupt service routine & one interrupt at a time 
   sc  = rtems_interrupt_handler_install(
@@ -791,6 +673,30 @@ int am335x_i2c_bus_register(
   bus->base.transfer = am335x_i2c_transfer;
   bus->base.set_clock = am335x_i2c_set_clock;
   bus->base.destroy = am335x_i2c_destroy;
-  printk("exit register\n");
+  
   return i2c_bus_register(&bus->base,bus_path);
 }
+
+
+static void flush_fifo(i2c_bus *base)
+{
+  bbb_i2c_bus *bus = (bbb_i2c_bus *) base;
+  volatile bbb_i2c_regs *regs = bus->regs;
+
+ 
+  int stat;
+
+  /*
+   * note: if you try and read data when its not there or ready
+   * you get a bus error
+   */
+  while (1) {
+    stat = readw(&bus->regs->BBB_I2C_IRQSTATUS);
+    if (stat == I2C_STAT_RRDY) {
+      readb(&bus->regs->BBB_I2C_DATA);
+      writew(I2C_STAT_RRDY, &bus->regs->BBB_I2C_IRQSTATUS);
+      udelay(1000);
+    } else
+      break;
+  }
+}
diff --git a/c/src/lib/libbsp/arm/beagle/include/i2c.h b/c/src/lib/libbsp/arm/beagle/include/i2c.h
index d4a9e32..a4fcf21 100644
--- a/c/src/lib/libbsp/arm/beagle/include/i2c.h
+++ b/c/src/lib/libbsp/arm/beagle/include/i2c.h
@@ -132,11 +132,11 @@ extern "C" {
 
 
 #define DISP_LINE_LEN 128
-#define I2C_TIMEOUT 1000
+#define I2C_TIMEOUT 500
 
 #define I2C_BUS_MAX 3
 
-#define I2C_BASE1         (OMAP34XX_CORE_L4_IO_BASE + 0x070000)
+#define I2C_BASE1         (OMAP34XX_CORE_L4_IO_BASE + 0x070000) //0x48000000+0x070000
 
 #define I2C_DEFAULT_BASE      I2C_BASE1
 
@@ -356,7 +356,7 @@ static inline rtems_status_code beagle_i2c_read(
     | AM335X_I2C_IRQSTATUS_ARDY \
     | AM335X_I2C_IRQSTATUS_RRDY \
     | AM335X_I2C_IRQSTATUS_XRDY \
-    | AM335X_I2C_IRQSTATUS_XUDF)
+    | AM335X_I2C_IRQSTATUS_XUDF )
 
 #define BBB_I2C_IRQ_USED \
   ( BBB_I2C_IRQ_ERROR \
@@ -378,6 +378,8 @@ static inline rtems_status_code beagle_i2c_read(
 #define MODE2 2
 #define MODE3 3
 
+#define delay_bbb_i2c printf("     ");
+
 typedef enum {
   I2C0,
   I2C1,
@@ -478,6 +480,9 @@ static inline int bbb_register_i2c_2(void)
 }
 
 
+
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
-- 
2.7.4






More information about the devel mailing list