[PATCH] bsp/beagle: Partial re-write of I2C driver.

Vijay Kumar Banerjee vijaykumar9597 at gmail.com
Tue Jun 25 06:21:15 UTC 2019


On Tue, Jun 25, 2019 at 1:47 AM <list at c-mauderer.de> wrote:

> From: Christian Mauderer <christian.mauderer at embedded-brains.de>
>
> The old driver worked well for EEPROMS with the RTEMS EEPROM driver. But
> it had problems with a lot of other situations. Although it's not a
> direct port, the new driver is heavily modeled after the FreeBSD ti_i2c
> driver.
>
This is great!
I have tried this patch with the FreeBSD ported IIC bus through the
rtems_i2c
adaptation layer is FreeBSD and the output MATCHES the original FreeBSD i2c
scan with the ti_i2c driver.
Would also like to add that the i2c probe and i2c md in u-boot also shows
the same
results.
```
SHLL [/] # i2c -a 0x50 -w16 -mtr -c10
aa 55 33 ee 41 33 33 35 42 4e
SHLL [/] # i2c -s
Scanning I2C devices on /dev/iic0: Hardware may not support START/STOP
scanning; trying less-reliable read method.
24 34 50
```

> ---
>  bsps/arm/beagle/i2c/bbb-i2c.c     | 646 ++++++++++++++++--------------
>  bsps/arm/beagle/include/bsp/i2c.h |  84 +---
>  bsps/arm/include/libcpu/am335x.h  |  35 +-
>  3 files changed, 370 insertions(+), 395 deletions(-)
>
> diff --git a/bsps/arm/beagle/i2c/bbb-i2c.c b/bsps/arm/beagle/i2c/bbb-i2c.c
> index 3a8637d457..37b88864b9 100644
> --- a/bsps/arm/beagle/i2c/bbb-i2c.c
> +++ b/bsps/arm/beagle/i2c/bbb-i2c.c
> @@ -9,17 +9,14 @@
>  /*
>   * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
>   * Copyright (c) 2017 Sichen Zhao <zsc19940506 at gmail.com>
> + * Copyright (c) 2019 Christian Mauderer <
> christian.mauderer at embedded-brains.de>
>   *
>   * 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.
>   */
>
> -/*
> - * Modified on Punit Vara<punitvara at gmail.com> works, currently
> - * the i2c file is working on the Beaglebone Black board(AM335x)
> - */
> -
> +#include <rtems/bspIo.h>
>  #include <stdio.h>
>  #include <bsp/i2c.h>
>  #include <libcpu/am335x.h>
> @@ -27,26 +24,114 @@
>  #include <rtems/counter.h>
>  #include <bsp/bbb-gpio.h>
>  #include <rtems/score/assert.h>
> +#include <dev/i2c/i2c.h>
>
> -static void am335x_i2c0_pinmux( bbb_i2c_bus *bus )
> +typedef struct bbb_i2c_bus {
> +  i2c_bus base;
> +  volatile bbb_i2c_regs *regs;
> +  struct {
> +    volatile uint32_t *ctrl_clkctrl;
> +    volatile uint32_t *i2c_clkctrl;
> +    volatile uint32_t *clkstctrl;
> +  } clkregs;
> +  struct {
> +    volatile uint32_t *conf_sda;
> +    uint32_t mmode_sda;
> +    volatile uint32_t *conf_scl;
> +    uint32_t mmode_scl;
> +  } pinregs;
> +  rtems_id task_id;
> +  rtems_vector_number irq;
> +  i2c_msg *buffer;
> +  size_t buffer_pos;
> +  int error;
> +  uint32_t con_reg;
> +} bbb_i2c_bus;
> +
> +#define TRANSFER_TIMEOUT_COUNT 100
> +#define FIFO_THRESHOLD 5
> +#define min(l,r) ((l) < (r) ? (l) : (r))
> +#if 0
> +#define debug_print(fmt, args...) printk("bbb-i2c: " fmt, ## args)
> +#else
> +#define debug_print(fmt, args...)
> +#endif
> +
> +static int am335x_i2c_fill_registers(
> +  bbb_i2c_bus *bus,
> +  uintptr_t register_base
> +)
>  {
> -  REG( bus->regs + AM335X_CONF_I2C0_SDA ) =
> -    ( BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN );
> +  /* FIXME: The pin handling should be replaced by a proper pin handling
> during
> +   * initialization. This one is heavily board specific. */
> +#if ! IS_AM335X
> +  printk ("The I2C driver currently only works on Beagle Bone. Please add
> your pin configs.")
> +  return EINVAL;
> +#endif
> +  bus->regs = (volatile bbb_i2c_regs *) register_base;
> +  switch ((intptr_t) bus->regs) {
> +  case AM335X_I2C0_BASE:
> +    bus->clkregs.ctrl_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +
> +                                 AM335X_CM_WKUP_CONTROL_CLKCTRL);
> +    bus->clkregs.i2c_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +
> +                                 AM335X_CM_WKUP_I2C0_CLKCTRL);
> +    bus->clkregs.clkstctrl = &REG(AM335X_SOC_CM_WKUP_REGS +
> +                                   AM335X_CM_WKUP_CLKSTCTRL);
> +    bus->pinregs.conf_sda = &REG(AM335X_PADCONF_BASE +
> AM335X_CONF_I2C0_SDA);
> +    bus->pinregs.mmode_sda = 0;
> +    bus->pinregs.conf_scl = &REG(AM335X_PADCONF_BASE +
> AM335X_CONF_I2C0_SCL);
> +    bus->pinregs.mmode_scl = 0;
> +    break;
> +  case AM335X_I2C1_BASE:
> +    bus->clkregs.ctrl_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +
> +                                 AM335X_CM_WKUP_CONTROL_CLKCTRL);
> +    bus->clkregs.i2c_clkctrl = &REG(AM335X_CM_PER_ADDR +
> +                                 AM335X_CM_PER_I2C1_CLKCTRL);
> +    bus->clkregs.clkstctrl = NULL;
> +    bus->pinregs.conf_sda = &REG(AM335X_PADCONF_BASE +
> AM335X_CONF_SPI0_D1);
> +    bus->pinregs.mmode_sda = 2;
> +    bus->pinregs.conf_scl = &REG(AM335X_PADCONF_BASE +
> AM335X_CONF_SPI0_CS0);
> +    bus->pinregs.mmode_scl = 2;
> +    break;
> +  case AM335X_I2C2_BASE:
> +    bus->clkregs.ctrl_clkctrl = &REG(AM335X_SOC_CM_WKUP_REGS +
> +                                 AM335X_CM_WKUP_CONTROL_CLKCTRL);
> +    bus->clkregs.i2c_clkctrl = &REG(AM335X_CM_PER_ADDR +
> +                                 AM335X_CM_PER_I2C2_CLKCTRL);
> +    bus->clkregs.clkstctrl = NULL;
> +    bus->pinregs.conf_sda = &REG(AM335X_PADCONF_BASE +
> AM335X_CONF_UART1_CTSN);
> +    bus->pinregs.mmode_sda = 3;
> +    bus->pinregs.conf_scl = &REG(AM335X_PADCONF_BASE +
> AM335X_CONF_UART1_RTSN);
> +    bus->pinregs.mmode_scl = 3;
> +    break;
> +  default:
> +    return EINVAL;
> +  }
> +  return 0;
> +}
>
> -  REG( bus->regs + AM335X_CONF_I2C0_SCL ) =
> -    ( BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN );
> +static void am335x_i2c_pinmux( bbb_i2c_bus *bus )
> +{
> +  *bus->pinregs.conf_sda =
> +    ( BBB_RXACTIVE | BBB_SLEWCTRL | bus->pinregs.mmode_sda);
> +
> +  *bus->pinregs.conf_scl =
> +    ( BBB_RXACTIVE | BBB_SLEWCTRL | bus->pinregs.mmode_scl);
>  }
>
> -static void I2C0ModuleClkConfig( void )
> +static void am335x_i2c_module_clk_enable( bbb_i2c_bus *bus )
>  {
> +  volatile uint32_t *ctrl_clkctrl = bus->clkregs.ctrl_clkctrl;
> +  volatile uint32_t *i2c_clkctrl = bus->clkregs.i2c_clkctrl;
> +  volatile uint32_t *clkstctrl = bus->clkregs.clkstctrl;
> +
>    /* Writing to MODULEMODE field of AM335X_CM_WKUP_I2C0_CLKCTRL register.
> */
> -  REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_I2C0_CLKCTRL ) |=
> -    AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE;
> +  *i2c_clkctrl |= AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE;
>
>    /* Waiting for MODULEMODE field to reflect the written value. */
>    while ( AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE !=
> -          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_I2C0_CLKCTRL ) &
> -            AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE ) ) ;
> +          ( *i2c_clkctrl & AM335X_CM_WKUP_I2C0_CLKCTRL_MODULEMODE ) )
> +  { /* busy wait */ }
>
>    /*
>     * Waiting for IDLEST field in AM335X_CM_WKUP_CONTROL_CLKCTRL
> @@ -54,16 +139,18 @@ static void I2C0ModuleClkConfig( void )
>     */
>    while ( ( AM335X_CM_WKUP_CONTROL_CLKCTRL_IDLEST_FUNC <<
>              AM335X_CM_WKUP_CONTROL_CLKCTRL_IDLEST_SHIFT ) !=
> -          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_CONTROL_CLKCTRL
> ) &
> -            AM335X_CM_WKUP_CONTROL_CLKCTRL_IDLEST ) ) ;
> -
> -  /*
> -   * Waiting for CLKACTIVITY_I2C0_GFCLK field in AM335X_CM_WKUP_CLKSTCTRL
> -   * register to attain desired value.
> -   */
> -  while ( AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK !=
> -          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_CLKSTCTRL ) &
> -            AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK ) ) ;
> +          ( *ctrl_clkctrl & AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST ) )
> +  { /* busy wait */ }
> +
> +  if ( clkstctrl != NULL ) {
> +    /*
> +     * Waiting for CLKACTIVITY_I2C0_GFCLK field in
> AM335X_CM_WKUP_CLKSTCTRL
> +     * register to attain desired value.
> +     */
> +    while ( AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK !=
> +            ( *clkstctrl &
> AM335X_CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK ) )
> +    { /* busy wait */ }
> +  }
>
>    /*
>     * Waiting for IDLEST field in AM335X_CM_WKUP_I2C0_CLKCTRL register to
> attain
> @@ -71,333 +158,286 @@ static void I2C0ModuleClkConfig( void )
>     */
>    while ( ( AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST_FUNC <<
>              AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST_SHIFT ) !=
> -          ( REG( AM335X_SOC_CM_WKUP_REGS + AM335X_CM_WKUP_I2C0_CLKCTRL ) &
> -            AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST ) ) ;
> -}
> -
> -static void am335x_i2c_reset( bbb_i2c_bus *bus )
> -{
> -  volatile bbb_i2c_regs *regs = bus->regs;
> -  int                    timeout = I2C_TIMEOUT;
> -
> -  if ( REG( &regs->BBB_I2C_CON ) & BBB_I2C_CON_EN ) {
> -    REG( &regs->BBB_I2C_CON ) = BBB_I2C_CON_CLR;
> -    udelay( 50000 );
> -  }
> -
> -  REG( &regs->BBB_I2C_SYSC ) = BBB_I2C_SYSC_SRST; /* for ES2 after soft
> reset */
> -  udelay( 1000 );
> -  REG( &regs->BBB_I2C_CON ) = BBB_I2C_CON_EN;
> -
> -  while ( !( REG( &regs->BBB_I2C_SYSS ) & BBB_I2C_SYSS_RDONE ) &&
> timeout-- ) {
> -    if ( timeout <= 0 ) {
> -      puts( "ERROR: Timeout in soft-reset\n" );
> -
> -      return;
> -    }
> -
> -    udelay( 1000 );
> -  }
> +          ( *i2c_clkctrl & AM335X_CM_WKUP_I2C0_CLKCTRL_IDLEST ) ) ;
>  }
> -/*
> - * 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
> +static int am335x_i2c_set_clock(
> +  i2c_bus      *base,
> +  unsigned long clock
>  )
>  {
> -  /*
> -   * 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 */
> -    REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_7BIT_SLAVE_ADDR;
> -  } else {
> -    /* 10-bit slave address mode */
> -    REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_10BIT_SLAVE_ADDR;
> -  }
> -}
> -
> -static void am335x_i2c_next_byte( bbb_i2c_bus *bus )
> -{
> -  i2c_msg *msg;
> +  bbb_i2c_bus           *bus = (bbb_i2c_bus *) base;
> +  uint32_t               prescaler, divider;
>
> -  ++bus->msgs;
> -  --bus->msg_todo;
> -  msg = &bus->msgs[ 0 ];
> -  bus->current_msg_todo = msg->len;
> -  bus->current_msg_byte = msg->buf;
> -}
> +  prescaler = ( BBB_I2C_SYSCLK / BBB_I2C_INTERNAL_CLK ) - 1;
> +  bus->regs->BBB_I2C_PSC = prescaler;
> +  divider = BBB_I2C_INTERNAL_CLK / ( 2 * clock );
> +  bus->regs->BBB_I2C_SCLL = ( divider - 7 );
> +  bus->regs->BBB_I2C_SCLH = ( divider - 5 );
>
> -static void am335x_i2c_masterint_enable(
> -  volatile bbb_i2c_regs *regs,
> -  unsigned int           flag
> -)
> -{
> -  REG( &regs->BBB_I2C_IRQENABLE_SET ) |= flag;
> +  return 0;
>  }
>
> -static void am335x_i2c_masterint_disable(
> -  volatile bbb_i2c_regs *regs,
> -  unsigned int           flag
> -)
> +static int am335x_i2c_reset( bbb_i2c_bus *bus )
>  {
> -  REG( &regs->BBB_I2C_IRQENABLE_CLR ) = flag;
> -}
> +  volatile bbb_i2c_regs *regs = bus->regs;
> +  int                    timeout = 100;
> +  int                    err;
>
> -static void am335x_int_clear(
> -  volatile bbb_i2c_regs *regs,
> -  unsigned int           flag
> -)
> -{
> -  REG( &regs->BBB_I2C_IRQSTATUS ) = flag;
> -}
> +  bus->con_reg = 0;
> +  regs->BBB_I2C_CON = bus->con_reg;
> +  udelay( 50000 );
>
> -static void am335x_clean_interrupts( volatile bbb_i2c_regs *regs )
> -{
> -  am335x_i2c_masterint_enable( regs, BBB_I2C_ALL_FLAGS );
> -  am335x_int_clear( regs, BBB_I2C_ALL_FLAGS );
> -  am335x_i2c_masterint_disable( regs, BBB_I2C_ALL_FLAGS );
> -}
> -
> -static void am335x_i2c_setup_read_transfer(
> -  bbb_i2c_bus           *bus,
> -  volatile bbb_i2c_regs *regs,
> -  const i2c_msg         *msgs,
> -  bool                   send_stop
> -)
> -{
> -  REG( &regs->BBB_I2C_CNT ) = bus->current_msg_todo;
> +  regs->BBB_I2C_SYSC = AM335X_I2C_SYSC_SRST;
> +  udelay( 1000 );
> +  regs->BBB_I2C_CON = AM335X_I2C_CON_I2C_EN;
>
> -  REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_MST_RX |
> AM335X_I2C_CON_I2C_EN;
> +  while ( !( regs->BBB_I2C_SYSS & AM335X_I2C_SYSS_RDONE )
> +          && timeout >= 0 ) {
> +    --timeout;
> +    udelay( 100 );
> +  }
>
> -  if ( send_stop ) {
> -    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_START |
> AM335X_I2C_CON_STOP;
> -  } else {
> -    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_START;
> +  if ( timeout <= 0 ) {
> +    puts( "ERROR: Timeout in soft-reset\n" );
> +    return ETIMEDOUT;
>    }
>
> -  am335x_i2c_masterint_enable( regs, AM335X_I2C_INT_RECV_READY |
> -    AM335X_I2C_IRQSTATUS_ARDY );
> -}
> +  /* Disable again after reset */
> +  regs->BBB_I2C_CON = bus->con_reg;
>
> -static void am335x_i2c_continue_read_transfer(
> -  bbb_i2c_bus           *bus,
> -  volatile bbb_i2c_regs *regs
> -)
> -{
> -  bus->current_msg_byte[ bus->already_transferred ] =
> -    REG( &regs->BBB_I2C_DATA );
> +  err = am335x_i2c_set_clock( &bus->base, I2C_BUS_CLOCK_DEFAULT );
> +  if (err) {
> +    return err;
> +  }
>
> -  bus->already_transferred++;
> +  regs->BBB_I2C_BUF = AM335X_I2C_BUF_TXTRSH(FIFO_THRESHOLD) |
> +                              AM335X_I2C_BUF_RXTRSH(FIFO_THRESHOLD);
>
> -  REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_INT_RECV_READY;
> +  /* Enable the I2C controller in master mode. */
> +  bus->con_reg |= AM335X_I2C_CON_I2C_EN | AM335X_I2C_CON_MST;
> +  regs->BBB_I2C_CON = bus->con_reg;
>
> -  if ( bus->already_transferred == bus->current_msg_todo - 1 ) {
> -    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_STOP;
> -  }
> -}
> +  regs->BBB_I2C_IRQENABLE_SET =
> +      AM335X_I2C_IRQSTATUS_XDR | AM335X_I2C_IRQSTATUS_XRDY |
> +      AM335X_I2C_IRQSTATUS_RDR | AM335X_I2C_IRQSTATUS_RRDY |
> +      AM335X_I2C_IRQSTATUS_ARDY | AM335X_I2C_IRQSTATUS_NACK |
> +      AM335X_I2C_IRQSTATUS_AL;
>
> -static void am335x_i2c_continue_write(
> -  bbb_i2c_bus           *bus,
> -  volatile bbb_i2c_regs *regs
> -)
> -{
> -  if ( bus->already_transferred == bus->msg_todo ) {
> -    REG( &regs->BBB_I2C_DATA ) =
> -      bus->current_msg_byte[ bus->already_transferred ];
> -    REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_IRQSTATUS_XRDY;
> -    am335x_i2c_masterint_disable( regs, AM335X_I2C_IRQSTATUS_XRDY );
> -    REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_STOP;
> -  } else {
> -    writeb( bus->current_msg_byte[ bus->already_transferred ],
> -      &regs->BBB_I2C_DATA );
> -    REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_IRQSTATUS_XRDY;
> -    bus->already_transferred++;
> -  }
> -}
> -
> -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;
> -
> -  REG( &regs->BBB_I2C_CNT ) = bus->current_msg_todo;
> -  no_bytes = REG( &regs->BBB_I2C_CNT );
> -  (void) no_bytes; /* indicate we know that no_bytes is not referenced
> again */
> -  REG( &regs->BBB_I2C_SA ) = msgs->addr;
> -  REG( &regs->BBB_I2C_CON ) = AM335X_I2C_CFG_MST_TX |
> AM335X_I2C_CON_I2C_EN;
> -  am335x_clean_interrupts( regs );
> -  am335x_i2c_masterint_enable( regs, AM335X_I2C_IRQSTATUS_XRDY );
> -  REG( &regs->BBB_I2C_CON ) |= AM335X_I2C_CON_START | AM335X_I2C_CON_STOP;
> +  return 0;
>  }
>
> -static void am335x_i2c_setup_transfer(
> -  bbb_i2c_bus           *bus,
> -  volatile bbb_i2c_regs *regs
> -)
> +/* Return true if done. */
> +static bool am335x_i2c_transfer_intr(bbb_i2c_bus *bus, uint32_t status)
>  {
> -  const i2c_msg *msgs = bus->msgs;
> -  uint32_t       msg_todo = bus->msg_todo;
> -  bool           send_stop = false;
> -  uint32_t       i;
> +  size_t i;
> +  size_t amount = 0;
> +  volatile bbb_i2c_regs *regs = bus->regs;
>
> -  bus->current_todo = msgs[ 0 ].len;
> +  /* Handle errors */
> +  if ((status & AM335X_I2C_IRQSTATUS_NACK) != 0) {
> +    debug_print("NACK\n");
> +    regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_NACK;
> +    bus->error = ENXIO;
> +  } else if ((status & AM335X_I2C_IRQSTATUS_AL) != 0) {
> +    debug_print("Arbitration lost\n");
> +    regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_AL;
> +    bus->error = ENXIO;
> +  }
>
> -  for ( i = 1; i < msg_todo && ( msgs[ i ].flags & I2C_M_NOSTART ) != 0;
> -        ++i ) {
> -    bus->current_todo += msgs[ i ].len;
> +  /* Transfer finished? */
> +  if ((status & AM335X_I2C_IRQSTATUS_ARDY) != 0) {
> +    debug_print("ARDY transaction complete\n");
> +    if (bus->error != 0 && (bus->buffer->flags & I2C_M_STOP) == 0) {
> +      regs->BBB_I2C_CON = bus->con_reg | AM335X_I2C_CON_STOP;
> +    }
> +    regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_ARDY |
> +                              AM335X_I2C_IRQSTATUS_RDR |
> +                              AM335X_I2C_IRQSTATUS_RRDY |
> +                              AM335X_I2C_IRQSTATUS_XDR |
> +                              AM335X_I2C_IRQSTATUS_XRDY;
> +    return true;
>    }
>
> -  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 = ( msgs->flags & I2C_M_RD ) != 0;
> -  bus->already_transferred = ( bus->read == true ) ? 0 : 1;
> +  if (bus->buffer->flags & I2C_M_RD) {
> +    if (status & AM335X_I2C_IRQSTATUS_RDR) {
> +      debug_print("RDR\n");
> +      /* last data received */
> +      amount = bus->buffer->len - bus->buffer_pos;
> +    } else if (status & AM335X_I2C_IRQSTATUS_RRDY) {
> +      debug_print("RRDY\n");
> +      /* FIFO threshold reached */
> +      amount = min(FIFO_THRESHOLD, bus->buffer->len - bus->buffer_pos);
> +    }
>
> -  if ( bus->read ) {
> -    if ( bus->current_msg_todo == 1 ) {
> -      send_stop = true;
> +    debug_print("Read %d bytes\n", amount);
> +    for (i = 0; i < amount; i++) {
> +      bus->buffer->buf[bus->buffer_pos] = (uint8_t)(regs->BBB_I2C_DATA);
> +      ++bus->buffer_pos;
>      }
>
> -    am335x_i2c_setup_read_transfer( bus, regs, msgs, send_stop );
> +    if (status & AM335X_I2C_IRQSTATUS_RDR) {
> +      regs->BBB_I2C_IRQSTATUS =AM335X_I2C_IRQSTATUS_RDR;
> +    }
> +    if (status & AM335X_I2C_IRQSTATUS_RRDY) {
> +      regs->BBB_I2C_IRQSTATUS =AM335X_I2C_IRQSTATUS_RRDY;
> +    }
>    } else {
> -    am335x_i2c_setup_write_transfer( bus, regs, msgs );
> +    if (status & AM335X_I2C_IRQSTATUS_XDR) {
> +      debug_print("XDR\n");
> +      /* Remaining TX data won't reach the FIFO threshold. */
> +      amount = bus->buffer->len - bus->buffer_pos;
> +    } else if (status & AM335X_I2C_IRQSTATUS_XRDY) {
> +      debug_print("XRDY\n");
> +      /* FIFO threshold reached */
> +      amount = min(FIFO_THRESHOLD, bus->buffer->len - bus->buffer_pos);
> +    }
> +
> +    debug_print("Write %d bytes\n", amount);
> +    for (i = 0; i < amount; i++) {
> +      regs->BBB_I2C_DATA = bus->buffer->buf[bus->buffer_pos];
> +      ++bus->buffer_pos;
> +    }
> +
> +    if (status & AM335X_I2C_IRQSTATUS_XDR) {
> +      regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_XDR;
> +    }
> +    if (status & AM335X_I2C_IRQSTATUS_XRDY) {
> +      regs->BBB_I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS_XRDY;
> +    }
>    }
> +
> +  return false;
>  }
>
>  static void am335x_i2c_interrupt( void *arg )
>  {
> -  bbb_i2c_bus           *bus = 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;
> +  uint32_t status;
>
> -  /*
> -   * 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 ) );
> +  status = regs->BBB_I2C_IRQSTATUS;
>
> -  if ( irqstatus & AM335X_I2C_INT_RECV_READY ) {
> -    am335x_i2c_continue_read_transfer( bus, regs );
> -  }
> -
> -  if ( irqstatus & AM335X_I2C_IRQSTATUS_XRDY ) {
> -    am335x_i2c_continue_write( bus, regs );
> -  }
> +  debug_print("interrupt: %08x\n", status);
>
> -  if ( irqstatus & AM335X_I2C_IRQSTATUS_NACK ) {
> -    done = true;
> -    am335x_i2c_masterint_disable( regs, AM335X_I2C_IRQSTATUS_NACK );
> +  if (status == 0) {
> +    /* Why can this even happen? */
> +    return;
>    }
>
> -  if ( irqstatus & AM335X_I2C_IRQSTATUS_ARDY ) {
> -    done = true;
> -    REG( &regs->BBB_I2C_IRQSTATUS ) = BBB_I2C_STAT_ARDY;
> +  if (bus->buffer == NULL) {
> +    debug_print("Buffer is NULL\n");
> +    bus->error = EINVAL;
>    }
>
> -  if ( irqstatus & AM335X_I2C_IRQSTATUS_BF ) {
> -    REG( &regs->BBB_I2C_IRQSTATUS ) = AM335X_I2C_IRQSTATUS_BF;
> -  }
> -
> -  if ( done ) {
> -    uint32_t err = irqstatus & BBB_I2C_IRQ_ERROR;
> -    am335x_i2c_next_byte( bus );
> -
> -    if ( bus->msg_todo == 0 ) {
> -      rtems_status_code sc;
> -      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 );
> -    }
> +  if (bus->buffer == NULL || am335x_i2c_transfer_intr(bus, status)) {
> +    rtems_status_code sc;
> +    sc = rtems_event_transient_send( bus->task_id );
> +    _Assert( sc == RTEMS_SUCCESSFUL );
> +    (void) sc; /* suppress warning in case of no assert */
>    }
>  }
>
>  static int am335x_i2c_transfer(
>    i2c_bus *base,
>    i2c_msg *msgs,
> -  uint32_t msg_count
> +  uint32_t nmsgs
>  )
>  {
> -  rtems_status_code      sc;
> -  bbb_i2c_bus           *bus = (bbb_i2c_bus *) base;
> -  volatile bbb_i2c_regs *regs;
> -  uint32_t               i;
> +  size_t i;
> +  int err = 0;
> +  bool repstart = false;
> +  int timeout = 0;
> +  bbb_i2c_bus *bus = (bbb_i2c_bus *) base;
> +  volatile bbb_i2c_regs *regs = bus->regs;
> +  uint32_t reg;
> +  rtems_status_code sc;
> +
> +  bus->task_id = rtems_task_self();
>
> -  rtems_task_wake_after( 1 );
> +  for (i = 0; i < nmsgs; i++) {
> +    bus->buffer = &msgs[i];
> +    bus->buffer_pos = 0;
> +    bus->error = 0;
>
> -  if ( msg_count < 1 ) {
> -    return 1;
> -  }
> +    debug_print("processing %2d/%d: addr: 0x%04x, flags: 0x%04x, len: %d,
> buf: %p\n",
> +        i, nmsgs, msgs[i].addr, msgs[i].flags, msgs[i].len, msgs[i].buf);
>
> -  for ( i = 0; i < msg_count; ++i ) {
> -    if ( ( msgs[ i ].flags & I2C_M_RECV_LEN ) != 0 ) {
> -      return -EINVAL;
> +    if (bus->buffer == NULL || bus->buffer->buf == NULL ||
> +        bus->buffer->len == 0) {
> +      err = EINVAL;
> +      break;
>      }
> -  }
>
> -  bus->msgs = &msgs[ 0 ];
> -  bus->msg_todo = msg_count;
> -  bus->current_msg_todo = msgs[ 0 ].len;
> -  bus->current_msg_byte = 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;
> +    /*
> +     * Send START when bus is busy on repeated starts.
> +     * Otherwise wait some time.
> +     */
> +    if (!repstart) {
> +      timeout = 0;
> +      while ((regs->BBB_I2C_IRQSTATUS_RAW & AM335X_I2C_IRQSTATUS_BB) != 0
> +              && timeout <= TRANSFER_TIMEOUT_COUNT) {
> +        ++timeout;
> +        rtems_task_wake_after(RTEMS_MICROSECONDS_TO_TICKS(1000));
> +      }
> +      if (timeout > TRANSFER_TIMEOUT_COUNT) {
> +        err = EBUSY;
> +        break;
> +      }
> +      timeout = 0;
> +    } else {
> +      repstart = false;
> +    }
> +
> +    if ((bus->buffer->flags & I2C_M_STOP) == 0) {
> +      repstart = true;
> +    }
>
> -  sc = rtems_event_transient_receive( RTEMS_WAIT, bus->base.timeout );
> +    regs->BBB_I2C_SA = bus->buffer->addr;
> +    regs->BBB_I2C_CNT = bus->buffer->len;
>
> -  if ( sc != RTEMS_SUCCESSFUL ) {
> -    am335x_i2c_reset( bus );
> -    rtems_event_transient_clear();
> +    regs->BBB_I2C_BUF |= AM335X_I2C_BUF_RXFIFO_CLR |
> AM335X_I2C_BUF_TXFIFO_CLR;
>
> -    return -ETIMEDOUT;
> +    reg = bus->con_reg | AM335X_I2C_CON_START;
> +    if (!repstart) {
> +      reg |= AM335X_I2C_CON_STOP;
> +    }
> +    if ((bus->buffer->flags & I2C_M_RD) == 0) {
> +      reg |= AM335X_I2C_CON_TRX;
> +    }
> +    /* Implicit stop on last message. */
> +    if (i == nmsgs - 1) {
> +      reg |= AM335X_I2C_CON_STOP;
> +    }
> +    regs->BBB_I2C_CON = reg;
> +
> +    sc = rtems_event_transient_receive( RTEMS_WAIT, bus->base.timeout );
> +    if ( sc != RTEMS_SUCCESSFUL ) {
> +      rtems_event_transient_clear();
> +      err = ETIMEDOUT;
> +      break;
> +    }
> +    if (bus->error) {
> +      err = bus->error;
> +      break;
> +    }
>    }
>
> -  return 0;
> -}
> +  if (timeout == 0) {
> +    while ((regs->BBB_I2C_IRQSTATUS_RAW & AM335X_I2C_IRQSTATUS_BB) != 0
> +            && timeout <= TRANSFER_TIMEOUT_COUNT) {
> +      ++timeout;
> +      rtems_task_wake_after(RTEMS_MICROSECONDS_TO_TICKS(1000));
> +    }
> +  }
>
> -static int am335x_i2c_set_clock(
> -  i2c_bus      *base,
> -  unsigned long clock
> -)
> -{
> -  bbb_i2c_bus           *bus = (bbb_i2c_bus *) base;
> -  uint32_t               prescaler, divider;
> +  if ((regs->BBB_I2C_CON & AM335X_I2C_CON_MST) == 0) {
> +    regs->BBB_I2C_CON = bus->con_reg;
> +  }
>
> -  prescaler = ( BBB_I2C_SYSCLK / BBB_I2C_INTERNAL_CLK ) - 1;
> -  REG( &bus->regs->BBB_I2C_PSC ) = prescaler;
> -  divider = BBB_I2C_INTERNAL_CLK / ( 2 * clock );
> -  REG( &bus->regs->BBB_I2C_SCLL ) = ( divider - 7 );
> -  REG( &bus->regs->BBB_I2C_SCLH ) = ( divider - 5 );
> +  bus->buffer = NULL;
>
> -  return 0;
> +  return -err;
>  }
>
>  static void am335x_i2c_destroy( i2c_bus *base )
> @@ -405,6 +445,8 @@ static void am335x_i2c_destroy( i2c_bus *base )
>    bbb_i2c_bus      *bus = (bbb_i2c_bus *) base;
>    rtems_status_code sc;
>
> +  bus->regs->BBB_I2C_IRQENABLE_CLR = 0xFFFF;
> +  bus->regs->BBB_I2C_CON = 0;
>    sc = rtems_interrupt_handler_remove( bus->irq, am335x_i2c_interrupt,
> bus );
>    _Assert( sc == RTEMS_SUCCESSFUL );
>    (void) sc;
> @@ -422,36 +464,36 @@ int am335x_i2c_bus_register(
>    rtems_status_code sc;
>    int               err;
>
> -  /* Check bus number is >0 & <MAX */
> +  (void) input_clock; /* FIXME: Unused. Left for compatibility. */
> +
>    bus = (bbb_i2c_bus *) i2c_bus_alloc_and_init( sizeof( *bus ) );
>
>    if ( bus == NULL ) {
>      return -1;
>    }
>
> -  bus->regs = (volatile bbb_i2c_regs *) register_base;
> -
> -  I2C0ModuleClkConfig();
> -  am335x_i2c0_pinmux( bus );
> -  am335x_i2c_reset( bus );
> -  bus->input_clock = input_clock;
> -  err = am335x_i2c_set_clock( &bus->base, I2C_BUS_CLOCK_DEFAULT );
> +  bus->irq = irq;
>
> -  if ( err != 0 ) {
> +  err = am335x_i2c_fill_registers(bus, register_base);
> +  if (err != 0) {
>      ( *bus->base.destroy )( &bus->base );
> -    rtems_set_errno_and_return_minus_one( -err );
> +    rtems_set_errno_and_return_minus_one( err );
> +  }
> +  am335x_i2c_module_clk_enable(bus);
> +  am335x_i2c_pinmux( bus );
> +  err = am335x_i2c_reset( bus );
> +  if (err != 0) {
> +    ( *bus->base.destroy )( &bus->base );
> +    rtems_set_errno_and_return_minus_one( err );
>    }
> -
> -  bus->irq = irq;
> -  REG( &bus->regs->BBB_I2C_IRQSTATUS ) = BBB_I2C_ALL_IRQ_FLAGS;
>
>    sc = rtems_interrupt_handler_install(
> -    irq,
> +    bus->irq,
>      "BBB_I2C",
>      RTEMS_INTERRUPT_UNIQUE,
>      (rtems_interrupt_handler) am335x_i2c_interrupt,
>      bus
> -       );
> +  );
>
>    if ( sc != RTEMS_SUCCESSFUL ) {
>      ( *bus->base.destroy )( &bus->base );
> diff --git a/bsps/arm/beagle/include/bsp/i2c.h
> b/bsps/arm/beagle/include/bsp/i2c.h
> index 3ada3c4b0d..9d253406bf 100644
> --- a/bsps/arm/beagle/include/bsp/i2c.h
> +++ b/bsps/arm/beagle/include/bsp/i2c.h
> @@ -24,76 +24,15 @@
>  #define LIBBSP_ARM_BEAGLE_I2C_H
>
>  #include <rtems.h>
> -#include <dev/i2c/i2c.h>
>  #include <bsp.h>
> +#include <dev/i2c/i2c.h>
>
>  #ifdef __cplusplus
>  extern "C" {
>  #endif /* __cplusplus */
>
> -
> -/* I2C Configuration Register (I2C_CON): */
> -
> -#define BBB_I2C_CON_EN  (1 << 15)  /* I2C module enable */
> -#define BBB_I2C_CON_BE  (1 << 14)  /* Big endian mode */
> -#define BBB_I2C_CON_STB (1 << 11)  /* Start byte mode (master mode only)
> */
> -#define BBB_I2C_CON_MST (1 << 10)  /* Master/slave mode */
> -#define BBB_I2C_CON_TRX (1 << 9)   /* Transmitter/receiver mode */
> -           /* (master mode only) */
> -#define BBB_I2C_CON_XA  (1 << 8)   /* Expand address */
> -#define BBB_I2C_CON_STP (1 << 1)   /* Stop condition (master mode only) */
> -#define BBB_I2C_CON_STT (1 << 0)   /* Start condition (master mode only)
> */
> -#define BBB_I2C_CON_CLR 0x0  /* Clear configuration register */
> -/* I2C Status Register (I2C_STAT): */
> -
> -#define BBB_I2C_STAT_SBD  (1 << 15) /* Single byte data */
> -#define BBB_I2C_STAT_BB (1 << 12) /* Bus busy */
> -#define BBB_I2C_STAT_ROVR (1 << 11) /* Receive overrun */
> -#define BBB_I2C_STAT_XUDF (1 << 10) /* Transmit underflow */
> -#define BBB_I2C_STAT_AAS  (1 << 9)  /* Address as slave */
> -#define BBB_I2C_STAT_GC (1 << 5)
> -#define BBB_I2C_STAT_XRDY (1 << 4)  /* Transmit data ready */
> -#define BBB_I2C_STAT_RRDY (1 << 3)  /* Receive data ready */
> -#define BBB_I2C_STAT_ARDY (1 << 2)  /* Register access ready */
> -#define BBB_I2C_STAT_NACK (1 << 1)  /* No acknowledgment interrupt enable
> */
> -#define BBB_I2C_STAT_AL (1 << 0)  /* Arbitration lost interrupt enable */
> -
> -/* I2C Interrupt Enable Register (I2C_IE): */
> -#define BBB_I2C_IE_GC_IE  (1 << 5)
> -#define BBB_I2C_IE_XRDY_IE  (1 << 4) /* Transmit data ready interrupt
> enable */
> -#define BBB_I2C_IE_RRDY_IE  (1 << 3) /* Receive data ready interrupt
> enable */
> -#define BBB_I2C_IE_ARDY_IE  (1 << 2) /* Register access ready interrupt
> enable */
> -#define BBB_I2C_IE_NACK_IE  (1 << 1) /* No acknowledgment interrupt
> enable */
> -#define BBB_I2C_IE_AL_IE  (1 << 0) /* Arbitration lost interrupt enable */
> -
> -/* I2C SYSC Register (I2C_SYSC): */
> -#define BBB_I2C_SYSC_SRST (1 << 1)
> -
> -#define BBB_I2C_TIMEOUT 1000
> -
> -#define BBB_I2C_SYSS_RDONE            (1 << 0)  /* Internel reset
> monitoring */
> -
> -#define BBB_CONFIG_SYS_I2C_SPEED    100000
> -#define BBB_CONFIG_SYS_I2C_SLAVE    1
> -#define BBB_I2C_ALL_FLAGS 0x7FFF
> -#define BBB_I2C_ALL_IRQ_FLAGS 0xFFFF
> -
>  #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 \
> -  ( AM335X_I2C_IRQSTATUS_ARDY \
> -    | AM335X_I2C_IRQSTATUS_XRDY )
>
>  #define BBB_I2C_0_BUS_PATH "/dev/i2c-0"
>  #define BBB_I2C_1_BUS_PATH "/dev/i2c-1"
> @@ -103,9 +42,6 @@ extern "C" {
>  #define BBB_I2C1_IRQ 71
>  #define BBB_I2C2_IRQ 30
>
> -#define BBB_MODE2 2
> -#define BBB_MODE3 3
> -
>  typedef enum {
>    I2C0,
>    I2C1,
> @@ -151,26 +87,10 @@ typedef struct i2c_regs {
>    uint32_t BBB_I2C_SBLOCK;
>  } 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;
> -  uint8_t *current_msg_byte;
> -  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,
> +  uint32_t            input_clock, /* FIXME: Unused. Left for
> compatibility. */
>    rtems_vector_number irq
>  );
>
> diff --git a/bsps/arm/include/libcpu/am335x.h
> b/bsps/arm/include/libcpu/am335x.h
> index a78cbd028d..b69c822d62 100644
> --- a/bsps/arm/include/libcpu/am335x.h
> +++ b/bsps/arm/include/libcpu/am335x.h
> @@ -664,6 +664,9 @@
>  #define AM335X_I2C_CON_MST   (0x00000400u)
>  #define AM335X_I2C_CON_STB   (0x00000800u)
>  #define AM335X_I2C_SYSC_AUTOIDLE   (0x00000001u)
> +#define AM335X_I2C_SYSC_SRST       (0x00000002u)
> +#define AM335X_I2C_SYSC_ENAWAKEUP  (0x00000004u)
> +#define AM335X_I2C_SYSS_RDONE      (0x00000001u)
>
>  /*I2C0 module clock registers*/
>  #define AM335X_CM_WKUP_CONTROL_CLKCTRL   (0x4)
> @@ -686,29 +689,39 @@
>  #define AM335X_CM_PER_CONTROL_CLKCTRL_IDLEST   (0x00030000u)
>
>
> +#define AM335X_I2C_BUF_TXTRSH_SHIFT (0)
> +#define AM335X_I2C_BUF_TXTRSH_MASK  (0x0000003Fu)
> +#define AM335X_I2C_BUF_TXTRSH(X)    (((X) << AM335X_I2C_BUF_TXTRSH_SHIFT)
> \
> +                                     & AM335X_I2C_BUF_TXTRSH_MASK)
> +#define AM335X_I2C_BUF_TXFIFO_CLR   (0x00000040u)
> +#define AM335X_I2C_BUF_RXTRSH_SHIFT (8)
> +#define AM335X_I2C_BUF_RXTRSH_MASK  (0x00003F00u)
> +#define AM335X_I2C_BUF_RXTRSH(X)    (((X) << AM335X_I2C_BUF_RXTRSH_SHIFT)
> \
> +                                     & AM335X_I2C_BUF_RXTRSH_MASK)
> +#define AM335X_I2C_BUF_RXFIFO_CLR   (0x00004000u)
> +
>  /* I2C status Register */
> +#define AM335X_I2C_IRQSTATUS_AL   (1 << 0)
>  #define AM335X_I2C_IRQSTATUS_NACK (1 << 1)
> -#define AM335X_I2C_IRQSTATUS_ROVR (1 << 11)
> -#define AM335X_I2C_IRQSTATUS_AL   (1<<0)
>  #define AM335X_I2C_IRQSTATUS_ARDY (1 << 2)
>  #define AM335X_I2C_IRQSTATUS_RRDY (1 << 3)
>  #define AM335X_I2C_IRQSTATUS_XRDY (1 << 4)
> -#define AM335X_I2C_IRQSTATUS_XUDF (1 << 10)
> -#define AM335X_I2C_BUF_TXFIFO_CLR   (0x00000040u)
> -#define AM335X_I2C_BUF_RXFIFO_CLR   (0x00004000u)
> -#define AM335X_I2C_IRQSTATUS_AAS  (1 << 9)
> -#define AM335X_I2C_IRQSTATUS_BF  (1 << 8)
> +#define AM335X_I2C_IRQSTATUS_GC   (1 << 5)
>  #define AM335X_I2C_IRQSTATUS_STC  (1 << 6)
> -#define AM335X_I2C_IRQSTATUS_GC (1 << 5)
> -#define AM335X_I2C_IRQSTATUS_XDR (1 << 14)
> -#define AM335X_I2C_IRQSTATUS_RDR (1 << 13)
> +#define AM335X_I2C_IRQSTATUS_AERR (1 << 7)
> +#define AM335X_I2C_IRQSTATUS_BF   (1 << 8)
> +#define AM335X_I2C_IRQSTATUS_AAS  (1 << 9)
> +#define AM335X_I2C_IRQSTATUS_XUDF (1 << 10)
> +#define AM335X_I2C_IRQSTATUS_ROVR (1 << 11)
> +#define AM335X_I2C_IRQSTATUS_BB   (1 << 12)
> +#define AM335X_I2C_IRQSTATUS_RDR  (1 << 13)
> +#define AM335X_I2C_IRQSTATUS_XDR  (1 << 14)
>
>  #define AM335X_I2C_INT_RECV_READY AM335X_I2C_IRQSTATUS_RRDY
>  #define AM335X_I2C_CON_STOP  (0x00000002u)
>  #define AM335X_I2C_CON_START (0x00000001u)
>  #define AM335X_I2C_CFG_MST_RX AM335X_I2C_CON_MST
>  #define AM335X_I2C_CFG_MST_TX  (AM335X_I2C_CON_TRX | AM335X_I2C_CON_MST)
> -#define AM335X_I2C_IRQSTATUS_RAW_BB   (0x00001000u)
>  #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK
> (0x00000020u)
>  #define AM335X_I2C_INT_STOP_CONDITION AM335X_I2C_IRQSTATUS_BF
>
> --
> 2.21.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20190625/2a6fc513/attachment-0002.html>


More information about the devel mailing list