<div dir="ltr"><div dir="ltr"><br><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jun 25, 2019 at 1:47 AM <<a href="mailto:list@c-mauderer.de">list@c-mauderer.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Christian Mauderer <<a href="mailto:christian.mauderer@embedded-brains.de" target="_blank">christian.mauderer@embedded-brains.de</a>><br>
<br>
The old driver worked well for EEPROMS with the RTEMS EEPROM driver. But<br>
it had problems with a lot of other situations. Although it's not a<br>
direct port, the new driver is heavily modeled after the FreeBSD ti_i2c<br>
driver.<br></blockquote><div>This is great!</div><div>I have tried this patch with the FreeBSD ported IIC bus through the rtems_i2c</div><div>adaptation layer is FreeBSD and the output MATCHES the original FreeBSD i2c</div><div>scan with the ti_i2c driver. </div><div>Would also like to add that the i2c probe and i2c md in u-boot also shows the same</div><div>results. </div><div>```</div><div>SHLL [/] # i2c -a 0x50 -w16 -mtr -c10<br>aa 55 33 ee 41 33 33 35 42 4e <br>SHLL [/] # i2c -s<br>Scanning I2C devices on /dev/iic0: Hardware may not support START/STOP scanning; trying less-reliable read method.<br>24 34 50 <br></div><div>``` </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
---<br>
 bsps/arm/beagle/i2c/bbb-i2c.c     | 646 ++++++++++++++++--------------<br>
 bsps/arm/beagle/include/bsp/i2c.h |  84 +---<br>
 bsps/arm/include/libcpu/am335x.h  |  35 +-<br>
 3 files changed, 370 insertions(+), 395 deletions(-)<br>
<br>
diff --git a/bsps/arm/beagle/i2c/bbb-i2c.c b/bsps/arm/beagle/i2c/bbb-i2c.c<br>
index 3a8637d457..37b88864b9 100644<br>
--- a/bsps/arm/beagle/i2c/bbb-i2c.c<br>
+++ b/bsps/arm/beagle/i2c/bbb-i2c.c<br>
@@ -9,17 +9,14 @@<br>
 /*<br>
  * Copyright (c) 2016 Punit Vara <<a href="mailto:punitvara@gmail.com" target="_blank">punitvara@gmail.com</a>><br>
  * Copyright (c) 2017 Sichen Zhao <<a href="mailto:zsc19940506@gmail.com" target="_blank">zsc19940506@gmail.com</a>><br>
+ * Copyright (c) 2019 Christian Mauderer <<a href="mailto:christian.mauderer@embedded-brains.de" target="_blank">christian.mauderer@embedded-brains.de</a>><br>
  *<br>
  * The license and distribution terms for this file may be<br>
  * found in the file LICENSE in this distribution or at<br>
  * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
  */<br>
<br>
-/*<br>
- * Modified on Punit Vara<<a href="mailto:punitvara@gmail.com" target="_blank">punitvara@gmail.com</a>> works, currently<br>
- * the i2c file is working on the Beaglebone Black board(AM335x)<br>
- */<br>
-<br>
+#include <rtems/bspIo.h><br>
 #include <stdio.h><br>
 #include <bsp/i2c.h><br>
 #include <libcpu/am335x.h><br>
@@ -27,26 +24,114 @@<br>
 #include <rtems/counter.h><br>
 #include <bsp/bbb-gpio.h><br>
 #include <rtems/score/assert.h><br>
+#include <dev/i2c/i2c.h><br>
<br>
-static void am335x_i2c0_pinmux( bbb_i2c_bus *bus )<br>
+typedef struct bbb_i2c_bus {<br>
+  i2c_bus base;<br>
+  volatile bbb_i2c_regs *regs;<br>
+  struct {<br>
+    volatile uint32_t *ctrl_clkctrl;<br>
+    volatile uint32_t *i2c_clkctrl;<br>
+    volatile uint32_t *clkstctrl;<br>
+  } clkregs;<br>
+  struct {<br>
+    volatile uint32_t *conf_sda;<br>
+    uint32_t mmode_sda;<br>
+    volatile uint32_t *conf_scl;<br>
+    uint32_t mmode_scl;<br>
+  } pinregs;<br>
+  rtems_id task_id;<br>
+  rtems_vector_number irq;<br>
+  i2c_msg *buffer;<br>
+  size_t buffer_pos;<br>
+  int error;<br>
+  uint32_t con_reg;<br>
+} bbb_i2c_bus;<br>
+<br>
+#define TRANSFER_TIMEOUT_COUNT 100<br>
+#define FIFO_THRESHOLD 5<br>
+#define min(l,r) ((l) < (r) ? (l) : (r))<br>
+#if 0<br>
+#define debug_print(fmt, args...) printk("bbb-i2c: " fmt, ## args)<br>
+#else<br>
+#define debug_print(fmt, args...)<br>
+#endif<br>
+<br>
+static int am335x_i2c_fill_registers(<br>
+  bbb_i2c_bus *bus,<br>
+  uintptr_t register_base<br>
+)<br>
 {<br>
-  REG( bus->regs + AM335X_CONF_I2C0_SDA ) =<br>
-    ( BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN );<br>
+  /* FIXME: The pin handling should be replaced by a proper pin handling during<br>
+   * initialization. This one is heavily board specific. */<br>
+#if ! IS_AM335X<br>
+  printk ("The I2C driver currently only works on Beagle Bone. Please add your pin configs.")<br>
+  return EINVAL;<br>
+#endif<br>
+  bus->regs = (volatile bbb_i2c_regs *) register_base;<br>
+  switch ((intptr_t) bus->regs) {<br>
+  case AM335X_I2C0_BASE:<br>
+    bus->clkregs.ctrl_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +<br>
+                                 AM335X_CM_WKUP_CONTROL_CLKCTRL);<br>
+    bus->clkregs.i2c_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +<br>
+                                 AM335X_CM_WKUP_I2C0_CLKCTRL);<br>
+    bus->clkregs.clkstctrl = &REG(AM335X_SOC_CM_WKUP_REGS +<br>
+                                   AM335X_CM_WKUP_CLKSTCTRL);<br>
+    bus->pinregs.conf_sda = &REG(AM335X_PADCONF_BASE + AM335X_CONF_I2C0_SDA);<br>
+    bus->pinregs.mmode_sda = 0;<br>
+    bus->pinregs.conf_scl = &REG(AM335X_PADCONF_BASE + AM335X_CONF_I2C0_SCL);<br>
+    bus->pinregs.mmode_scl = 0;<br>
+    break;<br>
+  case AM335X_I2C1_BASE:<br>
+    bus->clkregs.ctrl_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +<br>
+                                 AM335X_CM_WKUP_CONTROL_CLKCTRL);<br>
+    bus->clkregs.i2c_clkctrl = &REG(AM335X_CM_PER_ADDR +<br>
+                                 AM335X_CM_PER_I2C1_CLKCTRL);<br>
+    bus->clkregs.clkstctrl = NULL;<br>
+    bus->pinregs.conf_sda = &REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D1);<br>
+    bus->pinregs.mmode_sda = 2;<br>
+    bus->pinregs.conf_scl = &REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_CS0);<br>
+    bus->pinregs.mmode_scl = 2;<br>
+    break;<br>
+  case AM335X_I2C2_BASE:<br>
+    bus->clkregs.ctrl_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +<br>
+                                 AM335X_CM_WKUP_CONTROL_CLKCTRL);<br>
+    bus->clkregs.i2c_clkctrl = &REG(AM335X_CM_PER_ADDR +<br>
+                                 AM335X_CM_PER_I2C2_CLKCTRL);<br>
+    bus->clkregs.clkstctrl = NULL;<br>
+    bus->pinregs.conf_sda = &REG(AM335X_PADCONF_BASE + AM335X_CONF_UART1_CTSN);<br>
+    bus->pinregs.mmode_sda = 3;<br>
+    bus->pinregs.conf_scl = &REG(AM335X_PADCONF_BASE + AM335X_CONF_UART1_RTSN);<br>
+    bus->pinregs.mmode_scl = 3;<br>
+    break;<br>
+  default:<br>
+    return EINVAL;<br>
+  }<br>
+  return 0;<br>
+}<br>
<br>
-  REG( bus->regs + AM335X_CONF_I2C0_SCL ) =<br>
-    ( BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN );<br>
+static void am335x_i2c_pinmux( bbb_i2c_bus *bus )<br>
+{<br>
+  *bus->pinregs.conf_sda =<br>
+    ( BBB_RXACTIVE | BBB_SLEWCTRL | bus->pinregs.mmode_sda);<br>
+<br>
+  *bus->pinregs.conf_scl =<br>
+    ( BBB_RXACTIVE | BBB_SLEWCTRL | bus->pinregs.mmode_scl);<br>
 }<br>
<br>
-static void I2C0ModuleClkConfig( void )<br>
+static void am335x_i2c_module_clk_enable( bbb_i2c_bus *bus )<br>
 {<br>
+  volatile uint32_t *ctrl_clkctrl = bus->clkregs.ctrl_clkctrl;<br>
+  volatile uint32_t *i2c_clkctrl = bus->clkregs.i2c_clkctrl;<br>
+  volatile uint32_t *clkstctrl = bus->clkregs.clkstctrl;<br>
+<br>
   /* Writing to MODULEMODE field of AM335X_CM_WKUP_I2C0_CLKCTRL register. */<br>
-  REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_I2C0_CLKCTRL ) |=<br>
-    AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE;<br>
+  *i2c_clkctrl |= AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE;<br>
<br>
   /* Waiting for MODULEMODE field to reflect the written value. */<br>
   while ( AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE !=<br>
-          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_I2C0_CLKCTRL ) &<br>
-            AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE ) ) ;<br>
+          ( *i2c_clkctrl & AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE ) )<br>
+  { /* busy wait */ }<br>
<br>
   /*<br>
    * Waiting for IDLEST field in AM335X_CM_WKUP_CONTROL_CLKCTRL<br>
@@ -54,16 +139,18 @@ static void I2C0ModuleClkConfig( void )<br>
    */<br>
   while ( ( AM335X_CM_WKUP_CONTROL_CLKCTRL_IDLEST_FUNC <<<br>
             AM335X_CM_WKUP_CONTROL_CLKCTRL_IDLEST_SHIFT ) !=<br>
-          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_CONTROL_CLKCTRL ) &<br>
-            AM335X_CM_WKUP_CONTROL_CLKCTRL_IDLEST ) ) ;<br>
-<br>
-  /*<br>
-   * Waiting for CLKACTIVITY_I2C0_GFCLK field in AM335X_CM_WKUP_CLKSTCTRL<br>
-   * register to attain desired value.<br>
-   */<br>
-  while ( AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK !=<br>
-          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_CLKSTCTRL ) &<br>
-            AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK ) ) ;<br>
+          ( *ctrl_clkctrl & AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST ) )<br>
+  { /* busy wait */ }<br>
+<br>
+  if ( clkstctrl != NULL ) {<br>
+    /*<br>
+     * Waiting for CLKACTIVITY_I2C0_GFCLK field in AM335X_CM_WKUP_CLKSTCTRL<br>
+     * register to attain desired value.<br>
+     */<br>
+    while ( AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK !=<br>
+            ( *clkstctrl & AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK ) )<br>
+    { /* busy wait */ }<br>
+  }<br>
<br>
   /*<br>
    * Waiting for IDLEST field in AM335X_CM_WKUP_I2C0_CLKCTRL register to attain<br>
@@ -71,333 +158,286 @@ static void I2C0ModuleClkConfig( void )<br>
    */<br>
   while ( ( AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST_FUNC <<<br>
             AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST_SHIFT ) !=<br>
-          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_I2C0_CLKCTRL ) &<br>
-            AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST ) ) ;<br>
-}<br>
-<br>
-static void am335x_i2c_reset( bbb_i2c_bus *bus )<br>
-{<br>
-  volatile bbb_i2c_regs *regs = bus->regs;<br>
-  int                    timeout = I2C_TIMEOUT;<br>
-<br>
-  if ( REG( &regs->BBB_I2C_CON ) & BBB_I2C_CON_EN ) {<br>
-    REG( &regs->BBB_I2C_CON ) = BBB_I2C_CON_CLR;<br>
-    udelay( 50000 );<br>
-  }<br>
-<br>
-  REG( &regs->BBB_I2C_SYSC ) = BBB_I2C_SYSC_SRST; /* for ES2 after soft reset */<br>
-  udelay( 1000 );<br>
-  REG( &regs->BBB_I2C_CON ) = BBB_I2C_CON_EN;<br>
-<br>
-  while ( !( REG( &regs->BBB_I2C_SYSS ) & BBB_I2C_SYSS_RDONE ) && timeout-- ) {<br>
-    if ( timeout <= 0 ) {<br>
-      puts( "ERROR: Timeout in soft-reset\n" );<br>
-<br>
-      return;<br>
-    }<br>
-<br>
-    udelay( 1000 );<br>
-  }<br>
+          ( *i2c_clkctrl & AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST ) ) ;<br>
 }<br>
-/*<br>
- * Possible values for msg->flag<br>
- * - @ref I2C_M_TEN,<br>
- * - @ref I2C_M_RD,<br>
- * - @ref I2C_M_STOP,<br>
- * - @ref I2C_M_NOSTART,<br>
- * - @ref I2C_M_REV_DIR_ADDR,<br>
- * - @ref I2C_M_IGNORE_NAK,<br>
- * - @ref I2C_M_NO_RD_ACK, and<br>
- * - @ref I2C_M_RECV_LEN.<br>
- */<br>
<br>
-static void am335x_i2c_set_address_size(<br>
-  const i2c_msg         *msgs,<br>
-  volatile bbb_i2c_regs *regs<br>
+static int am335x_i2c_set_clock(<br>
+  i2c_bus      *base,<br>
+  unsigned long clock<br>
 )<br>
 {<br>
-  /*<br>
-   * Can be configured multiple modes here.<br>
-   * Need to think about own address modes<br>
-   */<br>
-  if ( ( msgs->flags & I2C_M_TEN ) == 0 ) {<br>
-    /* 7-bit mode slave address mode */<br>
-    REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_7BIT_SLAVE_ADDR;<br>
-  } else {<br>
-    /* 10-bit slave address mode */<br>
-    REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_10BIT_SLAVE_ADDR;<br>
-  }<br>
-}<br>
-<br>
-static void am335x_i2c_next_byte( bbb_i2c_bus *bus )<br>
-{<br>
-  i2c_msg *msg;<br>
+  bbb_i2c_bus           *bus = (bbb_i2c_bus *) base;<br>
+  uint32_t               prescaler, divider;<br>
<br>
-  ++bus->msgs;<br>
-  --bus->msg_todo;<br>
-  msg = &bus->msgs[ 0 ];<br>
-  bus->current_msg_todo = msg->len;<br>
-  bus->current_msg_byte = msg->buf;<br>
-}<br>
+  prescaler = ( BBB_I2C_SYSCLK / BBB_I2C_INTERNAL_CLK ) - 1;<br>
+  bus->regs->BBB_I2C_PSC = prescaler;<br>
+  divider = BBB_I2C_INTERNAL_CLK / ( 2 * clock );<br>
+  bus->regs->BBB_I2C_SCLL = ( divider - 7 );<br>
+  bus->regs->BBB_I2C_SCLH = ( divider - 5 );<br>
<br>
-static void am335x_i2c_masterint_enable(<br>
-  volatile bbb_i2c_regs *regs,<br>
-  unsigned int           flag<br>
-)<br>
-{<br>
-  REG( &regs->BBB_I2C_IRQENABLE_SET ) |= flag;<br>
+  return 0;<br>
 }<br>
<br>
-static void am335x_i2c_masterint_disable(<br>
-  volatile bbb_i2c_regs *regs,<br>
-  unsigned int           flag<br>
-)<br>
+static int am335x_i2c_reset( bbb_i2c_bus *bus )<br>
 {<br>
-  REG( &regs->BBB_I2C_IRQENABLE_CLR ) = flag;<br>
-}<br>
+  volatile bbb_i2c_regs *regs = bus->regs;<br>
+  int                    timeout = 100;<br>
+  int                    err;<br>
<br>
-static void am335x_int_clear(<br>
-  volatile bbb_i2c_regs *regs,<br>
-  unsigned int           flag<br>
-)<br>
-{<br>
-  REG( &regs->BBB_I2C_IRQSTATUS ) = flag;<br>
-}<br>
+  bus->con_reg = 0;<br>
+  regs->BBB_I2C_CON = bus->con_reg;<br>
+  udelay( 50000 );<br>
<br>
-static void am335x_clean_interrupts( volatile bbb_i2c_regs *regs )<br>
-{<br>
-  am335x_i2c_masterint_enable( regs, BBB_I2C_ALL_FLAGS );<br>
-  am335x_int_clear( regs, BBB_I2C_ALL_FLAGS );<br>
-  am335x_i2c_masterint_disable( regs, BBB_I2C_ALL_FLAGS );<br>
-}<br>
-<br>
-static void am335x_i2c_setup_read_transfer(<br>
-  bbb_i2c_bus           *bus,<br>
-  volatile bbb_i2c_regs *regs,<br>
-  const i2c_msg         *msgs,<br>
-  bool                   send_stop<br>
-)<br>
-{<br>
-  REG( &regs->BBB_I2C_CNT ) = bus->current_msg_todo;<br>
+  regs->BBB_I2C_SYSC = AM335X_I2C_SYSC_SRST;<br>
+  udelay( 1000 );<br>
+  regs->BBB_I2C_CON = AM335X_I2C_CON_I2C_EN;<br>
<br>
-  REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_MST_RX | AM335X_I2C_CON_I2C_EN;<br>
+  while ( !( regs->BBB_I2C_SYSS & AM335X_I2C_SYSS_RDONE )<br>
+          && timeout >= 0 ) {<br>
+    --timeout;<br>
+    udelay( 100 );<br>
+  }<br>
<br>
-  if ( send_stop ) {<br>
-    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_START | AM335X_I2C_CON_STOP;<br>
-  } else {<br>
-    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_START;<br>
+  if ( timeout <= 0 ) {<br>
+    puts( "ERROR: Timeout in soft-reset\n" );<br>
+    return ETIMEDOUT;<br>
   }<br>
<br>
-  am335x_i2c_masterint_enable( regs, AM335X_I2C_INT_RECV_READY |<br>
-    AM335X_I2C_IRQSTATUS_ARDY );<br>
-}<br>
+  /* Disable again after reset */<br>
+  regs->BBB_I2C_CON = bus->con_reg;<br>
<br>
-static void am335x_i2c_continue_read_transfer(<br>
-  bbb_i2c_bus           *bus,<br>
-  volatile bbb_i2c_regs *regs<br>
-)<br>
-{<br>
-  bus->current_msg_byte[ bus->already_transferred ] =<br>
-    REG( &regs->BBB_I2C_DATA );<br>
+  err = am335x_i2c_set_clock( &bus->base, I2C_BUS_CLOCK_DEFAULT );<br>
+  if (err) {<br>
+    return err;<br>
+  }<br>
<br>
-  bus->already_transferred++;<br>
+  regs->BBB_I2C_BUF = AM335X_I2C_BUF_TXTRSH(FIFO_THRESHOLD) |<br>
+                              AM335X_I2C_BUF_RXTRSH(FIFO_THRESHOLD);<br>
<br>
-  REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_INT_RECV_READY;<br>
+  /* Enable the I2C controller in master mode. */<br>
+  bus->con_reg |= AM335X_I2C_CON_I2C_EN | AM335X_I2C_CON_MST;<br>
+  regs->BBB_I2C_CON = bus->con_reg;<br>
<br>
-  if ( bus->already_transferred == bus->current_msg_todo - 1 ) {<br>
-    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_STOP;<br>
-  }<br>
-}<br>
+  regs->BBB_I2C_IRQENABLE_SET =<br>
+      AM335X_I2C_IRQSTATUS_XDR | AM335X_I2C_IRQSTATUS_XRDY |<br>
+      AM335X_I2C_IRQSTATUS_RDR | AM335X_I2C_IRQSTATUS_RRDY |<br>
+      AM335X_I2C_IRQSTATUS_ARDY | AM335X_I2C_IRQSTATUS_NACK |<br>
+      AM335X_I2C_IRQSTATUS_AL;<br>
<br>
-static void am335x_i2c_continue_write(<br>
-  bbb_i2c_bus           *bus,<br>
-  volatile bbb_i2c_regs *regs<br>
-)<br>
-{<br>
-  if ( bus->already_transferred == bus->msg_todo ) {<br>
-    REG( &regs->BBB_I2C_DATA ) =<br>
-      bus->current_msg_byte[ bus->already_transferred ];<br>
-    REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_IRQSTATUS_XRDY;<br>
-    am335x_i2c_masterint_disable( regs, AM335X_I2C_IRQSTATUS_XRDY );<br>
-    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_STOP;<br>
-  } else {<br>
-    writeb( bus->current_msg_byte[ bus->already_transferred ],<br>
-      &regs->BBB_I2C_DATA );<br>
-    REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_IRQSTATUS_XRDY;<br>
-    bus->already_transferred++;<br>
-  }<br>
-}<br>
-<br>
-static void am335x_i2c_setup_write_transfer(<br>
-  bbb_i2c_bus           *bus,<br>
-  volatile bbb_i2c_regs *regs,<br>
-  const i2c_msg         *msgs<br>
-)<br>
-{<br>
-  volatile unsigned int no_bytes;<br>
-<br>
-  REG( &regs->BBB_I2C_CNT ) = bus->current_msg_todo;<br>
-  no_bytes = REG( &regs->BBB_I2C_CNT );<br>
-  (void) no_bytes; /* indicate we know that no_bytes is not referenced again */<br>
-  REG( &regs->BBB_I2C_SA ) = msgs->addr;<br>
-  REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_MST_TX | AM335X_I2C_CON_I2C_EN;<br>
-  am335x_clean_interrupts( regs );<br>
-  am335x_i2c_masterint_enable( regs, AM335X_I2C_IRQSTATUS_XRDY );<br>
-  REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_START | AM335X_I2C_CON_STOP;<br>
+  return 0;<br>
 }<br>
<br>
-static void am335x_i2c_setup_transfer(<br>
-  bbb_i2c_bus           *bus,<br>
-  volatile bbb_i2c_regs *regs<br>
-)<br>
+/* Return true if done. */<br>
+static bool am335x_i2c_transfer_intr(bbb_i2c_bus *bus, uint32_t status)<br>
 {<br>
-  const i2c_msg *msgs = bus->msgs;<br>
-  uint32_t       msg_todo = bus->msg_todo;<br>
-  bool           send_stop = false;<br>
-  uint32_t       i;<br>
+  size_t i;<br>
+  size_t amount = 0;<br>
+  volatile bbb_i2c_regs *regs = bus->regs;<br>
<br>
-  bus->current_todo = msgs[ 0 ].len;<br>
+  /* Handle errors */<br>
+  if ((status & AM335X_I2C_IRQSTATUS_NACK) != 0) {<br>
+    debug_print("NACK\n");<br>
+    regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_NACK;<br>
+    bus->error = ENXIO;<br>
+  } else if ((status & AM335X_I2C_IRQSTATUS_AL) != 0) {<br>
+    debug_print("Arbitration lost\n");<br>
+    regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_AL;<br>
+    bus->error = ENXIO;<br>
+  }<br>
<br>
-  for ( i = 1; i < msg_todo && ( msgs[ i ].flags & I2C_M_NOSTART ) != 0;<br>
-        ++i ) {<br>
-    bus->current_todo += msgs[ i ].len;<br>
+  /* Transfer finished? */<br>
+  if ((status & AM335X_I2C_IRQSTATUS_ARDY) != 0) {<br>
+    debug_print("ARDY transaction complete\n");<br>
+    if (bus->error != 0 && (bus->buffer->flags & I2C_M_STOP) == 0) {<br>
+      regs->BBB_I2C_CON = bus->con_reg | AM335X_I2C_CON_STOP;<br>
+    }<br>
+    regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_ARDY |<br>
+                              AM335X_I2C_IRQSTATUS_RDR |<br>
+                              AM335X_I2C_IRQSTATUS_RRDY |<br>
+                              AM335X_I2C_IRQSTATUS_XDR |<br>
+                              AM335X_I2C_IRQSTATUS_XRDY;<br>
+    return true;<br>
   }<br>
<br>
-  regs = bus->regs;<br>
-  REG( &bus->regs->BBB_I2C_BUF ) |= AM335X_I2C_BUF_TXFIFO_CLR;<br>
-  REG( &bus->regs->BBB_I2C_BUF ) |= AM335X_I2C_BUF_RXFIFO_CLR;<br>
-  am335x_i2c_set_address_size( msgs, regs );<br>
-  bus->read = ( msgs->flags & I2C_M_RD ) != 0;<br>
-  bus->already_transferred = ( bus->read == true ) ? 0 : 1;<br>
+  if (bus->buffer->flags & I2C_M_RD) {<br>
+    if (status & AM335X_I2C_IRQSTATUS_RDR) {<br>
+      debug_print("RDR\n");<br>
+      /* last data received */<br>
+      amount = bus->buffer->len - bus->buffer_pos;<br>
+    } else if (status & AM335X_I2C_IRQSTATUS_RRDY) {<br>
+      debug_print("RRDY\n");<br>
+      /* FIFO threshold reached */<br>
+      amount = min(FIFO_THRESHOLD, bus->buffer->len - bus->buffer_pos);<br>
+    }<br>
<br>
-  if ( bus->read ) {<br>
-    if ( bus->current_msg_todo == 1 ) {<br>
-      send_stop = true;<br>
+    debug_print("Read %d bytes\n", amount);<br>
+    for (i = 0; i < amount; i++) {<br>
+      bus->buffer->buf[bus->buffer_pos] = (uint8_t)(regs->BBB_I2C_DATA);<br>
+      ++bus->buffer_pos;<br>
     }<br>
<br>
-    am335x_i2c_setup_read_transfer( bus, regs, msgs, send_stop );<br>
+    if (status & AM335X_I2C_IRQSTATUS_RDR) {<br>
+      regs->BBB_I2C_IRQSTATUS =AM335X_I2C_IRQSTATUS_RDR;<br>
+    }<br>
+    if (status & AM335X_I2C_IRQSTATUS_RRDY) {<br>
+      regs->BBB_I2C_IRQSTATUS =AM335X_I2C_IRQSTATUS_RRDY;<br>
+    }<br>
   } else {<br>
-    am335x_i2c_setup_write_transfer( bus, regs, msgs );<br>
+    if (status & AM335X_I2C_IRQSTATUS_XDR) {<br>
+      debug_print("XDR\n");<br>
+      /* Remaining TX data won't reach the FIFO threshold. */<br>
+      amount = bus->buffer->len - bus->buffer_pos;<br>
+    } else if (status & AM335X_I2C_IRQSTATUS_XRDY) {<br>
+      debug_print("XRDY\n");<br>
+      /* FIFO threshold reached */<br>
+      amount = min(FIFO_THRESHOLD, bus->buffer->len - bus->buffer_pos);<br>
+    }<br>
+<br>
+    debug_print("Write %d bytes\n", amount);<br>
+    for (i = 0; i < amount; i++) {<br>
+      regs->BBB_I2C_DATA = bus->buffer->buf[bus->buffer_pos];<br>
+      ++bus->buffer_pos;<br>
+    }<br>
+<br>
+    if (status & AM335X_I2C_IRQSTATUS_XDR) {<br>
+      regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_XDR;<br>
+    }<br>
+    if (status & AM335X_I2C_IRQSTATUS_XRDY) {<br>
+      regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_XRDY;<br>
+    }<br>
   }<br>
+<br>
+  return false;<br>
 }<br>
<br>
 static void am335x_i2c_interrupt( void *arg )<br>
 {<br>
-  bbb_i2c_bus           *bus = arg;<br>
+  bbb_i2c_bus *bus = arg;<br>
   volatile bbb_i2c_regs *regs = bus->regs;<br>
-  /* Get status of enabled interrupts */<br>
-  uint32_t irqstatus = REG( &regs->BBB_I2C_IRQSTATUS );<br>
-  bool     done = false;<br>
+  uint32_t status;<br>
<br>
-  /*<br>
-   * Clear all enabled interrupt except receive ready<br>
-   * and transmit ready interrupt in status register<br>
-   */<br>
-  REG( &regs->BBB_I2C_IRQSTATUS ) =<br>
-    ( irqstatus & ~( AM335X_I2C_IRQSTATUS_RRDY |<br>
-                     AM335X_I2C_IRQSTATUS_XRDY ) );<br>
+  status = regs->BBB_I2C_IRQSTATUS;<br>
<br>
-  if ( irqstatus & AM335X_I2C_INT_RECV_READY ) {<br>
-    am335x_i2c_continue_read_transfer( bus, regs );<br>
-  }<br>
-<br>
-  if ( irqstatus & AM335X_I2C_IRQSTATUS_XRDY ) {<br>
-    am335x_i2c_continue_write( bus, regs );<br>
-  }<br>
+  debug_print("interrupt: %08x\n", status);<br>
<br>
-  if ( irqstatus & AM335X_I2C_IRQSTATUS_NACK ) {<br>
-    done = true;<br>
-    am335x_i2c_masterint_disable( regs, AM335X_I2C_IRQSTATUS_NACK );<br>
+  if (status == 0) {<br>
+    /* Why can this even happen? */<br>
+    return;<br>
   }<br>
<br>
-  if ( irqstatus & AM335X_I2C_IRQSTATUS_ARDY ) {<br>
-    done = true;<br>
-    REG( &regs->BBB_I2C_IRQSTATUS ) = BBB_I2C_STAT_ARDY;<br>
+  if (bus->buffer == NULL) {<br>
+    debug_print("Buffer is NULL\n");<br>
+    bus->error = EINVAL;<br>
   }<br>
<br>
-  if ( irqstatus & AM335X_I2C_IRQSTATUS_BF ) {<br>
-    REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_IRQSTATUS_BF;<br>
-  }<br>
-<br>
-  if ( done ) {<br>
-    uint32_t err = irqstatus & BBB_I2C_IRQ_ERROR;<br>
-    am335x_i2c_next_byte( bus );<br>
-<br>
-    if ( bus->msg_todo == 0 ) {<br>
-      rtems_status_code sc;<br>
-      am335x_i2c_masterint_disable( regs, ( AM335X_I2C_IRQSTATUS_RRDY |<br>
-                                            AM335X_I2C_IRQSTATUS_XRDY |<br>
-                                            AM335X_I2C_IRQSTATUS_BF ) );<br>
-      REG( &regs->BBB_I2C_IRQSTATUS ) = err;<br>
-<br>
-      sc = rtems_event_transient_send( bus->task_id );<br>
-      _Assert( sc == RTEMS_SUCCESSFUL );<br>
-      (void) sc;<br>
-    } else {<br>
-      am335x_i2c_setup_transfer( bus, regs );<br>
-    }<br>
+  if (bus->buffer == NULL || am335x_i2c_transfer_intr(bus, status)) {<br>
+    rtems_status_code sc;<br>
+    sc = rtems_event_transient_send( bus->task_id );<br>
+    _Assert( sc == RTEMS_SUCCESSFUL );<br>
+    (void) sc; /* suppress warning in case of no assert */<br>
   }<br>
 }<br>
<br>
 static int am335x_i2c_transfer(<br>
   i2c_bus *base,<br>
   i2c_msg *msgs,<br>
-  uint32_t msg_count<br>
+  uint32_t nmsgs<br>
 )<br>
 {<br>
-  rtems_status_code      sc;<br>
-  bbb_i2c_bus           *bus = (bbb_i2c_bus *) base;<br>
-  volatile bbb_i2c_regs *regs;<br>
-  uint32_t               i;<br>
+  size_t i;<br>
+  int err = 0;<br>
+  bool repstart = false;<br>
+  int timeout = 0;<br>
+  bbb_i2c_bus *bus = (bbb_i2c_bus *) base;<br>
+  volatile bbb_i2c_regs *regs = bus->regs;<br>
+  uint32_t reg;<br>
+  rtems_status_code sc;<br>
+<br>
+  bus->task_id = rtems_task_self();<br>
<br>
-  rtems_task_wake_after( 1 );<br>
+  for (i = 0; i < nmsgs; i++) {<br>
+    bus->buffer = &msgs[i];<br>
+    bus->buffer_pos = 0;<br>
+    bus->error = 0;<br>
<br>
-  if ( msg_count < 1 ) {<br>
-    return 1;<br>
-  }<br>
+    debug_print("processing %2d/%d: addr: 0x%04x, flags: 0x%04x, len: %d, buf: %p\n",<br>
+        i, nmsgs, msgs[i].addr, msgs[i].flags, msgs[i].len, msgs[i].buf);<br>
<br>
-  for ( i = 0; i < msg_count; ++i ) {<br>
-    if ( ( msgs[ i ].flags & I2C_M_RECV_LEN ) != 0 ) {<br>
-      return -EINVAL;<br>
+    if (bus->buffer == NULL || bus->buffer->buf == NULL ||<br>
+        bus->buffer->len == 0) {<br>
+      err = EINVAL;<br>
+      break;<br>
     }<br>
-  }<br>
<br>
-  bus->msgs = &msgs[ 0 ];<br>
-  bus->msg_todo = msg_count;<br>
-  bus->current_msg_todo = msgs[ 0 ].len;<br>
-  bus->current_msg_byte = msgs[ 0 ].buf;<br>
-  bus->task_id = rtems_task_self();<br>
-  regs = bus->regs;<br>
-  am335x_i2c_setup_transfer( bus, regs );<br>
-  REG( &regs->BBB_I2C_IRQENABLE_SET ) = BBB_I2C_IRQ_USED;<br>
+    /*<br>
+     * Send START when bus is busy on repeated starts.<br>
+     * Otherwise wait some time.<br>
+     */<br>
+    if (!repstart) {<br>
+      timeout = 0;<br>
+      while ((regs->BBB_I2C_IRQSTATUS_RAW & AM335X_I2C_IRQSTATUS_BB) != 0<br>
+              && timeout <= TRANSFER_TIMEOUT_COUNT) {<br>
+        ++timeout;<br>
+        rtems_task_wake_after(RTEMS_MICROSECONDS_TO_TICKS(1000));<br>
+      }<br>
+      if (timeout > TRANSFER_TIMEOUT_COUNT) {<br>
+        err = EBUSY;<br>
+        break;<br>
+      }<br>
+      timeout = 0;<br>
+    } else {<br>
+      repstart = false;<br>
+    }<br>
+<br>
+    if ((bus->buffer->flags & I2C_M_STOP) == 0) {<br>
+      repstart = true;<br>
+    }<br>
<br>
-  sc = rtems_event_transient_receive( RTEMS_WAIT, bus->base.timeout );<br>
+    regs->BBB_I2C_SA = bus->buffer->addr;<br>
+    regs->BBB_I2C_CNT = bus->buffer->len;<br>
<br>
-  if ( sc != RTEMS_SUCCESSFUL ) {<br>
-    am335x_i2c_reset( bus );<br>
-    rtems_event_transient_clear();<br>
+    regs->BBB_I2C_BUF |= AM335X_I2C_BUF_RXFIFO_CLR | AM335X_I2C_BUF_TXFIFO_CLR;<br>
<br>
-    return -ETIMEDOUT;<br>
+    reg = bus->con_reg | AM335X_I2C_CON_START;<br>
+    if (!repstart) {<br>
+      reg |= AM335X_I2C_CON_STOP;<br>
+    }<br>
+    if ((bus->buffer->flags & I2C_M_RD) == 0) {<br>
+      reg |= AM335X_I2C_CON_TRX;<br>
+    }<br>
+    /* Implicit stop on last message. */<br>
+    if (i == nmsgs - 1) {<br>
+      reg |= AM335X_I2C_CON_STOP;<br>
+    }<br>
+    regs->BBB_I2C_CON = reg;<br>
+<br>
+    sc = rtems_event_transient_receive( RTEMS_WAIT, bus->base.timeout );<br>
+    if ( sc != RTEMS_SUCCESSFUL ) {<br>
+      rtems_event_transient_clear();<br>
+      err = ETIMEDOUT;<br>
+      break;<br>
+    }<br>
+    if (bus->error) {<br>
+      err = bus->error;<br>
+      break;<br>
+    }<br>
   }<br>
<br>
-  return 0;<br>
-}<br>
+  if (timeout == 0) {<br>
+    while ((regs->BBB_I2C_IRQSTATUS_RAW & AM335X_I2C_IRQSTATUS_BB) != 0<br>
+            && timeout <= TRANSFER_TIMEOUT_COUNT) {<br>
+      ++timeout;<br>
+      rtems_task_wake_after(RTEMS_MICROSECONDS_TO_TICKS(1000));<br>
+    }<br>
+  }<br>
<br>
-static int am335x_i2c_set_clock(<br>
-  i2c_bus      *base,<br>
-  unsigned long clock<br>
-)<br>
-{<br>
-  bbb_i2c_bus           *bus = (bbb_i2c_bus *) base;<br>
-  uint32_t               prescaler, divider;<br>
+  if ((regs->BBB_I2C_CON & AM335X_I2C_CON_MST) == 0) {<br>
+    regs->BBB_I2C_CON = bus->con_reg;<br>
+  }<br>
<br>
-  prescaler = ( BBB_I2C_SYSCLK / BBB_I2C_INTERNAL_CLK ) - 1;<br>
-  REG( &bus->regs->BBB_I2C_PSC ) = prescaler;<br>
-  divider = BBB_I2C_INTERNAL_CLK / ( 2 * clock );<br>
-  REG( &bus->regs->BBB_I2C_SCLL ) = ( divider - 7 );<br>
-  REG( &bus->regs->BBB_I2C_SCLH ) = ( divider - 5 );<br>
+  bus->buffer = NULL;<br>
<br>
-  return 0;<br>
+  return -err;<br>
 }<br>
<br>
 static void am335x_i2c_destroy( i2c_bus *base )<br>
@@ -405,6 +445,8 @@ static void am335x_i2c_destroy( i2c_bus *base )<br>
   bbb_i2c_bus      *bus = (bbb_i2c_bus *) base;<br>
   rtems_status_code sc;<br>
<br>
+  bus->regs->BBB_I2C_IRQENABLE_CLR = 0xFFFF;<br>
+  bus->regs->BBB_I2C_CON = 0;<br>
   sc = rtems_interrupt_handler_remove( bus->irq, am335x_i2c_interrupt, bus );<br>
   _Assert( sc == RTEMS_SUCCESSFUL );<br>
   (void) sc;<br>
@@ -422,36 +464,36 @@ int am335x_i2c_bus_register(<br>
   rtems_status_code sc;<br>
   int               err;<br>
<br>
-  /* Check bus number is >0 & <MAX */<br>
+  (void) input_clock; /* FIXME: Unused. Left for compatibility. */<br>
+<br>
   bus = (bbb_i2c_bus *) i2c_bus_alloc_and_init( sizeof( *bus ) );<br>
<br>
   if ( bus == NULL ) {<br>
     return -1;<br>
   }<br>
<br>
-  bus->regs = (volatile bbb_i2c_regs *) register_base;<br>
-<br>
-  I2C0ModuleClkConfig();<br>
-  am335x_i2c0_pinmux( bus );<br>
-  am335x_i2c_reset( bus );<br>
-  bus->input_clock = input_clock;<br>
-  err = am335x_i2c_set_clock( &bus->base, I2C_BUS_CLOCK_DEFAULT );<br>
+  bus->irq = irq;<br>
<br>
-  if ( err != 0 ) {<br>
+  err = am335x_i2c_fill_registers(bus, register_base);<br>
+  if (err != 0) {<br>
     ( *bus->base.destroy )( &bus->base );<br>
-    rtems_set_errno_and_return_minus_one( -err );<br>
+    rtems_set_errno_and_return_minus_one( err );<br>
+  }<br>
+  am335x_i2c_module_clk_enable(bus);<br>
+  am335x_i2c_pinmux( bus );<br>
+  err = am335x_i2c_reset( bus );<br>
+  if (err != 0) {<br>
+    ( *bus->base.destroy )( &bus->base );<br>
+    rtems_set_errno_and_return_minus_one( err );<br>
   }<br>
-<br>
-  bus->irq = irq;<br>
-  REG( &bus->regs->BBB_I2C_IRQSTATUS ) = BBB_I2C_ALL_IRQ_FLAGS;<br>
<br>
   sc = rtems_interrupt_handler_install(<br>
-    irq,<br>
+    bus->irq,<br>
     "BBB_I2C",<br>
     RTEMS_INTERRUPT_UNIQUE,<br>
     (rtems_interrupt_handler) am335x_i2c_interrupt,<br>
     bus<br>
-       );<br>
+  );<br>
<br>
   if ( sc != RTEMS_SUCCESSFUL ) {<br>
     ( *bus->base.destroy )( &bus->base );<br>
diff --git a/bsps/arm/beagle/include/bsp/i2c.h b/bsps/arm/beagle/include/bsp/i2c.h<br>
index 3ada3c4b0d..9d253406bf 100644<br>
--- a/bsps/arm/beagle/include/bsp/i2c.h<br>
+++ b/bsps/arm/beagle/include/bsp/i2c.h<br>
@@ -24,76 +24,15 @@<br>
 #define LIBBSP_ARM_BEAGLE_I2C_H<br>
<br>
 #include <rtems.h><br>
-#include <dev/i2c/i2c.h><br>
 #include <bsp.h><br>
+#include <dev/i2c/i2c.h><br>
<br>
 #ifdef __cplusplus<br>
 extern "C" {<br>
 #endif /* __cplusplus */<br>
<br>
-<br>
-/* I2C Configuration Register (I2C_CON): */<br>
-<br>
-#define BBB_I2C_CON_EN  (1 << 15)  /* I2C module enable */<br>
-#define BBB_I2C_CON_BE  (1 << 14)  /* Big endian mode */<br>
-#define BBB_I2C_CON_STB (1 << 11)  /* Start byte mode (master mode only) */<br>
-#define BBB_I2C_CON_MST (1 << 10)  /* Master/slave mode */<br>
-#define BBB_I2C_CON_TRX (1 << 9)   /* Transmitter/receiver mode */<br>
-           /* (master mode only) */<br>
-#define BBB_I2C_CON_XA  (1 << 8)   /* Expand address */<br>
-#define BBB_I2C_CON_STP (1 << 1)   /* Stop condition (master mode only) */<br>
-#define BBB_I2C_CON_STT (1 << 0)   /* Start condition (master mode only) */<br>
-#define BBB_I2C_CON_CLR 0x0  /* Clear configuration register */<br>
-/* I2C Status Register (I2C_STAT): */<br>
-<br>
-#define BBB_I2C_STAT_SBD  (1 << 15) /* Single byte data */<br>
-#define BBB_I2C_STAT_BB (1 << 12) /* Bus busy */<br>
-#define BBB_I2C_STAT_ROVR (1 << 11) /* Receive overrun */<br>
-#define BBB_I2C_STAT_XUDF (1 << 10) /* Transmit underflow */<br>
-#define BBB_I2C_STAT_AAS  (1 << 9)  /* Address as slave */<br>
-#define BBB_I2C_STAT_GC (1 << 5)<br>
-#define BBB_I2C_STAT_XRDY (1 << 4)  /* Transmit data ready */<br>
-#define BBB_I2C_STAT_RRDY (1 << 3)  /* Receive data ready */<br>
-#define BBB_I2C_STAT_ARDY (1 << 2)  /* Register access ready */<br>
-#define BBB_I2C_STAT_NACK (1 << 1)  /* No acknowledgment interrupt enable */<br>
-#define BBB_I2C_STAT_AL (1 << 0)  /* Arbitration lost interrupt enable */<br>
-<br>
-/* I2C Interrupt Enable Register (I2C_IE): */<br>
-#define BBB_I2C_IE_GC_IE  (1 << 5)<br>
-#define BBB_I2C_IE_XRDY_IE  (1 << 4) /* Transmit data ready interrupt enable */<br>
-#define BBB_I2C_IE_RRDY_IE  (1 << 3) /* Receive data ready interrupt enable */<br>
-#define BBB_I2C_IE_ARDY_IE  (1 << 2) /* Register access ready interrupt enable */<br>
-#define BBB_I2C_IE_NACK_IE  (1 << 1) /* No acknowledgment interrupt enable */<br>
-#define BBB_I2C_IE_AL_IE  (1 << 0) /* Arbitration lost interrupt enable */<br>
-<br>
-/* I2C SYSC Register (I2C_SYSC): */<br>
-#define BBB_I2C_SYSC_SRST (1 << 1)<br>
-<br>
-#define BBB_I2C_TIMEOUT 1000<br>
-<br>
-#define BBB_I2C_SYSS_RDONE            (1 << 0)  /* Internel reset monitoring */<br>
-<br>
-#define BBB_CONFIG_SYS_I2C_SPEED    100000<br>
-#define BBB_CONFIG_SYS_I2C_SLAVE    1<br>
-#define BBB_I2C_ALL_FLAGS 0x7FFF<br>
-#define BBB_I2C_ALL_IRQ_FLAGS 0xFFFF<br>
-<br>
 #define BBB_I2C_SYSCLK 48000000<br>
 #define BBB_I2C_INTERNAL_CLK 12000000<br>
-#define BBB_I2C_SPEED_CLK 100000<br>
-<br>
-#define BBB_I2C_IRQ_ERROR \<br>
-  ( AM335X_I2C_IRQSTATUS_NACK \<br>
-    | AM335X_I2C_IRQSTATUS_ROVR \<br>
-    | AM335X_I2C_IRQSTATUS_AL \<br>
-    | AM335X_I2C_IRQSTATUS_ARDY \<br>
-    | AM335X_I2C_IRQSTATUS_RRDY \<br>
-    | AM335X_I2C_IRQSTATUS_XRDY \<br>
-    | AM335X_I2C_IRQSTATUS_XUDF )<br>
-<br>
-#define BBB_I2C_IRQ_USED \<br>
-  ( AM335X_I2C_IRQSTATUS_ARDY \<br>
-    | AM335X_I2C_IRQSTATUS_XRDY )<br>
<br>
 #define BBB_I2C_0_BUS_PATH "/dev/i2c-0"<br>
 #define BBB_I2C_1_BUS_PATH "/dev/i2c-1"<br>
@@ -103,9 +42,6 @@ extern "C" {<br>
 #define BBB_I2C1_IRQ 71<br>
 #define BBB_I2C2_IRQ 30<br>
<br>
-#define BBB_MODE2 2<br>
-#define BBB_MODE3 3<br>
-<br>
 typedef enum {<br>
   I2C0,<br>
   I2C1,<br>
@@ -151,26 +87,10 @@ typedef struct i2c_regs {<br>
   uint32_t BBB_I2C_SBLOCK;<br>
 } bbb_i2c_regs;<br>
<br>
-typedef struct bbb_i2c_bus {<br>
-  i2c_bus base;<br>
-  volatile bbb_i2c_regs *regs;<br>
-  i2c_msg *msgs;<br>
-  uint32_t msg_todo;<br>
-  uint32_t current_msg_todo;<br>
-  uint8_t *current_msg_byte;<br>
-  uint32_t current_todo;<br>
-  bool read;<br>
-  bool hold;<br>
-  rtems_id task_id;<br>
-  rtems_vector_number irq;<br>
-  uint32_t input_clock;<br>
-  uint32_t already_transferred;<br>
-} bbb_i2c_bus;<br>
-<br>
 int am335x_i2c_bus_register(<br>
   const char         *bus_path,<br>
   uintptr_t           register_base,<br>
-  uint32_t            input_clock,<br>
+  uint32_t            input_clock, /* FIXME: Unused. Left for compatibility. */<br>
   rtems_vector_number irq<br>
 );<br>
<br>
diff --git a/bsps/arm/include/libcpu/am335x.h b/bsps/arm/include/libcpu/am335x.h<br>
index a78cbd028d..b69c822d62 100644<br>
--- a/bsps/arm/include/libcpu/am335x.h<br>
+++ b/bsps/arm/include/libcpu/am335x.h<br>
@@ -664,6 +664,9 @@<br>
 #define AM335X_I2C_CON_MST   (0x00000400u)<br>
 #define AM335X_I2C_CON_STB   (0x00000800u)<br>
 #define AM335X_I2C_SYSC_AUTOIDLE   (0x00000001u)<br>
+#define AM335X_I2C_SYSC_SRST       (0x00000002u)<br>
+#define AM335X_I2C_SYSC_ENAWAKEUP  (0x00000004u)<br>
+#define AM335X_I2C_SYSS_RDONE      (0x00000001u)<br>
<br>
 /*I2C0 module clock registers*/<br>
 #define AM335X_CM_WKUP_CONTROL_CLKCTRL   (0x4)<br>
@@ -686,29 +689,39 @@<br>
 #define AM335X_CM_PER_CONTROL_CLKCTRL_IDLEST   (0x00030000u)<br>
<br>
<br>
+#define AM335X_I2C_BUF_TXTRSH_SHIFT (0)<br>
+#define AM335X_I2C_BUF_TXTRSH_MASK  (0x0000003Fu)<br>
+#define AM335X_I2C_BUF_TXTRSH(X)    (((X) << AM335X_I2C_BUF_TXTRSH_SHIFT) \<br>
+                                     & AM335X_I2C_BUF_TXTRSH_MASK)<br>
+#define AM335X_I2C_BUF_TXFIFO_CLR   (0x00000040u)<br>
+#define AM335X_I2C_BUF_RXTRSH_SHIFT (8)<br>
+#define AM335X_I2C_BUF_RXTRSH_MASK  (0x00003F00u)<br>
+#define AM335X_I2C_BUF_RXTRSH(X)    (((X) << AM335X_I2C_BUF_RXTRSH_SHIFT) \<br>
+                                     & AM335X_I2C_BUF_RXTRSH_MASK)<br>
+#define AM335X_I2C_BUF_RXFIFO_CLR   (0x00004000u)<br>
+<br>
 /* I2C status Register */<br>
+#define AM335X_I2C_IRQSTATUS_AL   (1 << 0)<br>
 #define AM335X_I2C_IRQSTATUS_NACK (1 << 1)<br>
-#define AM335X_I2C_IRQSTATUS_ROVR (1 << 11)<br>
-#define AM335X_I2C_IRQSTATUS_AL   (1<<0)<br>
 #define AM335X_I2C_IRQSTATUS_ARDY (1 << 2)<br>
 #define AM335X_I2C_IRQSTATUS_RRDY (1 << 3)<br>
 #define AM335X_I2C_IRQSTATUS_XRDY (1 << 4)<br>
-#define AM335X_I2C_IRQSTATUS_XUDF (1 << 10)<br>
-#define AM335X_I2C_BUF_TXFIFO_CLR   (0x00000040u)<br>
-#define AM335X_I2C_BUF_RXFIFO_CLR   (0x00004000u)<br>
-#define AM335X_I2C_IRQSTATUS_AAS  (1 << 9)<br>
-#define AM335X_I2C_IRQSTATUS_BF  (1 << 8)<br>
+#define AM335X_I2C_IRQSTATUS_GC   (1 << 5)<br>
 #define AM335X_I2C_IRQSTATUS_STC  (1 << 6)<br>
-#define AM335X_I2C_IRQSTATUS_GC (1 << 5)<br>
-#define AM335X_I2C_IRQSTATUS_XDR (1 << 14)<br>
-#define AM335X_I2C_IRQSTATUS_RDR (1 << 13)<br>
+#define AM335X_I2C_IRQSTATUS_AERR (1 << 7)<br>
+#define AM335X_I2C_IRQSTATUS_BF   (1 << 8)<br>
+#define AM335X_I2C_IRQSTATUS_AAS  (1 << 9)<br>
+#define AM335X_I2C_IRQSTATUS_XUDF (1 << 10)<br>
+#define AM335X_I2C_IRQSTATUS_ROVR (1 << 11)<br>
+#define AM335X_I2C_IRQSTATUS_BB   (1 << 12)<br>
+#define AM335X_I2C_IRQSTATUS_RDR  (1 << 13)<br>
+#define AM335X_I2C_IRQSTATUS_XDR  (1 << 14)<br>
<br>
 #define AM335X_I2C_INT_RECV_READY AM335X_I2C_IRQSTATUS_RRDY<br>
 #define AM335X_I2C_CON_STOP  (0x00000002u)<br>
 #define AM335X_I2C_CON_START (0x00000001u)<br>
 #define AM335X_I2C_CFG_MST_RX AM335X_I2C_CON_MST<br>
 #define AM335X_I2C_CFG_MST_TX  (AM335X_I2C_CON_TRX | AM335X_I2C_CON_MST)<br>
-#define AM335X_I2C_IRQSTATUS_RAW_BB   (0x00001000u)<br>
 #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK (0x00000020u)<br>
 #define AM335X_I2C_INT_STOP_CONDITION AM335X_I2C_IRQSTATUS_BF<br>
<br>
-- <br>
2.21.0<br>
<br>
</blockquote></div></div>