Beispiel #1
0
static void send_and_receive(void)
{
    uint8_t cmd[3];
    uint8_t resp[2];

    cmd[0] = TMP105_REG_TEMPERATURE;
    i2c_send(i2c, addr, cmd, 1);
    i2c_recv(i2c, addr, resp, 2);
    g_assert_cmpuint(((uint16_t)resp[0] << 8) | resp[1], ==, 0);

    cmd[0] = TMP105_REG_CONFIG;
    cmd[1] = 0x0; /* matches the reset value */
    i2c_send(i2c, addr, cmd, 2);
    i2c_recv(i2c, addr, resp, 1);
    g_assert_cmphex(resp[0], ==, cmd[1]);

    cmd[0] = TMP105_REG_T_LOW;
    cmd[1] = 0x12;
    cmd[2] = 0x34;
    i2c_send(i2c, addr, cmd, 3);
    i2c_recv(i2c, addr, resp, 2);
    g_assert_cmphex(resp[0], ==, cmd[1]);
    g_assert_cmphex(resp[1], ==, cmd[2]);

    cmd[0] = TMP105_REG_T_HIGH;
    cmd[1] = 0x42;
    cmd[2] = 0x31;
    i2c_send(i2c, addr, cmd, 3);
    i2c_recv(i2c, addr, resp, 2);
    g_assert_cmphex(resp[0], ==, cmd[1]);
    g_assert_cmphex(resp[1], ==, cmd[2]);
}
Beispiel #2
0
uint16_t smbus_read_word(i2c_bus *bus, int addr, uint8_t command)
{
    uint16_t data;
    i2c_start_transfer(bus, addr, 0);
    i2c_send(bus, command);
    i2c_start_transfer(bus, addr, 1);
    data = i2c_recv(bus);
    data |= i2c_recv(bus) << 8;
    i2c_nack(bus);
    i2c_end_transfer(bus);
    return data;
}
Beispiel #3
0
int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data)
{
    int len;
    int i;

    i2c_start_transfer(bus, addr, 0);
    i2c_send(bus, command);
    i2c_start_transfer(bus, addr, 1);
    len = i2c_recv(bus);
    if (len > 32)
        len = 0;
    for (i = 0; i < len; i++)
        data[i] = i2c_recv(bus);
    i2c_nack(bus);
    i2c_end_transfer(bus);
    return len;
}
Beispiel #4
0
uint8_t smbus_receive_byte(i2c_bus *bus, int addr)
{
    uint8_t data;

    i2c_start_transfer(bus, addr, 1);
    data = i2c_recv(bus);
    i2c_nack(bus);
    i2c_end_transfer(bus);
    return data;
}
Beispiel #5
0
uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command)
{
    uint8_t data;
    i2c_start_transfer(bus, addr, 0);
    i2c_send(bus, command);
    i2c_start_transfer(bus, addr, 1);
    data = i2c_recv(bus);
    i2c_nack(bus);
    i2c_end_transfer(bus);
    return data;
}
Beispiel #6
0
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
{
    uint8_t ret;

    aspeed_i2c_set_state(bus, I2CD_MRXD);
    ret = i2c_recv(bus->bus);
    bus->intr_status |= I2CD_INTR_RX_DONE;
    bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
    if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
        i2c_nack(bus->bus);
    }
    bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
    aspeed_i2c_set_state(bus, I2CD_MACTIVE);
}
Beispiel #7
0
char I2CSendReceive(char addr, char tx_count, char rx_count)
{
  if (I2CSendStop(addr, tx_count, 0))
    {
     /* If send fails, abort but don't send a stop condition if we lost
	 arbitration */

      if (i2cError != I2CERR_LOST) I2CStop();
      return 1;
    }

  SDA_HIGH; /* One of these may be low now, in which case the next */
  SCL_HIGH; /* start condition wouldn't be detected so make */
  I2CDelay(I2CDELAY); /*   sure that they're up and wait for one delay slot */

  if (i2c_recv((char)(addr|0x01), rx_count)) return 1;
  return (i2cError ? 1 : 0);
}
Beispiel #8
0
static int pca954x_recv(I2CSlave *i2c)
{
    PCA954XState *s = PCA954X(i2c);
    int i;
    int ret = 0;

    if (s->control_decoded) {
        ret |= s->control_reg;
        DB_PRINT("returning control register: %x\n", ret);
    } else {
        for (i = 0; i < s->lanes; ++i) {
            if (s->active_lanes & (1 << i)) {
                ret |= i2c_recv(s->busses[i]);
                DB_PRINT("recieving from active bus %d:%x\n", i, ret);
            }
        }
    }

    return ret;
}
Beispiel #9
0
int i2c_init_clk()
{
	// We only need the I2C device for the clock setup, so just move it all here instead
	XIicPs i2c_dev;
	int rv = 0;

	XIicPs_Config* cfg = XIicPs_LookupConfig(I2C_DEV);
	if(cfg == NULL)
	{
		printf("Could not lookup config for device %d\r\n", I2C_DEV);
		return -1;
	}

	rv = XIicPs_CfgInitialize(&i2c_dev, cfg, cfg->BaseAddress);
	if(rv != XST_SUCCESS)
	{
		printf("Could not init I2C device\r\n");
		return -1;
	}

	rv = XIicPs_SelfTest(&i2c_dev);
	if(rv != XST_SUCCESS)
	{
		printf("I2C Self-test failed\r\n");
		return -1;
	}

	XIicPs_SetSClk(&i2c_dev, I2C_CLK);

	// Ok, try and read from the bus switch
	uint8_t val = 0;
	rv = i2c_recv(&i2c_dev, I2C_BUS_SWITCH, &val, 1);
	if(rv != XST_SUCCESS)
	{
		printf("i2c_recv failed with code %d\r\n", rv);
		return -1;
	}

	val = I2C_BUS_SWITCH_DIR_SI5324;
	rv = i2c_write_await(&i2c_dev, I2C_BUS_SWITCH, &val, 1);
	if(rv != XST_SUCCESS)
	{
		printf("i2c_send failed with code %d\r\n", rv);
		return -1;
	}

	rv = i2c_recv(&i2c_dev, I2C_BUS_SWITCH, &val, 1);
	if(rv != XST_SUCCESS)
	{
		printf("i2c_read failed with code %d\r\n", rv);
		return -1;
	}

	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x0,   0x54);   // FREE_RUN
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x1,   0xE4);   // CK_PRIOR2,CK_PRIOR1
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2,   0x12);   // BWSEL was 32
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x3,   0x15);   // CKSEL_REG
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x4,   0x92);   // AUTOSEL_REG
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0xa,   0x08);   // DSBL2_REG
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0xb,   0x40);   // PD_CK2
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x19,  0xA0);   // N1_HS
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x1f,  0x00);   // NC1_LS[19:16]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x20,  0x00);   // NC1_LS[15:8]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x21,  0x03);   // NC1_LS[7:0]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x28,  0xC2);   // N2_HS, N2_LS[19:16]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x29,  0x49);   // N2_LS[15:8]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2a,  0xEF);   // N2_LS[7:0]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2b,  0x00);   // N31[18:16]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2c,  0x77);   // N31[15:8]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2d,  0x0B);   // N31[7:0]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2e,  0x00);   // N32[18:16]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2f,  0x77);   // N32[15:8]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x30,  0x0B);   // N32[7:0]
	i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x88,  0x40);   // RST_REG,ICAL

	return XST_SUCCESS;
}
static void i2c_state_update(i2c_interface *i2c, int data, int clock)
{
    if (!i2c)
        return;

    switch (i2c->state) {
    case STOPPED:
        if (data == 0 && i2c->last_data == 1 && clock == 1)
            i2c->state = INITIALIZING;
        break;

    case INITIALIZING:
        if (clock == 0 && i2c->last_clock == 1 && data == 0)
            i2c->state = SENDING_BIT7;
        else
            i2c_enter_stop(i2c);
        break;

    case SENDING_BIT7 ... SENDING_BIT0:
        if (clock == 0 && i2c->last_clock == 1) {
            i2c->buffer = (i2c->buffer << 1) | data;
            i2c->state++; /* will end up in WAITING_FOR_ACK */
        } else if (data == 1 && i2c->last_data == 0 && clock == 1)
            i2c_enter_stop(i2c);
        break;

    case WAITING_FOR_ACK:
        if (clock == 0 && i2c->last_clock == 1) {
            if (i2c->current_addr < 0) {
                i2c->current_addr = i2c->buffer;
                i2c_start_transfer(i2c->bus, i2c->current_addr & 0xfe,
                                   i2c->buffer & 1);
            } else
                i2c_send(i2c->bus, i2c->buffer);
            if (i2c->current_addr & 1) {
                i2c->state = RECEIVING_BIT7;
                i2c->buffer = i2c_recv(i2c->bus);
            } else
                i2c->state = SENDING_BIT7;
        } else if (data == 1 && i2c->last_data == 0 && clock == 1)
            i2c_enter_stop(i2c);
        break;

    case RECEIVING_BIT7 ... RECEIVING_BIT0:
        if (clock == 0 && i2c->last_clock == 1) {
            i2c->state++; /* will end up in SENDING_ACK */
            i2c->buffer <<= 1;
        } else if (data == 1 && i2c->last_data == 0 && clock == 1)
            i2c_enter_stop(i2c);
        break;

    case SENDING_ACK:
        if (clock == 0 && i2c->last_clock == 1) {
            i2c->state = RECEIVING_BIT7;
            if (data == 0)
                i2c->buffer = i2c_recv(i2c->bus);
            else
                i2c_nack(i2c->bus);
        } else if (data == 1 && i2c->last_data == 0 && clock == 1)
            i2c_enter_stop(i2c);
        break;
    }

    i2c->last_data = data;
    i2c->last_clock = clock;
}
Beispiel #11
0
static uint64_t imx_i2c_read(void *opaque, hwaddr offset,
                             unsigned size)
{
    uint16_t value;
    IMXI2CState *s = IMX_I2C(opaque);

    switch (offset) {
    case IADR_ADDR:
        value = s->iadr;
        break;
    case IFDR_ADDR:
        value = s->ifdr;
        break;
    case I2CR_ADDR:
        value = s->i2cr;
        break;
    case I2SR_ADDR:
        value = s->i2sr;
        break;
    case I2DR_ADDR:
        value = s->i2dr_read;

        if (imx_i2c_is_master(s)) {
            int ret = 0xff;

            if (s->address == ADDR_RESET) {
                /* something is wrong as the address is not set */
                qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
                              "without specifying the slave address\n",
                              TYPE_IMX_I2C, __func__);
            } else if (s->i2cr & I2CR_MTX) {
                qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
                              "but MTX is set\n", TYPE_IMX_I2C, __func__);
            } else {
                /* get the next byte */
                ret = i2c_recv(s->bus);

                if (ret >= 0) {
                    imx_i2c_raise_interrupt(s);
                } else {
                    qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed "
                                  "for device 0x%02x\n", TYPE_IMX_I2C,
                                  __func__, s->address);
                    ret = 0xff;
                }
            }

            s->i2dr_read = ret;
        } else {
            qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
                          TYPE_IMX_I2C, __func__);
        }
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset);
        value = 0;
        break;
    }

    DPRINTF("read %s [0x%" HWADDR_PRIx "] -> 0x%02x\n",
            imx_i2c_get_regname(offset), offset, value);

    return (uint64_t)value;
}