qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

lsm303dlhc-mag-test.c (5428B)


      1 /*
      2  * QTest testcase for the LSM303DLHC I2C magnetometer
      3  *
      4  * Copyright (C) 2021 Linaro Ltd.
      5  * Written by Kevin Townsend <kevin.townsend@linaro.org>
      6  *
      7  * Based on: https://www.st.com/resource/en/datasheet/lsm303dlhc.pdf
      8  *
      9  * SPDX-License-Identifier: GPL-2.0-or-later
     10  */
     11 
     12 #include "qemu/osdep.h"
     13 #include "libqtest-single.h"
     14 #include "libqos/qgraph.h"
     15 #include "libqos/i2c.h"
     16 #include "qapi/qmp/qdict.h"
     17 
     18 #define LSM303DLHC_MAG_TEST_ID        "lsm303dlhc_mag-test"
     19 #define LSM303DLHC_MAG_REG_CRA        0x00
     20 #define LSM303DLHC_MAG_REG_CRB        0x01
     21 #define LSM303DLHC_MAG_REG_OUT_X_H    0x03
     22 #define LSM303DLHC_MAG_REG_OUT_Z_H    0x05
     23 #define LSM303DLHC_MAG_REG_OUT_Y_H    0x07
     24 #define LSM303DLHC_MAG_REG_IRC        0x0C
     25 #define LSM303DLHC_MAG_REG_TEMP_OUT_H 0x31
     26 
     27 static int qmp_lsm303dlhc_mag_get_property(const char *id, const char *prop)
     28 {
     29     QDict *response;
     30     int ret;
     31 
     32     response = qmp("{ 'execute': 'qom-get', 'arguments': { 'path': %s, "
     33                    "'property': %s } }", id, prop);
     34     g_assert(qdict_haskey(response, "return"));
     35     ret = qdict_get_int(response, "return");
     36     qobject_unref(response);
     37     return ret;
     38 }
     39 
     40 static void qmp_lsm303dlhc_mag_set_property(const char *id, const char *prop,
     41                                             int value)
     42 {
     43     QDict *response;
     44 
     45     response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
     46                    "'property': %s, 'value': %d } }", id, prop, value);
     47     g_assert(qdict_haskey(response, "return"));
     48     qobject_unref(response);
     49 }
     50 
     51 static void send_and_receive(void *obj, void *data, QGuestAllocator *alloc)
     52 {
     53     int64_t value;
     54     QI2CDevice *i2cdev = (QI2CDevice *)obj;
     55 
     56     /* Check default value for CRB */
     57     g_assert_cmphex(i2c_get8(i2cdev, LSM303DLHC_MAG_REG_CRB), ==, 0x20);
     58 
     59     /* Set x to 1.0 gauss and verify the value */
     60     qmp_lsm303dlhc_mag_set_property(LSM303DLHC_MAG_TEST_ID, "mag-x", 100000);
     61     value = qmp_lsm303dlhc_mag_get_property(
     62         LSM303DLHC_MAG_TEST_ID, "mag-x");
     63     g_assert_cmpint(value, ==, 100000);
     64 
     65     /* Set y to 1.5 gauss and verify the value */
     66     qmp_lsm303dlhc_mag_set_property(LSM303DLHC_MAG_TEST_ID, "mag-y", 150000);
     67     value = qmp_lsm303dlhc_mag_get_property(
     68         LSM303DLHC_MAG_TEST_ID, "mag-y");
     69     g_assert_cmpint(value, ==, 150000);
     70 
     71     /* Set z to 0.5 gauss and verify the value */
     72     qmp_lsm303dlhc_mag_set_property(LSM303DLHC_MAG_TEST_ID, "mag-z", 50000);
     73     value = qmp_lsm303dlhc_mag_get_property(
     74         LSM303DLHC_MAG_TEST_ID, "mag-z");
     75     g_assert_cmpint(value, ==, 50000);
     76 
     77     /* Set temperature to 23.6 C and verify the value */
     78     qmp_lsm303dlhc_mag_set_property(LSM303DLHC_MAG_TEST_ID,
     79         "temperature", 23600);
     80     value = qmp_lsm303dlhc_mag_get_property(
     81         LSM303DLHC_MAG_TEST_ID, "temperature");
     82     /* Should return 23.5 C due to 0.125°C steps. */
     83     g_assert_cmpint(value, ==, 23500);
     84 
     85     /* Read raw x axis registers (1 gauss = 1100 at +/-1.3 g gain) */
     86     value = i2c_get16(i2cdev, LSM303DLHC_MAG_REG_OUT_X_H);
     87     g_assert_cmphex(value, ==, 1100);
     88 
     89     /* Read raw y axis registers (1.5 gauss = 1650 at +/- 1.3 g gain = ) */
     90     value = i2c_get16(i2cdev, LSM303DLHC_MAG_REG_OUT_Y_H);
     91     g_assert_cmphex(value, ==, 1650);
     92 
     93     /* Read raw z axis registers (0.5 gauss = 490 at +/- 1.3 g gain = ) */
     94     value = i2c_get16(i2cdev, LSM303DLHC_MAG_REG_OUT_Z_H);
     95     g_assert_cmphex(value, ==, 490);
     96 
     97     /* Read raw temperature registers with temp disabled (CRA = 0x10) */
     98     value = i2c_get16(i2cdev, LSM303DLHC_MAG_REG_TEMP_OUT_H);
     99     g_assert_cmphex(value, ==, 0);
    100 
    101     /* Enable temperature reads (CRA = 0x90) */
    102     i2c_set8(i2cdev, LSM303DLHC_MAG_REG_CRA, 0x90);
    103 
    104     /* Read raw temp registers (23.5 C = 188 at 1 lsb = 0.125 C) */
    105     value = i2c_get16(i2cdev, LSM303DLHC_MAG_REG_TEMP_OUT_H);
    106     g_assert_cmphex(value, ==, 188);
    107 }
    108 
    109 static void reg_wraparound(void *obj, void *data, QGuestAllocator *alloc)
    110 {
    111     uint8_t value[4];
    112     QI2CDevice *i2cdev = (QI2CDevice *)obj;
    113 
    114     /* Set x to 1.0 gauss, and y to 1.5 gauss for known test values */
    115     qmp_lsm303dlhc_mag_set_property(LSM303DLHC_MAG_TEST_ID, "mag-x", 100000);
    116     qmp_lsm303dlhc_mag_set_property(LSM303DLHC_MAG_TEST_ID, "mag-y", 150000);
    117 
    118     /* Check that requesting 4 bytes starting at Y_H wraps around to X_L */
    119     i2c_read_block(i2cdev, LSM303DLHC_MAG_REG_OUT_Y_H, value, 4);
    120     /* 1.5 gauss = 1650 lsb = 0x672 */
    121     g_assert_cmphex(value[0], ==, 0x06);
    122     g_assert_cmphex(value[1], ==, 0x72);
    123     /* 1.0 gauss = 1100 lsb = 0x44C */
    124     g_assert_cmphex(value[2], ==, 0x04);
    125     g_assert_cmphex(value[3], ==, 0x4C);
    126 
    127     /* Check that requesting LSM303DLHC_MAG_REG_IRC wraps around to CRA */
    128     i2c_read_block(i2cdev, LSM303DLHC_MAG_REG_IRC, value, 2);
    129     /* Default value for IRC = 0x33 */
    130     g_assert_cmphex(value[0], ==, 0x33);
    131     /* Default value for CRA = 0x10 */
    132     g_assert_cmphex(value[1], ==, 0x10);
    133 }
    134 
    135 static void lsm303dlhc_mag_register_nodes(void)
    136 {
    137     QOSGraphEdgeOptions opts = {
    138         .extra_device_opts = "id=" LSM303DLHC_MAG_TEST_ID ",address=0x1e"
    139     };
    140     add_qi2c_address(&opts, &(QI2CAddress) { 0x1E });
    141 
    142     qos_node_create_driver("lsm303dlhc_mag", i2c_device_create);
    143     qos_node_consumes("lsm303dlhc_mag", "i2c-bus", &opts);
    144 
    145     qos_add_test("tx-rx", "lsm303dlhc_mag", send_and_receive, NULL);
    146     qos_add_test("regwrap", "lsm303dlhc_mag", reg_wraparound, NULL);
    147 }
    148 libqos_init(lsm303dlhc_mag_register_nodes);