diff options
author | Martin Braun <martin.braun@ettus.com> | 2014-10-07 09:39:25 +0200 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2014-10-07 09:39:25 +0200 |
commit | 5bd58bc309e959537e3e820abfa39ee629b140a5 (patch) | |
tree | 81e3a611134e02d9118f0aa846b7146234849fe8 /firmware/x300/lib/wb_i2c.c | |
parent | 9f6a11173aef5e661100268bd746963d713adb91 (diff) | |
download | uhd-5bd58bc309e959537e3e820abfa39ee629b140a5.tar.gz uhd-5bd58bc309e959537e3e820abfa39ee629b140a5.tar.bz2 uhd-5bd58bc309e959537e3e820abfa39ee629b140a5.zip |
Reorganized firmware/ subdirectory (x300->usrp3, zpu->usrp2)
Diffstat (limited to 'firmware/x300/lib/wb_i2c.c')
-rw-r--r-- | firmware/x300/lib/wb_i2c.c | 137 |
1 files changed, 0 insertions, 137 deletions
diff --git a/firmware/x300/lib/wb_i2c.c b/firmware/x300/lib/wb_i2c.c deleted file mode 100644 index 611908e18..000000000 --- a/firmware/x300/lib/wb_i2c.c +++ /dev/null @@ -1,137 +0,0 @@ - -// Copyright 2012 Ettus Research LLC -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -// NOTE: this driver left shifts a "7bit" I2C address by one bit and puts a R/W bit as bit 0. -// Some devices may specify there I2C address assuming this R/W bit is already in place. - -#include <wb_i2c.h> - -typedef struct { - volatile uint32_t prescaler_lo; // r/w - volatile uint32_t prescaler_hi; // r/w - volatile uint32_t ctrl; // r/w - volatile uint32_t data; // wr = transmit reg; rd = receive reg - volatile uint32_t cmd_status; // wr = command reg; rd = status reg -} i2c_regs_t; - -#define i2c_regs ((i2c_regs_t *) base) - -#define I2C_CTRL_EN (1 << 7) // core enable -#define I2C_CTRL_IE (1 << 6) // interrupt enable - -// -// STA, STO, RD, WR, and IACK bits are cleared automatically -// -#define I2C_CMD_START (1 << 7) // generate (repeated) start condition -#define I2C_CMD_STOP (1 << 6) // generate stop condition -#define I2C_CMD_RD (1 << 5) // read from slave -#define I2C_CMD_WR (1 << 4) // write to slave -#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) -#define I2C_CMD_RSVD_2 (1 << 2) // reserved -#define I2C_CMD_RSVD_1 (1 << 1) // reserved -#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt - -#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) -#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected -#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration -#define I2C_ST_RSVD_4 (1 << 4) // reserved -#define I2C_ST_RSVD_3 (1 << 3) // reserved -#define I2C_ST_RSVD_2 (1 << 2) // reserved -#define I2C_ST_TIP (1 << 1) // Transfer-in-progress -#define I2C_ST_IP (1 << 0) // Interrupt pending - -void wb_i2c_init(const uint32_t base, const size_t clk_rate) -{ - // prescaler divisor values for 100 kHz I2C [uses 5 * SCLK internally] - const uint16_t prescaler = (clk_rate/(5 * 400000)) - 1; - i2c_regs->prescaler_lo = prescaler & 0xff; - i2c_regs->prescaler_hi = (prescaler >> 8) & 0xff; - - i2c_regs->ctrl = I2C_CTRL_EN; //| I2C_CTRL_IE; // enable core -} - -static inline void -wait_for_xfer(const uint32_t base) -{ - while (i2c_regs->cmd_status & I2C_ST_TIP) // wait for xfer to complete - ; -} - -static inline bool -wait_chk_ack(const uint32_t base) -{ - wait_for_xfer(base); - - if ((i2c_regs->cmd_status & I2C_ST_RXACK) != 0){ // target NAK'd - return false; - } - return true; -} - -bool wb_i2c_read(const uint32_t base, const uint8_t i2c_addr, uint8_t *buf, size_t len) -{ - if (len == 0) // reading zero bytes always works - return true; - - while (i2c_regs->cmd_status & I2C_ST_BUSY) - ; - - i2c_regs->data = (i2c_addr << 1) | 1; // 7 bit address and read bit (1) - // generate START and write addr - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START; - if (!wait_chk_ack(base)) - goto fail; - - for (; len > 0; buf++, len--){ - i2c_regs->cmd_status = I2C_CMD_RD | (len == 1 ? (I2C_CMD_NACK | I2C_CMD_STOP) : 0); - wait_for_xfer(base); - *buf = i2c_regs->data; - } - return true; - - fail: - i2c_regs->cmd_status = I2C_CMD_STOP; // generate STOP - return false; -} - -bool wb_i2c_write(const uint32_t base, const uint8_t i2c_addr, const uint8_t *buf, size_t len) -{ - while (i2c_regs->cmd_status & I2C_ST_BUSY) - ; - - i2c_regs->data = (i2c_addr << 1) | 0; // 7 bit address and write bit (0) - - // generate START and write addr (and maybe STOP) - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START | (len == 0 ? I2C_CMD_STOP : 0); - if (!wait_chk_ack(base)) - goto fail; - - for (; len > 0; buf++, len--){ - i2c_regs->data = *buf; - i2c_regs->cmd_status = I2C_CMD_WR | (len == 1 ? I2C_CMD_STOP : 0); - if (!wait_chk_ack(base)) - goto fail; - } - return true; - - fail: - i2c_regs->cmd_status = I2C_CMD_STOP; // generate STOP - return false; -} - |