--- 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(®s->BBB_I2C_IRQSTATUS_RAW) & AM335X_I2C_IRQSTATUS_RAW_BB) + while ((stat = readw(®s->BBB_I2C_IRQSTATUS_RAW) & + AM335X_I2C_IRQSTATUS_RAW_BB) && timeout--) { + + writew(stat, ®s->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, ®s->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",®s->BBB_I2C_CON); - mmio_clear((®s->BBB_I2C_CON),AM335X_I2C_CON_I2C_EN); - mmio_clear((®s->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(®s->BBB_I2C_CON) & I2C_CON_EN) { + writew(0, ®s->BBB_I2C_CON); + udelay(50000); + } + + writew(0x2, ®s->BBB_I2C_SYSC); /* for ES2 after soft reset */ + udelay(1000); + + writew(I2C_CON_EN, ®s->BBB_I2C_CON); + while (!(readw(®s->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(®s->BBB_I2C_CNT) = 0x02; - no_bytes = REG(®s->BBB_I2C_CNT); - - // I2C Controller in Master Mode - REG(®s->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(®s->BBB_I2C_CON)); - - // Set Slave address & Master enable, bring out of reset - REG(®s->BBB_I2C_SA) = msgs->addr; - printf("slave address : %x\n",REG(®s->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(®s->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(®s->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(®s->BBB_I2C_CNT) = bus->msg_todo; - - // clear status of all interrupts - //am335x_clean_interrupts(regs); - // I2C Controller in Master Mode REG(®s->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(®s->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(®s->BBB_I2C_CON) |= AM335X_I2C_CON_STOP; } else { // start condition - printk("start to read\n"); REG(®s->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(®s->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(®s->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(®s->BBB_I2C_CON) |= AM335X_I2C_CON_STOP; - printk("stop condition in continue read transfer %x\n",REG(®s->BBB_I2C_CON)); + } } + static void am335x_i2c_continue_write(bbb_i2c_bus *bus, volatile bbb_i2c_regs *regs) { - REG(®s->BBB_I2C_DATA) = 0x00; - am335x_int_clear(regs, AM335X_I2C_IRQSTATUS_XRDY); - printk("clear XRDY continue write\n"); - /* - if (bus->already_transferred == REG(®s->BBB_I2C_CNT)) { - printk("\n finished transfer \n"); - am335x_i2c_masterint_disable(regs, AM335X_I2C_IRQSTATUS_XRDY); - printk("disable XRDY continue write \n"); - REG(®s->BBB_I2C_CON) |= AM335X_I2C_CON_STOP; - } else { - printk("write memory address \n"); - REG(®s->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(®s->BBB_I2C_CON) |= AM335X_I2C_CON_STOP; - } else { - printk("remaining byte \n"); - REG(®s->BBB_I2C_DATA) = bus->current_msg_byte[bus->already_transferred]; - printk("%s",REG(®s->BBB_I2C_DATA)); - bus->already_transferred++; - } - */ + + writeb(0x0,®s->BBB_I2C_DATA); + + writew(AM335X_I2C_IRQSTATUS_XRDY, ®s->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(®s->BBB_I2C_CNT) = bus->msg_todo; + REG(®s->BBB_I2C_CNT) = bus->current_msg_todo; no_bytes = REG(®s->BBB_I2C_CNT); - // clear status of all interrupts - // Already cleaned during reset - am335x_clean_interrupts(regs); - + REG(®s->BBB_I2C_SA) = msgs->addr; + // I2C Controller in Master transmitter Mode REG(®s->BBB_I2C_CON) = AM335X_I2C_CFG_MST_TX | AM335X_I2C_CON_I2C_EN; - printk("enable master in transmiter mode setup write %x\n",REG(®s->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(®s->BBB_I2C_CON) |= AM335X_I2C_CON_START; - printk("set start condition in setup write %x \n",REG(®s->BBB_I2C_CON)); + - while(am335x_i2c_busbusy(regs) == 0); - printk("CNT in setup write : %x \n",REG(®s->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(®s->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(®s->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(®s->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(®s->BBB_I2C_IRQSTATUS) = (irqstatus & ~(AM335X_I2C_IRQSTATUS_RRDY | AM335X_I2C_IRQSTATUS_XRDY)); - printk("\n irqstatus = %x \n",REG(®s->BBB_I2C_IRQSTATUS)); + REG(®s->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, ®s->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(®s->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 ",®s->BBB_I2C_PSC); - printk("PSC offset %x \n", &bus->regs->BBB_I2C_PSC); - //mmio_write((®s->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((®s->BBB_I2C_SCLL), (divider - 7)); + REG(&bus->regs->BBB_I2C_SCLL) = (divider - 7); - //mmio_write((®s->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@rtems.org http://lists.rtems.org/mailman/listinfo/devel