From patchwork Wed Dec 12 06:29:33 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 205442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D49742C00A5 for ; Wed, 12 Dec 2012 17:30:28 +1100 (EST) Received: from localhost ([::1]:35308 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tifpp-0004OB-CY for incoming@patchwork.ozlabs.org; Wed, 12 Dec 2012 01:30:25 -0500 Received: from eggs.gnu.org ([208.118.235.92]:48009) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TifpQ-00042Z-No for qemu-devel@nongnu.org; Wed, 12 Dec 2012 01:30:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TifpG-0008CX-Ul for qemu-devel@nongnu.org; Wed, 12 Dec 2012 01:30:00 -0500 Received: from mout.web.de ([212.227.15.3]:60278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TifpG-0008CL-Lk for qemu-devel@nongnu.org; Wed, 12 Dec 2012 01:29:50 -0500 Received: from localhost.localdomain ([84.148.43.42]) by smtp.web.de (mrweb001) with ESMTPSA (Nemesis) id 0MEmKo-1TuDTz0aNO-00G7ku; Wed, 12 Dec 2012 07:29:49 +0100 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= To: qemu-devel@nongnu.org Date: Wed, 12 Dec 2012 07:29:33 +0100 Message-Id: <1355293773-18361-3-git-send-email-andreas.faerber@web.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1355293773-18361-1-git-send-email-andreas.faerber@web.de> References: <1355293773-18361-1-git-send-email-andreas.faerber@web.de> MIME-Version: 1.0 X-Provags-ID: V02:K0:8tqOgAkGn2KiNJAJrVtSCi4rZH46B8Xq+lXlV1mDn5o Uq1vhjEb94B7wvaGZT26/y+QEbgiH2JAopCZ/UivLtD60xF/24 7QokuxtR34wSN52KmUl55t26JfBTkprL2p7w5sweV6IewY60mB 8MnKAls9Wt5QrTO16qc4g8Hksb1FZNJSkA/aZiffV/4asyjG0Z AyB1EIHhhhoJzmPLS18LA== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 212.227.15.3 Cc: Peter Maydell , Blue Swirl , Alex Horn , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Anthony Liguori Subject: [Qemu-devel] [PATCH 2/2] tests: Add tmp105 unit test X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Exercise all four commands of the TMP105, testing for an issue in the I2C TX path. The test case is specific to the n800's OMAP I2C for now and is the first test case for arm. Signed-off-by: Andreas Färber --- tests/Makefile | 2 + tests/tmp105-test.c | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 Dateien geändert, 207 Zeilen hinzugefügt(+) create mode 100644 tests/tmp105-test.c diff --git a/tests/Makefile b/tests/Makefile index b60f0fb..69eff45 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -28,6 +28,7 @@ check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) check-qtest-sparc-y = tests/m48t59-test$(EXESUF) check-qtest-sparc64-y = tests/m48t59-test$(EXESUF) +check-qtest-arm-y = tests/tmp105-test$(EXESUF) GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h @@ -78,6 +79,7 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y) +tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(trace-obj-y) # QTest rules diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c new file mode 100644 index 0000000..26d51f7 --- /dev/null +++ b/tests/tmp105-test.c @@ -0,0 +1,205 @@ +/* + * 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. + */ +#include "libqtest.h" + +#include +#include + +enum OMAPI2CRegisters { + OMAP_I2C_REV = 0x00, + OMAP_I2C_STAT = 0x08, + OMAP_I2C_CNT = 0x18, + OMAP_I2C_DATA = 0x1c, + OMAP_I2C_CON = 0x24, + OMAP_I2C_SA = 0x2c, +}; + +enum OMAPI2CSTATBits { + OMAP_I2C_STAT_NACK = 1 << 1, + OMAP_I2C_STAT_ARDY = 1 << 2, + OMAP_I2C_STAT_RRDY = 1 << 3, + OMAP_I2C_STAT_XRDY = 1 << 4, + OMAP_I2C_STAT_ROVR = 1 << 11, + OMAP_I2C_STAT_SBD = 1 << 15, +}; + +enum OMAPI2CCONBits { + OMAP_I2C_CON_STT = 1 << 0, + OMAP_I2C_CON_STP = 1 << 1, + OMAP_I2C_CON_TRX = 1 << 9, + OMAP_I2C_CON_MST = 1 << 10, + OMAP_I2C_CON_BE = 1 << 14, + OMAP_I2C_CON_I2C_EN = 1 << 15, +}; + +#define OMAP2_I2C_1_BASE 0x48070000 + +#define N8X0_ADDR 0x48 + +static const uint32_t i2c_base = OMAP2_I2C_1_BASE; + +static void omap_i2c_init(void) +{ + uint16_t data; + + /* verify the mmio address by looking for a known signature */ + memread(i2c_base + OMAP_I2C_REV, &data, 2); + g_assert_cmphex(data, ==, 0x34); +} + +static void omap_i2c_set_slave_addr(uint8_t addr) +{ + uint16_t data = addr; + + memwrite(i2c_base + OMAP_I2C_SA, &data, 2); + memread(i2c_base + OMAP_I2C_SA, &data, 2); + g_assert_cmphex(data, ==, addr); +} + +static void omap_i2c_send(uint8_t addr, const void *buf, uint16_t len) +{ + uint16_t data; + + omap_i2c_set_slave_addr(addr); + + data = len; + memwrite(i2c_base + OMAP_I2C_CNT, &data, 2); + + data = OMAP_I2C_CON_I2C_EN | + OMAP_I2C_CON_TRX | + OMAP_I2C_CON_MST | + OMAP_I2C_CON_STT | + OMAP_I2C_CON_STP; + memwrite(i2c_base + OMAP_I2C_CON, &data, 2); + memread(i2c_base + OMAP_I2C_CON, &data, 2); + g_assert((data & OMAP_I2C_CON_STP) != 0); + + memread(i2c_base + OMAP_I2C_STAT, &data, 2); + g_assert((data & OMAP_I2C_STAT_NACK) == 0); + + while (len > 1) { + memread(i2c_base + OMAP_I2C_STAT, &data, 2); + g_assert((data & OMAP_I2C_STAT_XRDY) != 0); + + memwrite(i2c_base + OMAP_I2C_DATA, buf, 2); + buf = (uint8_t *)buf + 2; + len -= 2; + } + if (len == 1) { + memread(i2c_base + OMAP_I2C_STAT, &data, 2); + g_assert((data & OMAP_I2C_STAT_XRDY) != 0); + + memwrite(i2c_base + OMAP_I2C_DATA, buf, 1); + } + + memread(i2c_base + OMAP_I2C_CON, &data, 2); + g_assert((data & OMAP_I2C_CON_STP) == 0); +} + +static void omap_i2c_recv(uint8_t addr, void *buf, uint16_t len) +{ + uint16_t data, stat; + + omap_i2c_set_slave_addr(addr); + + data = len; + memwrite(i2c_base + OMAP_I2C_CNT, &data, 2); + + data = OMAP_I2C_CON_I2C_EN | + OMAP_I2C_CON_MST | + OMAP_I2C_CON_STT | + OMAP_I2C_CON_STP; + memwrite(i2c_base + OMAP_I2C_CON, &data, 2); + memread(i2c_base + OMAP_I2C_CON, &data, 2); + g_assert((data & OMAP_I2C_CON_STP) == 0); + + memread(i2c_base + OMAP_I2C_STAT, &data, 2); + g_assert((data & OMAP_I2C_STAT_NACK) == 0); + + memread(i2c_base + OMAP_I2C_CNT, &data, 2); + g_assert_cmpuint(data, ==, len); + + while (len > 0) { + memread(i2c_base + OMAP_I2C_STAT, &data, 2); + g_assert((data & OMAP_I2C_STAT_RRDY) != 0); + g_assert((data & OMAP_I2C_STAT_ROVR) == 0); + + memread(i2c_base + OMAP_I2C_DATA, &data, 2); + + memread(i2c_base + OMAP_I2C_STAT, &stat, 2); + if ((stat & OMAP_I2C_STAT_SBD) != 0) { + *(uint8_t *)buf = data & 0xf; + buf = (uint8_t *)buf + 1; + len--; + } else { + memcpy(buf, &data, 2); + buf = (uint8_t *)buf + 2; + len -= 2; + } + } + + memread(i2c_base + OMAP_I2C_CON, &data, 2); + g_assert((data & OMAP_I2C_CON_STP) == 0); +} + +static void send_and_receive(void) +{ + const uint8_t addr = N8X0_ADDR; + uint8_t cmd[3]; + uint8_t resp[2]; + + omap_i2c_init(); + + cmd[0] = 0; + omap_i2c_send(addr, cmd, 1); + omap_i2c_recv(addr, resp, 2); + g_assert_cmpuint(((uint16_t)resp[0] << 8) | resp[1], ==, 0); + + cmd[0] = 1; + cmd[1] = 0x0; + omap_i2c_send(addr, cmd, 2); + omap_i2c_recv(addr, resp, 1); + g_assert_cmphex(resp[0], ==, cmd[1]); + + cmd[0] = 2; + cmd[1] = 0x12; + cmd[2] = 0x34; + omap_i2c_send(addr, cmd, 3); + omap_i2c_recv(addr, resp, 2); + g_assert_cmphex(resp[0], ==, cmd[1]); + g_assert_cmphex(resp[1], ==, cmd[2]); + + cmd[0] = 3; + cmd[1] = 0x42; + cmd[2] = 0x31; + omap_i2c_send(addr, cmd, 3); + omap_i2c_recv(addr, resp, 2); + g_assert_cmphex(resp[0], ==, cmd[1]); + g_assert_cmphex(resp[1], ==, cmd[2]); +} + +int main(int argc, char **argv) +{ + QTestState *s = NULL; + int ret; + + g_test_init(&argc, &argv, NULL); + + s = qtest_start("-display none -machine n800"); + + qtest_add_func("/tmp105/tx-rx", send_and_receive); + + ret = g_test_run(); + + if (s) { + qtest_quit(s); + } + + return ret; +}