[PATCH 1/2] beagle i2c: Add beaglebone i2c driver code

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


From: Punit Vara <punitvara at gmail.com>

This patch add the I2C driver code for Beaglebone Black:
- Add beagle/i2c/bbb-i2c.c  i2c driver code
- Modify include/i2c.h
- Modify beagle/Makefile.am

But i2c can not work currently
---
 c/src/lib/libbsp/arm/beagle/Makefile.am   |   4 +-
 c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c | 796 ++++++++++++++++++++++++++++++
 c/src/lib/libbsp/arm/beagle/include/i2c.h | 153 +++++-
 3 files changed, 934 insertions(+), 19 deletions(-)
 create mode 100644 c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c

diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am
index 8bb8478..4da72bc 100644
--- a/c/src/lib/libbsp/arm/beagle/Makefile.am
+++ b/c/src/lib/libbsp/arm/beagle/Makefile.am
@@ -88,7 +88,6 @@ libbsp_a_SOURCES += ../../shared/timerstub.c
 libbsp_a_SOURCES += ../../shared/cpucounterread.c
 libbsp_a_SOURCES += ../shared/startup/bsp-start-memcpy.S
 libbsp_a_SOURCES += ../shared/arm-cp15-set-exception-handler.c
-libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.c
 
 # Startup
 libbsp_a_SOURCES += startup/bspreset.c
@@ -116,6 +115,9 @@ libbsp_a_SOURCES += ../../shared/console.c \
 # I2C
 libbsp_a_SOURCES += misc/i2c.c
 
+# i2c
+libbsp_a_SOURCES += i2c/bbb-i2c.c
+
 # GPIO
 libbsp_a_SOURCES += gpio/bbb-gpio.c
 
diff --git a/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c b/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c
new file mode 100644
index 0000000..6b790e5
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c
@@ -0,0 +1,796 @@
+/**
+ * @file
+ *
+ * @ingroup arm_beagle
+ *
+ * @brief BeagleBoard I2C bus initialization and API Support.
+ */
+
+/*
+ * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdio.h>
+#include <bsp/i2c.h>
+#include <libcpu/am335x.h>
+#include <rtems/irq-extension.h>
+#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 am335x_i2c0_pinmux(bbb_i2c_bus *bus)
+{
+  REG(bus->regs + AM335X_CONF_I2C0_SDA) =
+  (BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN);
+
+  REG(bus->regs + AM335X_CONF_I2C0_SCL) =
+  (BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN); 
+}
+
+static void I2C0ModuleClkConfig(void)
+{
+    /* Configuring L3 Interface Clocks. */
+
+    /* Writing to MODULEMODE field of CM_PER_L3_CLKCTRL register. */
+    REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKCTRL) |=
+          CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE;
+
+    /* Waiting for MODULEMODE field to reflect the written value. */
+    while(CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKCTRL) &
+           CM_PER_L3_CLKCTRL_MODULEMODE));
+
+    /* Writing to MODULEMODE field of CM_PER_L3_INSTR_CLKCTRL register. */
+    REG(AM335X_CM_PER_ADDR + CM_PER_L3_INSTR_CLKCTRL) |=
+          CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE;
+
+    /* Waiting for MODULEMODE field to reflect the written value. */
+    while(CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_INSTR_CLKCTRL) &
+           CM_PER_L3_INSTR_CLKCTRL_MODULEMODE));
+
+    /* Writing to CLKTRCTRL field of CM_PER_L3_CLKSTCTRL register. */
+    REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKSTCTRL) |=
+          CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
+
+    /* Waiting for CLKTRCTRL field to reflect the written value. */
+    while(CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKSTCTRL) &
+           CM_PER_L3_CLKSTCTRL_CLKTRCTRL));
+
+    /* Writing to CLKTRCTRL field of CM_PER_OCPWP_L3_CLKSTCTRL register. */
+    REG(AM335X_CM_PER_ADDR + CM_PER_OCPWP_L3_CLKSTCTRL) |=
+          CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
+
+    /*Waiting for CLKTRCTRL field to reflect the written value. */
+    while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_OCPWP_L3_CLKSTCTRL) &
+           CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL));
+
+    /* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */
+    REG(AM335X_CM_PER_ADDR + CM_PER_L3S_CLKSTCTRL) |=
+          CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
+
+    /*Waiting for CLKTRCTRL field to reflect the written value. */
+    while(CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3S_CLKSTCTRL) &
+           CM_PER_L3S_CLKSTCTRL_CLKTRCTRL));
+
+    /* Checking fields for necessary values.  */
+
+    /* Waiting for IDLEST field in CM_PER_L3_CLKCTRL register to be set to 0x0. */
+    while((CM_PER_L3_CLKCTRL_IDLEST_FUNC << CM_PER_L3_CLKCTRL_IDLEST_SHIFT)!=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKCTRL) &
+           CM_PER_L3_CLKCTRL_IDLEST));
+
+    /*
+    ** Waiting for IDLEST field in CM_PER_L3_INSTR_CLKCTRL register to attain the
+    ** desired value.
+    */
+    while((CM_PER_L3_INSTR_CLKCTRL_IDLEST_FUNC <<
+           CM_PER_L3_INSTR_CLKCTRL_IDLEST_SHIFT)!=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_INSTR_CLKCTRL) &
+           CM_PER_L3_INSTR_CLKCTRL_IDLEST));
+
+    /*
+    ** Waiting for CLKACTIVITY_L3_GCLK field in CM_PER_L3_CLKSTCTRL register to
+    ** attain the desired value.
+    */
+    while(CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKSTCTRL) &
+           CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK));
+
+    /*
+    ** Waiting for CLKACTIVITY_OCPWP_L3_GCLK field in CM_PER_OCPWP_L3_CLKSTCTRL
+    ** register to attain the desired value.
+    */
+    while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_OCPWP_L3_CLKSTCTRL) &
+           CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK));
+
+    /*
+    ** Waiting for CLKACTIVITY_L3S_GCLK field in CM_PER_L3S_CLKSTCTRL register
+    ** to attain the desired value.
+    */
+    while(CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK !=
+          (REG(AM335X_CM_PER_ADDR + CM_PER_L3S_CLKSTCTRL) &
+          CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK));
+
+
+    /* Configuring registers related to Wake-Up region. */
+
+    /* Writing to MODULEMODE field of CM_WKUP_CONTROL_CLKCTRL register. */
+    REG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) |=
+          CM_WKUP_CONTROL_CLKCTRL_MODULEMODE_ENABLE;
+
+    /* Waiting for MODULEMODE field to reflect the written value. */
+    while(CM_WKUP_CONTROL_CLKCTRL_MODULEMODE_ENABLE !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) &
+           CM_WKUP_CONTROL_CLKCTRL_MODULEMODE));
+
+    /* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */
+    REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) |=
+          CM_WKUP_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
+
+    /*Waiting for CLKTRCTRL field to reflect the written value. */
+    while(CM_WKUP_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &
+           CM_WKUP_CLKSTCTRL_CLKTRCTRL));
+
+    /* Writing to CLKTRCTRL field of CM_L3_AON_CLKSTCTRL register. */
+    REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L3_AON_CLKSTCTRL) |=
+          CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL_SW_WKUP;
+
+    /*Waiting for CLKTRCTRL field to reflect the written value. */
+    while(CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L3_AON_CLKSTCTRL) &
+           CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL));
+
+    /* Writing to MODULEMODE field of CM_WKUP_I2C0_CLKCTRL register. */
+    REG(SOC_CM_WKUP_REGS + CM_WKUP_I2C0_CLKCTRL) |=
+          CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE;
+
+    /* Waiting for MODULEMODE field to reflect the written value. */
+    while(CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_I2C0_CLKCTRL) &
+           CM_WKUP_I2C0_CLKCTRL_MODULEMODE));
+
+    /* Verifying if the other bits are set to required settings. */
+
+    /*
+    ** Waiting for IDLEST field in CM_WKUP_CONTROL_CLKCTRL register to attain
+    ** desired value.
+    */
+    while((CM_WKUP_CONTROL_CLKCTRL_IDLEST_FUNC <<
+           CM_WKUP_CONTROL_CLKCTRL_IDLEST_SHIFT) !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) &
+           CM_WKUP_CONTROL_CLKCTRL_IDLEST));
+
+    /*
+    ** Waiting for CLKACTIVITY_L3_AON_GCLK field in CM_L3_AON_CLKSTCTRL
+    ** register to attain desired value.
+    */
+    while(CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKACTIVITY_L3_AON_GCLK !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L3_AON_CLKSTCTRL) &
+           CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKACTIVITY_L3_AON_GCLK));
+
+    /*
+    ** Waiting for IDLEST field in CM_WKUP_L4WKUP_CLKCTRL register to attain
+    ** desired value.
+    */
+    while((CM_WKUP_L4WKUP_CLKCTRL_IDLEST_FUNC <<
+           CM_WKUP_L4WKUP_CLKCTRL_IDLEST_SHIFT) !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_L4WKUP_CLKCTRL) &
+           CM_WKUP_L4WKUP_CLKCTRL_IDLEST));
+
+    /*
+    ** Waiting for CLKACTIVITY_L4_WKUP_GCLK field in CM_WKUP_CLKSTCTRL register
+    ** to attain desired value.
+    */
+    while(CM_WKUP_CLKSTCTRL_CLKACTIVITY_L4_WKUP_GCLK !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &
+           CM_WKUP_CLKSTCTRL_CLKACTIVITY_L4_WKUP_GCLK));
+
+    /*
+    ** Waiting for CLKACTIVITY_L4_WKUP_AON_GCLK field in CM_L4_WKUP_AON_CLKSTCTRL
+    ** register to attain desired value.
+    */
+    while(CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL_CLKACTIVITY_L4_WKUP_AON_GCLK !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL) &
+           CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL_CLKACTIVITY_L4_WKUP_AON_GCLK));
+
+    /*
+    ** Waiting for CLKACTIVITY_I2C0_GFCLK field in CM_WKUP_CLKSTCTRL
+    ** register to attain desired value.
+    */
+    while(CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &
+           CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK));
+
+    /*
+    ** Waiting for IDLEST field in CM_WKUP_I2C0_CLKCTRL register to attain
+    ** desired value.
+    */
+    while((CM_WKUP_I2C0_CLKCTRL_IDLEST_FUNC <<
+           CM_WKUP_I2C0_CLKCTRL_IDLEST_SHIFT) !=
+          (REG(SOC_CM_WKUP_REGS + CM_WKUP_I2C0_CLKCTRL) &
+           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;
+
+  if (REG(&regs->BBB_I2C_IRQSTATUS_RAW) & AM335X_I2C_IRQSTATUS_RAW_BB)
+  {
+    status = true; 
+  } else {
+    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), ??)
+  */
+}
+
+/*
+Possible values for msg->flag 
+   * - @ref I2C_M_TEN,
+   * - @ref I2C_M_RD,
+   * - @ref I2C_M_STOP,
+   * - @ref I2C_M_NOSTART,
+   * - @ref I2C_M_REV_DIR_ADDR,
+   * - @ref I2C_M_IGNORE_NAK,
+   * - @ref I2C_M_NO_RD_ACK, and
+   * - @ref I2C_M_RECV_LEN.
+*/
+
+static void am335x_i2c_set_address_size(const i2c_msg *msgs,volatile bbb_i2c_regs *regs)
+{
+    /*can be configured multiple modes here. Need to think about own address modes*/
+  if ((msgs->flags & I2C_M_TEN) == 0)  {/* 7-bit mode slave address mode*/
+  mmio_write(&regs->BBB_I2C_CON,(AM335X_I2C_CFG_7BIT_SLAVE_ADDR | AM335X_I2C_CON_I2C_EN)); 
+  } else { /* 10-bit slave address mode*/
+  mmio_write(&regs->BBB_I2C_CON,(AM335X_I2C_CFG_10BIT_SLAVE_ADDR | AM335X_I2C_CON_I2C_EN));
+  }
+  }
+
+static void am335x_i2c_next_byte(bbb_i2c_bus *bus)
+{
+  i2c_msg *msg;
+  
+  printk("Enter next_byte\n");
+  ++bus->msgs;
+  --bus->msg_todo;
+
+  msg = &bus->msgs[0];
+
+  bus->current_msg_todo = msg->len;
+  bus->current_msg_byte = msg->buf;
+}
+
+static unsigned int am335x_i2c_intrawstatus(volatile bbb_i2c_regs *regs)
+{
+  return (REG(&regs->BBB_I2C_IRQSTATUS_RAW));
+}
+
+static void am335x_i2c_masterint_enable(volatile bbb_i2c_regs *regs, unsigned int flag)
+{
+  REG(&regs->BBB_I2C_IRQENABLE_SET) |= flag;
+}
+
+static void am335x_i2c_masterint_disable(volatile bbb_i2c_regs *regs, unsigned int flag)
+{
+ REG(&regs->BBB_I2C_IRQENABLE_CLR) = flag;
+}
+
+static void am335x_int_clear(volatile bbb_i2c_regs *regs, unsigned int flag)
+{
+  REG(&regs->BBB_I2C_IRQSTATUS) = flag;
+}
+
+
+static void am335x_clean_interrupts(volatile bbb_i2c_regs *regs)
+{
+  am335x_i2c_masterint_enable(regs,0x7FFF);
+  am335x_int_clear(regs,0x7FFF);
+  am335x_i2c_masterint_disable(regs,0x7FFF); 
+}
+
+
+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));
+
+  // 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)));
+  
+  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");
+}
+
+
+static void am335x_i2c_continue_read_transfer(
+  bbb_i2c_bus *bus,
+  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++;   
+   }
+   */
+}
+
+static void am335x_i2c_setup_write_transfer(bbb_i2c_bus *bus,volatile bbb_i2c_regs *regs)
+{
+  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;
+  no_bytes = REG(&regs->BBB_I2C_CNT);
+  // clear status of all interrupts
+  // Already cleaned during reset
+  am335x_clean_interrupts(regs);
+  
+  // 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));
+  
+  // transmit interrupt is enabled
+  am335x_i2c_masterint_enable(regs,AM335X_I2C_IRQSTATUS_XRDY);
+  printk("enable XRDY setup write\n");
+ 
+  //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_intrawstatus(regs)) & (AM335X_I2C_IRQSTATUS_ARDY)));
+  printk("exit setup write \n");
+}
+
+
+static void am335x_i2c_setup_transfer(bbb_i2c_bus *bus, volatile bbb_i2c_regs *regs)
+{
+  const i2c_msg *msgs = bus->msgs;
+  uint32_t msg_todo = bus->msg_todo;
+  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;
+  }
+
+  regs = bus->regs;
+  
+  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->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);
+  }
+  
+}
+
+static void am335x_i2c_interrupt(void *arg)
+{
+  bbb_i2c_bus *bus = arg;
+  volatile bbb_i2c_regs *regs = bus->regs;
+  /* 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));
+
+  if (irqstatus & AM335X_I2C_INT_RECV_READY) {
+     printk("\nInside receive interrupt\n");
+    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_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) {
+    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;
+  
+    sc = rtems_event_transient_send(bus->task_id);
+    _Assert(sc == RTEMS_SUCCESSFUL);
+    (void) sc;
+    } else {
+      am335x_i2c_setup_transfer(bus, regs);
+    }
+  }
+}
+
+static int am335x_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
+{
+  rtems_status_code sc;
+  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);
+  
+
+  if (msg_count < 1){
+    return 1;
+  }
+ 
+  for (i=0; i<msg_count;++i) {
+      if ((msgs[i].flags & I2C_M_RECV_LEN) != 0) {
+        return -EINVAL;
+      }
+  }
+  
+  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;
+  am335x_i2c_setup_transfer(bus,regs);
+  REG(&regs->BBB_I2C_IRQENABLE_SET) = BBB_I2C_IRQ_USED;
+
+  sc = rtems_event_transient_receive(RTEMS_WAIT, bus->base.timeout);
+  // If timeout then return timeout error
+  if (sc != RTEMS_SUCCESSFUL) {
+    am335x_i2c_reset(bus);
+
+    rtems_event_transient_clear();
+
+    return -ETIMEDOUT;
+  }
+  printk("exit transfer\n");
+  // return bus->regs->BBB_I2C_IRQSTATUS == 0 ? 0 : -EIO;
+  return 0;
+}
+
+static int am335x_i2c_set_clock(i2c_bus *base, unsigned long clock)
+{
+  bbb_i2c_bus *bus = (bbb_i2c_bus *) base;
+  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;
+}
+
+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);
+}
+
+int am335x_i2c_bus_register(
+  const char *bus_path,
+  uintptr_t register_base,
+  uint32_t input_clock,
+  rtems_vector_number irq
+)
+{
+  
+  bbb_i2c_bus *bus;
+  rtems_status_code sc;
+  int err;
+  /*check bus number is >0 & <MAX*/
+
+  bus = (bbb_i2c_bus *) i2c_bus_alloc_and_init(sizeof(*bus));
+  
+  if (bus == NULL) {
+    return -1;
+  }
+
+  bus->regs = (volatile bbb_i2c_regs *) register_base;
+ 
+// 1. Enable clock for I2CX
+  I2C0ModuleClkConfig();
+// 2. pinmux setup
+  am335x_i2c0_pinmux(bus);
+// 3. RESET : Disable Master, autoideal 
+  am335x_i2c_reset(bus);
+// 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) {
+    (*bus->base.destroy)(&bus->base);
+    
+    rtems_set_errno_and_return_minus_one(-err);
+  }
+   bus->irq = irq;
+  
+  //bring I2C out of reset
+
+   REG(&bus->regs->BBB_I2C_CON) |= AM335X_I2C_CON_I2C_EN;
+ 
+  // 5. Start interrupt service routine & one interrupt at a time 
+  sc  = rtems_interrupt_handler_install(
+    irq,
+    "BBB I2C",
+    RTEMS_INTERRUPT_UNIQUE,
+    am335x_i2c_interrupt,
+    bus
+   );
+  
+  if (sc != RTEMS_SUCCESSFUL) {
+    (*bus->base.destroy)(&bus->base);
+ 
+    rtems_set_errno_and_return_minus_one(EIO);
+  }
+  // 6. start transfer for reading and writing 
+  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);
+}
diff --git a/c/src/lib/libbsp/arm/beagle/include/i2c.h b/c/src/lib/libbsp/arm/beagle/include/i2c.h
index e7d1716..d4a9e32 100644
--- a/c/src/lib/libbsp/arm/beagle/include/i2c.h
+++ b/c/src/lib/libbsp/arm/beagle/include/i2c.h
@@ -1,5 +1,5 @@
 /**
- * @file
+ 
  *
  * @ingroup arm_beagle
  *
@@ -24,7 +24,7 @@
 #define LIBBSP_ARM_BEAGLE_I2C_H
 
 #include <rtems.h>
-
+#include <dev/i2c/i2c.h>
 #include <bsp.h>
 
 #ifdef __cplusplus
@@ -180,20 +180,8 @@ struct i2c {
   unsigned short res15;
 };
 
-static unsigned short wait_for_pin( void );
-
-static void wait_for_bb( void );
-
-static void flush_fifo( void );
-
 void i2c_init( int speed, int slaveadd );
 
-static int i2c_read_byte(
-  unsigned char devaddr,
-  unsigned char regoffset,
-  unsigned char *value
-);
-
 int i2c_write(
   unsigned char chip,
   unsigned int addr,
@@ -210,10 +198,6 @@ int i2c_read(
   int len
 );
 
-static int imw ( unsigned char  chip, unsigned long addr, unsigned char byte );
-
-static int imd( unsigned char chip, unsigned int addr, unsigned int length );
-
 /**
  * @brief Initializes the I2C module @a i2c.
  *
@@ -361,6 +345,139 @@ static inline rtems_status_code beagle_i2c_read(
   return beagle_i2c_write_and_read(i2c, addr, NULL, 0, in, in_size);
 }
 
+#define BBB_I2C_SYSCLK 48000000
+#define BBB_I2C_INTERNAL_CLK 12000000
+#define BBB_I2C_SPEED_CLK 100000
+
+#define BBB_I2C_IRQ_ERROR \
+  (AM335X_I2C_IRQSTATUS_NACK \
+    | AM335X_I2C_IRQSTATUS_ROVR \
+    | AM335X_I2C_IRQSTATUS_AL \
+    | AM335X_I2C_IRQSTATUS_ARDY \
+    | AM335X_I2C_IRQSTATUS_RRDY \
+    | AM335X_I2C_IRQSTATUS_XRDY \
+    | AM335X_I2C_IRQSTATUS_XUDF)
+
+#define BBB_I2C_IRQ_USED \
+  ( BBB_I2C_IRQ_ERROR \
+    | AM335X_I2C_IRQSTATUS_AAS \
+    | AM335X_I2C_IRQSTATUS_BF \
+    | AM335X_I2C_IRQSTATUS_STC \
+    | AM335X_I2C_IRQSTATUS_GC \
+    | AM335X_I2C_IRQSTATUS_XDR \
+    | AM335X_I2C_IRQSTATUS_RDR)
+
+#define BBB_I2C_0_BUS_PATH "/dev/i2c-0"
+#define BBB_I2C_1_BUS_PATH "/dev/i2c-1"
+#define BBB_I2C_2_BUS_PATH "/dev/i2c-2"
+
+#define BBB_I2C0_IRQ 70
+#define BBB_I2C1_IRQ 71
+#define BBB_I2C2_IRQ 30
+
+#define MODE2 2
+#define MODE3 3
+
+typedef enum {
+  I2C0,
+  I2C1,
+  I2C2,
+  I2C_COUNT
+}bbb_i2c_id_t;
+
+typedef struct i2c_regs 
+{ 
+  uint32_t BBB_I2C_REVNB_LO; // 0h
+  uint32_t BBB_I2C_REVNB_HI; //4h 
+  uint32_t dummy1[2];
+  uint32_t BBB_I2C_SYSC;  // 10h =16
+  uint32_t dummy2[4];  
+  uint32_t BBB_I2C_IRQSTATUS_RAW;  //24h =36
+  uint32_t BBB_I2C_IRQSTATUS;  //28h =40
+  uint32_t BBB_I2C_IRQENABLE_SET;  //2Ch =44
+  uint32_t BBB_I2C_IRQENABLE_CLR; //30h =48
+  uint32_t BBB_I2C_WE;  // 34h = 52
+  uint32_t BBB_I2C_DMARXENABLE_SET; //38h = 56
+  uint32_t BBB_I2C_DMATXENABLE_SET;  //3Ch = 60
+  uint32_t BBB_I2C_DMARXENABLE_CLR;  //40h = 64
+  uint32_t BBB_I2C_DMATXENABLE_CLR;  //44h = 68
+  uint32_t BBB_I2C_DMARXWAKE_EN;  //48h = 72
+  uint32_t BBB_I2C_DMATXWAKE_EN;  //4Ch =76
+  uint32_t dummy3[16];
+  uint32_t BBB_I2C_SYSS;  // 90h =144
+  uint32_t BBB_I2C_BUF;  // 94h =148
+  uint32_t BBB_I2C_CNT;  // 98h =152
+  uint32_t BBB_I2C_DATA; //9Ch =156
+  uint32_t dummy4;
+  uint32_t BBB_I2C_CON;  // A4h = 164 
+  uint32_t BBB_I2C_OA;  //A8h = 168
+  uint32_t BBB_I2C_SA;  //ACh = 172
+  uint32_t BBB_I2C_PSC;  //B0h = 176
+  uint32_t BBB_I2C_SCLL;  //B4h = 180
+  uint32_t BBB_I2C_SCLH;  //B8h = 184
+  uint32_t BBB_I2C_SYSTEST;  //BCh = 188
+  uint32_t BBB_I2C_BUFSTAT;  //C0h 192
+  uint32_t BBB_I2C_OA1;  //C4h 196
+  uint32_t BBB_I2C_OA2;  //C8h 200
+  uint32_t BBB_I2C_OA3;  //CCh 204
+  uint32_t BBB_I2C_ACTOA;  //D0h 208
+  uint32_t BBB_I2C_SBLOCK;  //D4h 212
+}bbb_i2c_regs;
+
+typedef struct bbb_i2c_bus{
+  i2c_bus base;
+  volatile bbb_i2c_regs *regs;
+  i2c_msg *msgs;
+  uint32_t msg_todo;  
+  uint32_t current_msg_todo; // current_data_size 
+  uint8_t *current_msg_byte; // current_data
+  uint32_t current_todo;
+  bool read;
+  bool hold;
+  rtems_id task_id;
+  rtems_vector_number irq;
+  uint32_t input_clock;
+  uint32_t already_transferred;
+} bbb_i2c_bus;
+
+int am335x_i2c_bus_register(
+  const char *bus_path,
+  uintptr_t register_base,
+  uint32_t input_clock,
+  rtems_vector_number irq
+);
+
+static inline int bbb_register_i2c_0(void)
+{
+  return am335x_i2c_bus_register(
+    BBB_I2C_0_BUS_PATH,
+    AM335X_I2C0_BASE,
+    I2C_BUS_CLOCK_DEFAULT,
+    BBB_I2C0_IRQ
+  );
+}
+
+static inline int bbb_register_i2c_1(void)
+{
+  return am335x_i2c_bus_register(
+    BBB_I2C_1_BUS_PATH,
+    AM335X_I2C1_BASE,
+    I2C_BUS_CLOCK_DEFAULT,
+    BBB_I2C1_IRQ
+  );
+}
+
+static inline int bbb_register_i2c_2(void)
+{
+  return am335x_i2c_bus_register(
+    BBB_I2C_2_BUS_PATH,
+    AM335X_I2C2_BASE,
+    I2C_BUS_CLOCK_DEFAULT,
+    BBB_I2C2_IRQ
+  );
+}
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
-- 
2.7.4





More information about the devel mailing list