[PATCH 1/2] Beaglebone black i2c code, modify by Punit Vara - Add beagle/bbb-i2c.c i2c driver - Modify include/i2c.h - Modify Makefile.am But i2c cannot work currently

Gedare Bloom gedare at rtems.org
Thu Mar 30 15:24:54 UTC 2017


Hi Sichen,

Can you please make your git commit message a bit "cleaner" so that it
appears more nicely in git-log and in the email subject?
https://devel.rtems.org/wiki/Developer/Git#GitCommits Give a
descriptive short first line, followed by a blank line, and then the
more detailed commit message can follow.

Since this code was written by someone else, you should use the
--author="Punit Vara <...>" to give proper credit to him. This is part
of the reason to provide separate commits. Note that the author's name
is included in the git-commit information, so you don't need to also
repeat it in your commit message.

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



More information about the devel mailing list