[PATCH 2/2] Beagle i2c: Update Beaglebone i2c driver code

Christian Mauderer christian.mauderer at embedded-brains.de
Sun May 14 12:42:53 UTC 2017


Hello Sichen Zhao,

I haven't tested the code yet. But on a first look, I noted some points regarding the style:

- If I apply the patches, there are a lot of "trailing whitespace" warnings
- There are some // comments in the code
- Quite a number of lines is longer than 80 characters
- There are some functions with really unnecessary blank lines like am335x_i2c_set_clock

There is no unique coding style throughout RTEMS but there are some guidelines here:

    https://devel.rtems.org/wiki/Developer/Coding/Conventions

It's good style for new code to follow these conventions. Knowing that you will work with the libbsd too, please note that these conventions are only for RTEMS core system. In the libbsd, most of the code follows the BSD-Style.

Kind regards

Christian

----- Ursprüngliche Mail -----
> Von: "Sichen Zhao" <1473996754 at qq.com>
> An: devel at rtems.org, "punit vara" <punitvara at gmail.com>, "Christian Mauderer" <christian.mauderer at embedded-brains.de>
> Gesendet: Samstag, 13. Mai 2017 05:52:13
> Betreff: [PATCH 2/2] Beagle i2c: Update Beaglebone i2c driver code

> This patch modify the i2c code for Beaglebone Black based on PV works:
> - bbb-i2c.c: Modify the interrupt handler, transfer funciton, read function,
> am335x_i2c_busbusy function etc. Add flush_fifo function
> - include/i2c.h: Modify some macros, such as BBB_I2C_IRQ_ERROR
> 
> Now the i2c is working on Beaglebone Black, it can read the EEPROM information.
> ---
> c/src/lib/libbsp/arm/beagle/i2c/bbb-i2c.c | 378 +++++++++++-------------------
> c/src/lib/libbsp/arm/beagle/include/i2c.h |  11 +-
> 2 files changed, 150 insertions(+), 239 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 6b790e5..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,88 +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)
> {
> @@ -303,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;
> +
> +
> +   while ((stat = readw(&regs->BBB_I2C_IRQSTATUS_RAW) &
> +    AM335X_I2C_IRQSTATUS_RAW_BB) && timeout--) {
> +
> +    writew(stat, &regs->BBB_I2C_IRQSTATUS);
> +    udelay(100);
> +  }
> 
> -  if (REG(&regs->BBB_I2C_IRQSTATUS_RAW) & AM335X_I2C_IRQSTATUS_RAW_BB)
> +  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);
> +  }
> +
> +
> }
> 
> /*
> @@ -368,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;
> 
> @@ -410,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));
> +  int status;
> 
> -  // 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)));
> +    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");
> +
> +
> }
> 
> 
> @@ -473,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");
> +
> }
> 
> 
> @@ -562,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;
>   }
> @@ -574,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);
>   }
>   
> }
> @@ -597,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;
> @@ -641,6 +525,7 @@ static void am335x_i2c_interrupt(void *arg)
>     _Assert(sc == RTEMS_SUCCESSFUL);
>     (void) sc;
>     } else {
> +
>       am335x_i2c_setup_transfer(bus, regs);
>     }
>   }
> @@ -652,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);
>   
> 
> @@ -668,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;
> @@ -688,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;
> }
> 
> @@ -699,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;
> }
> 
> @@ -721,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);
> }
> 
> @@ -759,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) {
> @@ -771,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(
> @@ -791,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

-- 
--------------------------------------------
embedded brains GmbH
Christian Mauderer
Dornierstr. 4
D-82178 Puchheim
Germany
email: christian.mauderer at embedded-brains.de
Phone: +49-89-18 94 741 - 18
Fax:   +49-89-18 94 741 - 08
PGP: Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.


More information about the devel mailing list