tmp105-test.c 4.8 KB
Newer Older
1 2 3 4 5 6 7 8
/*
 * QTest testcase for the TMP105 temperature sensor
 *
 * Copyright (c) 2012 Andreas Färber
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */
9 10 11

#include <glib.h>

12
#include "libqtest.h"
A
Andreas Färber 已提交
13
#include "libqos/i2c.h"
P
Paolo Bonzini 已提交
14
#include "hw/misc/tmp105_regs.h"
15 16 17

#define OMAP2_I2C_1_BASE 0x48070000

18 19
#define TMP105_TEST_ID   "tmp105-test"
#define TMP105_TEST_ADDR 0x49
20 21 22

static I2CAdapter *i2c;

23 24 25 26 27 28 29 30
static uint16_t tmp105_get8(I2CAdapter *i2c, uint8_t addr, uint8_t reg)
{
    uint8_t resp[1];
    i2c_send(i2c, addr, &reg, 1);
    i2c_recv(i2c, addr, resp, 1);
    return resp[0];
}

31
static uint16_t tmp105_get16(I2CAdapter *i2c, uint8_t addr, uint8_t reg)
32 33
{
    uint8_t resp[2];
34
    i2c_send(i2c, addr, &reg, 1);
35
    i2c_recv(i2c, addr, resp, 2);
36 37 38 39 40 41 42 43
    return (resp[0] << 8) | resp[1];
}

static void tmp105_set8(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
                        uint8_t value)
{
    uint8_t cmd[2];
    uint8_t resp[1];
44

45 46
    cmd[0] = reg;
    cmd[1] = value;
47 48 49
    i2c_send(i2c, addr, cmd, 2);
    i2c_recv(i2c, addr, resp, 1);
    g_assert_cmphex(resp[0], ==, cmd[1]);
50
}
51

52 53 54 55 56
static void tmp105_set16(I2CAdapter *i2c, uint8_t addr, uint8_t reg,
                         uint16_t value)
{
    uint8_t cmd[3];
    uint8_t resp[2];
57

58 59 60
    cmd[0] = reg;
    cmd[1] = value >> 8;
    cmd[2] = value & 255;
61 62 63 64 65 66
    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]);
}

67 68 69 70
static int qmp_tmp105_get_temperature(const char *id)
{
    QDict *response;
    int ret;
71

72
    response = qmp("{ 'execute': 'qom-get', 'arguments': { 'path': %s, "
73 74 75 76 77 78 79 80 81 82 83
                   "'property': 'temperature' } }", id);
    g_assert(qdict_haskey(response, "return"));
    ret = qdict_get_int(response, "return");
    QDECREF(response);
    return ret;
}

static void qmp_tmp105_set_temperature(const char *id, int value)
{
    QDict *response;

84
    response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
85 86 87 88 89 90
                   "'property': 'temperature', 'value': %d } }", id, value);
    g_assert(qdict_haskey(response, "return"));
    QDECREF(response);
}

#define TMP105_PRECISION (1000/16)
91 92 93 94
static void send_and_receive(void)
{
    uint16_t value;

95
    value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
96 97
    g_assert_cmpuint(value, ==, 0);

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0);

    qmp_tmp105_set_temperature(TMP105_TEST_ID, 20000);
    value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
    g_assert_cmpuint(value, ==, 20000);

    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0x1400);

    qmp_tmp105_set_temperature(TMP105_TEST_ID, 20938); /* 20 + 15/16 */
    value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
    g_assert_cmpuint(value, >=, 20938 - TMP105_PRECISION/2);
    g_assert_cmpuint(value, <, 20938 + TMP105_PRECISION/2);

    /* Set config */
    tmp105_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x60);
    value = tmp105_get8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG);
    g_assert_cmphex(value, ==, 0x60);

    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0x14f0);

    /* Set precision to 9, 10, 11 bits.  */
    tmp105_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x00);
    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0x1480);

    tmp105_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x20);
    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0x14c0);

    tmp105_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x40);
    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0x14e0);

    /* stored precision remains the same */
    value = qmp_tmp105_get_temperature(TMP105_TEST_ID);
    g_assert_cmpuint(value, >=, 20938 - TMP105_PRECISION/2);
    g_assert_cmpuint(value, <, 20938 + TMP105_PRECISION/2);

    tmp105_set8(i2c, TMP105_TEST_ADDR, TMP105_REG_CONFIG, 0x60);
    value = tmp105_get16(i2c, TMP105_TEST_ADDR, TMP105_REG_TEMPERATURE);
    g_assert_cmphex(value, ==, 0x14f0);
142

143 144
    tmp105_set16(i2c, TMP105_TEST_ADDR, TMP105_REG_T_LOW, 0x1234);
    tmp105_set16(i2c, TMP105_TEST_ADDR, TMP105_REG_T_HIGH, 0x4231);
145 146
}

147 148 149 150 151 152 153
int main(int argc, char **argv)
{
    QTestState *s = NULL;
    int ret;

    g_test_init(&argc, &argv, NULL);

154 155 156
    s = qtest_start("-machine n800 "
                    "-device tmp105,bus=i2c-bus.0,id=" TMP105_TEST_ID
                    ",address=0x49");
157 158 159 160 161 162 163 164 165 166 167 168 169
    i2c = omap_i2c_create(OMAP2_I2C_1_BASE);

    qtest_add_func("/tmp105/tx-rx", send_and_receive);

    ret = g_test_run();

    if (s) {
        qtest_quit(s);
    }
    g_free(i2c);

    return ret;
}