<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Arial, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p>I got your mean, thank you , PV.</p>
<p><br>
</p>
<p>Best Regards</p>
<p>Sichen Zhao</p>
<div id="Signature"></div>
<br>
<br>
<div style="color: rgb(0, 0, 0);">
<div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> devel <devel-bounces@rtems.org> on behalf of punit vara <punitvara@gmail.com><br>
<b>Sent:</b> Wednesday, May 24, 2017 2:05 AM<br>
<b>To:</b> Sichen Zhao<br>
<b>Cc:</b> Christian Mauderer; rtems-devel@rtems.org<br>
<b>Subject:</b> Re: [PATCH] Add the i2c driver for Beaglebone Black:</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">On Tue, May 23, 2017 at 7:13 PM, Sichen Zhao <1473996754@qq.com> wrote:<br>
> Update ticket #2891 and my GSOC project<br>
><br>
> add c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c<br>
> modify c/src/lib/libbsp/arm/beagle/include/i2c.h<br>
> modify c/src/lib/libbsp/arm/beagle/include/bbb-gpio.h<br>
> modify c/src/lib/libcpu/arm/shared/include/am335x.h<br>
> modify c/src/lib/libbsp/arm/beagle/Makefile.am<br>
><br>
> Now can read the EEPROM by i2c, the test application link is: <a href="https://github.com/hahchenchen/GSOC-test-application" id="LPlnk200946" previewremoved="true">
https://github.com/hahchenchen/GSOC-test-application</a><br>
> ---<br>
>  c/src/lib/libbsp/arm/beagle/Makefile.am        |   1 +<br>
>  c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c      | 577 +++++++++++++++++++++++++<br>
>  c/src/lib/libbsp/arm/beagle/include/bbb-gpio.h |   4 +-<br>
>  c/src/lib/libbsp/arm/beagle/include/i2c.h      | 161 ++++++-<br>
>  c/src/lib/libcpu/arm/shared/include/am335x.h   | 198 +++++++++<br>
>  5 files changed, 921 insertions(+), 20 deletions(-)<br>
>  create mode 100644 c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c<br>
><br>
> diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am<br>
> index 8bb8478..274dc0e 100644<br>
> --- a/c/src/lib/libbsp/arm/beagle/Makefile.am<br>
> +++ b/c/src/lib/libbsp/arm/beagle/Makefile.am<br>
> @@ -115,6 +115,7 @@ libbsp_a_SOURCES += ../../shared/console.c \<br>
><br>
>  # I2C<br>
>  libbsp_a_SOURCES += misc/i2c.c<br>
> +libbsp_a_SOURCES += i2c/bbb-i2c.c<br>
><br>
>  # GPIO<br>
>  libbsp_a_SOURCES += gpio/bbb-gpio.c<br>
> diff --git a/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c b/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c<br>
> new file mode 100644<br>
> index 0000000..5c8958f<br>
> --- /dev/null<br>
> +++ b/c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c<br>
> @@ -0,0 +1,577 @@<br>
> +/**<br>
> + * @file<br>
> + *<br>
> + * @ingroup arm_beagle<br>
> + *<br>
> + * @brief BeagleBoard I2C bus initialization and API Support.<br>
> + */<br>
> +<br>
> +/*<br>
> + * Copyright (c) 2017 Sichen Zhao <zsc19940506@gmail.com><br>
> + *<br>
> + * The license and distribution terms for this file may be<br>
> + * found in the file LICENSE in this distribution or at<br>
> + * <a href="http://www.rtems.org/license/LICENSE" id="LPlnk739400" previewremoved="true">
http://www.rtems.org/license/LICENSE</a>.<br>
> + */<br>
> +<br>
> +/*<br>
> + * Modified on Punit Vara<punitvara@gmail.com> works, currently<br>
> + * the i2c file is working on the Beaglebone Black board(AM335x).<br>
> + */<br>
> +<br>
> +#include <stdio.h><br>
> +#include <bsp/i2c.h><br>
> +#include <libcpu/am335x.h><br>
> +#include <rtems/irq-extension.h><br>
> +#include <rtems/counter.h><br>
> +#include <bsp/bbb-gpio.h><br>
> +#include <rtems/score/assert.h><br>
> +<br>
> +<br>
> +static void am335x_i2c0_pinmux(bbb_i2c_bus *bus)<br>
> +{<br>
> +  REG(bus->regs + AM335X_CONF_I2C0_SDA) =<br>
> +  (BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN);<br>
> +<br>
> +  REG(bus->regs + AM335X_CONF_I2C0_SCL) =<br>
> +  (BBB_RXACTIVE | BBB_SLEWCTRL | BBB_PU_EN);<br>
> +}<br>
> +<br>
> +static void I2C0ModuleClkConfig(void)<br>
> +{<br>
> +    /* Configuring L3 Interface Clocks. */<br>
> +<br>
> +    /* Writing to MODULEMODE field of CM_PER_L3_CLKCTRL register. */<br>
> +  REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKCTRL) |=<br>
> +          CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE;<br>
> +<br>
<br>
I can see few Macros without AM335X_ . Change all those macros and<br>
don't use same name because this function is similar to starterware. I<br>
have used to just test my code last year. So change the macro names<br>
completely and add AM335X as prefix.<br>
<br>
Remove unnecessary lines in this code. Only write registers which are<br>
required to enable clock.<br>
<br>
> +    /* Waiting for MODULEMODE field to reflect the written value. */<br>
> +  while(CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKCTRL) &<br>
> +           CM_PER_L3_CLKCTRL_MODULEMODE));<br>
> +<br>
> +    /* Writing to MODULEMODE field of CM_PER_L3_INSTR_CLKCTRL register. */<br>
> +  REG(AM335X_CM_PER_ADDR + CM_PER_L3_INSTR_CLKCTRL) |=<br>
> +          CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE;<br>
> +<br>
> +    /* Waiting for MODULEMODE field to reflect the written value. */<br>
> +  while(CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_INSTR_CLKCTRL) &<br>
> +           CM_PER_L3_INSTR_CLKCTRL_MODULEMODE));<br>
> +<br>
> +    /* Writing to CLKTRCTRL field of CM_PER_L3_CLKSTCTRL register. */<br>
> +  REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKSTCTRL) |=<br>
> +          CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;<br>
> +<br>
> +    /* Waiting for CLKTRCTRL field to reflect the written value. */<br>
> +  while(CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKSTCTRL) &<br>
> +           CM_PER_L3_CLKSTCTRL_CLKTRCTRL));<br>
> +<br>
> +    /* Writing to CLKTRCTRL field of CM_PER_OCPWP_L3_CLKSTCTRL register. */<br>
> +  REG(AM335X_CM_PER_ADDR + CM_PER_OCPWP_L3_CLKSTCTRL) |=<br>
> +          CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP;<br>
> +<br>
> +    /*Waiting for CLKTRCTRL field to reflect the written value. */<br>
> +  while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_OCPWP_L3_CLKSTCTRL) &<br>
> +           CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL));<br>
> +<br>
> +    /* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */<br>
> +  REG(AM335X_CM_PER_ADDR + CM_PER_L3S_CLKSTCTRL) |=<br>
> +          CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP;<br>
> +<br>
> +    /*Waiting for CLKTRCTRL field to reflect the written value. */<br>
> +  while(CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3S_CLKSTCTRL) &<br>
> +           CM_PER_L3S_CLKSTCTRL_CLKTRCTRL));<br>
> +<br>
> +    /* Checking fields for necessary values.  */<br>
> +<br>
> +    /* Waiting for IDLEST field in CM_PER_L3_CLKCTRL register to be set to 0x0. */<br>
> +  while((CM_PER_L3_CLKCTRL_IDLEST_FUNC << CM_PER_L3_CLKCTRL_IDLEST_SHIFT)!=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKCTRL) &<br>
> +           CM_PER_L3_CLKCTRL_IDLEST));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for IDLEST field in CM_PER_L3_INSTR_CLKCTRL register to attain the<br>
> +    ** desired value.<br>
> +    */<br>
> +  while((CM_PER_L3_INSTR_CLKCTRL_IDLEST_FUNC <<<br>
> +           CM_PER_L3_INSTR_CLKCTRL_IDLEST_SHIFT)!=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_INSTR_CLKCTRL) &<br>
> +           CM_PER_L3_INSTR_CLKCTRL_IDLEST));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_L3_GCLK field in CM_PER_L3_CLKSTCTRL register to<br>
> +    ** attain the desired value.<br>
> +    */<br>
> +  while(CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3_CLKSTCTRL) &<br>
> +           CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_OCPWP_L3_GCLK field in CM_PER_OCPWP_L3_CLKSTCTRL<br>
> +    ** register to attain the desired value.<br>
> +    */<br>
> +  while(CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_OCPWP_L3_CLKSTCTRL) &<br>
> +           CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_L3S_GCLK field in CM_PER_L3S_CLKSTCTRL register<br>
> +    ** to attain the desired value.<br>
> +    */<br>
> +  while(CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK !=<br>
> +          (REG(AM335X_CM_PER_ADDR + CM_PER_L3S_CLKSTCTRL) &<br>
> +          CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK));<br>
> +<br>
> +<br>
> +    /* Configuring registers related to Wake-Up region. */<br>
> +<br>
> +    /* Writing to MODULEMODE field of CM_WKUP_CONTROL_CLKCTRL register. */<br>
> +  REG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) |=<br>
> +          CM_WKUP_CONTROL_CLKCTRL_MODULEMODE_ENABLE;<br>
> +<br>
> +    /* Waiting for MODULEMODE field to reflect the written value. */<br>
> +  while(CM_WKUP_CONTROL_CLKCTRL_MODULEMODE_ENABLE !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) &<br>
> +           CM_WKUP_CONTROL_CLKCTRL_MODULEMODE));<br>
> +<br>
> +    /* Writing to CLKTRCTRL field of CM_PER_L3S_CLKSTCTRL register. */<br>
> +  REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) |=<br>
> +          CM_WKUP_CLKSTCTRL_CLKTRCTRL_SW_WKUP;<br>
> +<br>
> +    /*Waiting for CLKTRCTRL field to reflect the written value. */<br>
> +  while(CM_WKUP_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &<br>
> +           CM_WKUP_CLKSTCTRL_CLKTRCTRL));<br>
> +<br>
> +    /* Writing to CLKTRCTRL field of CM_L3_AON_CLKSTCTRL register. */<br>
> +  REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L3_AON_CLKSTCTRL) |=<br>
> +          CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL_SW_WKUP;<br>
> +<br>
> +    /*Waiting for CLKTRCTRL field to reflect the written value. */<br>
> +  while(CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL_SW_WKUP !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L3_AON_CLKSTCTRL) &<br>
> +           CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL));<br>
> +<br>
> +    /* Writing to MODULEMODE field of CM_WKUP_I2C0_CLKCTRL register. */<br>
> +  REG(SOC_CM_WKUP_REGS + CM_WKUP_I2C0_CLKCTRL) |=<br>
> +          CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE;<br>
> +<br>
> +    /* Waiting for MODULEMODE field to reflect the written value. */<br>
> +  while(CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_I2C0_CLKCTRL) &<br>
> +           CM_WKUP_I2C0_CLKCTRL_MODULEMODE));<br>
> +<br>
> +    /* Verifying if the other bits are set to required settings. */<br>
> +<br>
> +    /*<br>
> +    ** Waiting for IDLEST field in CM_WKUP_CONTROL_CLKCTRL register to attain<br>
> +    ** desired value.<br>
> +    */<br>
> +  while((CM_WKUP_CONTROL_CLKCTRL_IDLEST_FUNC <<<br>
> +           CM_WKUP_CONTROL_CLKCTRL_IDLEST_SHIFT) !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) &<br>
> +           CM_WKUP_CONTROL_CLKCTRL_IDLEST));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_L3_AON_GCLK field in CM_L3_AON_CLKSTCTRL<br>
> +    ** register to attain desired value.<br>
> +    */<br>
> +  while(CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKACTIVITY_L3_AON_GCLK !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L3_AON_CLKSTCTRL) &<br>
> +           CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKACTIVITY_L3_AON_GCLK));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for IDLEST field in CM_WKUP_L4WKUP_CLKCTRL register to attain<br>
> +    ** desired value.<br>
> +    */<br>
> +  while((CM_WKUP_L4WKUP_CLKCTRL_IDLEST_FUNC <<<br>
> +           CM_WKUP_L4WKUP_CLKCTRL_IDLEST_SHIFT) !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_L4WKUP_CLKCTRL) &<br>
> +           CM_WKUP_L4WKUP_CLKCTRL_IDLEST));<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_L4_WKUP_GCLK field in CM_WKUP_CLKSTCTRL register<br>
> +    ** to attain desired value.<br>
> +    */<br>
> +  while(CM_WKUP_CLKSTCTRL_CLKACTIVITY_L4_WKUP_GCLK !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &<br>
> +           CM_WKUP_CLKSTCTRL_CLKACTIVITY_L4_WKUP_GCLK));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_L4_WKUP_AON_GCLK field in CM_L4_WKUP_AON_CLKSTCTRL<br>
> +    ** register to attain desired value.<br>
> +    */<br>
> +  while(CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL_CLKACTIVITY_L4_WKUP_AON_GCLK !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL) &<br>
> +           CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL_CLKACTIVITY_L4_WKUP_AON_GCLK));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for CLKACTIVITY_I2C0_GFCLK field in CM_WKUP_CLKSTCTRL<br>
> +    ** register to attain desired value.<br>
> +    */<br>
> +  while(CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_CLKSTCTRL) &<br>
> +           CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK));<br>
> +<br>
> +    /*<br>
> +    ** Waiting for IDLEST field in CM_WKUP_I2C0_CLKCTRL register to attain<br>
> +    ** desired value.<br>
> +    */<br>
> +  while((CM_WKUP_I2C0_CLKCTRL_IDLEST_FUNC <<<br>
> +           CM_WKUP_I2C0_CLKCTRL_IDLEST_SHIFT) !=<br>
> +          (REG(SOC_CM_WKUP_REGS + CM_WKUP_I2C0_CLKCTRL) &<br>
> +           CM_WKUP_I2C0_CLKCTRL_IDLEST));<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_i2c_reset(bbb_i2c_bus *bus)<br>
> +{<br>
> +  volatile bbb_i2c_regs *regs = bus->regs;<br>
> +   int timeout = I2C_TIMEOUT;<br>
> +  if (REG(&regs->BBB_I2C_CON) & I2C_CON_EN) {<br>
> +    REG(&regs->BBB_I2C_CON) = I2C_CON_CLR;<br>
> +    udelay(50000);<br>
> +  }<br>
> +  REG(&regs->BBB_I2C_SYSC) = I2C_SYSC_SRST; /* for ES2 after soft reset */<br>
> +  udelay(1000);<br>
> +  REG(&regs->BBB_I2C_CON) = I2C_CON_EN;<br>
> +<br>
> +  while (!(REG(&regs->BBB_I2C_SYSS) & I2C_SYSS_RDONE) && timeout--) {<br>
> +    if (timeout <= 0) {<br>
> +      puts("ERROR: Timeout in soft-reset\n");<br>
> +      return;<br>
> +    }<br>
> +    udelay(1000);<br>
> +  }<br>
> +}<br>
> +/*<br>
> +Possible values for msg->flag<br>
> +   * - @ref I2C_M_TEN,<br>
> +   * - @ref I2C_M_RD,<br>
> +   * - @ref I2C_M_STOP,<br>
> +   * - @ref I2C_M_NOSTART,<br>
> +   * - @ref I2C_M_REV_DIR_ADDR,<br>
> +   * - @ref I2C_M_IGNORE_NAK,<br>
> +   * - @ref I2C_M_NO_RD_ACK, and<br>
> +   * - @ref I2C_M_RECV_LEN.<br>
> +*/<br>
> +<br>
> +static void am335x_i2c_set_address_size(const i2c_msg *msgs,<br>
> +           volatile bbb_i2c_regs *regs)<br>
> +{<br>
> +    /*can be configured multiple modes here. Need to think about own address modes*/<br>
> +  if ((msgs->flags & I2C_M_TEN) == 0)  {<br>
> +  /* 7-bit mode slave address mode*/<br>
> +  REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_7BIT_SLAVE_ADDR;<br>
> +  } else {<br>
> +  /* 10-bit slave address mode*/<br>
> +  REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_10BIT_SLAVE_ADDR;<br>
> +  }<br>
> +  }<br>
> +<br>
> +static void am335x_i2c_next_byte(bbb_i2c_bus *bus)<br>
> +{<br>
> +  i2c_msg *msg;<br>
> +  ++bus->msgs;<br>
> +  --bus->msg_todo;<br>
> +  msg = &bus->msgs[0];<br>
> +  bus->current_msg_todo = msg->len;<br>
> +  bus->current_msg_byte = msg->buf;<br>
> +}<br>
> +<br>
> +static unsigned int am335x_i2c_intrawstatus(volatile bbb_i2c_regs *regs)<br>
> +{<br>
> +  return (REG(&regs->BBB_I2C_IRQSTATUS_RAW));<br>
> +}<br>
> +<br>
> +static void am335x_i2c_masterint_enable(volatile bbb_i2c_regs *regs,<br>
> +       unsigned int flag)<br>
> +{<br>
> +  REG(&regs->BBB_I2C_IRQENABLE_SET) |= flag;<br>
> +}<br>
> +<br>
> +static void am335x_i2c_masterint_disable(volatile bbb_i2c_regs *regs,<br>
> +       unsigned int flag)<br>
> +{<br>
> +  REG(&regs->BBB_I2C_IRQENABLE_CLR) = flag;<br>
> +}<br>
> +<br>
> +static void am335x_int_clear(volatile bbb_i2c_regs *regs, unsigned int flag)<br>
> +{<br>
> +  REG(&regs->BBB_I2C_IRQSTATUS) = flag;<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_clean_interrupts(volatile bbb_i2c_regs *regs)<br>
> +{<br>
> +  am335x_i2c_masterint_enable(regs,I2C_ALL_FLAGS);<br>
> +  am335x_int_clear(regs,I2C_ALL_FLAGS);<br>
> +  am335x_i2c_masterint_disable(regs,I2C_ALL_FLAGS);<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_i2c_setup_read_transfer(bbb_i2c_bus *bus,<br>
> +       volatile bbb_i2c_regs *regs,<br>
> +       const i2c_msg *msgs, bool send_stop)<br>
> +{<br>
> +  volatile unsigned int no_bytes;<br>
> +  int status;<br>
> +<br>
> +  REG(&regs->BBB_I2C_CNT) = bus->current_msg_todo;<br>
> +<br>
> +  REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_MST_RX | AM335X_I2C_CON_I2C_EN;<br>
> +<br>
> +  if (send_stop) {<br>
> +    REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_START | AM335X_I2C_CON_STOP;<br>
> +  } else {<br>
> +  REG(&regs->BBB_I2C_CON) |=  AM335X_I2C_CON_START;<br>
> +  }<br>
> +  am335x_i2c_masterint_enable(regs,AM335X_I2C_INT_RECV_READY<br>
> +                                  | AM335X_I2C_IRQSTATUS_ARDY);<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_i2c_continue_read_transfer(<br>
> +  bbb_i2c_bus *bus,<br>
> +  volatile bbb_i2c_regs *regs<br>
> +)<br>
> +{<br>
> +  bus->current_msg_byte[bus->already_transferred] = REG(&regs->BBB_I2C_DATA);<br>
> +<br>
> +  bus->already_transferred++;<br>
> +<br>
> +  REG(&regs->BBB_I2C_IRQSTATUS) = AM335X_I2C_INT_RECV_READY;<br>
> +<br>
> +  if (bus->already_transferred ==  bus->current_msg_todo-1) {<br>
> +  REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_STOP;<br>
> +  }<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_i2c_continue_write(bbb_i2c_bus *bus,<br>
> +       volatile bbb_i2c_regs *regs)<br>
> +{<br>
> +<br>
> +<br>
> +if (bus->already_transferred == bus->msg_todo) {<br>
> +  REG(&regs->BBB_I2C_DATA) = bus->current_msg_byte[bus->already_transferred];<br>
> +  REG(&regs->BBB_I2C_IRQSTATUS) = AM335X_I2C_IRQSTATUS_XRDY;<br>
> +  am335x_i2c_masterint_disable(regs, AM335X_I2C_IRQSTATUS_XRDY );<br>
> +  REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_STOP;<br>
> +   } else {<br>
> +  writeb(bus->current_msg_byte[bus->already_transferred],&regs->BBB_I2C_DATA);<br>
> +  REG(&regs->BBB_I2C_IRQSTATUS) = AM335X_I2C_IRQSTATUS_XRDY;<br>
> +     bus->already_transferred++;<br>
> +   }<br>
> +}<br>
> +<br>
> +static void am335x_i2c_setup_write_transfer(bbb_i2c_bus *bus,<br>
> +       volatile bbb_i2c_regs *regs, const i2c_msg *msgs)<br>
> +{<br>
> +  volatile unsigned int no_bytes;<br>
> +<br>
> +  REG(&regs->BBB_I2C_CNT) = bus->current_msg_todo;<br>
> +  no_bytes = REG(&regs->BBB_I2C_CNT);<br>
> +  REG(&regs->BBB_I2C_SA) = msgs->addr;<br>
> +  REG(&regs->BBB_I2C_CON) = AM335X_I2C_CFG_MST_TX | AM335X_I2C_CON_I2C_EN;<br>
> +  am335x_clean_interrupts(regs);<br>
> +  am335x_i2c_masterint_enable(regs,AM335X_I2C_IRQSTATUS_XRDY );<br>
> +  REG(&regs->BBB_I2C_CON) |= AM335X_I2C_CON_START | AM335X_I2C_CON_STOP;<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_i2c_setup_transfer(bbb_i2c_bus *bus,<br>
> +            volatile bbb_i2c_regs *regs)<br>
> +{<br>
> +  const i2c_msg *msgs = bus->msgs;<br>
> +  uint32_t msg_todo = bus->msg_todo;<br>
> +  bool send_stop = false;<br>
> +  uint32_t i;<br>
> +<br>
> +  bus->current_todo = msgs[0].len;<br>
> +  for (i = 1; i < msg_todo && (msgs[i].flags & I2C_M_NOSTART) != 0; ++i) {<br>
> +    bus->current_todo += msgs[i].len;<br>
> +  }<br>
> +  regs = bus->regs;<br>
> +  REG(&bus->regs->BBB_I2C_BUF) |= AM335X_I2C_BUF_TXFIFO_CLR;<br>
> +  REG(&bus->regs->BBB_I2C_BUF) |= AM335X_I2C_BUF_RXFIFO_CLR;<br>
> +  am335x_i2c_set_address_size(msgs,regs);<br>
> +  bus->read = (msgs->flags & I2C_M_RD) != 0;<br>
> +  bus->already_transferred = (bus->read == true) ? 0 : 1;<br>
> +<br>
> +  if (bus->read) {<br>
> +    if (bus->current_msg_todo == 1) {<br>
> +      send_stop = true;<br>
> +    }<br>
> +  am335x_i2c_setup_read_transfer(bus,regs,msgs,send_stop);<br>
> +  } else {<br>
> +  am335x_i2c_setup_write_transfer(bus,regs,msgs);<br>
> +  }<br>
> +}<br>
> +<br>
> +<br>
> +static void am335x_i2c_interrupt(void *arg)<br>
> +{<br>
> +  bbb_i2c_bus *bus = arg;<br>
> +  volatile bbb_i2c_regs *regs = bus->regs;<br>
> +  /* get status of enabled interrupts */<br>
> +  uint32_t irqstatus = REG(&regs->BBB_I2C_IRQSTATUS);<br>
> +  bool done = false;<br>
> +  /* Clear all enabled interrupt except receive ready and transmit ready interrupt in status register */<br>
> +  REG(&regs->BBB_I2C_IRQSTATUS) = (irqstatus & ~( AM335X_I2C_IRQSTATUS_RRDY<br>
> +                                                | AM335X_I2C_IRQSTATUS_XRDY));<br>
> +<br>
> + if (irqstatus & AM335X_I2C_INT_RECV_READY ) {<br>
> +    am335x_i2c_continue_read_transfer(bus, regs);<br>
> +  }<br>
> +<br>
> +  if (irqstatus & AM335X_I2C_IRQSTATUS_XRDY) {<br>
> +    am335x_i2c_continue_write(bus,regs);<br>
> +  }<br>
> +<br>
> +  if (irqstatus & AM335X_I2C_IRQSTATUS_NACK) {<br>
> +    done = true;<br>
> +    am335x_i2c_masterint_disable(regs,AM335X_I2C_IRQSTATUS_NACK);<br>
> +  }<br>
> +<br>
> +   if (irqstatus & AM335X_I2C_IRQSTATUS_ARDY) {<br>
> +  done = true;<br>
> +  REG(&regs->BBB_I2C_IRQSTATUS) = I2C_STAT_ARDY;<br>
> +  }<br>
> +<br>
> +   if (irqstatus & AM335X_I2C_IRQSTATUS_BF) {<br>
> +   REG( &regs->BBB_I2C_IRQSTATUS) = AM335X_I2C_IRQSTATUS_BF;<br>
> +  }<br>
> +<br>
> +  if (done) {<br>
> +    uint32_t err = irqstatus & BBB_I2C_IRQ_ERROR;<br>
> +    am335x_i2c_next_byte(bus);<br>
> +<br>
> +    if (bus->msg_todo == 0 ) {<br>
> +    rtems_status_code sc;<br>
> +    am335x_i2c_masterint_disable(regs, (AM335X_I2C_IRQSTATUS_RRDY<br>
> +                                       | AM335X_I2C_IRQSTATUS_XRDY<br>
> +                                       | AM335X_I2C_IRQSTATUS_BF));<br>
> +    REG(&regs->BBB_I2C_IRQSTATUS) = err;<br>
> +<br>
> +    sc = rtems_event_transient_send(bus->task_id);<br>
> +    _Assert(sc == RTEMS_SUCCESSFUL);<br>
> +    (void) sc;<br>
> +    } else {<br>
> +    am335x_i2c_setup_transfer(bus, regs);<br>
> +    }<br>
> +  }<br>
> +}<br>
> +<br>
> +static int am335x_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)<br>
> +{<br>
> +  rtems_status_code sc;<br>
> +  bbb_i2c_bus *bus = (bbb_i2c_bus *)base;<br>
> +  volatile bbb_i2c_regs *regs;<br>
> +  uint32_t i;<br>
> +  rtems_task_wake_after(1);<br>
> +<br>
> +  if (msg_count < 1){<br>
> +    return 1;<br>
> +  }<br>
> +  for (i=0; i<msg_count;++i) {<br>
> +      if ((msgs[i].flags & I2C_M_RECV_LEN) != 0) {<br>
> +        return -EINVAL;<br>
> +      }<br>
> +  }<br>
> +  bus->msgs = &msgs[0];<br>
> +  bus->msg_todo = msg_count;<br>
> +  bus->current_msg_todo = msgs[0].len;<br>
> +  bus->current_msg_byte = msgs[0].buf;<br>
> +  bus->task_id = rtems_task_self();<br>
> +  regs = bus->regs;<br>
> +  am335x_i2c_setup_transfer(bus,regs);<br>
> +  REG(&regs->BBB_I2C_IRQENABLE_SET) = BBB_I2C_IRQ_USED;<br>
> +<br>
> +  sc = rtems_event_transient_receive(RTEMS_WAIT, bus->base.timeout);<br>
> +  if (sc != RTEMS_SUCCESSFUL) {<br>
> +    am335x_i2c_reset(bus);<br>
> +    rtems_event_transient_clear();<br>
> +    return -ETIMEDOUT;<br>
> +  }<br>
> +  return 0;<br>
> +}<br>
> +<br>
> +static int am335x_i2c_set_clock(i2c_bus *base, unsigned long clock)<br>
> +{<br>
> +  bbb_i2c_bus *bus = (bbb_i2c_bus *) base;<br>
> +  volatile bbb_i2c_regs *regs = bus->regs;<br>
> +  uint32_t prescaler,divider;<br>
> +<br>
> +  prescaler = (BBB_I2C_SYSCLK / BBB_I2C_INTERNAL_CLK) -1;<br>
> +  REG(&bus->regs->BBB_I2C_PSC) = prescaler;<br>
> +  divider = BBB_I2C_INTERNAL_CLK/(2*clock);<br>
> +  REG(&bus->regs->BBB_I2C_SCLL) = (divider - 7);<br>
> +  REG(&bus->regs->BBB_I2C_SCLH) = (divider - 5);<br>
> +  return 0;<br>
> +}<br>
> +<br>
> +<br>
> +<br>
> +<br>
> +static void am335x_i2c_destroy(i2c_bus *base)<br>
> +{<br>
> +  bbb_i2c_bus *bus = (bbb_i2c_bus *) base;<br>
> +  rtems_status_code sc;<br>
> +<br>
> +  sc = rtems_interrupt_handler_remove(bus->irq, am335x_i2c_interrupt, bus);<br>
> +  _Assert(sc == RTEMS_SUCCESSFUL);<br>
> +  (void)sc;<br>
> +  i2c_bus_destroy_and_free(&bus->base);<br>
> +}<br>
> +<br>
> +int am335x_i2c_bus_register(<br>
> +  const char *bus_path,<br>
> +  uintptr_t register_base,<br>
> +  uint32_t input_clock,<br>
> +  rtems_vector_number irq<br>
> +)<br>
> +{<br>
> +  bbb_i2c_bus *bus;<br>
> +  rtems_status_code sc;<br>
> +  int err;<br>
> +  /*check bus number is >0 & <MAX*/<br>
> +  bus = (bbb_i2c_bus *) i2c_bus_alloc_and_init(sizeof(*bus));<br>
> +  if (bus == NULL) {<br>
> +    return -1;<br>
> +  }<br>
> +  bus->regs = (volatile bbb_i2c_regs *) register_base;<br>
> +<br>
> +  I2C0ModuleClkConfig();<br>
> +  am335x_i2c0_pinmux(bus);<br>
> +  am335x_i2c_reset(bus);<br>
> +  bus->input_clock = input_clock;<br>
> +  err = am335x_i2c_set_clock(&bus->base, I2C_BUS_CLOCK_DEFAULT);<br>
> +<br>
> +  if (err != 0) {<br>
> +    (*bus->base.destroy)(&bus->base);<br>
> +    rtems_set_errno_and_return_minus_one(-err);<br>
> +  }<br>
> +   bus->irq = irq;<br>
> +  REG(&bus->regs->BBB_I2C_IRQSTATUS) = I2C_ALL_IRQ_FLAGS;<br>
> +<br>
> +  sc  = rtems_interrupt_handler_install(<br>
> +    irq,<br>
> +    "BBB_I2C",<br>
> +    RTEMS_INTERRUPT_UNIQUE,<br>
> +    (rtems_interrupt_handler)am335x_i2c_interrupt,<br>
> +    bus<br>
> +   );<br>
> +<br>
> +  if (sc != RTEMS_SUCCESSFUL) {<br>
> +    (*bus->base.destroy)(&bus->base);<br>
> +    rtems_set_errno_and_return_minus_one(EIO);<br>
> +  }<br>
> +  bus->base.transfer = am335x_i2c_transfer;<br>
> +  bus->base.set_clock = am335x_i2c_set_clock;<br>
> +  bus->base.destroy = am335x_i2c_destroy;<br>
> +  return i2c_bus_register(&bus->base,bus_path);<br>
> +}<br>
> \ No newline at end of file<br>
> diff --git a/c/src/lib/libbsp/arm/beagle/include/bbb-gpio.h b/c/src/lib/libbsp/arm/beagle/include/bbb-gpio.h<br>
> index 8cce556..ceb12a4 100644<br>
> --- a/c/src/lib/libbsp/arm/beagle/include/bbb-gpio.h<br>
> +++ b/c/src/lib/libbsp/arm/beagle/include/bbb-gpio.h<br>
> @@ -35,9 +35,11 @@ extern "C" {<br>
>  #define BBB_PU_EN (1 << 4)<br>
>  #define BBB_PD_EN ~BBB_PU_EN<br>
>  #define BBB_MUXMODE(X) (X & 0x7)<br>
> +#define BBB_RXACTIVE (1 << 5)<br>
> +#define BBB_SLEWCTRL (1 << 6)<br>
><br>
>  #ifdef __cplusplus<br>
>  }<br>
>  #endif /* __cplusplus */<br>
><br>
> -#endif /* LIBBSP_ARM_BEAGLE_BBB_GPIO_H */<br>
> \ No newline at end of file<br>
> +#endif /* LIBBSP_ARM_BEAGLE_BBB_GPIO_H */<br>
> diff --git a/c/src/lib/libbsp/arm/beagle/include/i2c.h b/c/src/lib/libbsp/arm/beagle/include/i2c.h<br>
> index e7d1716..d111070 100644<br>
> --- a/c/src/lib/libbsp/arm/beagle/include/i2c.h<br>
> +++ b/c/src/lib/libbsp/arm/beagle/include/i2c.h<br>
> @@ -1,5 +1,5 @@<br>
>  /**<br>
> - * @file<br>
> +<br>
>   *<br>
>   * @ingroup arm_beagle<br>
>   *<br>
> @@ -24,7 +24,7 @@<br>
>  #define LIBBSP_ARM_BEAGLE_I2C_H<br>
><br>
>  #include <rtems.h><br>
> -<br>
> +#include <dev/i2c/i2c.h><br>
>  #include <bsp.h><br>
><br>
>  #ifdef __cplusplus<br>
> @@ -43,6 +43,7 @@ extern "C" {<br>
>  #define I2C_CON_XA  (1 << 8)   /* Expand address */<br>
>  #define I2C_CON_STP (1 << 1)   /* Stop condition (master mode only) */<br>
>  #define I2C_CON_STT (1 << 0)   /* Start condition (master mode only) */<br>
> +#define I2C_CON_CLR 0x0  /* Clear configuration register */<br>
><br>
>  /* I2C Status Register (I2C_STAT): */<br>
><br>
> @@ -57,7 +58,6 @@ extern "C" {<br>
>  #define I2C_STAT_ARDY (1 << 2)  /* Register access ready */<br>
>  #define I2C_STAT_NACK (1 << 1)  /* No acknowledgment interrupt enable */<br>
>  #define I2C_STAT_AL (1 << 0)  /* Arbitration lost interrupt enable */<br>
> -<br>
>  /* I2C Interrupt Enable Register (I2C_IE): */<br>
>  #define I2C_IE_GC_IE  (1 << 5)<br>
>  #define I2C_IE_XRDY_IE  (1 << 4) /* Transmit data ready interrupt enable */<br>
> @@ -65,6 +65,10 @@ extern "C" {<br>
>  #define I2C_IE_ARDY_IE  (1 << 2) /* Register access ready interrupt enable */<br>
>  #define I2C_IE_NACK_IE  (1 << 1) /* No acknowledgment interrupt enable */<br>
>  #define I2C_IE_AL_IE  (1 << 0) /* Arbitration lost interrupt enable */<br>
> +<br>
> +/* I2C SYSC Register (I2C_SYSC): */<br>
> +#define I2C_SYSC_SRST (1 << 1)<br>
> +<br>
>  /*<br>
>   * The equation for the low and high time is<br>
>   * tlow = scll + scll_trim = (sampling clock * tlow_duty) / speed<br>
> @@ -144,6 +148,8 @@ extern "C" {<br>
><br>
>  #define CONFIG_SYS_I2C_SPEED    100000<br>
>  #define CONFIG_SYS_I2C_SLAVE    1<br>
> +#define I2C_ALL_FLAGS 0x7FFF<br>
> +#define I2C_ALL_IRQ_FLAGS 0xFFFF<br>
><br>
>  struct i2c {<br>
>    unsigned short rev;   /* 0x00 */<br>
> @@ -180,20 +186,8 @@ struct i2c {<br>
>    unsigned short res15;<br>
>  };<br>
><br>
> -static unsigned short wait_for_pin( void );<br>
> -<br>
> -static void wait_for_bb( void );<br>
> -<br>
> -static void flush_fifo( void );<br>
> -<br>
>  void i2c_init( int speed, int slaveadd );<br>
><br>
> -static int i2c_read_byte(<br>
> -  unsigned char devaddr,<br>
> -  unsigned char regoffset,<br>
> -  unsigned char *value<br>
> -);<br>
> -<br>
>  int i2c_write(<br>
>    unsigned char chip,<br>
>    unsigned int addr,<br>
> @@ -210,10 +204,6 @@ int i2c_read(<br>
>    int len<br>
>  );<br>
><br>
> -static int imw ( unsigned char  chip, unsigned long addr, unsigned char byte );<br>
> -<br>
> -static int imd( unsigned char chip, unsigned int addr, unsigned int length );<br>
> -<br>
>  /**<br>
>   * @brief Initializes the I2C module @a i2c.<br>
>   *<br>
> @@ -361,6 +351,139 @@ static inline rtems_status_code beagle_i2c_read(<br>
>    return beagle_i2c_write_and_read(i2c, addr, NULL, 0, in, in_size);<br>
>  }<br>
><br>
> +#define BBB_I2C_SYSCLK 48000000<br>
> +#define BBB_I2C_INTERNAL_CLK 12000000<br>
> +#define BBB_I2C_SPEED_CLK 100000<br>
> +<br>
> +#define BBB_I2C_IRQ_ERROR \<br>
> +  (AM335X_I2C_IRQSTATUS_NACK \<br>
> +    | AM335X_I2C_IRQSTATUS_ROVR \<br>
> +    | AM335X_I2C_IRQSTATUS_AL \<br>
> +    | AM335X_I2C_IRQSTATUS_ARDY \<br>
> +    | AM335X_I2C_IRQSTATUS_RRDY \<br>
> +    | AM335X_I2C_IRQSTATUS_XRDY \<br>
> +    | AM335X_I2C_IRQSTATUS_XUDF )<br>
> +<br>
> +  #define BBB_I2C_IRQ_USED \<br>
> +  ( AM335X_I2C_IRQSTATUS_ARDY \<br>
> +    | AM335X_I2C_IRQSTATUS_XRDY)<br>
> +<br>
> +<br>
> +#define BBB_I2C_0_BUS_PATH "/dev/i2c-0"<br>
> +#define BBB_I2C_1_BUS_PATH "/dev/i2c-1"<br>
> +#define BBB_I2C_2_BUS_PATH "/dev/i2c-2"<br>
> +<br>
> +#define BBB_I2C0_IRQ 70<br>
> +#define BBB_I2C1_IRQ 71<br>
> +#define BBB_I2C2_IRQ 30<br>
> +<br>
> +#define MODE2 2<br>
> +#define MODE3 3<br>
> +<br>
> +<br>
> +typedef enum {<br>
> +  I2C0,<br>
> +  I2C1,<br>
> +  I2C2,<br>
> +  I2C_COUNT<br>
> +}bbb_i2c_id_t;<br>
> +<br>
> +typedef struct i2c_regs<br>
> +{<br>
> +  uint32_t BBB_I2C_REVNB_LO;<br>
> +  uint32_t BBB_I2C_REVNB_HI;<br>
> +  uint32_t dummy1[2];<br>
> +  uint32_t BBB_I2C_SYSC;<br>
> +  uint32_t dummy2[4];<br>
> +  uint32_t BBB_I2C_IRQSTATUS_RAW;<br>
> +  uint32_t BBB_I2C_IRQSTATUS;<br>
> +  uint32_t BBB_I2C_IRQENABLE_SET;<br>
> +  uint32_t BBB_I2C_IRQENABLE_CLR;<br>
> +  uint32_t BBB_I2C_WE;<br>
> +  uint32_t BBB_I2C_DMARXENABLE_SET;<br>
> +  uint32_t BBB_I2C_DMATXENABLE_SET;<br>
> +  uint32_t BBB_I2C_DMARXENABLE_CLR;<br>
> +  uint32_t BBB_I2C_DMATXENABLE_CLR;<br>
> +  uint32_t BBB_I2C_DMARXWAKE_EN;<br>
> +  uint32_t BBB_I2C_DMATXWAKE_EN;<br>
> +  uint32_t dummy3[16];<br>
> +  uint32_t BBB_I2C_SYSS;<br>
> +  uint32_t BBB_I2C_BUF;<br>
> +  uint32_t BBB_I2C_CNT;<br>
> +  uint32_t BBB_I2C_DATA;<br>
> +  uint32_t dummy4;<br>
> +  uint32_t BBB_I2C_CON;<br>
> +  uint32_t BBB_I2C_OA;<br>
> +  uint32_t BBB_I2C_SA;<br>
> +  uint32_t BBB_I2C_PSC;<br>
> +  uint32_t BBB_I2C_SCLL;<br>
> +  uint32_t BBB_I2C_SCLH;<br>
> +  uint32_t BBB_I2C_SYSTEST;<br>
> +  uint32_t BBB_I2C_BUFSTAT;<br>
> +  uint32_t BBB_I2C_OA1;<br>
> +  uint32_t BBB_I2C_OA2;<br>
> +  uint32_t BBB_I2C_OA3;<br>
> +  uint32_t BBB_I2C_ACTOA;<br>
> +  uint32_t BBB_I2C_SBLOCK;<br>
> +}bbb_i2c_regs;<br>
> +<br>
> +typedef struct bbb_i2c_bus{<br>
> +  i2c_bus base;<br>
> +  volatile bbb_i2c_regs *regs;<br>
> +  i2c_msg *msgs;<br>
> +  uint32_t msg_todo;<br>
> +  uint32_t current_msg_todo;<br>
> +  uint8_t *current_msg_byte;<br>
> +  uint32_t current_todo;<br>
> +  bool read;<br>
> +  bool hold;<br>
> +  rtems_id task_id;<br>
> +  rtems_vector_number irq;<br>
> +  uint32_t input_clock;<br>
> +  uint32_t already_transferred;<br>
> +} bbb_i2c_bus;<br>
> +<br>
> +int am335x_i2c_bus_register(<br>
> +  const char *bus_path,<br>
> +  uintptr_t register_base,<br>
> +  uint32_t input_clock,<br>
> +  rtems_vector_number irq<br>
> +);<br>
> +<br>
> +static inline int bbb_register_i2c_0(void)<br>
> +{<br>
> +  return am335x_i2c_bus_register(<br>
> +    BBB_I2C_0_BUS_PATH,<br>
> +    AM335X_I2C0_BASE,<br>
> +    I2C_BUS_CLOCK_DEFAULT,<br>
> +    BBB_I2C0_IRQ<br>
> +  );<br>
> +}<br>
> +<br>
> +static inline int bbb_register_i2c_1(void)<br>
> +{<br>
> +  return am335x_i2c_bus_register(<br>
> +    BBB_I2C_1_BUS_PATH,<br>
> +    AM335X_I2C1_BASE,<br>
> +    I2C_BUS_CLOCK_DEFAULT,<br>
> +    BBB_I2C1_IRQ<br>
> +  );<br>
> +}<br>
> +<br>
> +static inline int bbb_register_i2c_2(void)<br>
> +{<br>
> +  return am335x_i2c_bus_register(<br>
> +    BBB_I2C_2_BUS_PATH,<br>
> +    AM335X_I2C2_BASE,<br>
> +    I2C_BUS_CLOCK_DEFAULT,<br>
> +    BBB_I2C2_IRQ<br>
> +  );<br>
> +}<br>
> +<br>
> +<br>
> +<br>
> +<br>
> +<br>
>  #ifdef __cplusplus<br>
>  }<br>
>  #endif /* __cplusplus */<br>
> diff --git a/c/src/lib/libcpu/arm/shared/include/am335x.h b/c/src/lib/libcpu/arm/shared/include/am335x.h<br>
> index f59f896..00b6ddb 100644<br>
> --- a/c/src/lib/libcpu/arm/shared/include/am335x.h<br>
> +++ b/c/src/lib/libcpu/arm/shared/include/am335x.h<br>
> @@ -563,3 +563,201 @@<br>
><br>
><br>
><br>
> +/* I2C registers */<br>
> +#define AM335X_I2C0_BASE 0x44e0b000<br>
> +    /* I2C0 base address */<br>
> +#define AM335X_I2C1_BASE 0x4802a000<br>
> +    /* I2C1 base address */<br>
> +#define AM335X_I2C2_BASE 0x4819c000<br>
> +    /* I2C2 base address */<br>
> +#define AM335X_I2C_REVNB_LO        0x00<br>
> +    /* Module Revision Register (low bytes) */<br>
> +#define AM335X_I2C_REVNB_HI        0x04<br>
> +    /* Module Revision Register (high bytes) */<br>
> +#define AM335X_I2C_SYSC            0x10<br>
> +    /* System Configuration Register */<br>
> +#define AM335X_I2C_IRQSTATUS_RAW   0x24<br>
> +    /* I2C Status Raw Register */<br>
> +#define AM335X_I2C_IRQSTATUS       0x28<br>
> +    /* I2C Status Register */<br>
> +#define AM335X_I2C_IRQENABLE_SET   0x2c<br>
> +    /* I2C Interrupt Enable Set Register */<br>
> +#define AM335X_I2C_IRQENABLE_CLR   0x30<br>
> +    /* I2C Interrupt Enable Clear Register */<br>
> +#define AM335X_I2C_WE              0x34<br>
> +    /* I2C Wakeup Enable Register */<br>
> +#define AM335X_I2C_DMARXENABLE_SET 0x38<br>
> +    /* Receive DMA Enable Set Register */<br>
> +#define AM335X_I2C_DMATXENABLE_SET 0x3c<br>
> +    /* Transmit DMA Enable Set Register */<br>
> +#define AM335X_I2C_DMARXENABLE_CLR 0x40<br>
> +    /* Receive DMA Enable Clear Register */<br>
> +#define AM335X_I2C_DMATXENABLE_CLR 0x44<br>
> +    /* Transmit DMA Enable Clear Register */<br>
> +#define AM335X_I2C_DMARXWAKE_EN    0x48<br>
> +    /* Receive DMA Wakeup Register */<br>
> +#define AM335X_I2C_DMATXWAKE_EN    0x4c<br>
> +    /* Transmit DMA Wakeup Register */<br>
> +#define AM335X_I2C_SYSS            0x90<br>
> +    /* System Status Register */<br>
> +#define AM335X_I2C_BUF             0x94<br>
> +    /* Buffer Configuration Register */<br>
> +#define AM335X_I2C_CNT             0x98<br>
> +    /* Data Counter Register */<br>
> +#define AM335X_I2C_DATA            0x9c<br>
> +    /* Data Access Register */<br>
> +#define AM335X_I2C_CON             0xa4<br>
> +    /* I2C Configuration Register */<br>
> +#define AM335X_I2C_OA              0xa8<br>
> +    /* I2C Own Address Register */<br>
> +#define AM335X_I2C_SA              0xac<br>
> +    /* I2C Slave Address Register */<br>
> +#define AM335X_I2C_PSC             0xb0<br>
> +    /* I2C Clock Prescaler Register */<br>
> +#define AM335X_I2C_SCLL            0xb4<br>
> +    /* I2C SCL Low Time Register */<br>
> +#define AM335X_I2C_SCLH            0xb8<br>
> +    /* I2C SCL High Time Register */<br>
> +#define AM335X_I2C_SYSTEST         0xbc<br>
> +    /* System Test Register */<br>
> +#define AM335X_I2C_BUFSTAT         0xc0<br>
> +    /* I2C Buffer Status Register */<br>
> +#define AM335X_I2C_OA1             0xc4<br>
> +    /* I2C Own Address 1 Register */<br>
> +#define AM335X_I2C_OA2             0xc8<br>
> +    /* I2C Own Address 2 Register */<br>
> +#define AM335X_I2C_OA3             0xcc<br>
> +    /* I2C Own Address 3 Register */<br>
> +#define AM335X_I2C_ACTOA           0xd0<br>
> +    /* Active Own Address Register */<br>
> +#define AM335X_I2C_SBLOCK          0xd4<br>
> +    /* I2C Clock Blocking Enable Register */<br>
> +<br>
> +#define AM335X_CM_PER_L4LS_CLKSTCTRL  (0x0)<br>
> +#define AM335X_CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL_SW_WKUP  (0x2u)<br>
> +#define AM335X_CM_PER_L4LS_CLKSTCTRL_CLKTRCTRL  (0x00000003u)<br>
> +#define AM335X_CM_PER_L4LS_CLKCTRL  (0x60)<br>
> +#define AM335X_CM_PER_L4LS_CLKCTRL_MODULEMODE_ENABLE  (0x2u)<br>
> +#define AM335X_CM_PER_L4LS_CLKCTRL_MODULEMODE  (0x00000003u)<br>
> +#define AM335X_CM_PER_I2C1_CLKCTRL  (0x48)<br>
> +#define AM335X_CM_PER_I2C1_CLKCTRL_MODULEMODE_ENABLE  (0x2u)<br>
> +#define AM335X_ CM_PER_I2C1_CLKCTRL_MODULEMODE  (0x00000003u)<br>
> +#define AM335X_CM_PER_I2C2_CLKCTRL (0x44)<br>
> +#define AM335X_CM_PER_I2C2_CLKCTRL_MODULEMODE_ENABLE  (0x2u)<br>
> +#define AM335X_CM_PER_I2C2_CLKCTRL_MODULEMODE  (0x00000003u)<br>
> +#define AM335X_CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_L4LS_GCLK (0x00000100u)<br>
> +#define AM335X_CM_PER_L4LS_CLKSTCTRL_CLKACTIVITY_I2C_FCLK (0x01000000u)<br>
> +#define AM335X_CM_PER_I2C1_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define AM335X_I2C_CON_XSA  (0x00000100u)<br>
> +#define AM335X_I2C_CFG_10BIT_SLAVE_ADDR  AM335X_I2C_CON_XSA<br>
> +#define AM335X_I2C_CON_XSA_SHIFT  (0x00000008u)<br>
> +#define AM335X_I2C_CFG_7BIT_SLAVE_ADDR  (0 << AM335X_I2C_CON_XSA_SHIFT)<br>
> +#define AM335X_I2C_CON_I2C_EN   (0x00008000u)<br>
> +#define AM335X_I2C_CON_TRX   (0x00000200u)<br>
> +#define AM335X_I2C_CON_MST   (0x00000400u)<br>
> +#define AM335X_I2C_CON_STB   (0x00000800u)<br>
> +#define AM335X_I2C_SYSC_AUTOIDLE   (0x00000001u)<br>
> +<br>
> +/*I2C0 module clock registers*/<br>
> +<br>
> +#define CM_PER_L3_CLKCTRL   (0xe0)<br>
> +#define CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE   (0x2u)<br>
> +#define CM_PER_L3_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define CM_PER_L3_INSTR_CLKCTRL   (0xdc)<br>
> +#define CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE   (0x2u)<br>
> +#define CM_PER_L3_INSTR_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define CM_PER_L3_CLKSTCTRL   (0xc)<br>
> +#define CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define CM_PER_L3_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define CM_PER_OCPWP_L3_CLKSTCTRL   (0x12c)<br>
> +#define CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define CM_PER_L3S_CLKSTCTRL   (0x4)<br>
> +#define CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define CM_PER_L3S_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define CM_PER_L3_CLKCTRL_IDLEST_FUNC   (0x0u)<br>
> +#define CM_PER_L3_CLKCTRL_IDLEST_SHIFT   (0x00000010u)<br>
> +#define CM_PER_L3_CLKCTRL_IDLEST   (0x00030000u)<br>
> +#define CM_PER_L3_INSTR_CLKCTRL_IDLEST_FUNC   (0x0u)<br>
> +#define CM_PER_L3_INSTR_CLKCTRL_IDLEST_SHIFT   (0x00000010u)<br>
> +#define CM_PER_L3_INSTR_CLKCTRL_IDLEST   (0x00030000u)<br>
> +#define CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK   (0x00000010u)<br>
> +#define CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK   (0x00000010u)<br>
> +#define CM_PER_OCPWP_L3_CLKSTCTRL   (0x12c)<br>
> +#define CM_PER_L3S_CLKSTCTRL_CLKACTIVITY_L3S_GCLK   (0x00000008u)<br>
> +#define CM_WKUP_CONTROL_CLKCTRL   (0x4)<br>
> +#define CM_WKUP_CONTROL_CLKCTRL_MODULEMODE_ENABLE   (0x2u)<br>
> +#define CM_WKUP_CONTROL_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define CM_WKUP_CLKSTCTRL   (0x0)<br>
> +#define CM_WKUP_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define CM_WKUP_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define CM_WKUP_CM_L3_AON_CLKSTCTRL   (0x18)<br>
> +#define CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define CM_WKUP_I2C0_CLKCTRL   (0xb8)<br>
> +#define CM_WKUP_I2C0_CLKCTRL_MODULEMODE_ENABLE   (0x2u)<br>
> +#define CM_WKUP_I2C0_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define CM_WKUP_CONTROL_CLKCTRL_IDLEST_FUNC   (0x0u)<br>
> +#define CM_WKUP_CONTROL_CLKCTRL_IDLEST_SHIFT   (0x00000010u)<br>
> +#define CM_WKUP_CONTROL_CLKCTRL_IDLEST   (0x00030000u)<br>
> +#define CM_WKUP_CM_L3_AON_CLKSTCTRL_CLKACTIVITY_L3_AON_GCLK   (0x00000008u)<br>
> +#define CM_WKUP_L4WKUP_CLKCTRL_IDLEST_FUNC   (0x0u)<br>
> +#define CM_WKUP_L4WKUP_CLKCTRL_IDLEST_SHIFT   (0x00000010u)<br>
> +#define CM_WKUP_L4WKUP_CLKCTRL   (0xc)<br>
> +#define CM_WKUP_CLKSTCTRL_CLKACTIVITY_L4_WKUP_GCLK   (0x00000004u)<br>
> +#define CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL_CLKACTIVITY_L4_WKUP_AON_GCLK   (0x00000004u)<br>
> +#define CM_WKUP_CM_L4_WKUP_AON_CLKSTCTRL   (0xcc)<br>
> +#define CM_WKUP_CLKSTCTRL_CLKACTIVITY_I2C0_GFCLK   (0x00000800u)<br>
> +#define CM_WKUP_I2C0_CLKCTRL_IDLEST_FUNC   (0x0u)<br>
> +#define CM_WKUP_I2C0_CLKCTRL_IDLEST_SHIFT   (0x00000010u)<br>
> +#define CM_WKUP_I2C0_CLKCTRL_IDLEST   (0x00030000u)<br>
> +#define CM_WKUP_L4WKUP_CLKCTRL_IDLEST   (0x00030000u)<br>
> +#define SOC_CM_WKUP_REGS                     (AM335X_CM_PER_ADDR + 0x400)<br>
> +<br>
> +/* I2C status Register */<br>
> +#define AM335X_I2C_IRQSTATUS_NACK (1 << 1)<br>
> +#define AM335X_I2C_IRQSTATUS_ROVR (1 << 11)<br>
> +#define AM335X_I2C_IRQSTATUS_AL   ( 1<<0 )<br>
> +#define AM335X_I2C_IRQSTATUS_ARDY (1 << 2)<br>
> +#define AM335X_I2C_IRQSTATUS_RRDY (1 << 3)<br>
> +#define AM335X_I2C_IRQSTATUS_XRDY (1 << 4)<br>
> +#define AM335X_I2C_IRQSTATUS_XUDF (1 << 10)<br>
> +#define AM335X_I2C_BUF_TXFIFO_CLR   (0x00000040u)<br>
> +#define AM335X_I2C_BUF_RXFIFO_CLR   (0x00004000u)<br>
> +#define AM335X_I2C_IRQSTATUS_AAS  (1 << 9)<br>
> +#define AM335X_I2C_IRQSTATUS_BF  (1 << 8)<br>
> +#define AM335X_I2C_IRQSTATUS_STC  (1 << 6)<br>
> +#define AM335X_I2C_IRQSTATUS_GC (1 << 5)<br>
> +#define AM335X_I2C_IRQSTATUS_XDR (1 << 14)<br>
> +#define AM335X_I2C_IRQSTATUS_RDR (1 << 13)<br>
> +<br>
> +#define AM335X_I2C_INT_RECV_READY AM335X_I2C_IRQSTATUS_RRDY<br>
> +#define AM335X_I2C_CON_STOP  (0x00000002u)<br>
> +#define AM335X_I2C_CON_START (0x00000001u)<br>
> +#define AM335X_I2C_CFG_MST_RX AM335X_I2C_CON_MST<br>
> +#define AM335X_I2C_CFG_MST_TX  AM335X_I2C_CON_TRX | AM335X_I2C_CON_MST<br>
> +#define AM335X_I2C_IRQSTATUS_RAW_BB   (0x00001000u)<br>
> +#define AM335X_I2C_IRQSTATUS_BF (0x00000100u)<br>
> +#define AM335X_CM_PER_L3S_CLKSTCTRL   (0x4)<br>
> +#define AM335X_CM_PER_L3S_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define AM335X_CM_PER_L3S_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define AM335X_CM_PER_L3_CLKSTCTRL   (0xc)<br>
> +#define AM335X_CM_PER_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define AM335X_CM_PER_L3_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define AM335X_CM_PER_L3_INSTR_CLKCTRL   (0xdc)<br>
> +#define AM335X_CM_PER_L3_INSTR_CLKCTRL_MODULEMODE_ENABLE   (0x2u)<br>
> +#define AM335X_CM_PER_L3_CLKCTRL   (0xe0)<br>
> +#define AM335X_CM_PER_L3_CLKCTRL_MODULEMODE_ENABLE   (0x2u)<br>
> +#define AM335X_CM_PER_L3_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL   (0x12c)<br>
> +#define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL   (0x00000003u)<br>
> +#define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKTRCTRL_SW_WKUP   (0x2u)<br>
> +#define AM335X_CM_PER_L3_CLKSTCTRL_CLKACTIVITY_L3_GCLK   (0x00000010u)<br>
> +#define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L3_GCLK   (0x00000010u)<br>
> +#define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK   (0x00000020u)<br>
> +#define AM335X_CM_PER_L3_INSTR_CLKCTRL_MODULEMODE   (0x00000003u)<br>
> +#define AM335X_I2C_IRQSTATUS_BF   (0x00000100u)<br>
> +#define AM335X_I2C_INT_STOP_CONDITION AM335X_I2C_IRQSTATUS_BF<br>
> +<br>
> +<br>
> --<br>
> 2.7.4<br>
><br>
_______________________________________________<br>
devel mailing list<br>
devel@rtems.org<br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" id="LPlnk297669" previewremoved="true">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</div>
</span></font></div>
</div>
</body>
</html>